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 "tcg-op.h"
  28#include "exec/cpu_ldst.h"
  29
  30#include "exec/helper-proto.h"
  31#include "exec/helper-gen.h"
  32#include "sysemu/kvm.h"
  33#include "exec/semihost.h"
  34
  35#include "trace-tcg.h"
  36#include "exec/log.h"
  37
  38#define MIPS_DEBUG_DISAS 0
  39
  40/* MIPS major opcodes */
  41#define MASK_OP_MAJOR(op)  (op & (0x3F << 26))
  42
  43enum {
  44    /* indirect opcode tables */
  45    OPC_SPECIAL  = (0x00 << 26),
  46    OPC_REGIMM   = (0x01 << 26),
  47    OPC_CP0      = (0x10 << 26),
  48    OPC_CP1      = (0x11 << 26),
  49    OPC_CP2      = (0x12 << 26),
  50    OPC_CP3      = (0x13 << 26),
  51    OPC_SPECIAL2 = (0x1C << 26),
  52    OPC_SPECIAL3 = (0x1F << 26),
  53    /* arithmetic with immediate */
  54    OPC_ADDI     = (0x08 << 26),
  55    OPC_ADDIU    = (0x09 << 26),
  56    OPC_SLTI     = (0x0A << 26),
  57    OPC_SLTIU    = (0x0B << 26),
  58    /* logic with immediate */
  59    OPC_ANDI     = (0x0C << 26),
  60    OPC_ORI      = (0x0D << 26),
  61    OPC_XORI     = (0x0E << 26),
  62    OPC_LUI      = (0x0F << 26),
  63    /* arithmetic with immediate */
  64    OPC_DADDI    = (0x18 << 26),
  65    OPC_DADDIU   = (0x19 << 26),
  66    /* Jump and branches */
  67    OPC_J        = (0x02 << 26),
  68    OPC_JAL      = (0x03 << 26),
  69    OPC_BEQ      = (0x04 << 26),  /* Unconditional if rs = rt = 0 (B) */
  70    OPC_BEQL     = (0x14 << 26),
  71    OPC_BNE      = (0x05 << 26),
  72    OPC_BNEL     = (0x15 << 26),
  73    OPC_BLEZ     = (0x06 << 26),
  74    OPC_BLEZL    = (0x16 << 26),
  75    OPC_BGTZ     = (0x07 << 26),
  76    OPC_BGTZL    = (0x17 << 26),
  77    OPC_JALX     = (0x1D << 26),
  78    OPC_DAUI     = (0x1D << 26),
  79    /* Load and stores */
  80    OPC_LDL      = (0x1A << 26),
  81    OPC_LDR      = (0x1B << 26),
  82    OPC_LB       = (0x20 << 26),
  83    OPC_LH       = (0x21 << 26),
  84    OPC_LWL      = (0x22 << 26),
  85    OPC_LW       = (0x23 << 26),
  86    OPC_LWPC     = OPC_LW | 0x5,
  87    OPC_LBU      = (0x24 << 26),
  88    OPC_LHU      = (0x25 << 26),
  89    OPC_LWR      = (0x26 << 26),
  90    OPC_LWU      = (0x27 << 26),
  91    OPC_SB       = (0x28 << 26),
  92    OPC_SH       = (0x29 << 26),
  93    OPC_SWL      = (0x2A << 26),
  94    OPC_SW       = (0x2B << 26),
  95    OPC_SDL      = (0x2C << 26),
  96    OPC_SDR      = (0x2D << 26),
  97    OPC_SWR      = (0x2E << 26),
  98    OPC_LL       = (0x30 << 26),
  99    OPC_LLD      = (0x34 << 26),
 100    OPC_LD       = (0x37 << 26),
 101    OPC_LDPC     = OPC_LD | 0x5,
 102    OPC_SC       = (0x38 << 26),
 103    OPC_SCD      = (0x3C << 26),
 104    OPC_SD       = (0x3F << 26),
 105    /* Floating point load/store */
 106    OPC_LWC1     = (0x31 << 26),
 107    OPC_LWC2     = (0x32 << 26),
 108    OPC_LDC1     = (0x35 << 26),
 109    OPC_LDC2     = (0x36 << 26),
 110    OPC_SWC1     = (0x39 << 26),
 111    OPC_SWC2     = (0x3A << 26),
 112    OPC_SDC1     = (0x3D << 26),
 113    OPC_SDC2     = (0x3E << 26),
 114    /* Compact Branches */
 115    OPC_BLEZALC  = (0x06 << 26),
 116    OPC_BGEZALC  = (0x06 << 26),
 117    OPC_BGEUC    = (0x06 << 26),
 118    OPC_BGTZALC  = (0x07 << 26),
 119    OPC_BLTZALC  = (0x07 << 26),
 120    OPC_BLTUC    = (0x07 << 26),
 121    OPC_BOVC     = (0x08 << 26),
 122    OPC_BEQZALC  = (0x08 << 26),
 123    OPC_BEQC     = (0x08 << 26),
 124    OPC_BLEZC    = (0x16 << 26),
 125    OPC_BGEZC    = (0x16 << 26),
 126    OPC_BGEC     = (0x16 << 26),
 127    OPC_BGTZC    = (0x17 << 26),
 128    OPC_BLTZC    = (0x17 << 26),
 129    OPC_BLTC     = (0x17 << 26),
 130    OPC_BNVC     = (0x18 << 26),
 131    OPC_BNEZALC  = (0x18 << 26),
 132    OPC_BNEC     = (0x18 << 26),
 133    OPC_BC       = (0x32 << 26),
 134    OPC_BEQZC    = (0x36 << 26),
 135    OPC_JIC      = (0x36 << 26),
 136    OPC_BALC     = (0x3A << 26),
 137    OPC_BNEZC    = (0x3E << 26),
 138    OPC_JIALC    = (0x3E << 26),
 139    /* MDMX ASE specific */
 140    OPC_MDMX     = (0x1E << 26),
 141    /* MSA ASE, same as MDMX */
 142    OPC_MSA      = OPC_MDMX,
 143    /* Cache and prefetch */
 144    OPC_CACHE    = (0x2F << 26),
 145    OPC_PREF     = (0x33 << 26),
 146    /* PC-relative address computation / loads */
 147    OPC_PCREL    = (0x3B << 26),
 148};
 149
 150/* PC-relative address computation / loads  */
 151#define MASK_OPC_PCREL_TOP2BITS(op)  (MASK_OP_MAJOR(op) | (op & (3 << 19)))
 152#define MASK_OPC_PCREL_TOP5BITS(op)  (MASK_OP_MAJOR(op) | (op & (0x1f << 16)))
 153enum {
 154    /* Instructions determined by bits 19 and 20 */
 155    OPC_ADDIUPC = OPC_PCREL | (0 << 19),
 156    R6_OPC_LWPC = OPC_PCREL | (1 << 19),
 157    OPC_LWUPC   = OPC_PCREL | (2 << 19),
 158
 159    /* Instructions determined by bits 16 ... 20 */
 160    OPC_AUIPC   = OPC_PCREL | (0x1e << 16),
 161    OPC_ALUIPC  = OPC_PCREL | (0x1f << 16),
 162
 163    /* Other */
 164    R6_OPC_LDPC = OPC_PCREL | (6 << 18),
 165};
 166
 167/* MIPS special opcodes */
 168#define MASK_SPECIAL(op)   MASK_OP_MAJOR(op) | (op & 0x3F)
 169
 170enum {
 171    /* Shifts */
 172    OPC_SLL      = 0x00 | OPC_SPECIAL,
 173    /* NOP is SLL r0, r0, 0   */
 174    /* SSNOP is SLL r0, r0, 1 */
 175    /* EHB is SLL r0, r0, 3 */
 176    OPC_SRL      = 0x02 | OPC_SPECIAL, /* also ROTR */
 177    OPC_ROTR     = OPC_SRL | (1 << 21),
 178    OPC_SRA      = 0x03 | OPC_SPECIAL,
 179    OPC_SLLV     = 0x04 | OPC_SPECIAL,
 180    OPC_SRLV     = 0x06 | OPC_SPECIAL, /* also ROTRV */
 181    OPC_ROTRV    = OPC_SRLV | (1 << 6),
 182    OPC_SRAV     = 0x07 | OPC_SPECIAL,
 183    OPC_DSLLV    = 0x14 | OPC_SPECIAL,
 184    OPC_DSRLV    = 0x16 | OPC_SPECIAL, /* also DROTRV */
 185    OPC_DROTRV   = OPC_DSRLV | (1 << 6),
 186    OPC_DSRAV    = 0x17 | OPC_SPECIAL,
 187    OPC_DSLL     = 0x38 | OPC_SPECIAL,
 188    OPC_DSRL     = 0x3A | OPC_SPECIAL, /* also DROTR */
 189    OPC_DROTR    = OPC_DSRL | (1 << 21),
 190    OPC_DSRA     = 0x3B | OPC_SPECIAL,
 191    OPC_DSLL32   = 0x3C | OPC_SPECIAL,
 192    OPC_DSRL32   = 0x3E | OPC_SPECIAL, /* also DROTR32 */
 193    OPC_DROTR32  = OPC_DSRL32 | (1 << 21),
 194    OPC_DSRA32   = 0x3F | OPC_SPECIAL,
 195    /* Multiplication / division */
 196    OPC_MULT     = 0x18 | OPC_SPECIAL,
 197    OPC_MULTU    = 0x19 | OPC_SPECIAL,
 198    OPC_DIV      = 0x1A | OPC_SPECIAL,
 199    OPC_DIVU     = 0x1B | OPC_SPECIAL,
 200    OPC_DMULT    = 0x1C | OPC_SPECIAL,
 201    OPC_DMULTU   = 0x1D | OPC_SPECIAL,
 202    OPC_DDIV     = 0x1E | OPC_SPECIAL,
 203    OPC_DDIVU    = 0x1F | OPC_SPECIAL,
 204
 205    /* 2 registers arithmetic / logic */
 206    OPC_ADD      = 0x20 | OPC_SPECIAL,
 207    OPC_ADDU     = 0x21 | OPC_SPECIAL,
 208    OPC_SUB      = 0x22 | OPC_SPECIAL,
 209    OPC_SUBU     = 0x23 | OPC_SPECIAL,
 210    OPC_AND      = 0x24 | OPC_SPECIAL,
 211    OPC_OR       = 0x25 | OPC_SPECIAL,
 212    OPC_XOR      = 0x26 | OPC_SPECIAL,
 213    OPC_NOR      = 0x27 | OPC_SPECIAL,
 214    OPC_SLT      = 0x2A | OPC_SPECIAL,
 215    OPC_SLTU     = 0x2B | OPC_SPECIAL,
 216    OPC_DADD     = 0x2C | OPC_SPECIAL,
 217    OPC_DADDU    = 0x2D | OPC_SPECIAL,
 218    OPC_DSUB     = 0x2E | OPC_SPECIAL,
 219    OPC_DSUBU    = 0x2F | OPC_SPECIAL,
 220    /* Jumps */
 221    OPC_JR       = 0x08 | OPC_SPECIAL, /* Also JR.HB */
 222    OPC_JALR     = 0x09 | OPC_SPECIAL, /* Also JALR.HB */
 223    /* Traps */
 224    OPC_TGE      = 0x30 | OPC_SPECIAL,
 225    OPC_TGEU     = 0x31 | OPC_SPECIAL,
 226    OPC_TLT      = 0x32 | OPC_SPECIAL,
 227    OPC_TLTU     = 0x33 | OPC_SPECIAL,
 228    OPC_TEQ      = 0x34 | OPC_SPECIAL,
 229    OPC_TNE      = 0x36 | OPC_SPECIAL,
 230    /* HI / LO registers load & stores */
 231    OPC_MFHI     = 0x10 | OPC_SPECIAL,
 232    OPC_MTHI     = 0x11 | OPC_SPECIAL,
 233    OPC_MFLO     = 0x12 | OPC_SPECIAL,
 234    OPC_MTLO     = 0x13 | OPC_SPECIAL,
 235    /* Conditional moves */
 236    OPC_MOVZ     = 0x0A | OPC_SPECIAL,
 237    OPC_MOVN     = 0x0B | OPC_SPECIAL,
 238
 239    OPC_SELEQZ   = 0x35 | OPC_SPECIAL,
 240    OPC_SELNEZ   = 0x37 | OPC_SPECIAL,
 241
 242    OPC_MOVCI    = 0x01 | OPC_SPECIAL,
 243
 244    /* Special */
 245    OPC_PMON     = 0x05 | OPC_SPECIAL, /* unofficial */
 246    OPC_SYSCALL  = 0x0C | OPC_SPECIAL,
 247    OPC_BREAK    = 0x0D | OPC_SPECIAL,
 248    OPC_SPIM     = 0x0E | OPC_SPECIAL, /* unofficial */
 249    OPC_SYNC     = 0x0F | OPC_SPECIAL,
 250
 251    OPC_SPECIAL28_RESERVED = 0x28 | OPC_SPECIAL,
 252    OPC_SPECIAL29_RESERVED = 0x29 | OPC_SPECIAL,
 253    OPC_SPECIAL39_RESERVED = 0x39 | OPC_SPECIAL,
 254    OPC_SPECIAL3D_RESERVED = 0x3D | OPC_SPECIAL,
 255};
 256
 257/* R6 Multiply and Divide instructions have the same Opcode
 258   and function field as legacy OPC_MULT[U]/OPC_DIV[U] */
 259#define MASK_R6_MULDIV(op)   (MASK_SPECIAL(op) | (op & (0x7ff)))
 260
 261enum {
 262    R6_OPC_MUL   = OPC_MULT  | (2 << 6),
 263    R6_OPC_MUH   = OPC_MULT  | (3 << 6),
 264    R6_OPC_MULU  = OPC_MULTU | (2 << 6),
 265    R6_OPC_MUHU  = OPC_MULTU | (3 << 6),
 266    R6_OPC_DIV   = OPC_DIV   | (2 << 6),
 267    R6_OPC_MOD   = OPC_DIV   | (3 << 6),
 268    R6_OPC_DIVU  = OPC_DIVU  | (2 << 6),
 269    R6_OPC_MODU  = OPC_DIVU  | (3 << 6),
 270
 271    R6_OPC_DMUL   = OPC_DMULT  | (2 << 6),
 272    R6_OPC_DMUH   = OPC_DMULT  | (3 << 6),
 273    R6_OPC_DMULU  = OPC_DMULTU | (2 << 6),
 274    R6_OPC_DMUHU  = OPC_DMULTU | (3 << 6),
 275    R6_OPC_DDIV   = OPC_DDIV   | (2 << 6),
 276    R6_OPC_DMOD   = OPC_DDIV   | (3 << 6),
 277    R6_OPC_DDIVU  = OPC_DDIVU  | (2 << 6),
 278    R6_OPC_DMODU  = OPC_DDIVU  | (3 << 6),
 279
 280    R6_OPC_CLZ      = 0x10 | OPC_SPECIAL,
 281    R6_OPC_CLO      = 0x11 | OPC_SPECIAL,
 282    R6_OPC_DCLZ     = 0x12 | OPC_SPECIAL,
 283    R6_OPC_DCLO     = 0x13 | OPC_SPECIAL,
 284    R6_OPC_SDBBP    = 0x0e | OPC_SPECIAL,
 285
 286    OPC_LSA  = 0x05 | OPC_SPECIAL,
 287    OPC_DLSA = 0x15 | OPC_SPECIAL,
 288};
 289
 290/* Multiplication variants of the vr54xx. */
 291#define MASK_MUL_VR54XX(op)   MASK_SPECIAL(op) | (op & (0x1F << 6))
 292
 293enum {
 294    OPC_VR54XX_MULS    = (0x03 << 6) | OPC_MULT,
 295    OPC_VR54XX_MULSU   = (0x03 << 6) | OPC_MULTU,
 296    OPC_VR54XX_MACC    = (0x05 << 6) | OPC_MULT,
 297    OPC_VR54XX_MACCU   = (0x05 << 6) | OPC_MULTU,
 298    OPC_VR54XX_MSAC    = (0x07 << 6) | OPC_MULT,
 299    OPC_VR54XX_MSACU   = (0x07 << 6) | OPC_MULTU,
 300    OPC_VR54XX_MULHI   = (0x09 << 6) | OPC_MULT,
 301    OPC_VR54XX_MULHIU  = (0x09 << 6) | OPC_MULTU,
 302    OPC_VR54XX_MULSHI  = (0x0B << 6) | OPC_MULT,
 303    OPC_VR54XX_MULSHIU = (0x0B << 6) | OPC_MULTU,
 304    OPC_VR54XX_MACCHI  = (0x0D << 6) | OPC_MULT,
 305    OPC_VR54XX_MACCHIU = (0x0D << 6) | OPC_MULTU,
 306    OPC_VR54XX_MSACHI  = (0x0F << 6) | OPC_MULT,
 307    OPC_VR54XX_MSACHIU = (0x0F << 6) | OPC_MULTU,
 308};
 309
 310/* REGIMM (rt field) opcodes */
 311#define MASK_REGIMM(op)    MASK_OP_MAJOR(op) | (op & (0x1F << 16))
 312
 313enum {
 314    OPC_BLTZ     = (0x00 << 16) | OPC_REGIMM,
 315    OPC_BLTZL    = (0x02 << 16) | OPC_REGIMM,
 316    OPC_BGEZ     = (0x01 << 16) | OPC_REGIMM,
 317    OPC_BGEZL    = (0x03 << 16) | OPC_REGIMM,
 318    OPC_BLTZAL   = (0x10 << 16) | OPC_REGIMM,
 319    OPC_BLTZALL  = (0x12 << 16) | OPC_REGIMM,
 320    OPC_BGEZAL   = (0x11 << 16) | OPC_REGIMM,
 321    OPC_BGEZALL  = (0x13 << 16) | OPC_REGIMM,
 322    OPC_TGEI     = (0x08 << 16) | OPC_REGIMM,
 323    OPC_TGEIU    = (0x09 << 16) | OPC_REGIMM,
 324    OPC_TLTI     = (0x0A << 16) | OPC_REGIMM,
 325    OPC_TLTIU    = (0x0B << 16) | OPC_REGIMM,
 326    OPC_TEQI     = (0x0C << 16) | OPC_REGIMM,
 327    OPC_TNEI     = (0x0E << 16) | OPC_REGIMM,
 328    OPC_SIGRIE   = (0x17 << 16) | OPC_REGIMM,
 329    OPC_SYNCI    = (0x1F << 16) | OPC_REGIMM,
 330
 331    OPC_DAHI     = (0x06 << 16) | OPC_REGIMM,
 332    OPC_DATI     = (0x1e << 16) | OPC_REGIMM,
 333};
 334
 335/* Special2 opcodes */
 336#define MASK_SPECIAL2(op)  MASK_OP_MAJOR(op) | (op & 0x3F)
 337
 338enum {
 339    /* Multiply & xxx operations */
 340    OPC_MADD     = 0x00 | OPC_SPECIAL2,
 341    OPC_MADDU    = 0x01 | OPC_SPECIAL2,
 342    OPC_MUL      = 0x02 | OPC_SPECIAL2,
 343    OPC_MSUB     = 0x04 | OPC_SPECIAL2,
 344    OPC_MSUBU    = 0x05 | OPC_SPECIAL2,
 345    /* Loongson 2F */
 346    OPC_MULT_G_2F   = 0x10 | OPC_SPECIAL2,
 347    OPC_DMULT_G_2F  = 0x11 | OPC_SPECIAL2,
 348    OPC_MULTU_G_2F  = 0x12 | OPC_SPECIAL2,
 349    OPC_DMULTU_G_2F = 0x13 | OPC_SPECIAL2,
 350    OPC_DIV_G_2F    = 0x14 | OPC_SPECIAL2,
 351    OPC_DDIV_G_2F   = 0x15 | OPC_SPECIAL2,
 352    OPC_DIVU_G_2F   = 0x16 | OPC_SPECIAL2,
 353    OPC_DDIVU_G_2F  = 0x17 | OPC_SPECIAL2,
 354    OPC_MOD_G_2F    = 0x1c | OPC_SPECIAL2,
 355    OPC_DMOD_G_2F   = 0x1d | OPC_SPECIAL2,
 356    OPC_MODU_G_2F   = 0x1e | OPC_SPECIAL2,
 357    OPC_DMODU_G_2F  = 0x1f | OPC_SPECIAL2,
 358    /* Misc */
 359    OPC_CLZ      = 0x20 | OPC_SPECIAL2,
 360    OPC_CLO      = 0x21 | OPC_SPECIAL2,
 361    OPC_DCLZ     = 0x24 | OPC_SPECIAL2,
 362    OPC_DCLO     = 0x25 | OPC_SPECIAL2,
 363    /* Special */
 364    OPC_SDBBP    = 0x3F | OPC_SPECIAL2,
 365};
 366
 367/* Special3 opcodes */
 368#define MASK_SPECIAL3(op)  MASK_OP_MAJOR(op) | (op & 0x3F)
 369
 370enum {
 371    OPC_EXT      = 0x00 | OPC_SPECIAL3,
 372    OPC_DEXTM    = 0x01 | OPC_SPECIAL3,
 373    OPC_DEXTU    = 0x02 | OPC_SPECIAL3,
 374    OPC_DEXT     = 0x03 | OPC_SPECIAL3,
 375    OPC_INS      = 0x04 | OPC_SPECIAL3,
 376    OPC_DINSM    = 0x05 | OPC_SPECIAL3,
 377    OPC_DINSU    = 0x06 | OPC_SPECIAL3,
 378    OPC_DINS     = 0x07 | OPC_SPECIAL3,
 379    OPC_FORK     = 0x08 | OPC_SPECIAL3,
 380    OPC_YIELD    = 0x09 | OPC_SPECIAL3,
 381    OPC_BSHFL    = 0x20 | OPC_SPECIAL3,
 382    OPC_DBSHFL   = 0x24 | OPC_SPECIAL3,
 383    OPC_RDHWR    = 0x3B | OPC_SPECIAL3,
 384
 385    /* Loongson 2E */
 386    OPC_MULT_G_2E   = 0x18 | OPC_SPECIAL3,
 387    OPC_MULTU_G_2E  = 0x19 | OPC_SPECIAL3,
 388    OPC_DIV_G_2E    = 0x1A | OPC_SPECIAL3,
 389    OPC_DIVU_G_2E   = 0x1B | OPC_SPECIAL3,
 390    OPC_DMULT_G_2E  = 0x1C | OPC_SPECIAL3,
 391    OPC_DMULTU_G_2E = 0x1D | OPC_SPECIAL3,
 392    OPC_DDIV_G_2E   = 0x1E | OPC_SPECIAL3,
 393    OPC_DDIVU_G_2E  = 0x1F | OPC_SPECIAL3,
 394    OPC_MOD_G_2E    = 0x22 | OPC_SPECIAL3,
 395    OPC_MODU_G_2E   = 0x23 | OPC_SPECIAL3,
 396    OPC_DMOD_G_2E   = 0x26 | OPC_SPECIAL3,
 397    OPC_DMODU_G_2E  = 0x27 | OPC_SPECIAL3,
 398
 399    /* MIPS DSP Load */
 400    OPC_LX_DSP         = 0x0A | OPC_SPECIAL3,
 401    /* MIPS DSP Arithmetic */
 402    OPC_ADDU_QB_DSP    = 0x10 | OPC_SPECIAL3,
 403    OPC_ADDU_OB_DSP    = 0x14 | OPC_SPECIAL3,
 404    OPC_ABSQ_S_PH_DSP  = 0x12 | OPC_SPECIAL3,
 405    OPC_ABSQ_S_QH_DSP  = 0x16 | OPC_SPECIAL3,
 406    /* OPC_ADDUH_QB_DSP is same as OPC_MULT_G_2E.  */
 407    /* OPC_ADDUH_QB_DSP   = 0x18 | OPC_SPECIAL3,  */
 408    OPC_CMPU_EQ_QB_DSP = 0x11 | OPC_SPECIAL3,
 409    OPC_CMPU_EQ_OB_DSP = 0x15 | OPC_SPECIAL3,
 410    /* MIPS DSP GPR-Based Shift Sub-class */
 411    OPC_SHLL_QB_DSP    = 0x13 | OPC_SPECIAL3,
 412    OPC_SHLL_OB_DSP    = 0x17 | OPC_SPECIAL3,
 413    /* MIPS DSP Multiply Sub-class insns */
 414    /* OPC_MUL_PH_DSP is same as OPC_ADDUH_QB_DSP.  */
 415    /* OPC_MUL_PH_DSP     = 0x18 | OPC_SPECIAL3,  */
 416    OPC_DPA_W_PH_DSP   = 0x30 | OPC_SPECIAL3,
 417    OPC_DPAQ_W_QH_DSP  = 0x34 | OPC_SPECIAL3,
 418    /* DSP Bit/Manipulation Sub-class */
 419    OPC_INSV_DSP       = 0x0C | OPC_SPECIAL3,
 420    OPC_DINSV_DSP      = 0x0D | OPC_SPECIAL3,
 421    /* MIPS DSP Append Sub-class */
 422    OPC_APPEND_DSP     = 0x31 | OPC_SPECIAL3,
 423    OPC_DAPPEND_DSP    = 0x35 | OPC_SPECIAL3,
 424    /* MIPS DSP Accumulator and DSPControl Access Sub-class */
 425    OPC_EXTR_W_DSP     = 0x38 | OPC_SPECIAL3,
 426    OPC_DEXTR_W_DSP    = 0x3C | OPC_SPECIAL3,
 427
 428    /* R6 */
 429    R6_OPC_PREF        = 0x35 | OPC_SPECIAL3,
 430    R6_OPC_CACHE       = 0x25 | OPC_SPECIAL3,
 431    R6_OPC_LL          = 0x36 | OPC_SPECIAL3,
 432    R6_OPC_SC          = 0x26 | OPC_SPECIAL3,
 433    R6_OPC_LLD         = 0x37 | OPC_SPECIAL3,
 434    R6_OPC_SCD         = 0x27 | OPC_SPECIAL3,
 435};
 436
 437/* BSHFL opcodes */
 438#define MASK_BSHFL(op)     MASK_SPECIAL3(op) | (op & (0x1F << 6))
 439
 440enum {
 441    OPC_WSBH      = (0x02 << 6) | OPC_BSHFL,
 442    OPC_SEB       = (0x10 << 6) | OPC_BSHFL,
 443    OPC_SEH       = (0x18 << 6) | OPC_BSHFL,
 444    OPC_ALIGN     = (0x08 << 6) | OPC_BSHFL, /* 010.bp */
 445    OPC_ALIGN_END = (0x0B << 6) | OPC_BSHFL, /* 010.00 to 010.11 */
 446    OPC_BITSWAP   = (0x00 << 6) | OPC_BSHFL  /* 00000 */
 447};
 448
 449/* DBSHFL opcodes */
 450#define MASK_DBSHFL(op)    MASK_SPECIAL3(op) | (op & (0x1F << 6))
 451
 452enum {
 453    OPC_DSBH       = (0x02 << 6) | OPC_DBSHFL,
 454    OPC_DSHD       = (0x05 << 6) | OPC_DBSHFL,
 455    OPC_DALIGN     = (0x08 << 6) | OPC_DBSHFL, /* 01.bp */
 456    OPC_DALIGN_END = (0x0F << 6) | OPC_DBSHFL, /* 01.000 to 01.111 */
 457    OPC_DBITSWAP   = (0x00 << 6) | OPC_DBSHFL, /* 00000 */
 458};
 459
 460/* MIPS DSP REGIMM opcodes */
 461enum {
 462    OPC_BPOSGE32 = (0x1C << 16) | OPC_REGIMM,
 463    OPC_BPOSGE64 = (0x1D << 16) | OPC_REGIMM,
 464};
 465
 466#define MASK_LX(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
 467/* MIPS DSP Load */
 468enum {
 469    OPC_LBUX = (0x06 << 6) | OPC_LX_DSP,
 470    OPC_LHX  = (0x04 << 6) | OPC_LX_DSP,
 471    OPC_LWX  = (0x00 << 6) | OPC_LX_DSP,
 472    OPC_LDX = (0x08 << 6) | OPC_LX_DSP,
 473};
 474
 475#define MASK_ADDU_QB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
 476enum {
 477    /* MIPS DSP Arithmetic Sub-class */
 478    OPC_ADDQ_PH        = (0x0A << 6) | OPC_ADDU_QB_DSP,
 479    OPC_ADDQ_S_PH      = (0x0E << 6) | OPC_ADDU_QB_DSP,
 480    OPC_ADDQ_S_W       = (0x16 << 6) | OPC_ADDU_QB_DSP,
 481    OPC_ADDU_QB        = (0x00 << 6) | OPC_ADDU_QB_DSP,
 482    OPC_ADDU_S_QB      = (0x04 << 6) | OPC_ADDU_QB_DSP,
 483    OPC_ADDU_PH        = (0x08 << 6) | OPC_ADDU_QB_DSP,
 484    OPC_ADDU_S_PH      = (0x0C << 6) | OPC_ADDU_QB_DSP,
 485    OPC_SUBQ_PH        = (0x0B << 6) | OPC_ADDU_QB_DSP,
 486    OPC_SUBQ_S_PH      = (0x0F << 6) | OPC_ADDU_QB_DSP,
 487    OPC_SUBQ_S_W       = (0x17 << 6) | OPC_ADDU_QB_DSP,
 488    OPC_SUBU_QB        = (0x01 << 6) | OPC_ADDU_QB_DSP,
 489    OPC_SUBU_S_QB      = (0x05 << 6) | OPC_ADDU_QB_DSP,
 490    OPC_SUBU_PH        = (0x09 << 6) | OPC_ADDU_QB_DSP,
 491    OPC_SUBU_S_PH      = (0x0D << 6) | OPC_ADDU_QB_DSP,
 492    OPC_ADDSC          = (0x10 << 6) | OPC_ADDU_QB_DSP,
 493    OPC_ADDWC          = (0x11 << 6) | OPC_ADDU_QB_DSP,
 494    OPC_MODSUB         = (0x12 << 6) | OPC_ADDU_QB_DSP,
 495    OPC_RADDU_W_QB     = (0x14 << 6) | OPC_ADDU_QB_DSP,
 496    /* MIPS DSP Multiply Sub-class insns */
 497    OPC_MULEU_S_PH_QBL = (0x06 << 6) | OPC_ADDU_QB_DSP,
 498    OPC_MULEU_S_PH_QBR = (0x07 << 6) | OPC_ADDU_QB_DSP,
 499    OPC_MULQ_RS_PH     = (0x1F << 6) | OPC_ADDU_QB_DSP,
 500    OPC_MULEQ_S_W_PHL  = (0x1C << 6) | OPC_ADDU_QB_DSP,
 501    OPC_MULEQ_S_W_PHR  = (0x1D << 6) | OPC_ADDU_QB_DSP,
 502    OPC_MULQ_S_PH      = (0x1E << 6) | OPC_ADDU_QB_DSP,
 503};
 504
 505#define OPC_ADDUH_QB_DSP OPC_MULT_G_2E
 506#define MASK_ADDUH_QB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
 507enum {
 508    /* MIPS DSP Arithmetic Sub-class */
 509    OPC_ADDUH_QB   = (0x00 << 6) | OPC_ADDUH_QB_DSP,
 510    OPC_ADDUH_R_QB = (0x02 << 6) | OPC_ADDUH_QB_DSP,
 511    OPC_ADDQH_PH   = (0x08 << 6) | OPC_ADDUH_QB_DSP,
 512    OPC_ADDQH_R_PH = (0x0A << 6) | OPC_ADDUH_QB_DSP,
 513    OPC_ADDQH_W    = (0x10 << 6) | OPC_ADDUH_QB_DSP,
 514    OPC_ADDQH_R_W  = (0x12 << 6) | OPC_ADDUH_QB_DSP,
 515    OPC_SUBUH_QB   = (0x01 << 6) | OPC_ADDUH_QB_DSP,
 516    OPC_SUBUH_R_QB = (0x03 << 6) | OPC_ADDUH_QB_DSP,
 517    OPC_SUBQH_PH   = (0x09 << 6) | OPC_ADDUH_QB_DSP,
 518    OPC_SUBQH_R_PH = (0x0B << 6) | OPC_ADDUH_QB_DSP,
 519    OPC_SUBQH_W    = (0x11 << 6) | OPC_ADDUH_QB_DSP,
 520    OPC_SUBQH_R_W  = (0x13 << 6) | OPC_ADDUH_QB_DSP,
 521    /* MIPS DSP Multiply Sub-class insns */
 522    OPC_MUL_PH     = (0x0C << 6) | OPC_ADDUH_QB_DSP,
 523    OPC_MUL_S_PH   = (0x0E << 6) | OPC_ADDUH_QB_DSP,
 524    OPC_MULQ_S_W   = (0x16 << 6) | OPC_ADDUH_QB_DSP,
 525    OPC_MULQ_RS_W  = (0x17 << 6) | OPC_ADDUH_QB_DSP,
 526};
 527
 528#define MASK_ABSQ_S_PH(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
 529enum {
 530    /* MIPS DSP Arithmetic Sub-class */
 531    OPC_ABSQ_S_QB       = (0x01 << 6) | OPC_ABSQ_S_PH_DSP,
 532    OPC_ABSQ_S_PH       = (0x09 << 6) | OPC_ABSQ_S_PH_DSP,
 533    OPC_ABSQ_S_W        = (0x11 << 6) | OPC_ABSQ_S_PH_DSP,
 534    OPC_PRECEQ_W_PHL    = (0x0C << 6) | OPC_ABSQ_S_PH_DSP,
 535    OPC_PRECEQ_W_PHR    = (0x0D << 6) | OPC_ABSQ_S_PH_DSP,
 536    OPC_PRECEQU_PH_QBL  = (0x04 << 6) | OPC_ABSQ_S_PH_DSP,
 537    OPC_PRECEQU_PH_QBR  = (0x05 << 6) | OPC_ABSQ_S_PH_DSP,
 538    OPC_PRECEQU_PH_QBLA = (0x06 << 6) | OPC_ABSQ_S_PH_DSP,
 539    OPC_PRECEQU_PH_QBRA = (0x07 << 6) | OPC_ABSQ_S_PH_DSP,
 540    OPC_PRECEU_PH_QBL   = (0x1C << 6) | OPC_ABSQ_S_PH_DSP,
 541    OPC_PRECEU_PH_QBR   = (0x1D << 6) | OPC_ABSQ_S_PH_DSP,
 542    OPC_PRECEU_PH_QBLA  = (0x1E << 6) | OPC_ABSQ_S_PH_DSP,
 543    OPC_PRECEU_PH_QBRA  = (0x1F << 6) | OPC_ABSQ_S_PH_DSP,
 544    /* DSP Bit/Manipulation Sub-class */
 545    OPC_BITREV          = (0x1B << 6) | OPC_ABSQ_S_PH_DSP,
 546    OPC_REPL_QB         = (0x02 << 6) | OPC_ABSQ_S_PH_DSP,
 547    OPC_REPLV_QB        = (0x03 << 6) | OPC_ABSQ_S_PH_DSP,
 548    OPC_REPL_PH         = (0x0A << 6) | OPC_ABSQ_S_PH_DSP,
 549    OPC_REPLV_PH        = (0x0B << 6) | OPC_ABSQ_S_PH_DSP,
 550};
 551
 552#define MASK_CMPU_EQ_QB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
 553enum {
 554    /* MIPS DSP Arithmetic Sub-class */
 555    OPC_PRECR_QB_PH      = (0x0D << 6) | OPC_CMPU_EQ_QB_DSP,
 556    OPC_PRECRQ_QB_PH     = (0x0C << 6) | OPC_CMPU_EQ_QB_DSP,
 557    OPC_PRECR_SRA_PH_W   = (0x1E << 6) | OPC_CMPU_EQ_QB_DSP,
 558    OPC_PRECR_SRA_R_PH_W = (0x1F << 6) | OPC_CMPU_EQ_QB_DSP,
 559    OPC_PRECRQ_PH_W      = (0x14 << 6) | OPC_CMPU_EQ_QB_DSP,
 560    OPC_PRECRQ_RS_PH_W   = (0x15 << 6) | OPC_CMPU_EQ_QB_DSP,
 561    OPC_PRECRQU_S_QB_PH  = (0x0F << 6) | OPC_CMPU_EQ_QB_DSP,
 562    /* DSP Compare-Pick Sub-class */
 563    OPC_CMPU_EQ_QB       = (0x00 << 6) | OPC_CMPU_EQ_QB_DSP,
 564    OPC_CMPU_LT_QB       = (0x01 << 6) | OPC_CMPU_EQ_QB_DSP,
 565    OPC_CMPU_LE_QB       = (0x02 << 6) | OPC_CMPU_EQ_QB_DSP,
 566    OPC_CMPGU_EQ_QB      = (0x04 << 6) | OPC_CMPU_EQ_QB_DSP,
 567    OPC_CMPGU_LT_QB      = (0x05 << 6) | OPC_CMPU_EQ_QB_DSP,
 568    OPC_CMPGU_LE_QB      = (0x06 << 6) | OPC_CMPU_EQ_QB_DSP,
 569    OPC_CMPGDU_EQ_QB     = (0x18 << 6) | OPC_CMPU_EQ_QB_DSP,
 570    OPC_CMPGDU_LT_QB     = (0x19 << 6) | OPC_CMPU_EQ_QB_DSP,
 571    OPC_CMPGDU_LE_QB     = (0x1A << 6) | OPC_CMPU_EQ_QB_DSP,
 572    OPC_CMP_EQ_PH        = (0x08 << 6) | OPC_CMPU_EQ_QB_DSP,
 573    OPC_CMP_LT_PH        = (0x09 << 6) | OPC_CMPU_EQ_QB_DSP,
 574    OPC_CMP_LE_PH        = (0x0A << 6) | OPC_CMPU_EQ_QB_DSP,
 575    OPC_PICK_QB          = (0x03 << 6) | OPC_CMPU_EQ_QB_DSP,
 576    OPC_PICK_PH          = (0x0B << 6) | OPC_CMPU_EQ_QB_DSP,
 577    OPC_PACKRL_PH        = (0x0E << 6) | OPC_CMPU_EQ_QB_DSP,
 578};
 579
 580#define MASK_SHLL_QB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
 581enum {
 582    /* MIPS DSP GPR-Based Shift Sub-class */
 583    OPC_SHLL_QB    = (0x00 << 6) | OPC_SHLL_QB_DSP,
 584    OPC_SHLLV_QB   = (0x02 << 6) | OPC_SHLL_QB_DSP,
 585    OPC_SHLL_PH    = (0x08 << 6) | OPC_SHLL_QB_DSP,
 586    OPC_SHLLV_PH   = (0x0A << 6) | OPC_SHLL_QB_DSP,
 587    OPC_SHLL_S_PH  = (0x0C << 6) | OPC_SHLL_QB_DSP,
 588    OPC_SHLLV_S_PH = (0x0E << 6) | OPC_SHLL_QB_DSP,
 589    OPC_SHLL_S_W   = (0x14 << 6) | OPC_SHLL_QB_DSP,
 590    OPC_SHLLV_S_W  = (0x16 << 6) | OPC_SHLL_QB_DSP,
 591    OPC_SHRL_QB    = (0x01 << 6) | OPC_SHLL_QB_DSP,
 592    OPC_SHRLV_QB   = (0x03 << 6) | OPC_SHLL_QB_DSP,
 593    OPC_SHRL_PH    = (0x19 << 6) | OPC_SHLL_QB_DSP,
 594    OPC_SHRLV_PH   = (0x1B << 6) | OPC_SHLL_QB_DSP,
 595    OPC_SHRA_QB    = (0x04 << 6) | OPC_SHLL_QB_DSP,
 596    OPC_SHRA_R_QB  = (0x05 << 6) | OPC_SHLL_QB_DSP,
 597    OPC_SHRAV_QB   = (0x06 << 6) | OPC_SHLL_QB_DSP,
 598    OPC_SHRAV_R_QB = (0x07 << 6) | OPC_SHLL_QB_DSP,
 599    OPC_SHRA_PH    = (0x09 << 6) | OPC_SHLL_QB_DSP,
 600    OPC_SHRAV_PH   = (0x0B << 6) | OPC_SHLL_QB_DSP,
 601    OPC_SHRA_R_PH  = (0x0D << 6) | OPC_SHLL_QB_DSP,
 602    OPC_SHRAV_R_PH = (0x0F << 6) | OPC_SHLL_QB_DSP,
 603    OPC_SHRA_R_W   = (0x15 << 6) | OPC_SHLL_QB_DSP,
 604    OPC_SHRAV_R_W  = (0x17 << 6) | OPC_SHLL_QB_DSP,
 605};
 606
 607#define MASK_DPA_W_PH(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
 608enum {
 609    /* MIPS DSP Multiply Sub-class insns */
 610    OPC_DPAU_H_QBL    = (0x03 << 6) | OPC_DPA_W_PH_DSP,
 611    OPC_DPAU_H_QBR    = (0x07 << 6) | OPC_DPA_W_PH_DSP,
 612    OPC_DPSU_H_QBL    = (0x0B << 6) | OPC_DPA_W_PH_DSP,
 613    OPC_DPSU_H_QBR    = (0x0F << 6) | OPC_DPA_W_PH_DSP,
 614    OPC_DPA_W_PH      = (0x00 << 6) | OPC_DPA_W_PH_DSP,
 615    OPC_DPAX_W_PH     = (0x08 << 6) | OPC_DPA_W_PH_DSP,
 616    OPC_DPAQ_S_W_PH   = (0x04 << 6) | OPC_DPA_W_PH_DSP,
 617    OPC_DPAQX_S_W_PH  = (0x18 << 6) | OPC_DPA_W_PH_DSP,
 618    OPC_DPAQX_SA_W_PH = (0x1A << 6) | OPC_DPA_W_PH_DSP,
 619    OPC_DPS_W_PH      = (0x01 << 6) | OPC_DPA_W_PH_DSP,
 620    OPC_DPSX_W_PH     = (0x09 << 6) | OPC_DPA_W_PH_DSP,
 621    OPC_DPSQ_S_W_PH   = (0x05 << 6) | OPC_DPA_W_PH_DSP,
 622    OPC_DPSQX_S_W_PH  = (0x19 << 6) | OPC_DPA_W_PH_DSP,
 623    OPC_DPSQX_SA_W_PH = (0x1B << 6) | OPC_DPA_W_PH_DSP,
 624    OPC_MULSAQ_S_W_PH = (0x06 << 6) | OPC_DPA_W_PH_DSP,
 625    OPC_DPAQ_SA_L_W   = (0x0C << 6) | OPC_DPA_W_PH_DSP,
 626    OPC_DPSQ_SA_L_W   = (0x0D << 6) | OPC_DPA_W_PH_DSP,
 627    OPC_MAQ_S_W_PHL   = (0x14 << 6) | OPC_DPA_W_PH_DSP,
 628    OPC_MAQ_S_W_PHR   = (0x16 << 6) | OPC_DPA_W_PH_DSP,
 629    OPC_MAQ_SA_W_PHL  = (0x10 << 6) | OPC_DPA_W_PH_DSP,
 630    OPC_MAQ_SA_W_PHR  = (0x12 << 6) | OPC_DPA_W_PH_DSP,
 631    OPC_MULSA_W_PH    = (0x02 << 6) | OPC_DPA_W_PH_DSP,
 632};
 633
 634#define MASK_INSV(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
 635enum {
 636    /* DSP Bit/Manipulation Sub-class */
 637    OPC_INSV = (0x00 << 6) | OPC_INSV_DSP,
 638};
 639
 640#define MASK_APPEND(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
 641enum {
 642    /* MIPS DSP Append Sub-class */
 643    OPC_APPEND  = (0x00 << 6) | OPC_APPEND_DSP,
 644    OPC_PREPEND = (0x01 << 6) | OPC_APPEND_DSP,
 645    OPC_BALIGN  = (0x10 << 6) | OPC_APPEND_DSP,
 646};
 647
 648#define MASK_EXTR_W(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
 649enum {
 650    /* MIPS DSP Accumulator and DSPControl Access Sub-class */
 651    OPC_EXTR_W     = (0x00 << 6) | OPC_EXTR_W_DSP,
 652    OPC_EXTR_R_W   = (0x04 << 6) | OPC_EXTR_W_DSP,
 653    OPC_EXTR_RS_W  = (0x06 << 6) | OPC_EXTR_W_DSP,
 654    OPC_EXTR_S_H   = (0x0E << 6) | OPC_EXTR_W_DSP,
 655    OPC_EXTRV_S_H  = (0x0F << 6) | OPC_EXTR_W_DSP,
 656    OPC_EXTRV_W    = (0x01 << 6) | OPC_EXTR_W_DSP,
 657    OPC_EXTRV_R_W  = (0x05 << 6) | OPC_EXTR_W_DSP,
 658    OPC_EXTRV_RS_W = (0x07 << 6) | OPC_EXTR_W_DSP,
 659    OPC_EXTP       = (0x02 << 6) | OPC_EXTR_W_DSP,
 660    OPC_EXTPV      = (0x03 << 6) | OPC_EXTR_W_DSP,
 661    OPC_EXTPDP     = (0x0A << 6) | OPC_EXTR_W_DSP,
 662    OPC_EXTPDPV    = (0x0B << 6) | OPC_EXTR_W_DSP,
 663    OPC_SHILO      = (0x1A << 6) | OPC_EXTR_W_DSP,
 664    OPC_SHILOV     = (0x1B << 6) | OPC_EXTR_W_DSP,
 665    OPC_MTHLIP     = (0x1F << 6) | OPC_EXTR_W_DSP,
 666    OPC_WRDSP      = (0x13 << 6) | OPC_EXTR_W_DSP,
 667    OPC_RDDSP      = (0x12 << 6) | OPC_EXTR_W_DSP,
 668};
 669
 670#define MASK_ABSQ_S_QH(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
 671enum {
 672    /* MIPS DSP Arithmetic Sub-class */
 673    OPC_PRECEQ_L_PWL    = (0x14 << 6) | OPC_ABSQ_S_QH_DSP,
 674    OPC_PRECEQ_L_PWR    = (0x15 << 6) | OPC_ABSQ_S_QH_DSP,
 675    OPC_PRECEQ_PW_QHL   = (0x0C << 6) | OPC_ABSQ_S_QH_DSP,
 676    OPC_PRECEQ_PW_QHR   = (0x0D << 6) | OPC_ABSQ_S_QH_DSP,
 677    OPC_PRECEQ_PW_QHLA  = (0x0E << 6) | OPC_ABSQ_S_QH_DSP,
 678    OPC_PRECEQ_PW_QHRA  = (0x0F << 6) | OPC_ABSQ_S_QH_DSP,
 679    OPC_PRECEQU_QH_OBL  = (0x04 << 6) | OPC_ABSQ_S_QH_DSP,
 680    OPC_PRECEQU_QH_OBR  = (0x05 << 6) | OPC_ABSQ_S_QH_DSP,
 681    OPC_PRECEQU_QH_OBLA = (0x06 << 6) | OPC_ABSQ_S_QH_DSP,
 682    OPC_PRECEQU_QH_OBRA = (0x07 << 6) | OPC_ABSQ_S_QH_DSP,
 683    OPC_PRECEU_QH_OBL   = (0x1C << 6) | OPC_ABSQ_S_QH_DSP,
 684    OPC_PRECEU_QH_OBR   = (0x1D << 6) | OPC_ABSQ_S_QH_DSP,
 685    OPC_PRECEU_QH_OBLA  = (0x1E << 6) | OPC_ABSQ_S_QH_DSP,
 686    OPC_PRECEU_QH_OBRA  = (0x1F << 6) | OPC_ABSQ_S_QH_DSP,
 687    OPC_ABSQ_S_OB       = (0x01 << 6) | OPC_ABSQ_S_QH_DSP,
 688    OPC_ABSQ_S_PW       = (0x11 << 6) | OPC_ABSQ_S_QH_DSP,
 689    OPC_ABSQ_S_QH       = (0x09 << 6) | OPC_ABSQ_S_QH_DSP,
 690    /* DSP Bit/Manipulation Sub-class */
 691    OPC_REPL_OB         = (0x02 << 6) | OPC_ABSQ_S_QH_DSP,
 692    OPC_REPL_PW         = (0x12 << 6) | OPC_ABSQ_S_QH_DSP,
 693    OPC_REPL_QH         = (0x0A << 6) | OPC_ABSQ_S_QH_DSP,
 694    OPC_REPLV_OB        = (0x03 << 6) | OPC_ABSQ_S_QH_DSP,
 695    OPC_REPLV_PW        = (0x13 << 6) | OPC_ABSQ_S_QH_DSP,
 696    OPC_REPLV_QH        = (0x0B << 6) | OPC_ABSQ_S_QH_DSP,
 697};
 698
 699#define MASK_ADDU_OB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
 700enum {
 701    /* MIPS DSP Multiply Sub-class insns */
 702    OPC_MULEQ_S_PW_QHL = (0x1C << 6) | OPC_ADDU_OB_DSP,
 703    OPC_MULEQ_S_PW_QHR = (0x1D << 6) | OPC_ADDU_OB_DSP,
 704    OPC_MULEU_S_QH_OBL = (0x06 << 6) | OPC_ADDU_OB_DSP,
 705    OPC_MULEU_S_QH_OBR = (0x07 << 6) | OPC_ADDU_OB_DSP,
 706    OPC_MULQ_RS_QH     = (0x1F << 6) | OPC_ADDU_OB_DSP,
 707    /* MIPS DSP Arithmetic Sub-class */
 708    OPC_RADDU_L_OB     = (0x14 << 6) | OPC_ADDU_OB_DSP,
 709    OPC_SUBQ_PW        = (0x13 << 6) | OPC_ADDU_OB_DSP,
 710    OPC_SUBQ_S_PW      = (0x17 << 6) | OPC_ADDU_OB_DSP,
 711    OPC_SUBQ_QH        = (0x0B << 6) | OPC_ADDU_OB_DSP,
 712    OPC_SUBQ_S_QH      = (0x0F << 6) | OPC_ADDU_OB_DSP,
 713    OPC_SUBU_OB        = (0x01 << 6) | OPC_ADDU_OB_DSP,
 714    OPC_SUBU_S_OB      = (0x05 << 6) | OPC_ADDU_OB_DSP,
 715    OPC_SUBU_QH        = (0x09 << 6) | OPC_ADDU_OB_DSP,
 716    OPC_SUBU_S_QH      = (0x0D << 6) | OPC_ADDU_OB_DSP,
 717    OPC_SUBUH_OB       = (0x19 << 6) | OPC_ADDU_OB_DSP,
 718    OPC_SUBUH_R_OB     = (0x1B << 6) | OPC_ADDU_OB_DSP,
 719    OPC_ADDQ_PW        = (0x12 << 6) | OPC_ADDU_OB_DSP,
 720    OPC_ADDQ_S_PW      = (0x16 << 6) | OPC_ADDU_OB_DSP,
 721    OPC_ADDQ_QH        = (0x0A << 6) | OPC_ADDU_OB_DSP,
 722    OPC_ADDQ_S_QH      = (0x0E << 6) | OPC_ADDU_OB_DSP,
 723    OPC_ADDU_OB        = (0x00 << 6) | OPC_ADDU_OB_DSP,
 724    OPC_ADDU_S_OB      = (0x04 << 6) | OPC_ADDU_OB_DSP,
 725    OPC_ADDU_QH        = (0x08 << 6) | OPC_ADDU_OB_DSP,
 726    OPC_ADDU_S_QH      = (0x0C << 6) | OPC_ADDU_OB_DSP,
 727    OPC_ADDUH_OB       = (0x18 << 6) | OPC_ADDU_OB_DSP,
 728    OPC_ADDUH_R_OB     = (0x1A << 6) | OPC_ADDU_OB_DSP,
 729};
 730
 731#define MASK_CMPU_EQ_OB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
 732enum {
 733    /* DSP Compare-Pick Sub-class */
 734    OPC_CMP_EQ_PW         = (0x10 << 6) | OPC_CMPU_EQ_OB_DSP,
 735    OPC_CMP_LT_PW         = (0x11 << 6) | OPC_CMPU_EQ_OB_DSP,
 736    OPC_CMP_LE_PW         = (0x12 << 6) | OPC_CMPU_EQ_OB_DSP,
 737    OPC_CMP_EQ_QH         = (0x08 << 6) | OPC_CMPU_EQ_OB_DSP,
 738    OPC_CMP_LT_QH         = (0x09 << 6) | OPC_CMPU_EQ_OB_DSP,
 739    OPC_CMP_LE_QH         = (0x0A << 6) | OPC_CMPU_EQ_OB_DSP,
 740    OPC_CMPGDU_EQ_OB      = (0x18 << 6) | OPC_CMPU_EQ_OB_DSP,
 741    OPC_CMPGDU_LT_OB      = (0x19 << 6) | OPC_CMPU_EQ_OB_DSP,
 742    OPC_CMPGDU_LE_OB      = (0x1A << 6) | OPC_CMPU_EQ_OB_DSP,
 743    OPC_CMPGU_EQ_OB       = (0x04 << 6) | OPC_CMPU_EQ_OB_DSP,
 744    OPC_CMPGU_LT_OB       = (0x05 << 6) | OPC_CMPU_EQ_OB_DSP,
 745    OPC_CMPGU_LE_OB       = (0x06 << 6) | OPC_CMPU_EQ_OB_DSP,
 746    OPC_CMPU_EQ_OB        = (0x00 << 6) | OPC_CMPU_EQ_OB_DSP,
 747    OPC_CMPU_LT_OB        = (0x01 << 6) | OPC_CMPU_EQ_OB_DSP,
 748    OPC_CMPU_LE_OB        = (0x02 << 6) | OPC_CMPU_EQ_OB_DSP,
 749    OPC_PACKRL_PW         = (0x0E << 6) | OPC_CMPU_EQ_OB_DSP,
 750    OPC_PICK_OB           = (0x03 << 6) | OPC_CMPU_EQ_OB_DSP,
 751    OPC_PICK_PW           = (0x13 << 6) | OPC_CMPU_EQ_OB_DSP,
 752    OPC_PICK_QH           = (0x0B << 6) | OPC_CMPU_EQ_OB_DSP,
 753    /* MIPS DSP Arithmetic Sub-class */
 754    OPC_PRECR_OB_QH       = (0x0D << 6) | OPC_CMPU_EQ_OB_DSP,
 755    OPC_PRECR_SRA_QH_PW   = (0x1E << 6) | OPC_CMPU_EQ_OB_DSP,
 756    OPC_PRECR_SRA_R_QH_PW = (0x1F << 6) | OPC_CMPU_EQ_OB_DSP,
 757    OPC_PRECRQ_OB_QH      = (0x0C << 6) | OPC_CMPU_EQ_OB_DSP,
 758    OPC_PRECRQ_PW_L       = (0x1C << 6) | OPC_CMPU_EQ_OB_DSP,
 759    OPC_PRECRQ_QH_PW      = (0x14 << 6) | OPC_CMPU_EQ_OB_DSP,
 760    OPC_PRECRQ_RS_QH_PW   = (0x15 << 6) | OPC_CMPU_EQ_OB_DSP,
 761    OPC_PRECRQU_S_OB_QH   = (0x0F << 6) | OPC_CMPU_EQ_OB_DSP,
 762};
 763
 764#define MASK_DAPPEND(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
 765enum {
 766    /* DSP Append Sub-class */
 767    OPC_DAPPEND  = (0x00 << 6) | OPC_DAPPEND_DSP,
 768    OPC_PREPENDD = (0x03 << 6) | OPC_DAPPEND_DSP,
 769    OPC_PREPENDW = (0x01 << 6) | OPC_DAPPEND_DSP,
 770    OPC_DBALIGN  = (0x10 << 6) | OPC_DAPPEND_DSP,
 771};
 772
 773#define MASK_DEXTR_W(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
 774enum {
 775    /* MIPS DSP Accumulator and DSPControl Access Sub-class */
 776    OPC_DMTHLIP     = (0x1F << 6) | OPC_DEXTR_W_DSP,
 777    OPC_DSHILO      = (0x1A << 6) | OPC_DEXTR_W_DSP,
 778    OPC_DEXTP       = (0x02 << 6) | OPC_DEXTR_W_DSP,
 779    OPC_DEXTPDP     = (0x0A << 6) | OPC_DEXTR_W_DSP,
 780    OPC_DEXTPDPV    = (0x0B << 6) | OPC_DEXTR_W_DSP,
 781    OPC_DEXTPV      = (0x03 << 6) | OPC_DEXTR_W_DSP,
 782    OPC_DEXTR_L     = (0x10 << 6) | OPC_DEXTR_W_DSP,
 783    OPC_DEXTR_R_L   = (0x14 << 6) | OPC_DEXTR_W_DSP,
 784    OPC_DEXTR_RS_L  = (0x16 << 6) | OPC_DEXTR_W_DSP,
 785    OPC_DEXTR_W     = (0x00 << 6) | OPC_DEXTR_W_DSP,
 786    OPC_DEXTR_R_W   = (0x04 << 6) | OPC_DEXTR_W_DSP,
 787    OPC_DEXTR_RS_W  = (0x06 << 6) | OPC_DEXTR_W_DSP,
 788    OPC_DEXTR_S_H   = (0x0E << 6) | OPC_DEXTR_W_DSP,
 789    OPC_DEXTRV_L    = (0x11 << 6) | OPC_DEXTR_W_DSP,
 790    OPC_DEXTRV_R_L  = (0x15 << 6) | OPC_DEXTR_W_DSP,
 791    OPC_DEXTRV_RS_L = (0x17 << 6) | OPC_DEXTR_W_DSP,
 792    OPC_DEXTRV_S_H  = (0x0F << 6) | OPC_DEXTR_W_DSP,
 793    OPC_DEXTRV_W    = (0x01 << 6) | OPC_DEXTR_W_DSP,
 794    OPC_DEXTRV_R_W  = (0x05 << 6) | OPC_DEXTR_W_DSP,
 795    OPC_DEXTRV_RS_W = (0x07 << 6) | OPC_DEXTR_W_DSP,
 796    OPC_DSHILOV     = (0x1B << 6) | OPC_DEXTR_W_DSP,
 797};
 798
 799#define MASK_DINSV(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
 800enum {
 801    /* DSP Bit/Manipulation Sub-class */
 802    OPC_DINSV = (0x00 << 6) | OPC_DINSV_DSP,
 803};
 804
 805#define MASK_DPAQ_W_QH(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
 806enum {
 807    /* MIPS DSP Multiply Sub-class insns */
 808    OPC_DMADD         = (0x19 << 6) | OPC_DPAQ_W_QH_DSP,
 809    OPC_DMADDU        = (0x1D << 6) | OPC_DPAQ_W_QH_DSP,
 810    OPC_DMSUB         = (0x1B << 6) | OPC_DPAQ_W_QH_DSP,
 811    OPC_DMSUBU        = (0x1F << 6) | OPC_DPAQ_W_QH_DSP,
 812    OPC_DPA_W_QH      = (0x00 << 6) | OPC_DPAQ_W_QH_DSP,
 813    OPC_DPAQ_S_W_QH   = (0x04 << 6) | OPC_DPAQ_W_QH_DSP,
 814    OPC_DPAQ_SA_L_PW  = (0x0C << 6) | OPC_DPAQ_W_QH_DSP,
 815    OPC_DPAU_H_OBL    = (0x03 << 6) | OPC_DPAQ_W_QH_DSP,
 816    OPC_DPAU_H_OBR    = (0x07 << 6) | OPC_DPAQ_W_QH_DSP,
 817    OPC_DPS_W_QH      = (0x01 << 6) | OPC_DPAQ_W_QH_DSP,
 818    OPC_DPSQ_S_W_QH   = (0x05 << 6) | OPC_DPAQ_W_QH_DSP,
 819    OPC_DPSQ_SA_L_PW  = (0x0D << 6) | OPC_DPAQ_W_QH_DSP,
 820    OPC_DPSU_H_OBL    = (0x0B << 6) | OPC_DPAQ_W_QH_DSP,
 821    OPC_DPSU_H_OBR    = (0x0F << 6) | OPC_DPAQ_W_QH_DSP,
 822    OPC_MAQ_S_L_PWL   = (0x1C << 6) | OPC_DPAQ_W_QH_DSP,
 823    OPC_MAQ_S_L_PWR   = (0x1E << 6) | OPC_DPAQ_W_QH_DSP,
 824    OPC_MAQ_S_W_QHLL  = (0x14 << 6) | OPC_DPAQ_W_QH_DSP,
 825    OPC_MAQ_SA_W_QHLL = (0x10 << 6) | OPC_DPAQ_W_QH_DSP,
 826    OPC_MAQ_S_W_QHLR  = (0x15 << 6) | OPC_DPAQ_W_QH_DSP,
 827    OPC_MAQ_SA_W_QHLR = (0x11 << 6) | OPC_DPAQ_W_QH_DSP,
 828    OPC_MAQ_S_W_QHRL  = (0x16 << 6) | OPC_DPAQ_W_QH_DSP,
 829    OPC_MAQ_SA_W_QHRL = (0x12 << 6) | OPC_DPAQ_W_QH_DSP,
 830    OPC_MAQ_S_W_QHRR  = (0x17 << 6) | OPC_DPAQ_W_QH_DSP,
 831    OPC_MAQ_SA_W_QHRR = (0x13 << 6) | OPC_DPAQ_W_QH_DSP,
 832    OPC_MULSAQ_S_L_PW = (0x0E << 6) | OPC_DPAQ_W_QH_DSP,
 833    OPC_MULSAQ_S_W_QH = (0x06 << 6) | OPC_DPAQ_W_QH_DSP,
 834};
 835
 836#define MASK_SHLL_OB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
 837enum {
 838    /* MIPS DSP GPR-Based Shift Sub-class */
 839    OPC_SHLL_PW    = (0x10 << 6) | OPC_SHLL_OB_DSP,
 840    OPC_SHLL_S_PW  = (0x14 << 6) | OPC_SHLL_OB_DSP,
 841    OPC_SHLLV_OB   = (0x02 << 6) | OPC_SHLL_OB_DSP,
 842    OPC_SHLLV_PW   = (0x12 << 6) | OPC_SHLL_OB_DSP,
 843    OPC_SHLLV_S_PW = (0x16 << 6) | OPC_SHLL_OB_DSP,
 844    OPC_SHLLV_QH   = (0x0A << 6) | OPC_SHLL_OB_DSP,
 845    OPC_SHLLV_S_QH = (0x0E << 6) | OPC_SHLL_OB_DSP,
 846    OPC_SHRA_PW    = (0x11 << 6) | OPC_SHLL_OB_DSP,
 847    OPC_SHRA_R_PW  = (0x15 << 6) | OPC_SHLL_OB_DSP,
 848    OPC_SHRAV_OB   = (0x06 << 6) | OPC_SHLL_OB_DSP,
 849    OPC_SHRAV_R_OB = (0x07 << 6) | OPC_SHLL_OB_DSP,
 850    OPC_SHRAV_PW   = (0x13 << 6) | OPC_SHLL_OB_DSP,
 851    OPC_SHRAV_R_PW = (0x17 << 6) | OPC_SHLL_OB_DSP,
 852    OPC_SHRAV_QH   = (0x0B << 6) | OPC_SHLL_OB_DSP,
 853    OPC_SHRAV_R_QH = (0x0F << 6) | OPC_SHLL_OB_DSP,
 854    OPC_SHRLV_OB   = (0x03 << 6) | OPC_SHLL_OB_DSP,
 855    OPC_SHRLV_QH   = (0x1B << 6) | OPC_SHLL_OB_DSP,
 856    OPC_SHLL_OB    = (0x00 << 6) | OPC_SHLL_OB_DSP,
 857    OPC_SHLL_QH    = (0x08 << 6) | OPC_SHLL_OB_DSP,
 858    OPC_SHLL_S_QH  = (0x0C << 6) | OPC_SHLL_OB_DSP,
 859    OPC_SHRA_OB    = (0x04 << 6) | OPC_SHLL_OB_DSP,
 860    OPC_SHRA_R_OB  = (0x05 << 6) | OPC_SHLL_OB_DSP,
 861    OPC_SHRA_QH    = (0x09 << 6) | OPC_SHLL_OB_DSP,
 862    OPC_SHRA_R_QH  = (0x0D << 6) | OPC_SHLL_OB_DSP,
 863    OPC_SHRL_OB    = (0x01 << 6) | OPC_SHLL_OB_DSP,
 864    OPC_SHRL_QH    = (0x19 << 6) | OPC_SHLL_OB_DSP,
 865};
 866
 867/* Coprocessor 0 (rs field) */
 868#define MASK_CP0(op)       MASK_OP_MAJOR(op) | (op & (0x1F << 21))
 869
 870enum {
 871    OPC_MFC0     = (0x00 << 21) | OPC_CP0,
 872    OPC_DMFC0    = (0x01 << 21) | OPC_CP0,
 873    OPC_MFHC0    = (0x02 << 21) | OPC_CP0,
 874    OPC_MTC0     = (0x04 << 21) | OPC_CP0,
 875    OPC_DMTC0    = (0x05 << 21) | OPC_CP0,
 876    OPC_MTHC0    = (0x06 << 21) | OPC_CP0,
 877    OPC_MFTR     = (0x08 << 21) | OPC_CP0,
 878    OPC_RDPGPR   = (0x0A << 21) | OPC_CP0,
 879    OPC_MFMC0    = (0x0B << 21) | OPC_CP0,
 880    OPC_MTTR     = (0x0C << 21) | OPC_CP0,
 881    OPC_WRPGPR   = (0x0E << 21) | OPC_CP0,
 882    OPC_C0       = (0x10 << 21) | OPC_CP0,
 883    OPC_C0_FIRST = (0x10 << 21) | OPC_CP0,
 884    OPC_C0_LAST  = (0x1F << 21) | OPC_CP0,
 885};
 886
 887/* MFMC0 opcodes */
 888#define MASK_MFMC0(op)     MASK_CP0(op) | (op & 0xFFFF)
 889
 890enum {
 891    OPC_DMT      = 0x01 | (0 << 5) | (0x0F << 6) | (0x01 << 11) | OPC_MFMC0,
 892    OPC_EMT      = 0x01 | (1 << 5) | (0x0F << 6) | (0x01 << 11) | OPC_MFMC0,
 893    OPC_DVPE     = 0x01 | (0 << 5) | OPC_MFMC0,
 894    OPC_EVPE     = 0x01 | (1 << 5) | OPC_MFMC0,
 895    OPC_DI       = (0 << 5) | (0x0C << 11) | OPC_MFMC0,
 896    OPC_EI       = (1 << 5) | (0x0C << 11) | OPC_MFMC0,
 897    OPC_DVP      = 0x04 | (0 << 3) | (1 << 5) | (0 << 11) | OPC_MFMC0,
 898    OPC_EVP      = 0x04 | (0 << 3) | (0 << 5) | (0 << 11) | OPC_MFMC0,
 899};
 900
 901/* Coprocessor 0 (with rs == C0) */
 902#define MASK_C0(op)        MASK_CP0(op) | (op & 0x3F)
 903
 904enum {
 905    OPC_TLBR     = 0x01 | OPC_C0,
 906    OPC_TLBWI    = 0x02 | OPC_C0,
 907    OPC_TLBINV   = 0x03 | OPC_C0,
 908    OPC_TLBINVF  = 0x04 | OPC_C0,
 909    OPC_TLBWR    = 0x06 | OPC_C0,
 910    OPC_TLBP     = 0x08 | OPC_C0,
 911    OPC_RFE      = 0x10 | OPC_C0,
 912    OPC_ERET     = 0x18 | OPC_C0,
 913    OPC_DERET    = 0x1F | OPC_C0,
 914    OPC_WAIT     = 0x20 | OPC_C0,
 915};
 916
 917/* Coprocessor 1 (rs field) */
 918#define MASK_CP1(op)       MASK_OP_MAJOR(op) | (op & (0x1F << 21))
 919
 920/* Values for the fmt field in FP instructions */
 921enum {
 922    /* 0 - 15 are reserved */
 923    FMT_S = 16,          /* single fp */
 924    FMT_D = 17,          /* double fp */
 925    FMT_E = 18,          /* extended fp */
 926    FMT_Q = 19,          /* quad fp */
 927    FMT_W = 20,          /* 32-bit fixed */
 928    FMT_L = 21,          /* 64-bit fixed */
 929    FMT_PS = 22,         /* paired single fp */
 930    /* 23 - 31 are reserved */
 931};
 932
 933enum {
 934    OPC_MFC1     = (0x00 << 21) | OPC_CP1,
 935    OPC_DMFC1    = (0x01 << 21) | OPC_CP1,
 936    OPC_CFC1     = (0x02 << 21) | OPC_CP1,
 937    OPC_MFHC1    = (0x03 << 21) | OPC_CP1,
 938    OPC_MTC1     = (0x04 << 21) | OPC_CP1,
 939    OPC_DMTC1    = (0x05 << 21) | OPC_CP1,
 940    OPC_CTC1     = (0x06 << 21) | OPC_CP1,
 941    OPC_MTHC1    = (0x07 << 21) | OPC_CP1,
 942    OPC_BC1      = (0x08 << 21) | OPC_CP1, /* bc */
 943    OPC_BC1ANY2  = (0x09 << 21) | OPC_CP1,
 944    OPC_BC1ANY4  = (0x0A << 21) | OPC_CP1,
 945    OPC_BZ_V     = (0x0B << 21) | OPC_CP1,
 946    OPC_BNZ_V    = (0x0F << 21) | OPC_CP1,
 947    OPC_S_FMT    = (FMT_S << 21) | OPC_CP1,
 948    OPC_D_FMT    = (FMT_D << 21) | OPC_CP1,
 949    OPC_E_FMT    = (FMT_E << 21) | OPC_CP1,
 950    OPC_Q_FMT    = (FMT_Q << 21) | OPC_CP1,
 951    OPC_W_FMT    = (FMT_W << 21) | OPC_CP1,
 952    OPC_L_FMT    = (FMT_L << 21) | OPC_CP1,
 953    OPC_PS_FMT   = (FMT_PS << 21) | OPC_CP1,
 954    OPC_BC1EQZ   = (0x09 << 21) | OPC_CP1,
 955    OPC_BC1NEZ   = (0x0D << 21) | OPC_CP1,
 956    OPC_BZ_B     = (0x18 << 21) | OPC_CP1,
 957    OPC_BZ_H     = (0x19 << 21) | OPC_CP1,
 958    OPC_BZ_W     = (0x1A << 21) | OPC_CP1,
 959    OPC_BZ_D     = (0x1B << 21) | OPC_CP1,
 960    OPC_BNZ_B    = (0x1C << 21) | OPC_CP1,
 961    OPC_BNZ_H    = (0x1D << 21) | OPC_CP1,
 962    OPC_BNZ_W    = (0x1E << 21) | OPC_CP1,
 963    OPC_BNZ_D    = (0x1F << 21) | OPC_CP1,
 964};
 965
 966#define MASK_CP1_FUNC(op)       MASK_CP1(op) | (op & 0x3F)
 967#define MASK_BC1(op)            MASK_CP1(op) | (op & (0x3 << 16))
 968
 969enum {
 970    OPC_BC1F     = (0x00 << 16) | OPC_BC1,
 971    OPC_BC1T     = (0x01 << 16) | OPC_BC1,
 972    OPC_BC1FL    = (0x02 << 16) | OPC_BC1,
 973    OPC_BC1TL    = (0x03 << 16) | OPC_BC1,
 974};
 975
 976enum {
 977    OPC_BC1FANY2     = (0x00 << 16) | OPC_BC1ANY2,
 978    OPC_BC1TANY2     = (0x01 << 16) | OPC_BC1ANY2,
 979};
 980
 981enum {
 982    OPC_BC1FANY4     = (0x00 << 16) | OPC_BC1ANY4,
 983    OPC_BC1TANY4     = (0x01 << 16) | OPC_BC1ANY4,
 984};
 985
 986#define MASK_CP2(op)       MASK_OP_MAJOR(op) | (op & (0x1F << 21))
 987
 988enum {
 989    OPC_MFC2    = (0x00 << 21) | OPC_CP2,
 990    OPC_DMFC2   = (0x01 << 21) | OPC_CP2,
 991    OPC_CFC2    = (0x02 << 21) | OPC_CP2,
 992    OPC_MFHC2   = (0x03 << 21) | OPC_CP2,
 993    OPC_MTC2    = (0x04 << 21) | OPC_CP2,
 994    OPC_DMTC2   = (0x05 << 21) | OPC_CP2,
 995    OPC_CTC2    = (0x06 << 21) | OPC_CP2,
 996    OPC_MTHC2   = (0x07 << 21) | OPC_CP2,
 997    OPC_BC2     = (0x08 << 21) | OPC_CP2,
 998    OPC_BC2EQZ  = (0x09 << 21) | OPC_CP2,
 999    OPC_BC2NEZ  = (0x0D << 21) | OPC_CP2,
1000};
1001
1002#define MASK_LMI(op)  (MASK_OP_MAJOR(op) | (op & (0x1F << 21)) | (op & 0x1F))
1003
1004enum {
1005    OPC_PADDSH  = (24 << 21) | (0x00) | OPC_CP2,
1006    OPC_PADDUSH = (25 << 21) | (0x00) | OPC_CP2,
1007    OPC_PADDH   = (26 << 21) | (0x00) | OPC_CP2,
1008    OPC_PADDW   = (27 << 21) | (0x00) | OPC_CP2,
1009    OPC_PADDSB  = (28 << 21) | (0x00) | OPC_CP2,
1010    OPC_PADDUSB = (29 << 21) | (0x00) | OPC_CP2,
1011    OPC_PADDB   = (30 << 21) | (0x00) | OPC_CP2,
1012    OPC_PADDD   = (31 << 21) | (0x00) | OPC_CP2,
1013
1014    OPC_PSUBSH  = (24 << 21) | (0x01) | OPC_CP2,
1015    OPC_PSUBUSH = (25 << 21) | (0x01) | OPC_CP2,
1016    OPC_PSUBH   = (26 << 21) | (0x01) | OPC_CP2,
1017    OPC_PSUBW   = (27 << 21) | (0x01) | OPC_CP2,
1018    OPC_PSUBSB  = (28 << 21) | (0x01) | OPC_CP2,
1019    OPC_PSUBUSB = (29 << 21) | (0x01) | OPC_CP2,
1020    OPC_PSUBB   = (30 << 21) | (0x01) | OPC_CP2,
1021    OPC_PSUBD   = (31 << 21) | (0x01) | OPC_CP2,
1022
1023    OPC_PSHUFH   = (24 << 21) | (0x02) | OPC_CP2,
1024    OPC_PACKSSWH = (25 << 21) | (0x02) | OPC_CP2,
1025    OPC_PACKSSHB = (26 << 21) | (0x02) | OPC_CP2,
1026    OPC_PACKUSHB = (27 << 21) | (0x02) | OPC_CP2,
1027    OPC_XOR_CP2  = (28 << 21) | (0x02) | OPC_CP2,
1028    OPC_NOR_CP2  = (29 << 21) | (0x02) | OPC_CP2,
1029    OPC_AND_CP2  = (30 << 21) | (0x02) | OPC_CP2,
1030    OPC_PANDN    = (31 << 21) | (0x02) | OPC_CP2,
1031
1032    OPC_PUNPCKLHW = (24 << 21) | (0x03) | OPC_CP2,
1033    OPC_PUNPCKHHW = (25 << 21) | (0x03) | OPC_CP2,
1034    OPC_PUNPCKLBH = (26 << 21) | (0x03) | OPC_CP2,
1035    OPC_PUNPCKHBH = (27 << 21) | (0x03) | OPC_CP2,
1036    OPC_PINSRH_0  = (28 << 21) | (0x03) | OPC_CP2,
1037    OPC_PINSRH_1  = (29 << 21) | (0x03) | OPC_CP2,
1038    OPC_PINSRH_2  = (30 << 21) | (0x03) | OPC_CP2,
1039    OPC_PINSRH_3  = (31 << 21) | (0x03) | OPC_CP2,
1040
1041    OPC_PAVGH   = (24 << 21) | (0x08) | OPC_CP2,
1042    OPC_PAVGB   = (25 << 21) | (0x08) | OPC_CP2,
1043    OPC_PMAXSH  = (26 << 21) | (0x08) | OPC_CP2,
1044    OPC_PMINSH  = (27 << 21) | (0x08) | OPC_CP2,
1045    OPC_PMAXUB  = (28 << 21) | (0x08) | OPC_CP2,
1046    OPC_PMINUB  = (29 << 21) | (0x08) | OPC_CP2,
1047
1048    OPC_PCMPEQW = (24 << 21) | (0x09) | OPC_CP2,
1049    OPC_PCMPGTW = (25 << 21) | (0x09) | OPC_CP2,
1050    OPC_PCMPEQH = (26 << 21) | (0x09) | OPC_CP2,
1051    OPC_PCMPGTH = (27 << 21) | (0x09) | OPC_CP2,
1052    OPC_PCMPEQB = (28 << 21) | (0x09) | OPC_CP2,
1053    OPC_PCMPGTB = (29 << 21) | (0x09) | OPC_CP2,
1054
1055    OPC_PSLLW   = (24 << 21) | (0x0A) | OPC_CP2,
1056    OPC_PSLLH   = (25 << 21) | (0x0A) | OPC_CP2,
1057    OPC_PMULLH  = (26 << 21) | (0x0A) | OPC_CP2,
1058    OPC_PMULHH  = (27 << 21) | (0x0A) | OPC_CP2,
1059    OPC_PMULUW  = (28 << 21) | (0x0A) | OPC_CP2,
1060    OPC_PMULHUH = (29 << 21) | (0x0A) | OPC_CP2,
1061
1062    OPC_PSRLW     = (24 << 21) | (0x0B) | OPC_CP2,
1063    OPC_PSRLH     = (25 << 21) | (0x0B) | OPC_CP2,
1064    OPC_PSRAW     = (26 << 21) | (0x0B) | OPC_CP2,
1065    OPC_PSRAH     = (27 << 21) | (0x0B) | OPC_CP2,
1066    OPC_PUNPCKLWD = (28 << 21) | (0x0B) | OPC_CP2,
1067    OPC_PUNPCKHWD = (29 << 21) | (0x0B) | OPC_CP2,
1068
1069    OPC_ADDU_CP2 = (24 << 21) | (0x0C) | OPC_CP2,
1070    OPC_OR_CP2   = (25 << 21) | (0x0C) | OPC_CP2,
1071    OPC_ADD_CP2  = (26 << 21) | (0x0C) | OPC_CP2,
1072    OPC_DADD_CP2 = (27 << 21) | (0x0C) | OPC_CP2,
1073    OPC_SEQU_CP2 = (28 << 21) | (0x0C) | OPC_CP2,
1074    OPC_SEQ_CP2  = (29 << 21) | (0x0C) | OPC_CP2,
1075
1076    OPC_SUBU_CP2 = (24 << 21) | (0x0D) | OPC_CP2,
1077    OPC_PASUBUB  = (25 << 21) | (0x0D) | OPC_CP2,
1078    OPC_SUB_CP2  = (26 << 21) | (0x0D) | OPC_CP2,
1079    OPC_DSUB_CP2 = (27 << 21) | (0x0D) | OPC_CP2,
1080    OPC_SLTU_CP2 = (28 << 21) | (0x0D) | OPC_CP2,
1081    OPC_SLT_CP2  = (29 << 21) | (0x0D) | OPC_CP2,
1082
1083    OPC_SLL_CP2  = (24 << 21) | (0x0E) | OPC_CP2,
1084    OPC_DSLL_CP2 = (25 << 21) | (0x0E) | OPC_CP2,
1085    OPC_PEXTRH   = (26 << 21) | (0x0E) | OPC_CP2,
1086    OPC_PMADDHW  = (27 << 21) | (0x0E) | OPC_CP2,
1087    OPC_SLEU_CP2 = (28 << 21) | (0x0E) | OPC_CP2,
1088    OPC_SLE_CP2  = (29 << 21) | (0x0E) | OPC_CP2,
1089
1090    OPC_SRL_CP2  = (24 << 21) | (0x0F) | OPC_CP2,
1091    OPC_DSRL_CP2 = (25 << 21) | (0x0F) | OPC_CP2,
1092    OPC_SRA_CP2  = (26 << 21) | (0x0F) | OPC_CP2,
1093    OPC_DSRA_CP2 = (27 << 21) | (0x0F) | OPC_CP2,
1094    OPC_BIADD    = (28 << 21) | (0x0F) | OPC_CP2,
1095    OPC_PMOVMSKB = (29 << 21) | (0x0F) | OPC_CP2,
1096};
1097
1098
1099#define MASK_CP3(op)       MASK_OP_MAJOR(op) | (op & 0x3F)
1100
1101enum {
1102    OPC_LWXC1   = 0x00 | OPC_CP3,
1103    OPC_LDXC1   = 0x01 | OPC_CP3,
1104    OPC_LUXC1   = 0x05 | OPC_CP3,
1105    OPC_SWXC1   = 0x08 | OPC_CP3,
1106    OPC_SDXC1   = 0x09 | OPC_CP3,
1107    OPC_SUXC1   = 0x0D | OPC_CP3,
1108    OPC_PREFX   = 0x0F | OPC_CP3,
1109    OPC_ALNV_PS = 0x1E | OPC_CP3,
1110    OPC_MADD_S  = 0x20 | OPC_CP3,
1111    OPC_MADD_D  = 0x21 | OPC_CP3,
1112    OPC_MADD_PS = 0x26 | OPC_CP3,
1113    OPC_MSUB_S  = 0x28 | OPC_CP3,
1114    OPC_MSUB_D  = 0x29 | OPC_CP3,
1115    OPC_MSUB_PS = 0x2E | OPC_CP3,
1116    OPC_NMADD_S = 0x30 | OPC_CP3,
1117    OPC_NMADD_D = 0x31 | OPC_CP3,
1118    OPC_NMADD_PS= 0x36 | OPC_CP3,
1119    OPC_NMSUB_S = 0x38 | OPC_CP3,
1120    OPC_NMSUB_D = 0x39 | OPC_CP3,
1121    OPC_NMSUB_PS= 0x3E | OPC_CP3,
1122};
1123
1124/* MSA Opcodes */
1125#define MASK_MSA_MINOR(op)    (MASK_OP_MAJOR(op) | (op & 0x3F))
1126enum {
1127    OPC_MSA_I8_00   = 0x00 | OPC_MSA,
1128    OPC_MSA_I8_01   = 0x01 | OPC_MSA,
1129    OPC_MSA_I8_02   = 0x02 | OPC_MSA,
1130    OPC_MSA_I5_06   = 0x06 | OPC_MSA,
1131    OPC_MSA_I5_07   = 0x07 | OPC_MSA,
1132    OPC_MSA_BIT_09  = 0x09 | OPC_MSA,
1133    OPC_MSA_BIT_0A  = 0x0A | OPC_MSA,
1134    OPC_MSA_3R_0D   = 0x0D | OPC_MSA,
1135    OPC_MSA_3R_0E   = 0x0E | OPC_MSA,
1136    OPC_MSA_3R_0F   = 0x0F | OPC_MSA,
1137    OPC_MSA_3R_10   = 0x10 | OPC_MSA,
1138    OPC_MSA_3R_11   = 0x11 | OPC_MSA,
1139    OPC_MSA_3R_12   = 0x12 | OPC_MSA,
1140    OPC_MSA_3R_13   = 0x13 | OPC_MSA,
1141    OPC_MSA_3R_14   = 0x14 | OPC_MSA,
1142    OPC_MSA_3R_15   = 0x15 | OPC_MSA,
1143    OPC_MSA_ELM     = 0x19 | OPC_MSA,
1144    OPC_MSA_3RF_1A  = 0x1A | OPC_MSA,
1145    OPC_MSA_3RF_1B  = 0x1B | OPC_MSA,
1146    OPC_MSA_3RF_1C  = 0x1C | OPC_MSA,
1147    OPC_MSA_VEC     = 0x1E | OPC_MSA,
1148
1149    /* MI10 instruction */
1150    OPC_LD_B    = (0x20) | OPC_MSA,
1151    OPC_LD_H    = (0x21) | OPC_MSA,
1152    OPC_LD_W    = (0x22) | OPC_MSA,
1153    OPC_LD_D    = (0x23) | OPC_MSA,
1154    OPC_ST_B    = (0x24) | OPC_MSA,
1155    OPC_ST_H    = (0x25) | OPC_MSA,
1156    OPC_ST_W    = (0x26) | OPC_MSA,
1157    OPC_ST_D    = (0x27) | OPC_MSA,
1158};
1159
1160enum {
1161    /* I5 instruction df(bits 22..21) = _b, _h, _w, _d */
1162    OPC_ADDVI_df    = (0x0 << 23) | OPC_MSA_I5_06,
1163    OPC_CEQI_df     = (0x0 << 23) | OPC_MSA_I5_07,
1164    OPC_SUBVI_df    = (0x1 << 23) | OPC_MSA_I5_06,
1165    OPC_MAXI_S_df   = (0x2 << 23) | OPC_MSA_I5_06,
1166    OPC_CLTI_S_df   = (0x2 << 23) | OPC_MSA_I5_07,
1167    OPC_MAXI_U_df   = (0x3 << 23) | OPC_MSA_I5_06,
1168    OPC_CLTI_U_df   = (0x3 << 23) | OPC_MSA_I5_07,
1169    OPC_MINI_S_df   = (0x4 << 23) | OPC_MSA_I5_06,
1170    OPC_CLEI_S_df   = (0x4 << 23) | OPC_MSA_I5_07,
1171    OPC_MINI_U_df   = (0x5 << 23) | OPC_MSA_I5_06,
1172    OPC_CLEI_U_df   = (0x5 << 23) | OPC_MSA_I5_07,
1173    OPC_LDI_df      = (0x6 << 23) | OPC_MSA_I5_07,
1174
1175    /* I8 instruction */
1176    OPC_ANDI_B  = (0x0 << 24) | OPC_MSA_I8_00,
1177    OPC_BMNZI_B = (0x0 << 24) | OPC_MSA_I8_01,
1178    OPC_SHF_B   = (0x0 << 24) | OPC_MSA_I8_02,
1179    OPC_ORI_B   = (0x1 << 24) | OPC_MSA_I8_00,
1180    OPC_BMZI_B  = (0x1 << 24) | OPC_MSA_I8_01,
1181    OPC_SHF_H   = (0x1 << 24) | OPC_MSA_I8_02,
1182    OPC_NORI_B  = (0x2 << 24) | OPC_MSA_I8_00,
1183    OPC_BSELI_B = (0x2 << 24) | OPC_MSA_I8_01,
1184    OPC_SHF_W   = (0x2 << 24) | OPC_MSA_I8_02,
1185    OPC_XORI_B  = (0x3 << 24) | OPC_MSA_I8_00,
1186
1187    /* VEC/2R/2RF instruction */
1188    OPC_AND_V   = (0x00 << 21) | OPC_MSA_VEC,
1189    OPC_OR_V    = (0x01 << 21) | OPC_MSA_VEC,
1190    OPC_NOR_V   = (0x02 << 21) | OPC_MSA_VEC,
1191    OPC_XOR_V   = (0x03 << 21) | OPC_MSA_VEC,
1192    OPC_BMNZ_V  = (0x04 << 21) | OPC_MSA_VEC,
1193    OPC_BMZ_V   = (0x05 << 21) | OPC_MSA_VEC,
1194    OPC_BSEL_V  = (0x06 << 21) | OPC_MSA_VEC,
1195
1196    OPC_MSA_2R      = (0x18 << 21) | OPC_MSA_VEC,
1197    OPC_MSA_2RF     = (0x19 << 21) | OPC_MSA_VEC,
1198
1199    /* 2R instruction df(bits 17..16) = _b, _h, _w, _d */
1200    OPC_FILL_df = (0x00 << 18) | OPC_MSA_2R,
1201    OPC_PCNT_df = (0x01 << 18) | OPC_MSA_2R,
1202    OPC_NLOC_df = (0x02 << 18) | OPC_MSA_2R,
1203    OPC_NLZC_df = (0x03 << 18) | OPC_MSA_2R,
1204
1205    /* 2RF instruction df(bit 16) = _w, _d */
1206    OPC_FCLASS_df   = (0x00 << 17) | OPC_MSA_2RF,
1207    OPC_FTRUNC_S_df = (0x01 << 17) | OPC_MSA_2RF,
1208    OPC_FTRUNC_U_df = (0x02 << 17) | OPC_MSA_2RF,
1209    OPC_FSQRT_df    = (0x03 << 17) | OPC_MSA_2RF,
1210    OPC_FRSQRT_df   = (0x04 << 17) | OPC_MSA_2RF,
1211    OPC_FRCP_df     = (0x05 << 17) | OPC_MSA_2RF,
1212    OPC_FRINT_df    = (0x06 << 17) | OPC_MSA_2RF,
1213    OPC_FLOG2_df    = (0x07 << 17) | OPC_MSA_2RF,
1214    OPC_FEXUPL_df   = (0x08 << 17) | OPC_MSA_2RF,
1215    OPC_FEXUPR_df   = (0x09 << 17) | OPC_MSA_2RF,
1216    OPC_FFQL_df     = (0x0A << 17) | OPC_MSA_2RF,
1217    OPC_FFQR_df     = (0x0B << 17) | OPC_MSA_2RF,
1218    OPC_FTINT_S_df  = (0x0C << 17) | OPC_MSA_2RF,
1219    OPC_FTINT_U_df  = (0x0D << 17) | OPC_MSA_2RF,
1220    OPC_FFINT_S_df  = (0x0E << 17) | OPC_MSA_2RF,
1221    OPC_FFINT_U_df  = (0x0F << 17) | OPC_MSA_2RF,
1222
1223    /* 3R instruction df(bits 22..21) = _b, _h, _w, d */
1224    OPC_SLL_df      = (0x0 << 23) | OPC_MSA_3R_0D,
1225    OPC_ADDV_df     = (0x0 << 23) | OPC_MSA_3R_0E,
1226    OPC_CEQ_df      = (0x0 << 23) | OPC_MSA_3R_0F,
1227    OPC_ADD_A_df    = (0x0 << 23) | OPC_MSA_3R_10,
1228    OPC_SUBS_S_df   = (0x0 << 23) | OPC_MSA_3R_11,
1229    OPC_MULV_df     = (0x0 << 23) | OPC_MSA_3R_12,
1230    OPC_DOTP_S_df   = (0x0 << 23) | OPC_MSA_3R_13,
1231    OPC_SLD_df      = (0x0 << 23) | OPC_MSA_3R_14,
1232    OPC_VSHF_df     = (0x0 << 23) | OPC_MSA_3R_15,
1233    OPC_SRA_df      = (0x1 << 23) | OPC_MSA_3R_0D,
1234    OPC_SUBV_df     = (0x1 << 23) | OPC_MSA_3R_0E,
1235    OPC_ADDS_A_df   = (0x1 << 23) | OPC_MSA_3R_10,
1236    OPC_SUBS_U_df   = (0x1 << 23) | OPC_MSA_3R_11,
1237    OPC_MADDV_df    = (0x1 << 23) | OPC_MSA_3R_12,
1238    OPC_DOTP_U_df   = (0x1 << 23) | OPC_MSA_3R_13,
1239    OPC_SPLAT_df    = (0x1 << 23) | OPC_MSA_3R_14,
1240    OPC_SRAR_df     = (0x1 << 23) | OPC_MSA_3R_15,
1241    OPC_SRL_df      = (0x2 << 23) | OPC_MSA_3R_0D,
1242    OPC_MAX_S_df    = (0x2 << 23) | OPC_MSA_3R_0E,
1243    OPC_CLT_S_df    = (0x2 << 23) | OPC_MSA_3R_0F,
1244    OPC_ADDS_S_df   = (0x2 << 23) | OPC_MSA_3R_10,
1245    OPC_SUBSUS_U_df = (0x2 << 23) | OPC_MSA_3R_11,
1246    OPC_MSUBV_df    = (0x2 << 23) | OPC_MSA_3R_12,
1247    OPC_DPADD_S_df  = (0x2 << 23) | OPC_MSA_3R_13,
1248    OPC_PCKEV_df    = (0x2 << 23) | OPC_MSA_3R_14,
1249    OPC_SRLR_df     = (0x2 << 23) | OPC_MSA_3R_15,
1250    OPC_BCLR_df     = (0x3 << 23) | OPC_MSA_3R_0D,
1251    OPC_MAX_U_df    = (0x3 << 23) | OPC_MSA_3R_0E,
1252    OPC_CLT_U_df    = (0x3 << 23) | OPC_MSA_3R_0F,
1253    OPC_ADDS_U_df   = (0x3 << 23) | OPC_MSA_3R_10,
1254    OPC_SUBSUU_S_df = (0x3 << 23) | OPC_MSA_3R_11,
1255    OPC_DPADD_U_df  = (0x3 << 23) | OPC_MSA_3R_13,
1256    OPC_PCKOD_df    = (0x3 << 23) | OPC_MSA_3R_14,
1257    OPC_BSET_df     = (0x4 << 23) | OPC_MSA_3R_0D,
1258    OPC_MIN_S_df    = (0x4 << 23) | OPC_MSA_3R_0E,
1259    OPC_CLE_S_df    = (0x4 << 23) | OPC_MSA_3R_0F,
1260    OPC_AVE_S_df    = (0x4 << 23) | OPC_MSA_3R_10,
1261    OPC_ASUB_S_df   = (0x4 << 23) | OPC_MSA_3R_11,
1262    OPC_DIV_S_df    = (0x4 << 23) | OPC_MSA_3R_12,
1263    OPC_DPSUB_S_df  = (0x4 << 23) | OPC_MSA_3R_13,
1264    OPC_ILVL_df     = (0x4 << 23) | OPC_MSA_3R_14,
1265    OPC_HADD_S_df   = (0x4 << 23) | OPC_MSA_3R_15,
1266    OPC_BNEG_df     = (0x5 << 23) | OPC_MSA_3R_0D,
1267    OPC_MIN_U_df    = (0x5 << 23) | OPC_MSA_3R_0E,
1268    OPC_CLE_U_df    = (0x5 << 23) | OPC_MSA_3R_0F,
1269    OPC_AVE_U_df    = (0x5 << 23) | OPC_MSA_3R_10,
1270    OPC_ASUB_U_df   = (0x5 << 23) | OPC_MSA_3R_11,
1271    OPC_DIV_U_df    = (0x5 << 23) | OPC_MSA_3R_12,
1272    OPC_DPSUB_U_df  = (0x5 << 23) | OPC_MSA_3R_13,
1273    OPC_ILVR_df     = (0x5 << 23) | OPC_MSA_3R_14,
1274    OPC_HADD_U_df   = (0x5 << 23) | OPC_MSA_3R_15,
1275    OPC_BINSL_df    = (0x6 << 23) | OPC_MSA_3R_0D,
1276    OPC_MAX_A_df    = (0x6 << 23) | OPC_MSA_3R_0E,
1277    OPC_AVER_S_df   = (0x6 << 23) | OPC_MSA_3R_10,
1278    OPC_MOD_S_df    = (0x6 << 23) | OPC_MSA_3R_12,
1279    OPC_ILVEV_df    = (0x6 << 23) | OPC_MSA_3R_14,
1280    OPC_HSUB_S_df   = (0x6 << 23) | OPC_MSA_3R_15,
1281    OPC_BINSR_df    = (0x7 << 23) | OPC_MSA_3R_0D,
1282    OPC_MIN_A_df    = (0x7 << 23) | OPC_MSA_3R_0E,
1283    OPC_AVER_U_df   = (0x7 << 23) | OPC_MSA_3R_10,
1284    OPC_MOD_U_df    = (0x7 << 23) | OPC_MSA_3R_12,
1285    OPC_ILVOD_df    = (0x7 << 23) | OPC_MSA_3R_14,
1286    OPC_HSUB_U_df   = (0x7 << 23) | OPC_MSA_3R_15,
1287
1288    /* ELM instructions df(bits 21..16) = _b, _h, _w, _d */
1289    OPC_SLDI_df     = (0x0 << 22) | (0x00 << 16) | OPC_MSA_ELM,
1290    OPC_CTCMSA      = (0x0 << 22) | (0x3E << 16) | OPC_MSA_ELM,
1291    OPC_SPLATI_df   = (0x1 << 22) | (0x00 << 16) | OPC_MSA_ELM,
1292    OPC_CFCMSA      = (0x1 << 22) | (0x3E << 16) | OPC_MSA_ELM,
1293    OPC_COPY_S_df   = (0x2 << 22) | (0x00 << 16) | OPC_MSA_ELM,
1294    OPC_MOVE_V      = (0x2 << 22) | (0x3E << 16) | OPC_MSA_ELM,
1295    OPC_COPY_U_df   = (0x3 << 22) | (0x00 << 16) | OPC_MSA_ELM,
1296    OPC_INSERT_df   = (0x4 << 22) | (0x00 << 16) | OPC_MSA_ELM,
1297    OPC_INSVE_df    = (0x5 << 22) | (0x00 << 16) | OPC_MSA_ELM,
1298
1299    /* 3RF instruction _df(bit 21) = _w, _d */
1300    OPC_FCAF_df     = (0x0 << 22) | OPC_MSA_3RF_1A,
1301    OPC_FADD_df     = (0x0 << 22) | OPC_MSA_3RF_1B,
1302    OPC_FCUN_df     = (0x1 << 22) | OPC_MSA_3RF_1A,
1303    OPC_FSUB_df     = (0x1 << 22) | OPC_MSA_3RF_1B,
1304    OPC_FCOR_df     = (0x1 << 22) | OPC_MSA_3RF_1C,
1305    OPC_FCEQ_df     = (0x2 << 22) | OPC_MSA_3RF_1A,
1306    OPC_FMUL_df     = (0x2 << 22) | OPC_MSA_3RF_1B,
1307    OPC_FCUNE_df    = (0x2 << 22) | OPC_MSA_3RF_1C,
1308    OPC_FCUEQ_df    = (0x3 << 22) | OPC_MSA_3RF_1A,
1309    OPC_FDIV_df     = (0x3 << 22) | OPC_MSA_3RF_1B,
1310    OPC_FCNE_df     = (0x3 << 22) | OPC_MSA_3RF_1C,
1311    OPC_FCLT_df     = (0x4 << 22) | OPC_MSA_3RF_1A,
1312    OPC_FMADD_df    = (0x4 << 22) | OPC_MSA_3RF_1B,
1313    OPC_MUL_Q_df    = (0x4 << 22) | OPC_MSA_3RF_1C,
1314    OPC_FCULT_df    = (0x5 << 22) | OPC_MSA_3RF_1A,
1315    OPC_FMSUB_df    = (0x5 << 22) | OPC_MSA_3RF_1B,
1316    OPC_MADD_Q_df   = (0x5 << 22) | OPC_MSA_3RF_1C,
1317    OPC_FCLE_df     = (0x6 << 22) | OPC_MSA_3RF_1A,
1318    OPC_MSUB_Q_df   = (0x6 << 22) | OPC_MSA_3RF_1C,
1319    OPC_FCULE_df    = (0x7 << 22) | OPC_MSA_3RF_1A,
1320    OPC_FEXP2_df    = (0x7 << 22) | OPC_MSA_3RF_1B,
1321    OPC_FSAF_df     = (0x8 << 22) | OPC_MSA_3RF_1A,
1322    OPC_FEXDO_df    = (0x8 << 22) | OPC_MSA_3RF_1B,
1323    OPC_FSUN_df     = (0x9 << 22) | OPC_MSA_3RF_1A,
1324    OPC_FSOR_df     = (0x9 << 22) | OPC_MSA_3RF_1C,
1325    OPC_FSEQ_df     = (0xA << 22) | OPC_MSA_3RF_1A,
1326    OPC_FTQ_df      = (0xA << 22) | OPC_MSA_3RF_1B,
1327    OPC_FSUNE_df    = (0xA << 22) | OPC_MSA_3RF_1C,
1328    OPC_FSUEQ_df    = (0xB << 22) | OPC_MSA_3RF_1A,
1329    OPC_FSNE_df     = (0xB << 22) | OPC_MSA_3RF_1C,
1330    OPC_FSLT_df     = (0xC << 22) | OPC_MSA_3RF_1A,
1331    OPC_FMIN_df     = (0xC << 22) | OPC_MSA_3RF_1B,
1332    OPC_MULR_Q_df   = (0xC << 22) | OPC_MSA_3RF_1C,
1333    OPC_FSULT_df    = (0xD << 22) | OPC_MSA_3RF_1A,
1334    OPC_FMIN_A_df   = (0xD << 22) | OPC_MSA_3RF_1B,
1335    OPC_MADDR_Q_df  = (0xD << 22) | OPC_MSA_3RF_1C,
1336    OPC_FSLE_df     = (0xE << 22) | OPC_MSA_3RF_1A,
1337    OPC_FMAX_df     = (0xE << 22) | OPC_MSA_3RF_1B,
1338    OPC_MSUBR_Q_df  = (0xE << 22) | OPC_MSA_3RF_1C,
1339    OPC_FSULE_df    = (0xF << 22) | OPC_MSA_3RF_1A,
1340    OPC_FMAX_A_df   = (0xF << 22) | OPC_MSA_3RF_1B,
1341
1342    /* BIT instruction df(bits 22..16) = _B _H _W _D */
1343    OPC_SLLI_df     = (0x0 << 23) | OPC_MSA_BIT_09,
1344    OPC_SAT_S_df    = (0x0 << 23) | OPC_MSA_BIT_0A,
1345    OPC_SRAI_df     = (0x1 << 23) | OPC_MSA_BIT_09,
1346    OPC_SAT_U_df    = (0x1 << 23) | OPC_MSA_BIT_0A,
1347    OPC_SRLI_df     = (0x2 << 23) | OPC_MSA_BIT_09,
1348    OPC_SRARI_df    = (0x2 << 23) | OPC_MSA_BIT_0A,
1349    OPC_BCLRI_df    = (0x3 << 23) | OPC_MSA_BIT_09,
1350    OPC_SRLRI_df    = (0x3 << 23) | OPC_MSA_BIT_0A,
1351    OPC_BSETI_df    = (0x4 << 23) | OPC_MSA_BIT_09,
1352    OPC_BNEGI_df    = (0x5 << 23) | OPC_MSA_BIT_09,
1353    OPC_BINSLI_df   = (0x6 << 23) | OPC_MSA_BIT_09,
1354    OPC_BINSRI_df   = (0x7 << 23) | OPC_MSA_BIT_09,
1355};
1356
1357/* global register indices */
1358static TCGv_env cpu_env;
1359static TCGv cpu_gpr[32], cpu_PC;
1360static TCGv cpu_HI[MIPS_DSP_ACC], cpu_LO[MIPS_DSP_ACC];
1361static TCGv cpu_dspctrl, btarget, bcond;
1362static TCGv_i32 hflags;
1363static TCGv_i32 fpu_fcr0, fpu_fcr31;
1364static TCGv_i64 fpu_f64[32];
1365static TCGv_i64 msa_wr_d[64];
1366
1367#include "exec/gen-icount.h"
1368
1369#define gen_helper_0e0i(name, arg) do {                           \
1370    TCGv_i32 helper_tmp = tcg_const_i32(arg);                     \
1371    gen_helper_##name(cpu_env, helper_tmp);                       \
1372    tcg_temp_free_i32(helper_tmp);                                \
1373    } while(0)
1374
1375#define gen_helper_0e1i(name, arg1, arg2) do {                    \
1376    TCGv_i32 helper_tmp = tcg_const_i32(arg2);                    \
1377    gen_helper_##name(cpu_env, arg1, helper_tmp);                 \
1378    tcg_temp_free_i32(helper_tmp);                                \
1379    } while(0)
1380
1381#define gen_helper_1e0i(name, ret, arg1) do {                     \
1382    TCGv_i32 helper_tmp = tcg_const_i32(arg1);                    \
1383    gen_helper_##name(ret, cpu_env, helper_tmp);                  \
1384    tcg_temp_free_i32(helper_tmp);                                \
1385    } while(0)
1386
1387#define gen_helper_1e1i(name, ret, arg1, arg2) do {               \
1388    TCGv_i32 helper_tmp = tcg_const_i32(arg2);                    \
1389    gen_helper_##name(ret, cpu_env, arg1, helper_tmp);            \
1390    tcg_temp_free_i32(helper_tmp);                                \
1391    } while(0)
1392
1393#define gen_helper_0e2i(name, arg1, arg2, arg3) do {              \
1394    TCGv_i32 helper_tmp = tcg_const_i32(arg3);                    \
1395    gen_helper_##name(cpu_env, arg1, arg2, helper_tmp);           \
1396    tcg_temp_free_i32(helper_tmp);                                \
1397    } while(0)
1398
1399#define gen_helper_1e2i(name, ret, arg1, arg2, arg3) do {         \
1400    TCGv_i32 helper_tmp = tcg_const_i32(arg3);                    \
1401    gen_helper_##name(ret, cpu_env, arg1, arg2, helper_tmp);      \
1402    tcg_temp_free_i32(helper_tmp);                                \
1403    } while(0)
1404
1405#define gen_helper_0e3i(name, arg1, arg2, arg3, arg4) do {        \
1406    TCGv_i32 helper_tmp = tcg_const_i32(arg4);                    \
1407    gen_helper_##name(cpu_env, arg1, arg2, arg3, helper_tmp);     \
1408    tcg_temp_free_i32(helper_tmp);                                \
1409    } while(0)
1410
1411typedef struct DisasContext {
1412    struct TranslationBlock *tb;
1413    target_ulong pc, saved_pc;
1414    uint32_t opcode;
1415    int singlestep_enabled;
1416    int insn_flags;
1417    int32_t CP0_Config1;
1418    /* Routine used to access memory */
1419    int mem_idx;
1420    TCGMemOp default_tcg_memop_mask;
1421    uint32_t hflags, saved_hflags;
1422    int bstate;
1423    target_ulong btarget;
1424    bool ulri;
1425    int kscrexist;
1426    bool rxi;
1427    int ie;
1428    bool bi;
1429    bool bp;
1430    uint64_t PAMask;
1431    bool mvh;
1432    int CP0_LLAddr_shift;
1433    bool ps;
1434    bool vp;
1435    bool cmgcr;
1436    bool mrp;
1437} DisasContext;
1438
1439enum {
1440    BS_NONE     = 0, /* We go out of the TB without reaching a branch or an
1441                      * exception condition */
1442    BS_STOP     = 1, /* We want to stop translation for any reason */
1443    BS_BRANCH   = 2, /* We reached a branch condition     */
1444    BS_EXCP     = 3, /* We reached an exception condition */
1445};
1446
1447static const char * const regnames[] = {
1448    "r0", "at", "v0", "v1", "a0", "a1", "a2", "a3",
1449    "t0", "t1", "t2", "t3", "t4", "t5", "t6", "t7",
1450    "s0", "s1", "s2", "s3", "s4", "s5", "s6", "s7",
1451    "t8", "t9", "k0", "k1", "gp", "sp", "s8", "ra",
1452};
1453
1454static const char * const regnames_HI[] = {
1455    "HI0", "HI1", "HI2", "HI3",
1456};
1457
1458static const char * const regnames_LO[] = {
1459    "LO0", "LO1", "LO2", "LO3",
1460};
1461
1462static const char * const fregnames[] = {
1463    "f0",  "f1",  "f2",  "f3",  "f4",  "f5",  "f6",  "f7",
1464    "f8",  "f9",  "f10", "f11", "f12", "f13", "f14", "f15",
1465    "f16", "f17", "f18", "f19", "f20", "f21", "f22", "f23",
1466    "f24", "f25", "f26", "f27", "f28", "f29", "f30", "f31",
1467};
1468
1469static const char * const msaregnames[] = {
1470    "w0.d0",  "w0.d1",  "w1.d0",  "w1.d1",
1471    "w2.d0",  "w2.d1",  "w3.d0",  "w3.d1",
1472    "w4.d0",  "w4.d1",  "w5.d0",  "w5.d1",
1473    "w6.d0",  "w6.d1",  "w7.d0",  "w7.d1",
1474    "w8.d0",  "w8.d1",  "w9.d0",  "w9.d1",
1475    "w10.d0", "w10.d1", "w11.d0", "w11.d1",
1476    "w12.d0", "w12.d1", "w13.d0", "w13.d1",
1477    "w14.d0", "w14.d1", "w15.d0", "w15.d1",
1478    "w16.d0", "w16.d1", "w17.d0", "w17.d1",
1479    "w18.d0", "w18.d1", "w19.d0", "w19.d1",
1480    "w20.d0", "w20.d1", "w21.d0", "w21.d1",
1481    "w22.d0", "w22.d1", "w23.d0", "w23.d1",
1482    "w24.d0", "w24.d1", "w25.d0", "w25.d1",
1483    "w26.d0", "w26.d1", "w27.d0", "w27.d1",
1484    "w28.d0", "w28.d1", "w29.d0", "w29.d1",
1485    "w30.d0", "w30.d1", "w31.d0", "w31.d1",
1486};
1487
1488#define LOG_DISAS(...)                                                        \
1489    do {                                                                      \
1490        if (MIPS_DEBUG_DISAS) {                                               \
1491            qemu_log_mask(CPU_LOG_TB_IN_ASM, ## __VA_ARGS__);                 \
1492        }                                                                     \
1493    } while (0)
1494
1495#define MIPS_INVAL(op)                                                        \
1496    do {                                                                      \
1497        if (MIPS_DEBUG_DISAS) {                                               \
1498            qemu_log_mask(CPU_LOG_TB_IN_ASM,                                  \
1499                          TARGET_FMT_lx ": %08x Invalid %s %03x %03x %03x\n", \
1500                          ctx->pc, ctx->opcode, op, ctx->opcode >> 26,        \
1501                          ctx->opcode & 0x3F, ((ctx->opcode >> 16) & 0x1F));  \
1502        }                                                                     \
1503    } while (0)
1504
1505/* General purpose registers moves. */
1506static inline void gen_load_gpr (TCGv t, int reg)
1507{
1508    if (reg == 0)
1509        tcg_gen_movi_tl(t, 0);
1510    else
1511        tcg_gen_mov_tl(t, cpu_gpr[reg]);
1512}
1513
1514static inline void gen_store_gpr (TCGv t, int reg)
1515{
1516    if (reg != 0)
1517        tcg_gen_mov_tl(cpu_gpr[reg], t);
1518}
1519
1520/* Moves to/from shadow registers. */
1521static inline void gen_load_srsgpr (int from, int to)
1522{
1523    TCGv t0 = tcg_temp_new();
1524
1525    if (from == 0)
1526        tcg_gen_movi_tl(t0, 0);
1527    else {
1528        TCGv_i32 t2 = tcg_temp_new_i32();
1529        TCGv_ptr addr = tcg_temp_new_ptr();
1530
1531        tcg_gen_ld_i32(t2, cpu_env, offsetof(CPUMIPSState, CP0_SRSCtl));
1532        tcg_gen_shri_i32(t2, t2, CP0SRSCtl_PSS);
1533        tcg_gen_andi_i32(t2, t2, 0xf);
1534        tcg_gen_muli_i32(t2, t2, sizeof(target_ulong) * 32);
1535        tcg_gen_ext_i32_ptr(addr, t2);
1536        tcg_gen_add_ptr(addr, cpu_env, addr);
1537
1538        tcg_gen_ld_tl(t0, addr, sizeof(target_ulong) * from);
1539        tcg_temp_free_ptr(addr);
1540        tcg_temp_free_i32(t2);
1541    }
1542    gen_store_gpr(t0, to);
1543    tcg_temp_free(t0);
1544}
1545
1546static inline void gen_store_srsgpr (int from, int to)
1547{
1548    if (to != 0) {
1549        TCGv t0 = tcg_temp_new();
1550        TCGv_i32 t2 = tcg_temp_new_i32();
1551        TCGv_ptr addr = tcg_temp_new_ptr();
1552
1553        gen_load_gpr(t0, from);
1554        tcg_gen_ld_i32(t2, cpu_env, offsetof(CPUMIPSState, CP0_SRSCtl));
1555        tcg_gen_shri_i32(t2, t2, CP0SRSCtl_PSS);
1556        tcg_gen_andi_i32(t2, t2, 0xf);
1557        tcg_gen_muli_i32(t2, t2, sizeof(target_ulong) * 32);
1558        tcg_gen_ext_i32_ptr(addr, t2);
1559        tcg_gen_add_ptr(addr, cpu_env, addr);
1560
1561        tcg_gen_st_tl(t0, addr, sizeof(target_ulong) * to);
1562        tcg_temp_free_ptr(addr);
1563        tcg_temp_free_i32(t2);
1564        tcg_temp_free(t0);
1565    }
1566}
1567
1568/* Tests */
1569static inline void gen_save_pc(target_ulong pc)
1570{
1571    tcg_gen_movi_tl(cpu_PC, pc);
1572}
1573
1574static inline void save_cpu_state(DisasContext *ctx, int do_save_pc)
1575{
1576    LOG_DISAS("hflags %08x saved %08x\n", ctx->hflags, ctx->saved_hflags);
1577    if (do_save_pc && ctx->pc != ctx->saved_pc) {
1578        gen_save_pc(ctx->pc);
1579        ctx->saved_pc = ctx->pc;
1580    }
1581    if (ctx->hflags != ctx->saved_hflags) {
1582        tcg_gen_movi_i32(hflags, ctx->hflags);
1583        ctx->saved_hflags = ctx->hflags;
1584        switch (ctx->hflags & MIPS_HFLAG_BMASK_BASE) {
1585        case MIPS_HFLAG_BR:
1586            break;
1587        case MIPS_HFLAG_BC:
1588        case MIPS_HFLAG_BL:
1589        case MIPS_HFLAG_B:
1590            tcg_gen_movi_tl(btarget, ctx->btarget);
1591            break;
1592        }
1593    }
1594}
1595
1596static inline void restore_cpu_state(CPUMIPSState *env, DisasContext *ctx)
1597{
1598    ctx->saved_hflags = ctx->hflags;
1599    switch (ctx->hflags & MIPS_HFLAG_BMASK_BASE) {
1600    case MIPS_HFLAG_BR:
1601        break;
1602    case MIPS_HFLAG_BC:
1603    case MIPS_HFLAG_BL:
1604    case MIPS_HFLAG_B:
1605        ctx->btarget = env->btarget;
1606        break;
1607    }
1608}
1609
1610static inline void generate_exception_err(DisasContext *ctx, int excp, int err)
1611{
1612    TCGv_i32 texcp = tcg_const_i32(excp);
1613    TCGv_i32 terr = tcg_const_i32(err);
1614    save_cpu_state(ctx, 1);
1615    gen_helper_raise_exception_err(cpu_env, texcp, terr);
1616    tcg_temp_free_i32(terr);
1617    tcg_temp_free_i32(texcp);
1618    ctx->bstate = BS_EXCP;
1619}
1620
1621static inline void generate_exception(DisasContext *ctx, int excp)
1622{
1623    gen_helper_0e0i(raise_exception, excp);
1624}
1625
1626static inline void generate_exception_end(DisasContext *ctx, int excp)
1627{
1628    generate_exception_err(ctx, excp, 0);
1629}
1630
1631/* Floating point register moves. */
1632static void gen_load_fpr32(DisasContext *ctx, TCGv_i32 t, int reg)
1633{
1634    if (ctx->hflags & MIPS_HFLAG_FRE) {
1635        generate_exception(ctx, EXCP_RI);
1636    }
1637    tcg_gen_extrl_i64_i32(t, fpu_f64[reg]);
1638}
1639
1640static void gen_store_fpr32(DisasContext *ctx, TCGv_i32 t, int reg)
1641{
1642    TCGv_i64 t64;
1643    if (ctx->hflags & MIPS_HFLAG_FRE) {
1644        generate_exception(ctx, EXCP_RI);
1645    }
1646    t64 = tcg_temp_new_i64();
1647    tcg_gen_extu_i32_i64(t64, t);
1648    tcg_gen_deposit_i64(fpu_f64[reg], fpu_f64[reg], t64, 0, 32);
1649    tcg_temp_free_i64(t64);
1650}
1651
1652static void gen_load_fpr32h(DisasContext *ctx, TCGv_i32 t, int reg)
1653{
1654    if (ctx->hflags & MIPS_HFLAG_F64) {
1655        tcg_gen_extrh_i64_i32(t, fpu_f64[reg]);
1656    } else {
1657        gen_load_fpr32(ctx, t, reg | 1);
1658    }
1659}
1660
1661static void gen_store_fpr32h(DisasContext *ctx, TCGv_i32 t, int reg)
1662{
1663    if (ctx->hflags & MIPS_HFLAG_F64) {
1664        TCGv_i64 t64 = tcg_temp_new_i64();
1665        tcg_gen_extu_i32_i64(t64, t);
1666        tcg_gen_deposit_i64(fpu_f64[reg], fpu_f64[reg], t64, 32, 32);
1667        tcg_temp_free_i64(t64);
1668    } else {
1669        gen_store_fpr32(ctx, t, reg | 1);
1670    }
1671}
1672
1673static void gen_load_fpr64(DisasContext *ctx, TCGv_i64 t, int reg)
1674{
1675    if (ctx->hflags & MIPS_HFLAG_F64) {
1676        tcg_gen_mov_i64(t, fpu_f64[reg]);
1677    } else {
1678        tcg_gen_concat32_i64(t, fpu_f64[reg & ~1], fpu_f64[reg | 1]);
1679    }
1680}
1681
1682static void gen_store_fpr64(DisasContext *ctx, TCGv_i64 t, int reg)
1683{
1684    if (ctx->hflags & MIPS_HFLAG_F64) {
1685        tcg_gen_mov_i64(fpu_f64[reg], t);
1686    } else {
1687        TCGv_i64 t0;
1688        tcg_gen_deposit_i64(fpu_f64[reg & ~1], fpu_f64[reg & ~1], t, 0, 32);
1689        t0 = tcg_temp_new_i64();
1690        tcg_gen_shri_i64(t0, t, 32);
1691        tcg_gen_deposit_i64(fpu_f64[reg | 1], fpu_f64[reg | 1], t0, 0, 32);
1692        tcg_temp_free_i64(t0);
1693    }
1694}
1695
1696static inline int get_fp_bit (int cc)
1697{
1698    if (cc)
1699        return 24 + cc;
1700    else
1701        return 23;
1702}
1703
1704/* Addresses computation */
1705static inline void gen_op_addr_add (DisasContext *ctx, TCGv ret, TCGv arg0, TCGv arg1)
1706{
1707    tcg_gen_add_tl(ret, arg0, arg1);
1708
1709#if defined(TARGET_MIPS64)
1710    if (ctx->hflags & MIPS_HFLAG_AWRAP) {
1711        tcg_gen_ext32s_i64(ret, ret);
1712    }
1713#endif
1714}
1715
1716/* Addresses computation (translation time) */
1717static target_long addr_add(DisasContext *ctx, target_long base,
1718                            target_long offset)
1719{
1720    target_long sum = base + offset;
1721
1722#if defined(TARGET_MIPS64)
1723    if (ctx->hflags & MIPS_HFLAG_AWRAP) {
1724        sum = (int32_t)sum;
1725    }
1726#endif
1727    return sum;
1728}
1729
1730/* Sign-extract the low 32-bits to a target_long.  */
1731static inline void gen_move_low32(TCGv ret, TCGv_i64 arg)
1732{
1733#if defined(TARGET_MIPS64)
1734    tcg_gen_ext32s_i64(ret, arg);
1735#else
1736    tcg_gen_extrl_i64_i32(ret, arg);
1737#endif
1738}
1739
1740/* Sign-extract the high 32-bits to a target_long.  */
1741static inline void gen_move_high32(TCGv ret, TCGv_i64 arg)
1742{
1743#if defined(TARGET_MIPS64)
1744    tcg_gen_sari_i64(ret, arg, 32);
1745#else
1746    tcg_gen_extrh_i64_i32(ret, arg);
1747#endif
1748}
1749
1750static inline void check_cp0_enabled(DisasContext *ctx)
1751{
1752    if (unlikely(!(ctx->hflags & MIPS_HFLAG_CP0)))
1753        generate_exception_err(ctx, EXCP_CpU, 0);
1754}
1755
1756static inline void check_cp1_enabled(DisasContext *ctx)
1757{
1758    if (unlikely(!(ctx->hflags & MIPS_HFLAG_FPU)))
1759        generate_exception_err(ctx, EXCP_CpU, 1);
1760}
1761
1762/* Verify that the processor is running with COP1X instructions enabled.
1763   This is associated with the nabla symbol in the MIPS32 and MIPS64
1764   opcode tables.  */
1765
1766static inline void check_cop1x(DisasContext *ctx)
1767{
1768    if (unlikely(!(ctx->hflags & MIPS_HFLAG_COP1X)))
1769        generate_exception_end(ctx, EXCP_RI);
1770}
1771
1772/* Verify that the processor is running with 64-bit floating-point
1773   operations enabled.  */
1774
1775static inline void check_cp1_64bitmode(DisasContext *ctx)
1776{
1777    if (unlikely(~ctx->hflags & (MIPS_HFLAG_F64 | MIPS_HFLAG_COP1X)))
1778        generate_exception_end(ctx, EXCP_RI);
1779}
1780
1781/*
1782 * Verify if floating point register is valid; an operation is not defined
1783 * if bit 0 of any register specification is set and the FR bit in the
1784 * Status register equals zero, since the register numbers specify an
1785 * even-odd pair of adjacent coprocessor general registers. When the FR bit
1786 * in the Status register equals one, both even and odd register numbers
1787 * are valid. This limitation exists only for 64 bit wide (d,l,ps) registers.
1788 *
1789 * Multiple 64 bit wide registers can be checked by calling
1790 * gen_op_cp1_registers(freg1 | freg2 | ... | fregN);
1791 */
1792static inline void check_cp1_registers(DisasContext *ctx, int regs)
1793{
1794    if (unlikely(!(ctx->hflags & MIPS_HFLAG_F64) && (regs & 1)))
1795        generate_exception_end(ctx, EXCP_RI);
1796}
1797
1798/* Verify that the processor is running with DSP instructions enabled.
1799   This is enabled by CP0 Status register MX(24) bit.
1800 */
1801
1802static inline void check_dsp(DisasContext *ctx)
1803{
1804    if (unlikely(!(ctx->hflags & MIPS_HFLAG_DSP))) {
1805        if (ctx->insn_flags & ASE_DSP) {
1806            generate_exception_end(ctx, EXCP_DSPDIS);
1807        } else {
1808            generate_exception_end(ctx, EXCP_RI);
1809        }
1810    }
1811}
1812
1813static inline void check_dspr2(DisasContext *ctx)
1814{
1815    if (unlikely(!(ctx->hflags & MIPS_HFLAG_DSPR2))) {
1816        if (ctx->insn_flags & ASE_DSP) {
1817            generate_exception_end(ctx, EXCP_DSPDIS);
1818        } else {
1819            generate_exception_end(ctx, EXCP_RI);
1820        }
1821    }
1822}
1823
1824/* This code generates a "reserved instruction" exception if the
1825   CPU does not support the instruction set corresponding to flags. */
1826static inline void check_insn(DisasContext *ctx, int flags)
1827{
1828    if (unlikely(!(ctx->insn_flags & flags))) {
1829        generate_exception_end(ctx, EXCP_RI);
1830    }
1831}
1832
1833/* This code generates a "reserved instruction" exception if the
1834   CPU has corresponding flag set which indicates that the instruction
1835   has been removed. */
1836static inline void check_insn_opc_removed(DisasContext *ctx, int flags)
1837{
1838    if (unlikely(ctx->insn_flags & flags)) {
1839        generate_exception_end(ctx, EXCP_RI);
1840    }
1841}
1842
1843/* This code generates a "reserved instruction" exception if the
1844   CPU does not support 64-bit paired-single (PS) floating point data type */
1845static inline void check_ps(DisasContext *ctx)
1846{
1847    if (unlikely(!ctx->ps)) {
1848        generate_exception(ctx, EXCP_RI);
1849    }
1850    check_cp1_64bitmode(ctx);
1851}
1852
1853#ifdef TARGET_MIPS64
1854/* This code generates a "reserved instruction" exception if 64-bit
1855   instructions are not enabled. */
1856static inline void check_mips_64(DisasContext *ctx)
1857{
1858    if (unlikely(!(ctx->hflags & MIPS_HFLAG_64)))
1859        generate_exception_end(ctx, EXCP_RI);
1860}
1861#endif
1862
1863#ifndef CONFIG_USER_ONLY
1864static inline void check_mvh(DisasContext *ctx)
1865{
1866    if (unlikely(!ctx->mvh)) {
1867        generate_exception(ctx, EXCP_RI);
1868    }
1869}
1870#endif
1871
1872/* Define small wrappers for gen_load_fpr* so that we have a uniform
1873   calling interface for 32 and 64-bit FPRs.  No sense in changing
1874   all callers for gen_load_fpr32 when we need the CTX parameter for
1875   this one use.  */
1876#define gen_ldcmp_fpr32(ctx, x, y) gen_load_fpr32(ctx, x, y)
1877#define gen_ldcmp_fpr64(ctx, x, y) gen_load_fpr64(ctx, x, y)
1878#define FOP_CONDS(type, abs, fmt, ifmt, bits)                                 \
1879static inline void gen_cmp ## type ## _ ## fmt(DisasContext *ctx, int n,      \
1880                                               int ft, int fs, int cc)        \
1881{                                                                             \
1882    TCGv_i##bits fp0 = tcg_temp_new_i##bits ();                               \
1883    TCGv_i##bits fp1 = tcg_temp_new_i##bits ();                               \
1884    switch (ifmt) {                                                           \
1885    case FMT_PS:                                                              \
1886        check_ps(ctx);                                                        \
1887        break;                                                                \
1888    case FMT_D:                                                               \
1889        if (abs) {                                                            \
1890            check_cop1x(ctx);                                                 \
1891        }                                                                     \
1892        check_cp1_registers(ctx, fs | ft);                                    \
1893        break;                                                                \
1894    case FMT_S:                                                               \
1895        if (abs) {                                                            \
1896            check_cop1x(ctx);                                                 \
1897        }                                                                     \
1898        break;                                                                \
1899    }                                                                         \
1900    gen_ldcmp_fpr##bits (ctx, fp0, fs);                                       \
1901    gen_ldcmp_fpr##bits (ctx, fp1, ft);                                       \
1902    switch (n) {                                                              \
1903    case  0: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _f, fp0, fp1, cc);    break;\
1904    case  1: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _un, fp0, fp1, cc);   break;\
1905    case  2: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _eq, fp0, fp1, cc);   break;\
1906    case  3: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ueq, fp0, fp1, cc);  break;\
1907    case  4: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _olt, fp0, fp1, cc);  break;\
1908    case  5: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ult, fp0, fp1, cc);  break;\
1909    case  6: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ole, fp0, fp1, cc);  break;\
1910    case  7: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ule, fp0, fp1, cc);  break;\
1911    case  8: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _sf, fp0, fp1, cc);   break;\
1912    case  9: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ngle, fp0, fp1, cc); break;\
1913    case 10: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _seq, fp0, fp1, cc);  break;\
1914    case 11: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ngl, fp0, fp1, cc);  break;\
1915    case 12: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _lt, fp0, fp1, cc);   break;\
1916    case 13: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _nge, fp0, fp1, cc);  break;\
1917    case 14: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _le, fp0, fp1, cc);   break;\
1918    case 15: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ngt, fp0, fp1, cc);  break;\
1919    default: abort();                                                         \
1920    }                                                                         \
1921    tcg_temp_free_i##bits (fp0);                                              \
1922    tcg_temp_free_i##bits (fp1);                                              \
1923}
1924
1925FOP_CONDS(, 0, d, FMT_D, 64)
1926FOP_CONDS(abs, 1, d, FMT_D, 64)
1927FOP_CONDS(, 0, s, FMT_S, 32)
1928FOP_CONDS(abs, 1, s, FMT_S, 32)
1929FOP_CONDS(, 0, ps, FMT_PS, 64)
1930FOP_CONDS(abs, 1, ps, FMT_PS, 64)
1931#undef FOP_CONDS
1932
1933#define FOP_CONDNS(fmt, ifmt, bits, STORE)                              \
1934static inline void gen_r6_cmp_ ## fmt(DisasContext * ctx, int n,        \
1935                                      int ft, int fs, int fd)           \
1936{                                                                       \
1937    TCGv_i ## bits fp0 = tcg_temp_new_i ## bits();                      \
1938    TCGv_i ## bits fp1 = tcg_temp_new_i ## bits();                      \
1939    if (ifmt == FMT_D) {                                                \
1940        check_cp1_registers(ctx, fs | ft | fd);                         \
1941    }                                                                   \
1942    gen_ldcmp_fpr ## bits(ctx, fp0, fs);                                \
1943    gen_ldcmp_fpr ## bits(ctx, fp1, ft);                                \
1944    switch (n) {                                                        \
1945    case  0:                                                            \
1946        gen_helper_r6_cmp_ ## fmt ## _af(fp0, cpu_env, fp0, fp1);       \
1947        break;                                                          \
1948    case  1:                                                            \
1949        gen_helper_r6_cmp_ ## fmt ## _un(fp0, cpu_env, fp0, fp1);       \
1950        break;                                                          \
1951    case  2:                                                            \
1952        gen_helper_r6_cmp_ ## fmt ## _eq(fp0, cpu_env, fp0, fp1);       \
1953        break;                                                          \
1954    case  3:                                                            \
1955        gen_helper_r6_cmp_ ## fmt ## _ueq(fp0, cpu_env, fp0, fp1);      \
1956        break;                                                          \
1957    case  4:                                                            \
1958        gen_helper_r6_cmp_ ## fmt ## _lt(fp0, cpu_env, fp0, fp1);       \
1959        break;                                                          \
1960    case  5:                                                            \
1961        gen_helper_r6_cmp_ ## fmt ## _ult(fp0, cpu_env, fp0, fp1);      \
1962        break;                                                          \
1963    case  6:                                                            \
1964        gen_helper_r6_cmp_ ## fmt ## _le(fp0, cpu_env, fp0, fp1);       \
1965        break;                                                          \
1966    case  7:                                                            \
1967        gen_helper_r6_cmp_ ## fmt ## _ule(fp0, cpu_env, fp0, fp1);      \
1968        break;                                                          \
1969    case  8:                                                            \
1970        gen_helper_r6_cmp_ ## fmt ## _saf(fp0, cpu_env, fp0, fp1);      \
1971        break;                                                          \
1972    case  9:                                                            \
1973        gen_helper_r6_cmp_ ## fmt ## _sun(fp0, cpu_env, fp0, fp1);      \
1974        break;                                                          \
1975    case 10:                                                            \
1976        gen_helper_r6_cmp_ ## fmt ## _seq(fp0, cpu_env, fp0, fp1);      \
1977        break;                                                          \
1978    case 11:                                                            \
1979        gen_helper_r6_cmp_ ## fmt ## _sueq(fp0, cpu_env, fp0, fp1);     \
1980        break;                                                          \
1981    case 12:                                                            \
1982        gen_helper_r6_cmp_ ## fmt ## _slt(fp0, cpu_env, fp0, fp1);      \
1983        break;                                                          \
1984    case 13:                                                            \
1985        gen_helper_r6_cmp_ ## fmt ## _sult(fp0, cpu_env, fp0, fp1);     \
1986        break;                                                          \
1987    case 14:                                                            \
1988        gen_helper_r6_cmp_ ## fmt ## _sle(fp0, cpu_env, fp0, fp1);      \
1989        break;                                                          \
1990    case 15:                                                            \
1991        gen_helper_r6_cmp_ ## fmt ## _sule(fp0, cpu_env, fp0, fp1);     \
1992        break;                                                          \
1993    case 17:                                                            \
1994        gen_helper_r6_cmp_ ## fmt ## _or(fp0, cpu_env, fp0, fp1);       \
1995        break;                                                          \
1996    case 18:                                                            \
1997        gen_helper_r6_cmp_ ## fmt ## _une(fp0, cpu_env, fp0, fp1);      \
1998        break;                                                          \
1999    case 19:                                                            \
2000        gen_helper_r6_cmp_ ## fmt ## _ne(fp0, cpu_env, fp0, fp1);       \
2001        break;                                                          \
2002    case 25:                                                            \
2003        gen_helper_r6_cmp_ ## fmt ## _sor(fp0, cpu_env, fp0, fp1);      \
2004        break;                                                          \
2005    case 26:                                                            \
2006        gen_helper_r6_cmp_ ## fmt ## _sune(fp0, cpu_env, fp0, fp1);     \
2007        break;                                                          \
2008    case 27:                                                            \
2009        gen_helper_r6_cmp_ ## fmt ## _sne(fp0, cpu_env, fp0, fp1);      \
2010        break;                                                          \
2011    default:                                                            \
2012        abort();                                                        \
2013    }                                                                   \
2014    STORE;                                                              \
2015    tcg_temp_free_i ## bits (fp0);                                      \
2016    tcg_temp_free_i ## bits (fp1);                                      \
2017}
2018
2019FOP_CONDNS(d, FMT_D, 64, gen_store_fpr64(ctx, fp0, fd))
2020FOP_CONDNS(s, FMT_S, 32, gen_store_fpr32(ctx, fp0, fd))
2021#undef FOP_CONDNS
2022#undef gen_ldcmp_fpr32
2023#undef gen_ldcmp_fpr64
2024
2025/* load/store instructions. */
2026#ifdef CONFIG_USER_ONLY
2027#define OP_LD_ATOMIC(insn,fname)                                           \
2028static inline void op_ld_##insn(TCGv ret, TCGv arg1, DisasContext *ctx)    \
2029{                                                                          \
2030    TCGv t0 = tcg_temp_new();                                              \
2031    tcg_gen_mov_tl(t0, arg1);                                              \
2032    tcg_gen_qemu_##fname(ret, arg1, ctx->mem_idx);                         \
2033    tcg_gen_st_tl(t0, cpu_env, offsetof(CPUMIPSState, lladdr));                \
2034    tcg_gen_st_tl(ret, cpu_env, offsetof(CPUMIPSState, llval));                \
2035    tcg_temp_free(t0);                                                     \
2036}
2037#else
2038#define OP_LD_ATOMIC(insn,fname)                                           \
2039static inline void op_ld_##insn(TCGv ret, TCGv arg1, DisasContext *ctx)    \
2040{                                                                          \
2041    gen_helper_1e1i(insn, ret, arg1, ctx->mem_idx);                        \
2042}
2043#endif
2044OP_LD_ATOMIC(ll,ld32s);
2045#if defined(TARGET_MIPS64)
2046OP_LD_ATOMIC(lld,ld64);
2047#endif
2048#undef OP_LD_ATOMIC
2049
2050#ifdef CONFIG_USER_ONLY
2051#define OP_ST_ATOMIC(insn,fname,ldname,almask)                               \
2052static inline void op_st_##insn(TCGv arg1, TCGv arg2, int rt, DisasContext *ctx) \
2053{                                                                            \
2054    TCGv t0 = tcg_temp_new();                                                \
2055    TCGLabel *l1 = gen_new_label();                                          \
2056    TCGLabel *l2 = gen_new_label();                                          \
2057                                                                             \
2058    tcg_gen_andi_tl(t0, arg2, almask);                                       \
2059    tcg_gen_brcondi_tl(TCG_COND_EQ, t0, 0, l1);                              \
2060    tcg_gen_st_tl(arg2, cpu_env, offsetof(CPUMIPSState, CP0_BadVAddr));          \
2061    generate_exception(ctx, EXCP_AdES);                                      \
2062    gen_set_label(l1);                                                       \
2063    tcg_gen_ld_tl(t0, cpu_env, offsetof(CPUMIPSState, lladdr));                  \
2064    tcg_gen_brcond_tl(TCG_COND_NE, arg2, t0, l2);                            \
2065    tcg_gen_movi_tl(t0, rt | ((almask << 3) & 0x20));                        \
2066    tcg_gen_st_tl(t0, cpu_env, offsetof(CPUMIPSState, llreg));                   \
2067    tcg_gen_st_tl(arg1, cpu_env, offsetof(CPUMIPSState, llnewval));              \
2068    generate_exception_end(ctx, EXCP_SC);                                    \
2069    gen_set_label(l2);                                                       \
2070    tcg_gen_movi_tl(t0, 0);                                                  \
2071    gen_store_gpr(t0, rt);                                                   \
2072    tcg_temp_free(t0);                                                       \
2073}
2074#else
2075#define OP_ST_ATOMIC(insn,fname,ldname,almask)                               \
2076static inline void op_st_##insn(TCGv arg1, TCGv arg2, int rt, DisasContext *ctx) \
2077{                                                                            \
2078    TCGv t0 = tcg_temp_new();                                                \
2079    gen_helper_1e2i(insn, t0, arg1, arg2, ctx->mem_idx);                     \
2080    gen_store_gpr(t0, rt);                                                   \
2081    tcg_temp_free(t0);                                                       \
2082}
2083#endif
2084OP_ST_ATOMIC(sc,st32,ld32s,0x3);
2085#if defined(TARGET_MIPS64)
2086OP_ST_ATOMIC(scd,st64,ld64,0x7);
2087#endif
2088#undef OP_ST_ATOMIC
2089
2090static void gen_base_offset_addr (DisasContext *ctx, TCGv addr,
2091                                  int base, int16_t offset)
2092{
2093    if (base == 0) {
2094        tcg_gen_movi_tl(addr, offset);
2095    } else if (offset == 0) {
2096        gen_load_gpr(addr, base);
2097    } else {
2098        tcg_gen_movi_tl(addr, offset);
2099        gen_op_addr_add(ctx, addr, cpu_gpr[base], addr);
2100    }
2101}
2102
2103static target_ulong pc_relative_pc (DisasContext *ctx)
2104{
2105    target_ulong pc = ctx->pc;
2106
2107    if (ctx->hflags & MIPS_HFLAG_BMASK) {
2108        int branch_bytes = ctx->hflags & MIPS_HFLAG_BDS16 ? 2 : 4;
2109
2110        pc -= branch_bytes;
2111    }
2112
2113    pc &= ~(target_ulong)3;
2114    return pc;
2115}
2116
2117/* Load */
2118static void gen_ld(DisasContext *ctx, uint32_t opc,
2119                   int rt, int base, int16_t offset)
2120{
2121    TCGv t0, t1, t2;
2122
2123    if (rt == 0 && ctx->insn_flags & (INSN_LOONGSON2E | INSN_LOONGSON2F)) {
2124        /* Loongson CPU uses a load to zero register for prefetch.
2125           We emulate it as a NOP. On other CPU we must perform the
2126           actual memory access. */
2127        return;
2128    }
2129
2130    t0 = tcg_temp_new();
2131    gen_base_offset_addr(ctx, t0, base, offset);
2132
2133    switch (opc) {
2134#if defined(TARGET_MIPS64)
2135    case OPC_LWU:
2136        tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEUL |
2137                           ctx->default_tcg_memop_mask);
2138        gen_store_gpr(t0, rt);
2139        break;
2140    case OPC_LD:
2141        tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEQ |
2142                           ctx->default_tcg_memop_mask);
2143        gen_store_gpr(t0, rt);
2144        break;
2145    case OPC_LLD:
2146    case R6_OPC_LLD:
2147        op_ld_lld(t0, t0, ctx);
2148        gen_store_gpr(t0, rt);
2149        break;
2150    case OPC_LDL:
2151        t1 = tcg_temp_new();
2152        /* Do a byte access to possibly trigger a page
2153           fault with the unaligned address.  */
2154        tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_UB);
2155        tcg_gen_andi_tl(t1, t0, 7);
2156#ifndef TARGET_WORDS_BIGENDIAN
2157        tcg_gen_xori_tl(t1, t1, 7);
2158#endif
2159        tcg_gen_shli_tl(t1, t1, 3);
2160        tcg_gen_andi_tl(t0, t0, ~7);
2161        tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEQ);
2162        tcg_gen_shl_tl(t0, t0, t1);
2163        t2 = tcg_const_tl(-1);
2164        tcg_gen_shl_tl(t2, t2, t1);
2165        gen_load_gpr(t1, rt);
2166        tcg_gen_andc_tl(t1, t1, t2);
2167        tcg_temp_free(t2);
2168        tcg_gen_or_tl(t0, t0, t1);
2169        tcg_temp_free(t1);
2170        gen_store_gpr(t0, rt);
2171        break;
2172    case OPC_LDR:
2173        t1 = tcg_temp_new();
2174        /* Do a byte access to possibly trigger a page
2175           fault with the unaligned address.  */
2176        tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_UB);
2177        tcg_gen_andi_tl(t1, t0, 7);
2178#ifdef TARGET_WORDS_BIGENDIAN
2179        tcg_gen_xori_tl(t1, t1, 7);
2180#endif
2181        tcg_gen_shli_tl(t1, t1, 3);
2182        tcg_gen_andi_tl(t0, t0, ~7);
2183        tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEQ);
2184        tcg_gen_shr_tl(t0, t0, t1);
2185        tcg_gen_xori_tl(t1, t1, 63);
2186        t2 = tcg_const_tl(0xfffffffffffffffeull);
2187        tcg_gen_shl_tl(t2, t2, t1);
2188        gen_load_gpr(t1, rt);
2189        tcg_gen_and_tl(t1, t1, t2);
2190        tcg_temp_free(t2);
2191        tcg_gen_or_tl(t0, t0, t1);
2192        tcg_temp_free(t1);
2193        gen_store_gpr(t0, rt);
2194        break;
2195    case OPC_LDPC:
2196        t1 = tcg_const_tl(pc_relative_pc(ctx));
2197        gen_op_addr_add(ctx, t0, t0, t1);
2198        tcg_temp_free(t1);
2199        tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEQ);
2200        gen_store_gpr(t0, rt);
2201        break;
2202#endif
2203    case OPC_LWPC:
2204        t1 = tcg_const_tl(pc_relative_pc(ctx));
2205        gen_op_addr_add(ctx, t0, t0, t1);
2206        tcg_temp_free(t1);
2207        tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TESL);
2208        gen_store_gpr(t0, rt);
2209        break;
2210    case OPC_LW:
2211        tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TESL |
2212                           ctx->default_tcg_memop_mask);
2213        gen_store_gpr(t0, rt);
2214        break;
2215    case OPC_LH:
2216        tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TESW |
2217                           ctx->default_tcg_memop_mask);
2218        gen_store_gpr(t0, rt);
2219        break;
2220    case OPC_LHU:
2221        tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEUW |
2222                           ctx->default_tcg_memop_mask);
2223        gen_store_gpr(t0, rt);
2224        break;
2225    case OPC_LB:
2226        tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_SB);
2227        gen_store_gpr(t0, rt);
2228        break;
2229    case OPC_LBU:
2230        tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_UB);
2231        gen_store_gpr(t0, rt);
2232        break;
2233    case OPC_LWL:
2234        t1 = tcg_temp_new();
2235        /* Do a byte access to possibly trigger a page
2236           fault with the unaligned address.  */
2237        tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_UB);
2238        tcg_gen_andi_tl(t1, t0, 3);
2239#ifndef TARGET_WORDS_BIGENDIAN
2240        tcg_gen_xori_tl(t1, t1, 3);
2241#endif
2242        tcg_gen_shli_tl(t1, t1, 3);
2243        tcg_gen_andi_tl(t0, t0, ~3);
2244        tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEUL);
2245        tcg_gen_shl_tl(t0, t0, t1);
2246        t2 = tcg_const_tl(-1);
2247        tcg_gen_shl_tl(t2, t2, t1);
2248        gen_load_gpr(t1, rt);
2249        tcg_gen_andc_tl(t1, t1, t2);
2250        tcg_temp_free(t2);
2251        tcg_gen_or_tl(t0, t0, t1);
2252        tcg_temp_free(t1);
2253        tcg_gen_ext32s_tl(t0, t0);
2254        gen_store_gpr(t0, rt);
2255        break;
2256    case OPC_LWR:
2257        t1 = tcg_temp_new();
2258        /* Do a byte access to possibly trigger a page
2259           fault with the unaligned address.  */
2260        tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_UB);
2261        tcg_gen_andi_tl(t1, t0, 3);
2262#ifdef TARGET_WORDS_BIGENDIAN
2263        tcg_gen_xori_tl(t1, t1, 3);
2264#endif
2265        tcg_gen_shli_tl(t1, t1, 3);
2266        tcg_gen_andi_tl(t0, t0, ~3);
2267        tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEUL);
2268        tcg_gen_shr_tl(t0, t0, t1);
2269        tcg_gen_xori_tl(t1, t1, 31);
2270        t2 = tcg_const_tl(0xfffffffeull);
2271        tcg_gen_shl_tl(t2, t2, t1);
2272        gen_load_gpr(t1, rt);
2273        tcg_gen_and_tl(t1, t1, t2);
2274        tcg_temp_free(t2);
2275        tcg_gen_or_tl(t0, t0, t1);
2276        tcg_temp_free(t1);
2277        tcg_gen_ext32s_tl(t0, t0);
2278        gen_store_gpr(t0, rt);
2279        break;
2280    case OPC_LL:
2281    case R6_OPC_LL:
2282        op_ld_ll(t0, t0, ctx);
2283        gen_store_gpr(t0, rt);
2284        break;
2285    }
2286    tcg_temp_free(t0);
2287}
2288
2289/* Store */
2290static void gen_st (DisasContext *ctx, uint32_t opc, int rt,
2291                    int base, int16_t offset)
2292{
2293    TCGv t0 = tcg_temp_new();
2294    TCGv t1 = tcg_temp_new();
2295
2296    gen_base_offset_addr(ctx, t0, base, offset);
2297    gen_load_gpr(t1, rt);
2298    switch (opc) {
2299#if defined(TARGET_MIPS64)
2300    case OPC_SD:
2301        tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEQ |
2302                           ctx->default_tcg_memop_mask);
2303        break;
2304    case OPC_SDL:
2305        gen_helper_0e2i(sdl, t1, t0, ctx->mem_idx);
2306        break;
2307    case OPC_SDR:
2308        gen_helper_0e2i(sdr, t1, t0, ctx->mem_idx);
2309        break;
2310#endif
2311    case OPC_SW:
2312        tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL |
2313                           ctx->default_tcg_memop_mask);
2314        break;
2315    case OPC_SH:
2316        tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUW |
2317                           ctx->default_tcg_memop_mask);
2318        break;
2319    case OPC_SB:
2320        tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_8);
2321        break;
2322    case OPC_SWL:
2323        gen_helper_0e2i(swl, t1, t0, ctx->mem_idx);
2324        break;
2325    case OPC_SWR:
2326        gen_helper_0e2i(swr, t1, t0, ctx->mem_idx);
2327        break;
2328    }
2329    tcg_temp_free(t0);
2330    tcg_temp_free(t1);
2331}
2332
2333
2334/* Store conditional */
2335static void gen_st_cond (DisasContext *ctx, uint32_t opc, int rt,
2336                         int base, int16_t offset)
2337{
2338    TCGv t0, t1;
2339
2340#ifdef CONFIG_USER_ONLY
2341    t0 = tcg_temp_local_new();
2342    t1 = tcg_temp_local_new();
2343#else
2344    t0 = tcg_temp_new();
2345    t1 = tcg_temp_new();
2346#endif
2347    gen_base_offset_addr(ctx, t0, base, offset);
2348    gen_load_gpr(t1, rt);
2349    switch (opc) {
2350#if defined(TARGET_MIPS64)
2351    case OPC_SCD:
2352    case R6_OPC_SCD:
2353        op_st_scd(t1, t0, rt, ctx);
2354        break;
2355#endif
2356    case OPC_SC:
2357    case R6_OPC_SC:
2358        op_st_sc(t1, t0, rt, ctx);
2359        break;
2360    }
2361    tcg_temp_free(t1);
2362    tcg_temp_free(t0);
2363}
2364
2365/* Load and store */
2366static void gen_flt_ldst (DisasContext *ctx, uint32_t opc, int ft,
2367                          int base, int16_t offset)
2368{
2369    TCGv t0 = tcg_temp_new();
2370
2371    gen_base_offset_addr(ctx, t0, base, offset);
2372    /* Don't do NOP if destination is zero: we must perform the actual
2373       memory access. */
2374    switch (opc) {
2375    case OPC_LWC1:
2376        {
2377            TCGv_i32 fp0 = tcg_temp_new_i32();
2378            tcg_gen_qemu_ld_i32(fp0, t0, ctx->mem_idx, MO_TESL |
2379                                ctx->default_tcg_memop_mask);
2380            gen_store_fpr32(ctx, fp0, ft);
2381            tcg_temp_free_i32(fp0);
2382        }
2383        break;
2384    case OPC_SWC1:
2385        {
2386            TCGv_i32 fp0 = tcg_temp_new_i32();
2387            gen_load_fpr32(ctx, fp0, ft);
2388            tcg_gen_qemu_st_i32(fp0, t0, ctx->mem_idx, MO_TEUL |
2389                                ctx->default_tcg_memop_mask);
2390            tcg_temp_free_i32(fp0);
2391        }
2392        break;
2393    case OPC_LDC1:
2394        {
2395            TCGv_i64 fp0 = tcg_temp_new_i64();
2396            tcg_gen_qemu_ld_i64(fp0, t0, ctx->mem_idx, MO_TEQ |
2397                                ctx->default_tcg_memop_mask);
2398            gen_store_fpr64(ctx, fp0, ft);
2399            tcg_temp_free_i64(fp0);
2400        }
2401        break;
2402    case OPC_SDC1:
2403        {
2404            TCGv_i64 fp0 = tcg_temp_new_i64();
2405            gen_load_fpr64(ctx, fp0, ft);
2406            tcg_gen_qemu_st_i64(fp0, t0, ctx->mem_idx, MO_TEQ |
2407                                ctx->default_tcg_memop_mask);
2408            tcg_temp_free_i64(fp0);
2409        }
2410        break;
2411    default:
2412        MIPS_INVAL("flt_ldst");
2413        generate_exception_end(ctx, EXCP_RI);
2414        goto out;
2415    }
2416 out:
2417    tcg_temp_free(t0);
2418}
2419
2420static void gen_cop1_ldst(DisasContext *ctx, uint32_t op, int rt,
2421                          int rs, int16_t imm)
2422{
2423    if (ctx->CP0_Config1 & (1 << CP0C1_FP)) {
2424        check_cp1_enabled(ctx);
2425        switch (op) {
2426        case OPC_LDC1:
2427        case OPC_SDC1:
2428            check_insn(ctx, ISA_MIPS2);
2429            /* Fallthrough */
2430        default:
2431            gen_flt_ldst(ctx, op, rt, rs, imm);
2432        }
2433    } else {
2434        generate_exception_err(ctx, EXCP_CpU, 1);
2435    }
2436}
2437
2438/* Arithmetic with immediate operand */
2439static void gen_arith_imm(DisasContext *ctx, uint32_t opc,
2440                          int rt, int rs, int16_t imm)
2441{
2442    target_ulong uimm = (target_long)imm; /* Sign extend to 32/64 bits */
2443
2444    if (rt == 0 && opc != OPC_ADDI && opc != OPC_DADDI) {
2445        /* If no destination, treat it as a NOP.
2446           For addi, we must generate the overflow exception when needed. */
2447        return;
2448    }
2449    switch (opc) {
2450    case OPC_ADDI:
2451        {
2452            TCGv t0 = tcg_temp_local_new();
2453            TCGv t1 = tcg_temp_new();
2454            TCGv t2 = tcg_temp_new();
2455            TCGLabel *l1 = gen_new_label();
2456
2457            gen_load_gpr(t1, rs);
2458            tcg_gen_addi_tl(t0, t1, uimm);
2459            tcg_gen_ext32s_tl(t0, t0);
2460
2461            tcg_gen_xori_tl(t1, t1, ~uimm);
2462            tcg_gen_xori_tl(t2, t0, uimm);
2463            tcg_gen_and_tl(t1, t1, t2);
2464            tcg_temp_free(t2);
2465            tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
2466            tcg_temp_free(t1);
2467            /* operands of same sign, result different sign */
2468            generate_exception(ctx, EXCP_OVERFLOW);
2469            gen_set_label(l1);
2470            tcg_gen_ext32s_tl(t0, t0);
2471            gen_store_gpr(t0, rt);
2472            tcg_temp_free(t0);
2473        }
2474        break;
2475    case OPC_ADDIU:
2476        if (rs != 0) {
2477            tcg_gen_addi_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
2478            tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
2479        } else {
2480            tcg_gen_movi_tl(cpu_gpr[rt], uimm);
2481        }
2482        break;
2483#if defined(TARGET_MIPS64)
2484    case OPC_DADDI:
2485        {
2486            TCGv t0 = tcg_temp_local_new();
2487            TCGv t1 = tcg_temp_new();
2488            TCGv t2 = tcg_temp_new();
2489            TCGLabel *l1 = gen_new_label();
2490
2491            gen_load_gpr(t1, rs);
2492            tcg_gen_addi_tl(t0, t1, uimm);
2493
2494            tcg_gen_xori_tl(t1, t1, ~uimm);
2495            tcg_gen_xori_tl(t2, t0, uimm);
2496            tcg_gen_and_tl(t1, t1, t2);
2497            tcg_temp_free(t2);
2498            tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
2499            tcg_temp_free(t1);
2500            /* operands of same sign, result different sign */
2501            generate_exception(ctx, EXCP_OVERFLOW);
2502            gen_set_label(l1);
2503            gen_store_gpr(t0, rt);
2504            tcg_temp_free(t0);
2505        }
2506        break;
2507    case OPC_DADDIU:
2508        if (rs != 0) {
2509            tcg_gen_addi_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
2510        } else {
2511            tcg_gen_movi_tl(cpu_gpr[rt], uimm);
2512        }
2513        break;
2514#endif
2515    }
2516}
2517
2518/* Logic with immediate operand */
2519static void gen_logic_imm(DisasContext *ctx, uint32_t opc,
2520                          int rt, int rs, int16_t imm)
2521{
2522    target_ulong uimm;
2523
2524    if (rt == 0) {
2525        /* If no destination, treat it as a NOP. */
2526        return;
2527    }
2528    uimm = (uint16_t)imm;
2529    switch (opc) {
2530    case OPC_ANDI:
2531        if (likely(rs != 0))
2532            tcg_gen_andi_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
2533        else
2534            tcg_gen_movi_tl(cpu_gpr[rt], 0);
2535        break;
2536    case OPC_ORI:
2537        if (rs != 0)
2538            tcg_gen_ori_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
2539        else
2540            tcg_gen_movi_tl(cpu_gpr[rt], uimm);
2541        break;
2542    case OPC_XORI:
2543        if (likely(rs != 0))
2544            tcg_gen_xori_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
2545        else
2546            tcg_gen_movi_tl(cpu_gpr[rt], uimm);
2547        break;
2548    case OPC_LUI:
2549        if (rs != 0 && (ctx->insn_flags & ISA_MIPS32R6)) {
2550            /* OPC_AUI */
2551            tcg_gen_addi_tl(cpu_gpr[rt], cpu_gpr[rs], imm << 16);
2552            tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
2553        } else {
2554            tcg_gen_movi_tl(cpu_gpr[rt], imm << 16);
2555        }
2556        break;
2557
2558    default:
2559        break;
2560    }
2561}
2562
2563/* Set on less than with immediate operand */
2564static void gen_slt_imm(DisasContext *ctx, uint32_t opc,
2565                        int rt, int rs, int16_t imm)
2566{
2567    target_ulong uimm = (target_long)imm; /* Sign extend to 32/64 bits */
2568    TCGv t0;
2569
2570    if (rt == 0) {
2571        /* If no destination, treat it as a NOP. */
2572        return;
2573    }
2574    t0 = tcg_temp_new();
2575    gen_load_gpr(t0, rs);
2576    switch (opc) {
2577    case OPC_SLTI:
2578        tcg_gen_setcondi_tl(TCG_COND_LT, cpu_gpr[rt], t0, uimm);
2579        break;
2580    case OPC_SLTIU:
2581        tcg_gen_setcondi_tl(TCG_COND_LTU, cpu_gpr[rt], t0, uimm);
2582        break;
2583    }
2584    tcg_temp_free(t0);
2585}
2586
2587/* Shifts with immediate operand */
2588static void gen_shift_imm(DisasContext *ctx, uint32_t opc,
2589                          int rt, int rs, int16_t imm)
2590{
2591    target_ulong uimm = ((uint16_t)imm) & 0x1f;
2592    TCGv t0;
2593
2594    if (rt == 0) {
2595        /* If no destination, treat it as a NOP. */
2596        return;
2597    }
2598
2599    t0 = tcg_temp_new();
2600    gen_load_gpr(t0, rs);
2601    switch (opc) {
2602    case OPC_SLL:
2603        tcg_gen_shli_tl(t0, t0, uimm);
2604        tcg_gen_ext32s_tl(cpu_gpr[rt], t0);
2605        break;
2606    case OPC_SRA:
2607        tcg_gen_sari_tl(cpu_gpr[rt], t0, uimm);
2608        break;
2609    case OPC_SRL:
2610        if (uimm != 0) {
2611            tcg_gen_ext32u_tl(t0, t0);
2612            tcg_gen_shri_tl(cpu_gpr[rt], t0, uimm);
2613        } else {
2614            tcg_gen_ext32s_tl(cpu_gpr[rt], t0);
2615        }
2616        break;
2617    case OPC_ROTR:
2618        if (uimm != 0) {
2619            TCGv_i32 t1 = tcg_temp_new_i32();
2620
2621            tcg_gen_trunc_tl_i32(t1, t0);
2622            tcg_gen_rotri_i32(t1, t1, uimm);
2623            tcg_gen_ext_i32_tl(cpu_gpr[rt], t1);
2624            tcg_temp_free_i32(t1);
2625        } else {
2626            tcg_gen_ext32s_tl(cpu_gpr[rt], t0);
2627        }
2628        break;
2629#if defined(TARGET_MIPS64)
2630    case OPC_DSLL:
2631        tcg_gen_shli_tl(cpu_gpr[rt], t0, uimm);
2632        break;
2633    case OPC_DSRA:
2634        tcg_gen_sari_tl(cpu_gpr[rt], t0, uimm);
2635        break;
2636    case OPC_DSRL:
2637        tcg_gen_shri_tl(cpu_gpr[rt], t0, uimm);
2638        break;
2639    case OPC_DROTR:
2640        if (uimm != 0) {
2641            tcg_gen_rotri_tl(cpu_gpr[rt], t0, uimm);
2642        } else {
2643            tcg_gen_mov_tl(cpu_gpr[rt], t0);
2644        }
2645        break;
2646    case OPC_DSLL32:
2647        tcg_gen_shli_tl(cpu_gpr[rt], t0, uimm + 32);
2648        break;
2649    case OPC_DSRA32:
2650        tcg_gen_sari_tl(cpu_gpr[rt], t0, uimm + 32);
2651        break;
2652    case OPC_DSRL32:
2653        tcg_gen_shri_tl(cpu_gpr[rt], t0, uimm + 32);
2654        break;
2655    case OPC_DROTR32:
2656        tcg_gen_rotri_tl(cpu_gpr[rt], t0, uimm + 32);
2657        break;
2658#endif
2659    }
2660    tcg_temp_free(t0);
2661}
2662
2663/* Arithmetic */
2664static void gen_arith(DisasContext *ctx, uint32_t opc,
2665                      int rd, int rs, int rt)
2666{
2667    if (rd == 0 && opc != OPC_ADD && opc != OPC_SUB
2668       && opc != OPC_DADD && opc != OPC_DSUB) {
2669        /* If no destination, treat it as a NOP.
2670           For add & sub, we must generate the overflow exception when needed. */
2671        return;
2672    }
2673
2674    switch (opc) {
2675    case OPC_ADD:
2676        {
2677            TCGv t0 = tcg_temp_local_new();
2678            TCGv t1 = tcg_temp_new();
2679            TCGv t2 = tcg_temp_new();
2680            TCGLabel *l1 = gen_new_label();
2681
2682            gen_load_gpr(t1, rs);
2683            gen_load_gpr(t2, rt);
2684            tcg_gen_add_tl(t0, t1, t2);
2685            tcg_gen_ext32s_tl(t0, t0);
2686            tcg_gen_xor_tl(t1, t1, t2);
2687            tcg_gen_xor_tl(t2, t0, t2);
2688            tcg_gen_andc_tl(t1, t2, t1);
2689            tcg_temp_free(t2);
2690            tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
2691            tcg_temp_free(t1);
2692            /* operands of same sign, result different sign */
2693            generate_exception(ctx, EXCP_OVERFLOW);
2694            gen_set_label(l1);
2695            gen_store_gpr(t0, rd);
2696            tcg_temp_free(t0);
2697        }
2698        break;
2699    case OPC_ADDU:
2700        if (rs != 0 && rt != 0) {
2701            tcg_gen_add_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2702            tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
2703        } else if (rs == 0 && rt != 0) {
2704            tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
2705        } else if (rs != 0 && rt == 0) {
2706            tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
2707        } else {
2708            tcg_gen_movi_tl(cpu_gpr[rd], 0);
2709        }
2710        break;
2711    case OPC_SUB:
2712        {
2713            TCGv t0 = tcg_temp_local_new();
2714            TCGv t1 = tcg_temp_new();
2715            TCGv t2 = tcg_temp_new();
2716            TCGLabel *l1 = gen_new_label();
2717
2718            gen_load_gpr(t1, rs);
2719            gen_load_gpr(t2, rt);
2720            tcg_gen_sub_tl(t0, t1, t2);
2721            tcg_gen_ext32s_tl(t0, t0);
2722            tcg_gen_xor_tl(t2, t1, t2);
2723            tcg_gen_xor_tl(t1, t0, t1);
2724            tcg_gen_and_tl(t1, t1, t2);
2725            tcg_temp_free(t2);
2726            tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
2727            tcg_temp_free(t1);
2728            /* operands of different sign, first operand and result different sign */
2729            generate_exception(ctx, EXCP_OVERFLOW);
2730            gen_set_label(l1);
2731            gen_store_gpr(t0, rd);
2732            tcg_temp_free(t0);
2733        }
2734        break;
2735    case OPC_SUBU:
2736        if (rs != 0 && rt != 0) {
2737            tcg_gen_sub_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2738            tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
2739        } else if (rs == 0 && rt != 0) {
2740            tcg_gen_neg_tl(cpu_gpr[rd], cpu_gpr[rt]);
2741            tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
2742        } else if (rs != 0 && rt == 0) {
2743            tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
2744        } else {
2745            tcg_gen_movi_tl(cpu_gpr[rd], 0);
2746        }
2747        break;
2748#if defined(TARGET_MIPS64)
2749    case OPC_DADD:
2750        {
2751            TCGv t0 = tcg_temp_local_new();
2752            TCGv t1 = tcg_temp_new();
2753            TCGv t2 = tcg_temp_new();
2754            TCGLabel *l1 = gen_new_label();
2755
2756            gen_load_gpr(t1, rs);
2757            gen_load_gpr(t2, rt);
2758            tcg_gen_add_tl(t0, t1, t2);
2759            tcg_gen_xor_tl(t1, t1, t2);
2760            tcg_gen_xor_tl(t2, t0, t2);
2761            tcg_gen_andc_tl(t1, t2, t1);
2762            tcg_temp_free(t2);
2763            tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
2764            tcg_temp_free(t1);
2765            /* operands of same sign, result different sign */
2766            generate_exception(ctx, EXCP_OVERFLOW);
2767            gen_set_label(l1);
2768            gen_store_gpr(t0, rd);
2769            tcg_temp_free(t0);
2770        }
2771        break;
2772    case OPC_DADDU:
2773        if (rs != 0 && rt != 0) {
2774            tcg_gen_add_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2775        } else if (rs == 0 && rt != 0) {
2776            tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
2777        } else if (rs != 0 && rt == 0) {
2778            tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
2779        } else {
2780            tcg_gen_movi_tl(cpu_gpr[rd], 0);
2781        }
2782        break;
2783    case OPC_DSUB:
2784        {
2785            TCGv t0 = tcg_temp_local_new();
2786            TCGv t1 = tcg_temp_new();
2787            TCGv t2 = tcg_temp_new();
2788            TCGLabel *l1 = gen_new_label();
2789
2790            gen_load_gpr(t1, rs);
2791            gen_load_gpr(t2, rt);
2792            tcg_gen_sub_tl(t0, t1, t2);
2793            tcg_gen_xor_tl(t2, t1, t2);
2794            tcg_gen_xor_tl(t1, t0, t1);
2795            tcg_gen_and_tl(t1, t1, t2);
2796            tcg_temp_free(t2);
2797            tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
2798            tcg_temp_free(t1);
2799            /* operands of different sign, first operand and result different sign */
2800            generate_exception(ctx, EXCP_OVERFLOW);
2801            gen_set_label(l1);
2802            gen_store_gpr(t0, rd);
2803            tcg_temp_free(t0);
2804        }
2805        break;
2806    case OPC_DSUBU:
2807        if (rs != 0 && rt != 0) {
2808            tcg_gen_sub_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2809        } else if (rs == 0 && rt != 0) {
2810            tcg_gen_neg_tl(cpu_gpr[rd], cpu_gpr[rt]);
2811        } else if (rs != 0 && rt == 0) {
2812            tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
2813        } else {
2814            tcg_gen_movi_tl(cpu_gpr[rd], 0);
2815        }
2816        break;
2817#endif
2818    case OPC_MUL:
2819        if (likely(rs != 0 && rt != 0)) {
2820            tcg_gen_mul_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2821            tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
2822        } else {
2823            tcg_gen_movi_tl(cpu_gpr[rd], 0);
2824        }
2825        break;
2826    }
2827}
2828
2829/* Conditional move */
2830static void gen_cond_move(DisasContext *ctx, uint32_t opc,
2831                          int rd, int rs, int rt)
2832{
2833    TCGv t0, t1, t2;
2834
2835    if (rd == 0) {
2836        /* If no destination, treat it as a NOP. */
2837        return;
2838    }
2839
2840    t0 = tcg_temp_new();
2841    gen_load_gpr(t0, rt);
2842    t1 = tcg_const_tl(0);
2843    t2 = tcg_temp_new();
2844    gen_load_gpr(t2, rs);
2845    switch (opc) {
2846    case OPC_MOVN:
2847        tcg_gen_movcond_tl(TCG_COND_NE, cpu_gpr[rd], t0, t1, t2, cpu_gpr[rd]);
2848        break;
2849    case OPC_MOVZ:
2850        tcg_gen_movcond_tl(TCG_COND_EQ, cpu_gpr[rd], t0, t1, t2, cpu_gpr[rd]);
2851        break;
2852    case OPC_SELNEZ:
2853        tcg_gen_movcond_tl(TCG_COND_NE, cpu_gpr[rd], t0, t1, t2, t1);
2854        break;
2855    case OPC_SELEQZ:
2856        tcg_gen_movcond_tl(TCG_COND_EQ, cpu_gpr[rd], t0, t1, t2, t1);
2857        break;
2858    }
2859    tcg_temp_free(t2);
2860    tcg_temp_free(t1);
2861    tcg_temp_free(t0);
2862}
2863
2864/* Logic */
2865static void gen_logic(DisasContext *ctx, uint32_t opc,
2866                      int rd, int rs, int rt)
2867{
2868    if (rd == 0) {
2869        /* If no destination, treat it as a NOP. */
2870        return;
2871    }
2872
2873    switch (opc) {
2874    case OPC_AND:
2875        if (likely(rs != 0 && rt != 0)) {
2876            tcg_gen_and_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2877        } else {
2878            tcg_gen_movi_tl(cpu_gpr[rd], 0);
2879        }
2880        break;
2881    case OPC_NOR:
2882        if (rs != 0 && rt != 0) {
2883            tcg_gen_nor_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2884        } else if (rs == 0 && rt != 0) {
2885            tcg_gen_not_tl(cpu_gpr[rd], cpu_gpr[rt]);
2886        } else if (rs != 0 && rt == 0) {
2887            tcg_gen_not_tl(cpu_gpr[rd], cpu_gpr[rs]);
2888        } else {
2889            tcg_gen_movi_tl(cpu_gpr[rd], ~((target_ulong)0));
2890        }
2891        break;
2892    case OPC_OR:
2893        if (likely(rs != 0 && rt != 0)) {
2894            tcg_gen_or_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2895        } else if (rs == 0 && rt != 0) {
2896            tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
2897        } else if (rs != 0 && rt == 0) {
2898            tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
2899        } else {
2900            tcg_gen_movi_tl(cpu_gpr[rd], 0);
2901        }
2902        break;
2903    case OPC_XOR:
2904        if (likely(rs != 0 && rt != 0)) {
2905            tcg_gen_xor_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2906        } else if (rs == 0 && rt != 0) {
2907            tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
2908        } else if (rs != 0 && rt == 0) {
2909            tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
2910        } else {
2911            tcg_gen_movi_tl(cpu_gpr[rd], 0);
2912        }
2913        break;
2914    }
2915}
2916
2917/* Set on lower than */
2918static void gen_slt(DisasContext *ctx, uint32_t opc,
2919                    int rd, int rs, int rt)
2920{
2921    TCGv t0, t1;
2922
2923    if (rd == 0) {
2924        /* If no destination, treat it as a NOP. */
2925        return;
2926    }
2927
2928    t0 = tcg_temp_new();
2929    t1 = tcg_temp_new();
2930    gen_load_gpr(t0, rs);
2931    gen_load_gpr(t1, rt);
2932    switch (opc) {
2933    case OPC_SLT:
2934        tcg_gen_setcond_tl(TCG_COND_LT, cpu_gpr[rd], t0, t1);
2935        break;
2936    case OPC_SLTU:
2937        tcg_gen_setcond_tl(TCG_COND_LTU, cpu_gpr[rd], t0, t1);
2938        break;
2939    }
2940    tcg_temp_free(t0);
2941    tcg_temp_free(t1);
2942}
2943
2944/* Shifts */
2945static void gen_shift(DisasContext *ctx, uint32_t opc,
2946                      int rd, int rs, int rt)
2947{
2948    TCGv t0, t1;
2949
2950    if (rd == 0) {
2951        /* If no destination, treat it as a NOP.
2952           For add & sub, we must generate the overflow exception when needed. */
2953        return;
2954    }
2955
2956    t0 = tcg_temp_new();
2957    t1 = tcg_temp_new();
2958    gen_load_gpr(t0, rs);
2959    gen_load_gpr(t1, rt);
2960    switch (opc) {
2961    case OPC_SLLV:
2962        tcg_gen_andi_tl(t0, t0, 0x1f);
2963        tcg_gen_shl_tl(t0, t1, t0);
2964        tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
2965        break;
2966    case OPC_SRAV:
2967        tcg_gen_andi_tl(t0, t0, 0x1f);
2968        tcg_gen_sar_tl(cpu_gpr[rd], t1, t0);
2969        break;
2970    case OPC_SRLV:
2971        tcg_gen_ext32u_tl(t1, t1);
2972        tcg_gen_andi_tl(t0, t0, 0x1f);
2973        tcg_gen_shr_tl(t0, t1, t0);
2974        tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
2975        break;
2976    case OPC_ROTRV:
2977        {
2978            TCGv_i32 t2 = tcg_temp_new_i32();
2979            TCGv_i32 t3 = tcg_temp_new_i32();
2980
2981            tcg_gen_trunc_tl_i32(t2, t0);
2982            tcg_gen_trunc_tl_i32(t3, t1);
2983            tcg_gen_andi_i32(t2, t2, 0x1f);
2984            tcg_gen_rotr_i32(t2, t3, t2);
2985            tcg_gen_ext_i32_tl(cpu_gpr[rd], t2);
2986            tcg_temp_free_i32(t2);
2987            tcg_temp_free_i32(t3);
2988        }
2989        break;
2990#if defined(TARGET_MIPS64)
2991    case OPC_DSLLV:
2992        tcg_gen_andi_tl(t0, t0, 0x3f);
2993        tcg_gen_shl_tl(cpu_gpr[rd], t1, t0);
2994        break;
2995    case OPC_DSRAV:
2996        tcg_gen_andi_tl(t0, t0, 0x3f);
2997        tcg_gen_sar_tl(cpu_gpr[rd], t1, t0);
2998        break;
2999    case OPC_DSRLV:
3000        tcg_gen_andi_tl(t0, t0, 0x3f);
3001        tcg_gen_shr_tl(cpu_gpr[rd], t1, t0);
3002        break;
3003    case OPC_DROTRV:
3004        tcg_gen_andi_tl(t0, t0, 0x3f);
3005        tcg_gen_rotr_tl(cpu_gpr[rd], t1, t0);
3006        break;
3007#endif
3008    }
3009    tcg_temp_free(t0);
3010    tcg_temp_free(t1);
3011}
3012
3013/* Arithmetic on HI/LO registers */
3014static void gen_HILO(DisasContext *ctx, uint32_t opc, int acc, int reg)
3015{
3016    if (reg == 0 && (opc == OPC_MFHI || opc == OPC_MFLO)) {
3017        /* Treat as NOP. */
3018        return;
3019    }
3020
3021    if (acc != 0) {
3022        check_dsp(ctx);
3023    }
3024
3025    switch (opc) {
3026    case OPC_MFHI:
3027#if defined(TARGET_MIPS64)
3028        if (acc != 0) {
3029            tcg_gen_ext32s_tl(cpu_gpr[reg], cpu_HI[acc]);
3030        } else
3031#endif
3032        {
3033            tcg_gen_mov_tl(cpu_gpr[reg], cpu_HI[acc]);
3034        }
3035        break;
3036    case OPC_MFLO:
3037#if defined(TARGET_MIPS64)
3038        if (acc != 0) {
3039            tcg_gen_ext32s_tl(cpu_gpr[reg], cpu_LO[acc]);
3040        } else
3041#endif
3042        {
3043            tcg_gen_mov_tl(cpu_gpr[reg], cpu_LO[acc]);
3044        }
3045        break;
3046    case OPC_MTHI:
3047        if (reg != 0) {
3048#if defined(TARGET_MIPS64)
3049            if (acc != 0) {
3050                tcg_gen_ext32s_tl(cpu_HI[acc], cpu_gpr[reg]);
3051            } else
3052#endif
3053            {
3054                tcg_gen_mov_tl(cpu_HI[acc], cpu_gpr[reg]);
3055            }
3056        } else {
3057            tcg_gen_movi_tl(cpu_HI[acc], 0);
3058        }
3059        break;
3060    case OPC_MTLO:
3061        if (reg != 0) {
3062#if defined(TARGET_MIPS64)
3063            if (acc != 0) {
3064                tcg_gen_ext32s_tl(cpu_LO[acc], cpu_gpr[reg]);
3065            } else
3066#endif
3067            {
3068                tcg_gen_mov_tl(cpu_LO[acc], cpu_gpr[reg]);
3069            }
3070        } else {
3071            tcg_gen_movi_tl(cpu_LO[acc], 0);
3072        }
3073        break;
3074    }
3075}
3076
3077static inline void gen_r6_ld(target_long addr, int reg, int memidx,
3078                             TCGMemOp memop)
3079{
3080    TCGv t0 = tcg_const_tl(addr);
3081    tcg_gen_qemu_ld_tl(t0, t0, memidx, memop);
3082    gen_store_gpr(t0, reg);
3083    tcg_temp_free(t0);
3084}
3085
3086static inline void gen_pcrel(DisasContext *ctx, int opc, target_ulong pc,
3087                             int rs)
3088{
3089    target_long offset;
3090    target_long addr;
3091
3092    switch (MASK_OPC_PCREL_TOP2BITS(opc)) {
3093    case OPC_ADDIUPC:
3094        if (rs != 0) {
3095            offset = sextract32(ctx->opcode << 2, 0, 21);
3096            addr = addr_add(ctx, pc, offset);
3097            tcg_gen_movi_tl(cpu_gpr[rs], addr);
3098        }
3099        break;
3100    case R6_OPC_LWPC:
3101        offset = sextract32(ctx->opcode << 2, 0, 21);
3102        addr = addr_add(ctx, pc, offset);
3103        gen_r6_ld(addr, rs, ctx->mem_idx, MO_TESL);
3104        break;
3105#if defined(TARGET_MIPS64)
3106    case OPC_LWUPC:
3107        check_mips_64(ctx);
3108        offset = sextract32(ctx->opcode << 2, 0, 21);
3109        addr = addr_add(ctx, pc, offset);
3110        gen_r6_ld(addr, rs, ctx->mem_idx, MO_TEUL);
3111        break;
3112#endif
3113    default:
3114        switch (MASK_OPC_PCREL_TOP5BITS(opc)) {
3115        case OPC_AUIPC:
3116            if (rs != 0) {
3117                offset = sextract32(ctx->opcode, 0, 16) << 16;
3118                addr = addr_add(ctx, pc, offset);
3119                tcg_gen_movi_tl(cpu_gpr[rs], addr);
3120            }
3121            break;
3122        case OPC_ALUIPC:
3123            if (rs != 0) {
3124                offset = sextract32(ctx->opcode, 0, 16) << 16;
3125                addr = ~0xFFFF & addr_add(ctx, pc, offset);
3126                tcg_gen_movi_tl(cpu_gpr[rs], addr);
3127            }
3128            break;
3129#if defined(TARGET_MIPS64)
3130        case R6_OPC_LDPC: /* bits 16 and 17 are part of immediate */
3131        case R6_OPC_LDPC + (1 << 16):
3132        case R6_OPC_LDPC + (2 << 16):
3133        case R6_OPC_LDPC + (3 << 16):
3134            check_mips_64(ctx);
3135            offset = sextract32(ctx->opcode << 3, 0, 21);
3136            addr = addr_add(ctx, (pc & ~0x7), offset);
3137            gen_r6_ld(addr, rs, ctx->mem_idx, MO_TEQ);
3138            break;
3139#endif
3140        default:
3141            MIPS_INVAL("OPC_PCREL");
3142            generate_exception_end(ctx, EXCP_RI);
3143            break;
3144        }
3145        break;
3146    }
3147}
3148
3149static void gen_r6_muldiv(DisasContext *ctx, int opc, int rd, int rs, int rt)
3150{
3151    TCGv t0, t1;
3152
3153    if (rd == 0) {
3154        /* Treat as NOP. */
3155        return;
3156    }
3157
3158    t0 = tcg_temp_new();
3159    t1 = tcg_temp_new();
3160
3161    gen_load_gpr(t0, rs);
3162    gen_load_gpr(t1, rt);
3163
3164    switch (opc) {
3165    case R6_OPC_DIV:
3166        {
3167            TCGv t2 = tcg_temp_new();
3168            TCGv t3 = tcg_temp_new();
3169            tcg_gen_ext32s_tl(t0, t0);
3170            tcg_gen_ext32s_tl(t1, t1);
3171            tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, INT_MIN);
3172            tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1);
3173            tcg_gen_and_tl(t2, t2, t3);
3174            tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
3175            tcg_gen_or_tl(t2, t2, t3);
3176            tcg_gen_movi_tl(t3, 0);
3177            tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
3178            tcg_gen_div_tl(cpu_gpr[rd], t0, t1);
3179            tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3180            tcg_temp_free(t3);
3181            tcg_temp_free(t2);
3182        }
3183        break;
3184    case R6_OPC_MOD:
3185        {
3186            TCGv t2 = tcg_temp_new();
3187            TCGv t3 = tcg_temp_new();
3188            tcg_gen_ext32s_tl(t0, t0);
3189            tcg_gen_ext32s_tl(t1, t1);
3190            tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, INT_MIN);
3191            tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1);
3192            tcg_gen_and_tl(t2, t2, t3);
3193            tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
3194            tcg_gen_or_tl(t2, t2, t3);
3195            tcg_gen_movi_tl(t3, 0);
3196            tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
3197            tcg_gen_rem_tl(cpu_gpr[rd], t0, t1);
3198            tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3199            tcg_temp_free(t3);
3200            tcg_temp_free(t2);
3201        }
3202        break;
3203    case R6_OPC_DIVU:
3204        {
3205            TCGv t2 = tcg_const_tl(0);
3206            TCGv t3 = tcg_const_tl(1);
3207            tcg_gen_ext32u_tl(t0, t0);
3208            tcg_gen_ext32u_tl(t1, t1);
3209            tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
3210            tcg_gen_divu_tl(cpu_gpr[rd], t0, t1);
3211            tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3212            tcg_temp_free(t3);
3213            tcg_temp_free(t2);
3214        }
3215        break;
3216    case R6_OPC_MODU:
3217        {
3218            TCGv t2 = tcg_const_tl(0);
3219            TCGv t3 = tcg_const_tl(1);
3220            tcg_gen_ext32u_tl(t0, t0);
3221            tcg_gen_ext32u_tl(t1, t1);
3222            tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
3223            tcg_gen_remu_tl(cpu_gpr[rd], t0, t1);
3224            tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3225            tcg_temp_free(t3);
3226            tcg_temp_free(t2);
3227        }
3228        break;
3229    case R6_OPC_MUL:
3230        {
3231            TCGv_i32 t2 = tcg_temp_new_i32();
3232            TCGv_i32 t3 = tcg_temp_new_i32();
3233            tcg_gen_trunc_tl_i32(t2, t0);
3234            tcg_gen_trunc_tl_i32(t3, t1);
3235            tcg_gen_mul_i32(t2, t2, t3);
3236            tcg_gen_ext_i32_tl(cpu_gpr[rd], t2);
3237            tcg_temp_free_i32(t2);
3238            tcg_temp_free_i32(t3);
3239        }
3240        break;
3241    case R6_OPC_MUH:
3242        {
3243            TCGv_i32 t2 = tcg_temp_new_i32();
3244            TCGv_i32 t3 = tcg_temp_new_i32();
3245            tcg_gen_trunc_tl_i32(t2, t0);
3246            tcg_gen_trunc_tl_i32(t3, t1);
3247            tcg_gen_muls2_i32(t2, t3, t2, t3);
3248            tcg_gen_ext_i32_tl(cpu_gpr[rd], t3);
3249            tcg_temp_free_i32(t2);
3250            tcg_temp_free_i32(t3);
3251        }
3252        break;
3253    case R6_OPC_MULU:
3254        {
3255            TCGv_i32 t2 = tcg_temp_new_i32();
3256            TCGv_i32 t3 = tcg_temp_new_i32();
3257            tcg_gen_trunc_tl_i32(t2, t0);
3258            tcg_gen_trunc_tl_i32(t3, t1);
3259            tcg_gen_mul_i32(t2, t2, t3);
3260            tcg_gen_ext_i32_tl(cpu_gpr[rd], t2);
3261            tcg_temp_free_i32(t2);
3262            tcg_temp_free_i32(t3);
3263        }
3264        break;
3265    case R6_OPC_MUHU:
3266        {
3267            TCGv_i32 t2 = tcg_temp_new_i32();
3268            TCGv_i32 t3 = tcg_temp_new_i32();
3269            tcg_gen_trunc_tl_i32(t2, t0);
3270            tcg_gen_trunc_tl_i32(t3, t1);
3271            tcg_gen_mulu2_i32(t2, t3, t2, t3);
3272            tcg_gen_ext_i32_tl(cpu_gpr[rd], t3);
3273            tcg_temp_free_i32(t2);
3274            tcg_temp_free_i32(t3);
3275        }
3276        break;
3277#if defined(TARGET_MIPS64)
3278    case R6_OPC_DDIV:
3279        {
3280            TCGv t2 = tcg_temp_new();
3281            TCGv t3 = tcg_temp_new();
3282            tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, -1LL << 63);
3283            tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1LL);
3284            tcg_gen_and_tl(t2, t2, t3);
3285            tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
3286            tcg_gen_or_tl(t2, t2, t3);
3287            tcg_gen_movi_tl(t3, 0);
3288            tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
3289            tcg_gen_div_tl(cpu_gpr[rd], t0, t1);
3290            tcg_temp_free(t3);
3291            tcg_temp_free(t2);
3292        }
3293        break;
3294    case R6_OPC_DMOD:
3295        {
3296            TCGv t2 = tcg_temp_new();
3297            TCGv t3 = tcg_temp_new();
3298            tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, -1LL << 63);
3299            tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1LL);
3300            tcg_gen_and_tl(t2, t2, t3);
3301            tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
3302            tcg_gen_or_tl(t2, t2, t3);
3303            tcg_gen_movi_tl(t3, 0);
3304            tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
3305            tcg_gen_rem_tl(cpu_gpr[rd], t0, t1);
3306            tcg_temp_free(t3);
3307            tcg_temp_free(t2);
3308        }
3309        break;
3310    case R6_OPC_DDIVU:
3311        {
3312            TCGv t2 = tcg_const_tl(0);
3313            TCGv t3 = tcg_const_tl(1);
3314            tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
3315            tcg_gen_divu_i64(cpu_gpr[rd], t0, t1);
3316            tcg_temp_free(t3);
3317            tcg_temp_free(t2);
3318        }
3319        break;
3320    case R6_OPC_DMODU:
3321        {
3322            TCGv t2 = tcg_const_tl(0);
3323            TCGv t3 = tcg_const_tl(1);
3324            tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
3325            tcg_gen_remu_i64(cpu_gpr[rd], t0, t1);
3326            tcg_temp_free(t3);
3327            tcg_temp_free(t2);
3328        }
3329        break;
3330    case R6_OPC_DMUL:
3331        tcg_gen_mul_i64(cpu_gpr[rd], t0, t1);
3332        break;
3333    case R6_OPC_DMUH:
3334        {
3335            TCGv t2 = tcg_temp_new();
3336            tcg_gen_muls2_i64(t2, cpu_gpr[rd], t0, t1);
3337            tcg_temp_free(t2);
3338        }
3339        break;
3340    case R6_OPC_DMULU:
3341        tcg_gen_mul_i64(cpu_gpr[rd], t0, t1);
3342        break;
3343    case R6_OPC_DMUHU:
3344        {
3345            TCGv t2 = tcg_temp_new();
3346            tcg_gen_mulu2_i64(t2, cpu_gpr[rd], t0, t1);
3347            tcg_temp_free(t2);
3348        }
3349        break;
3350#endif
3351    default:
3352        MIPS_INVAL("r6 mul/div");
3353        generate_exception_end(ctx, EXCP_RI);
3354        goto out;
3355    }
3356 out:
3357    tcg_temp_free(t0);
3358    tcg_temp_free(t1);
3359}
3360
3361static void gen_muldiv(DisasContext *ctx, uint32_t opc,
3362                       int acc, int rs, int rt)
3363{
3364    TCGv t0, t1;
3365
3366    t0 = tcg_temp_new();
3367    t1 = tcg_temp_new();
3368
3369    gen_load_gpr(t0, rs);
3370    gen_load_gpr(t1, rt);
3371
3372    if (acc != 0) {
3373        check_dsp(ctx);
3374    }
3375
3376    switch (opc) {
3377    case OPC_DIV:
3378        {
3379            TCGv t2 = tcg_temp_new();
3380            TCGv t3 = tcg_temp_new();
3381            tcg_gen_ext32s_tl(t0, t0);
3382            tcg_gen_ext32s_tl(t1, t1);
3383            tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, INT_MIN);
3384            tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1);
3385            tcg_gen_and_tl(t2, t2, t3);
3386            tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
3387            tcg_gen_or_tl(t2, t2, t3);
3388            tcg_gen_movi_tl(t3, 0);
3389            tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
3390            tcg_gen_div_tl(cpu_LO[acc], t0, t1);
3391            tcg_gen_rem_tl(cpu_HI[acc], t0, t1);
3392            tcg_gen_ext32s_tl(cpu_LO[acc], cpu_LO[acc]);
3393            tcg_gen_ext32s_tl(cpu_HI[acc], cpu_HI[acc]);
3394            tcg_temp_free(t3);
3395            tcg_temp_free(t2);
3396        }
3397        break;
3398    case OPC_DIVU:
3399        {
3400            TCGv t2 = tcg_const_tl(0);
3401            TCGv t3 = tcg_const_tl(1);
3402            tcg_gen_ext32u_tl(t0, t0);
3403            tcg_gen_ext32u_tl(t1, t1);
3404            tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
3405            tcg_gen_divu_tl(cpu_LO[acc], t0, t1);
3406            tcg_gen_remu_tl(cpu_HI[acc], t0, t1);
3407            tcg_gen_ext32s_tl(cpu_LO[acc], cpu_LO[acc]);
3408            tcg_gen_ext32s_tl(cpu_HI[acc], cpu_HI[acc]);
3409            tcg_temp_free(t3);
3410            tcg_temp_free(t2);
3411        }
3412        break;
3413    case OPC_MULT:
3414        {
3415            TCGv_i32 t2 = tcg_temp_new_i32();
3416            TCGv_i32 t3 = tcg_temp_new_i32();
3417            tcg_gen_trunc_tl_i32(t2, t0);
3418            tcg_gen_trunc_tl_i32(t3, t1);
3419            tcg_gen_muls2_i32(t2, t3, t2, t3);
3420            tcg_gen_ext_i32_tl(cpu_LO[acc], t2);
3421            tcg_gen_ext_i32_tl(cpu_HI[acc], t3);
3422            tcg_temp_free_i32(t2);
3423            tcg_temp_free_i32(t3);
3424        }
3425        break;
3426    case OPC_MULTU:
3427        {
3428            TCGv_i32 t2 = tcg_temp_new_i32();
3429            TCGv_i32 t3 = tcg_temp_new_i32();
3430            tcg_gen_trunc_tl_i32(t2, t0);
3431            tcg_gen_trunc_tl_i32(t3, t1);
3432            tcg_gen_mulu2_i32(t2, t3, t2, t3);
3433            tcg_gen_ext_i32_tl(cpu_LO[acc], t2);
3434            tcg_gen_ext_i32_tl(cpu_HI[acc], t3);
3435            tcg_temp_free_i32(t2);
3436            tcg_temp_free_i32(t3);
3437        }
3438        break;
3439#if defined(TARGET_MIPS64)
3440    case OPC_DDIV:
3441        {
3442            TCGv t2 = tcg_temp_new();
3443            TCGv t3 = tcg_temp_new();
3444            tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, -1LL << 63);
3445            tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1LL);
3446            tcg_gen_and_tl(t2, t2, t3);
3447            tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
3448            tcg_gen_or_tl(t2, t2, t3);
3449            tcg_gen_movi_tl(t3, 0);
3450            tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
3451            tcg_gen_div_tl(cpu_LO[acc], t0, t1);
3452            tcg_gen_rem_tl(cpu_HI[acc], t0, t1);
3453            tcg_temp_free(t3);
3454            tcg_temp_free(t2);
3455        }
3456        break;
3457    case OPC_DDIVU:
3458        {
3459            TCGv t2 = tcg_const_tl(0);
3460            TCGv t3 = tcg_const_tl(1);
3461            tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
3462            tcg_gen_divu_i64(cpu_LO[acc], t0, t1);
3463            tcg_gen_remu_i64(cpu_HI[acc], t0, t1);
3464            tcg_temp_free(t3);
3465            tcg_temp_free(t2);
3466        }
3467        break;
3468    case OPC_DMULT:
3469        tcg_gen_muls2_i64(cpu_LO[acc], cpu_HI[acc], t0, t1);
3470        break;
3471    case OPC_DMULTU:
3472        tcg_gen_mulu2_i64(cpu_LO[acc], cpu_HI[acc], t0, t1);
3473        break;
3474#endif
3475    case OPC_MADD:
3476        {
3477            TCGv_i64 t2 = tcg_temp_new_i64();
3478            TCGv_i64 t3 = tcg_temp_new_i64();
3479
3480            tcg_gen_ext_tl_i64(t2, t0);
3481            tcg_gen_ext_tl_i64(t3, t1);
3482            tcg_gen_mul_i64(t2, t2, t3);
3483            tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
3484            tcg_gen_add_i64(t2, t2, t3);
3485            tcg_temp_free_i64(t3);
3486            gen_move_low32(cpu_LO[acc], t2);
3487            gen_move_high32(cpu_HI[acc], t2);
3488            tcg_temp_free_i64(t2);
3489        }
3490        break;
3491    case OPC_MADDU:
3492        {
3493            TCGv_i64 t2 = tcg_temp_new_i64();
3494            TCGv_i64 t3 = tcg_temp_new_i64();
3495
3496            tcg_gen_ext32u_tl(t0, t0);
3497            tcg_gen_ext32u_tl(t1, t1);
3498            tcg_gen_extu_tl_i64(t2, t0);
3499            tcg_gen_extu_tl_i64(t3, t1);
3500            tcg_gen_mul_i64(t2, t2, t3);
3501            tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
3502            tcg_gen_add_i64(t2, t2, t3);
3503            tcg_temp_free_i64(t3);
3504            gen_move_low32(cpu_LO[acc], t2);
3505            gen_move_high32(cpu_HI[acc], t2);
3506            tcg_temp_free_i64(t2);
3507        }
3508        break;
3509    case OPC_MSUB:
3510        {
3511            TCGv_i64 t2 = tcg_temp_new_i64();
3512            TCGv_i64 t3 = tcg_temp_new_i64();
3513
3514            tcg_gen_ext_tl_i64(t2, t0);
3515            tcg_gen_ext_tl_i64(t3, t1);
3516            tcg_gen_mul_i64(t2, t2, t3);
3517            tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
3518            tcg_gen_sub_i64(t2, t3, t2);
3519            tcg_temp_free_i64(t3);
3520            gen_move_low32(cpu_LO[acc], t2);
3521            gen_move_high32(cpu_HI[acc], t2);
3522            tcg_temp_free_i64(t2);
3523        }
3524        break;
3525    case OPC_MSUBU:
3526        {
3527            TCGv_i64 t2 = tcg_temp_new_i64();
3528            TCGv_i64 t3 = tcg_temp_new_i64();
3529
3530            tcg_gen_ext32u_tl(t0, t0);
3531            tcg_gen_ext32u_tl(t1, t1);
3532            tcg_gen_extu_tl_i64(t2, t0);
3533            tcg_gen_extu_tl_i64(t3, t1);
3534            tcg_gen_mul_i64(t2, t2, t3);
3535            tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
3536            tcg_gen_sub_i64(t2, t3, t2);
3537            tcg_temp_free_i64(t3);
3538            gen_move_low32(cpu_LO[acc], t2);
3539            gen_move_high32(cpu_HI[acc], t2);
3540            tcg_temp_free_i64(t2);
3541        }
3542        break;
3543    default:
3544        MIPS_INVAL("mul/div");
3545        generate_exception_end(ctx, EXCP_RI);
3546        goto out;
3547    }
3548 out:
3549    tcg_temp_free(t0);
3550    tcg_temp_free(t1);
3551}
3552
3553static void gen_mul_vr54xx (DisasContext *ctx, uint32_t opc,
3554                            int rd, int rs, int rt)
3555{
3556    TCGv t0 = tcg_temp_new();
3557    TCGv t1 = tcg_temp_new();
3558
3559    gen_load_gpr(t0, rs);
3560    gen_load_gpr(t1, rt);
3561
3562    switch (opc) {
3563    case OPC_VR54XX_MULS:
3564        gen_helper_muls(t0, cpu_env, t0, t1);
3565        break;
3566    case OPC_VR54XX_MULSU:
3567        gen_helper_mulsu(t0, cpu_env, t0, t1);
3568        break;
3569    case OPC_VR54XX_MACC:
3570        gen_helper_macc(t0, cpu_env, t0, t1);
3571        break;
3572    case OPC_VR54XX_MACCU:
3573        gen_helper_maccu(t0, cpu_env, t0, t1);
3574        break;
3575    case OPC_VR54XX_MSAC:
3576        gen_helper_msac(t0, cpu_env, t0, t1);
3577        break;
3578    case OPC_VR54XX_MSACU:
3579        gen_helper_msacu(t0, cpu_env, t0, t1);
3580        break;
3581    case OPC_VR54XX_MULHI:
3582        gen_helper_mulhi(t0, cpu_env, t0, t1);
3583        break;
3584    case OPC_VR54XX_MULHIU:
3585        gen_helper_mulhiu(t0, cpu_env, t0, t1);
3586        break;
3587    case OPC_VR54XX_MULSHI:
3588        gen_helper_mulshi(t0, cpu_env, t0, t1);
3589        break;
3590    case OPC_VR54XX_MULSHIU:
3591        gen_helper_mulshiu(t0, cpu_env, t0, t1);
3592        break;
3593    case OPC_VR54XX_MACCHI:
3594        gen_helper_macchi(t0, cpu_env, t0, t1);
3595        break;
3596    case OPC_VR54XX_MACCHIU:
3597        gen_helper_macchiu(t0, cpu_env, t0, t1);
3598        break;
3599    case OPC_VR54XX_MSACHI:
3600        gen_helper_msachi(t0, cpu_env, t0, t1);
3601        break;
3602    case OPC_VR54XX_MSACHIU:
3603        gen_helper_msachiu(t0, cpu_env, t0, t1);
3604        break;
3605    default:
3606        MIPS_INVAL("mul vr54xx");
3607        generate_exception_end(ctx, EXCP_RI);
3608        goto out;
3609    }
3610    gen_store_gpr(t0, rd);
3611
3612 out:
3613    tcg_temp_free(t0);
3614    tcg_temp_free(t1);
3615}
3616
3617static void gen_cl (DisasContext *ctx, uint32_t opc,
3618                    int rd, int rs)
3619{
3620    TCGv t0;
3621
3622    if (rd == 0) {
3623        /* Treat as NOP. */
3624        return;
3625    }
3626    t0 = tcg_temp_new();
3627    gen_load_gpr(t0, rs);
3628    switch (opc) {
3629    case OPC_CLO:
3630    case R6_OPC_CLO:
3631        gen_helper_clo(cpu_gpr[rd], t0);
3632        break;
3633    case OPC_CLZ:
3634    case R6_OPC_CLZ:
3635        gen_helper_clz(cpu_gpr[rd], t0);
3636        break;
3637#if defined(TARGET_MIPS64)
3638    case OPC_DCLO:
3639    case R6_OPC_DCLO:
3640        gen_helper_dclo(cpu_gpr[rd], t0);
3641        break;
3642    case OPC_DCLZ:
3643    case R6_OPC_DCLZ:
3644        gen_helper_dclz(cpu_gpr[rd], t0);
3645        break;
3646#endif
3647    }
3648    tcg_temp_free(t0);
3649}
3650
3651/* Godson integer instructions */
3652static void gen_loongson_integer(DisasContext *ctx, uint32_t opc,
3653                                 int rd, int rs, int rt)
3654{
3655    TCGv t0, t1;
3656
3657    if (rd == 0) {
3658        /* Treat as NOP. */
3659        return;
3660    }
3661
3662    switch (opc) {
3663    case OPC_MULT_G_2E:
3664    case OPC_MULT_G_2F:
3665    case OPC_MULTU_G_2E:
3666    case OPC_MULTU_G_2F:
3667#if defined(TARGET_MIPS64)
3668    case OPC_DMULT_G_2E:
3669    case OPC_DMULT_G_2F:
3670    case OPC_DMULTU_G_2E:
3671    case OPC_DMULTU_G_2F:
3672#endif
3673        t0 = tcg_temp_new();
3674        t1 = tcg_temp_new();
3675        break;
3676    default:
3677        t0 = tcg_temp_local_new();
3678        t1 = tcg_temp_local_new();
3679        break;
3680    }
3681
3682    gen_load_gpr(t0, rs);
3683    gen_load_gpr(t1, rt);
3684
3685    switch (opc) {
3686    case OPC_MULT_G_2E:
3687    case OPC_MULT_G_2F:
3688        tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
3689        tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3690        break;
3691    case OPC_MULTU_G_2E:
3692    case OPC_MULTU_G_2F:
3693        tcg_gen_ext32u_tl(t0, t0);
3694        tcg_gen_ext32u_tl(t1, t1);
3695        tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
3696        tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3697        break;
3698    case OPC_DIV_G_2E:
3699    case OPC_DIV_G_2F:
3700        {
3701            TCGLabel *l1 = gen_new_label();
3702            TCGLabel *l2 = gen_new_label();
3703            TCGLabel *l3 = gen_new_label();
3704            tcg_gen_ext32s_tl(t0, t0);
3705            tcg_gen_ext32s_tl(t1, t1);
3706            tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
3707            tcg_gen_movi_tl(cpu_gpr[rd], 0);
3708            tcg_gen_br(l3);
3709            gen_set_label(l1);
3710            tcg_gen_brcondi_tl(TCG_COND_NE, t0, INT_MIN, l2);
3711            tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1, l2);
3712            tcg_gen_mov_tl(cpu_gpr[rd], t0);
3713            tcg_gen_br(l3);
3714            gen_set_label(l2);
3715            tcg_gen_div_tl(cpu_gpr[rd], t0, t1);
3716            tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3717            gen_set_label(l3);
3718        }
3719        break;
3720    case OPC_DIVU_G_2E:
3721    case OPC_DIVU_G_2F:
3722        {
3723            TCGLabel *l1 = gen_new_label();
3724            TCGLabel *l2 = gen_new_label();
3725            tcg_gen_ext32u_tl(t0, t0);
3726            tcg_gen_ext32u_tl(t1, t1);
3727            tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
3728            tcg_gen_movi_tl(cpu_gpr[rd], 0);
3729            tcg_gen_br(l2);
3730            gen_set_label(l1);
3731            tcg_gen_divu_tl(cpu_gpr[rd], t0, t1);
3732            tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3733            gen_set_label(l2);
3734        }
3735        break;
3736    case OPC_MOD_G_2E:
3737    case OPC_MOD_G_2F:
3738        {
3739            TCGLabel *l1 = gen_new_label();
3740            TCGLabel *l2 = gen_new_label();
3741            TCGLabel *l3 = gen_new_label();
3742            tcg_gen_ext32u_tl(t0, t0);
3743            tcg_gen_ext32u_tl(t1, t1);
3744            tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
3745            tcg_gen_brcondi_tl(TCG_COND_NE, t0, INT_MIN, l2);
3746            tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1, l2);
3747            gen_set_label(l1);
3748            tcg_gen_movi_tl(cpu_gpr[rd], 0);
3749            tcg_gen_br(l3);
3750            gen_set_label(l2);
3751            tcg_gen_rem_tl(cpu_gpr[rd], t0, t1);
3752            tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3753            gen_set_label(l3);
3754        }
3755        break;
3756    case OPC_MODU_G_2E:
3757    case OPC_MODU_G_2F:
3758        {
3759            TCGLabel *l1 = gen_new_label();
3760            TCGLabel *l2 = gen_new_label();
3761            tcg_gen_ext32u_tl(t0, t0);
3762            tcg_gen_ext32u_tl(t1, t1);
3763            tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
3764            tcg_gen_movi_tl(cpu_gpr[rd], 0);
3765            tcg_gen_br(l2);
3766            gen_set_label(l1);
3767            tcg_gen_remu_tl(cpu_gpr[rd], t0, t1);
3768            tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3769            gen_set_label(l2);
3770        }
3771        break;
3772#if defined(TARGET_MIPS64)
3773    case OPC_DMULT_G_2E:
3774    case OPC_DMULT_G_2F:
3775        tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
3776        break;
3777    case OPC_DMULTU_G_2E:
3778    case OPC_DMULTU_G_2F:
3779        tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
3780        break;
3781    case OPC_DDIV_G_2E:
3782    case OPC_DDIV_G_2F:
3783        {
3784            TCGLabel *l1 = gen_new_label();
3785            TCGLabel *l2 = gen_new_label();
3786            TCGLabel *l3 = gen_new_label();
3787            tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
3788            tcg_gen_movi_tl(cpu_gpr[rd], 0);
3789            tcg_gen_br(l3);
3790            gen_set_label(l1);
3791            tcg_gen_brcondi_tl(TCG_COND_NE, t0, -1LL << 63, l2);
3792            tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1LL, l2);
3793            tcg_gen_mov_tl(cpu_gpr[rd], t0);
3794            tcg_gen_br(l3);
3795            gen_set_label(l2);
3796            tcg_gen_div_tl(cpu_gpr[rd], t0, t1);
3797            gen_set_label(l3);
3798        }
3799        break;
3800    case OPC_DDIVU_G_2E:
3801    case OPC_DDIVU_G_2F:
3802        {
3803            TCGLabel *l1 = gen_new_label();
3804            TCGLabel *l2 = gen_new_label();
3805            tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
3806            tcg_gen_movi_tl(cpu_gpr[rd], 0);
3807            tcg_gen_br(l2);
3808            gen_set_label(l1);
3809            tcg_gen_divu_tl(cpu_gpr[rd], t0, t1);
3810            gen_set_label(l2);
3811        }
3812        break;
3813    case OPC_DMOD_G_2E:
3814    case OPC_DMOD_G_2F:
3815        {
3816            TCGLabel *l1 = gen_new_label();
3817            TCGLabel *l2 = gen_new_label();
3818            TCGLabel *l3 = gen_new_label();
3819            tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
3820            tcg_gen_brcondi_tl(TCG_COND_NE, t0, -1LL << 63, l2);
3821            tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1LL, l2);
3822            gen_set_label(l1);
3823            tcg_gen_movi_tl(cpu_gpr[rd], 0);
3824            tcg_gen_br(l3);
3825            gen_set_label(l2);
3826            tcg_gen_rem_tl(cpu_gpr[rd], t0, t1);
3827            gen_set_label(l3);
3828        }
3829        break;
3830    case OPC_DMODU_G_2E:
3831    case OPC_DMODU_G_2F:
3832        {
3833            TCGLabel *l1 = gen_new_label();
3834            TCGLabel *l2 = gen_new_label();
3835            tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
3836            tcg_gen_movi_tl(cpu_gpr[rd], 0);
3837            tcg_gen_br(l2);
3838            gen_set_label(l1);
3839            tcg_gen_remu_tl(cpu_gpr[rd], t0, t1);
3840            gen_set_label(l2);
3841        }
3842        break;
3843#endif
3844    }
3845
3846    tcg_temp_free(t0);
3847    tcg_temp_free(t1);
3848}
3849
3850/* Loongson multimedia instructions */
3851static void gen_loongson_multimedia(DisasContext *ctx, int rd, int rs, int rt)
3852{
3853    uint32_t opc, shift_max;
3854    TCGv_i64 t0, t1;
3855
3856    opc = MASK_LMI(ctx->opcode);
3857    switch (opc) {
3858    case OPC_ADD_CP2:
3859    case OPC_SUB_CP2:
3860    case OPC_DADD_CP2:
3861    case OPC_DSUB_CP2:
3862        t0 = tcg_temp_local_new_i64();
3863        t1 = tcg_temp_local_new_i64();
3864        break;
3865    default:
3866        t0 = tcg_temp_new_i64();
3867        t1 = tcg_temp_new_i64();
3868        break;
3869    }
3870
3871    gen_load_fpr64(ctx, t0, rs);
3872    gen_load_fpr64(ctx, t1, rt);
3873
3874#define LMI_HELPER(UP, LO) \
3875    case OPC_##UP: gen_helper_##LO(t0, t0, t1); break
3876#define LMI_HELPER_1(UP, LO) \
3877    case OPC_##UP: gen_helper_##LO(t0, t0); break
3878#define LMI_DIRECT(UP, LO, OP) \
3879    case OPC_##UP: tcg_gen_##OP##_i64(t0, t0, t1); break
3880
3881    switch (opc) {
3882    LMI_HELPER(PADDSH, paddsh);
3883    LMI_HELPER(PADDUSH, paddush);
3884    LMI_HELPER(PADDH, paddh);
3885    LMI_HELPER(PADDW, paddw);
3886    LMI_HELPER(PADDSB, paddsb);
3887    LMI_HELPER(PADDUSB, paddusb);
3888    LMI_HELPER(PADDB, paddb);
3889
3890    LMI_HELPER(PSUBSH, psubsh);
3891    LMI_HELPER(PSUBUSH, psubush);
3892    LMI_HELPER(PSUBH, psubh);
3893    LMI_HELPER(PSUBW, psubw);
3894    LMI_HELPER(PSUBSB, psubsb);
3895    LMI_HELPER(PSUBUSB, psubusb);
3896    LMI_HELPER(PSUBB, psubb);
3897
3898    LMI_HELPER(PSHUFH, pshufh);
3899    LMI_HELPER(PACKSSWH, packsswh);
3900    LMI_HELPER(PACKSSHB, packsshb);
3901    LMI_HELPER(PACKUSHB, packushb);
3902
3903    LMI_HELPER(PUNPCKLHW, punpcklhw);
3904    LMI_HELPER(PUNPCKHHW, punpckhhw);
3905    LMI_HELPER(PUNPCKLBH, punpcklbh);
3906    LMI_HELPER(PUNPCKHBH, punpckhbh);
3907    LMI_HELPER(PUNPCKLWD, punpcklwd);
3908    LMI_HELPER(PUNPCKHWD, punpckhwd);
3909
3910    LMI_HELPER(PAVGH, pavgh);
3911    LMI_HELPER(PAVGB, pavgb);
3912    LMI_HELPER(PMAXSH, pmaxsh);
3913    LMI_HELPER(PMINSH, pminsh);
3914    LMI_HELPER(PMAXUB, pmaxub);
3915    LMI_HELPER(PMINUB, pminub);
3916
3917    LMI_HELPER(PCMPEQW, pcmpeqw);
3918    LMI_HELPER(PCMPGTW, pcmpgtw);
3919    LMI_HELPER(PCMPEQH, pcmpeqh);
3920    LMI_HELPER(PCMPGTH, pcmpgth);
3921    LMI_HELPER(PCMPEQB, pcmpeqb);
3922    LMI_HELPER(PCMPGTB, pcmpgtb);
3923
3924    LMI_HELPER(PSLLW, psllw);
3925    LMI_HELPER(PSLLH, psllh);
3926    LMI_HELPER(PSRLW, psrlw);
3927    LMI_HELPER(PSRLH, psrlh);
3928    LMI_HELPER(PSRAW, psraw);
3929    LMI_HELPER(PSRAH, psrah);
3930
3931    LMI_HELPER(PMULLH, pmullh);
3932    LMI_HELPER(PMULHH, pmulhh);
3933    LMI_HELPER(PMULHUH, pmulhuh);
3934    LMI_HELPER(PMADDHW, pmaddhw);
3935
3936    LMI_HELPER(PASUBUB, pasubub);
3937    LMI_HELPER_1(BIADD, biadd);
3938    LMI_HELPER_1(PMOVMSKB, pmovmskb);
3939
3940    LMI_DIRECT(PADDD, paddd, add);
3941    LMI_DIRECT(PSUBD, psubd, sub);
3942    LMI_DIRECT(XOR_CP2, xor, xor);
3943    LMI_DIRECT(NOR_CP2, nor, nor);
3944    LMI_DIRECT(AND_CP2, and, and);
3945    LMI_DIRECT(PANDN, pandn, andc);
3946    LMI_DIRECT(OR, or, or);
3947
3948    case OPC_PINSRH_0:
3949        tcg_gen_deposit_i64(t0, t0, t1, 0, 16);
3950        break;
3951    case OPC_PINSRH_1:
3952        tcg_gen_deposit_i64(t0, t0, t1, 16, 16);
3953        break;
3954    case OPC_PINSRH_2:
3955        tcg_gen_deposit_i64(t0, t0, t1, 32, 16);
3956        break;
3957    case OPC_PINSRH_3:
3958        tcg_gen_deposit_i64(t0, t0, t1, 48, 16);
3959        break;
3960
3961    case OPC_PEXTRH:
3962        tcg_gen_andi_i64(t1, t1, 3);
3963        tcg_gen_shli_i64(t1, t1, 4);
3964        tcg_gen_shr_i64(t0, t0, t1);
3965        tcg_gen_ext16u_i64(t0, t0);
3966        break;
3967
3968    case OPC_ADDU_CP2:
3969        tcg_gen_add_i64(t0, t0, t1);
3970        tcg_gen_ext32s_i64(t0, t0);
3971        break;
3972    case OPC_SUBU_CP2:
3973        tcg_gen_sub_i64(t0, t0, t1);
3974        tcg_gen_ext32s_i64(t0, t0);
3975        break;
3976
3977    case OPC_SLL_CP2:
3978        shift_max = 32;
3979        goto do_shift;
3980    case OPC_SRL_CP2:
3981        shift_max = 32;
3982        goto do_shift;
3983    case OPC_SRA_CP2:
3984        shift_max = 32;
3985        goto do_shift;
3986    case OPC_DSLL_CP2:
3987        shift_max = 64;
3988        goto do_shift;
3989    case OPC_DSRL_CP2:
3990        shift_max = 64;
3991        goto do_shift;
3992    case OPC_DSRA_CP2:
3993        shift_max = 64;
3994        goto do_shift;
3995    do_shift:
3996        /* Make sure shift count isn't TCG undefined behaviour.  */
3997        tcg_gen_andi_i64(t1, t1, shift_max - 1);
3998
3999        switch (opc) {
4000        case OPC_SLL_CP2:
4001        case OPC_DSLL_CP2:
4002            tcg_gen_shl_i64(t0, t0, t1);
4003            break;
4004        case OPC_SRA_CP2:
4005        case OPC_DSRA_CP2:
4006            /* Since SRA is UndefinedResult without sign-extended inputs,
4007               we can treat SRA and DSRA the same.  */
4008            tcg_gen_sar_i64(t0, t0, t1);
4009            break;
4010        case OPC_SRL_CP2:
4011            /* We want to shift in zeros for SRL; zero-extend first.  */
4012            tcg_gen_ext32u_i64(t0, t0);
4013            /* FALLTHRU */
4014        case OPC_DSRL_CP2:
4015            tcg_gen_shr_i64(t0, t0, t1);
4016            break;
4017        }
4018
4019        if (shift_max == 32) {
4020            tcg_gen_ext32s_i64(t0, t0);
4021        }
4022
4023        /* Shifts larger than MAX produce zero.  */
4024        tcg_gen_setcondi_i64(TCG_COND_LTU, t1, t1, shift_max);
4025        tcg_gen_neg_i64(t1, t1);
4026        tcg_gen_and_i64(t0, t0, t1);
4027        break;
4028
4029    case OPC_ADD_CP2:
4030    case OPC_DADD_CP2:
4031        {
4032            TCGv_i64 t2 = tcg_temp_new_i64();
4033            TCGLabel *lab = gen_new_label();
4034
4035            tcg_gen_mov_i64(t2, t0);
4036            tcg_gen_add_i64(t0, t1, t2);
4037            if (opc == OPC_ADD_CP2) {
4038                tcg_gen_ext32s_i64(t0, t0);
4039            }
4040            tcg_gen_xor_i64(t1, t1, t2);
4041            tcg_gen_xor_i64(t2, t2, t0);
4042            tcg_gen_andc_i64(t1, t2, t1);
4043            tcg_temp_free_i64(t2);
4044            tcg_gen_brcondi_i64(TCG_COND_GE, t1, 0, lab);
4045            generate_exception(ctx, EXCP_OVERFLOW);
4046            gen_set_label(lab);
4047            break;
4048        }
4049
4050    case OPC_SUB_CP2:
4051    case OPC_DSUB_CP2:
4052        {
4053            TCGv_i64 t2 = tcg_temp_new_i64();
4054            TCGLabel *lab = gen_new_label();
4055
4056            tcg_gen_mov_i64(t2, t0);
4057            tcg_gen_sub_i64(t0, t1, t2);
4058            if (opc == OPC_SUB_CP2) {
4059                tcg_gen_ext32s_i64(t0, t0);
4060            }
4061            tcg_gen_xor_i64(t1, t1, t2);
4062            tcg_gen_xor_i64(t2, t2, t0);
4063            tcg_gen_and_i64(t1, t1, t2);
4064            tcg_temp_free_i64(t2);
4065            tcg_gen_brcondi_i64(TCG_COND_GE, t1, 0, lab);
4066            generate_exception(ctx, EXCP_OVERFLOW);
4067            gen_set_label(lab);
4068            break;
4069        }
4070
4071    case OPC_PMULUW:
4072        tcg_gen_ext32u_i64(t0, t0);
4073        tcg_gen_ext32u_i64(t1, t1);
4074        tcg_gen_mul_i64(t0, t0, t1);
4075        break;
4076
4077    case OPC_SEQU_CP2:
4078    case OPC_SEQ_CP2:
4079    case OPC_SLTU_CP2:
4080    case OPC_SLT_CP2:
4081    case OPC_SLEU_CP2:
4082    case OPC_SLE_CP2:
4083        /* ??? Document is unclear: Set FCC[CC].  Does that mean the
4084           FD field is the CC field?  */
4085    default:
4086        MIPS_INVAL("loongson_cp2");
4087        generate_exception_end(ctx, EXCP_RI);
4088        return;
4089    }
4090
4091#undef LMI_HELPER
4092#undef LMI_DIRECT
4093
4094    gen_store_fpr64(ctx, t0, rd);
4095
4096    tcg_temp_free_i64(t0);
4097    tcg_temp_free_i64(t1);
4098}
4099
4100/* Traps */
4101static void gen_trap (DisasContext *ctx, uint32_t opc,
4102                      int rs, int rt, int16_t imm)
4103{
4104    int cond;
4105    TCGv t0 = tcg_temp_new();
4106    TCGv t1 = tcg_temp_new();
4107
4108    cond = 0;
4109    /* Load needed operands */
4110    switch (opc) {
4111    case OPC_TEQ:
4112    case OPC_TGE:
4113    case OPC_TGEU:
4114    case OPC_TLT:
4115    case OPC_TLTU:
4116    case OPC_TNE:
4117        /* Compare two registers */
4118        if (rs != rt) {
4119            gen_load_gpr(t0, rs);
4120            gen_load_gpr(t1, rt);
4121            cond = 1;
4122        }
4123        break;
4124    case OPC_TEQI:
4125    case OPC_TGEI:
4126    case OPC_TGEIU:
4127    case OPC_TLTI:
4128    case OPC_TLTIU:
4129    case OPC_TNEI:
4130        /* Compare register to immediate */
4131        if (rs != 0 || imm != 0) {
4132            gen_load_gpr(t0, rs);
4133            tcg_gen_movi_tl(t1, (int32_t)imm);
4134            cond = 1;
4135        }
4136        break;
4137    }
4138    if (cond == 0) {
4139        switch (opc) {
4140        case OPC_TEQ:   /* rs == rs */
4141        case OPC_TEQI:  /* r0 == 0  */
4142        case OPC_TGE:   /* rs >= rs */
4143        case OPC_TGEI:  /* r0 >= 0  */
4144        case OPC_TGEU:  /* rs >= rs unsigned */
4145        case OPC_TGEIU: /* r0 >= 0  unsigned */
4146            /* Always trap */
4147            generate_exception_end(ctx, EXCP_TRAP);
4148            break;
4149        case OPC_TLT:   /* rs < rs           */
4150        case OPC_TLTI:  /* r0 < 0            */
4151        case OPC_TLTU:  /* rs < rs unsigned  */
4152        case OPC_TLTIU: /* r0 < 0  unsigned  */
4153        case OPC_TNE:   /* rs != rs          */
4154        case OPC_TNEI:  /* r0 != 0           */
4155            /* Never trap: treat as NOP. */
4156            break;
4157        }
4158    } else {
4159        TCGLabel *l1 = gen_new_label();
4160
4161        switch (opc) {
4162        case OPC_TEQ:
4163        case OPC_TEQI:
4164            tcg_gen_brcond_tl(TCG_COND_NE, t0, t1, l1);
4165            break;
4166        case OPC_TGE:
4167        case OPC_TGEI:
4168            tcg_gen_brcond_tl(TCG_COND_LT, t0, t1, l1);
4169            break;
4170        case OPC_TGEU:
4171        case OPC_TGEIU:
4172            tcg_gen_brcond_tl(TCG_COND_LTU, t0, t1, l1);
4173            break;
4174        case OPC_TLT:
4175        case OPC_TLTI:
4176            tcg_gen_brcond_tl(TCG_COND_GE, t0, t1, l1);
4177            break;
4178        case OPC_TLTU:
4179        case OPC_TLTIU:
4180            tcg_gen_brcond_tl(TCG_COND_GEU, t0, t1, l1);
4181            break;
4182        case OPC_TNE:
4183        case OPC_TNEI:
4184            tcg_gen_brcond_tl(TCG_COND_EQ, t0, t1, l1);
4185            break;
4186        }
4187        generate_exception(ctx, EXCP_TRAP);
4188        gen_set_label(l1);
4189    }
4190    tcg_temp_free(t0);
4191    tcg_temp_free(t1);
4192}
4193
4194static inline void gen_goto_tb(DisasContext *ctx, int n, target_ulong dest)
4195{
4196    TranslationBlock *tb;
4197    tb = ctx->tb;
4198    if ((tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK) &&
4199        likely(!ctx->singlestep_enabled)) {
4200        tcg_gen_goto_tb(n);
4201        gen_save_pc(dest);
4202        tcg_gen_exit_tb((uintptr_t)tb + n);
4203    } else {
4204        gen_save_pc(dest);
4205        if (ctx->singlestep_enabled) {
4206            save_cpu_state(ctx, 0);
4207            gen_helper_raise_exception_debug(cpu_env);
4208        }
4209        tcg_gen_exit_tb(0);
4210    }
4211}
4212
4213/* Branches (before delay slot) */
4214static void gen_compute_branch (DisasContext *ctx, uint32_t opc,
4215                                int insn_bytes,
4216                                int rs, int rt, int32_t offset,
4217                                int delayslot_size)
4218{
4219    target_ulong btgt = -1;
4220    int blink = 0;
4221    int bcond_compute = 0;
4222    TCGv t0 = tcg_temp_new();
4223    TCGv t1 = tcg_temp_new();
4224
4225    if (ctx->hflags & MIPS_HFLAG_BMASK) {
4226#ifdef MIPS_DEBUG_DISAS
4227        LOG_DISAS("Branch in delay / forbidden slot at PC 0x"
4228                  TARGET_FMT_lx "\n", ctx->pc);
4229#endif
4230        generate_exception_end(ctx, EXCP_RI);
4231        goto out;
4232    }
4233
4234    /* Load needed operands */
4235    switch (opc) {
4236    case OPC_BEQ:
4237    case OPC_BEQL:
4238    case OPC_BNE:
4239    case OPC_BNEL:
4240        /* Compare two registers */
4241        if (rs != rt) {
4242            gen_load_gpr(t0, rs);
4243            gen_load_gpr(t1, rt);
4244            bcond_compute = 1;
4245        }
4246        btgt = ctx->pc + insn_bytes + offset;
4247        break;
4248    case OPC_BGEZ:
4249    case OPC_BGEZAL:
4250    case OPC_BGEZALL:
4251    case OPC_BGEZL:
4252    case OPC_BGTZ:
4253    case OPC_BGTZL:
4254    case OPC_BLEZ:
4255    case OPC_BLEZL:
4256    case OPC_BLTZ:
4257    case OPC_BLTZAL:
4258    case OPC_BLTZALL:
4259    case OPC_BLTZL:
4260        /* Compare to zero */
4261        if (rs != 0) {
4262            gen_load_gpr(t0, rs);
4263            bcond_compute = 1;
4264        }
4265        btgt = ctx->pc + insn_bytes + offset;
4266        break;
4267    case OPC_BPOSGE32:
4268#if defined(TARGET_MIPS64)
4269    case OPC_BPOSGE64:
4270        tcg_gen_andi_tl(t0, cpu_dspctrl, 0x7F);
4271#else
4272        tcg_gen_andi_tl(t0, cpu_dspctrl, 0x3F);
4273#endif
4274        bcond_compute = 1;
4275        btgt = ctx->pc + insn_bytes + offset;
4276        break;
4277    case OPC_J:
4278    case OPC_JAL:
4279    case OPC_JALX:
4280        /* Jump to immediate */
4281        btgt = ((ctx->pc + insn_bytes) & (int32_t)0xF0000000) | (uint32_t)offset;
4282        break;
4283    case OPC_JR:
4284    case OPC_JALR:
4285        /* Jump to register */
4286        if (offset != 0 && offset != 16) {
4287            /* Hint = 0 is JR/JALR, hint 16 is JR.HB/JALR.HB, the
4288               others are reserved. */
4289            MIPS_INVAL("jump hint");
4290            generate_exception_end(ctx, EXCP_RI);
4291            goto out;
4292        }
4293        gen_load_gpr(btarget, rs);
4294        break;
4295    default:
4296        MIPS_INVAL("branch/jump");
4297        generate_exception_end(ctx, EXCP_RI);
4298        goto out;
4299    }
4300    if (bcond_compute == 0) {
4301        /* No condition to be computed */
4302        switch (opc) {
4303        case OPC_BEQ:     /* rx == rx        */
4304        case OPC_BEQL:    /* rx == rx likely */
4305        case OPC_BGEZ:    /* 0 >= 0          */
4306        case OPC_BGEZL:   /* 0 >= 0 likely   */
4307        case OPC_BLEZ:    /* 0 <= 0          */
4308        case OPC_BLEZL:   /* 0 <= 0 likely   */
4309            /* Always take */
4310            ctx->hflags |= MIPS_HFLAG_B;
4311            break;
4312        case OPC_BGEZAL:  /* 0 >= 0          */
4313        case OPC_BGEZALL: /* 0 >= 0 likely   */
4314            /* Always take and link */
4315            blink = 31;
4316            ctx->hflags |= MIPS_HFLAG_B;
4317            break;
4318        case OPC_BNE:     /* rx != rx        */
4319        case OPC_BGTZ:    /* 0 > 0           */
4320        case OPC_BLTZ:    /* 0 < 0           */
4321            /* Treat as NOP. */
4322            goto out;
4323        case OPC_BLTZAL:  /* 0 < 0           */
4324            /* Handle as an unconditional branch to get correct delay
4325               slot checking.  */
4326            blink = 31;
4327            btgt = ctx->pc + insn_bytes + delayslot_size;
4328            ctx->hflags |= MIPS_HFLAG_B;
4329            break;
4330        case OPC_BLTZALL: /* 0 < 0 likely */
4331            tcg_gen_movi_tl(cpu_gpr[31], ctx->pc + 8);
4332            /* Skip the instruction in the delay slot */
4333            ctx->pc += 4;
4334            goto out;
4335        case OPC_BNEL:    /* rx != rx likely */
4336        case OPC_BGTZL:   /* 0 > 0 likely */
4337        case OPC_BLTZL:   /* 0 < 0 likely */
4338            /* Skip the instruction in the delay slot */
4339            ctx->pc += 4;
4340            goto out;
4341        case OPC_J:
4342            ctx->hflags |= MIPS_HFLAG_B;
4343            break;
4344        case OPC_JALX:
4345            ctx->hflags |= MIPS_HFLAG_BX;
4346            /* Fallthrough */
4347        case OPC_JAL:
4348            blink = 31;
4349            ctx->hflags |= MIPS_HFLAG_B;
4350            break;
4351        case OPC_JR:
4352            ctx->hflags |= MIPS_HFLAG_BR;
4353            break;
4354        case OPC_JALR:
4355            blink = rt;
4356            ctx->hflags |= MIPS_HFLAG_BR;
4357            break;
4358        default:
4359            MIPS_INVAL("branch/jump");
4360            generate_exception_end(ctx, EXCP_RI);
4361            goto out;
4362        }
4363    } else {
4364        switch (opc) {
4365        case OPC_BEQ:
4366            tcg_gen_setcond_tl(TCG_COND_EQ, bcond, t0, t1);
4367            goto not_likely;
4368        case OPC_BEQL:
4369            tcg_gen_setcond_tl(TCG_COND_EQ, bcond, t0, t1);
4370            goto likely;
4371        case OPC_BNE:
4372            tcg_gen_setcond_tl(TCG_COND_NE, bcond, t0, t1);
4373            goto not_likely;
4374        case OPC_BNEL:
4375            tcg_gen_setcond_tl(TCG_COND_NE, bcond, t0, t1);
4376            goto likely;
4377        case OPC_BGEZ:
4378            tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
4379            goto not_likely;
4380        case OPC_BGEZL:
4381            tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
4382            goto likely;
4383        case OPC_BGEZAL:
4384            tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
4385            blink = 31;
4386            goto not_likely;
4387        case OPC_BGEZALL:
4388            tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
4389            blink = 31;
4390            goto likely;
4391        case OPC_BGTZ:
4392            tcg_gen_setcondi_tl(TCG_COND_GT, bcond, t0, 0);
4393            goto not_likely;
4394        case OPC_BGTZL:
4395            tcg_gen_setcondi_tl(TCG_COND_GT, bcond, t0, 0);
4396            goto likely;
4397        case OPC_BLEZ:
4398            tcg_gen_setcondi_tl(TCG_COND_LE, bcond, t0, 0);
4399            goto not_likely;
4400        case OPC_BLEZL:
4401            tcg_gen_setcondi_tl(TCG_COND_LE, bcond, t0, 0);
4402            goto likely;
4403        case OPC_BLTZ:
4404            tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
4405            goto not_likely;
4406        case OPC_BLTZL:
4407            tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
4408            goto likely;
4409        case OPC_BPOSGE32:
4410            tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 32);
4411            goto not_likely;
4412#if defined(TARGET_MIPS64)
4413        case OPC_BPOSGE64:
4414            tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 64);
4415            goto not_likely;
4416#endif
4417        case OPC_BLTZAL:
4418            tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
4419            blink = 31;
4420        not_likely:
4421            ctx->hflags |= MIPS_HFLAG_BC;
4422            break;
4423        case OPC_BLTZALL:
4424            tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
4425            blink = 31;
4426        likely:
4427            ctx->hflags |= MIPS_HFLAG_BL;
4428            break;
4429        default:
4430            MIPS_INVAL("conditional branch/jump");
4431            generate_exception_end(ctx, EXCP_RI);
4432            goto out;
4433        }
4434    }
4435
4436    ctx->btarget = btgt;
4437
4438    switch (delayslot_size) {
4439    case 2:
4440        ctx->hflags |= MIPS_HFLAG_BDS16;
4441        break;
4442    case 4:
4443        ctx->hflags |= MIPS_HFLAG_BDS32;
4444        break;
4445    }
4446
4447    if (blink > 0) {
4448        int post_delay = insn_bytes + delayslot_size;
4449        int lowbit = !!(ctx->hflags & MIPS_HFLAG_M16);
4450
4451        tcg_gen_movi_tl(cpu_gpr[blink], ctx->pc + post_delay + lowbit);
4452    }
4453
4454 out:
4455    if (insn_bytes == 2)
4456        ctx->hflags |= MIPS_HFLAG_B16;
4457    tcg_temp_free(t0);
4458    tcg_temp_free(t1);
4459}
4460
4461/* special3 bitfield operations */
4462static void gen_bitops (DisasContext *ctx, uint32_t opc, int rt,
4463                        int rs, int lsb, int msb)
4464{
4465    TCGv t0 = tcg_temp_new();
4466    TCGv t1 = tcg_temp_new();
4467
4468    gen_load_gpr(t1, rs);
4469    switch (opc) {
4470    case OPC_EXT:
4471        if (lsb + msb > 31) {
4472            goto fail;
4473        }
4474        tcg_gen_shri_tl(t0, t1, lsb);
4475        if (msb != 31) {
4476            tcg_gen_andi_tl(t0, t0, (1U << (msb + 1)) - 1);
4477        } else {
4478            tcg_gen_ext32s_tl(t0, t0);
4479        }
4480        break;
4481#if defined(TARGET_MIPS64)
4482    case OPC_DEXTU:
4483        lsb += 32;
4484        goto do_dext;
4485    case OPC_DEXTM:
4486        msb += 32;
4487        goto do_dext;
4488    case OPC_DEXT:
4489    do_dext:
4490        if (lsb + msb > 63) {
4491            goto fail;
4492        }
4493        tcg_gen_shri_tl(t0, t1, lsb);
4494        if (msb != 63) {
4495            tcg_gen_andi_tl(t0, t0, (1ULL << (msb + 1)) - 1);
4496        }
4497        break;
4498#endif
4499    case OPC_INS:
4500        if (lsb > msb) {
4501            goto fail;
4502        }
4503        gen_load_gpr(t0, rt);
4504        tcg_gen_deposit_tl(t0, t0, t1, lsb, msb - lsb + 1);
4505        tcg_gen_ext32s_tl(t0, t0);
4506        break;
4507#if defined(TARGET_MIPS64)
4508    case OPC_DINSU:
4509        lsb += 32;
4510        /* FALLTHRU */
4511    case OPC_DINSM:
4512        msb += 32;
4513        /* FALLTHRU */
4514    case OPC_DINS:
4515        if (lsb > msb) {
4516            goto fail;
4517        }
4518        gen_load_gpr(t0, rt);
4519        tcg_gen_deposit_tl(t0, t0, t1, lsb, msb - lsb + 1);
4520        break;
4521#endif
4522    default:
4523fail:
4524        MIPS_INVAL("bitops");
4525        generate_exception_end(ctx, EXCP_RI);
4526        tcg_temp_free(t0);
4527        tcg_temp_free(t1);
4528        return;
4529    }
4530    gen_store_gpr(t0, rt);
4531    tcg_temp_free(t0);
4532    tcg_temp_free(t1);
4533}
4534
4535static void gen_bshfl (DisasContext *ctx, uint32_t op2, int rt, int rd)
4536{
4537    TCGv t0;
4538
4539    if (rd == 0) {
4540        /* If no destination, treat it as a NOP. */
4541        return;
4542    }
4543
4544    t0 = tcg_temp_new();
4545    gen_load_gpr(t0, rt);
4546    switch (op2) {
4547    case OPC_WSBH:
4548        {
4549            TCGv t1 = tcg_temp_new();
4550
4551            tcg_gen_shri_tl(t1, t0, 8);
4552            tcg_gen_andi_tl(t1, t1, 0x00FF00FF);
4553            tcg_gen_shli_tl(t0, t0, 8);
4554            tcg_gen_andi_tl(t0, t0, ~0x00FF00FF);
4555            tcg_gen_or_tl(t0, t0, t1);
4556            tcg_temp_free(t1);
4557            tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
4558        }
4559        break;
4560    case OPC_SEB:
4561        tcg_gen_ext8s_tl(cpu_gpr[rd], t0);
4562        break;
4563    case OPC_SEH:
4564        tcg_gen_ext16s_tl(cpu_gpr[rd], t0);
4565        break;
4566#if defined(TARGET_MIPS64)
4567    case OPC_DSBH:
4568        {
4569            TCGv t1 = tcg_temp_new();
4570
4571            tcg_gen_shri_tl(t1, t0, 8);
4572            tcg_gen_andi_tl(t1, t1, 0x00FF00FF00FF00FFULL);
4573            tcg_gen_shli_tl(t0, t0, 8);
4574            tcg_gen_andi_tl(t0, t0, ~0x00FF00FF00FF00FFULL);
4575            tcg_gen_or_tl(cpu_gpr[rd], t0, t1);
4576            tcg_temp_free(t1);
4577        }
4578        break;
4579    case OPC_DSHD:
4580        {
4581            TCGv t1 = tcg_temp_new();
4582
4583            tcg_gen_shri_tl(t1, t0, 16);
4584            tcg_gen_andi_tl(t1, t1, 0x0000FFFF0000FFFFULL);
4585            tcg_gen_shli_tl(t0, t0, 16);
4586            tcg_gen_andi_tl(t0, t0, ~0x0000FFFF0000FFFFULL);
4587            tcg_gen_or_tl(t0, t0, t1);
4588            tcg_gen_shri_tl(t1, t0, 32);
4589            tcg_gen_shli_tl(t0, t0, 32);
4590            tcg_gen_or_tl(cpu_gpr[rd], t0, t1);
4591            tcg_temp_free(t1);
4592        }
4593        break;
4594#endif
4595    default:
4596        MIPS_INVAL("bsfhl");
4597        generate_exception_end(ctx, EXCP_RI);
4598        tcg_temp_free(t0);
4599        return;
4600    }
4601    tcg_temp_free(t0);
4602}
4603
4604static void gen_lsa(DisasContext *ctx, int opc, int rd, int rs, int rt,
4605                    int imm2)
4606{
4607    TCGv t0;
4608    TCGv t1;
4609    if (rd == 0) {
4610        /* Treat as NOP. */
4611        return;
4612    }
4613    t0 = tcg_temp_new();
4614    t1 = tcg_temp_new();
4615    gen_load_gpr(t0, rs);
4616    gen_load_gpr(t1, rt);
4617    tcg_gen_shli_tl(t0, t0, imm2 + 1);
4618    tcg_gen_add_tl(cpu_gpr[rd], t0, t1);
4619    if (opc == OPC_LSA) {
4620        tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
4621    }
4622
4623    tcg_temp_free(t1);
4624    tcg_temp_free(t0);
4625
4626    return;
4627}
4628
4629static void gen_align(DisasContext *ctx, int opc, int rd, int rs, int rt,
4630                      int bp)
4631{
4632    TCGv t0;
4633    if (rd == 0) {
4634        /* Treat as NOP. */
4635        return;
4636    }
4637    t0 = tcg_temp_new();
4638    gen_load_gpr(t0, rt);
4639    if (bp == 0) {
4640        switch (opc) {
4641        case OPC_ALIGN:
4642            tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
4643            break;
4644#if defined(TARGET_MIPS64)
4645        case OPC_DALIGN:
4646            tcg_gen_mov_tl(cpu_gpr[rd], t0);
4647            break;
4648#endif
4649        }
4650    } else {
4651        TCGv t1 = tcg_temp_new();
4652        gen_load_gpr(t1, rs);
4653        switch (opc) {
4654        case OPC_ALIGN:
4655            {
4656                TCGv_i64 t2 = tcg_temp_new_i64();
4657                tcg_gen_concat_tl_i64(t2, t1, t0);
4658                tcg_gen_shri_i64(t2, t2, 8 * (4 - bp));
4659                gen_move_low32(cpu_gpr[rd], t2);
4660                tcg_temp_free_i64(t2);
4661            }
4662            break;
4663#if defined(TARGET_MIPS64)
4664        case OPC_DALIGN:
4665            tcg_gen_shli_tl(t0, t0, 8 * bp);
4666            tcg_gen_shri_tl(t1, t1, 8 * (8 - bp));
4667            tcg_gen_or_tl(cpu_gpr[rd], t1, t0);
4668            break;
4669#endif
4670        }
4671        tcg_temp_free(t1);
4672    }
4673
4674    tcg_temp_free(t0);
4675}
4676
4677static void gen_bitswap(DisasContext *ctx, int opc, int rd, int rt)
4678{
4679    TCGv t0;
4680    if (rd == 0) {
4681        /* Treat as NOP. */
4682        return;
4683    }
4684    t0 = tcg_temp_new();
4685    gen_load_gpr(t0, rt);
4686    switch (opc) {
4687    case OPC_BITSWAP:
4688        gen_helper_bitswap(cpu_gpr[rd], t0);
4689        break;
4690#if defined(TARGET_MIPS64)
4691    case OPC_DBITSWAP:
4692        gen_helper_dbitswap(cpu_gpr[rd], t0);
4693        break;
4694#endif
4695    }
4696    tcg_temp_free(t0);
4697}
4698
4699#ifndef CONFIG_USER_ONLY
4700/* CP0 (MMU and control) */
4701static inline void gen_mthc0_entrylo(TCGv arg, target_ulong off)
4702{
4703    TCGv_i64 t0 = tcg_temp_new_i64();
4704    TCGv_i64 t1 = tcg_temp_new_i64();
4705
4706    tcg_gen_ext_tl_i64(t0, arg);
4707    tcg_gen_ld_i64(t1, cpu_env, off);
4708#if defined(TARGET_MIPS64)
4709    tcg_gen_deposit_i64(t1, t1, t0, 30, 32);
4710#else
4711    tcg_gen_concat32_i64(t1, t1, t0);
4712#endif
4713    tcg_gen_st_i64(t1, cpu_env, off);
4714    tcg_temp_free_i64(t1);
4715    tcg_temp_free_i64(t0);
4716}
4717
4718static inline void gen_mthc0_store64(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    tcg_gen_concat32_i64(t1, t1, t0);
4726    tcg_gen_st_i64(t1, cpu_env, off);
4727    tcg_temp_free_i64(t1);
4728    tcg_temp_free_i64(t0);
4729}
4730
4731static inline void gen_mfhc0_entrylo(TCGv arg, target_ulong off)
4732{
4733    TCGv_i64 t0 = tcg_temp_new_i64();
4734
4735    tcg_gen_ld_i64(t0, cpu_env, off);
4736#if defined(TARGET_MIPS64)
4737    tcg_gen_shri_i64(t0, t0, 30);
4738#else
4739    tcg_gen_shri_i64(t0, t0, 32);
4740#endif
4741    gen_move_low32(arg, t0);
4742    tcg_temp_free_i64(t0);
4743}
4744
4745static inline void gen_mfhc0_load64(TCGv arg, target_ulong off, int shift)
4746{
4747    TCGv_i64 t0 = tcg_temp_new_i64();
4748
4749    tcg_gen_ld_i64(t0, cpu_env, off);
4750    tcg_gen_shri_i64(t0, t0, 32 + shift);
4751    gen_move_low32(arg, t0);
4752    tcg_temp_free_i64(t0);
4753}
4754
4755static inline void gen_mfc0_load32 (TCGv arg, target_ulong off)
4756{
4757    TCGv_i32 t0 = tcg_temp_new_i32();
4758
4759    tcg_gen_ld_i32(t0, cpu_env, off);
4760    tcg_gen_ext_i32_tl(arg, t0);
4761    tcg_temp_free_i32(t0);
4762}
4763
4764static inline void gen_mfc0_load64 (TCGv arg, target_ulong off)
4765{
4766    tcg_gen_ld_tl(arg, cpu_env, off);
4767    tcg_gen_ext32s_tl(arg, arg);
4768}
4769
4770static inline void gen_mtc0_store32 (TCGv arg, target_ulong off)
4771{
4772    TCGv_i32 t0 = tcg_temp_new_i32();
4773
4774    tcg_gen_trunc_tl_i32(t0, arg);
4775    tcg_gen_st_i32(t0, cpu_env, off);
4776    tcg_temp_free_i32(t0);
4777}
4778
4779#define CP0_CHECK(c)                            \
4780    do {                                        \
4781        if (!(c)) {                             \
4782            goto cp0_unimplemented;             \
4783        }                                       \
4784    } while (0)
4785
4786static void gen_mfhc0(DisasContext *ctx, TCGv arg, int reg, int sel)
4787{
4788    const char *rn = "invalid";
4789
4790    CP0_CHECK(ctx->hflags & MIPS_HFLAG_ELPA);
4791
4792    switch (reg) {
4793    case 2:
4794        switch (sel) {
4795        case 0:
4796            gen_mfhc0_entrylo(arg, offsetof(CPUMIPSState, CP0_EntryLo0));
4797            rn = "EntryLo0";
4798            break;
4799        default:
4800            goto cp0_unimplemented;
4801        }
4802        break;
4803    case 3:
4804        switch (sel) {
4805        case 0:
4806            gen_mfhc0_entrylo(arg, offsetof(CPUMIPSState, CP0_EntryLo1));
4807            rn = "EntryLo1";
4808            break;
4809        default:
4810            goto cp0_unimplemented;
4811        }
4812        break;
4813    case 17:
4814        switch (sel) {
4815        case 0:
4816            gen_mfhc0_load64(arg, offsetof(CPUMIPSState, lladdr),
4817                             ctx->CP0_LLAddr_shift);
4818            rn = "LLAddr";
4819            break;
4820        case 1:
4821            CP0_CHECK(ctx->mrp);
4822            gen_helper_mfhc0_maar(arg, cpu_env);
4823            rn = "MAAR";
4824            break;
4825        default:
4826            goto cp0_unimplemented;
4827        }
4828        break;
4829    case 28:
4830        switch (sel) {
4831        case 0:
4832        case 2:
4833        case 4:
4834        case 6:
4835            gen_mfhc0_load64(arg, offsetof(CPUMIPSState, CP0_TagLo), 0);
4836            rn = "TagLo";
4837            break;
4838        default:
4839            goto cp0_unimplemented;
4840        }
4841        break;
4842    default:
4843        goto cp0_unimplemented;
4844    }
4845
4846    (void)rn; /* avoid a compiler warning */
4847    LOG_DISAS("mfhc0 %s (reg %d sel %d)\n", rn, reg, sel);
4848    return;
4849
4850cp0_unimplemented:
4851    LOG_DISAS("mfhc0 %s (reg %d sel %d)\n", rn, reg, sel);
4852    tcg_gen_movi_tl(arg, 0);
4853}
4854
4855static void gen_mthc0(DisasContext *ctx, TCGv arg, int reg, int sel)
4856{
4857    const char *rn = "invalid";
4858    uint64_t mask = ctx->PAMask >> 36;
4859
4860    CP0_CHECK(ctx->hflags & MIPS_HFLAG_ELPA);
4861
4862    switch (reg) {
4863    case 2:
4864        switch (sel) {
4865        case 0:
4866            tcg_gen_andi_tl(arg, arg, mask);
4867            gen_mthc0_entrylo(arg, offsetof(CPUMIPSState, CP0_EntryLo0));
4868            rn = "EntryLo0";
4869            break;
4870        default:
4871            goto cp0_unimplemented;
4872        }
4873        break;
4874    case 3:
4875        switch (sel) {
4876        case 0:
4877            tcg_gen_andi_tl(arg, arg, mask);
4878            gen_mthc0_entrylo(arg, offsetof(CPUMIPSState, CP0_EntryLo1));
4879            rn = "EntryLo1";
4880            break;
4881        default:
4882            goto cp0_unimplemented;
4883        }
4884        break;
4885    case 17:
4886        switch (sel) {
4887        case 0:
4888            /* LLAddr is read-only (the only exception is bit 0 if LLB is
4889               supported); the CP0_LLAddr_rw_bitmask does not seem to be
4890               relevant for modern MIPS cores supporting MTHC0, therefore
4891               treating MTHC0 to LLAddr as NOP. */
4892            rn = "LLAddr";
4893            break;
4894        case 1:
4895            CP0_CHECK(ctx->mrp);
4896            gen_helper_mthc0_maar(cpu_env, arg);
4897            rn = "MAAR";
4898            break;
4899        default:
4900            goto cp0_unimplemented;
4901        }
4902        break;
4903    case 28:
4904        switch (sel) {
4905        case 0:
4906        case 2:
4907        case 4:
4908        case 6:
4909            tcg_gen_andi_tl(arg, arg, mask);
4910            gen_mthc0_store64(arg, offsetof(CPUMIPSState, CP0_TagLo));
4911            rn = "TagLo";
4912            break;
4913        default:
4914            goto cp0_unimplemented;
4915        }
4916        break;
4917    default:
4918        goto cp0_unimplemented;
4919    }
4920
4921    (void)rn; /* avoid a compiler warning */
4922cp0_unimplemented:
4923    LOG_DISAS("mthc0 %s (reg %d sel %d)\n", rn, reg, sel);
4924}
4925
4926static inline void gen_mfc0_unimplemented(DisasContext *ctx, TCGv arg)
4927{
4928    if (ctx->insn_flags & ISA_MIPS32R6) {
4929        tcg_gen_movi_tl(arg, 0);
4930    } else {
4931        tcg_gen_movi_tl(arg, ~0);
4932    }
4933}
4934
4935static void gen_mfc0(DisasContext *ctx, TCGv arg, int reg, int sel)
4936{
4937    const char *rn = "invalid";
4938
4939    if (sel != 0)
4940        check_insn(ctx, ISA_MIPS32);
4941
4942    switch (reg) {
4943    case 0:
4944        switch (sel) {
4945        case 0:
4946            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Index));
4947            rn = "Index";
4948            break;
4949        case 1:
4950            CP0_CHECK(ctx->insn_flags & ASE_MT);
4951            gen_helper_mfc0_mvpcontrol(arg, cpu_env);
4952            rn = "MVPControl";
4953            break;
4954        case 2:
4955            CP0_CHECK(ctx->insn_flags & ASE_MT);
4956            gen_helper_mfc0_mvpconf0(arg, cpu_env);
4957            rn = "MVPConf0";
4958            break;
4959        case 3:
4960            CP0_CHECK(ctx->insn_flags & ASE_MT);
4961            gen_helper_mfc0_mvpconf1(arg, cpu_env);
4962            rn = "MVPConf1";
4963            break;
4964        case 4:
4965            CP0_CHECK(ctx->vp);
4966            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPControl));
4967            rn = "VPControl";
4968            break;
4969        default:
4970            goto cp0_unimplemented;
4971        }
4972        break;
4973    case 1:
4974        switch (sel) {
4975        case 0:
4976            CP0_CHECK(!(ctx->insn_flags & ISA_MIPS32R6));
4977            gen_helper_mfc0_random(arg, cpu_env);
4978            rn = "Random";
4979            break;
4980        case 1:
4981            CP0_CHECK(ctx->insn_flags & ASE_MT);
4982            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEControl));
4983            rn = "VPEControl";
4984            break;
4985        case 2:
4986            CP0_CHECK(ctx->insn_flags & ASE_MT);
4987            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf0));
4988            rn = "VPEConf0";
4989            break;
4990        case 3:
4991            CP0_CHECK(ctx->insn_flags & ASE_MT);
4992            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf1));
4993            rn = "VPEConf1";
4994            break;
4995        case 4:
4996            CP0_CHECK(ctx->insn_flags & ASE_MT);
4997            gen_mfc0_load64(arg, offsetof(CPUMIPSState, CP0_YQMask));
4998            rn = "YQMask";
4999            break;
5000        case 5:
5001            CP0_CHECK(ctx->insn_flags & ASE_MT);
5002            gen_mfc0_load64(arg, offsetof(CPUMIPSState, CP0_VPESchedule));
5003            rn = "VPESchedule";
5004            break;
5005        case 6:
5006            CP0_CHECK(ctx->insn_flags & ASE_MT);
5007            gen_mfc0_load64(arg, offsetof(CPUMIPSState, CP0_VPEScheFBack));
5008            rn = "VPEScheFBack";
5009            break;
5010        case 7:
5011            CP0_CHECK(ctx->insn_flags & ASE_MT);
5012            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEOpt));
5013            rn = "VPEOpt";
5014            break;
5015        default:
5016            goto cp0_unimplemented;
5017        }
5018        break;
5019    case 2:
5020        switch (sel) {
5021        case 0:
5022            {
5023                TCGv_i64 tmp = tcg_temp_new_i64();
5024                tcg_gen_ld_i64(tmp, cpu_env,
5025                               offsetof(CPUMIPSState, CP0_EntryLo0));
5026#if defined(TARGET_MIPS64)
5027                if (ctx->rxi) {
5028                    /* Move RI/XI fields to bits 31:30 */
5029                    tcg_gen_shri_tl(arg, tmp, CP0EnLo_XI);
5030                    tcg_gen_deposit_tl(tmp, tmp, arg, 30, 2);
5031                }
5032#endif
5033                gen_move_low32(arg, tmp);
5034                tcg_temp_free_i64(tmp);
5035            }
5036            rn = "EntryLo0";
5037            break;
5038        case 1:
5039            CP0_CHECK(ctx->insn_flags & ASE_MT);
5040            gen_helper_mfc0_tcstatus(arg, cpu_env);
5041            rn = "TCStatus";
5042            break;
5043        case 2:
5044            CP0_CHECK(ctx->insn_flags & ASE_MT);
5045            gen_helper_mfc0_tcbind(arg, cpu_env);
5046            rn = "TCBind";
5047            break;
5048        case 3:
5049            CP0_CHECK(ctx->insn_flags & ASE_MT);
5050            gen_helper_mfc0_tcrestart(arg, cpu_env);
5051            rn = "TCRestart";
5052            break;
5053        case 4:
5054            CP0_CHECK(ctx->insn_flags & ASE_MT);
5055            gen_helper_mfc0_tchalt(arg, cpu_env);
5056            rn = "TCHalt";
5057            break;
5058        case 5:
5059            CP0_CHECK(ctx->insn_flags & ASE_MT);
5060            gen_helper_mfc0_tccontext(arg, cpu_env);
5061            rn = "TCContext";
5062            break;
5063        case 6:
5064            CP0_CHECK(ctx->insn_flags & ASE_MT);
5065            gen_helper_mfc0_tcschedule(arg, cpu_env);
5066            rn = "TCSchedule";
5067            break;
5068        case 7:
5069            CP0_CHECK(ctx->insn_flags & ASE_MT);
5070            gen_helper_mfc0_tcschefback(arg, cpu_env);
5071            rn = "TCScheFBack";
5072            break;
5073        default:
5074            goto cp0_unimplemented;
5075        }
5076        break;
5077    case 3:
5078        switch (sel) {
5079        case 0:
5080            {
5081                TCGv_i64 tmp = tcg_temp_new_i64();
5082                tcg_gen_ld_i64(tmp, cpu_env,
5083                               offsetof(CPUMIPSState, CP0_EntryLo1));
5084#if defined(TARGET_MIPS64)
5085                if (ctx->rxi) {
5086                    /* Move RI/XI fields to bits 31:30 */
5087                    tcg_gen_shri_tl(arg, tmp, CP0EnLo_XI);
5088                    tcg_gen_deposit_tl(tmp, tmp, arg, 30, 2);
5089                }
5090#endif
5091                gen_move_low32(arg, tmp);
5092                tcg_temp_free_i64(tmp);
5093            }
5094            rn = "EntryLo1";
5095            break;
5096        case 1:
5097            CP0_CHECK(ctx->vp);
5098            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_GlobalNumber));
5099            rn = "GlobalNumber";
5100            break;
5101        default:
5102            goto cp0_unimplemented;
5103        }
5104        break;
5105    case 4:
5106        switch (sel) {
5107        case 0:
5108            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_Context));
5109            tcg_gen_ext32s_tl(arg, arg);
5110            rn = "Context";
5111            break;
5112        case 1:
5113//            gen_helper_mfc0_contextconfig(arg); /* SmartMIPS ASE */
5114            rn = "ContextConfig";
5115            goto cp0_unimplemented;
5116//            break;
5117        case 2:
5118            CP0_CHECK(ctx->ulri);
5119            tcg_gen_ld32s_tl(arg, cpu_env,
5120                             offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
5121            rn = "UserLocal";
5122            break;
5123        default:
5124            goto cp0_unimplemented;
5125        }
5126        break;
5127    case 5:
5128        switch (sel) {
5129        case 0:
5130            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageMask));
5131            rn = "PageMask";
5132            break;
5133        case 1:
5134            check_insn(ctx, ISA_MIPS32R2);
5135            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageGrain));
5136            rn = "PageGrain";
5137            break;
5138        default:
5139            goto cp0_unimplemented;
5140        }
5141        break;
5142    case 6:
5143        switch (sel) {
5144        case 0:
5145            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Wired));
5146            rn = "Wired";
5147            break;
5148        case 1:
5149            check_insn(ctx, ISA_MIPS32R2);
5150            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf0));
5151            rn = "SRSConf0";
5152            break;
5153        case 2:
5154            check_insn(ctx, ISA_MIPS32R2);
5155            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf1));
5156            rn = "SRSConf1";
5157            break;
5158        case 3:
5159            check_insn(ctx, ISA_MIPS32R2);
5160            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf2));
5161            rn = "SRSConf2";
5162            break;
5163        case 4:
5164            check_insn(ctx, ISA_MIPS32R2);
5165            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf3));
5166            rn = "SRSConf3";
5167            break;
5168        case 5:
5169            check_insn(ctx, ISA_MIPS32R2);
5170            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf4));
5171            rn = "SRSConf4";
5172            break;
5173        default:
5174            goto cp0_unimplemented;
5175        }
5176        break;
5177    case 7:
5178        switch (sel) {
5179        case 0:
5180            check_insn(ctx, ISA_MIPS32R2);
5181            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_HWREna));
5182            rn = "HWREna";
5183            break;
5184        default:
5185            goto cp0_unimplemented;
5186        }
5187        break;
5188    case 8:
5189        switch (sel) {
5190        case 0:
5191            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_BadVAddr));
5192            tcg_gen_ext32s_tl(arg, arg);
5193            rn = "BadVAddr";
5194            break;
5195        case 1:
5196            CP0_CHECK(ctx->bi);
5197            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_BadInstr));
5198            rn = "BadInstr";
5199            break;
5200        case 2:
5201            CP0_CHECK(ctx->bp);
5202            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_BadInstrP));
5203            rn = "BadInstrP";
5204            break;
5205        default:
5206            goto cp0_unimplemented;
5207        }
5208        break;
5209    case 9:
5210        switch (sel) {
5211        case 0:
5212            /* Mark as an IO operation because we read the time.  */
5213            if (ctx->tb->cflags & CF_USE_ICOUNT) {
5214                gen_io_start();
5215            }
5216            gen_helper_mfc0_count(arg, cpu_env);
5217            if (ctx->tb->cflags & CF_USE_ICOUNT) {
5218                gen_io_end();
5219            }
5220            /* Break the TB to be able to take timer interrupts immediately
5221               after reading count.  */
5222            ctx->bstate = BS_STOP;
5223            rn = "Count";
5224            break;
5225        /* 6,7 are implementation dependent */
5226        default:
5227            goto cp0_unimplemented;
5228        }
5229        break;
5230    case 10:
5231        switch (sel) {
5232        case 0:
5233            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryHi));
5234            tcg_gen_ext32s_tl(arg, arg);
5235            rn = "EntryHi";
5236            break;
5237        default:
5238            goto cp0_unimplemented;
5239        }
5240        break;
5241    case 11:
5242        switch (sel) {
5243        case 0:
5244            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Compare));
5245            rn = "Compare";
5246            break;
5247        /* 6,7 are implementation dependent */
5248        default:
5249            goto cp0_unimplemented;
5250        }
5251        break;
5252    case 12:
5253        switch (sel) {
5254        case 0:
5255            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Status));
5256            rn = "Status";
5257            break;
5258        case 1:
5259            check_insn(ctx, ISA_MIPS32R2);
5260            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_IntCtl));
5261            rn = "IntCtl";
5262            break;
5263        case 2:
5264            check_insn(ctx, ISA_MIPS32R2);
5265            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSCtl));
5266            rn = "SRSCtl";
5267            break;
5268        case 3:
5269            check_insn(ctx, ISA_MIPS32R2);
5270            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSMap));
5271            rn = "SRSMap";
5272            break;
5273        default:
5274            goto cp0_unimplemented;
5275       }
5276        break;
5277    case 13:
5278        switch (sel) {
5279        case 0:
5280            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Cause));
5281            rn = "Cause";
5282            break;
5283        default:
5284            goto cp0_unimplemented;
5285       }
5286        break;
5287    case 14:
5288        switch (sel) {
5289        case 0:
5290            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EPC));
5291            tcg_gen_ext32s_tl(arg, arg);
5292            rn = "EPC";
5293            break;
5294        default:
5295            goto cp0_unimplemented;
5296        }
5297        break;
5298    case 15:
5299        switch (sel) {
5300        case 0:
5301            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PRid));
5302            rn = "PRid";
5303            break;
5304        case 1:
5305            check_insn(ctx, ISA_MIPS32R2);
5306            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_EBase));
5307            rn = "EBase";
5308            break;
5309        case 3:
5310            check_insn(ctx, ISA_MIPS32R2);
5311            CP0_CHECK(ctx->cmgcr);
5312            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_CMGCRBase));
5313            tcg_gen_ext32s_tl(arg, arg);
5314            rn = "CMGCRBase";
5315            break;
5316        default:
5317            goto cp0_unimplemented;
5318       }
5319        break;
5320    case 16:
5321        switch (sel) {
5322        case 0:
5323            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config0));
5324            rn = "Config";
5325            break;
5326        case 1:
5327            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config1));
5328            rn = "Config1";
5329            break;
5330        case 2:
5331            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config2));
5332            rn = "Config2";
5333            break;
5334        case 3:
5335            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config3));
5336            rn = "Config3";
5337            break;
5338        case 4:
5339            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config4));
5340            rn = "Config4";
5341            break;
5342        case 5:
5343            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config5));
5344            rn = "Config5";
5345            break;
5346        /* 6,7 are implementation dependent */
5347        case 6:
5348            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config6));
5349            rn = "Config6";
5350            break;
5351        case 7:
5352            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config7));
5353            rn = "Config7";
5354            break;
5355        default:
5356            goto cp0_unimplemented;
5357        }
5358        break;
5359    case 17:
5360        switch (sel) {
5361        case 0:
5362            gen_helper_mfc0_lladdr(arg, cpu_env);
5363            rn = "LLAddr";
5364            break;
5365        case 1:
5366            CP0_CHECK(ctx->mrp);
5367            gen_helper_mfc0_maar(arg, cpu_env);
5368            rn = "MAAR";
5369            break;
5370        case 2:
5371            CP0_CHECK(ctx->mrp);
5372            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_MAARI));
5373            rn = "MAARI";
5374            break;
5375        default:
5376            goto cp0_unimplemented;
5377        }
5378        break;
5379    case 18:
5380        switch (sel) {
5381        case 0 ... 7:
5382            gen_helper_1e0i(mfc0_watchlo, arg, sel);
5383            rn = "WatchLo";
5384            break;
5385        default:
5386            goto cp0_unimplemented;
5387        }
5388        break;
5389    case 19:
5390        switch (sel) {
5391        case 0 ...7:
5392            gen_helper_1e0i(mfc0_watchhi, arg, sel);
5393            rn = "WatchHi";
5394            break;
5395        default:
5396            goto cp0_unimplemented;
5397        }
5398        break;
5399    case 20:
5400        switch (sel) {
5401        case 0:
5402#if defined(TARGET_MIPS64)
5403            check_insn(ctx, ISA_MIPS3);
5404            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_XContext));
5405            tcg_gen_ext32s_tl(arg, arg);
5406            rn = "XContext";
5407            break;
5408#endif
5409        default:
5410            goto cp0_unimplemented;
5411        }
5412        break;
5413    case 21:
5414       /* Officially reserved, but sel 0 is used for R1x000 framemask */
5415        CP0_CHECK(!(ctx->insn_flags & ISA_MIPS32R6));
5416        switch (sel) {
5417        case 0:
5418            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Framemask));
5419            rn = "Framemask";
5420            break;
5421        default:
5422            goto cp0_unimplemented;
5423        }
5424        break;
5425    case 22:
5426        tcg_gen_movi_tl(arg, 0); /* unimplemented */
5427        rn = "'Diagnostic"; /* implementation dependent */
5428        break;
5429    case 23:
5430        switch (sel) {
5431        case 0:
5432            gen_helper_mfc0_debug(arg, cpu_env); /* EJTAG support */
5433            rn = "Debug";
5434            break;
5435        case 1:
5436//            gen_helper_mfc0_tracecontrol(arg); /* PDtrace support */
5437            rn = "TraceControl";
5438//            break;
5439        case 2:
5440//            gen_helper_mfc0_tracecontrol2(arg); /* PDtrace support */
5441            rn = "TraceControl2";
5442//            break;
5443        case 3:
5444//            gen_helper_mfc0_usertracedata(arg); /* PDtrace support */
5445            rn = "UserTraceData";
5446//            break;
5447        case 4:
5448//            gen_helper_mfc0_tracebpc(arg); /* PDtrace support */
5449            rn = "TraceBPC";
5450//            break;
5451        default:
5452            goto cp0_unimplemented;
5453        }
5454        break;
5455    case 24:
5456        switch (sel) {
5457        case 0:
5458            /* EJTAG support */
5459            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_DEPC));
5460            tcg_gen_ext32s_tl(arg, arg);
5461            rn = "DEPC";
5462            break;
5463        default:
5464            goto cp0_unimplemented;
5465        }
5466        break;
5467    case 25:
5468        switch (sel) {
5469        case 0:
5470            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Performance0));
5471            rn = "Performance0";
5472            break;
5473        case 1:
5474//            gen_helper_mfc0_performance1(arg);
5475            rn = "Performance1";
5476//            break;
5477        case 2:
5478//            gen_helper_mfc0_performance2(arg);
5479            rn = "Performance2";
5480//            break;
5481        case 3:
5482//            gen_helper_mfc0_performance3(arg);
5483            rn = "Performance3";
5484//            break;
5485        case 4:
5486//            gen_helper_mfc0_performance4(arg);
5487            rn = "Performance4";
5488//            break;
5489        case 5:
5490//            gen_helper_mfc0_performance5(arg);
5491            rn = "Performance5";
5492//            break;
5493        case 6:
5494//            gen_helper_mfc0_performance6(arg);
5495            rn = "Performance6";
5496//            break;
5497        case 7:
5498//            gen_helper_mfc0_performance7(arg);
5499            rn = "Performance7";
5500//            break;
5501        default:
5502            goto cp0_unimplemented;
5503        }
5504        break;
5505    case 26:
5506        switch (sel) {
5507        case 0:
5508            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_ErrCtl));
5509            rn = "ErrCtl";
5510            break;
5511        default:
5512            goto cp0_unimplemented;
5513        }
5514        break;
5515    case 27:
5516        switch (sel) {
5517        case 0 ... 3:
5518            tcg_gen_movi_tl(arg, 0); /* unimplemented */
5519            rn = "CacheErr";
5520            break;
5521        default:
5522            goto cp0_unimplemented;
5523        }
5524        break;
5525    case 28:
5526        switch (sel) {
5527        case 0:
5528        case 2:
5529        case 4:
5530        case 6:
5531            {
5532                TCGv_i64 tmp = tcg_temp_new_i64();
5533                tcg_gen_ld_i64(tmp, cpu_env, offsetof(CPUMIPSState, CP0_TagLo));
5534                gen_move_low32(arg, tmp);
5535                tcg_temp_free_i64(tmp);
5536            }
5537            rn = "TagLo";
5538            break;
5539        case 1:
5540        case 3:
5541        case 5:
5542        case 7:
5543            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataLo));
5544            rn = "DataLo";
5545            break;
5546        default:
5547            goto cp0_unimplemented;
5548        }
5549        break;
5550    case 29:
5551        switch (sel) {
5552        case 0:
5553        case 2:
5554        case 4:
5555        case 6:
5556            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_TagHi));
5557            rn = "TagHi";
5558            break;
5559        case 1:
5560        case 3:
5561        case 5:
5562        case 7:
5563            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataHi));
5564            rn = "DataHi";
5565            break;
5566        default:
5567            goto cp0_unimplemented;
5568        }
5569        break;
5570    case 30:
5571        switch (sel) {
5572        case 0:
5573            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_ErrorEPC));
5574            tcg_gen_ext32s_tl(arg, arg);
5575            rn = "ErrorEPC";
5576            break;
5577        default:
5578            goto cp0_unimplemented;
5579        }
5580        break;
5581    case 31:
5582        switch (sel) {
5583        case 0:
5584            /* EJTAG support */
5585            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DESAVE));
5586            rn = "DESAVE";
5587            break;
5588        case 2 ... 7:
5589            CP0_CHECK(ctx->kscrexist & (1 << sel));
5590            tcg_gen_ld_tl(arg, cpu_env,
5591                          offsetof(CPUMIPSState, CP0_KScratch[sel-2]));
5592            tcg_gen_ext32s_tl(arg, arg);
5593            rn = "KScratch";
5594            break;
5595        default:
5596            goto cp0_unimplemented;
5597        }
5598        break;
5599    default:
5600       goto cp0_unimplemented;
5601    }
5602    (void)rn; /* avoid a compiler warning */
5603    LOG_DISAS("mfc0 %s (reg %d sel %d)\n", rn, reg, sel);
5604    return;
5605
5606cp0_unimplemented:
5607    LOG_DISAS("mfc0 %s (reg %d sel %d)\n", rn, reg, sel);
5608    gen_mfc0_unimplemented(ctx, arg);
5609}
5610
5611static void gen_mtc0(DisasContext *ctx, TCGv arg, int reg, int sel)
5612{
5613    const char *rn = "invalid";
5614
5615    if (sel != 0)
5616        check_insn(ctx, ISA_MIPS32);
5617
5618    if (ctx->tb->cflags & CF_USE_ICOUNT) {
5619        gen_io_start();
5620    }
5621
5622    switch (reg) {
5623    case 0:
5624        switch (sel) {
5625        case 0:
5626            gen_helper_mtc0_index(cpu_env, arg);
5627            rn = "Index";
5628            break;
5629        case 1:
5630            CP0_CHECK(ctx->insn_flags & ASE_MT);
5631            gen_helper_mtc0_mvpcontrol(cpu_env, arg);
5632            rn = "MVPControl";
5633            break;
5634        case 2:
5635            CP0_CHECK(ctx->insn_flags & ASE_MT);
5636            /* ignored */
5637            rn = "MVPConf0";
5638            break;
5639        case 3:
5640            CP0_CHECK(ctx->insn_flags & ASE_MT);
5641            /* ignored */
5642            rn = "MVPConf1";
5643            break;
5644        case 4:
5645            CP0_CHECK(ctx->vp);
5646            /* ignored */
5647            rn = "VPControl";
5648            break;
5649        default:
5650            goto cp0_unimplemented;
5651        }
5652        break;
5653    case 1:
5654        switch (sel) {
5655        case 0:
5656            /* ignored */
5657            rn = "Random";
5658            break;
5659        case 1:
5660            CP0_CHECK(ctx->insn_flags & ASE_MT);
5661            gen_helper_mtc0_vpecontrol(cpu_env, arg);
5662            rn = "VPEControl";
5663            break;
5664        case 2:
5665            CP0_CHECK(ctx->insn_flags & ASE_MT);
5666            gen_helper_mtc0_vpeconf0(cpu_env, arg);
5667            rn = "VPEConf0";
5668            break;
5669        case 3:
5670            CP0_CHECK(ctx->insn_flags & ASE_MT);
5671            gen_helper_mtc0_vpeconf1(cpu_env, arg);
5672            rn = "VPEConf1";
5673            break;
5674        case 4:
5675            CP0_CHECK(ctx->insn_flags & ASE_MT);
5676            gen_helper_mtc0_yqmask(cpu_env, arg);
5677            rn = "YQMask";
5678            break;
5679        case 5:
5680            CP0_CHECK(ctx->insn_flags & ASE_MT);
5681            tcg_gen_st_tl(arg, cpu_env,
5682                          offsetof(CPUMIPSState, CP0_VPESchedule));
5683            rn = "VPESchedule";
5684            break;
5685        case 6:
5686            CP0_CHECK(ctx->insn_flags & ASE_MT);
5687            tcg_gen_st_tl(arg, cpu_env,
5688                          offsetof(CPUMIPSState, CP0_VPEScheFBack));
5689            rn = "VPEScheFBack";
5690            break;
5691        case 7:
5692            CP0_CHECK(ctx->insn_flags & ASE_MT);
5693            gen_helper_mtc0_vpeopt(cpu_env, arg);
5694            rn = "VPEOpt";
5695            break;
5696        default:
5697            goto cp0_unimplemented;
5698        }
5699        break;
5700    case 2:
5701        switch (sel) {
5702        case 0:
5703            gen_helper_mtc0_entrylo0(cpu_env, arg);
5704            rn = "EntryLo0";
5705            break;
5706        case 1:
5707            CP0_CHECK(ctx->insn_flags & ASE_MT);
5708            gen_helper_mtc0_tcstatus(cpu_env, arg);
5709            rn = "TCStatus";
5710            break;
5711        case 2:
5712            CP0_CHECK(ctx->insn_flags & ASE_MT);
5713            gen_helper_mtc0_tcbind(cpu_env, arg);
5714            rn = "TCBind";
5715            break;
5716        case 3:
5717            CP0_CHECK(ctx->insn_flags & ASE_MT);
5718            gen_helper_mtc0_tcrestart(cpu_env, arg);
5719            rn = "TCRestart";
5720            break;
5721        case 4:
5722            CP0_CHECK(ctx->insn_flags & ASE_MT);
5723            gen_helper_mtc0_tchalt(cpu_env, arg);
5724            rn = "TCHalt";
5725            break;
5726        case 5:
5727            CP0_CHECK(ctx->insn_flags & ASE_MT);
5728            gen_helper_mtc0_tccontext(cpu_env, arg);
5729            rn = "TCContext";
5730            break;
5731        case 6:
5732            CP0_CHECK(ctx->insn_flags & ASE_MT);
5733            gen_helper_mtc0_tcschedule(cpu_env, arg);
5734            rn = "TCSchedule";
5735            break;
5736        case 7:
5737            CP0_CHECK(ctx->insn_flags & ASE_MT);
5738            gen_helper_mtc0_tcschefback(cpu_env, arg);
5739            rn = "TCScheFBack";
5740            break;
5741        default:
5742            goto cp0_unimplemented;
5743        }
5744        break;
5745    case 3:
5746        switch (sel) {
5747        case 0:
5748            gen_helper_mtc0_entrylo1(cpu_env, arg);
5749            rn = "EntryLo1";
5750            break;
5751        case 1:
5752            CP0_CHECK(ctx->vp);
5753            /* ignored */
5754            rn = "GlobalNumber";
5755            break;
5756        default:
5757            goto cp0_unimplemented;
5758        }
5759        break;
5760    case 4:
5761        switch (sel) {
5762        case 0:
5763            gen_helper_mtc0_context(cpu_env, arg);
5764            rn = "Context";
5765            break;
5766        case 1:
5767//            gen_helper_mtc0_contextconfig(cpu_env, arg); /* SmartMIPS ASE */
5768            rn = "ContextConfig";
5769            goto cp0_unimplemented;
5770//            break;
5771        case 2:
5772            CP0_CHECK(ctx->ulri);
5773            tcg_gen_st_tl(arg, cpu_env,
5774                          offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
5775            rn = "UserLocal";
5776            break;
5777        default:
5778            goto cp0_unimplemented;
5779        }
5780        break;
5781    case 5:
5782        switch (sel) {
5783        case 0:
5784            gen_helper_mtc0_pagemask(cpu_env, arg);
5785            rn = "PageMask";
5786            break;
5787        case 1:
5788            check_insn(ctx, ISA_MIPS32R2);
5789            gen_helper_mtc0_pagegrain(cpu_env, arg);
5790            rn = "PageGrain";
5791            ctx->bstate = BS_STOP;
5792            break;
5793        default:
5794            goto cp0_unimplemented;
5795        }
5796        break;
5797    case 6:
5798        switch (sel) {
5799        case 0:
5800            gen_helper_mtc0_wired(cpu_env, arg);
5801            rn = "Wired";
5802            break;
5803        case 1:
5804            check_insn(ctx, ISA_MIPS32R2);
5805            gen_helper_mtc0_srsconf0(cpu_env, arg);
5806            rn = "SRSConf0";
5807            break;
5808        case 2:
5809            check_insn(ctx, ISA_MIPS32R2);
5810            gen_helper_mtc0_srsconf1(cpu_env, arg);
5811            rn = "SRSConf1";
5812            break;
5813        case 3:
5814            check_insn(ctx, ISA_MIPS32R2);
5815            gen_helper_mtc0_srsconf2(cpu_env, arg);
5816            rn = "SRSConf2";
5817            break;
5818        case 4:
5819            check_insn(ctx, ISA_MIPS32R2);
5820            gen_helper_mtc0_srsconf3(cpu_env, arg);
5821            rn = "SRSConf3";
5822            break;
5823        case 5:
5824            check_insn(ctx, ISA_MIPS32R2);
5825            gen_helper_mtc0_srsconf4(cpu_env, arg);
5826            rn = "SRSConf4";
5827            break;
5828        default:
5829            goto cp0_unimplemented;
5830        }
5831        break;
5832    case 7:
5833        switch (sel) {
5834        case 0:
5835            check_insn(ctx, ISA_MIPS32R2);
5836            gen_helper_mtc0_hwrena(cpu_env, arg);
5837            ctx->bstate = BS_STOP;
5838            rn = "HWREna";
5839            break;
5840        default:
5841            goto cp0_unimplemented;
5842        }
5843        break;
5844    case 8:
5845        switch (sel) {
5846        case 0:
5847            /* ignored */
5848            rn = "BadVAddr";
5849            break;
5850        case 1:
5851            /* ignored */
5852            rn = "BadInstr";
5853            break;
5854        case 2:
5855            /* ignored */
5856            rn = "BadInstrP";
5857            break;
5858        default:
5859            goto cp0_unimplemented;
5860        }
5861        break;
5862    case 9:
5863        switch (sel) {
5864        case 0:
5865            gen_helper_mtc0_count(cpu_env, arg);
5866            rn = "Count";
5867            break;
5868        /* 6,7 are implementation dependent */
5869        default:
5870            goto cp0_unimplemented;
5871        }
5872        break;
5873    case 10:
5874        switch (sel) {
5875        case 0:
5876            gen_helper_mtc0_entryhi(cpu_env, arg);
5877            rn = "EntryHi";
5878            break;
5879        default:
5880            goto cp0_unimplemented;
5881        }
5882        break;
5883    case 11:
5884        switch (sel) {
5885        case 0:
5886            gen_helper_mtc0_compare(cpu_env, arg);
5887            rn = "Compare";
5888            break;
5889        /* 6,7 are implementation dependent */
5890        default:
5891            goto cp0_unimplemented;
5892        }
5893        break;
5894    case 12:
5895        switch (sel) {
5896        case 0:
5897            save_cpu_state(ctx, 1);
5898            gen_helper_mtc0_status(cpu_env, arg);
5899            /* BS_STOP isn't good enough here, hflags may have changed. */
5900            gen_save_pc(ctx->pc + 4);
5901            ctx->bstate = BS_EXCP;
5902            rn = "Status";
5903            break;
5904        case 1:
5905            check_insn(ctx, ISA_MIPS32R2);
5906            gen_helper_mtc0_intctl(cpu_env, arg);
5907            /* Stop translation as we may have switched the execution mode */
5908            ctx->bstate = BS_STOP;
5909            rn = "IntCtl";
5910            break;
5911        case 2:
5912            check_insn(ctx, ISA_MIPS32R2);
5913            gen_helper_mtc0_srsctl(cpu_env, arg);
5914            /* Stop translation as we may have switched the execution mode */
5915            ctx->bstate = BS_STOP;
5916            rn = "SRSCtl";
5917            break;
5918        case 3:
5919            check_insn(ctx, ISA_MIPS32R2);
5920            gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_SRSMap));
5921            /* Stop translation as we may have switched the execution mode */
5922            ctx->bstate = BS_STOP;
5923            rn = "SRSMap";
5924            break;
5925        default:
5926            goto cp0_unimplemented;
5927        }
5928        break;
5929    case 13:
5930        switch (sel) {
5931        case 0:
5932            save_cpu_state(ctx, 1);
5933            gen_helper_mtc0_cause(cpu_env, arg);
5934            rn = "Cause";
5935            break;
5936        default:
5937            goto cp0_unimplemented;
5938        }
5939        break;
5940    case 14:
5941        switch (sel) {
5942        case 0:
5943            tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EPC));
5944            rn = "EPC";
5945            break;
5946        default:
5947            goto cp0_unimplemented;
5948        }
5949        break;
5950    case 15:
5951        switch (sel) {
5952        case 0:
5953            /* ignored */
5954            rn = "PRid";
5955            break;
5956        case 1:
5957            check_insn(ctx, ISA_MIPS32R2);
5958            gen_helper_mtc0_ebase(cpu_env, arg);
5959            rn = "EBase";
5960            break;
5961        default:
5962            goto cp0_unimplemented;
5963        }
5964        break;
5965    case 16:
5966        switch (sel) {
5967        case 0:
5968            gen_helper_mtc0_config0(cpu_env, arg);
5969            rn = "Config";
5970            /* Stop translation as we may have switched the execution mode */
5971            ctx->bstate = BS_STOP;
5972            break;
5973        case 1:
5974            /* ignored, read only */
5975            rn = "Config1";
5976            break;
5977        case 2:
5978            gen_helper_mtc0_config2(cpu_env, arg);
5979            rn = "Config2";
5980            /* Stop translation as we may have switched the execution mode */
5981            ctx->bstate = BS_STOP;
5982            break;
5983        case 3:
5984            gen_helper_mtc0_config3(cpu_env, arg);
5985            rn = "Config3";
5986            /* Stop translation as we may have switched the execution mode */
5987            ctx->bstate = BS_STOP;
5988            break;
5989        case 4:
5990            gen_helper_mtc0_config4(cpu_env, arg);
5991            rn = "Config4";
5992            ctx->bstate = BS_STOP;
5993            break;
5994        case 5:
5995            gen_helper_mtc0_config5(cpu_env, arg);
5996            rn = "Config5";
5997            /* Stop translation as we may have switched the execution mode */
5998            ctx->bstate = BS_STOP;
5999            break;
6000        /* 6,7 are implementation dependent */
6001        case 6:
6002            /* ignored */
6003            rn = "Config6";
6004            break;
6005        case 7:
6006            /* ignored */
6007            rn = "Config7";
6008            break;
6009        default:
6010            rn = "Invalid config selector";
6011            goto cp0_unimplemented;
6012        }
6013        break;
6014    case 17:
6015        switch (sel) {
6016        case 0:
6017            gen_helper_mtc0_lladdr(cpu_env, arg);
6018            rn = "LLAddr";
6019            break;
6020        case 1:
6021            CP0_CHECK(ctx->mrp);
6022            gen_helper_mtc0_maar(cpu_env, arg);
6023            rn = "MAAR";
6024            break;
6025        case 2:
6026            CP0_CHECK(ctx->mrp);
6027            gen_helper_mtc0_maari(cpu_env, arg);
6028            rn = "MAARI";
6029            break;
6030        default:
6031            goto cp0_unimplemented;
6032        }
6033        break;
6034    case 18:
6035        switch (sel) {
6036        case 0 ... 7:
6037            gen_helper_0e1i(mtc0_watchlo, arg, sel);
6038            rn = "WatchLo";
6039            break;
6040        default:
6041            goto cp0_unimplemented;
6042        }
6043        break;
6044    case 19:
6045        switch (sel) {
6046        case 0 ... 7:
6047            gen_helper_0e1i(mtc0_watchhi, arg, sel);
6048            rn = "WatchHi";
6049            break;
6050        default:
6051            goto cp0_unimplemented;
6052        }
6053        break;
6054    case 20:
6055        switch (sel) {
6056        case 0:
6057#if defined(TARGET_MIPS64)
6058            check_insn(ctx, ISA_MIPS3);
6059            gen_helper_mtc0_xcontext(cpu_env, arg);
6060            rn = "XContext";
6061            break;
6062#endif
6063        default:
6064            goto cp0_unimplemented;
6065        }
6066        break;
6067    case 21:
6068       /* Officially reserved, but sel 0 is used for R1x000 framemask */
6069        CP0_CHECK(!(ctx->insn_flags & ISA_MIPS32R6));
6070        switch (sel) {
6071        case 0:
6072            gen_helper_mtc0_framemask(cpu_env, arg);
6073            rn = "Framemask";
6074            break;
6075        default:
6076            goto cp0_unimplemented;
6077        }
6078        break;
6079    case 22:
6080        /* ignored */
6081        rn = "Diagnostic"; /* implementation dependent */
6082        break;
6083    case 23:
6084        switch (sel) {
6085        case 0:
6086            gen_helper_mtc0_debug(cpu_env, arg); /* EJTAG support */
6087            /* BS_STOP isn't good enough here, hflags may have changed. */
6088            gen_save_pc(ctx->pc + 4);
6089            ctx->bstate = BS_EXCP;
6090            rn = "Debug";
6091            break;
6092        case 1:
6093//            gen_helper_mtc0_tracecontrol(cpu_env, arg); /* PDtrace support */
6094            rn = "TraceControl";
6095            /* Stop translation as we may have switched the execution mode */
6096            ctx->bstate = BS_STOP;
6097//            break;
6098        case 2:
6099//            gen_helper_mtc0_tracecontrol2(cpu_env, arg); /* PDtrace support */
6100            rn = "TraceControl2";
6101            /* Stop translation as we may have switched the execution mode */
6102            ctx->bstate = BS_STOP;
6103//            break;
6104        case 3:
6105            /* Stop translation as we may have switched the execution mode */
6106            ctx->bstate = BS_STOP;
6107//            gen_helper_mtc0_usertracedata(cpu_env, arg); /* PDtrace support */
6108            rn = "UserTraceData";
6109            /* Stop translation as we may have switched the execution mode */
6110            ctx->bstate = BS_STOP;
6111//            break;
6112        case 4:
6113//            gen_helper_mtc0_tracebpc(cpu_env, arg); /* PDtrace support */
6114            /* Stop translation as we may have switched the execution mode */
6115            ctx->bstate = BS_STOP;
6116            rn = "TraceBPC";
6117//            break;
6118        default:
6119            goto cp0_unimplemented;
6120        }
6121        break;
6122    case 24:
6123        switch (sel) {
6124        case 0:
6125            /* EJTAG support */
6126            tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_DEPC));
6127            rn = "DEPC";
6128            break;
6129        default:
6130            goto cp0_unimplemented;
6131        }
6132        break;
6133    case 25:
6134        switch (sel) {
6135        case 0:
6136            gen_helper_mtc0_performance0(cpu_env, arg);
6137            rn = "Performance0";
6138            break;
6139        case 1:
6140//            gen_helper_mtc0_performance1(arg);
6141            rn = "Performance1";
6142//            break;
6143        case 2:
6144//            gen_helper_mtc0_performance2(arg);
6145            rn = "Performance2";
6146//            break;
6147        case 3:
6148//            gen_helper_mtc0_performance3(arg);
6149            rn = "Performance3";
6150//            break;
6151        case 4:
6152//            gen_helper_mtc0_performance4(arg);
6153            rn = "Performance4";
6154//            break;
6155        case 5:
6156//            gen_helper_mtc0_performance5(arg);
6157            rn = "Performance5";
6158//            break;
6159        case 6:
6160//            gen_helper_mtc0_performance6(arg);
6161            rn = "Performance6";
6162//            break;
6163        case 7:
6164//            gen_helper_mtc0_performance7(arg);
6165            rn = "Performance7";
6166//            break;
6167        default:
6168            goto cp0_unimplemented;
6169        }
6170       break;
6171    case 26:
6172        switch (sel) {
6173        case 0:
6174            gen_helper_mtc0_errctl(cpu_env, arg);
6175            ctx->bstate = BS_STOP;
6176            rn = "ErrCtl";
6177            break;
6178        default:
6179            goto cp0_unimplemented;
6180        }
6181        break;
6182    case 27:
6183        switch (sel) {
6184        case 0 ... 3:
6185            /* ignored */
6186            rn = "CacheErr";
6187            break;
6188        default:
6189            goto cp0_unimplemented;
6190        }
6191       break;
6192    case 28:
6193        switch (sel) {
6194        case 0:
6195        case 2:
6196        case 4:
6197        case 6:
6198            gen_helper_mtc0_taglo(cpu_env, arg);
6199            rn = "TagLo";
6200            break;
6201        case 1:
6202        case 3:
6203        case 5:
6204        case 7:
6205            gen_helper_mtc0_datalo(cpu_env, arg);
6206            rn = "DataLo";
6207            break;
6208        default:
6209            goto cp0_unimplemented;
6210        }
6211        break;
6212    case 29:
6213        switch (sel) {
6214        case 0:
6215        case 2:
6216        case 4:
6217        case 6:
6218            gen_helper_mtc0_taghi(cpu_env, arg);
6219            rn = "TagHi";
6220            break;
6221        case 1:
6222        case 3:
6223        case 5:
6224        case 7:
6225            gen_helper_mtc0_datahi(cpu_env, arg);
6226            rn = "DataHi";
6227            break;
6228        default:
6229            rn = "invalid sel";
6230            goto cp0_unimplemented;
6231        }
6232       break;
6233    case 30:
6234        switch (sel) {
6235        case 0:
6236            tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_ErrorEPC));
6237            rn = "ErrorEPC";
6238            break;
6239        default:
6240            goto cp0_unimplemented;
6241        }
6242        break;
6243    case 31:
6244        switch (sel) {
6245        case 0:
6246            /* EJTAG support */
6247            gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_DESAVE));
6248            rn = "DESAVE";
6249            break;
6250        case 2 ... 7:
6251            CP0_CHECK(ctx->kscrexist & (1 << sel));
6252            tcg_gen_st_tl(arg, cpu_env,
6253                          offsetof(CPUMIPSState, CP0_KScratch[sel-2]));
6254            rn = "KScratch";
6255            break;
6256        default:
6257            goto cp0_unimplemented;
6258        }
6259        /* Stop translation as we may have switched the execution mode */
6260        ctx->bstate = BS_STOP;
6261        break;
6262    default:
6263       goto cp0_unimplemented;
6264    }
6265    (void)rn; /* avoid a compiler warning */
6266    LOG_DISAS("mtc0 %s (reg %d sel %d)\n", rn, reg, sel);
6267    /* For simplicity assume that all writes can cause interrupts.  */
6268    if (ctx->tb->cflags & CF_USE_ICOUNT) {
6269        gen_io_end();
6270        ctx->bstate = BS_STOP;
6271    }
6272    return;
6273
6274cp0_unimplemented:
6275    LOG_DISAS("mtc0 %s (reg %d sel %d)\n", rn, reg, sel);
6276}
6277
6278#if defined(TARGET_MIPS64)
6279static void gen_dmfc0(DisasContext *ctx, TCGv arg, int reg, int sel)
6280{
6281    const char *rn = "invalid";
6282
6283    if (sel != 0)
6284        check_insn(ctx, ISA_MIPS64);
6285
6286    switch (reg) {
6287    case 0:
6288        switch (sel) {
6289        case 0:
6290            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Index));
6291            rn = "Index";
6292            break;
6293        case 1:
6294            CP0_CHECK(ctx->insn_flags & ASE_MT);
6295            gen_helper_mfc0_mvpcontrol(arg, cpu_env);
6296            rn = "MVPControl";
6297            break;
6298        case 2:
6299            CP0_CHECK(ctx->insn_flags & ASE_MT);
6300            gen_helper_mfc0_mvpconf0(arg, cpu_env);
6301            rn = "MVPConf0";
6302            break;
6303        case 3:
6304            CP0_CHECK(ctx->insn_flags & ASE_MT);
6305            gen_helper_mfc0_mvpconf1(arg, cpu_env);
6306            rn = "MVPConf1";
6307            break;
6308        case 4:
6309            CP0_CHECK(ctx->vp);
6310            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPControl));
6311            rn = "VPControl";
6312            break;
6313        default:
6314            goto cp0_unimplemented;
6315        }
6316        break;
6317    case 1:
6318        switch (sel) {
6319        case 0:
6320            CP0_CHECK(!(ctx->insn_flags & ISA_MIPS32R6));
6321            gen_helper_mfc0_random(arg, cpu_env);
6322            rn = "Random";
6323            break;
6324        case 1:
6325            CP0_CHECK(ctx->insn_flags & ASE_MT);
6326            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEControl));
6327            rn = "VPEControl";
6328            break;
6329        case 2:
6330            CP0_CHECK(ctx->insn_flags & ASE_MT);
6331            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf0));
6332            rn = "VPEConf0";
6333            break;
6334        case 3:
6335            CP0_CHECK(ctx->insn_flags & ASE_MT);
6336            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf1));
6337            rn = "VPEConf1";
6338            break;
6339        case 4:
6340            CP0_CHECK(ctx->insn_flags & ASE_MT);
6341            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_YQMask));
6342            rn = "YQMask";
6343            break;
6344        case 5:
6345            CP0_CHECK(ctx->insn_flags & ASE_MT);
6346            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_VPESchedule));
6347            rn = "VPESchedule";
6348            break;
6349        case 6:
6350            CP0_CHECK(ctx->insn_flags & ASE_MT);
6351            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_VPEScheFBack));
6352            rn = "VPEScheFBack";
6353            break;
6354        case 7:
6355            CP0_CHECK(ctx->insn_flags & ASE_MT);
6356            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEOpt));
6357            rn = "VPEOpt";
6358            break;
6359        default:
6360            goto cp0_unimplemented;
6361        }
6362        break;
6363    case 2:
6364        switch (sel) {
6365        case 0:
6366            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryLo0));
6367            rn = "EntryLo0";
6368            break;
6369        case 1:
6370            CP0_CHECK(ctx->insn_flags & ASE_MT);
6371            gen_helper_mfc0_tcstatus(arg, cpu_env);
6372            rn = "TCStatus";
6373            break;
6374        case 2:
6375            CP0_CHECK(ctx->insn_flags & ASE_MT);
6376            gen_helper_mfc0_tcbind(arg, cpu_env);
6377            rn = "TCBind";
6378            break;
6379        case 3:
6380            CP0_CHECK(ctx->insn_flags & ASE_MT);
6381            gen_helper_dmfc0_tcrestart(arg, cpu_env);
6382            rn = "TCRestart";
6383            break;
6384        case 4:
6385            CP0_CHECK(ctx->insn_flags & ASE_MT);
6386            gen_helper_dmfc0_tchalt(arg, cpu_env);
6387            rn = "TCHalt";
6388            break;
6389        case 5:
6390            CP0_CHECK(ctx->insn_flags & ASE_MT);
6391            gen_helper_dmfc0_tccontext(arg, cpu_env);
6392            rn = "TCContext";
6393            break;
6394        case 6:
6395            CP0_CHECK(ctx->insn_flags & ASE_MT);
6396            gen_helper_dmfc0_tcschedule(arg, cpu_env);
6397            rn = "TCSchedule";
6398            break;
6399        case 7:
6400            CP0_CHECK(ctx->insn_flags & ASE_MT);
6401            gen_helper_dmfc0_tcschefback(arg, cpu_env);
6402            rn = "TCScheFBack";
6403            break;
6404        default:
6405            goto cp0_unimplemented;
6406        }
6407        break;
6408    case 3:
6409        switch (sel) {
6410        case 0:
6411            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryLo1));
6412            rn = "EntryLo1";
6413            break;
6414        case 1:
6415            CP0_CHECK(ctx->vp);
6416            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_GlobalNumber));
6417            rn = "GlobalNumber";
6418            break;
6419        default:
6420            goto cp0_unimplemented;
6421        }
6422        break;
6423    case 4:
6424        switch (sel) {
6425        case 0:
6426            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_Context));
6427            rn = "Context";
6428            break;
6429        case 1:
6430//            gen_helper_dmfc0_contextconfig(arg); /* SmartMIPS ASE */
6431            rn = "ContextConfig";
6432            goto cp0_unimplemented;
6433//            break;
6434        case 2:
6435            CP0_CHECK(ctx->ulri);
6436            tcg_gen_ld_tl(arg, cpu_env,
6437                          offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
6438            rn = "UserLocal";
6439            break;
6440        default:
6441            goto cp0_unimplemented;
6442        }
6443        break;
6444    case 5:
6445        switch (sel) {
6446        case 0:
6447            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageMask));
6448            rn = "PageMask";
6449            break;
6450        case 1:
6451            check_insn(ctx, ISA_MIPS32R2);
6452            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageGrain));
6453            rn = "PageGrain";
6454            break;
6455        default:
6456            goto cp0_unimplemented;
6457        }
6458        break;
6459    case 6:
6460        switch (sel) {
6461        case 0:
6462            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Wired));
6463            rn = "Wired";
6464            break;
6465        case 1:
6466            check_insn(ctx, ISA_MIPS32R2);
6467            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf0));
6468            rn = "SRSConf0";
6469            break;
6470        case 2:
6471            check_insn(ctx, ISA_MIPS32R2);
6472            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf1));
6473            rn = "SRSConf1";
6474            break;
6475        case 3:
6476            check_insn(ctx, ISA_MIPS32R2);
6477            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf2));
6478            rn = "SRSConf2";
6479            break;
6480        case 4:
6481            check_insn(ctx, ISA_MIPS32R2);
6482            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf3));
6483            rn = "SRSConf3";
6484            break;
6485        case 5:
6486            check_insn(ctx, ISA_MIPS32R2);
6487            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf4));
6488            rn = "SRSConf4";
6489            break;
6490        default:
6491            goto cp0_unimplemented;
6492        }
6493        break;
6494    case 7:
6495        switch (sel) {
6496        case 0:
6497            check_insn(ctx, ISA_MIPS32R2);
6498            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_HWREna));
6499            rn = "HWREna";
6500            break;
6501        default:
6502            goto cp0_unimplemented;
6503        }
6504        break;
6505    case 8:
6506        switch (sel) {
6507        case 0:
6508            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_BadVAddr));
6509            rn = "BadVAddr";
6510            break;
6511        case 1:
6512            CP0_CHECK(ctx->bi);
6513            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_BadInstr));
6514            rn = "BadInstr";
6515            break;
6516        case 2:
6517            CP0_CHECK(ctx->bp);
6518            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_BadInstrP));
6519            rn = "BadInstrP";
6520            break;
6521        default:
6522            goto cp0_unimplemented;
6523        }
6524        break;
6525    case 9:
6526        switch (sel) {
6527        case 0:
6528            /* Mark as an IO operation because we read the time.  */
6529            if (ctx->tb->cflags & CF_USE_ICOUNT) {
6530                gen_io_start();
6531            }
6532            gen_helper_mfc0_count(arg, cpu_env);
6533            if (ctx->tb->cflags & CF_USE_ICOUNT) {
6534                gen_io_end();
6535            }
6536            /* Break the TB to be able to take timer interrupts immediately
6537               after reading count.  */
6538            ctx->bstate = BS_STOP;
6539            rn = "Count";
6540            break;
6541        /* 6,7 are implementation dependent */
6542        default:
6543            goto cp0_unimplemented;
6544        }
6545        break;
6546    case 10:
6547        switch (sel) {
6548        case 0:
6549            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryHi));
6550            rn = "EntryHi";
6551            break;
6552        default:
6553            goto cp0_unimplemented;
6554        }
6555        break;
6556    case 11:
6557        switch (sel) {
6558        case 0:
6559            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Compare));
6560            rn = "Compare";
6561            break;
6562        /* 6,7 are implementation dependent */
6563        default:
6564            goto cp0_unimplemented;
6565        }
6566        break;
6567    case 12:
6568        switch (sel) {
6569        case 0:
6570            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Status));
6571            rn = "Status";
6572            break;
6573        case 1:
6574            check_insn(ctx, ISA_MIPS32R2);
6575            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_IntCtl));
6576            rn = "IntCtl";
6577            break;
6578        case 2:
6579            check_insn(ctx, ISA_MIPS32R2);
6580            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSCtl));
6581            rn = "SRSCtl";
6582            break;
6583        case 3:
6584            check_insn(ctx, ISA_MIPS32R2);
6585            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSMap));
6586            rn = "SRSMap";
6587            break;
6588        default:
6589            goto cp0_unimplemented;
6590        }
6591        break;
6592    case 13:
6593        switch (sel) {
6594        case 0:
6595            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Cause));
6596            rn = "Cause";
6597            break;
6598        default:
6599            goto cp0_unimplemented;
6600        }
6601        break;
6602    case 14:
6603        switch (sel) {
6604        case 0:
6605            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EPC));
6606            rn = "EPC";
6607            break;
6608        default:
6609            goto cp0_unimplemented;
6610        }
6611        break;
6612    case 15:
6613        switch (sel) {
6614        case 0:
6615            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PRid));
6616            rn = "PRid";
6617            break;
6618        case 1:
6619            check_insn(ctx, ISA_MIPS32R2);
6620            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_EBase));
6621            rn = "EBase";
6622            break;
6623        case 3:
6624            check_insn(ctx, ISA_MIPS32R2);
6625            CP0_CHECK(ctx->cmgcr);
6626            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_CMGCRBase));
6627            rn = "CMGCRBase";
6628            break;
6629        default:
6630            goto cp0_unimplemented;
6631        }
6632        break;
6633    case 16:
6634        switch (sel) {
6635        case 0:
6636            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config0));
6637            rn = "Config";
6638            break;
6639        case 1:
6640            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config1));
6641            rn = "Config1";
6642            break;
6643        case 2:
6644            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config2));
6645            rn = "Config2";
6646            break;
6647        case 3:
6648            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config3));
6649            rn = "Config3";
6650            break;
6651        case 4:
6652            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config4));
6653            rn = "Config4";
6654            break;
6655        case 5:
6656            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config5));
6657            rn = "Config5";
6658            break;
6659       /* 6,7 are implementation dependent */
6660        case 6:
6661            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config6));
6662            rn = "Config6";
6663            break;
6664        case 7:
6665            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config7));
6666            rn = "Config7";
6667            break;
6668        default:
6669            goto cp0_unimplemented;
6670        }
6671        break;
6672    case 17:
6673        switch (sel) {
6674        case 0:
6675            gen_helper_dmfc0_lladdr(arg, cpu_env);
6676            rn = "LLAddr";
6677            break;
6678        case 1:
6679            CP0_CHECK(ctx->mrp);
6680            gen_helper_dmfc0_maar(arg, cpu_env);
6681            rn = "MAAR";
6682            break;
6683        case 2:
6684            CP0_CHECK(ctx->mrp);
6685            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_MAARI));
6686            rn = "MAARI";
6687            break;
6688        default:
6689            goto cp0_unimplemented;
6690        }
6691        break;
6692    case 18:
6693        switch (sel) {
6694        case 0 ... 7:
6695            gen_helper_1e0i(dmfc0_watchlo, arg, sel);
6696            rn = "WatchLo";
6697            break;
6698        default:
6699            goto cp0_unimplemented;
6700        }
6701        break;
6702    case 19:
6703        switch (sel) {
6704        case 0 ... 7:
6705            gen_helper_1e0i(mfc0_watchhi, arg, sel);
6706            rn = "WatchHi";
6707            break;
6708        default:
6709            goto cp0_unimplemented;
6710        }
6711        break;
6712    case 20:
6713        switch (sel) {
6714        case 0:
6715            check_insn(ctx, ISA_MIPS3);
6716            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_XContext));
6717            rn = "XContext";
6718            break;
6719        default:
6720            goto cp0_unimplemented;
6721        }
6722        break;
6723    case 21:
6724       /* Officially reserved, but sel 0 is used for R1x000 framemask */
6725        CP0_CHECK(!(ctx->insn_flags & ISA_MIPS32R6));
6726        switch (sel) {
6727        case 0:
6728            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Framemask));
6729            rn = "Framemask";
6730            break;
6731        default:
6732            goto cp0_unimplemented;
6733        }
6734        break;
6735    case 22:
6736        tcg_gen_movi_tl(arg, 0); /* unimplemented */
6737        rn = "'Diagnostic"; /* implementation dependent */
6738        break;
6739    case 23:
6740        switch (sel) {
6741        case 0:
6742            gen_helper_mfc0_debug(arg, cpu_env); /* EJTAG support */
6743            rn = "Debug";
6744            break;
6745        case 1:
6746//            gen_helper_dmfc0_tracecontrol(arg, cpu_env); /* PDtrace support */
6747            rn = "TraceControl";
6748//            break;
6749        case 2:
6750//            gen_helper_dmfc0_tracecontrol2(arg, cpu_env); /* PDtrace support */
6751            rn = "TraceControl2";
6752//            break;
6753        case 3:
6754//            gen_helper_dmfc0_usertracedata(arg, cpu_env); /* PDtrace support */
6755            rn = "UserTraceData";
6756//            break;
6757        case 4:
6758//            gen_helper_dmfc0_tracebpc(arg, cpu_env); /* PDtrace support */
6759            rn = "TraceBPC";
6760//            break;
6761        default:
6762            goto cp0_unimplemented;
6763        }
6764        break;
6765    case 24:
6766        switch (sel) {
6767        case 0:
6768            /* EJTAG support */
6769            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_DEPC));
6770            rn = "DEPC";
6771            break;
6772        default:
6773            goto cp0_unimplemented;
6774        }
6775        break;
6776    case 25:
6777        switch (sel) {
6778        case 0:
6779            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Performance0));
6780            rn = "Performance0";
6781            break;
6782        case 1:
6783//            gen_helper_dmfc0_performance1(arg);
6784            rn = "Performance1";
6785//            break;
6786        case 2:
6787//            gen_helper_dmfc0_performance2(arg);
6788            rn = "Performance2";
6789//            break;
6790        case 3:
6791//            gen_helper_dmfc0_performance3(arg);
6792            rn = "Performance3";
6793//            break;
6794        case 4:
6795//            gen_helper_dmfc0_performance4(arg);
6796            rn = "Performance4";
6797//            break;
6798        case 5:
6799//            gen_helper_dmfc0_performance5(arg);
6800            rn = "Performance5";
6801//            break;
6802        case 6:
6803//            gen_helper_dmfc0_performance6(arg);
6804            rn = "Performance6";
6805//            break;
6806        case 7:
6807//            gen_helper_dmfc0_performance7(arg);
6808            rn = "Performance7";
6809//            break;
6810        default:
6811            goto cp0_unimplemented;
6812        }
6813        break;
6814    case 26:
6815        switch (sel) {
6816        case 0:
6817            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_ErrCtl));
6818            rn = "ErrCtl";
6819            break;
6820        default:
6821            goto cp0_unimplemented;
6822        }
6823        break;
6824    case 27:
6825        switch (sel) {
6826        /* ignored */
6827        case 0 ... 3:
6828            tcg_gen_movi_tl(arg, 0); /* unimplemented */
6829            rn = "CacheErr";
6830            break;
6831        default:
6832            goto cp0_unimplemented;
6833        }
6834        break;
6835    case 28:
6836        switch (sel) {
6837        case 0:
6838        case 2:
6839        case 4:
6840        case 6:
6841            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_TagLo));
6842            rn = "TagLo";
6843            break;
6844        case 1:
6845        case 3:
6846        case 5:
6847        case 7:
6848            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataLo));
6849            rn = "DataLo";
6850            break;
6851        default:
6852            goto cp0_unimplemented;
6853        }
6854        break;
6855    case 29:
6856        switch (sel) {
6857        case 0:
6858        case 2:
6859        case 4:
6860        case 6:
6861            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_TagHi));
6862            rn = "TagHi";
6863            break;
6864        case 1:
6865        case 3:
6866        case 5:
6867        case 7:
6868            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataHi));
6869            rn = "DataHi";
6870            break;
6871        default:
6872            goto cp0_unimplemented;
6873        }
6874        break;
6875    case 30:
6876        switch (sel) {
6877        case 0:
6878            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_ErrorEPC));
6879            rn = "ErrorEPC";
6880            break;
6881        default:
6882            goto cp0_unimplemented;
6883        }
6884        break;
6885    case 31:
6886        switch (sel) {
6887        case 0:
6888            /* EJTAG support */
6889            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DESAVE));
6890            rn = "DESAVE";
6891            break;
6892        case 2 ... 7:
6893            CP0_CHECK(ctx->kscrexist & (1 << sel));
6894            tcg_gen_ld_tl(arg, cpu_env,
6895                          offsetof(CPUMIPSState, CP0_KScratch[sel-2]));
6896            rn = "KScratch";
6897            break;
6898        default:
6899            goto cp0_unimplemented;
6900        }
6901        break;
6902    default:
6903        goto cp0_unimplemented;
6904    }
6905    (void)rn; /* avoid a compiler warning */
6906    LOG_DISAS("dmfc0 %s (reg %d sel %d)\n", rn, reg, sel);
6907    return;
6908
6909cp0_unimplemented:
6910    LOG_DISAS("dmfc0 %s (reg %d sel %d)\n", rn, reg, sel);
6911    gen_mfc0_unimplemented(ctx, arg);
6912}
6913
6914static void gen_dmtc0(DisasContext *ctx, TCGv arg, int reg, int sel)
6915{
6916    const char *rn = "invalid";
6917
6918    if (sel != 0)
6919        check_insn(ctx, ISA_MIPS64);
6920
6921    if (ctx->tb->cflags & CF_USE_ICOUNT) {
6922        gen_io_start();
6923    }
6924
6925    switch (reg) {
6926    case 0:
6927        switch (sel) {
6928        case 0:
6929            gen_helper_mtc0_index(cpu_env, arg);
6930            rn = "Index";
6931            break;
6932        case 1:
6933            CP0_CHECK(ctx->insn_flags & ASE_MT);
6934            gen_helper_mtc0_mvpcontrol(cpu_env, arg);
6935            rn = "MVPControl";
6936            break;
6937        case 2:
6938            CP0_CHECK(ctx->insn_flags & ASE_MT);
6939            /* ignored */
6940            rn = "MVPConf0";
6941            break;
6942        case 3:
6943            CP0_CHECK(ctx->insn_flags & ASE_MT);
6944            /* ignored */
6945            rn = "MVPConf1";
6946            break;
6947        case 4:
6948            CP0_CHECK(ctx->vp);
6949            /* ignored */
6950            rn = "VPControl";
6951            break;
6952        default:
6953            goto cp0_unimplemented;
6954        }
6955        break;
6956    case 1:
6957        switch (sel) {
6958        case 0:
6959            /* ignored */
6960            rn = "Random";
6961            break;
6962        case 1:
6963            CP0_CHECK(ctx->insn_flags & ASE_MT);
6964            gen_helper_mtc0_vpecontrol(cpu_env, arg);
6965            rn = "VPEControl";
6966            break;
6967        case 2:
6968            CP0_CHECK(ctx->insn_flags & ASE_MT);
6969            gen_helper_mtc0_vpeconf0(cpu_env, arg);
6970            rn = "VPEConf0";
6971            break;
6972        case 3:
6973            CP0_CHECK(ctx->insn_flags & ASE_MT);
6974            gen_helper_mtc0_vpeconf1(cpu_env, arg);
6975            rn = "VPEConf1";
6976            break;
6977        case 4:
6978            CP0_CHECK(ctx->insn_flags & ASE_MT);
6979            gen_helper_mtc0_yqmask(cpu_env, arg);
6980            rn = "YQMask";
6981            break;
6982        case 5:
6983            CP0_CHECK(ctx->insn_flags & ASE_MT);
6984            tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_VPESchedule));
6985            rn = "VPESchedule";
6986            break;
6987        case 6:
6988            CP0_CHECK(ctx->insn_flags & ASE_MT);
6989            tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_VPEScheFBack));
6990            rn = "VPEScheFBack";
6991            break;
6992        case 7:
6993            CP0_CHECK(ctx->insn_flags & ASE_MT);
6994            gen_helper_mtc0_vpeopt(cpu_env, arg);
6995            rn = "VPEOpt";
6996            break;
6997        default:
6998            goto cp0_unimplemented;
6999        }
7000        break;
7001    case 2:
7002        switch (sel) {
7003        case 0:
7004            gen_helper_dmtc0_entrylo0(cpu_env, arg);
7005            rn = "EntryLo0";
7006            break;
7007        case 1:
7008            CP0_CHECK(ctx->insn_flags & ASE_MT);
7009            gen_helper_mtc0_tcstatus(cpu_env, arg);
7010            rn = "TCStatus";
7011            break;
7012        case 2:
7013            CP0_CHECK(ctx->insn_flags & ASE_MT);
7014            gen_helper_mtc0_tcbind(cpu_env, arg);
7015            rn = "TCBind";
7016            break;
7017        case 3:
7018            CP0_CHECK(ctx->insn_flags & ASE_MT);
7019            gen_helper_mtc0_tcrestart(cpu_env, arg);
7020            rn = "TCRestart";
7021            break;
7022        case 4:
7023            CP0_CHECK(ctx->insn_flags & ASE_MT);
7024            gen_helper_mtc0_tchalt(cpu_env, arg);
7025            rn = "TCHalt";
7026            break;
7027        case 5:
7028            CP0_CHECK(ctx->insn_flags & ASE_MT);
7029            gen_helper_mtc0_tccontext(cpu_env, arg);
7030            rn = "TCContext";
7031            break;
7032        case 6:
7033            CP0_CHECK(ctx->insn_flags & ASE_MT);
7034            gen_helper_mtc0_tcschedule(cpu_env, arg);
7035            rn = "TCSchedule";
7036            break;
7037        case 7:
7038            CP0_CHECK(ctx->insn_flags & ASE_MT);
7039            gen_helper_mtc0_tcschefback(cpu_env, arg);
7040            rn = "TCScheFBack";
7041            break;
7042        default:
7043            goto cp0_unimplemented;
7044        }
7045        break;
7046    case 3:
7047        switch (sel) {
7048        case 0:
7049            gen_helper_dmtc0_entrylo1(cpu_env, arg);
7050            rn = "EntryLo1";
7051            break;
7052        case 1:
7053            CP0_CHECK(ctx->vp);
7054            /* ignored */
7055            rn = "GlobalNumber";
7056            break;
7057        default:
7058            goto cp0_unimplemented;
7059        }
7060        break;
7061    case 4:
7062        switch (sel) {
7063        case 0:
7064            gen_helper_mtc0_context(cpu_env, arg);
7065            rn = "Context";
7066            break;
7067        case 1:
7068//           gen_helper_mtc0_contextconfig(cpu_env, arg); /* SmartMIPS ASE */
7069            rn = "ContextConfig";
7070            goto cp0_unimplemented;
7071//           break;
7072        case 2:
7073            CP0_CHECK(ctx->ulri);
7074            tcg_gen_st_tl(arg, cpu_env,
7075                          offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
7076            rn = "UserLocal";
7077            break;
7078        default:
7079            goto cp0_unimplemented;
7080        }
7081        break;
7082    case 5:
7083        switch (sel) {
7084        case 0:
7085            gen_helper_mtc0_pagemask(cpu_env, arg);
7086            rn = "PageMask";
7087            break;
7088        case 1:
7089            check_insn(ctx, ISA_MIPS32R2);
7090            gen_helper_mtc0_pagegrain(cpu_env, arg);
7091            rn = "PageGrain";
7092            break;
7093        default:
7094            goto cp0_unimplemented;
7095        }
7096        break;
7097    case 6:
7098        switch (sel) {
7099        case 0:
7100            gen_helper_mtc0_wired(cpu_env, arg);
7101            rn = "Wired";
7102            break;
7103        case 1:
7104            check_insn(ctx, ISA_MIPS32R2);
7105            gen_helper_mtc0_srsconf0(cpu_env, arg);
7106            rn = "SRSConf0";
7107            break;
7108        case 2:
7109            check_insn(ctx, ISA_MIPS32R2);
7110            gen_helper_mtc0_srsconf1(cpu_env, arg);
7111            rn = "SRSConf1";
7112            break;
7113        case 3:
7114            check_insn(ctx, ISA_MIPS32R2);
7115            gen_helper_mtc0_srsconf2(cpu_env, arg);
7116            rn = "SRSConf2";
7117            break;
7118        case 4:
7119            check_insn(ctx, ISA_MIPS32R2);
7120            gen_helper_mtc0_srsconf3(cpu_env, arg);
7121            rn = "SRSConf3";
7122            break;
7123        case 5:
7124            check_insn(ctx, ISA_MIPS32R2);
7125            gen_helper_mtc0_srsconf4(cpu_env, arg);
7126            rn = "SRSConf4";
7127            break;
7128        default:
7129            goto cp0_unimplemented;
7130        }
7131        break;
7132    case 7:
7133        switch (sel) {
7134        case 0:
7135            check_insn(ctx, ISA_MIPS32R2);
7136            gen_helper_mtc0_hwrena(cpu_env, arg);
7137            ctx->bstate = BS_STOP;
7138            rn = "HWREna";
7139            break;
7140        default:
7141            goto cp0_unimplemented;
7142        }
7143        break;
7144    case 8:
7145        switch (sel) {
7146        case 0:
7147            /* ignored */
7148            rn = "BadVAddr";
7149            break;
7150        case 1:
7151            /* ignored */
7152            rn = "BadInstr";
7153            break;
7154        case 2:
7155            /* ignored */
7156            rn = "BadInstrP";
7157            break;
7158        default:
7159            goto cp0_unimplemented;
7160        }
7161        break;
7162    case 9:
7163        switch (sel) {
7164        case 0:
7165            gen_helper_mtc0_count(cpu_env, arg);
7166            rn = "Count";
7167            break;
7168        /* 6,7 are implementation dependent */
7169        default:
7170            goto cp0_unimplemented;
7171        }
7172        /* Stop translation as we may have switched the execution mode */
7173        ctx->bstate = BS_STOP;
7174        break;
7175    case 10:
7176        switch (sel) {
7177        case 0:
7178            gen_helper_mtc0_entryhi(cpu_env, arg);
7179            rn = "EntryHi";
7180            break;
7181        default:
7182            goto cp0_unimplemented;
7183        }
7184        break;
7185    case 11:
7186        switch (sel) {
7187        case 0:
7188            gen_helper_mtc0_compare(cpu_env, arg);
7189            rn = "Compare";
7190            break;
7191        /* 6,7 are implementation dependent */
7192        default:
7193            goto cp0_unimplemented;
7194        }
7195        /* Stop translation as we may have switched the execution mode */
7196        ctx->bstate = BS_STOP;
7197        break;
7198    case 12:
7199        switch (sel) {
7200        case 0:
7201            save_cpu_state(ctx, 1);
7202            gen_helper_mtc0_status(cpu_env, arg);
7203            /* BS_STOP isn't good enough here, hflags may have changed. */
7204            gen_save_pc(ctx->pc + 4);
7205            ctx->bstate = BS_EXCP;
7206            rn = "Status";
7207            break;
7208        case 1:
7209            check_insn(ctx, ISA_MIPS32R2);
7210            gen_helper_mtc0_intctl(cpu_env, arg);
7211            /* Stop translation as we may have switched the execution mode */
7212            ctx->bstate = BS_STOP;
7213            rn = "IntCtl";
7214            break;
7215        case 2:
7216            check_insn(ctx, ISA_MIPS32R2);
7217            gen_helper_mtc0_srsctl(cpu_env, arg);
7218            /* Stop translation as we may have switched the execution mode */
7219            ctx->bstate = BS_STOP;
7220            rn = "SRSCtl";
7221            break;
7222        case 3:
7223            check_insn(ctx, ISA_MIPS32R2);
7224            gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_SRSMap));
7225            /* Stop translation as we may have switched the execution mode */
7226            ctx->bstate = BS_STOP;
7227            rn = "SRSMap";
7228            break;
7229        default:
7230            goto cp0_unimplemented;
7231        }
7232        break;
7233    case 13:
7234        switch (sel) {
7235        case 0:
7236            save_cpu_state(ctx, 1);
7237            /* Mark as an IO operation because we may trigger a software
7238               interrupt.  */
7239            if (ctx->tb->cflags & CF_USE_ICOUNT) {
7240                gen_io_start();
7241            }
7242            gen_helper_mtc0_cause(cpu_env, arg);
7243            if (ctx->tb->cflags & CF_USE_ICOUNT) {
7244                gen_io_end();
7245            }
7246            /* Stop translation as we may have triggered an intetrupt */
7247            ctx->bstate = BS_STOP;
7248            rn = "Cause";
7249            break;
7250        default:
7251            goto cp0_unimplemented;
7252        }
7253        break;
7254    case 14:
7255        switch (sel) {
7256        case 0:
7257            tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EPC));
7258            rn = "EPC";
7259            break;
7260        default:
7261            goto cp0_unimplemented;
7262        }
7263        break;
7264    case 15:
7265        switch (sel) {
7266        case 0:
7267            /* ignored */
7268            rn = "PRid";
7269            break;
7270        case 1:
7271            check_insn(ctx, ISA_MIPS32R2);
7272            gen_helper_mtc0_ebase(cpu_env, arg);
7273            rn = "EBase";
7274            break;
7275        default:
7276            goto cp0_unimplemented;
7277        }
7278        break;
7279    case 16:
7280        switch (sel) {
7281        case 0:
7282            gen_helper_mtc0_config0(cpu_env, arg);
7283            rn = "Config";
7284            /* Stop translation as we may have switched the execution mode */
7285            ctx->bstate = BS_STOP;
7286            break;
7287        case 1:
7288            /* ignored, read only */
7289            rn = "Config1";
7290            break;
7291        case 2:
7292            gen_helper_mtc0_config2(cpu_env, arg);
7293            rn = "Config2";
7294            /* Stop translation as we may have switched the execution mode */
7295            ctx->bstate = BS_STOP;
7296            break;
7297        case 3:
7298            gen_helper_mtc0_config3(cpu_env, arg);
7299            rn = "Config3";
7300            /* Stop translation as we may have switched the execution mode */
7301            ctx->bstate = BS_STOP;
7302            break;
7303        case 4:
7304            /* currently ignored */
7305            rn = "Config4";
7306            break;
7307        case 5:
7308            gen_helper_mtc0_config5(cpu_env, arg);
7309            rn = "Config5";
7310            /* Stop translation as we may have switched the execution mode */
7311            ctx->bstate = BS_STOP;
7312            break;
7313        /* 6,7 are implementation dependent */
7314        default:
7315            rn = "Invalid config selector";
7316            goto cp0_unimplemented;
7317        }
7318        break;
7319    case 17:
7320        switch (sel) {
7321        case 0:
7322            gen_helper_mtc0_lladdr(cpu_env, arg);
7323            rn = "LLAddr";
7324            break;
7325        case 1:
7326            CP0_CHECK(ctx->mrp);
7327            gen_helper_mtc0_maar(cpu_env, arg);
7328            rn = "MAAR";
7329            break;
7330        case 2:
7331            CP0_CHECK(ctx->mrp);
7332            gen_helper_mtc0_maari(cpu_env, arg);
7333            rn = "MAARI";
7334            break;
7335        default:
7336            goto cp0_unimplemented;
7337        }
7338        break;
7339    case 18:
7340        switch (sel) {
7341        case 0 ... 7:
7342            gen_helper_0e1i(mtc0_watchlo, arg, sel);
7343            rn = "WatchLo";
7344            break;
7345        default:
7346            goto cp0_unimplemented;
7347        }
7348        break;
7349    case 19:
7350        switch (sel) {
7351        case 0 ... 7:
7352            gen_helper_0e1i(mtc0_watchhi, arg, sel);
7353            rn = "WatchHi";
7354            break;
7355        default:
7356            goto cp0_unimplemented;
7357        }
7358        break;
7359    case 20:
7360        switch (sel) {
7361        case 0:
7362            check_insn(ctx, ISA_MIPS3);
7363            gen_helper_mtc0_xcontext(cpu_env, arg);
7364            rn = "XContext";
7365            break;
7366        default:
7367            goto cp0_unimplemented;
7368        }
7369        break;
7370    case 21:
7371       /* Officially reserved, but sel 0 is used for R1x000 framemask */
7372        CP0_CHECK(!(ctx->insn_flags & ISA_MIPS32R6));
7373        switch (sel) {
7374        case 0:
7375            gen_helper_mtc0_framemask(cpu_env, arg);
7376            rn = "Framemask";
7377            break;
7378        default:
7379            goto cp0_unimplemented;
7380        }
7381        break;
7382    case 22:
7383        /* ignored */
7384        rn = "Diagnostic"; /* implementation dependent */
7385        break;
7386    case 23:
7387        switch (sel) {
7388        case 0:
7389            gen_helper_mtc0_debug(cpu_env, arg); /* EJTAG support */
7390            /* BS_STOP isn't good enough here, hflags may have changed. */
7391            gen_save_pc(ctx->pc + 4);
7392            ctx->bstate = BS_EXCP;
7393            rn = "Debug";
7394            break;
7395        case 1:
7396//            gen_helper_mtc0_tracecontrol(cpu_env, arg); /* PDtrace support */
7397            /* Stop translation as we may have switched the execution mode */
7398            ctx->bstate = BS_STOP;
7399            rn = "TraceControl";
7400//            break;
7401        case 2:
7402//            gen_helper_mtc0_tracecontrol2(cpu_env, arg); /* PDtrace support */
7403            /* Stop translation as we may have switched the execution mode */
7404            ctx->bstate = BS_STOP;
7405            rn = "TraceControl2";
7406//            break;
7407        case 3:
7408//            gen_helper_mtc0_usertracedata(cpu_env, arg); /* PDtrace support */
7409            /* Stop translation as we may have switched the execution mode */
7410            ctx->bstate = BS_STOP;
7411            rn = "UserTraceData";
7412//            break;
7413        case 4:
7414//            gen_helper_mtc0_tracebpc(cpu_env, arg); /* PDtrace support */
7415            /* Stop translation as we may have switched the execution mode */
7416            ctx->bstate = BS_STOP;
7417            rn = "TraceBPC";
7418//            break;
7419        default:
7420            goto cp0_unimplemented;
7421        }
7422        break;
7423    case 24:
7424        switch (sel) {
7425        case 0:
7426            /* EJTAG support */
7427            tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_DEPC));
7428            rn = "DEPC";
7429            break;
7430        default:
7431            goto cp0_unimplemented;
7432        }
7433        break;
7434    case 25:
7435        switch (sel) {
7436        case 0:
7437            gen_helper_mtc0_performance0(cpu_env, arg);
7438            rn = "Performance0";
7439            break;
7440        case 1:
7441//            gen_helper_mtc0_performance1(cpu_env, arg);
7442            rn = "Performance1";
7443//            break;
7444        case 2:
7445//            gen_helper_mtc0_performance2(cpu_env, arg);
7446            rn = "Performance2";
7447//            break;
7448        case 3:
7449//            gen_helper_mtc0_performance3(cpu_env, arg);
7450            rn = "Performance3";
7451//            break;
7452        case 4:
7453//            gen_helper_mtc0_performance4(cpu_env, arg);
7454            rn = "Performance4";
7455//            break;
7456        case 5:
7457//            gen_helper_mtc0_performance5(cpu_env, arg);
7458            rn = "Performance5";
7459//            break;
7460        case 6:
7461//            gen_helper_mtc0_performance6(cpu_env, arg);
7462            rn = "Performance6";
7463//            break;
7464        case 7:
7465//            gen_helper_mtc0_performance7(cpu_env, arg);
7466            rn = "Performance7";
7467//            break;
7468        default:
7469            goto cp0_unimplemented;
7470        }
7471        break;
7472    case 26:
7473        switch (sel) {
7474        case 0:
7475            gen_helper_mtc0_errctl(cpu_env, arg);
7476            ctx->bstate = BS_STOP;
7477            rn = "ErrCtl";
7478            break;
7479        default:
7480            goto cp0_unimplemented;
7481        }
7482        break;
7483    case 27:
7484        switch (sel) {
7485        case 0 ... 3:
7486            /* ignored */
7487            rn = "CacheErr";
7488            break;
7489        default:
7490            goto cp0_unimplemented;
7491        }
7492        break;
7493    case 28:
7494        switch (sel) {
7495        case 0:
7496        case 2:
7497        case 4:
7498        case 6:
7499            gen_helper_mtc0_taglo(cpu_env, arg);
7500            rn = "TagLo";
7501            break;
7502        case 1:
7503        case 3:
7504        case 5:
7505        case 7:
7506            gen_helper_mtc0_datalo(cpu_env, arg);
7507            rn = "DataLo";
7508            break;
7509        default:
7510            goto cp0_unimplemented;
7511        }
7512        break;
7513    case 29:
7514        switch (sel) {
7515        case 0:
7516        case 2:
7517        case 4:
7518        case 6:
7519            gen_helper_mtc0_taghi(cpu_env, arg);
7520            rn = "TagHi";
7521            break;
7522        case 1:
7523        case 3:
7524        case 5:
7525        case 7:
7526            gen_helper_mtc0_datahi(cpu_env, arg);
7527            rn = "DataHi";
7528            break;
7529        default:
7530            rn = "invalid sel";
7531            goto cp0_unimplemented;
7532        }
7533        break;
7534    case 30:
7535        switch (sel) {
7536        case 0:
7537            tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_ErrorEPC));
7538            rn = "ErrorEPC";
7539            break;
7540        default:
7541            goto cp0_unimplemented;
7542        }
7543        break;
7544    case 31:
7545        switch (sel) {
7546        case 0:
7547            /* EJTAG support */
7548            gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_DESAVE));
7549            rn = "DESAVE";
7550            break;
7551        case 2 ... 7:
7552            CP0_CHECK(ctx->kscrexist & (1 << sel));
7553            tcg_gen_st_tl(arg, cpu_env,
7554                          offsetof(CPUMIPSState, CP0_KScratch[sel-2]));
7555            rn = "KScratch";
7556            break;
7557        default:
7558            goto cp0_unimplemented;
7559        }
7560        /* Stop translation as we may have switched the execution mode */
7561        ctx->bstate = BS_STOP;
7562        break;
7563    default:
7564        goto cp0_unimplemented;
7565    }
7566    (void)rn; /* avoid a compiler warning */
7567    LOG_DISAS("dmtc0 %s (reg %d sel %d)\n", rn, reg, sel);
7568    /* For simplicity assume that all writes can cause interrupts.  */
7569    if (ctx->tb->cflags & CF_USE_ICOUNT) {
7570        gen_io_end();
7571        ctx->bstate = BS_STOP;
7572    }
7573    return;
7574
7575cp0_unimplemented:
7576    LOG_DISAS("dmtc0 %s (reg %d sel %d)\n", rn, reg, sel);
7577}
7578#endif /* TARGET_MIPS64 */
7579
7580static void gen_mftr(CPUMIPSState *env, DisasContext *ctx, int rt, int rd,
7581                     int u, int sel, int h)
7582{
7583    int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
7584    TCGv t0 = tcg_temp_local_new();
7585
7586    if ((env->CP0_VPEConf0 & (1 << CP0VPEC0_MVP)) == 0 &&
7587        ((env->tcs[other_tc].CP0_TCBind & (0xf << CP0TCBd_CurVPE)) !=
7588         (env->active_tc.CP0_TCBind & (0xf << CP0TCBd_CurVPE))))
7589        tcg_gen_movi_tl(t0, -1);
7590    else if ((env->CP0_VPEControl & (0xff << CP0VPECo_TargTC)) >
7591             (env->mvp->CP0_MVPConf0 & (0xff << CP0MVPC0_PTC)))
7592        tcg_gen_movi_tl(t0, -1);
7593    else if (u == 0) {
7594        switch (rt) {
7595        case 1:
7596            switch (sel) {
7597            case 1:
7598                gen_helper_mftc0_vpecontrol(t0, cpu_env);
7599                break;
7600            case 2:
7601                gen_helper_mftc0_vpeconf0(t0, cpu_env);
7602                break;
7603            default:
7604                goto die;
7605                break;
7606            }
7607            break;
7608        case 2:
7609            switch (sel) {
7610            case 1:
7611                gen_helper_mftc0_tcstatus(t0, cpu_env);
7612                break;
7613            case 2:
7614                gen_helper_mftc0_tcbind(t0, cpu_env);
7615                break;
7616            case 3:
7617                gen_helper_mftc0_tcrestart(t0, cpu_env);
7618                break;
7619            case 4:
7620                gen_helper_mftc0_tchalt(t0, cpu_env);
7621                break;
7622            case 5:
7623                gen_helper_mftc0_tccontext(t0, cpu_env);
7624                break;
7625            case 6:
7626                gen_helper_mftc0_tcschedule(t0, cpu_env);
7627                break;
7628            case 7:
7629                gen_helper_mftc0_tcschefback(t0, cpu_env);
7630                break;
7631            default:
7632                gen_mfc0(ctx, t0, rt, sel);
7633                break;
7634            }
7635            break;
7636        case 10:
7637            switch (sel) {
7638            case 0:
7639                gen_helper_mftc0_entryhi(t0, cpu_env);
7640                break;
7641            default:
7642                gen_mfc0(ctx, t0, rt, sel);
7643                break;
7644            }
7645        case 12:
7646            switch (sel) {
7647            case 0:
7648                gen_helper_mftc0_status(t0, cpu_env);
7649                break;
7650            default:
7651                gen_mfc0(ctx, t0, rt, sel);
7652                break;
7653            }
7654        case 13:
7655            switch (sel) {
7656            case 0:
7657                gen_helper_mftc0_cause(t0, cpu_env);
7658                break;
7659            default:
7660                goto die;
7661                break;
7662            }
7663            break;
7664        case 14:
7665            switch (sel) {
7666            case 0:
7667                gen_helper_mftc0_epc(t0, cpu_env);
7668                break;
7669            default:
7670                goto die;
7671                break;
7672            }
7673            break;
7674        case 15:
7675            switch (sel) {
7676            case 1:
7677                gen_helper_mftc0_ebase(t0, cpu_env);
7678                break;
7679            default:
7680                goto die;
7681                break;
7682            }
7683            break;
7684        case 16:
7685            switch (sel) {
7686            case 0 ... 7:
7687                gen_helper_mftc0_configx(t0, cpu_env, tcg_const_tl(sel));
7688                break;
7689            default:
7690                goto die;
7691                break;
7692            }
7693            break;
7694        case 23:
7695            switch (sel) {
7696            case 0:
7697                gen_helper_mftc0_debug(t0, cpu_env);
7698                break;
7699            default:
7700                gen_mfc0(ctx, t0, rt, sel);
7701                break;
7702            }
7703            break;
7704        default:
7705            gen_mfc0(ctx, t0, rt, sel);
7706        }
7707    } else switch (sel) {
7708    /* GPR registers. */
7709    case 0:
7710        gen_helper_1e0i(mftgpr, t0, rt);
7711        break;
7712    /* Auxiliary CPU registers */
7713    case 1:
7714        switch (rt) {
7715        case 0:
7716            gen_helper_1e0i(mftlo, t0, 0);
7717            break;
7718        case 1:
7719            gen_helper_1e0i(mfthi, t0, 0);
7720            break;
7721        case 2:
7722            gen_helper_1e0i(mftacx, t0, 0);
7723            break;
7724        case 4:
7725            gen_helper_1e0i(mftlo, t0, 1);
7726            break;
7727        case 5:
7728            gen_helper_1e0i(mfthi, t0, 1);
7729            break;
7730        case 6:
7731            gen_helper_1e0i(mftacx, t0, 1);
7732            break;
7733        case 8:
7734            gen_helper_1e0i(mftlo, t0, 2);
7735            break;
7736        case 9:
7737            gen_helper_1e0i(mfthi, t0, 2);
7738            break;
7739        case 10:
7740            gen_helper_1e0i(mftacx, t0, 2);
7741            break;
7742        case 12:
7743            gen_helper_1e0i(mftlo, t0, 3);
7744            break;
7745        case 13:
7746            gen_helper_1e0i(mfthi, t0, 3);
7747            break;
7748        case 14:
7749            gen_helper_1e0i(mftacx, t0, 3);
7750            break;
7751        case 16:
7752            gen_helper_mftdsp(t0, cpu_env);
7753            break;
7754        default:
7755            goto die;
7756        }
7757        break;
7758    /* Floating point (COP1). */
7759    case 2:
7760        /* XXX: For now we support only a single FPU context. */
7761        if (h == 0) {
7762            TCGv_i32 fp0 = tcg_temp_new_i32();
7763
7764            gen_load_fpr32(ctx, fp0, rt);
7765            tcg_gen_ext_i32_tl(t0, fp0);
7766            tcg_temp_free_i32(fp0);
7767        } else {
7768            TCGv_i32 fp0 = tcg_temp_new_i32();
7769
7770            gen_load_fpr32h(ctx, fp0, rt);
7771            tcg_gen_ext_i32_tl(t0, fp0);
7772            tcg_temp_free_i32(fp0);
7773        }
7774        break;
7775    case 3:
7776        /* XXX: For now we support only a single FPU context. */
7777        gen_helper_1e0i(cfc1, t0, rt);
7778        break;
7779    /* COP2: Not implemented. */
7780    case 4:
7781    case 5:
7782        /* fall through */
7783    default:
7784        goto die;
7785    }
7786    LOG_DISAS("mftr (reg %d u %d sel %d h %d)\n", rt, u, sel, h);
7787    gen_store_gpr(t0, rd);
7788    tcg_temp_free(t0);
7789    return;
7790
7791die:
7792    tcg_temp_free(t0);
7793    LOG_DISAS("mftr (reg %d u %d sel %d h %d)\n", rt, u, sel, h);
7794    generate_exception_end(ctx, EXCP_RI);
7795}
7796
7797static void gen_mttr(CPUMIPSState *env, DisasContext *ctx, int rd, int rt,
7798                     int u, int sel, int h)
7799{
7800    int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
7801    TCGv t0 = tcg_temp_local_new();
7802
7803    gen_load_gpr(t0, rt);
7804    if ((env->CP0_VPEConf0 & (1 << CP0VPEC0_MVP)) == 0 &&
7805        ((env->tcs[other_tc].CP0_TCBind & (0xf << CP0TCBd_CurVPE)) !=
7806         (env->active_tc.CP0_TCBind & (0xf << CP0TCBd_CurVPE))))
7807        /* NOP */ ;
7808    else if ((env->CP0_VPEControl & (0xff << CP0VPECo_TargTC)) >
7809             (env->mvp->CP0_MVPConf0 & (0xff << CP0MVPC0_PTC)))
7810        /* NOP */ ;
7811    else if (u == 0) {
7812        switch (rd) {
7813        case 1:
7814            switch (sel) {
7815            case 1:
7816                gen_helper_mttc0_vpecontrol(cpu_env, t0);
7817                break;
7818            case 2:
7819                gen_helper_mttc0_vpeconf0(cpu_env, t0);
7820                break;
7821            default:
7822                goto die;
7823                break;
7824            }
7825            break;
7826        case 2:
7827            switch (sel) {
7828            case 1:
7829                gen_helper_mttc0_tcstatus(cpu_env, t0);
7830                break;
7831            case 2:
7832                gen_helper_mttc0_tcbind(cpu_env, t0);
7833                break;
7834            case 3:
7835                gen_helper_mttc0_tcrestart(cpu_env, t0);
7836                break;
7837            case 4:
7838                gen_helper_mttc0_tchalt(cpu_env, t0);
7839                break;
7840            case 5:
7841                gen_helper_mttc0_tccontext(cpu_env, t0);
7842                break;
7843            case 6:
7844                gen_helper_mttc0_tcschedule(cpu_env, t0);
7845                break;
7846            case 7:
7847                gen_helper_mttc0_tcschefback(cpu_env, t0);
7848                break;
7849            default:
7850                gen_mtc0(ctx, t0, rd, sel);
7851                break;
7852            }
7853            break;
7854        case 10:
7855            switch (sel) {
7856            case 0:
7857                gen_helper_mttc0_entryhi(cpu_env, t0);
7858                break;
7859            default:
7860                gen_mtc0(ctx, t0, rd, sel);
7861                break;
7862            }
7863        case 12:
7864            switch (sel) {
7865            case 0:
7866                gen_helper_mttc0_status(cpu_env, t0);
7867                break;
7868            default:
7869                gen_mtc0(ctx, t0, rd, sel);
7870                break;
7871            }
7872        case 13:
7873            switch (sel) {
7874            case 0:
7875                gen_helper_mttc0_cause(cpu_env, t0);
7876                break;
7877            default:
7878                goto die;
7879                break;
7880            }
7881            break;
7882        case 15:
7883            switch (sel) {
7884            case 1:
7885                gen_helper_mttc0_ebase(cpu_env, t0);
7886                break;
7887            default:
7888                goto die;
7889                break;
7890            }
7891            break;
7892        case 23:
7893            switch (sel) {
7894            case 0:
7895                gen_helper_mttc0_debug(cpu_env, t0);
7896                break;
7897            default:
7898                gen_mtc0(ctx, t0, rd, sel);
7899                break;
7900            }
7901            break;
7902        default:
7903            gen_mtc0(ctx, t0, rd, sel);
7904        }
7905    } else switch (sel) {
7906    /* GPR registers. */
7907    case 0:
7908        gen_helper_0e1i(mttgpr, t0, rd);
7909        break;
7910    /* Auxiliary CPU registers */
7911    case 1:
7912        switch (rd) {
7913        case 0:
7914            gen_helper_0e1i(mttlo, t0, 0);
7915            break;
7916        case 1:
7917            gen_helper_0e1i(mtthi, t0, 0);
7918            break;
7919        case 2:
7920            gen_helper_0e1i(mttacx, t0, 0);
7921            break;
7922        case 4:
7923            gen_helper_0e1i(mttlo, t0, 1);
7924            break;
7925        case 5:
7926            gen_helper_0e1i(mtthi, t0, 1);
7927            break;
7928        case 6:
7929            gen_helper_0e1i(mttacx, t0, 1);
7930            break;
7931        case 8:
7932            gen_helper_0e1i(mttlo, t0, 2);
7933            break;
7934        case 9:
7935            gen_helper_0e1i(mtthi, t0, 2);
7936            break;
7937        case 10:
7938            gen_helper_0e1i(mttacx, t0, 2);
7939            break;
7940        case 12:
7941            gen_helper_0e1i(mttlo, t0, 3);
7942            break;
7943        case 13:
7944            gen_helper_0e1i(mtthi, t0, 3);
7945            break;
7946        case 14:
7947            gen_helper_0e1i(mttacx, t0, 3);
7948            break;
7949        case 16:
7950            gen_helper_mttdsp(cpu_env, t0);
7951            break;
7952        default:
7953            goto die;
7954        }
7955        break;
7956    /* Floating point (COP1). */
7957    case 2:
7958        /* XXX: For now we support only a single FPU context. */
7959        if (h == 0) {
7960            TCGv_i32 fp0 = tcg_temp_new_i32();
7961
7962            tcg_gen_trunc_tl_i32(fp0, t0);
7963            gen_store_fpr32(ctx, fp0, rd);
7964            tcg_temp_free_i32(fp0);
7965        } else {
7966            TCGv_i32 fp0 = tcg_temp_new_i32();
7967
7968            tcg_gen_trunc_tl_i32(fp0, t0);
7969            gen_store_fpr32h(ctx, fp0, rd);
7970            tcg_temp_free_i32(fp0);
7971        }
7972        break;
7973    case 3:
7974        /* XXX: For now we support only a single FPU context. */
7975        {
7976            TCGv_i32 fs_tmp = tcg_const_i32(rd);
7977
7978            gen_helper_0e2i(ctc1, t0, fs_tmp, rt);
7979            tcg_temp_free_i32(fs_tmp);
7980        }
7981        /* Stop translation as we may have changed hflags */
7982        ctx->bstate = BS_STOP;
7983        break;
7984    /* COP2: Not implemented. */
7985    case 4:
7986    case 5:
7987        /* fall through */
7988    default:
7989        goto die;
7990    }
7991    LOG_DISAS("mttr (reg %d u %d sel %d h %d)\n", rd, u, sel, h);
7992    tcg_temp_free(t0);
7993    return;
7994
7995die:
7996    tcg_temp_free(t0);
7997    LOG_DISAS("mttr (reg %d u %d sel %d h %d)\n", rd, u, sel, h);
7998    generate_exception_end(ctx, EXCP_RI);
7999}
8000
8001static void gen_cp0 (CPUMIPSState *env, DisasContext *ctx, uint32_t opc, int rt, int rd)
8002{
8003    const char *opn = "ldst";
8004
8005    check_cp0_enabled(ctx);
8006    switch (opc) {
8007    case OPC_MFC0:
8008        if (rt == 0) {
8009            /* Treat as NOP. */
8010            return;
8011        }
8012        gen_mfc0(ctx, cpu_gpr[rt], rd, ctx->opcode & 0x7);
8013        opn = "mfc0";
8014        break;
8015    case OPC_MTC0:
8016        {
8017            TCGv t0 = tcg_temp_new();
8018
8019            gen_load_gpr(t0, rt);
8020            gen_mtc0(ctx, t0, rd, ctx->opcode & 0x7);
8021            tcg_temp_free(t0);
8022        }
8023        opn = "mtc0";
8024        break;
8025#if defined(TARGET_MIPS64)
8026    case OPC_DMFC0:
8027        check_insn(ctx, ISA_MIPS3);
8028        if (rt == 0) {
8029            /* Treat as NOP. */
8030            return;
8031        }
8032        gen_dmfc0(ctx, cpu_gpr[rt], rd, ctx->opcode & 0x7);
8033        opn = "dmfc0";
8034        break;
8035    case OPC_DMTC0:
8036        check_insn(ctx, ISA_MIPS3);
8037        {
8038            TCGv t0 = tcg_temp_new();
8039
8040            gen_load_gpr(t0, rt);
8041            gen_dmtc0(ctx, t0, rd, ctx->opcode & 0x7);
8042            tcg_temp_free(t0);
8043        }
8044        opn = "dmtc0";
8045        break;
8046#endif
8047    case OPC_MFHC0:
8048        check_mvh(ctx);
8049        if (rt == 0) {
8050            /* Treat as NOP. */
8051            return;
8052        }
8053        gen_mfhc0(ctx, cpu_gpr[rt], rd, ctx->opcode & 0x7);
8054        opn = "mfhc0";
8055        break;
8056    case OPC_MTHC0:
8057        check_mvh(ctx);
8058        {
8059            TCGv t0 = tcg_temp_new();
8060            gen_load_gpr(t0, rt);
8061            gen_mthc0(ctx, t0, rd, ctx->opcode & 0x7);
8062            tcg_temp_free(t0);
8063        }
8064        opn = "mthc0";
8065        break;
8066    case OPC_MFTR:
8067        check_insn(ctx, ASE_MT);
8068        if (rd == 0) {
8069            /* Treat as NOP. */
8070            return;
8071        }
8072        gen_mftr(env, ctx, rt, rd, (ctx->opcode >> 5) & 1,
8073                 ctx->opcode & 0x7, (ctx->opcode >> 4) & 1);
8074        opn = "mftr";
8075        break;
8076    case OPC_MTTR:
8077        check_insn(ctx, ASE_MT);
8078        gen_mttr(env, ctx, rd, rt, (ctx->opcode >> 5) & 1,
8079                 ctx->opcode & 0x7, (ctx->opcode >> 4) & 1);
8080        opn = "mttr";
8081        break;
8082    case OPC_TLBWI:
8083        opn = "tlbwi";
8084        if (!env->tlb->helper_tlbwi)
8085            goto die;
8086        gen_helper_tlbwi(cpu_env);
8087        break;
8088    case OPC_TLBINV:
8089        opn = "tlbinv";
8090        if (ctx->ie >= 2) {
8091            if (!env->tlb->helper_tlbinv) {
8092                goto die;
8093            }
8094            gen_helper_tlbinv(cpu_env);
8095        } /* treat as nop if TLBINV not supported */
8096        break;
8097    case OPC_TLBINVF:
8098        opn = "tlbinvf";
8099        if (ctx->ie >= 2) {
8100            if (!env->tlb->helper_tlbinvf) {
8101                goto die;
8102            }
8103            gen_helper_tlbinvf(cpu_env);
8104        } /* treat as nop if TLBINV not supported */
8105        break;
8106    case OPC_TLBWR:
8107        opn = "tlbwr";
8108        if (!env->tlb->helper_tlbwr)
8109            goto die;
8110        gen_helper_tlbwr(cpu_env);
8111        break;
8112    case OPC_TLBP:
8113        opn = "tlbp";
8114        if (!env->tlb->helper_tlbp)
8115            goto die;
8116        gen_helper_tlbp(cpu_env);
8117        break;
8118    case OPC_TLBR:
8119        opn = "tlbr";
8120        if (!env->tlb->helper_tlbr)
8121            goto die;
8122        gen_helper_tlbr(cpu_env);
8123        break;
8124    case OPC_ERET: /* OPC_ERETNC */
8125        if ((ctx->insn_flags & ISA_MIPS32R6) &&
8126            (ctx->hflags & MIPS_HFLAG_BMASK)) {
8127            goto die;
8128        } else {
8129            int bit_shift = (ctx->hflags & MIPS_HFLAG_M16) ? 16 : 6;
8130            if (ctx->opcode & (1 << bit_shift)) {
8131                /* OPC_ERETNC */
8132                opn = "eretnc";
8133                check_insn(ctx, ISA_MIPS32R5);
8134                gen_helper_eretnc(cpu_env);
8135            } else {
8136                /* OPC_ERET */
8137                opn = "eret";
8138                check_insn(ctx, ISA_MIPS2);
8139                gen_helper_eret(cpu_env);
8140            }
8141            ctx->bstate = BS_EXCP;
8142        }
8143        break;
8144    case OPC_DERET:
8145        opn = "deret";
8146        check_insn(ctx, ISA_MIPS32);
8147        if ((ctx->insn_flags & ISA_MIPS32R6) &&
8148            (ctx->hflags & MIPS_HFLAG_BMASK)) {
8149            goto die;
8150        }
8151        if (!(ctx->hflags & MIPS_HFLAG_DM)) {
8152            MIPS_INVAL(opn);
8153            generate_exception_end(ctx, EXCP_RI);
8154        } else {
8155            gen_helper_deret(cpu_env);
8156            ctx->bstate = BS_EXCP;
8157        }
8158        break;
8159    case OPC_WAIT:
8160        opn = "wait";
8161        check_insn(ctx, ISA_MIPS3 | ISA_MIPS32);
8162        if ((ctx->insn_flags & ISA_MIPS32R6) &&
8163            (ctx->hflags & MIPS_HFLAG_BMASK)) {
8164            goto die;
8165        }
8166        /* If we get an exception, we want to restart at next instruction */
8167        ctx->pc += 4;
8168        save_cpu_state(ctx, 1);
8169        ctx->pc -= 4;
8170        gen_helper_wait(cpu_env);
8171        ctx->bstate = BS_EXCP;
8172        break;
8173    default:
8174 die:
8175        MIPS_INVAL(opn);
8176        generate_exception_end(ctx, EXCP_RI);
8177        return;
8178    }
8179    (void)opn; /* avoid a compiler warning */
8180}
8181#endif /* !CONFIG_USER_ONLY */
8182
8183/* CP1 Branches (before delay slot) */
8184static void gen_compute_branch1(DisasContext *ctx, uint32_t op,
8185                                int32_t cc, int32_t offset)
8186{
8187    target_ulong btarget;
8188    TCGv_i32 t0 = tcg_temp_new_i32();
8189
8190    if ((ctx->insn_flags & ISA_MIPS32R6) && (ctx->hflags & MIPS_HFLAG_BMASK)) {
8191        generate_exception_end(ctx, EXCP_RI);
8192        goto out;
8193    }
8194
8195    if (cc != 0)
8196        check_insn(ctx, ISA_MIPS4 | ISA_MIPS32);
8197
8198    btarget = ctx->pc + 4 + offset;
8199
8200    switch (op) {
8201    case OPC_BC1F:
8202        tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
8203        tcg_gen_not_i32(t0, t0);
8204        tcg_gen_andi_i32(t0, t0, 1);
8205        tcg_gen_extu_i32_tl(bcond, t0);
8206        goto not_likely;
8207    case OPC_BC1FL:
8208        tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
8209        tcg_gen_not_i32(t0, t0);
8210        tcg_gen_andi_i32(t0, t0, 1);
8211        tcg_gen_extu_i32_tl(bcond, t0);
8212        goto likely;
8213    case OPC_BC1T:
8214        tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
8215        tcg_gen_andi_i32(t0, t0, 1);
8216        tcg_gen_extu_i32_tl(bcond, t0);
8217        goto not_likely;
8218    case OPC_BC1TL:
8219        tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
8220        tcg_gen_andi_i32(t0, t0, 1);
8221        tcg_gen_extu_i32_tl(bcond, t0);
8222    likely:
8223        ctx->hflags |= MIPS_HFLAG_BL;
8224        break;
8225    case OPC_BC1FANY2:
8226        {
8227            TCGv_i32 t1 = tcg_temp_new_i32();
8228            tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
8229            tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+1));
8230            tcg_gen_nand_i32(t0, t0, t1);
8231            tcg_temp_free_i32(t1);
8232            tcg_gen_andi_i32(t0, t0, 1);
8233            tcg_gen_extu_i32_tl(bcond, t0);
8234        }
8235        goto not_likely;
8236    case OPC_BC1TANY2:
8237        {
8238            TCGv_i32 t1 = tcg_temp_new_i32();
8239            tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
8240            tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+1));
8241            tcg_gen_or_i32(t0, t0, t1);
8242            tcg_temp_free_i32(t1);
8243            tcg_gen_andi_i32(t0, t0, 1);
8244            tcg_gen_extu_i32_tl(bcond, t0);
8245        }
8246        goto not_likely;
8247    case OPC_BC1FANY4:
8248        {
8249            TCGv_i32 t1 = tcg_temp_new_i32();
8250            tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
8251            tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+1));
8252            tcg_gen_and_i32(t0, t0, t1);
8253            tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+2));
8254            tcg_gen_and_i32(t0, t0, t1);
8255            tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+3));
8256            tcg_gen_nand_i32(t0, t0, t1);
8257            tcg_temp_free_i32(t1);
8258            tcg_gen_andi_i32(t0, t0, 1);
8259            tcg_gen_extu_i32_tl(bcond, t0);
8260        }
8261        goto not_likely;
8262    case OPC_BC1TANY4:
8263        {
8264            TCGv_i32 t1 = tcg_temp_new_i32();
8265            tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
8266            tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+1));
8267            tcg_gen_or_i32(t0, t0, t1);
8268            tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+2));
8269            tcg_gen_or_i32(t0, t0, t1);
8270            tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+3));
8271            tcg_gen_or_i32(t0, t0, t1);
8272            tcg_temp_free_i32(t1);
8273            tcg_gen_andi_i32(t0, t0, 1);
8274            tcg_gen_extu_i32_tl(bcond, t0);
8275        }
8276    not_likely:
8277        ctx->hflags |= MIPS_HFLAG_BC;
8278        break;
8279    default:
8280        MIPS_INVAL("cp1 cond branch");
8281        generate_exception_end(ctx, EXCP_RI);
8282        goto out;
8283    }
8284    ctx->btarget = btarget;
8285    ctx->hflags |= MIPS_HFLAG_BDS32;
8286 out:
8287    tcg_temp_free_i32(t0);
8288}
8289
8290/* R6 CP1 Branches */
8291static void gen_compute_branch1_r6(DisasContext *ctx, uint32_t op,
8292                                   int32_t ft, int32_t offset,
8293                                   int delayslot_size)
8294{
8295    target_ulong btarget;
8296    TCGv_i64 t0 = tcg_temp_new_i64();
8297
8298    if (ctx->hflags & MIPS_HFLAG_BMASK) {
8299#ifdef MIPS_DEBUG_DISAS
8300        LOG_DISAS("Branch in delay / forbidden slot at PC 0x" TARGET_FMT_lx
8301                  "\n", ctx->pc);
8302#endif
8303        generate_exception_end(ctx, EXCP_RI);
8304        goto out;
8305    }
8306
8307    gen_load_fpr64(ctx, t0, ft);
8308    tcg_gen_andi_i64(t0, t0, 1);
8309
8310    btarget = addr_add(ctx, ctx->pc + 4, offset);
8311
8312    switch (op) {
8313    case OPC_BC1EQZ:
8314        tcg_gen_xori_i64(t0, t0, 1);
8315        ctx->hflags |= MIPS_HFLAG_BC;
8316        break;
8317    case OPC_BC1NEZ:
8318        /* t0 already set */
8319        ctx->hflags |= MIPS_HFLAG_BC;
8320        break;
8321    default:
8322        MIPS_INVAL("cp1 cond branch");
8323        generate_exception_end(ctx, EXCP_RI);
8324        goto out;
8325    }
8326
8327    tcg_gen_trunc_i64_tl(bcond, t0);
8328
8329    ctx->btarget = btarget;
8330
8331    switch (delayslot_size) {
8332    case 2:
8333        ctx->hflags |= MIPS_HFLAG_BDS16;
8334        break;
8335    case 4:
8336        ctx->hflags |= MIPS_HFLAG_BDS32;
8337        break;
8338    }
8339
8340out:
8341    tcg_temp_free_i64(t0);
8342}
8343
8344/* Coprocessor 1 (FPU) */
8345
8346#define FOP(func, fmt) (((fmt) << 21) | (func))
8347
8348enum fopcode {
8349    OPC_ADD_S = FOP(0, FMT_S),
8350    OPC_SUB_S = FOP(1, FMT_S),
8351    OPC_MUL_S = FOP(2, FMT_S),
8352    OPC_DIV_S = FOP(3, FMT_S),
8353    OPC_SQRT_S = FOP(4, FMT_S),
8354    OPC_ABS_S = FOP(5, FMT_S),
8355    OPC_MOV_S = FOP(6, FMT_S),
8356    OPC_NEG_S = FOP(7, FMT_S),
8357    OPC_ROUND_L_S = FOP(8, FMT_S),
8358    OPC_TRUNC_L_S = FOP(9, FMT_S),
8359    OPC_CEIL_L_S = FOP(10, FMT_S),
8360    OPC_FLOOR_L_S = FOP(11, FMT_S),
8361    OPC_ROUND_W_S = FOP(12, FMT_S),
8362    OPC_TRUNC_W_S = FOP(13, FMT_S),
8363    OPC_CEIL_W_S = FOP(14, FMT_S),
8364    OPC_FLOOR_W_S = FOP(15, FMT_S),
8365    OPC_SEL_S = FOP(16, FMT_S),
8366    OPC_MOVCF_S = FOP(17, FMT_S),
8367    OPC_MOVZ_S = FOP(18, FMT_S),
8368    OPC_MOVN_S = FOP(19, FMT_S),
8369    OPC_SELEQZ_S = FOP(20, FMT_S),
8370    OPC_RECIP_S = FOP(21, FMT_S),
8371    OPC_RSQRT_S = FOP(22, FMT_S),
8372    OPC_SELNEZ_S = FOP(23, FMT_S),
8373    OPC_MADDF_S = FOP(24, FMT_S),
8374    OPC_MSUBF_S = FOP(25, FMT_S),
8375    OPC_RINT_S = FOP(26, FMT_S),
8376    OPC_CLASS_S = FOP(27, FMT_S),
8377    OPC_MIN_S = FOP(28, FMT_S),
8378    OPC_RECIP2_S = FOP(28, FMT_S),
8379    OPC_MINA_S = FOP(29, FMT_S),
8380    OPC_RECIP1_S = FOP(29, FMT_S),
8381    OPC_MAX_S = FOP(30, FMT_S),
8382    OPC_RSQRT1_S = FOP(30, FMT_S),
8383    OPC_MAXA_S = FOP(31, FMT_S),
8384    OPC_RSQRT2_S = FOP(31, FMT_S),
8385    OPC_CVT_D_S = FOP(33, FMT_S),
8386    OPC_CVT_W_S = FOP(36, FMT_S),
8387    OPC_CVT_L_S = FOP(37, FMT_S),
8388    OPC_CVT_PS_S = FOP(38, FMT_S),
8389    OPC_CMP_F_S = FOP (48, FMT_S),
8390    OPC_CMP_UN_S = FOP (49, FMT_S),
8391    OPC_CMP_EQ_S = FOP (50, FMT_S),
8392    OPC_CMP_UEQ_S = FOP (51, FMT_S),
8393    OPC_CMP_OLT_S = FOP (52, FMT_S),
8394    OPC_CMP_ULT_S = FOP (53, FMT_S),
8395    OPC_CMP_OLE_S = FOP (54, FMT_S),
8396    OPC_CMP_ULE_S = FOP (55, FMT_S),
8397    OPC_CMP_SF_S = FOP (56, FMT_S),
8398    OPC_CMP_NGLE_S = FOP (57, FMT_S),
8399    OPC_CMP_SEQ_S = FOP (58, FMT_S),
8400    OPC_CMP_NGL_S = FOP (59, FMT_S),
8401    OPC_CMP_LT_S = FOP (60, FMT_S),
8402    OPC_CMP_NGE_S = FOP (61, FMT_S),
8403    OPC_CMP_LE_S = FOP (62, FMT_S),
8404    OPC_CMP_NGT_S = FOP (63, FMT_S),
8405
8406    OPC_ADD_D = FOP(0, FMT_D),
8407    OPC_SUB_D = FOP(1, FMT_D),
8408    OPC_MUL_D = FOP(2, FMT_D),
8409    OPC_DIV_D = FOP(3, FMT_D),
8410    OPC_SQRT_D = FOP(4, FMT_D),
8411    OPC_ABS_D = FOP(5, FMT_D),
8412    OPC_MOV_D = FOP(6, FMT_D),
8413    OPC_NEG_D = FOP(7, FMT_D),
8414    OPC_ROUND_L_D = FOP(8, FMT_D),
8415    OPC_TRUNC_L_D = FOP(9, FMT_D),
8416    OPC_CEIL_L_D = FOP(10, FMT_D),
8417    OPC_FLOOR_L_D = FOP(11, FMT_D),
8418    OPC_ROUND_W_D = FOP(12, FMT_D),
8419    OPC_TRUNC_W_D = FOP(13, FMT_D),
8420    OPC_CEIL_W_D = FOP(14, FMT_D),
8421    OPC_FLOOR_W_D = FOP(15, FMT_D),
8422    OPC_SEL_D = FOP(16, FMT_D),
8423    OPC_MOVCF_D = FOP(17, FMT_D),
8424    OPC_MOVZ_D = FOP(18, FMT_D),
8425    OPC_MOVN_D = FOP(19, FMT_D),
8426    OPC_SELEQZ_D = FOP(20, FMT_D),
8427    OPC_RECIP_D = FOP(21, FMT_D),
8428    OPC_RSQRT_D = FOP(22, FMT_D),
8429    OPC_SELNEZ_D = FOP(23, FMT_D),
8430    OPC_MADDF_D = FOP(24, FMT_D),
8431    OPC_MSUBF_D = FOP(25, FMT_D),
8432    OPC_RINT_D = FOP(26, FMT_D),
8433    OPC_CLASS_D = FOP(27, FMT_D),
8434    OPC_MIN_D = FOP(28, FMT_D),
8435    OPC_RECIP2_D = FOP(28, FMT_D),
8436    OPC_MINA_D = FOP(29, FMT_D),
8437    OPC_RECIP1_D = FOP(29, FMT_D),
8438    OPC_MAX_D = FOP(30, FMT_D),
8439    OPC_RSQRT1_D = FOP(30, FMT_D),
8440    OPC_MAXA_D = FOP(31, FMT_D),
8441    OPC_RSQRT2_D = FOP(31, FMT_D),
8442    OPC_CVT_S_D = FOP(32, FMT_D),
8443    OPC_CVT_W_D = FOP(36, FMT_D),
8444    OPC_CVT_L_D = FOP(37, FMT_D),
8445    OPC_CMP_F_D = FOP (48, FMT_D),
8446    OPC_CMP_UN_D = FOP (49, FMT_D),
8447    OPC_CMP_EQ_D = FOP (50, FMT_D),
8448    OPC_CMP_UEQ_D = FOP (51, FMT_D),
8449    OPC_CMP_OLT_D = FOP (52, FMT_D),
8450    OPC_CMP_ULT_D = FOP (53, FMT_D),
8451    OPC_CMP_OLE_D = FOP (54, FMT_D),
8452    OPC_CMP_ULE_D = FOP (55, FMT_D),
8453    OPC_CMP_SF_D = FOP (56, FMT_D),
8454    OPC_CMP_NGLE_D = FOP (57, FMT_D),
8455    OPC_CMP_SEQ_D = FOP (58, FMT_D),
8456    OPC_CMP_NGL_D = FOP (59, FMT_D),
8457    OPC_CMP_LT_D = FOP (60, FMT_D),
8458    OPC_CMP_NGE_D = FOP (61, FMT_D),
8459    OPC_CMP_LE_D = FOP (62, FMT_D),
8460    OPC_CMP_NGT_D = FOP (63, FMT_D),
8461
8462    OPC_CVT_S_W = FOP(32, FMT_W),
8463    OPC_CVT_D_W = FOP(33, FMT_W),
8464    OPC_CVT_S_L = FOP(32, FMT_L),
8465    OPC_CVT_D_L = FOP(33, FMT_L),
8466    OPC_CVT_PS_PW = FOP(38, FMT_W),
8467
8468    OPC_ADD_PS = FOP(0, FMT_PS),
8469    OPC_SUB_PS = FOP(1, FMT_PS),
8470    OPC_MUL_PS = FOP(2, FMT_PS),
8471    OPC_DIV_PS = FOP(3, FMT_PS),
8472    OPC_ABS_PS = FOP(5, FMT_PS),
8473    OPC_MOV_PS = FOP(6, FMT_PS),
8474    OPC_NEG_PS = FOP(7, FMT_PS),
8475    OPC_MOVCF_PS = FOP(17, FMT_PS),
8476    OPC_MOVZ_PS = FOP(18, FMT_PS),
8477    OPC_MOVN_PS = FOP(19, FMT_PS),
8478    OPC_ADDR_PS = FOP(24, FMT_PS),
8479    OPC_MULR_PS = FOP(26, FMT_PS),
8480    OPC_RECIP2_PS = FOP(28, FMT_PS),
8481    OPC_RECIP1_PS = FOP(29, FMT_PS),
8482    OPC_RSQRT1_PS = FOP(30, FMT_PS),
8483    OPC_RSQRT2_PS = FOP(31, FMT_PS),
8484
8485    OPC_CVT_S_PU = FOP(32, FMT_PS),
8486    OPC_CVT_PW_PS = FOP(36, FMT_PS),
8487    OPC_CVT_S_PL = FOP(40, FMT_PS),
8488    OPC_PLL_PS = FOP(44, FMT_PS),
8489    OPC_PLU_PS = FOP(45, FMT_PS),
8490    OPC_PUL_PS = FOP(46, FMT_PS),
8491    OPC_PUU_PS = FOP(47, FMT_PS),
8492    OPC_CMP_F_PS = FOP (48, FMT_PS),
8493    OPC_CMP_UN_PS = FOP (49, FMT_PS),
8494    OPC_CMP_EQ_PS = FOP (50, FMT_PS),
8495    OPC_CMP_UEQ_PS = FOP (51, FMT_PS),
8496    OPC_CMP_OLT_PS = FOP (52, FMT_PS),
8497    OPC_CMP_ULT_PS = FOP (53, FMT_PS),
8498    OPC_CMP_OLE_PS = FOP (54, FMT_PS),
8499    OPC_CMP_ULE_PS = FOP (55, FMT_PS),
8500    OPC_CMP_SF_PS = FOP (56, FMT_PS),
8501    OPC_CMP_NGLE_PS = FOP (57, FMT_PS),
8502    OPC_CMP_SEQ_PS = FOP (58, FMT_PS),
8503    OPC_CMP_NGL_PS = FOP (59, FMT_PS),
8504    OPC_CMP_LT_PS = FOP (60, FMT_PS),
8505    OPC_CMP_NGE_PS = FOP (61, FMT_PS),
8506    OPC_CMP_LE_PS = FOP (62, FMT_PS),
8507    OPC_CMP_NGT_PS = FOP (63, FMT_PS),
8508};
8509
8510enum r6_f_cmp_op {
8511    R6_OPC_CMP_AF_S   = FOP(0, FMT_W),
8512    R6_OPC_CMP_UN_S   = FOP(1, FMT_W),
8513    R6_OPC_CMP_EQ_S   = FOP(2, FMT_W),
8514    R6_OPC_CMP_UEQ_S  = FOP(3, FMT_W),
8515    R6_OPC_CMP_LT_S   = FOP(4, FMT_W),
8516    R6_OPC_CMP_ULT_S  = FOP(5, FMT_W),
8517    R6_OPC_CMP_LE_S   = FOP(6, FMT_W),
8518    R6_OPC_CMP_ULE_S  = FOP(7, FMT_W),
8519    R6_OPC_CMP_SAF_S  = FOP(8, FMT_W),
8520    R6_OPC_CMP_SUN_S  = FOP(9, FMT_W),
8521    R6_OPC_CMP_SEQ_S  = FOP(10, FMT_W),
8522    R6_OPC_CMP_SEUQ_S = FOP(11, FMT_W),
8523    R6_OPC_CMP_SLT_S  = FOP(12, FMT_W),
8524    R6_OPC_CMP_SULT_S = FOP(13, FMT_W),
8525    R6_OPC_CMP_SLE_S  = FOP(14, FMT_W),
8526    R6_OPC_CMP_SULE_S = FOP(15, FMT_W),
8527    R6_OPC_CMP_OR_S   = FOP(17, FMT_W),
8528    R6_OPC_CMP_UNE_S  = FOP(18, FMT_W),
8529    R6_OPC_CMP_NE_S   = FOP(19, FMT_W),
8530    R6_OPC_CMP_SOR_S  = FOP(25, FMT_W),
8531    R6_OPC_CMP_SUNE_S = FOP(26, FMT_W),
8532    R6_OPC_CMP_SNE_S  = FOP(27, FMT_W),
8533
8534    R6_OPC_CMP_AF_D   = FOP(0, FMT_L),
8535    R6_OPC_CMP_UN_D   = FOP(1, FMT_L),
8536    R6_OPC_CMP_EQ_D   = FOP(2, FMT_L),
8537    R6_OPC_CMP_UEQ_D  = FOP(3, FMT_L),
8538    R6_OPC_CMP_LT_D   = FOP(4, FMT_L),
8539    R6_OPC_CMP_ULT_D  = FOP(5, FMT_L),
8540    R6_OPC_CMP_LE_D   = FOP(6, FMT_L),
8541    R6_OPC_CMP_ULE_D  = FOP(7, FMT_L),
8542    R6_OPC_CMP_SAF_D  = FOP(8, FMT_L),
8543    R6_OPC_CMP_SUN_D  = FOP(9, FMT_L),
8544    R6_OPC_CMP_SEQ_D  = FOP(10, FMT_L),
8545    R6_OPC_CMP_SEUQ_D = FOP(11, FMT_L),
8546    R6_OPC_CMP_SLT_D  = FOP(12, FMT_L),
8547    R6_OPC_CMP_SULT_D = FOP(13, FMT_L),
8548    R6_OPC_CMP_SLE_D  = FOP(14, FMT_L),
8549    R6_OPC_CMP_SULE_D = FOP(15, FMT_L),
8550    R6_OPC_CMP_OR_D   = FOP(17, FMT_L),
8551    R6_OPC_CMP_UNE_D  = FOP(18, FMT_L),
8552    R6_OPC_CMP_NE_D   = FOP(19, FMT_L),
8553    R6_OPC_CMP_SOR_D  = FOP(25, FMT_L),
8554    R6_OPC_CMP_SUNE_D = FOP(26, FMT_L),
8555    R6_OPC_CMP_SNE_D  = FOP(27, FMT_L),
8556};
8557static void gen_cp1 (DisasContext *ctx, uint32_t opc, int rt, int fs)
8558{
8559    TCGv t0 = tcg_temp_new();
8560
8561    switch (opc) {
8562    case OPC_MFC1:
8563        {
8564            TCGv_i32 fp0 = tcg_temp_new_i32();
8565
8566            gen_load_fpr32(ctx, fp0, fs);
8567            tcg_gen_ext_i32_tl(t0, fp0);
8568            tcg_temp_free_i32(fp0);
8569        }
8570        gen_store_gpr(t0, rt);
8571        break;
8572    case OPC_MTC1:
8573        gen_load_gpr(t0, rt);
8574        {
8575            TCGv_i32 fp0 = tcg_temp_new_i32();
8576
8577            tcg_gen_trunc_tl_i32(fp0, t0);
8578            gen_store_fpr32(ctx, fp0, fs);
8579            tcg_temp_free_i32(fp0);
8580        }
8581        break;
8582    case OPC_CFC1:
8583        gen_helper_1e0i(cfc1, t0, fs);
8584        gen_store_gpr(t0, rt);
8585        break;
8586    case OPC_CTC1:
8587        gen_load_gpr(t0, rt);
8588        save_cpu_state(ctx, 0);
8589        {
8590            TCGv_i32 fs_tmp = tcg_const_i32(fs);
8591
8592            gen_helper_0e2i(ctc1, t0, fs_tmp, rt);
8593            tcg_temp_free_i32(fs_tmp);
8594        }
8595        /* Stop translation as we may have changed hflags */
8596        ctx->bstate = BS_STOP;
8597        break;
8598#if defined(TARGET_MIPS64)
8599    case OPC_DMFC1:
8600        gen_load_fpr64(ctx, t0, fs);
8601        gen_store_gpr(t0, rt);
8602        break;
8603    case OPC_DMTC1:
8604        gen_load_gpr(t0, rt);
8605        gen_store_fpr64(ctx, t0, fs);
8606        break;
8607#endif
8608    case OPC_MFHC1:
8609        {
8610            TCGv_i32 fp0 = tcg_temp_new_i32();
8611
8612            gen_load_fpr32h(ctx, fp0, fs);
8613            tcg_gen_ext_i32_tl(t0, fp0);
8614            tcg_temp_free_i32(fp0);
8615        }
8616        gen_store_gpr(t0, rt);
8617        break;
8618    case OPC_MTHC1:
8619        gen_load_gpr(t0, rt);
8620        {
8621            TCGv_i32 fp0 = tcg_temp_new_i32();
8622
8623            tcg_gen_trunc_tl_i32(fp0, t0);
8624            gen_store_fpr32h(ctx, fp0, fs);
8625            tcg_temp_free_i32(fp0);
8626        }
8627        break;
8628    default:
8629        MIPS_INVAL("cp1 move");
8630        generate_exception_end(ctx, EXCP_RI);
8631        goto out;
8632    }
8633
8634 out:
8635    tcg_temp_free(t0);
8636}
8637
8638static void gen_movci (DisasContext *ctx, int rd, int rs, int cc, int tf)
8639{
8640    TCGLabel *l1;
8641    TCGCond cond;
8642    TCGv_i32 t0;
8643
8644    if (rd == 0) {
8645        /* Treat as NOP. */
8646        return;
8647    }
8648
8649    if (tf)
8650        cond = TCG_COND_EQ;
8651    else
8652        cond = TCG_COND_NE;
8653
8654    l1 = gen_new_label();
8655    t0 = tcg_temp_new_i32();
8656    tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
8657    tcg_gen_brcondi_i32(cond, t0, 0, l1);
8658    tcg_temp_free_i32(t0);
8659    if (rs == 0) {
8660        tcg_gen_movi_tl(cpu_gpr[rd], 0);
8661    } else {
8662        tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
8663    }
8664    gen_set_label(l1);
8665}
8666
8667static inline void gen_movcf_s(DisasContext *ctx, int fs, int fd, int cc,
8668                               int tf)
8669{
8670    int cond;
8671    TCGv_i32 t0 = tcg_temp_new_i32();
8672    TCGLabel *l1 = gen_new_label();
8673
8674    if (tf)
8675        cond = TCG_COND_EQ;
8676    else
8677        cond = TCG_COND_NE;
8678
8679    tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
8680    tcg_gen_brcondi_i32(cond, t0, 0, l1);
8681    gen_load_fpr32(ctx, t0, fs);
8682    gen_store_fpr32(ctx, t0, fd);
8683    gen_set_label(l1);
8684    tcg_temp_free_i32(t0);
8685}
8686
8687static inline void gen_movcf_d (DisasContext *ctx, int fs, int fd, int cc, int tf)
8688{
8689    int cond;
8690    TCGv_i32 t0 = tcg_temp_new_i32();
8691    TCGv_i64 fp0;
8692    TCGLabel *l1 = gen_new_label();
8693
8694    if (tf)
8695        cond = TCG_COND_EQ;
8696    else
8697        cond = TCG_COND_NE;
8698
8699    tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
8700    tcg_gen_brcondi_i32(cond, t0, 0, l1);
8701    tcg_temp_free_i32(t0);
8702    fp0 = tcg_temp_new_i64();
8703    gen_load_fpr64(ctx, fp0, fs);
8704    gen_store_fpr64(ctx, fp0, fd);
8705    tcg_temp_free_i64(fp0);
8706    gen_set_label(l1);
8707}
8708
8709static inline void gen_movcf_ps(DisasContext *ctx, int fs, int fd,
8710                                int cc, int tf)
8711{
8712    int cond;
8713    TCGv_i32 t0 = tcg_temp_new_i32();
8714    TCGLabel *l1 = gen_new_label();
8715    TCGLabel *l2 = gen_new_label();
8716
8717    if (tf)
8718        cond = TCG_COND_EQ;
8719    else
8720        cond = TCG_COND_NE;
8721
8722    tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
8723    tcg_gen_brcondi_i32(cond, t0, 0, l1);
8724    gen_load_fpr32(ctx, t0, fs);
8725    gen_store_fpr32(ctx, t0, fd);
8726    gen_set_label(l1);
8727
8728    tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc+1));
8729    tcg_gen_brcondi_i32(cond, t0, 0, l2);
8730    gen_load_fpr32h(ctx, t0, fs);
8731    gen_store_fpr32h(ctx, t0, fd);
8732    tcg_temp_free_i32(t0);
8733    gen_set_label(l2);
8734}
8735
8736static void gen_sel_s(DisasContext *ctx, enum fopcode op1, int fd, int ft,
8737                      int fs)
8738{
8739    TCGv_i32 t1 = tcg_const_i32(0);
8740    TCGv_i32 fp0 = tcg_temp_new_i32();
8741    TCGv_i32 fp1 = tcg_temp_new_i32();
8742    TCGv_i32 fp2 = tcg_temp_new_i32();
8743    gen_load_fpr32(ctx, fp0, fd);
8744    gen_load_fpr32(ctx, fp1, ft);
8745    gen_load_fpr32(ctx, fp2, fs);
8746
8747    switch (op1) {
8748    case OPC_SEL_S:
8749        tcg_gen_andi_i32(fp0, fp0, 1);
8750        tcg_gen_movcond_i32(TCG_COND_NE, fp0, fp0, t1, fp1, fp2);
8751        break;
8752    case OPC_SELEQZ_S:
8753        tcg_gen_andi_i32(fp1, fp1, 1);
8754        tcg_gen_movcond_i32(TCG_COND_EQ, fp0, fp1, t1, fp2, t1);
8755        break;
8756    case OPC_SELNEZ_S:
8757        tcg_gen_andi_i32(fp1, fp1, 1);
8758        tcg_gen_movcond_i32(TCG_COND_NE, fp0, fp1, t1, fp2, t1);
8759        break;
8760    default:
8761        MIPS_INVAL("gen_sel_s");
8762        generate_exception_end(ctx, EXCP_RI);
8763        break;
8764    }
8765
8766    gen_store_fpr32(ctx, fp0, fd);
8767    tcg_temp_free_i32(fp2);
8768    tcg_temp_free_i32(fp1);
8769    tcg_temp_free_i32(fp0);
8770    tcg_temp_free_i32(t1);
8771}
8772
8773static void gen_sel_d(DisasContext *ctx, enum fopcode op1, int fd, int ft,
8774                      int fs)
8775{
8776    TCGv_i64 t1 = tcg_const_i64(0);
8777    TCGv_i64 fp0 = tcg_temp_new_i64();
8778    TCGv_i64 fp1 = tcg_temp_new_i64();
8779    TCGv_i64 fp2 = tcg_temp_new_i64();
8780    gen_load_fpr64(ctx, fp0, fd);
8781    gen_load_fpr64(ctx, fp1, ft);
8782    gen_load_fpr64(ctx, fp2, fs);
8783
8784    switch (op1) {
8785    case OPC_SEL_D:
8786        tcg_gen_andi_i64(fp0, fp0, 1);
8787        tcg_gen_movcond_i64(TCG_COND_NE, fp0, fp0, t1, fp1, fp2);
8788        break;
8789    case OPC_SELEQZ_D:
8790        tcg_gen_andi_i64(fp1, fp1, 1);
8791        tcg_gen_movcond_i64(TCG_COND_EQ, fp0, fp1, t1, fp2, t1);
8792        break;
8793    case OPC_SELNEZ_D:
8794        tcg_gen_andi_i64(fp1, fp1, 1);
8795        tcg_gen_movcond_i64(TCG_COND_NE, fp0, fp1, t1, fp2, t1);
8796        break;
8797    default:
8798        MIPS_INVAL("gen_sel_d");
8799        generate_exception_end(ctx, EXCP_RI);
8800        break;
8801    }
8802
8803    gen_store_fpr64(ctx, fp0, fd);
8804    tcg_temp_free_i64(fp2);
8805    tcg_temp_free_i64(fp1);
8806    tcg_temp_free_i64(fp0);
8807    tcg_temp_free_i64(t1);
8808}
8809
8810static void gen_farith (DisasContext *ctx, enum fopcode op1,
8811                        int ft, int fs, int fd, int cc)
8812{
8813    uint32_t func = ctx->opcode & 0x3f;
8814    switch (op1) {
8815    case OPC_ADD_S:
8816        {
8817            TCGv_i32 fp0 = tcg_temp_new_i32();
8818            TCGv_i32 fp1 = tcg_temp_new_i32();
8819
8820            gen_load_fpr32(ctx, fp0, fs);
8821            gen_load_fpr32(ctx, fp1, ft);
8822            gen_helper_float_add_s(fp0, cpu_env, fp0, fp1);
8823            tcg_temp_free_i32(fp1);
8824            gen_store_fpr32(ctx, fp0, fd);
8825            tcg_temp_free_i32(fp0);
8826        }
8827        break;
8828    case OPC_SUB_S:
8829        {
8830            TCGv_i32 fp0 = tcg_temp_new_i32();
8831            TCGv_i32 fp1 = tcg_temp_new_i32();
8832
8833            gen_load_fpr32(ctx, fp0, fs);
8834            gen_load_fpr32(ctx, fp1, ft);
8835            gen_helper_float_sub_s(fp0, cpu_env, fp0, fp1);
8836            tcg_temp_free_i32(fp1);
8837            gen_store_fpr32(ctx, fp0, fd);
8838            tcg_temp_free_i32(fp0);
8839        }
8840        break;
8841    case OPC_MUL_S:
8842        {
8843            TCGv_i32 fp0 = tcg_temp_new_i32();
8844            TCGv_i32 fp1 = tcg_temp_new_i32();
8845
8846            gen_load_fpr32(ctx, fp0, fs);
8847            gen_load_fpr32(ctx, fp1, ft);
8848            gen_helper_float_mul_s(fp0, cpu_env, fp0, fp1);
8849            tcg_temp_free_i32(fp1);
8850            gen_store_fpr32(ctx, fp0, fd);
8851            tcg_temp_free_i32(fp0);
8852        }
8853        break;
8854    case OPC_DIV_S:
8855        {
8856            TCGv_i32 fp0 = tcg_temp_new_i32();
8857            TCGv_i32 fp1 = tcg_temp_new_i32();
8858
8859            gen_load_fpr32(ctx, fp0, fs);
8860            gen_load_fpr32(ctx, fp1, ft);
8861            gen_helper_float_div_s(fp0, cpu_env, fp0, fp1);
8862            tcg_temp_free_i32(fp1);
8863            gen_store_fpr32(ctx, fp0, fd);
8864            tcg_temp_free_i32(fp0);
8865        }
8866        break;
8867    case OPC_SQRT_S:
8868        {
8869            TCGv_i32 fp0 = tcg_temp_new_i32();
8870
8871            gen_load_fpr32(ctx, fp0, fs);
8872            gen_helper_float_sqrt_s(fp0, cpu_env, fp0);
8873            gen_store_fpr32(ctx, fp0, fd);
8874            tcg_temp_free_i32(fp0);
8875        }
8876        break;
8877    case OPC_ABS_S:
8878        {
8879            TCGv_i32 fp0 = tcg_temp_new_i32();
8880
8881            gen_load_fpr32(ctx, fp0, fs);
8882            gen_helper_float_abs_s(fp0, fp0);
8883            gen_store_fpr32(ctx, fp0, fd);
8884            tcg_temp_free_i32(fp0);
8885        }
8886        break;
8887    case OPC_MOV_S:
8888        {
8889            TCGv_i32 fp0 = tcg_temp_new_i32();
8890
8891            gen_load_fpr32(ctx, fp0, fs);
8892            gen_store_fpr32(ctx, fp0, fd);
8893            tcg_temp_free_i32(fp0);
8894        }
8895        break;
8896    case OPC_NEG_S:
8897        {
8898            TCGv_i32 fp0 = tcg_temp_new_i32();
8899
8900            gen_load_fpr32(ctx, fp0, fs);
8901            gen_helper_float_chs_s(fp0, fp0);
8902            gen_store_fpr32(ctx, fp0, fd);
8903            tcg_temp_free_i32(fp0);
8904        }
8905        break;
8906    case OPC_ROUND_L_S:
8907        check_cp1_64bitmode(ctx);
8908        {
8909            TCGv_i32 fp32 = tcg_temp_new_i32();
8910            TCGv_i64 fp64 = tcg_temp_new_i64();
8911
8912            gen_load_fpr32(ctx, fp32, fs);
8913            gen_helper_float_roundl_s(fp64, cpu_env, fp32);
8914            tcg_temp_free_i32(fp32);
8915            gen_store_fpr64(ctx, fp64, fd);
8916            tcg_temp_free_i64(fp64);
8917        }
8918        break;
8919    case OPC_TRUNC_L_S:
8920        check_cp1_64bitmode(ctx);
8921        {
8922            TCGv_i32 fp32 = tcg_temp_new_i32();
8923            TCGv_i64 fp64 = tcg_temp_new_i64();
8924
8925            gen_load_fpr32(ctx, fp32, fs);
8926            gen_helper_float_truncl_s(fp64, cpu_env, fp32);
8927            tcg_temp_free_i32(fp32);
8928            gen_store_fpr64(ctx, fp64, fd);
8929            tcg_temp_free_i64(fp64);
8930        }
8931        break;
8932    case OPC_CEIL_L_S:
8933        check_cp1_64bitmode(ctx);
8934        {
8935            TCGv_i32 fp32 = tcg_temp_new_i32();
8936            TCGv_i64 fp64 = tcg_temp_new_i64();
8937
8938            gen_load_fpr32(ctx, fp32, fs);
8939            gen_helper_float_ceill_s(fp64, cpu_env, fp32);
8940            tcg_temp_free_i32(fp32);
8941            gen_store_fpr64(ctx, fp64, fd);
8942            tcg_temp_free_i64(fp64);
8943        }
8944        break;
8945    case OPC_FLOOR_L_S:
8946        check_cp1_64bitmode(ctx);
8947        {
8948            TCGv_i32 fp32 = tcg_temp_new_i32();
8949            TCGv_i64 fp64 = tcg_temp_new_i64();
8950
8951            gen_load_fpr32(ctx, fp32, fs);
8952            gen_helper_float_floorl_s(fp64, cpu_env, fp32);
8953            tcg_temp_free_i32(fp32);
8954            gen_store_fpr64(ctx, fp64, fd);
8955            tcg_temp_free_i64(fp64);
8956        }
8957        break;
8958    case OPC_ROUND_W_S:
8959        {
8960            TCGv_i32 fp0 = tcg_temp_new_i32();
8961
8962            gen_load_fpr32(ctx, fp0, fs);
8963            gen_helper_float_roundw_s(fp0, cpu_env, fp0);
8964            gen_store_fpr32(ctx, fp0, fd);
8965            tcg_temp_free_i32(fp0);
8966        }
8967        break;
8968    case OPC_TRUNC_W_S:
8969        {
8970            TCGv_i32 fp0 = tcg_temp_new_i32();
8971
8972            gen_load_fpr32(ctx, fp0, fs);
8973            gen_helper_float_truncw_s(fp0, cpu_env, fp0);
8974            gen_store_fpr32(ctx, fp0, fd);
8975            tcg_temp_free_i32(fp0);
8976        }
8977        break;
8978    case OPC_CEIL_W_S:
8979        {
8980            TCGv_i32 fp0 = tcg_temp_new_i32();
8981
8982            gen_load_fpr32(ctx, fp0, fs);
8983            gen_helper_float_ceilw_s(fp0, cpu_env, fp0);
8984            gen_store_fpr32(ctx, fp0, fd);
8985            tcg_temp_free_i32(fp0);
8986        }
8987        break;
8988    case OPC_FLOOR_W_S:
8989        {
8990            TCGv_i32 fp0 = tcg_temp_new_i32();
8991
8992            gen_load_fpr32(ctx, fp0, fs);
8993            gen_helper_float_floorw_s(fp0, cpu_env, fp0);
8994            gen_store_fpr32(ctx, fp0, fd);
8995            tcg_temp_free_i32(fp0);
8996        }
8997        break;
8998    case OPC_SEL_S:
8999        check_insn(ctx, ISA_MIPS32R6);
9000        gen_sel_s(ctx, op1, fd, ft, fs);
9001        break;
9002    case OPC_SELEQZ_S:
9003        check_insn(ctx, ISA_MIPS32R6);
9004        gen_sel_s(ctx, op1, fd, ft, fs);
9005        break;
9006    case OPC_SELNEZ_S:
9007        check_insn(ctx, ISA_MIPS32R6);
9008        gen_sel_s(ctx, op1, fd, ft, fs);
9009        break;
9010    case OPC_MOVCF_S:
9011        check_insn_opc_removed(ctx, ISA_MIPS32R6);
9012        gen_movcf_s(ctx, fs, fd, (ft >> 2) & 0x7, ft & 0x1);
9013        break;
9014    case OPC_MOVZ_S:
9015        check_insn_opc_removed(ctx, ISA_MIPS32R6);
9016        {
9017            TCGLabel *l1 = gen_new_label();
9018            TCGv_i32 fp0;
9019
9020            if (ft != 0) {
9021                tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[ft], 0, l1);
9022            }
9023            fp0 = tcg_temp_new_i32();
9024            gen_load_fpr32(ctx, fp0, fs);
9025            gen_store_fpr32(ctx, fp0, fd);
9026            tcg_temp_free_i32(fp0);
9027            gen_set_label(l1);
9028        }
9029        break;
9030    case OPC_MOVN_S:
9031        check_insn_opc_removed(ctx, ISA_MIPS32R6);
9032        {
9033            TCGLabel *l1 = gen_new_label();
9034            TCGv_i32 fp0;
9035
9036            if (ft != 0) {
9037                tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[ft], 0, l1);
9038                fp0 = tcg_temp_new_i32();
9039                gen_load_fpr32(ctx, fp0, fs);
9040                gen_store_fpr32(ctx, fp0, fd);
9041                tcg_temp_free_i32(fp0);
9042                gen_set_label(l1);
9043            }
9044        }
9045        break;
9046    case OPC_RECIP_S:
9047        {
9048            TCGv_i32 fp0 = tcg_temp_new_i32();
9049
9050            gen_load_fpr32(ctx, fp0, fs);
9051            gen_helper_float_recip_s(fp0, cpu_env, fp0);
9052            gen_store_fpr32(ctx, fp0, fd);
9053            tcg_temp_free_i32(fp0);
9054        }
9055        break;
9056    case OPC_RSQRT_S:
9057        {
9058            TCGv_i32 fp0 = tcg_temp_new_i32();
9059
9060            gen_load_fpr32(ctx, fp0, fs);
9061            gen_helper_float_rsqrt_s(fp0, cpu_env, fp0);
9062            gen_store_fpr32(ctx, fp0, fd);
9063            tcg_temp_free_i32(fp0);
9064        }
9065        break;
9066    case OPC_MADDF_S:
9067        check_insn(ctx, ISA_MIPS32R6);
9068        {
9069            TCGv_i32 fp0 = tcg_temp_new_i32();
9070            TCGv_i32 fp1 = tcg_temp_new_i32();
9071            TCGv_i32 fp2 = tcg_temp_new_i32();
9072            gen_load_fpr32(ctx, fp0, fs);
9073            gen_load_fpr32(ctx, fp1, ft);
9074            gen_load_fpr32(ctx, fp2, fd);
9075            gen_helper_float_maddf_s(fp2, cpu_env, fp0, fp1, fp2);
9076            gen_store_fpr32(ctx, fp2, fd);
9077            tcg_temp_free_i32(fp2);
9078            tcg_temp_free_i32(fp1);
9079            tcg_temp_free_i32(fp0);
9080        }
9081        break;
9082    case OPC_MSUBF_S:
9083        check_insn(ctx, ISA_MIPS32R6);
9084        {
9085            TCGv_i32 fp0 = tcg_temp_new_i32();
9086            TCGv_i32 fp1 = tcg_temp_new_i32();
9087            TCGv_i32 fp2 = tcg_temp_new_i32();
9088            gen_load_fpr32(ctx, fp0, fs);
9089            gen_load_fpr32(ctx, fp1, ft);
9090            gen_load_fpr32(ctx, fp2, fd);
9091            gen_helper_float_msubf_s(fp2, cpu_env, fp0, fp1, fp2);
9092            gen_store_fpr32(ctx, fp2, fd);
9093            tcg_temp_free_i32(fp2);
9094            tcg_temp_free_i32(fp1);
9095            tcg_temp_free_i32(fp0);
9096        }
9097        break;
9098    case OPC_RINT_S:
9099        check_insn(ctx, ISA_MIPS32R6);
9100        {
9101            TCGv_i32 fp0 = tcg_temp_new_i32();
9102            gen_load_fpr32(ctx, fp0, fs);
9103            gen_helper_float_rint_s(fp0, cpu_env, fp0);
9104            gen_store_fpr32(ctx, fp0, fd);
9105            tcg_temp_free_i32(fp0);
9106        }
9107        break;
9108    case OPC_CLASS_S:
9109        check_insn(ctx, ISA_MIPS32R6);
9110        {
9111            TCGv_i32 fp0 = tcg_temp_new_i32();
9112            gen_load_fpr32(ctx, fp0, fs);
9113            gen_helper_float_class_s(fp0, fp0);
9114            gen_store_fpr32(ctx, fp0, fd);
9115            tcg_temp_free_i32(fp0);
9116        }
9117        break;
9118    case OPC_MIN_S: /* OPC_RECIP2_S */
9119        if (ctx->insn_flags & ISA_MIPS32R6) {
9120            /* OPC_MIN_S */
9121            TCGv_i32 fp0 = tcg_temp_new_i32();
9122            TCGv_i32 fp1 = tcg_temp_new_i32();
9123            TCGv_i32 fp2 = tcg_temp_new_i32();
9124            gen_load_fpr32(ctx, fp0, fs);
9125            gen_load_fpr32(ctx, fp1, ft);
9126            gen_helper_float_min_s(fp2, cpu_env, fp0, fp1);
9127            gen_store_fpr32(ctx, fp2, fd);
9128            tcg_temp_free_i32(fp2);
9129            tcg_temp_free_i32(fp1);
9130            tcg_temp_free_i32(fp0);
9131        } else {
9132            /* OPC_RECIP2_S */
9133            check_cp1_64bitmode(ctx);
9134            {
9135                TCGv_i32 fp0 = tcg_temp_new_i32();
9136                TCGv_i32 fp1 = tcg_temp_new_i32();
9137
9138                gen_load_fpr32(ctx, fp0, fs);
9139                gen_load_fpr32(ctx, fp1, ft);
9140                gen_helper_float_recip2_s(fp0, cpu_env, fp0, fp1);
9141                tcg_temp_free_i32(fp1);
9142                gen_store_fpr32(ctx, fp0, fd);
9143                tcg_temp_free_i32(fp0);
9144            }
9145        }
9146        break;
9147    case OPC_MINA_S: /* OPC_RECIP1_S */
9148        if (ctx->insn_flags & ISA_MIPS32R6) {
9149            /* OPC_MINA_S */
9150            TCGv_i32 fp0 = tcg_temp_new_i32();
9151            TCGv_i32 fp1 = tcg_temp_new_i32();
9152            TCGv_i32 fp2 = tcg_temp_new_i32();
9153            gen_load_fpr32(ctx, fp0, fs);
9154            gen_load_fpr32(ctx, fp1, ft);
9155            gen_helper_float_mina_s(fp2, cpu_env, fp0, fp1);
9156            gen_store_fpr32(ctx, fp2, fd);
9157            tcg_temp_free_i32(fp2);
9158            tcg_temp_free_i32(fp1);
9159            tcg_temp_free_i32(fp0);
9160        } else {
9161            /* OPC_RECIP1_S */
9162            check_cp1_64bitmode(ctx);
9163            {
9164                TCGv_i32 fp0 = tcg_temp_new_i32();
9165
9166                gen_load_fpr32(ctx, fp0, fs);
9167                gen_helper_float_recip1_s(fp0, cpu_env, fp0);
9168                gen_store_fpr32(ctx, fp0, fd);
9169                tcg_temp_free_i32(fp0);
9170            }
9171        }
9172        break;
9173    case OPC_MAX_S: /* OPC_RSQRT1_S */
9174        if (ctx->insn_flags & ISA_MIPS32R6) {
9175            /* OPC_MAX_S */
9176            TCGv_i32 fp0 = tcg_temp_new_i32();
9177            TCGv_i32 fp1 = tcg_temp_new_i32();
9178            gen_load_fpr32(ctx, fp0, fs);
9179            gen_load_fpr32(ctx, fp1, ft);
9180            gen_helper_float_max_s(fp1, cpu_env, fp0, fp1);
9181            gen_store_fpr32(ctx, fp1, fd);
9182            tcg_temp_free_i32(fp1);
9183            tcg_temp_free_i32(fp0);
9184        } else {
9185            /* OPC_RSQRT1_S */
9186            check_cp1_64bitmode(ctx);
9187            {
9188                TCGv_i32 fp0 = tcg_temp_new_i32();
9189
9190                gen_load_fpr32(ctx, fp0, fs);
9191                gen_helper_float_rsqrt1_s(fp0, cpu_env, fp0);
9192                gen_store_fpr32(ctx, fp0, fd);
9193                tcg_temp_free_i32(fp0);
9194            }
9195        }
9196        break;
9197    case OPC_MAXA_S: /* OPC_RSQRT2_S */
9198        if (ctx->insn_flags & ISA_MIPS32R6) {
9199            /* OPC_MAXA_S */
9200            TCGv_i32 fp0 = tcg_temp_new_i32();
9201            TCGv_i32 fp1 = tcg_temp_new_i32();
9202            gen_load_fpr32(ctx, fp0, fs);
9203            gen_load_fpr32(ctx, fp1, ft);
9204            gen_helper_float_maxa_s(fp1, cpu_env, fp0, fp1);
9205            gen_store_fpr32(ctx, fp1, fd);
9206            tcg_temp_free_i32(fp1);
9207            tcg_temp_free_i32(fp0);
9208        } else {
9209            /* OPC_RSQRT2_S */
9210            check_cp1_64bitmode(ctx);
9211            {
9212                TCGv_i32 fp0 = tcg_temp_new_i32();
9213                TCGv_i32 fp1 = tcg_temp_new_i32();
9214
9215                gen_load_fpr32(ctx, fp0, fs);
9216                gen_load_fpr32(ctx, fp1, ft);
9217                gen_helper_float_rsqrt2_s(fp0, cpu_env, fp0, fp1);
9218                tcg_temp_free_i32(fp1);
9219                gen_store_fpr32(ctx, fp0, fd);
9220                tcg_temp_free_i32(fp0);
9221            }
9222        }
9223        break;
9224    case OPC_CVT_D_S:
9225        check_cp1_registers(ctx, fd);
9226        {
9227            TCGv_i32 fp32 = tcg_temp_new_i32();
9228            TCGv_i64 fp64 = tcg_temp_new_i64();
9229
9230            gen_load_fpr32(ctx, fp32, fs);
9231            gen_helper_float_cvtd_s(fp64, cpu_env, fp32);
9232            tcg_temp_free_i32(fp32);
9233            gen_store_fpr64(ctx, fp64, fd);
9234            tcg_temp_free_i64(fp64);
9235        }
9236        break;
9237    case OPC_CVT_W_S:
9238        {
9239            TCGv_i32 fp0 = tcg_temp_new_i32();
9240
9241            gen_load_fpr32(ctx, fp0, fs);
9242            gen_helper_float_cvtw_s(fp0, cpu_env, fp0);
9243            gen_store_fpr32(ctx, fp0, fd);
9244            tcg_temp_free_i32(fp0);
9245        }
9246        break;
9247    case OPC_CVT_L_S:
9248        check_cp1_64bitmode(ctx);
9249        {
9250            TCGv_i32 fp32 = tcg_temp_new_i32();
9251            TCGv_i64 fp64 = tcg_temp_new_i64();
9252
9253            gen_load_fpr32(ctx, fp32, fs);
9254            gen_helper_float_cvtl_s(fp64, cpu_env, fp32);
9255            tcg_temp_free_i32(fp32);
9256            gen_store_fpr64(ctx, fp64, fd);
9257            tcg_temp_free_i64(fp64);
9258        }
9259        break;
9260    case OPC_CVT_PS_S:
9261        check_ps(ctx);
9262        {
9263            TCGv_i64 fp64 = tcg_temp_new_i64();
9264            TCGv_i32 fp32_0 = tcg_temp_new_i32();
9265            TCGv_i32 fp32_1 = tcg_temp_new_i32();
9266
9267            gen_load_fpr32(ctx, fp32_0, fs);
9268            gen_load_fpr32(ctx, fp32_1, ft);
9269            tcg_gen_concat_i32_i64(fp64, fp32_1, fp32_0);
9270            tcg_temp_free_i32(fp32_1);
9271            tcg_temp_free_i32(fp32_0);
9272            gen_store_fpr64(ctx, fp64, fd);
9273            tcg_temp_free_i64(fp64);
9274        }
9275        break;
9276    case OPC_CMP_F_S:
9277    case OPC_CMP_UN_S:
9278    case OPC_CMP_EQ_S:
9279    case OPC_CMP_UEQ_S:
9280    case OPC_CMP_OLT_S:
9281    case OPC_CMP_ULT_S:
9282    case OPC_CMP_OLE_S:
9283    case OPC_CMP_ULE_S:
9284    case OPC_CMP_SF_S:
9285    case OPC_CMP_NGLE_S:
9286    case OPC_CMP_SEQ_S:
9287    case OPC_CMP_NGL_S:
9288    case OPC_CMP_LT_S:
9289    case OPC_CMP_NGE_S:
9290    case OPC_CMP_LE_S:
9291    case OPC_CMP_NGT_S:
9292        check_insn_opc_removed(ctx, ISA_MIPS32R6);
9293        if (ctx->opcode & (1 << 6)) {
9294            gen_cmpabs_s(ctx, func-48, ft, fs, cc);
9295        } else {
9296            gen_cmp_s(ctx, func-48, ft, fs, cc);
9297        }
9298        break;
9299    case OPC_ADD_D:
9300        check_cp1_registers(ctx, fs | ft | fd);
9301        {
9302            TCGv_i64 fp0 = tcg_temp_new_i64();
9303            TCGv_i64 fp1 = tcg_temp_new_i64();
9304
9305            gen_load_fpr64(ctx, fp0, fs);
9306            gen_load_fpr64(ctx, fp1, ft);
9307            gen_helper_float_add_d(fp0, cpu_env, fp0, fp1);
9308            tcg_temp_free_i64(fp1);
9309            gen_store_fpr64(ctx, fp0, fd);
9310            tcg_temp_free_i64(fp0);
9311        }
9312        break;
9313    case OPC_SUB_D:
9314        check_cp1_registers(ctx, fs | ft | fd);
9315        {
9316            TCGv_i64 fp0 = tcg_temp_new_i64();
9317            TCGv_i64 fp1 = tcg_temp_new_i64();
9318
9319            gen_load_fpr64(ctx, fp0, fs);
9320            gen_load_fpr64(ctx, fp1, ft);
9321            gen_helper_float_sub_d(fp0, cpu_env, fp0, fp1);
9322            tcg_temp_free_i64(fp1);
9323            gen_store_fpr64(ctx, fp0, fd);
9324            tcg_temp_free_i64(fp0);
9325        }
9326        break;
9327    case OPC_MUL_D:
9328        check_cp1_registers(ctx, fs | ft | fd);
9329        {
9330            TCGv_i64 fp0 = tcg_temp_new_i64();
9331            TCGv_i64 fp1 = tcg_temp_new_i64();
9332
9333            gen_load_fpr64(ctx, fp0, fs);
9334            gen_load_fpr64(ctx, fp1, ft);
9335            gen_helper_float_mul_d(fp0, cpu_env, fp0, fp1);
9336            tcg_temp_free_i64(fp1);
9337            gen_store_fpr64(ctx, fp0, fd);
9338            tcg_temp_free_i64(fp0);
9339        }
9340        break;
9341    case OPC_DIV_D:
9342        check_cp1_registers(ctx, fs | ft | fd);
9343        {
9344            TCGv_i64 fp0 = tcg_temp_new_i64();
9345            TCGv_i64 fp1 = tcg_temp_new_i64();
9346
9347            gen_load_fpr64(ctx, fp0, fs);
9348            gen_load_fpr64(ctx, fp1, ft);
9349            gen_helper_float_div_d(fp0, cpu_env, fp0, fp1);
9350            tcg_temp_free_i64(fp1);
9351            gen_store_fpr64(ctx, fp0, fd);
9352            tcg_temp_free_i64(fp0);
9353        }
9354        break;
9355    case OPC_SQRT_D:
9356        check_cp1_registers(ctx, fs | fd);
9357        {
9358            TCGv_i64 fp0 = tcg_temp_new_i64();
9359
9360            gen_load_fpr64(ctx, fp0, fs);
9361            gen_helper_float_sqrt_d(fp0, cpu_env, fp0);
9362            gen_store_fpr64(ctx, fp0, fd);
9363            tcg_temp_free_i64(fp0);
9364        }
9365        break;
9366    case OPC_ABS_D:
9367        check_cp1_registers(ctx, fs | fd);
9368        {
9369            TCGv_i64 fp0 = tcg_temp_new_i64();
9370
9371            gen_load_fpr64(ctx, fp0, fs);
9372            gen_helper_float_abs_d(fp0, fp0);
9373            gen_store_fpr64(ctx, fp0, fd);
9374            tcg_temp_free_i64(fp0);
9375        }
9376        break;
9377    case OPC_MOV_D:
9378        check_cp1_registers(ctx, fs | fd);
9379        {
9380            TCGv_i64 fp0 = tcg_temp_new_i64();
9381
9382            gen_load_fpr64(ctx, fp0, fs);
9383            gen_store_fpr64(ctx, fp0, fd);
9384            tcg_temp_free_i64(fp0);
9385        }
9386        break;
9387    case OPC_NEG_D:
9388        check_cp1_registers(ctx, fs | fd);
9389        {
9390            TCGv_i64 fp0 = tcg_temp_new_i64();
9391
9392            gen_load_fpr64(ctx, fp0, fs);
9393            gen_helper_float_chs_d(fp0, fp0);
9394            gen_store_fpr64(ctx, fp0, fd);
9395            tcg_temp_free_i64(fp0);
9396        }
9397        break;
9398    case OPC_ROUND_L_D:
9399        check_cp1_64bitmode(ctx);
9400        {
9401            TCGv_i64 fp0 = tcg_temp_new_i64();
9402
9403            gen_load_fpr64(ctx, fp0, fs);
9404            gen_helper_float_roundl_d(fp0, cpu_env, fp0);
9405            gen_store_fpr64(ctx, fp0, fd);
9406            tcg_temp_free_i64(fp0);
9407        }
9408        break;
9409    case OPC_TRUNC_L_D:
9410        check_cp1_64bitmode(ctx);
9411        {
9412            TCGv_i64 fp0 = tcg_temp_new_i64();
9413
9414            gen_load_fpr64(ctx, fp0, fs);
9415            gen_helper_float_truncl_d(fp0, cpu_env, fp0);
9416            gen_store_fpr64(ctx, fp0, fd);
9417            tcg_temp_free_i64(fp0);
9418        }
9419        break;
9420    case OPC_CEIL_L_D:
9421        check_cp1_64bitmode(ctx);
9422        {
9423            TCGv_i64 fp0 = tcg_temp_new_i64();
9424
9425            gen_load_fpr64(ctx, fp0, fs);
9426            gen_helper_float_ceill_d(fp0, cpu_env, fp0);
9427            gen_store_fpr64(ctx, fp0, fd);
9428            tcg_temp_free_i64(fp0);
9429        }
9430        break;
9431    case OPC_FLOOR_L_D:
9432        check_cp1_64bitmode(ctx);
9433        {
9434            TCGv_i64 fp0 = tcg_temp_new_i64();
9435
9436            gen_load_fpr64(ctx, fp0, fs);
9437            gen_helper_float_floorl_d(fp0, cpu_env, fp0);
9438            gen_store_fpr64(ctx, fp0, fd);
9439            tcg_temp_free_i64(fp0);
9440        }
9441        break;
9442    case OPC_ROUND_W_D:
9443        check_cp1_registers(ctx, fs);
9444        {
9445            TCGv_i32 fp32 = tcg_temp_new_i32();
9446            TCGv_i64 fp64 = tcg_temp_new_i64();
9447
9448            gen_load_fpr64(ctx, fp64, fs);
9449            gen_helper_float_roundw_d(fp32, cpu_env, fp64);
9450            tcg_temp_free_i64(fp64);
9451            gen_store_fpr32(ctx, fp32, fd);
9452            tcg_temp_free_i32(fp32);
9453        }
9454        break;
9455    case OPC_TRUNC_W_D:
9456        check_cp1_registers(ctx, fs);
9457        {
9458            TCGv_i32 fp32 = tcg_temp_new_i32();
9459            TCGv_i64 fp64 = tcg_temp_new_i64();
9460
9461            gen_load_fpr64(ctx, fp64, fs);
9462            gen_helper_float_truncw_d(fp32, cpu_env, fp64);
9463            tcg_temp_free_i64(fp64);
9464            gen_store_fpr32(ctx, fp32, fd);
9465            tcg_temp_free_i32(fp32);
9466        }
9467        break;
9468    case OPC_CEIL_W_D:
9469        check_cp1_registers(ctx, fs);
9470        {
9471            TCGv_i32 fp32 = tcg_temp_new_i32();
9472            TCGv_i64 fp64 = tcg_temp_new_i64();
9473
9474            gen_load_fpr64(ctx, fp64, fs);
9475            gen_helper_float_ceilw_d(fp32, cpu_env, fp64);
9476            tcg_temp_free_i64(fp64);
9477            gen_store_fpr32(ctx, fp32, fd);
9478            tcg_temp_free_i32(fp32);
9479        }
9480        break;
9481    case OPC_FLOOR_W_D:
9482        check_cp1_registers(ctx, fs);
9483        {
9484            TCGv_i32 fp32 = tcg_temp_new_i32();
9485            TCGv_i64 fp64 = tcg_temp_new_i64();
9486
9487            gen_load_fpr64(ctx, fp64, fs);
9488            gen_helper_float_floorw_d(fp32, cpu_env, fp64);
9489            tcg_temp_free_i64(fp64);
9490            gen_store_fpr32(ctx, fp32, fd);
9491            tcg_temp_free_i32(fp32);
9492        }
9493        break;
9494    case OPC_SEL_D:
9495        check_insn(ctx, ISA_MIPS32R6);
9496        gen_sel_d(ctx, op1, fd, ft, fs);
9497        break;
9498    case OPC_SELEQZ_D:
9499        check_insn(ctx, ISA_MIPS32R6);
9500        gen_sel_d(ctx, op1, fd, ft, fs);
9501        break;
9502    case OPC_SELNEZ_D:
9503        check_insn(ctx, ISA_MIPS32R6);
9504        gen_sel_d(ctx, op1, fd, ft, fs);
9505        break;
9506    case OPC_MOVCF_D:
9507        check_insn_opc_removed(ctx, ISA_MIPS32R6);
9508        gen_movcf_d(ctx, fs, fd, (ft >> 2) & 0x7, ft & 0x1);
9509        break;
9510    case OPC_MOVZ_D:
9511        check_insn_opc_removed(ctx, ISA_MIPS32R6);
9512        {
9513            TCGLabel *l1 = gen_new_label();
9514            TCGv_i64 fp0;
9515
9516            if (ft != 0) {
9517                tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[ft], 0, l1);
9518            }
9519            fp0 = tcg_temp_new_i64();
9520            gen_load_fpr64(ctx, fp0, fs);
9521            gen_store_fpr64(ctx, fp0, fd);
9522            tcg_temp_free_i64(fp0);
9523            gen_set_label(l1);
9524        }
9525        break;
9526    case OPC_MOVN_D:
9527        check_insn_opc_removed(ctx, ISA_MIPS32R6);
9528        {
9529            TCGLabel *l1 = gen_new_label();
9530            TCGv_i64 fp0;
9531
9532            if (ft != 0) {
9533                tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[ft], 0, l1);
9534                fp0 = tcg_temp_new_i64();
9535                gen_load_fpr64(ctx, fp0, fs);
9536                gen_store_fpr64(ctx, fp0, fd);
9537                tcg_temp_free_i64(fp0);
9538                gen_set_label(l1);
9539            }
9540        }
9541        break;
9542    case OPC_RECIP_D:
9543        check_cp1_registers(ctx, fs | fd);
9544        {
9545            TCGv_i64 fp0 = tcg_temp_new_i64();
9546
9547            gen_load_fpr64(ctx, fp0, fs);
9548            gen_helper_float_recip_d(fp0, cpu_env, fp0);
9549            gen_store_fpr64(ctx, fp0, fd);
9550            tcg_temp_free_i64(fp0);
9551        }
9552        break;
9553    case OPC_RSQRT_D:
9554        check_cp1_registers(ctx, fs | fd);
9555        {
9556            TCGv_i64 fp0 = tcg_temp_new_i64();
9557
9558            gen_load_fpr64(ctx, fp0, fs);
9559            gen_helper_float_rsqrt_d(fp0, cpu_env, fp0);
9560            gen_store_fpr64(ctx, fp0, fd);
9561            tcg_temp_free_i64(fp0);
9562        }
9563        break;
9564    case OPC_MADDF_D:
9565        check_insn(ctx, ISA_MIPS32R6);
9566        {
9567            TCGv_i64 fp0 = tcg_temp_new_i64();
9568            TCGv_i64 fp1 = tcg_temp_new_i64();
9569            TCGv_i64 fp2 = tcg_temp_new_i64();
9570            gen_load_fpr64(ctx, fp0, fs);
9571            gen_load_fpr64(ctx, fp1, ft);
9572            gen_load_fpr64(ctx, fp2, fd);
9573            gen_helper_float_maddf_d(fp2, cpu_env, fp0, fp1, fp2);
9574            gen_store_fpr64(ctx, fp2, fd);
9575            tcg_temp_free_i64(fp2);
9576            tcg_temp_free_i64(fp1);
9577            tcg_temp_free_i64(fp0);
9578        }
9579        break;
9580    case OPC_MSUBF_D:
9581        check_insn(ctx, ISA_MIPS32R6);
9582        {
9583            TCGv_i64 fp0 = tcg_temp_new_i64();
9584            TCGv_i64 fp1 = tcg_temp_new_i64();
9585            TCGv_i64 fp2 = tcg_temp_new_i64();
9586            gen_load_fpr64(ctx, fp0, fs);
9587            gen_load_fpr64(ctx, fp1, ft);
9588            gen_load_fpr64(ctx, fp2, fd);
9589            gen_helper_float_msubf_d(fp2, cpu_env, fp0, fp1, fp2);
9590            gen_store_fpr64(ctx, fp2, fd);
9591            tcg_temp_free_i64(fp2);
9592            tcg_temp_free_i64(fp1);
9593            tcg_temp_free_i64(fp0);
9594        }
9595        break;
9596    case OPC_RINT_D:
9597        check_insn(ctx, ISA_MIPS32R6);
9598        {
9599            TCGv_i64 fp0 = tcg_temp_new_i64();
9600            gen_load_fpr64(ctx, fp0, fs);
9601            gen_helper_float_rint_d(fp0, cpu_env, fp0);
9602            gen_store_fpr64(ctx, fp0, fd);
9603            tcg_temp_free_i64(fp0);
9604        }
9605        break;
9606    case OPC_CLASS_D:
9607        check_insn(ctx, ISA_MIPS32R6);
9608        {
9609            TCGv_i64 fp0 = tcg_temp_new_i64();
9610            gen_load_fpr64(ctx, fp0, fs);
9611            gen_helper_float_class_d(fp0, fp0);
9612            gen_store_fpr64(ctx, fp0, fd);
9613            tcg_temp_free_i64(fp0);
9614        }
9615        break;
9616    case OPC_MIN_D: /* OPC_RECIP2_D */
9617        if (ctx->insn_flags & ISA_MIPS32R6) {
9618            /* OPC_MIN_D */
9619            TCGv_i64 fp0 = tcg_temp_new_i64();
9620            TCGv_i64 fp1 = tcg_temp_new_i64();
9621            gen_load_fpr64(ctx, fp0, fs);
9622            gen_load_fpr64(ctx, fp1, ft);
9623            gen_helper_float_min_d(fp1, cpu_env, fp0, fp1);
9624            gen_store_fpr64(ctx, fp1, fd);
9625            tcg_temp_free_i64(fp1);
9626            tcg_temp_free_i64(fp0);
9627        } else {
9628            /* OPC_RECIP2_D */
9629            check_cp1_64bitmode(ctx);
9630            {
9631                TCGv_i64 fp0 = tcg_temp_new_i64();
9632                TCGv_i64 fp1 = tcg_temp_new_i64();
9633
9634                gen_load_fpr64(ctx, fp0, fs);
9635                gen_load_fpr64(ctx, fp1, ft);
9636                gen_helper_float_recip2_d(fp0, cpu_env, fp0, fp1);
9637                tcg_temp_free_i64(fp1);
9638                gen_store_fpr64(ctx, fp0, fd);
9639                tcg_temp_free_i64(fp0);
9640            }
9641        }
9642        break;
9643    case OPC_MINA_D: /* OPC_RECIP1_D */
9644        if (ctx->insn_flags & ISA_MIPS32R6) {
9645            /* OPC_MINA_D */
9646            TCGv_i64 fp0 = tcg_temp_new_i64();
9647            TCGv_i64 fp1 = tcg_temp_new_i64();
9648            gen_load_fpr64(ctx, fp0, fs);
9649            gen_load_fpr64(ctx, fp1, ft);
9650            gen_helper_float_mina_d(fp1, cpu_env, fp0, fp1);
9651            gen_store_fpr64(ctx, fp1, fd);
9652            tcg_temp_free_i64(fp1);
9653            tcg_temp_free_i64(fp0);
9654        } else {
9655            /* OPC_RECIP1_D */
9656            check_cp1_64bitmode(ctx);
9657            {
9658                TCGv_i64 fp0 = tcg_temp_new_i64();
9659
9660                gen_load_fpr64(ctx, fp0, fs);
9661                gen_helper_float_recip1_d(fp0, cpu_env, fp0);
9662                gen_store_fpr64(ctx, fp0, fd);
9663                tcg_temp_free_i64(fp0);
9664            }
9665        }
9666        break;
9667    case OPC_MAX_D: /*  OPC_RSQRT1_D */
9668        if (ctx->insn_flags & ISA_MIPS32R6) {
9669            /* OPC_MAX_D */
9670            TCGv_i64 fp0 = tcg_temp_new_i64();
9671            TCGv_i64 fp1 = tcg_temp_new_i64();
9672            gen_load_fpr64(ctx, fp0, fs);
9673            gen_load_fpr64(ctx, fp1, ft);
9674            gen_helper_float_max_d(fp1, cpu_env, fp0, fp1);
9675            gen_store_fpr64(ctx, fp1, fd);
9676            tcg_temp_free_i64(fp1);
9677            tcg_temp_free_i64(fp0);
9678        } else {
9679            /* OPC_RSQRT1_D */
9680            check_cp1_64bitmode(ctx);
9681            {
9682                TCGv_i64 fp0 = tcg_temp_new_i64();
9683
9684                gen_load_fpr64(ctx, fp0, fs);
9685                gen_helper_float_rsqrt1_d(fp0, cpu_env, fp0);
9686                gen_store_fpr64(ctx, fp0, fd);
9687                tcg_temp_free_i64(fp0);
9688            }
9689        }
9690        break;
9691    case OPC_MAXA_D: /* OPC_RSQRT2_D */
9692        if (ctx->insn_flags & ISA_MIPS32R6) {
9693            /* OPC_MAXA_D */
9694            TCGv_i64 fp0 = tcg_temp_new_i64();
9695            TCGv_i64 fp1 = tcg_temp_new_i64();
9696            gen_load_fpr64(ctx, fp0, fs);
9697            gen_load_fpr64(ctx, fp1, ft);
9698            gen_helper_float_maxa_d(fp1, cpu_env, fp0, fp1);
9699            gen_store_fpr64(ctx, fp1, fd);
9700            tcg_temp_free_i64(fp1);
9701            tcg_temp_free_i64(fp0);
9702        } else {
9703            /* OPC_RSQRT2_D */
9704            check_cp1_64bitmode(ctx);
9705            {
9706                TCGv_i64 fp0 = tcg_temp_new_i64();
9707                TCGv_i64 fp1 = tcg_temp_new_i64();
9708
9709                gen_load_fpr64(ctx, fp0, fs);
9710                gen_load_fpr64(ctx, fp1, ft);
9711                gen_helper_float_rsqrt2_d(fp0, cpu_env, fp0, fp1);
9712                tcg_temp_free_i64(fp1);
9713                gen_store_fpr64(ctx, fp0, fd);
9714                tcg_temp_free_i64(fp0);
9715            }
9716        }
9717        break;
9718    case OPC_CMP_F_D:
9719    case OPC_CMP_UN_D:
9720    case OPC_CMP_EQ_D:
9721    case OPC_CMP_UEQ_D:
9722    case OPC_CMP_OLT_D:
9723    case OPC_CMP_ULT_D:
9724    case OPC_CMP_OLE_D:
9725    case OPC_CMP_ULE_D:
9726    case OPC_CMP_SF_D:
9727    case OPC_CMP_NGLE_D:
9728    case OPC_CMP_SEQ_D:
9729    case OPC_CMP_NGL_D:
9730    case OPC_CMP_LT_D:
9731    case OPC_CMP_NGE_D:
9732    case OPC_CMP_LE_D:
9733    case OPC_CMP_NGT_D:
9734        check_insn_opc_removed(ctx, ISA_MIPS32R6);
9735        if (ctx->opcode & (1 << 6)) {
9736            gen_cmpabs_d(ctx, func-48, ft, fs, cc);
9737        } else {
9738            gen_cmp_d(ctx, func-48, ft, fs, cc);
9739        }
9740        break;
9741    case OPC_CVT_S_D:
9742        check_cp1_registers(ctx, fs);
9743        {
9744            TCGv_i32 fp32 = tcg_temp_new_i32();
9745            TCGv_i64 fp64 = tcg_temp_new_i64();
9746
9747            gen_load_fpr64(ctx, fp64, fs);
9748            gen_helper_float_cvts_d(fp32, cpu_env, fp64);
9749            tcg_temp_free_i64(fp64);
9750            gen_store_fpr32(ctx, fp32, fd);
9751            tcg_temp_free_i32(fp32);
9752        }
9753        break;
9754    case OPC_CVT_W_D:
9755        check_cp1_registers(ctx, fs);
9756        {
9757            TCGv_i32 fp32 = tcg_temp_new_i32();
9758            TCGv_i64 fp64 = tcg_temp_new_i64();
9759
9760            gen_load_fpr64(ctx, fp64, fs);
9761            gen_helper_float_cvtw_d(fp32, cpu_env, fp64);
9762            tcg_temp_free_i64(fp64);
9763            gen_store_fpr32(ctx, fp32, fd);
9764            tcg_temp_free_i32(fp32);
9765        }
9766        break;
9767    case OPC_CVT_L_D:
9768        check_cp1_64bitmode(ctx);
9769        {
9770            TCGv_i64 fp0 = tcg_temp_new_i64();
9771
9772            gen_load_fpr64(ctx, fp0, fs);
9773            gen_helper_float_cvtl_d(fp0, cpu_env, fp0);
9774            gen_store_fpr64(ctx, fp0, fd);
9775            tcg_temp_free_i64(fp0);
9776        }
9777        break;
9778    case OPC_CVT_S_W:
9779        {
9780            TCGv_i32 fp0 = tcg_temp_new_i32();
9781
9782            gen_load_fpr32(ctx, fp0, fs);
9783            gen_helper_float_cvts_w(fp0, cpu_env, fp0);
9784            gen_store_fpr32(ctx, fp0, fd);
9785            tcg_temp_free_i32(fp0);
9786        }
9787        break;
9788    case OPC_CVT_D_W:
9789        check_cp1_registers(ctx, fd);
9790        {
9791            TCGv_i32 fp32 = tcg_temp_new_i32();
9792            TCGv_i64 fp64 = tcg_temp_new_i64();
9793
9794            gen_load_fpr32(ctx, fp32, fs);
9795            gen_helper_float_cvtd_w(fp64, cpu_env, fp32);
9796            tcg_temp_free_i32(fp32);
9797            gen_store_fpr64(ctx, fp64, fd);
9798            tcg_temp_free_i64(fp64);
9799        }
9800        break;
9801    case OPC_CVT_S_L:
9802        check_cp1_64bitmode(ctx);
9803        {
9804            TCGv_i32 fp32 = tcg_temp_new_i32();
9805            TCGv_i64 fp64 = tcg_temp_new_i64();
9806
9807            gen_load_fpr64(ctx, fp64, fs);
9808            gen_helper_float_cvts_l(fp32, cpu_env, fp64);
9809            tcg_temp_free_i64(fp64);
9810            gen_store_fpr32(ctx, fp32, fd);
9811            tcg_temp_free_i32(fp32);
9812        }
9813        break;
9814    case OPC_CVT_D_L:
9815        check_cp1_64bitmode(ctx);
9816        {
9817            TCGv_i64 fp0 = tcg_temp_new_i64();
9818
9819            gen_load_fpr64(ctx, fp0, fs);
9820            gen_helper_float_cvtd_l(fp0, cpu_env, fp0);
9821            gen_store_fpr64(ctx, fp0, fd);
9822            tcg_temp_free_i64(fp0);
9823        }
9824        break;
9825    case OPC_CVT_PS_PW:
9826        check_ps(ctx);
9827        {
9828            TCGv_i64 fp0 = tcg_temp_new_i64();
9829
9830            gen_load_fpr64(ctx, fp0, fs);
9831            gen_helper_float_cvtps_pw(fp0, cpu_env, fp0);
9832            gen_store_fpr64(ctx, fp0, fd);
9833            tcg_temp_free_i64(fp0);
9834        }
9835        break;
9836    case OPC_ADD_PS:
9837        check_ps(ctx);
9838        {
9839            TCGv_i64 fp0 = tcg_temp_new_i64();
9840            TCGv_i64 fp1 = tcg_temp_new_i64();
9841
9842            gen_load_fpr64(ctx, fp0, fs);
9843            gen_load_fpr64(ctx, fp1, ft);
9844            gen_helper_float_add_ps(fp0, cpu_env, fp0, fp1);
9845            tcg_temp_free_i64(fp1);
9846            gen_store_fpr64(ctx, fp0, fd);
9847            tcg_temp_free_i64(fp0);
9848        }
9849        break;
9850    case OPC_SUB_PS:
9851        check_ps(ctx);
9852        {
9853            TCGv_i64 fp0 = tcg_temp_new_i64();
9854            TCGv_i64 fp1 = tcg_temp_new_i64();
9855
9856            gen_load_fpr64(ctx, fp0, fs);
9857            gen_load_fpr64(ctx, fp1, ft);
9858            gen_helper_float_sub_ps(fp0, cpu_env, fp0, fp1);
9859            tcg_temp_free_i64(fp1);
9860            gen_store_fpr64(ctx, fp0, fd);
9861            tcg_temp_free_i64(fp0);
9862        }
9863        break;
9864    case OPC_MUL_PS:
9865        check_ps(ctx);
9866        {
9867            TCGv_i64 fp0 = tcg_temp_new_i64();
9868            TCGv_i64 fp1 = tcg_temp_new_i64();
9869
9870            gen_load_fpr64(ctx, fp0, fs);
9871            gen_load_fpr64(ctx, fp1, ft);
9872            gen_helper_float_mul_ps(fp0, cpu_env, fp0, fp1);
9873            tcg_temp_free_i64(fp1);
9874            gen_store_fpr64(ctx, fp0, fd);
9875            tcg_temp_free_i64(fp0);
9876        }
9877        break;
9878    case OPC_ABS_PS:
9879        check_ps(ctx);
9880        {
9881            TCGv_i64 fp0 = tcg_temp_new_i64();
9882
9883            gen_load_fpr64(ctx, fp0, fs);
9884            gen_helper_float_abs_ps(fp0, fp0);
9885            gen_store_fpr64(ctx, fp0, fd);
9886            tcg_temp_free_i64(fp0);
9887        }
9888        break;
9889    case OPC_MOV_PS:
9890        check_ps(ctx);
9891        {
9892            TCGv_i64 fp0 = tcg_temp_new_i64();
9893
9894            gen_load_fpr64(ctx, fp0, fs);
9895            gen_store_fpr64(ctx, fp0, fd);
9896            tcg_temp_free_i64(fp0);
9897        }
9898        break;
9899    case OPC_NEG_PS:
9900        check_ps(ctx);
9901        {
9902            TCGv_i64 fp0 = tcg_temp_new_i64();
9903
9904            gen_load_fpr64(ctx, fp0, fs);
9905            gen_helper_float_chs_ps(fp0, fp0);
9906            gen_store_fpr64(ctx, fp0, fd);
9907            tcg_temp_free_i64(fp0);
9908        }
9909        break;
9910    case OPC_MOVCF_PS:
9911        check_ps(ctx);
9912        gen_movcf_ps(ctx, fs, fd, (ft >> 2) & 0x7, ft & 0x1);
9913        break;
9914    case OPC_MOVZ_PS:
9915        check_ps(ctx);
9916        {
9917            TCGLabel *l1 = gen_new_label();
9918            TCGv_i64 fp0;
9919
9920            if (ft != 0)
9921                tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[ft], 0, l1);
9922            fp0 = tcg_temp_new_i64();
9923            gen_load_fpr64(ctx, fp0, fs);
9924            gen_store_fpr64(ctx, fp0, fd);
9925            tcg_temp_free_i64(fp0);
9926            gen_set_label(l1);
9927        }
9928        break;
9929    case OPC_MOVN_PS:
9930        check_ps(ctx);
9931        {
9932            TCGLabel *l1 = gen_new_label();
9933            TCGv_i64 fp0;
9934
9935            if (ft != 0) {
9936                tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[ft], 0, l1);
9937                fp0 = tcg_temp_new_i64();
9938                gen_load_fpr64(ctx, fp0, fs);
9939                gen_store_fpr64(ctx, fp0, fd);
9940                tcg_temp_free_i64(fp0);
9941                gen_set_label(l1);
9942            }
9943        }
9944        break;
9945    case OPC_ADDR_PS:
9946        check_ps(ctx);
9947        {
9948            TCGv_i64 fp0 = tcg_temp_new_i64();
9949            TCGv_i64 fp1 = tcg_temp_new_i64();
9950
9951            gen_load_fpr64(ctx, fp0, ft);
9952            gen_load_fpr64(ctx, fp1, fs);
9953            gen_helper_float_addr_ps(fp0, cpu_env, fp0, fp1);
9954            tcg_temp_free_i64(fp1);
9955            gen_store_fpr64(ctx, fp0, fd);
9956            tcg_temp_free_i64(fp0);
9957        }
9958        break;
9959    case OPC_MULR_PS:
9960        check_ps(ctx);
9961        {
9962            TCGv_i64 fp0 = tcg_temp_new_i64();
9963            TCGv_i64 fp1 = tcg_temp_new_i64();
9964
9965            gen_load_fpr64(ctx, fp0, ft);
9966            gen_load_fpr64(ctx, fp1, fs);
9967            gen_helper_float_mulr_ps(fp0, cpu_env, fp0, fp1);
9968            tcg_temp_free_i64(fp1);
9969            gen_store_fpr64(ctx, fp0, fd);
9970            tcg_temp_free_i64(fp0);
9971        }
9972        break;
9973    case OPC_RECIP2_PS:
9974        check_ps(ctx);
9975        {
9976            TCGv_i64 fp0 = tcg_temp_new_i64();
9977            TCGv_i64 fp1 = tcg_temp_new_i64();
9978
9979            gen_load_fpr64(ctx, fp0, fs);
9980            gen_load_fpr64(ctx, fp1, ft);
9981            gen_helper_float_recip2_ps(fp0, cpu_env, fp0, fp1);
9982            tcg_temp_free_i64(fp1);
9983            gen_store_fpr64(ctx, fp0, fd);
9984            tcg_temp_free_i64(fp0);
9985        }
9986        break;
9987    case OPC_RECIP1_PS:
9988        check_ps(ctx);
9989        {
9990            TCGv_i64 fp0 = tcg_temp_new_i64();
9991
9992            gen_load_fpr64(ctx, fp0, fs);
9993            gen_helper_float_recip1_ps(fp0, cpu_env, fp0);
9994            gen_store_fpr64(ctx, fp0, fd);
9995            tcg_temp_free_i64(fp0);
9996        }
9997        break;
9998    case OPC_RSQRT1_PS:
9999        check_ps(ctx);
10000        {
10001            TCGv_i64 fp0 = tcg_temp_new_i64();
10002
10003            gen_load_fpr64(ctx, fp0, fs);
10004            gen_helper_float_rsqrt1_ps(fp0, cpu_env, fp0);
10005            gen_store_fpr64(ctx, fp0, fd);
10006            tcg_temp_free_i64(fp0);
10007        }
10008        break;
10009    case OPC_RSQRT2_PS:
10010        check_ps(ctx);
10011        {
10012            TCGv_i64 fp0 = tcg_temp_new_i64();
10013            TCGv_i64 fp1 = tcg_temp_new_i64();
10014
10015            gen_load_fpr64(ctx, fp0, fs);
10016            gen_load_fpr64(ctx, fp1, ft);
10017            gen_helper_float_rsqrt2_ps(fp0, cpu_env, fp0, fp1);
10018            tcg_temp_free_i64(fp1);
10019            gen_store_fpr64(ctx, fp0, fd);
10020            tcg_temp_free_i64(fp0);
10021        }
10022        break;
10023    case OPC_CVT_S_PU:
10024        check_cp1_64bitmode(ctx);
10025        {
10026            TCGv_i32 fp0 = tcg_temp_new_i32();
10027
10028            gen_load_fpr32h(ctx, fp0, fs);
10029            gen_helper_float_cvts_pu(fp0, cpu_env, fp0);
10030            gen_store_fpr32(ctx, fp0, fd);
10031            tcg_temp_free_i32(fp0);
10032        }
10033        break;
10034    case OPC_CVT_PW_PS:
10035        check_ps(ctx);
10036        {
10037            TCGv_i64 fp0 = tcg_temp_new_i64();
10038
10039            gen_load_fpr64(ctx, fp0, fs);
10040            gen_helper_float_cvtpw_ps(fp0, cpu_env, fp0);
10041            gen_store_fpr64(ctx, fp0, fd);
10042            tcg_temp_free_i64(fp0);
10043        }
10044        break;
10045    case OPC_CVT_S_PL:
10046        check_cp1_64bitmode(ctx);
10047        {
10048            TCGv_i32 fp0 = tcg_temp_new_i32();
10049
10050            gen_load_fpr32(ctx, fp0, fs);
10051            gen_helper_float_cvts_pl(fp0, cpu_env, fp0);
10052            gen_store_fpr32(ctx, fp0, fd);
10053            tcg_temp_free_i32(fp0);
10054        }
10055        break;
10056    case OPC_PLL_PS:
10057        check_ps(ctx);
10058        {
10059            TCGv_i32 fp0 = tcg_temp_new_i32();
10060            TCGv_i32 fp1 = tcg_temp_new_i32();
10061
10062            gen_load_fpr32(ctx, fp0, fs);
10063            gen_load_fpr32(ctx, fp1, ft);
10064            gen_store_fpr32h(ctx, fp0, fd);
10065            gen_store_fpr32(ctx, fp1, fd);
10066            tcg_temp_free_i32(fp0);
10067            tcg_temp_free_i32(fp1);
10068        }
10069        break;
10070    case OPC_PLU_PS:
10071        check_ps(ctx);
10072        {
10073            TCGv_i32 fp0 = tcg_temp_new_i32();
10074            TCGv_i32 fp1 = tcg_temp_new_i32();
10075
10076            gen_load_fpr32(ctx, fp0, fs);
10077            gen_load_fpr32h(ctx, fp1, ft);
10078            gen_store_fpr32(ctx, fp1, fd);
10079            gen_store_fpr32h(ctx, fp0, fd);
10080            tcg_temp_free_i32(fp0);
10081            tcg_temp_free_i32(fp1);
10082        }
10083        break;
10084    case OPC_PUL_PS:
10085        check_ps(ctx);
10086        {
10087            TCGv_i32 fp0 = tcg_temp_new_i32();
10088            TCGv_i32 fp1 = tcg_temp_new_i32();
10089
10090            gen_load_fpr32h(ctx, fp0, fs);
10091            gen_load_fpr32(ctx, fp1, ft);
10092            gen_store_fpr32(ctx, fp1, fd);
10093            gen_store_fpr32h(ctx, fp0, fd);
10094            tcg_temp_free_i32(fp0);
10095            tcg_temp_free_i32(fp1);
10096        }
10097        break;
10098    case OPC_PUU_PS:
10099        check_ps(ctx);
10100        {
10101            TCGv_i32 fp0 = tcg_temp_new_i32();
10102            TCGv_i32 fp1 = tcg_temp_new_i32();
10103
10104            gen_load_fpr32h(ctx, fp0, fs);
10105            gen_load_fpr32h(ctx, fp1, ft);
10106            gen_store_fpr32(ctx, fp1, fd);
10107            gen_store_fpr32h(ctx, fp0, fd);
10108            tcg_temp_free_i32(fp0);
10109            tcg_temp_free_i32(fp1);
10110        }
10111        break;
10112    case OPC_CMP_F_PS:
10113    case OPC_CMP_UN_PS:
10114    case OPC_CMP_EQ_PS:
10115    case OPC_CMP_UEQ_PS:
10116    case OPC_CMP_OLT_PS:
10117    case OPC_CMP_ULT_PS:
10118    case OPC_CMP_OLE_PS:
10119    case OPC_CMP_ULE_PS:
10120    case OPC_CMP_SF_PS:
10121    case OPC_CMP_NGLE_PS:
10122    case OPC_CMP_SEQ_PS:
10123    case OPC_CMP_NGL_PS:
10124    case OPC_CMP_LT_PS:
10125    case OPC_CMP_NGE_PS:
10126    case OPC_CMP_LE_PS:
10127    case OPC_CMP_NGT_PS:
10128        if (ctx->opcode & (1 << 6)) {
10129            gen_cmpabs_ps(ctx, func-48, ft, fs, cc);
10130        } else {
10131            gen_cmp_ps(ctx, func-48, ft, fs, cc);
10132        }
10133        break;
10134    default:
10135        MIPS_INVAL("farith");
10136        generate_exception_end(ctx, EXCP_RI);
10137        return;
10138    }
10139}
10140
10141/* Coprocessor 3 (FPU) */
10142static void gen_flt3_ldst (DisasContext *ctx, uint32_t opc,
10143                           int fd, int fs, int base, int index)
10144{
10145    TCGv t0 = tcg_temp_new();
10146
10147    if (base == 0) {
10148        gen_load_gpr(t0, index);
10149    } else if (index == 0) {
10150        gen_load_gpr(t0, base);
10151    } else {
10152        gen_op_addr_add(ctx, t0, cpu_gpr[base], cpu_gpr[index]);
10153    }
10154    /* Don't do NOP if destination is zero: we must perform the actual
10155       memory access. */
10156    switch (opc) {
10157    case OPC_LWXC1:
10158        check_cop1x(ctx);
10159        {
10160            TCGv_i32 fp0 = tcg_temp_new_i32();
10161
10162            tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TESL);
10163            tcg_gen_trunc_tl_i32(fp0, t0);
10164            gen_store_fpr32(ctx, fp0, fd);
10165            tcg_temp_free_i32(fp0);
10166        }
10167        break;
10168    case OPC_LDXC1:
10169        check_cop1x(ctx);
10170        check_cp1_registers(ctx, fd);
10171        {
10172            TCGv_i64 fp0 = tcg_temp_new_i64();
10173            tcg_gen_qemu_ld_i64(fp0, t0, ctx->mem_idx, MO_TEQ);
10174            gen_store_fpr64(ctx, fp0, fd);
10175            tcg_temp_free_i64(fp0);
10176        }
10177        break;
10178    case OPC_LUXC1:
10179        check_cp1_64bitmode(ctx);
10180        tcg_gen_andi_tl(t0, t0, ~0x7);
10181        {
10182            TCGv_i64 fp0 = tcg_temp_new_i64();
10183
10184            tcg_gen_qemu_ld_i64(fp0, t0, ctx->mem_idx, MO_TEQ);
10185            gen_store_fpr64(ctx, fp0, fd);
10186            tcg_temp_free_i64(fp0);
10187        }
10188        break;
10189    case OPC_SWXC1:
10190        check_cop1x(ctx);
10191        {
10192            TCGv_i32 fp0 = tcg_temp_new_i32();
10193            gen_load_fpr32(ctx, fp0, fs);
10194            tcg_gen_qemu_st_i32(fp0, t0, ctx->mem_idx, MO_TEUL);
10195            tcg_temp_free_i32(fp0);
10196        }
10197        break;
10198    case OPC_SDXC1:
10199        check_cop1x(ctx);
10200        check_cp1_registers(ctx, fs);
10201        {
10202            TCGv_i64 fp0 = tcg_temp_new_i64();
10203            gen_load_fpr64(ctx, fp0, fs);
10204            tcg_gen_qemu_st_i64(fp0, t0, ctx->mem_idx, MO_TEQ);
10205            tcg_temp_free_i64(fp0);
10206        }
10207        break;
10208    case OPC_SUXC1:
10209        check_cp1_64bitmode(ctx);
10210        tcg_gen_andi_tl(t0, t0, ~0x7);
10211        {
10212            TCGv_i64 fp0 = tcg_temp_new_i64();
10213            gen_load_fpr64(ctx, fp0, fs);
10214            tcg_gen_qemu_st_i64(fp0, t0, ctx->mem_idx, MO_TEQ);
10215            tcg_temp_free_i64(fp0);
10216        }
10217        break;
10218    }
10219    tcg_temp_free(t0);
10220}
10221
10222static void gen_flt3_arith (DisasContext *ctx, uint32_t opc,
10223                            int fd, int fr, int fs, int ft)
10224{
10225    switch (opc) {
10226    case OPC_ALNV_PS:
10227        check_ps(ctx);
10228        {
10229            TCGv t0 = tcg_temp_local_new();
10230            TCGv_i32 fp = tcg_temp_new_i32();
10231            TCGv_i32 fph = tcg_temp_new_i32();
10232            TCGLabel *l1 = gen_new_label();
10233            TCGLabel *l2 = gen_new_label();
10234
10235            gen_load_gpr(t0, fr);
10236            tcg_gen_andi_tl(t0, t0, 0x7);
10237
10238            tcg_gen_brcondi_tl(TCG_COND_NE, t0, 0, l1);
10239            gen_load_fpr32(ctx, fp, fs);
10240            gen_load_fpr32h(ctx, fph, fs);
10241            gen_store_fpr32(ctx, fp, fd);
10242            gen_store_fpr32h(ctx, fph, fd);
10243            tcg_gen_br(l2);
10244            gen_set_label(l1);
10245            tcg_gen_brcondi_tl(TCG_COND_NE, t0, 4, l2);
10246            tcg_temp_free(t0);
10247#ifdef TARGET_WORDS_BIGENDIAN
10248            gen_load_fpr32(ctx, fp, fs);
10249            gen_load_fpr32h(ctx, fph, ft);
10250            gen_store_fpr32h(ctx, fp, fd);
10251            gen_store_fpr32(ctx, fph, fd);
10252#else
10253            gen_load_fpr32h(ctx, fph, fs);
10254            gen_load_fpr32(ctx, fp, ft);
10255            gen_store_fpr32(ctx, fph, fd);
10256            gen_store_fpr32h(ctx, fp, fd);
10257#endif
10258            gen_set_label(l2);
10259            tcg_temp_free_i32(fp);
10260            tcg_temp_free_i32(fph);
10261        }
10262        break;
10263    case OPC_MADD_S:
10264        check_cop1x(ctx);
10265        {
10266            TCGv_i32 fp0 = tcg_temp_new_i32();
10267            TCGv_i32 fp1 = tcg_temp_new_i32();
10268            TCGv_i32 fp2 = tcg_temp_new_i32();
10269
10270            gen_load_fpr32(ctx, fp0, fs);
10271            gen_load_fpr32(ctx, fp1, ft);
10272            gen_load_fpr32(ctx, fp2, fr);
10273            gen_helper_float_madd_s(fp2, cpu_env, fp0, fp1, fp2);
10274            tcg_temp_free_i32(fp0);
10275            tcg_temp_free_i32(fp1);
10276            gen_store_fpr32(ctx, fp2, fd);
10277            tcg_temp_free_i32(fp2);
10278        }
10279        break;
10280    case OPC_MADD_D:
10281        check_cop1x(ctx);
10282        check_cp1_registers(ctx, fd | fs | ft | fr);
10283        {
10284            TCGv_i64 fp0 = tcg_temp_new_i64();
10285            TCGv_i64 fp1 = tcg_temp_new_i64();
10286            TCGv_i64 fp2 = tcg_temp_new_i64();
10287
10288            gen_load_fpr64(ctx, fp0, fs);
10289            gen_load_fpr64(ctx, fp1, ft);
10290            gen_load_fpr64(ctx, fp2, fr);
10291            gen_helper_float_madd_d(fp2, cpu_env, fp0, fp1, fp2);
10292            tcg_temp_free_i64(fp0);
10293            tcg_temp_free_i64(fp1);
10294            gen_store_fpr64(ctx, fp2, fd);
10295            tcg_temp_free_i64(fp2);
10296        }
10297        break;
10298    case OPC_MADD_PS:
10299        check_ps(ctx);
10300        {
10301            TCGv_i64 fp0 = tcg_temp_new_i64();
10302            TCGv_i64 fp1 = tcg_temp_new_i64();
10303            TCGv_i64 fp2 = tcg_temp_new_i64();
10304
10305            gen_load_fpr64(ctx, fp0, fs);
10306            gen_load_fpr64(ctx, fp1, ft);
10307            gen_load_fpr64(ctx, fp2, fr);
10308            gen_helper_float_madd_ps(fp2, cpu_env, fp0, fp1, fp2);
10309            tcg_temp_free_i64(fp0);
10310            tcg_temp_free_i64(fp1);
10311            gen_store_fpr64(ctx, fp2, fd);
10312            tcg_temp_free_i64(fp2);
10313        }
10314        break;
10315    case OPC_MSUB_S:
10316        check_cop1x(ctx);
10317        {
10318            TCGv_i32 fp0 = tcg_temp_new_i32();
10319            TCGv_i32 fp1 = tcg_temp_new_i32();
10320            TCGv_i32 fp2 = tcg_temp_new_i32();
10321
10322            gen_load_fpr32(ctx, fp0, fs);
10323            gen_load_fpr32(ctx, fp1, ft);
10324            gen_load_fpr32(ctx, fp2, fr);
10325            gen_helper_float_msub_s(fp2, cpu_env, fp0, fp1, fp2);
10326            tcg_temp_free_i32(fp0);
10327            tcg_temp_free_i32(fp1);
10328            gen_store_fpr32(ctx, fp2, fd);
10329            tcg_temp_free_i32(fp2);
10330        }
10331        break;
10332    case OPC_MSUB_D:
10333        check_cop1x(ctx);
10334        check_cp1_registers(ctx, fd | fs | ft | fr);
10335        {
10336            TCGv_i64 fp0 = tcg_temp_new_i64();
10337            TCGv_i64 fp1 = tcg_temp_new_i64();
10338            TCGv_i64 fp2 = tcg_temp_new_i64();
10339
10340            gen_load_fpr64(ctx, fp0, fs);
10341            gen_load_fpr64(ctx, fp1, ft);
10342            gen_load_fpr64(ctx, fp2, fr);
10343            gen_helper_float_msub_d(fp2, cpu_env, fp0, fp1, fp2);
10344            tcg_temp_free_i64(fp0);
10345            tcg_temp_free_i64(fp1);
10346            gen_store_fpr64(ctx, fp2, fd);
10347            tcg_temp_free_i64(fp2);
10348        }
10349        break;
10350    case OPC_MSUB_PS:
10351        check_ps(ctx);
10352        {
10353            TCGv_i64 fp0 = tcg_temp_new_i64();
10354            TCGv_i64 fp1 = tcg_temp_new_i64();
10355            TCGv_i64 fp2 = tcg_temp_new_i64();
10356
10357            gen_load_fpr64(ctx, fp0, fs);
10358            gen_load_fpr64(ctx, fp1, ft);
10359            gen_load_fpr64(ctx, fp2, fr);
10360            gen_helper_float_msub_ps(fp2, cpu_env, fp0, fp1, fp2);
10361            tcg_temp_free_i64(fp0);
10362            tcg_temp_free_i64(fp1);
10363            gen_store_fpr64(ctx, fp2, fd);
10364            tcg_temp_free_i64(fp2);
10365        }
10366        break;
10367    case OPC_NMADD_S:
10368        check_cop1x(ctx);
10369        {
10370            TCGv_i32 fp0 = tcg_temp_new_i32();
10371            TCGv_i32 fp1 = tcg_temp_new_i32();
10372            TCGv_i32 fp2 = tcg_temp_new_i32();
10373
10374            gen_load_fpr32(ctx, fp0, fs);
10375            gen_load_fpr32(ctx, fp1, ft);
10376            gen_load_fpr32(ctx, fp2, fr);
10377            gen_helper_float_nmadd_s(fp2, cpu_env, fp0, fp1, fp2);
10378            tcg_temp_free_i32(fp0);
10379            tcg_temp_free_i32(fp1);
10380            gen_store_fpr32(ctx, fp2, fd);
10381            tcg_temp_free_i32(fp2);
10382        }
10383        break;
10384    case OPC_NMADD_D:
10385        check_cop1x(ctx);
10386        check_cp1_registers(ctx, fd | fs | ft | fr);
10387        {
10388            TCGv_i64 fp0 = tcg_temp_new_i64();
10389            TCGv_i64 fp1 = tcg_temp_new_i64();
10390            TCGv_i64 fp2 = tcg_temp_new_i64();
10391
10392            gen_load_fpr64(ctx, fp0, fs);
10393            gen_load_fpr64(ctx, fp1, ft);
10394            gen_load_fpr64(ctx, fp2, fr);
10395            gen_helper_float_nmadd_d(fp2, cpu_env, fp0, fp1, fp2);
10396            tcg_temp_free_i64(fp0);
10397            tcg_temp_free_i64(fp1);
10398            gen_store_fpr64(ctx, fp2, fd);
10399            tcg_temp_free_i64(fp2);
10400        }
10401        break;
10402    case OPC_NMADD_PS:
10403        check_ps(ctx);
10404        {
10405            TCGv_i64 fp0 = tcg_temp_new_i64();
10406            TCGv_i64 fp1 = tcg_temp_new_i64();
10407            TCGv_i64 fp2 = tcg_temp_new_i64();
10408
10409            gen_load_fpr64(ctx, fp0, fs);
10410            gen_load_fpr64(ctx, fp1, ft);
10411            gen_load_fpr64(ctx, fp2, fr);
10412            gen_helper_float_nmadd_ps(fp2, cpu_env, fp0, fp1, fp2);
10413            tcg_temp_free_i64(fp0);
10414            tcg_temp_free_i64(fp1);
10415            gen_store_fpr64(ctx, fp2, fd);
10416            tcg_temp_free_i64(fp2);
10417        }
10418        break;
10419    case OPC_NMSUB_S:
10420        check_cop1x(ctx);
10421        {
10422            TCGv_i32 fp0 = tcg_temp_new_i32();
10423            TCGv_i32 fp1 = tcg_temp_new_i32();
10424            TCGv_i32 fp2 = tcg_temp_new_i32();
10425
10426            gen_load_fpr32(ctx, fp0, fs);
10427            gen_load_fpr32(ctx, fp1, ft);
10428            gen_load_fpr32(ctx, fp2, fr);
10429            gen_helper_float_nmsub_s(fp2, cpu_env, fp0, fp1, fp2);
10430            tcg_temp_free_i32(fp0);
10431            tcg_temp_free_i32(fp1);
10432            gen_store_fpr32(ctx, fp2, fd);
10433            tcg_temp_free_i32(fp2);
10434        }
10435        break;
10436    case OPC_NMSUB_D:
10437        check_cop1x(ctx);
10438        check_cp1_registers(ctx, fd | fs | ft | fr);
10439        {
10440            TCGv_i64 fp0 = tcg_temp_new_i64();
10441            TCGv_i64 fp1 = tcg_temp_new_i64();
10442            TCGv_i64 fp2 = tcg_temp_new_i64();
10443
10444            gen_load_fpr64(ctx, fp0, fs);
10445            gen_load_fpr64(ctx, fp1, ft);
10446            gen_load_fpr64(ctx, fp2, fr);
10447            gen_helper_float_nmsub_d(fp2, cpu_env, fp0, fp1, fp2);
10448            tcg_temp_free_i64(fp0);
10449            tcg_temp_free_i64(fp1);
10450            gen_store_fpr64(ctx, fp2, fd);
10451            tcg_temp_free_i64(fp2);
10452        }
10453        break;
10454    case OPC_NMSUB_PS:
10455        check_ps(ctx);
10456        {
10457            TCGv_i64 fp0 = tcg_temp_new_i64();
10458            TCGv_i64 fp1 = tcg_temp_new_i64();
10459            TCGv_i64 fp2 = tcg_temp_new_i64();
10460
10461            gen_load_fpr64(ctx, fp0, fs);
10462            gen_load_fpr64(ctx, fp1, ft);
10463            gen_load_fpr64(ctx, fp2, fr);
10464            gen_helper_float_nmsub_ps(fp2, cpu_env, fp0, fp1, fp2);
10465            tcg_temp_free_i64(fp0);
10466            tcg_temp_free_i64(fp1);
10467            gen_store_fpr64(ctx, fp2, fd);
10468            tcg_temp_free_i64(fp2);
10469        }
10470        break;
10471    default:
10472        MIPS_INVAL("flt3_arith");
10473        generate_exception_end(ctx, EXCP_RI);
10474        return;
10475    }
10476}
10477
10478static void gen_rdhwr(DisasContext *ctx, int rt, int rd, int sel)
10479{
10480    TCGv t0;
10481
10482#if !defined(CONFIG_USER_ONLY)
10483    /* The Linux kernel will emulate rdhwr if it's not supported natively.
10484       Therefore only check the ISA in system mode.  */
10485    check_insn(ctx, ISA_MIPS32R2);
10486#endif
10487    t0 = tcg_temp_new();
10488
10489    switch (rd) {
10490    case 0:
10491        gen_helper_rdhwr_cpunum(t0, cpu_env);
10492        gen_store_gpr(t0, rt);
10493        break;
10494    case 1:
10495        gen_helper_rdhwr_synci_step(t0, cpu_env);
10496        gen_store_gpr(t0, rt);
10497        break;
10498    case 2:
10499        gen_helper_rdhwr_cc(t0, cpu_env);
10500        gen_store_gpr(t0, rt);
10501        break;
10502    case 3:
10503        gen_helper_rdhwr_ccres(t0, cpu_env);
10504        gen_store_gpr(t0, rt);
10505        break;
10506    case 4:
10507        check_insn(ctx, ISA_MIPS32R6);
10508        if (sel != 0) {
10509            /* Performance counter registers are not implemented other than
10510             * control register 0.
10511             */
10512            generate_exception(ctx, EXCP_RI);
10513        }
10514        gen_helper_rdhwr_performance(t0, cpu_env);
10515        gen_store_gpr(t0, rt);
10516        break;
10517    case 5:
10518        check_insn(ctx, ISA_MIPS32R6);
10519        gen_helper_rdhwr_xnp(t0, cpu_env);
10520        gen_store_gpr(t0, rt);
10521        break;
10522    case 29:
10523#if defined(CONFIG_USER_ONLY)
10524        tcg_gen_ld_tl(t0, cpu_env,
10525                      offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
10526        gen_store_gpr(t0, rt);
10527        break;
10528#else
10529        if ((ctx->hflags & MIPS_HFLAG_CP0) ||
10530            (ctx->hflags & MIPS_HFLAG_HWRENA_ULR)) {
10531            tcg_gen_ld_tl(t0, cpu_env,
10532                          offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
10533            gen_store_gpr(t0, rt);
10534        } else {
10535            generate_exception_end(ctx, EXCP_RI);
10536        }
10537        break;
10538#endif
10539    default:            /* Invalid */
10540        MIPS_INVAL("rdhwr");
10541        generate_exception_end(ctx, EXCP_RI);
10542        break;
10543    }
10544    tcg_temp_free(t0);
10545}
10546
10547static inline void clear_branch_hflags(DisasContext *ctx)
10548{
10549    ctx->hflags &= ~MIPS_HFLAG_BMASK;
10550    if (ctx->bstate == BS_NONE) {
10551        save_cpu_state(ctx, 0);
10552    } else {
10553        /* it is not safe to save ctx->hflags as hflags may be changed
10554           in execution time by the instruction in delay / forbidden slot. */
10555        tcg_gen_andi_i32(hflags, hflags, ~MIPS_HFLAG_BMASK);
10556    }
10557}
10558
10559static void gen_branch(DisasContext *ctx, int insn_bytes)
10560{
10561    if (ctx->hflags & MIPS_HFLAG_BMASK) {
10562        int proc_hflags = ctx->hflags & MIPS_HFLAG_BMASK;
10563        /* Branches completion */
10564        clear_branch_hflags(ctx);
10565        ctx->bstate = BS_BRANCH;
10566        /* FIXME: Need to clear can_do_io.  */
10567        switch (proc_hflags & MIPS_HFLAG_BMASK_BASE) {
10568        case MIPS_HFLAG_FBNSLOT:
10569            gen_goto_tb(ctx, 0, ctx->pc + insn_bytes);
10570            break;
10571        case MIPS_HFLAG_B:
10572            /* unconditional branch */
10573            if (proc_hflags & MIPS_HFLAG_BX) {
10574                tcg_gen_xori_i32(hflags, hflags, MIPS_HFLAG_M16);
10575            }
10576            gen_goto_tb(ctx, 0, ctx->btarget);
10577            break;
10578        case MIPS_HFLAG_BL:
10579            /* blikely taken case */
10580            gen_goto_tb(ctx, 0, ctx->btarget);
10581            break;
10582        case MIPS_HFLAG_BC:
10583            /* Conditional branch */
10584            {
10585                TCGLabel *l1 = gen_new_label();
10586
10587                tcg_gen_brcondi_tl(TCG_COND_NE, bcond, 0, l1);
10588                gen_goto_tb(ctx, 1, ctx->pc + insn_bytes);
10589                gen_set_label(l1);
10590                gen_goto_tb(ctx, 0, ctx->btarget);
10591            }
10592            break;
10593        case MIPS_HFLAG_BR:
10594            /* unconditional branch to register */
10595            if (ctx->insn_flags & (ASE_MIPS16 | ASE_MICROMIPS)) {
10596                TCGv t0 = tcg_temp_new();
10597                TCGv_i32 t1 = tcg_temp_new_i32();
10598
10599                tcg_gen_andi_tl(t0, btarget, 0x1);
10600                tcg_gen_trunc_tl_i32(t1, t0);
10601                tcg_temp_free(t0);
10602                tcg_gen_andi_i32(hflags, hflags, ~(uint32_t)MIPS_HFLAG_M16);
10603                tcg_gen_shli_i32(t1, t1, MIPS_HFLAG_M16_SHIFT);
10604                tcg_gen_or_i32(hflags, hflags, t1);
10605                tcg_temp_free_i32(t1);
10606
10607                tcg_gen_andi_tl(cpu_PC, btarget, ~(target_ulong)0x1);
10608            } else {
10609                tcg_gen_mov_tl(cpu_PC, btarget);
10610            }
10611            if (ctx->singlestep_enabled) {
10612                save_cpu_state(ctx, 0);
10613                gen_helper_raise_exception_debug(cpu_env);
10614            }
10615            tcg_gen_exit_tb(0);
10616            break;
10617        default:
10618            fprintf(stderr, "unknown branch 0x%x\n", proc_hflags);
10619            abort();
10620        }
10621    }
10622}
10623
10624/* Compact Branches */
10625static void gen_compute_compact_branch(DisasContext *ctx, uint32_t opc,
10626                                       int rs, int rt, int32_t offset)
10627{
10628    int bcond_compute = 0;
10629    TCGv t0 = tcg_temp_new();
10630    TCGv t1 = tcg_temp_new();
10631    int m16_lowbit = (ctx->hflags & MIPS_HFLAG_M16) != 0;
10632
10633    if (ctx->hflags & MIPS_HFLAG_BMASK) {
10634#ifdef MIPS_DEBUG_DISAS
10635        LOG_DISAS("Branch in delay / forbidden slot at PC 0x" TARGET_FMT_lx
10636                  "\n", ctx->pc);
10637#endif
10638        generate_exception_end(ctx, EXCP_RI);
10639        goto out;
10640    }
10641
10642    /* Load needed operands and calculate btarget */
10643    switch (opc) {
10644    /* compact branch */
10645    case OPC_BOVC: /* OPC_BEQZALC, OPC_BEQC */
10646    case OPC_BNVC: /* OPC_BNEZALC, OPC_BNEC */
10647        gen_load_gpr(t0, rs);
10648        gen_load_gpr(t1, rt);
10649        bcond_compute = 1;
10650        ctx->btarget = addr_add(ctx, ctx->pc + 4, offset);
10651        if (rs <= rt && rs == 0) {
10652            /* OPC_BEQZALC, OPC_BNEZALC */
10653            tcg_gen_movi_tl(cpu_gpr[31], ctx->pc + 4 + m16_lowbit);
10654        }
10655        break;
10656    case OPC_BLEZC: /* OPC_BGEZC, OPC_BGEC */
10657    case OPC_BGTZC: /* OPC_BLTZC, OPC_BLTC */
10658        gen_load_gpr(t0, rs);
10659        gen_load_gpr(t1, rt);
10660        bcond_compute = 1;
10661        ctx->btarget = addr_add(ctx, ctx->pc + 4, offset);
10662        break;
10663    case OPC_BLEZALC: /* OPC_BGEZALC, OPC_BGEUC */
10664    case OPC_BGTZALC: /* OPC_BLTZALC, OPC_BLTUC */
10665        if (rs == 0 || rs == rt) {
10666            /* OPC_BLEZALC, OPC_BGEZALC */
10667            /* OPC_BGTZALC, OPC_BLTZALC */
10668            tcg_gen_movi_tl(cpu_gpr[31], ctx->pc + 4 + m16_lowbit);
10669        }
10670        gen_load_gpr(t0, rs);
10671        gen_load_gpr(t1, rt);
10672        bcond_compute = 1;
10673        ctx->btarget = addr_add(ctx, ctx->pc + 4, offset);
10674        break;
10675    case OPC_BC:
10676    case OPC_BALC:
10677        ctx->btarget = addr_add(ctx, ctx->pc + 4, offset);
10678        break;
10679    case OPC_BEQZC:
10680    case OPC_BNEZC:
10681        if (rs != 0) {
10682            /* OPC_BEQZC, OPC_BNEZC */
10683            gen_load_gpr(t0, rs);
10684            bcond_compute = 1;
10685            ctx->btarget = addr_add(ctx, ctx->pc + 4, offset);
10686        } else {
10687            /* OPC_JIC, OPC_JIALC */
10688            TCGv tbase = tcg_temp_new();
10689            TCGv toffset = tcg_temp_new();
10690
10691            gen_load_gpr(tbase, rt);
10692            tcg_gen_movi_tl(toffset, offset);
10693            gen_op_addr_add(ctx, btarget, tbase, toffset);
10694            tcg_temp_free(tbase);
10695            tcg_temp_free(toffset);
10696        }
10697        break;
10698    default:
10699        MIPS_INVAL("Compact branch/jump");
10700        generate_exception_end(ctx, EXCP_RI);
10701        goto out;
10702    }
10703
10704    if (bcond_compute == 0) {
10705        /* Uncoditional compact branch */
10706        switch (opc) {
10707        case OPC_JIALC:
10708            tcg_gen_movi_tl(cpu_gpr[31], ctx->pc + 4 + m16_lowbit);
10709            /* Fallthrough */
10710        case OPC_JIC:
10711            ctx->hflags |= MIPS_HFLAG_BR;
10712            break;
10713        case OPC_BALC:
10714            tcg_gen_movi_tl(cpu_gpr[31], ctx->pc + 4 + m16_lowbit);
10715            /* Fallthrough */
10716        case OPC_BC:
10717            ctx->hflags |= MIPS_HFLAG_B;
10718            break;
10719        default:
10720            MIPS_INVAL("Compact branch/jump");
10721            generate_exception_end(ctx, EXCP_RI);
10722            goto out;
10723        }
10724
10725        /* Generating branch here as compact branches don't have delay slot */
10726        gen_branch(ctx, 4);
10727    } else {
10728        /* Conditional compact branch */
10729        TCGLabel *fs = gen_new_label();
10730        save_cpu_state(ctx, 0);
10731
10732        switch (opc) {
10733        case OPC_BLEZALC: /* OPC_BGEZALC, OPC_BGEUC */
10734            if (rs == 0 && rt != 0) {
10735                /* OPC_BLEZALC */
10736                tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LE), t1, 0, fs);
10737            } else if (rs != 0 && rt != 0 && rs == rt) {
10738                /* OPC_BGEZALC */
10739                tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GE), t1, 0, fs);
10740            } else {
10741                /* OPC_BGEUC */
10742                tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_GEU), t0, t1, fs);
10743            }
10744            break;
10745        case OPC_BGTZALC: /* OPC_BLTZALC, OPC_BLTUC */
10746            if (rs == 0 && rt != 0) {
10747                /* OPC_BGTZALC */
10748                tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GT), t1, 0, fs);
10749            } else if (rs != 0 && rt != 0 && rs == rt) {
10750                /* OPC_BLTZALC */
10751                tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LT), t1, 0, fs);
10752            } else {
10753                /* OPC_BLTUC */
10754                tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_LTU), t0, t1, fs);
10755            }
10756            break;
10757        case OPC_BLEZC: /* OPC_BGEZC, OPC_BGEC */
10758            if (rs == 0 && rt != 0) {
10759                /* OPC_BLEZC */
10760                tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LE), t1, 0, fs);
10761            } else if (rs != 0 && rt != 0 && rs == rt) {
10762                /* OPC_BGEZC */
10763                tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GE), t1, 0, fs);
10764            } else {
10765                /* OPC_BGEC */
10766                tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_GE), t0, t1, fs);
10767            }
10768            break;
10769        case OPC_BGTZC: /* OPC_BLTZC, OPC_BLTC */
10770            if (rs == 0 && rt != 0) {
10771                /* OPC_BGTZC */
10772                tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GT), t1, 0, fs);
10773            } else if (rs != 0 && rt != 0 && rs == rt) {
10774                /* OPC_BLTZC */
10775                tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LT), t1, 0, fs);
10776            } else {
10777                /* OPC_BLTC */
10778                tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_LT), t0, t1, fs);
10779            }
10780            break;
10781        case OPC_BOVC: /* OPC_BEQZALC, OPC_BEQC */
10782        case OPC_BNVC: /* OPC_BNEZALC, OPC_BNEC */
10783            if (rs >= rt) {
10784                /* OPC_BOVC, OPC_BNVC */
10785                TCGv t2 = tcg_temp_new();
10786                TCGv t3 = tcg_temp_new();
10787                TCGv t4 = tcg_temp_new();
10788                TCGv input_overflow = tcg_temp_new();
10789
10790                gen_load_gpr(t0, rs);
10791                gen_load_gpr(t1, rt);
10792                tcg_gen_ext32s_tl(t2, t0);
10793                tcg_gen_setcond_tl(TCG_COND_NE, input_overflow, t2, t0);
10794                tcg_gen_ext32s_tl(t3, t1);
10795                tcg_gen_setcond_tl(TCG_COND_NE, t4, t3, t1);
10796                tcg_gen_or_tl(input_overflow, input_overflow, t4);
10797
10798                tcg_gen_add_tl(t4, t2, t3);
10799                tcg_gen_ext32s_tl(t4, t4);
10800                tcg_gen_xor_tl(t2, t2, t3);
10801                tcg_gen_xor_tl(t3, t4, t3);
10802                tcg_gen_andc_tl(t2, t3, t2);
10803                tcg_gen_setcondi_tl(TCG_COND_LT, t4, t2, 0);
10804                tcg_gen_or_tl(t4, t4, input_overflow);
10805                if (opc == OPC_BOVC) {
10806                    /* OPC_BOVC */
10807                    tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_NE), t4, 0, fs);
10808                } else {
10809                    /* OPC_BNVC */
10810                    tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_EQ), t4, 0, fs);
10811                }
10812                tcg_temp_free(input_overflow);
10813                tcg_temp_free(t4);
10814                tcg_temp_free(t3);
10815                tcg_temp_free(t2);
10816            } else if (rs < rt && rs == 0) {
10817                /* OPC_BEQZALC, OPC_BNEZALC */
10818                if (opc == OPC_BEQZALC) {
10819                    /* OPC_BEQZALC */
10820                    tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_EQ), t1, 0, fs);
10821                } else {
10822                    /* OPC_BNEZALC */
10823                    tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_NE), t1, 0, fs);
10824                }
10825            } else {
10826                /* OPC_BEQC, OPC_BNEC */
10827                if (opc == OPC_BEQC) {
10828                    /* OPC_BEQC */
10829                    tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_EQ), t0, t1, fs);
10830                } else {
10831                    /* OPC_BNEC */
10832                    tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_NE), t0, t1, fs);
10833                }
10834            }
10835            break;
10836        case OPC_BEQZC:
10837            tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_EQ), t0, 0, fs);
10838            break;
10839        case OPC_BNEZC:
10840            tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_NE), t0, 0, fs);
10841            break;
10842        default:
10843            MIPS_INVAL("Compact conditional branch/jump");
10844            generate_exception_end(ctx, EXCP_RI);
10845            goto out;
10846        }
10847
10848        /* Generating branch here as compact branches don't have delay slot */
10849        gen_goto_tb(ctx, 1, ctx->btarget);
10850        gen_set_label(fs);
10851
10852        ctx->hflags |= MIPS_HFLAG_FBNSLOT;
10853    }
10854
10855out:
10856    tcg_temp_free(t0);
10857    tcg_temp_free(t1);
10858}
10859
10860/* ISA extensions (ASEs) */
10861/* MIPS16 extension to MIPS32 */
10862
10863/* MIPS16 major opcodes */
10864enum {
10865  M16_OPC_ADDIUSP = 0x00,
10866  M16_OPC_ADDIUPC = 0x01,
10867  M16_OPC_B = 0x02,
10868  M16_OPC_JAL = 0x03,
10869  M16_OPC_BEQZ = 0x04,
10870  M16_OPC_BNEQZ = 0x05,
10871  M16_OPC_SHIFT = 0x06,
10872  M16_OPC_LD = 0x07,
10873  M16_OPC_RRIA = 0x08,
10874  M16_OPC_ADDIU8 = 0x09,
10875  M16_OPC_SLTI = 0x0a,
10876  M16_OPC_SLTIU = 0x0b,
10877  M16_OPC_I8 = 0x0c,
10878  M16_OPC_LI = 0x0d,
10879  M16_OPC_CMPI = 0x0e,
10880  M16_OPC_SD = 0x0f,
10881  M16_OPC_LB = 0x10,
10882  M16_OPC_LH = 0x11,
10883  M16_OPC_LWSP = 0x12,
10884  M16_OPC_LW = 0x13,
10885  M16_OPC_LBU = 0x14,
10886  M16_OPC_LHU = 0x15,
10887  M16_OPC_LWPC = 0x16,
10888  M16_OPC_LWU = 0x17,
10889  M16_OPC_SB = 0x18,
10890  M16_OPC_SH = 0x19,
10891  M16_OPC_SWSP = 0x1a,
10892  M16_OPC_SW = 0x1b,
10893  M16_OPC_RRR = 0x1c,
10894  M16_OPC_RR = 0x1d,
10895  M16_OPC_EXTEND = 0x1e,
10896  M16_OPC_I64 = 0x1f
10897};
10898
10899/* I8 funct field */
10900enum {
10901  I8_BTEQZ = 0x0,
10902  I8_BTNEZ = 0x1,
10903  I8_SWRASP = 0x2,
10904  I8_ADJSP = 0x3,
10905  I8_SVRS = 0x4,
10906  I8_MOV32R = 0x5,
10907  I8_MOVR32 = 0x7
10908};
10909
10910/* RRR f field */
10911enum {
10912  RRR_DADDU = 0x0,
10913  RRR_ADDU = 0x1,
10914  RRR_DSUBU = 0x2,
10915  RRR_SUBU = 0x3
10916};
10917
10918/* RR funct field */
10919enum {
10920  RR_JR = 0x00,
10921  RR_SDBBP = 0x01,
10922  RR_SLT = 0x02,
10923  RR_SLTU = 0x03,
10924  RR_SLLV = 0x04,
10925  RR_BREAK = 0x05,
10926  RR_SRLV = 0x06,
10927  RR_SRAV = 0x07,
10928  RR_DSRL = 0x08,
10929  RR_CMP = 0x0a,
10930  RR_NEG = 0x0b,
10931  RR_AND = 0x0c,
10932  RR_OR = 0x0d,
10933  RR_XOR = 0x0e,
10934  RR_NOT = 0x0f,
10935  RR_MFHI = 0x10,
10936  RR_CNVT = 0x11,
10937  RR_MFLO = 0x12,
10938  RR_DSRA = 0x13,
10939  RR_DSLLV = 0x14,
10940  RR_DSRLV = 0x16,
10941  RR_DSRAV = 0x17,
10942  RR_MULT = 0x18,
10943  RR_MULTU = 0x19,
10944  RR_DIV = 0x1a,
10945  RR_DIVU = 0x1b,
10946  RR_DMULT = 0x1c,
10947  RR_DMULTU = 0x1d,
10948  RR_DDIV = 0x1e,
10949  RR_DDIVU = 0x1f
10950};
10951
10952/* I64 funct field */
10953enum {
10954  I64_LDSP = 0x0,
10955  I64_SDSP = 0x1,
10956  I64_SDRASP = 0x2,
10957  I64_DADJSP = 0x3,
10958  I64_LDPC = 0x4,
10959  I64_DADDIU5 = 0x5,
10960  I64_DADDIUPC = 0x6,
10961  I64_DADDIUSP = 0x7
10962};
10963
10964/* RR ry field for CNVT */
10965enum {
10966  RR_RY_CNVT_ZEB = 0x0,
10967  RR_RY_CNVT_ZEH = 0x1,
10968  RR_RY_CNVT_ZEW = 0x2,
10969  RR_RY_CNVT_SEB = 0x4,
10970  RR_RY_CNVT_SEH = 0x5,
10971  RR_RY_CNVT_SEW = 0x6,
10972};
10973
10974static int xlat (int r)
10975{
10976  static int map[] = { 16, 17, 2, 3, 4, 5, 6, 7 };
10977
10978  return map[r];
10979}
10980
10981static void gen_mips16_save (DisasContext *ctx,
10982                             int xsregs, int aregs,
10983                             int do_ra, int do_s0, int do_s1,
10984                             int framesize)
10985{
10986    TCGv t0 = tcg_temp_new();
10987    TCGv t1 = tcg_temp_new();
10988    TCGv t2 = tcg_temp_new();
10989    int args, astatic;
10990
10991    switch (aregs) {
10992    case 0:
10993    case 1:
10994    case 2:
10995    case 3:
10996    case 11:
10997        args = 0;
10998        break;
10999    case 4:
11000    case 5:
11001    case 6:
11002    case 7:
11003        args = 1;
11004        break;
11005    case 8:
11006    case 9:
11007    case 10:
11008        args = 2;
11009        break;
11010    case 12:
11011    case 13:
11012        args = 3;
11013        break;
11014    case 14:
11015        args = 4;
11016        break;
11017    default:
11018        generate_exception_end(ctx, EXCP_RI);
11019        return;
11020    }
11021
11022    switch (args) {
11023    case 4:
11024        gen_base_offset_addr(ctx, t0, 29, 12);
11025        gen_load_gpr(t1, 7);
11026        tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL);
11027        /* Fall through */
11028    case 3:
11029        gen_base_offset_addr(ctx, t0, 29, 8);
11030        gen_load_gpr(t1, 6);
11031        tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL);
11032        /* Fall through */
11033    case 2:
11034        gen_base_offset_addr(ctx, t0, 29, 4);
11035        gen_load_gpr(t1, 5);
11036        tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL);
11037        /* Fall through */
11038    case 1:
11039        gen_base_offset_addr(ctx, t0, 29, 0);
11040        gen_load_gpr(t1, 4);
11041        tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL);
11042    }
11043
11044    gen_load_gpr(t0, 29);
11045
11046#define DECR_AND_STORE(reg) do {                                 \
11047        tcg_gen_movi_tl(t2, -4);                                 \
11048        gen_op_addr_add(ctx, t0, t0, t2);                        \
11049        gen_load_gpr(t1, reg);                                   \
11050        tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL); \
11051    } while (0)
11052
11053    if (do_ra) {
11054        DECR_AND_STORE(31);
11055    }
11056
11057    switch (xsregs) {
11058    case 7:
11059        DECR_AND_STORE(30);
11060        /* Fall through */
11061    case 6:
11062        DECR_AND_STORE(23);
11063        /* Fall through */
11064    case 5:
11065        DECR_AND_STORE(22);
11066        /* Fall through */
11067    case 4:
11068        DECR_AND_STORE(21);
11069        /* Fall through */
11070    case 3:
11071        DECR_AND_STORE(20);
11072        /* Fall through */
11073    case 2:
11074        DECR_AND_STORE(19);
11075        /* Fall through */
11076    case 1:
11077        DECR_AND_STORE(18);
11078    }
11079
11080    if (do_s1) {
11081        DECR_AND_STORE(17);
11082    }
11083    if (do_s0) {
11084        DECR_AND_STORE(16);
11085    }
11086
11087    switch (aregs) {
11088    case 0:
11089    case 4:
11090    case 8:
11091    case 12:
11092    case 14:
11093        astatic = 0;
11094        break;
11095    case 1:
11096    case 5:
11097    case 9:
11098    case 13:
11099        astatic = 1;
11100        break;
11101    case 2:
11102    case 6:
11103    case 10:
11104        astatic = 2;
11105        break;
11106    case 3:
11107    case 7:
11108        astatic = 3;
11109        break;
11110    case 11:
11111        astatic = 4;
11112        break;
11113    default:
11114        generate_exception_end(ctx, EXCP_RI);
11115        return;
11116    }
11117
11118    if (astatic > 0) {
11119        DECR_AND_STORE(7);
11120        if (astatic > 1) {
11121            DECR_AND_STORE(6);
11122            if (astatic > 2) {
11123                DECR_AND_STORE(5);
11124                if (astatic > 3) {
11125                    DECR_AND_STORE(4);
11126                }
11127            }
11128        }
11129    }
11130#undef DECR_AND_STORE
11131
11132    tcg_gen_movi_tl(t2, -framesize);
11133    gen_op_addr_add(ctx, cpu_gpr[29], cpu_gpr[29], t2);
11134    tcg_temp_free(t0);
11135    tcg_temp_free(t1);
11136    tcg_temp_free(t2);
11137}
11138
11139static void gen_mips16_restore (DisasContext *ctx,
11140                                int xsregs, int aregs,
11141                                int do_ra, int do_s0, int do_s1,
11142                                int framesize)
11143{
11144    int astatic;
11145    TCGv t0 = tcg_temp_new();
11146    TCGv t1 = tcg_temp_new();
11147    TCGv t2 = tcg_temp_new();
11148
11149    tcg_gen_movi_tl(t2, framesize);
11150    gen_op_addr_add(ctx, t0, cpu_gpr[29], t2);
11151
11152#define DECR_AND_LOAD(reg) do {                            \
11153        tcg_gen_movi_tl(t2, -4);                           \
11154        gen_op_addr_add(ctx, t0, t0, t2);                  \
11155        tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TESL); \
11156        gen_store_gpr(t1, reg);                            \
11157    } while (0)
11158
11159    if (do_ra) {
11160        DECR_AND_LOAD(31);
11161    }
11162
11163    switch (xsregs) {
11164    case 7:
11165        DECR_AND_LOAD(30);
11166        /* Fall through */
11167    case 6:
11168        DECR_AND_LOAD(23);
11169        /* Fall through */
11170    case 5:
11171        DECR_AND_LOAD(22);
11172        /* Fall through */
11173    case 4:
11174        DECR_AND_LOAD(21);
11175        /* Fall through */
11176    case 3:
11177        DECR_AND_LOAD(20);
11178        /* Fall through */
11179    case 2:
11180        DECR_AND_LOAD(19);
11181        /* Fall through */
11182    case 1:
11183        DECR_AND_LOAD(18);
11184    }
11185
11186    if (do_s1) {
11187        DECR_AND_LOAD(17);
11188    }
11189    if (do_s0) {
11190        DECR_AND_LOAD(16);
11191    }
11192
11193    switch (aregs) {
11194    case 0:
11195    case 4:
11196    case 8:
11197    case 12:
11198    case 14:
11199        astatic = 0;
11200        break;
11201    case 1:
11202    case 5:
11203    case 9:
11204    case 13:
11205        astatic = 1;
11206        break;
11207    case 2:
11208    case 6:
11209    case 10:
11210        astatic = 2;
11211        break;
11212    case 3:
11213    case 7:
11214        astatic = 3;
11215        break;
11216    case 11:
11217        astatic = 4;
11218        break;
11219    default:
11220        generate_exception_end(ctx, EXCP_RI);
11221        return;
11222    }
11223
11224    if (astatic > 0) {
11225        DECR_AND_LOAD(7);
11226        if (astatic > 1) {
11227            DECR_AND_LOAD(6);
11228            if (astatic > 2) {
11229                DECR_AND_LOAD(5);
11230                if (astatic > 3) {
11231                    DECR_AND_LOAD(4);
11232                }
11233            }
11234        }
11235    }
11236#undef DECR_AND_LOAD
11237
11238    tcg_gen_movi_tl(t2, framesize);
11239    gen_op_addr_add(ctx, cpu_gpr[29], cpu_gpr[29], t2);
11240    tcg_temp_free(t0);
11241    tcg_temp_free(t1);
11242    tcg_temp_free(t2);
11243}
11244
11245static void gen_addiupc (DisasContext *ctx, int rx, int imm,
11246                         int is_64_bit, int extended)
11247{
11248    TCGv t0;
11249
11250    if (extended && (ctx->hflags & MIPS_HFLAG_BMASK)) {
11251        generate_exception_end(ctx, EXCP_RI);
11252        return;
11253    }
11254
11255    t0 = tcg_temp_new();
11256
11257    tcg_gen_movi_tl(t0, pc_relative_pc(ctx));
11258    tcg_gen_addi_tl(cpu_gpr[rx], t0, imm);
11259    if (!is_64_bit) {
11260        tcg_gen_ext32s_tl(cpu_gpr[rx], cpu_gpr[rx]);
11261    }
11262
11263    tcg_temp_free(t0);
11264}
11265
11266static void gen_cache_operation(DisasContext *ctx, uint32_t op, int base,
11267                                int16_t offset)
11268{
11269    TCGv_i32 t0 = tcg_const_i32(op);
11270    TCGv t1 = tcg_temp_new();
11271    gen_base_offset_addr(ctx, t1, base, offset);
11272    gen_helper_cache(cpu_env, t1, t0);
11273}
11274
11275#if defined(TARGET_MIPS64)
11276static void decode_i64_mips16 (DisasContext *ctx,
11277                               int ry, int funct, int16_t offset,
11278                               int extended)
11279{
11280    switch (funct) {
11281    case I64_LDSP:
11282        check_insn(ctx, ISA_MIPS3);
11283        check_mips_64(ctx);
11284        offset = extended ? offset : offset << 3;
11285        gen_ld(ctx, OPC_LD, ry, 29, offset);
11286        break;
11287    case I64_SDSP:
11288        check_insn(ctx, ISA_MIPS3);
11289        check_mips_64(ctx);
11290        offset = extended ? offset : offset << 3;
11291        gen_st(ctx, OPC_SD, ry, 29, offset);
11292        break;
11293    case I64_SDRASP:
11294        check_insn(ctx, ISA_MIPS3);
11295        check_mips_64(ctx);
11296        offset = extended ? offset : (ctx->opcode & 0xff) << 3;
11297        gen_st(ctx, OPC_SD, 31, 29, offset);
11298        break;
11299    case I64_DADJSP:
11300        check_insn(ctx, ISA_MIPS3);
11301        check_mips_64(ctx);
11302        offset = extended ? offset : ((int8_t)ctx->opcode) << 3;
11303        gen_arith_imm(ctx, OPC_DADDIU, 29, 29, offset);
11304        break;
11305    case I64_LDPC:
11306        check_insn(ctx, ISA_MIPS3);
11307        check_mips_64(ctx);
11308        if (extended && (ctx->hflags & MIPS_HFLAG_BMASK)) {
11309            generate_exception_end(ctx, EXCP_RI);
11310        } else {
11311            offset = extended ? offset : offset << 3;
11312            gen_ld(ctx, OPC_LDPC, ry, 0, offset);
11313        }
11314        break;
11315    case I64_DADDIU5:
11316        check_insn(ctx, ISA_MIPS3);
11317        check_mips_64(ctx);
11318        offset = extended ? offset : ((int8_t)(offset << 3)) >> 3;
11319        gen_arith_imm(ctx, OPC_DADDIU, ry, ry, offset);
11320        break;
11321    case I64_DADDIUPC:
11322        check_insn(ctx, ISA_MIPS3);
11323        check_mips_64(ctx);
11324        offset = extended ? offset : offset << 2;
11325        gen_addiupc(ctx, ry, offset, 1, extended);
11326        break;
11327    case I64_DADDIUSP:
11328        check_insn(ctx, ISA_MIPS3);
11329        check_mips_64(ctx);
11330        offset = extended ? offset : offset << 2;
11331        gen_arith_imm(ctx, OPC_DADDIU, ry, 29, offset);
11332        break;
11333    }
11334}
11335#endif
11336
11337static int decode_extended_mips16_opc (CPUMIPSState *env, DisasContext *ctx)
11338{
11339    int extend = cpu_lduw_code(env, ctx->pc + 2);
11340    int op, rx, ry, funct, sa;
11341    int16_t imm, offset;
11342
11343    ctx->opcode = (ctx->opcode << 16) | extend;
11344    op = (ctx->opcode >> 11) & 0x1f;
11345    sa = (ctx->opcode >> 22) & 0x1f;
11346    funct = (ctx->opcode >> 8) & 0x7;
11347    rx = xlat((ctx->opcode >> 8) & 0x7);
11348    ry = xlat((ctx->opcode >> 5) & 0x7);
11349    offset = imm = (int16_t) (((ctx->opcode >> 16) & 0x1f) << 11
11350                              | ((ctx->opcode >> 21) & 0x3f) << 5
11351                              | (ctx->opcode & 0x1f));
11352
11353    /* The extended opcodes cleverly reuse the opcodes from their 16-bit
11354       counterparts.  */
11355    switch (op) {
11356    case M16_OPC_ADDIUSP:
11357        gen_arith_imm(ctx, OPC_ADDIU, rx, 29, imm);
11358        break;
11359    case M16_OPC_ADDIUPC:
11360        gen_addiupc(ctx, rx, imm, 0, 1);
11361        break;
11362    case M16_OPC_B:
11363        gen_compute_branch(ctx, OPC_BEQ, 4, 0, 0, offset << 1, 0);
11364        /* No delay slot, so just process as a normal instruction */
11365        break;
11366    case M16_OPC_BEQZ:
11367        gen_compute_branch(ctx, OPC_BEQ, 4, rx, 0, offset << 1, 0);
11368        /* No delay slot, so just process as a normal instruction */
11369        break;
11370    case M16_OPC_BNEQZ:
11371        gen_compute_branch(ctx, OPC_BNE, 4, rx, 0, offset << 1, 0);
11372        /* No delay slot, so just process as a normal instruction */
11373        break;
11374    case M16_OPC_SHIFT:
11375        switch (ctx->opcode & 0x3) {
11376        case 0x0:
11377            gen_shift_imm(ctx, OPC_SLL, rx, ry, sa);
11378            break;
11379        case 0x1:
11380#if defined(TARGET_MIPS64)
11381            check_mips_64(ctx);
11382            gen_shift_imm(ctx, OPC_DSLL, rx, ry, sa);
11383#else
11384            generate_exception_end(ctx, EXCP_RI);
11385#endif
11386            break;
11387        case 0x2:
11388            gen_shift_imm(ctx, OPC_SRL, rx, ry, sa);
11389            break;
11390        case 0x3:
11391            gen_shift_imm(ctx, OPC_SRA, rx, ry, sa);
11392            break;
11393        }
11394        break;
11395#if defined(TARGET_MIPS64)
11396    case M16_OPC_LD:
11397        check_insn(ctx, ISA_MIPS3);
11398        check_mips_64(ctx);
11399        gen_ld(ctx, OPC_LD, ry, rx, offset);
11400        break;
11401#endif
11402    case M16_OPC_RRIA:
11403        imm = ctx->opcode & 0xf;
11404        imm = imm | ((ctx->opcode >> 20) & 0x7f) << 4;
11405        imm = imm | ((ctx->opcode >> 16) & 0xf) << 11;
11406        imm = (int16_t) (imm << 1) >> 1;
11407        if ((ctx->opcode >> 4) & 0x1) {
11408#if defined(TARGET_MIPS64)
11409            check_mips_64(ctx);
11410            gen_arith_imm(ctx, OPC_DADDIU, ry, rx, imm);
11411#else
11412            generate_exception_end(ctx, EXCP_RI);
11413#endif
11414        } else {
11415            gen_arith_imm(ctx, OPC_ADDIU, ry, rx, imm);
11416        }
11417        break;
11418    case M16_OPC_ADDIU8:
11419        gen_arith_imm(ctx, OPC_ADDIU, rx, rx, imm);
11420        break;
11421    case M16_OPC_SLTI:
11422        gen_slt_imm(ctx, OPC_SLTI, 24, rx, imm);
11423        break;
11424    case M16_OPC_SLTIU:
11425        gen_slt_imm(ctx, OPC_SLTIU, 24, rx, imm);
11426        break;
11427    case M16_OPC_I8:
11428        switch (funct) {
11429        case I8_BTEQZ:
11430            gen_compute_branch(ctx, OPC_BEQ, 4, 24, 0, offset << 1, 0);
11431            break;
11432        case I8_BTNEZ:
11433            gen_compute_branch(ctx, OPC_BNE, 4, 24, 0, offset << 1, 0);
11434            break;
11435        case I8_SWRASP:
11436            gen_st(ctx, OPC_SW, 31, 29, imm);
11437            break;
11438        case I8_ADJSP:
11439            gen_arith_imm(ctx, OPC_ADDIU, 29, 29, imm);
11440            break;
11441        case I8_SVRS:
11442            check_insn(ctx, ISA_MIPS32);
11443            {
11444                int xsregs = (ctx->opcode >> 24) & 0x7;
11445                int aregs = (ctx->opcode >> 16) & 0xf;
11446                int do_ra = (ctx->opcode >> 6) & 0x1;
11447                int do_s0 = (ctx->opcode >> 5) & 0x1;
11448                int do_s1 = (ctx->opcode >> 4) & 0x1;
11449                int framesize = (((ctx->opcode >> 20) & 0xf) << 4
11450                                 | (ctx->opcode & 0xf)) << 3;
11451
11452                if (ctx->opcode & (1 << 7)) {
11453                    gen_mips16_save(ctx, xsregs, aregs,
11454                                    do_ra, do_s0, do_s1,
11455                                    framesize);
11456                } else {
11457                    gen_mips16_restore(ctx, xsregs, aregs,
11458                                       do_ra, do_s0, do_s1,
11459                                       framesize);
11460                }
11461            }
11462            break;
11463        default:
11464            generate_exception_end(ctx, EXCP_RI);
11465            break;
11466        }
11467        break;
11468    case M16_OPC_LI:
11469        tcg_gen_movi_tl(cpu_gpr[rx], (uint16_t) imm);
11470        break;
11471    case M16_OPC_CMPI:
11472        tcg_gen_xori_tl(cpu_gpr[24], cpu_gpr[rx], (uint16_t) imm);
11473        break;
11474#if defined(TARGET_MIPS64)
11475    case M16_OPC_SD:
11476        check_insn(ctx, ISA_MIPS3);
11477        check_mips_64(ctx);
11478        gen_st(ctx, OPC_SD, ry, rx, offset);
11479        break;
11480#endif
11481    case M16_OPC_LB:
11482        gen_ld(ctx, OPC_LB, ry, rx, offset);
11483        break;
11484    case M16_OPC_LH:
11485        gen_ld(ctx, OPC_LH, ry, rx, offset);
11486        break;
11487    case M16_OPC_LWSP:
11488        gen_ld(ctx, OPC_LW, rx, 29, offset);
11489        break;
11490    case M16_OPC_LW:
11491        gen_ld(ctx, OPC_LW, ry, rx, offset);
11492        break;
11493    case M16_OPC_LBU:
11494        gen_ld(ctx, OPC_LBU, ry, rx, offset);
11495        break;
11496    case M16_OPC_LHU:
11497        gen_ld(ctx, OPC_LHU, ry, rx, offset);
11498        break;
11499    case M16_OPC_LWPC:
11500        gen_ld(ctx, OPC_LWPC, rx, 0, offset);
11501        break;
11502#if defined(TARGET_MIPS64)
11503    case M16_OPC_LWU:
11504        check_insn(ctx, ISA_MIPS3);
11505        check_mips_64(ctx);
11506        gen_ld(ctx, OPC_LWU, ry, rx, offset);
11507        break;
11508#endif
11509    case M16_OPC_SB:
11510        gen_st(ctx, OPC_SB, ry, rx, offset);
11511        break;
11512    case M16_OPC_SH:
11513        gen_st(ctx, OPC_SH, ry, rx, offset);
11514        break;
11515    case M16_OPC_SWSP:
11516        gen_st(ctx, OPC_SW, rx, 29, offset);
11517        break;
11518    case M16_OPC_SW:
11519        gen_st(ctx, OPC_SW, ry, rx, offset);
11520        break;
11521#if defined(TARGET_MIPS64)
11522    case M16_OPC_I64:
11523        decode_i64_mips16(ctx, ry, funct, offset, 1);
11524        break;
11525#endif
11526    default:
11527        generate_exception_end(ctx, EXCP_RI);
11528        break;
11529    }
11530
11531    return 4;
11532}
11533
11534static inline bool is_uhi(int sdbbp_code)
11535{
11536#ifdef CONFIG_USER_ONLY
11537    return false;
11538#else
11539    return semihosting_enabled() && sdbbp_code == 1;
11540#endif
11541}
11542
11543static int decode_mips16_opc (CPUMIPSState *env, DisasContext *ctx)
11544{
11545    int rx, ry;
11546    int sa;
11547    int op, cnvt_op, op1, offset;
11548    int funct;
11549    int n_bytes;
11550
11551    op = (ctx->opcode >> 11) & 0x1f;
11552    sa = (ctx->opcode >> 2) & 0x7;
11553    sa = sa == 0 ? 8 : sa;
11554    rx = xlat((ctx->opcode >> 8) & 0x7);
11555    cnvt_op = (ctx->opcode >> 5) & 0x7;
11556    ry = xlat((ctx->opcode >> 5) & 0x7);
11557    op1 = offset = ctx->opcode & 0x1f;
11558
11559    n_bytes = 2;
11560
11561    switch (op) {
11562    case M16_OPC_ADDIUSP:
11563        {
11564            int16_t imm = ((uint8_t) ctx->opcode) << 2;
11565
11566            gen_arith_imm(ctx, OPC_ADDIU, rx, 29, imm);
11567        }
11568        break;
11569    case M16_OPC_ADDIUPC:
11570        gen_addiupc(ctx, rx, ((uint8_t) ctx->opcode) << 2, 0, 0);
11571        break;
11572    case M16_OPC_B:
11573        offset = (ctx->opcode & 0x7ff) << 1;
11574        offset = (int16_t)(offset << 4) >> 4;
11575        gen_compute_branch(ctx, OPC_BEQ, 2, 0, 0, offset, 0);
11576        /* No delay slot, so just process as a normal instruction */
11577        break;
11578    case M16_OPC_JAL:
11579        offset = cpu_lduw_code(env, ctx->pc + 2);
11580        offset = (((ctx->opcode & 0x1f) << 21)
11581                  | ((ctx->opcode >> 5) & 0x1f) << 16
11582                  | offset) << 2;
11583        op = ((ctx->opcode >> 10) & 0x1) ? OPC_JALX : OPC_JAL;
11584        gen_compute_branch(ctx, op, 4, rx, ry, offset, 2);
11585        n_bytes = 4;
11586        break;
11587    case M16_OPC_BEQZ:
11588        gen_compute_branch(ctx, OPC_BEQ, 2, rx, 0,
11589                           ((int8_t)ctx->opcode) << 1, 0);
11590        /* No delay slot, so just process as a normal instruction */
11591        break;
11592    case M16_OPC_BNEQZ:
11593        gen_compute_branch(ctx, OPC_BNE, 2, rx, 0,
11594                           ((int8_t)ctx->opcode) << 1, 0);
11595        /* No delay slot, so just process as a normal instruction */
11596        break;
11597    case M16_OPC_SHIFT:
11598        switch (ctx->opcode & 0x3) {
11599        case 0x0:
11600            gen_shift_imm(ctx, OPC_SLL, rx, ry, sa);
11601            break;
11602        case 0x1:
11603#if defined(TARGET_MIPS64)
11604            check_insn(ctx, ISA_MIPS3);
11605            check_mips_64(ctx);
11606            gen_shift_imm(ctx, OPC_DSLL, rx, ry, sa);
11607#else
11608            generate_exception_end(ctx, EXCP_RI);
11609#endif
11610            break;
11611        case 0x2:
11612            gen_shift_imm(ctx, OPC_SRL, rx, ry, sa);
11613            break;
11614        case 0x3:
11615            gen_shift_imm(ctx, OPC_SRA, rx, ry, sa);
11616            break;
11617        }
11618        break;
11619#if defined(TARGET_MIPS64)
11620    case M16_OPC_LD:
11621        check_insn(ctx, ISA_MIPS3);
11622        check_mips_64(ctx);
11623        gen_ld(ctx, OPC_LD, ry, rx, offset << 3);
11624        break;
11625#endif
11626    case M16_OPC_RRIA:
11627        {
11628            int16_t imm = (int8_t)((ctx->opcode & 0xf) << 4) >> 4;
11629
11630            if ((ctx->opcode >> 4) & 1) {
11631#if defined(TARGET_MIPS64)
11632                check_insn(ctx, ISA_MIPS3);
11633                check_mips_64(ctx);
11634                gen_arith_imm(ctx, OPC_DADDIU, ry, rx, imm);
11635#else
11636                generate_exception_end(ctx, EXCP_RI);
11637#endif
11638            } else {
11639                gen_arith_imm(ctx, OPC_ADDIU, ry, rx, imm);
11640            }
11641        }
11642        break;
11643    case M16_OPC_ADDIU8:
11644        {
11645            int16_t imm = (int8_t) ctx->opcode;
11646
11647            gen_arith_imm(ctx, OPC_ADDIU, rx, rx, imm);
11648        }
11649        break;
11650    case M16_OPC_SLTI:
11651        {
11652            int16_t imm = (uint8_t) ctx->opcode;
11653            gen_slt_imm(ctx, OPC_SLTI, 24, rx, imm);
11654        }
11655        break;
11656    case M16_OPC_SLTIU:
11657        {
11658            int16_t imm = (uint8_t) ctx->opcode;
11659            gen_slt_imm(ctx, OPC_SLTIU, 24, rx, imm);
11660        }
11661        break;
11662    case M16_OPC_I8:
11663        {
11664            int reg32;
11665
11666            funct = (ctx->opcode >> 8) & 0x7;
11667            switch (funct) {
11668            case I8_BTEQZ:
11669                gen_compute_branch(ctx, OPC_BEQ, 2, 24, 0,
11670                                   ((int8_t)ctx->opcode) << 1, 0);
11671                break;
11672            case I8_BTNEZ:
11673                gen_compute_branch(ctx, OPC_BNE, 2, 24, 0,
11674                                   ((int8_t)ctx->opcode) << 1, 0);
11675                break;
11676            case I8_SWRASP:
11677                gen_st(ctx, OPC_SW, 31, 29, (ctx->opcode & 0xff) << 2);
11678                break;
11679            case I8_ADJSP:
11680                gen_arith_imm(ctx, OPC_ADDIU, 29, 29,
11681                              ((int8_t)ctx->opcode) << 3);
11682                break;
11683            case I8_SVRS:
11684                check_insn(ctx, ISA_MIPS32);
11685                {
11686                    int do_ra = ctx->opcode & (1 << 6);
11687                    int do_s0 = ctx->opcode & (1 << 5);
11688                    int do_s1 = ctx->opcode & (1 << 4);
11689                    int framesize = ctx->opcode & 0xf;
11690
11691                    if (framesize == 0) {
11692                        framesize = 128;
11693                    } else {
11694                        framesize = framesize << 3;
11695                    }
11696
11697                    if (ctx->opcode & (1 << 7)) {
11698                        gen_mips16_save(ctx, 0, 0,
11699                                        do_ra, do_s0, do_s1, framesize);
11700                    } else {
11701                        gen_mips16_restore(ctx, 0, 0,
11702                                           do_ra, do_s0, do_s1, framesize);
11703                    }
11704                }
11705                break;
11706            case I8_MOV32R:
11707                {
11708                    int rz = xlat(ctx->opcode & 0x7);
11709
11710                    reg32 = (((ctx->opcode >> 3) & 0x3) << 3) |
11711                        ((ctx->opcode >> 5) & 0x7);
11712                    gen_arith(ctx, OPC_ADDU, reg32, rz, 0);
11713                }
11714                break;
11715            case I8_MOVR32:
11716                reg32 = ctx->opcode & 0x1f;
11717                gen_arith(ctx, OPC_ADDU, ry, reg32, 0);
11718                break;
11719            default:
11720                generate_exception_end(ctx, EXCP_RI);
11721                break;
11722            }
11723        }
11724        break;
11725    case M16_OPC_LI:
11726        {
11727            int16_t imm = (uint8_t) ctx->opcode;
11728
11729            gen_arith_imm(ctx, OPC_ADDIU, rx, 0, imm);
11730        }
11731        break;
11732    case M16_OPC_CMPI:
11733        {
11734            int16_t imm = (uint8_t) ctx->opcode;
11735            gen_logic_imm(ctx, OPC_XORI, 24, rx, imm);
11736        }
11737        break;
11738#if defined(TARGET_MIPS64)
11739    case M16_OPC_SD:
11740        check_insn(ctx, ISA_MIPS3);
11741        check_mips_64(ctx);
11742        gen_st(ctx, OPC_SD, ry, rx, offset << 3);
11743        break;
11744#endif
11745    case M16_OPC_LB:
11746        gen_ld(ctx, OPC_LB, ry, rx, offset);
11747        break;
11748    case M16_OPC_LH:
11749        gen_ld(ctx, OPC_LH, ry, rx, offset << 1);
11750        break;
11751    case M16_OPC_LWSP:
11752        gen_ld(ctx, OPC_LW, rx, 29, ((uint8_t)ctx->opcode) << 2);
11753        break;
11754    case M16_OPC_LW:
11755        gen_ld(ctx, OPC_LW, ry, rx, offset << 2);
11756        break;
11757    case M16_OPC_LBU:
11758        gen_ld(ctx, OPC_LBU, ry, rx, offset);
11759        break;
11760    case M16_OPC_LHU:
11761        gen_ld(ctx, OPC_LHU, ry, rx, offset << 1);
11762        break;
11763    case M16_OPC_LWPC:
11764        gen_ld(ctx, OPC_LWPC, rx, 0, ((uint8_t)ctx->opcode) << 2);
11765        break;
11766#if defined (TARGET_MIPS64)
11767    case M16_OPC_LWU:
11768        check_insn(ctx, ISA_MIPS3);
11769        check_mips_64(ctx);
11770        gen_ld(ctx, OPC_LWU, ry, rx, offset << 2);
11771        break;
11772#endif
11773    case M16_OPC_SB:
11774        gen_st(ctx, OPC_SB, ry, rx, offset);
11775        break;
11776    case M16_OPC_SH:
11777        gen_st(ctx, OPC_SH, ry, rx, offset << 1);
11778        break;
11779    case M16_OPC_SWSP:
11780        gen_st(ctx, OPC_SW, rx, 29, ((uint8_t)ctx->opcode) << 2);
11781        break;
11782    case M16_OPC_SW:
11783        gen_st(ctx, OPC_SW, ry, rx, offset << 2);
11784        break;
11785    case M16_OPC_RRR:
11786        {
11787            int rz = xlat((ctx->opcode >> 2) & 0x7);
11788            int mips32_op;
11789
11790            switch (ctx->opcode & 0x3) {
11791            case RRR_ADDU:
11792                mips32_op = OPC_ADDU;
11793                break;
11794            case RRR_SUBU:
11795                mips32_op = OPC_SUBU;
11796                break;
11797#if defined(TARGET_MIPS64)
11798            case RRR_DADDU:
11799                mips32_op = OPC_DADDU;
11800                check_insn(ctx, ISA_MIPS3);
11801                check_mips_64(ctx);
11802                break;
11803            case RRR_DSUBU:
11804                mips32_op = OPC_DSUBU;
11805                check_insn(ctx, ISA_MIPS3);
11806                check_mips_64(ctx);
11807                break;
11808#endif
11809            default:
11810                generate_exception_end(ctx, EXCP_RI);
11811                goto done;
11812            }
11813
11814            gen_arith(ctx, mips32_op, rz, rx, ry);
11815        done:
11816            ;
11817        }
11818        break;
11819    case M16_OPC_RR:
11820        switch (op1) {
11821        case RR_JR:
11822            {
11823                int nd = (ctx->opcode >> 7) & 0x1;
11824                int link = (ctx->opcode >> 6) & 0x1;
11825                int ra = (ctx->opcode >> 5) & 0x1;
11826
11827                if (nd) {
11828                    check_insn(ctx, ISA_MIPS32);
11829                }
11830
11831                if (link) {
11832                    op = OPC_JALR;
11833                } else {
11834                    op = OPC_JR;
11835                }
11836
11837                gen_compute_branch(ctx, op, 2, ra ? 31 : rx, 31, 0,
11838                                   (nd ? 0 : 2));
11839            }
11840            break;
11841        case RR_SDBBP:
11842            if (is_uhi(extract32(ctx->opcode, 5, 6))) {
11843                gen_helper_do_semihosting(cpu_env);
11844            } else {
11845                /* XXX: not clear which exception should be raised
11846                 *      when in debug mode...
11847                 */
11848                check_insn(ctx, ISA_MIPS32);
11849                generate_exception_end(ctx, EXCP_DBp);
11850            }
11851            break;
11852        case RR_SLT:
11853            gen_slt(ctx, OPC_SLT, 24, rx, ry);
11854            break;
11855        case RR_SLTU:
11856            gen_slt(ctx, OPC_SLTU, 24, rx, ry);
11857            break;
11858        case RR_BREAK:
11859            generate_exception_end(ctx, EXCP_BREAK);
11860            break;
11861        case RR_SLLV:
11862            gen_shift(ctx, OPC_SLLV, ry, rx, ry);
11863            break;
11864        case RR_SRLV:
11865            gen_shift(ctx, OPC_SRLV, ry, rx, ry);
11866            break;
11867        case RR_SRAV:
11868            gen_shift(ctx, OPC_SRAV, ry, rx, ry);
11869            break;
11870#if defined (TARGET_MIPS64)
11871        case RR_DSRL:
11872            check_insn(ctx, ISA_MIPS3);
11873            check_mips_64(ctx);
11874            gen_shift_imm(ctx, OPC_DSRL, ry, ry, sa);
11875            break;
11876#endif
11877        case RR_CMP:
11878            gen_logic(ctx, OPC_XOR, 24, rx, ry);
11879            break;
11880        case RR_NEG:
11881            gen_arith(ctx, OPC_SUBU, rx, 0, ry);
11882            break;
11883        case RR_AND:
11884            gen_logic(ctx, OPC_AND, rx, rx, ry);
11885            break;
11886        case RR_OR:
11887            gen_logic(ctx, OPC_OR, rx, rx, ry);
11888            break;
11889        case RR_XOR:
11890            gen_logic(ctx, OPC_XOR, rx, rx, ry);
11891            break;
11892        case RR_NOT:
11893            gen_logic(ctx, OPC_NOR, rx, ry, 0);
11894            break;
11895        case RR_MFHI:
11896            gen_HILO(ctx, OPC_MFHI, 0, rx);
11897            break;
11898        case RR_CNVT:
11899            check_insn(ctx, ISA_MIPS32);
11900            switch (cnvt_op) {
11901            case RR_RY_CNVT_ZEB:
11902                tcg_gen_ext8u_tl(cpu_gpr[rx], cpu_gpr[rx]);
11903                break;
11904            case RR_RY_CNVT_ZEH:
11905                tcg_gen_ext16u_tl(cpu_gpr[rx], cpu_gpr[rx]);
11906                break;
11907            case RR_RY_CNVT_SEB:
11908                tcg_gen_ext8s_tl(cpu_gpr[rx], cpu_gpr[rx]);
11909                break;
11910            case RR_RY_CNVT_SEH:
11911                tcg_gen_ext16s_tl(cpu_gpr[rx], cpu_gpr[rx]);
11912                break;
11913#if defined (TARGET_MIPS64)
11914            case RR_RY_CNVT_ZEW:
11915                check_insn(ctx, ISA_MIPS64);
11916                check_mips_64(ctx);
11917                tcg_gen_ext32u_tl(cpu_gpr[rx], cpu_gpr[rx]);
11918                break;
11919            case RR_RY_CNVT_SEW:
11920                check_insn(ctx, ISA_MIPS64);
11921                check_mips_64(ctx);
11922                tcg_gen_ext32s_tl(cpu_gpr[rx], cpu_gpr[rx]);
11923                break;
11924#endif
11925            default:
11926                generate_exception_end(ctx, EXCP_RI);
11927                break;
11928            }
11929            break;
11930        case RR_MFLO:
11931            gen_HILO(ctx, OPC_MFLO, 0, rx);
11932            break;
11933#if defined (TARGET_MIPS64)
11934        case RR_DSRA:
11935            check_insn(ctx, ISA_MIPS3);
11936            check_mips_64(ctx);
11937            gen_shift_imm(ctx, OPC_DSRA, ry, ry, sa);
11938            break;
11939        case RR_DSLLV:
11940            check_insn(ctx, ISA_MIPS3);
11941            check_mips_64(ctx);
11942            gen_shift(ctx, OPC_DSLLV, ry, rx, ry);
11943            break;
11944        case RR_DSRLV:
11945            check_insn(ctx, ISA_MIPS3);
11946            check_mips_64(ctx);
11947            gen_shift(ctx, OPC_DSRLV, ry, rx, ry);
11948            break;
11949        case RR_DSRAV:
11950            check_insn(ctx, ISA_MIPS3);
11951            check_mips_64(ctx);
11952            gen_shift(ctx, OPC_DSRAV, ry, rx, ry);
11953            break;
11954#endif
11955        case RR_MULT:
11956            gen_muldiv(ctx, OPC_MULT, 0, rx, ry);
11957            break;
11958        case RR_MULTU:
11959            gen_muldiv(ctx, OPC_MULTU, 0, rx, ry);
11960            break;
11961        case RR_DIV:
11962            gen_muldiv(ctx, OPC_DIV, 0, rx, ry);
11963            break;
11964        case RR_DIVU:
11965            gen_muldiv(ctx, OPC_DIVU, 0, rx, ry);
11966            break;
11967#if defined (TARGET_MIPS64)
11968        case RR_DMULT:
11969            check_insn(ctx, ISA_MIPS3);
11970            check_mips_64(ctx);
11971            gen_muldiv(ctx, OPC_DMULT, 0, rx, ry);
11972            break;
11973        case RR_DMULTU:
11974            check_insn(ctx, ISA_MIPS3);
11975            check_mips_64(ctx);
11976            gen_muldiv(ctx, OPC_DMULTU, 0, rx, ry);
11977            break;
11978        case RR_DDIV:
11979            check_insn(ctx, ISA_MIPS3);
11980            check_mips_64(ctx);
11981            gen_muldiv(ctx, OPC_DDIV, 0, rx, ry);
11982            break;
11983        case RR_DDIVU:
11984            check_insn(ctx, ISA_MIPS3);
11985            check_mips_64(ctx);
11986            gen_muldiv(ctx, OPC_DDIVU, 0, rx, ry);
11987            break;
11988#endif
11989        default:
11990            generate_exception_end(ctx, EXCP_RI);
11991            break;
11992        }
11993        break;
11994    case M16_OPC_EXTEND:
11995        decode_extended_mips16_opc(env, ctx);
11996        n_bytes = 4;
11997        break;
11998#if defined(TARGET_MIPS64)
11999    case M16_OPC_I64:
12000        funct = (ctx->opcode >> 8) & 0x7;
12001        decode_i64_mips16(ctx, ry, funct, offset, 0);
12002        break;
12003#endif
12004    default:
12005        generate_exception_end(ctx, EXCP_RI);
12006        break;
12007    }
12008
12009    return n_bytes;
12010}
12011
12012/* microMIPS extension to MIPS32/MIPS64 */
12013
12014/*
12015 * microMIPS32/microMIPS64 major opcodes
12016 *
12017 * 1. MIPS Architecture for Programmers Volume II-B:
12018 *      The microMIPS32 Instruction Set (Revision 3.05)
12019 *
12020 *    Table 6.2 microMIPS32 Encoding of Major Opcode Field
12021 *
12022 * 2. MIPS Architecture For Programmers Volume II-A:
12023 *      The MIPS64 Instruction Set (Revision 3.51)
12024 */
12025
12026enum {
12027    POOL32A = 0x00,
12028    POOL16A = 0x01,
12029    LBU16 = 0x02,
12030    MOVE16 = 0x03,
12031    ADDI32 = 0x04,
12032    R6_LUI = 0x04,
12033    AUI = 0x04,
12034    LBU32 = 0x05,
12035    SB32 = 0x06,
12036    LB32 = 0x07,
12037
12038    POOL32B = 0x08,
12039    POOL16B = 0x09,
12040    LHU16 = 0x0a,
12041    ANDI16 = 0x0b,
12042    ADDIU32 = 0x0c,
12043    LHU32 = 0x0d,
12044    SH32 = 0x0e,
12045    LH32 = 0x0f,
12046
12047    POOL32I = 0x10,
12048    POOL16C = 0x11,
12049    LWSP16 = 0x12,
12050    POOL16D = 0x13,
12051    ORI32 = 0x14,
12052    POOL32F = 0x15,
12053    POOL32S = 0x16,  /* MIPS64 */
12054    DADDIU32 = 0x17, /* MIPS64 */
12055
12056    POOL32C = 0x18,
12057    LWGP16 = 0x19,
12058    LW16 = 0x1a,
12059    POOL16E = 0x1b,
12060    XORI32 = 0x1c,
12061    JALS32 = 0x1d,
12062    BOVC = 0x1d,
12063    BEQC = 0x1d,
12064    BEQZALC = 0x1d,
12065    ADDIUPC = 0x1e,
12066    PCREL = 0x1e,
12067    BNVC = 0x1f,
12068    BNEC = 0x1f,
12069    BNEZALC = 0x1f,
12070
12071    R6_BEQZC = 0x20,
12072    JIC = 0x20,
12073    POOL16F = 0x21,
12074    SB16 = 0x22,
12075    BEQZ16 = 0x23,
12076    BEQZC16 = 0x23,
12077    SLTI32 = 0x24,
12078    BEQ32 = 0x25,
12079    BC = 0x25,
12080    SWC132 = 0x26,
12081    LWC132 = 0x27,
12082
12083    /* 0x29 is reserved */
12084    RES_29 = 0x29,
12085    R6_BNEZC = 0x28,
12086    JIALC = 0x28,
12087    SH16 = 0x2a,
12088    BNEZ16 = 0x2b,
12089    BNEZC16 = 0x2b,
12090    SLTIU32 = 0x2c,
12091    BNE32 = 0x2d,
12092    BALC = 0x2d,
12093    SDC132 = 0x2e,
12094    LDC132 = 0x2f,
12095
12096    /* 0x31 is reserved */
12097    RES_31 = 0x31,
12098    BLEZALC = 0x30,
12099    BGEZALC = 0x30,
12100    BGEUC = 0x30,
12101    SWSP16 = 0x32,
12102    B16 = 0x33,
12103    BC16 = 0x33,
12104    ANDI32 = 0x34,
12105    J32 = 0x35,
12106    BGTZC = 0x35,
12107    BLTZC = 0x35,
12108    BLTC = 0x35,
12109    SD32 = 0x36, /* MIPS64 */
12110    LD32 = 0x37, /* MIPS64 */
12111
12112    /* 0x39 is reserved */
12113    RES_39 = 0x39,
12114    BGTZALC = 0x38,
12115    BLTZALC = 0x38,
12116    BLTUC = 0x38,
12117    SW16 = 0x3a,
12118    LI16 = 0x3b,
12119    JALX32 = 0x3c,
12120    JAL32 = 0x3d,
12121    BLEZC = 0x3d,
12122    BGEZC = 0x3d,
12123    BGEC = 0x3d,
12124    SW32 = 0x3e,
12125    LW32 = 0x3f
12126};
12127
12128/* PCREL Instructions perform PC-Relative address calculation. bits 20..16 */
12129enum {
12130    ADDIUPC_00 = 0x00,
12131    ADDIUPC_07 = 0x07,
12132    AUIPC = 0x1e,
12133    ALUIPC = 0x1f,
12134    LWPC_08 = 0x08,
12135    LWPC_0F = 0x0F,
12136};
12137
12138/* POOL32A encoding of minor opcode field */
12139
12140enum {
12141    /* These opcodes are distinguished only by bits 9..6; those bits are
12142     * what are recorded below. */
12143    SLL32 = 0x0,
12144    SRL32 = 0x1,
12145    SRA = 0x2,
12146    ROTR = 0x3,
12147    SELEQZ = 0x5,
12148    SELNEZ = 0x6,
12149    R6_RDHWR = 0x7,
12150
12151    SLLV = 0x0,
12152    SRLV = 0x1,
12153    SRAV = 0x2,
12154    ROTRV = 0x3,
12155    ADD = 0x4,
12156    ADDU32 = 0x5,
12157    SUB = 0x6,
12158    SUBU32 = 0x7,
12159    MUL = 0x8,
12160    AND = 0x9,
12161    OR32 = 0xa,
12162    NOR = 0xb,
12163    XOR32 = 0xc,
12164    SLT = 0xd,
12165    SLTU = 0xe,
12166
12167    MOVN = 0x0,
12168    R6_MUL  = 0x0,
12169    MOVZ = 0x1,
12170    MUH  = 0x1,
12171    MULU = 0x2,
12172    MUHU = 0x3,
12173    LWXS = 0x4,
12174    R6_DIV  = 0x4,
12175    MOD  = 0x5,
12176    R6_DIVU = 0x6,
12177    MODU = 0x7,
12178
12179    /* The following can be distinguished by their lower 6 bits. */
12180    BREAK32 = 0x07,
12181    INS = 0x0c,
12182    LSA = 0x0f,
12183    ALIGN = 0x1f,
12184    EXT = 0x2c,
12185    POOL32AXF = 0x3c,
12186    SIGRIE = 0x3f
12187};
12188
12189/* POOL32AXF encoding of minor opcode field extension */
12190
12191/*
12192 * 1. MIPS Architecture for Programmers Volume II-B:
12193 *      The microMIPS32 Instruction Set (Revision 3.05)
12194 *
12195 *    Table 6.5 POOL32Axf Encoding of Minor Opcode Extension Field
12196 *
12197 * 2. MIPS Architecture for Programmers VolumeIV-e:
12198 *      The MIPS DSP Application-Specific Extension
12199 *        to the microMIPS32 Architecture (Revision 2.34)
12200 *
12201 *    Table 5.5 POOL32Axf Encoding of Minor Opcode Extension Field
12202 */
12203
12204enum {
12205    /* bits 11..6 */
12206    TEQ = 0x00,
12207    TGE = 0x08,
12208    TGEU = 0x10,
12209    TLT = 0x20,
12210    TLTU = 0x28,
12211    TNE = 0x30,
12212
12213    MFC0 = 0x03,
12214    MTC0 = 0x0b,
12215
12216    /* begin of microMIPS32 DSP */
12217
12218    /* bits 13..12 for 0x01 */
12219    MFHI_ACC = 0x0,
12220    MFLO_ACC = 0x1,
12221    MTHI_ACC = 0x2,
12222    MTLO_ACC = 0x3,
12223
12224    /* bits 13..12 for 0x2a */
12225    MADD_ACC = 0x0,
12226    MADDU_ACC = 0x1,
12227    MSUB_ACC = 0x2,
12228    MSUBU_ACC = 0x3,
12229
12230    /* bits 13..12 for 0x32 */
12231    MULT_ACC = 0x0,
12232    MULTU_ACC = 0x1,
12233
12234    /* end of microMIPS32 DSP */
12235
12236    /* bits 15..12 for 0x2c */
12237    BITSWAP = 0x0,
12238    SEB = 0x2,
12239    SEH = 0x3,
12240    CLO = 0x4,
12241    CLZ = 0x5,
12242    RDHWR = 0x6,
12243    WSBH = 0x7,
12244    MULT = 0x8,
12245    MULTU = 0x9,
12246    DIV = 0xa,
12247    DIVU = 0xb,
12248    MADD = 0xc,
12249    MADDU = 0xd,
12250    MSUB = 0xe,
12251    MSUBU = 0xf,
12252
12253    /* bits 15..12 for 0x34 */
12254    MFC2 = 0x4,
12255    MTC2 = 0x5,
12256    MFHC2 = 0x8,
12257    MTHC2 = 0x9,
12258    CFC2 = 0xc,
12259    CTC2 = 0xd,
12260
12261    /* bits 15..12 for 0x3c */
12262    JALR = 0x0,
12263    JR = 0x0,                   /* alias */
12264    JALRC = 0x0,
12265    JRC = 0x0,
12266    JALR_HB = 0x1,
12267    JALRC_HB = 0x1,
12268    JALRS = 0x4,
12269    JALRS_HB = 0x5,
12270
12271    /* bits 15..12 for 0x05 */
12272    RDPGPR = 0xe,
12273    WRPGPR = 0xf,
12274
12275    /* bits 15..12 for 0x0d */
12276    TLBP = 0x0,
12277    TLBR = 0x1,
12278    TLBWI = 0x2,
12279    TLBWR = 0x3,
12280    TLBINV = 0x4,
12281    TLBINVF = 0x5,
12282    WAIT = 0x9,
12283    IRET = 0xd,
12284    DERET = 0xe,
12285    ERET = 0xf,
12286
12287    /* bits 15..12 for 0x15 */
12288    DMT = 0x0,
12289    DVPE = 0x1,
12290    EMT = 0x2,
12291    EVPE = 0x3,
12292
12293    /* bits 15..12 for 0x1d */
12294    DI = 0x4,
12295    EI = 0x5,
12296
12297    /* bits 15..12 for 0x2d */
12298    SYNC = 0x6,
12299    SYSCALL = 0x8,
12300    SDBBP = 0xd,
12301
12302    /* bits 15..12 for 0x35 */
12303    MFHI32 = 0x0,
12304    MFLO32 = 0x1,
12305    MTHI32 = 0x2,
12306    MTLO32 = 0x3,
12307};
12308
12309/* POOL32B encoding of minor opcode field (bits 15..12) */
12310
12311enum {
12312    LWC2 = 0x0,
12313    LWP = 0x1,
12314    LDP = 0x4,
12315    LWM32 = 0x5,
12316    CACHE = 0x6,
12317    LDM = 0x7,
12318    SWC2 = 0x8,
12319    SWP = 0x9,
12320    SDP = 0xc,
12321    SWM32 = 0xd,
12322    SDM = 0xf
12323};
12324
12325/* POOL32C encoding of minor opcode field (bits 15..12) */
12326
12327enum {
12328    LWL = 0x0,
12329    SWL = 0x8,
12330    LWR = 0x1,
12331    SWR = 0x9,
12332    PREF = 0x2,
12333    /* 0xa is reserved */
12334    LL = 0x3,
12335    SC = 0xb,
12336    LDL = 0x4,
12337    SDL = 0xc,
12338    LDR = 0x5,
12339    SDR = 0xd,
12340    /* 0x6 is reserved */
12341    LWU = 0xe,
12342    LLD = 0x7,
12343    SCD = 0xf
12344};
12345
12346/* POOL32F encoding of minor opcode field (bits 5..0) */
12347
12348enum {
12349    /* These are the bit 7..6 values */
12350    ADD_FMT = 0x0,
12351
12352    SUB_FMT = 0x1,
12353
12354    MUL_FMT = 0x2,
12355
12356    DIV_FMT = 0x3,
12357
12358    /* These are the bit 8..6 values */
12359    MOVN_FMT = 0x0,
12360    RSQRT2_FMT = 0x0,
12361    MOVF_FMT = 0x0,
12362    RINT_FMT = 0x0,
12363    SELNEZ_FMT = 0x0,
12364
12365    MOVZ_FMT = 0x1,
12366    LWXC1 = 0x1,
12367    MOVT_FMT = 0x1,
12368    CLASS_FMT = 0x1,
12369    SELEQZ_FMT = 0x1,
12370
12371    PLL_PS = 0x2,
12372    SWXC1 = 0x2,
12373    SEL_FMT = 0x2,
12374
12375    PLU_PS = 0x3,
12376    LDXC1 = 0x3,
12377
12378    MOVN_FMT_04 = 0x4,
12379    PUL_PS = 0x4,
12380    SDXC1 = 0x4,
12381    RECIP2_FMT = 0x4,
12382
12383    MOVZ_FMT_05 = 0x05,
12384    PUU_PS = 0x5,
12385    LUXC1 = 0x5,
12386
12387    CVT_PS_S = 0x6,
12388    SUXC1 = 0x6,
12389    ADDR_PS = 0x6,
12390    PREFX = 0x6,
12391    MADDF_FMT = 0x6,
12392
12393    MULR_PS = 0x7,
12394    MSUBF_FMT = 0x7,
12395
12396    MADD_S = 0x01,
12397    MADD_D = 0x09,
12398    MADD_PS = 0x11,
12399    ALNV_PS = 0x19,
12400    MSUB_S = 0x21,
12401    MSUB_D = 0x29,
12402    MSUB_PS = 0x31,
12403
12404    NMADD_S = 0x02,
12405    NMADD_D = 0x0a,
12406    NMADD_PS = 0x12,
12407    NMSUB_S = 0x22,
12408    NMSUB_D = 0x2a,
12409    NMSUB_PS = 0x32,
12410
12411    MIN_FMT = 0x3,
12412    MAX_FMT = 0xb,
12413    MINA_FMT = 0x23,
12414    MAXA_FMT = 0x2b,
12415    POOL32FXF = 0x3b,
12416
12417    CABS_COND_FMT = 0x1c,              /* MIPS3D */
12418    C_COND_FMT = 0x3c,
12419
12420    CMP_CONDN_S = 0x5,
12421    CMP_CONDN_D = 0x15
12422};
12423
12424/* POOL32Fxf encoding of minor opcode extension field */
12425
12426enum {
12427    CVT_L = 0x04,
12428    RSQRT_FMT = 0x08,
12429    FLOOR_L = 0x0c,
12430    CVT_PW_PS = 0x1c,
12431    CVT_W = 0x24,
12432    SQRT_FMT = 0x28,
12433    FLOOR_W = 0x2c,
12434    CVT_PS_PW = 0x3c,
12435    CFC1 = 0x40,
12436    RECIP_FMT = 0x48,
12437    CEIL_L = 0x4c,
12438    CTC1 = 0x60,
12439    CEIL_W = 0x6c,
12440    MFC1 = 0x80,
12441    CVT_S_PL = 0x84,
12442    TRUNC_L = 0x8c,
12443    MTC1 = 0xa0,
12444    CVT_S_PU = 0xa4,
12445    TRUNC_W = 0xac,
12446    MFHC1 = 0xc0,
12447    ROUND_L = 0xcc,
12448    MTHC1 = 0xe0,
12449    ROUND_W = 0xec,
12450
12451    MOV_FMT = 0x01,
12452    MOVF = 0x05,
12453    ABS_FMT = 0x0d,
12454    RSQRT1_FMT = 0x1d,
12455    MOVT = 0x25,
12456    NEG_FMT = 0x2d,
12457    CVT_D = 0x4d,
12458    RECIP1_FMT = 0x5d,
12459    CVT_S = 0x6d
12460};
12461
12462/* POOL32I encoding of minor opcode field (bits 25..21) */
12463
12464enum {
12465    BLTZ = 0x00,
12466    BLTZAL = 0x01,
12467    BGEZ = 0x02,
12468    BGEZAL = 0x03,
12469    BLEZ = 0x04,
12470    BNEZC = 0x05,
12471    BGTZ = 0x06,
12472    BEQZC = 0x07,
12473    TLTI = 0x08,
12474    BC1EQZC = 0x08,
12475    TGEI = 0x09,
12476    BC1NEZC = 0x09,
12477    TLTIU = 0x0a,
12478    BC2EQZC = 0x0a,
12479    TGEIU = 0x0b,
12480    BC2NEZC = 0x0a,
12481    TNEI = 0x0c,
12482    R6_SYNCI = 0x0c,
12483    LUI = 0x0d,
12484    TEQI = 0x0e,
12485    SYNCI = 0x10,
12486    BLTZALS = 0x11,
12487    BGEZALS = 0x13,
12488    BC2F = 0x14,
12489    BC2T = 0x15,
12490    BPOSGE64 = 0x1a,
12491    BPOSGE32 = 0x1b,
12492    /* These overlap and are distinguished by bit16 of the instruction */
12493    BC1F = 0x1c,
12494    BC1T = 0x1d,
12495    BC1ANY2F = 0x1c,
12496    BC1ANY2T = 0x1d,
12497    BC1ANY4F = 0x1e,
12498    BC1ANY4T = 0x1f
12499};
12500
12501/* POOL16A encoding of minor opcode field */
12502
12503enum {
12504    ADDU16 = 0x0,
12505    SUBU16 = 0x1
12506};
12507
12508/* POOL16B encoding of minor opcode field */
12509
12510enum {
12511    SLL16 = 0x0,
12512    SRL16 = 0x1
12513};
12514
12515/* POOL16C encoding of minor opcode field */
12516
12517enum {
12518    NOT16 = 0x00,
12519    XOR16 = 0x04,
12520    AND16 = 0x08,
12521    OR16 = 0x0c,
12522    LWM16 = 0x10,
12523    SWM16 = 0x14,
12524    JR16 = 0x18,
12525    JRC16 = 0x1a,
12526    JALR16 = 0x1c,
12527    JALR16S = 0x1e,
12528    MFHI16 = 0x20,
12529    MFLO16 = 0x24,
12530    BREAK16 = 0x28,
12531    SDBBP16 = 0x2c,
12532    JRADDIUSP = 0x30
12533};
12534
12535/* R6 POOL16C encoding of minor opcode field (bits 0..5) */
12536
12537enum {
12538    R6_NOT16    = 0x00,
12539    R6_AND16    = 0x01,
12540    R6_LWM16    = 0x02,
12541    R6_JRC16    = 0x03,
12542    MOVEP       = 0x04,
12543    MOVEP_07    = 0x07,
12544    R6_XOR16    = 0x08,
12545    R6_OR16     = 0x09,
12546    R6_SWM16    = 0x0a,
12547    JALRC16     = 0x0b,
12548    MOVEP_0C    = 0x0c,
12549    MOVEP_0F    = 0x0f,
12550    JRCADDIUSP  = 0x13,
12551    R6_BREAK16  = 0x1b,
12552    R6_SDBBP16  = 0x3b
12553};
12554
12555/* POOL16D encoding of minor opcode field */
12556
12557enum {
12558    ADDIUS5 = 0x0,
12559    ADDIUSP = 0x1
12560};
12561
12562/* POOL16E encoding of minor opcode field */
12563
12564enum {
12565    ADDIUR2 = 0x0,
12566    ADDIUR1SP = 0x1
12567};
12568
12569static int mmreg (int r)
12570{
12571    static const int map[] = { 16, 17, 2, 3, 4, 5, 6, 7 };
12572
12573    return map[r];
12574}
12575
12576/* Used for 16-bit store instructions.  */
12577static int mmreg2 (int r)
12578{
12579    static const int map[] = { 0, 17, 2, 3, 4, 5, 6, 7 };
12580
12581    return map[r];
12582}
12583
12584#define uMIPS_RD(op) ((op >> 7) & 0x7)
12585#define uMIPS_RS(op) ((op >> 4) & 0x7)
12586#define uMIPS_RS2(op) uMIPS_RS(op)
12587#define uMIPS_RS1(op) ((op >> 1) & 0x7)
12588#define uMIPS_RD5(op) ((op >> 5) & 0x1f)
12589#define uMIPS_RS5(op) (op & 0x1f)
12590
12591/* Signed immediate */
12592#define SIMM(op, start, width)                                          \
12593    ((int32_t)(((op >> start) & ((~0U) >> (32-width)))                 \
12594               << (32-width))                                           \
12595     >> (32-width))
12596/* Zero-extended immediate */
12597#define ZIMM(op, start, width) ((op >> start) & ((~0U) >> (32-width)))
12598
12599static void gen_addiur1sp(DisasContext *ctx)
12600{
12601    int rd = mmreg(uMIPS_RD(ctx->opcode));
12602
12603    gen_arith_imm(ctx, OPC_ADDIU, rd, 29, ((ctx->opcode >> 1) & 0x3f) << 2);
12604}
12605
12606static void gen_addiur2(DisasContext *ctx)
12607{
12608    static const int decoded_imm[] = { 1, 4, 8, 12, 16, 20, 24, -1 };
12609    int rd = mmreg(uMIPS_RD(ctx->opcode));
12610    int rs = mmreg(uMIPS_RS(ctx->opcode));
12611
12612    gen_arith_imm(ctx, OPC_ADDIU, rd, rs, decoded_imm[ZIMM(ctx->opcode, 1, 3)]);
12613}
12614
12615static void gen_addiusp(DisasContext *ctx)
12616{
12617    int encoded = ZIMM(ctx->opcode, 1, 9);
12618    int decoded;
12619
12620    if (encoded <= 1) {
12621        decoded = 256 + encoded;
12622    } else if (encoded <= 255) {
12623        decoded = encoded;
12624    } else if (encoded <= 509) {
12625        decoded = encoded - 512;
12626    } else {
12627        decoded = encoded - 768;
12628    }
12629
12630    gen_arith_imm(ctx, OPC_ADDIU, 29, 29, decoded << 2);
12631}
12632
12633static void gen_addius5(DisasContext *ctx)
12634{
12635    int imm = SIMM(ctx->opcode, 1, 4);
12636    int rd = (ctx->opcode >> 5) & 0x1f;
12637
12638    gen_arith_imm(ctx, OPC_ADDIU, rd, rd, imm);
12639}
12640
12641static void gen_andi16(DisasContext *ctx)
12642{
12643    static const int decoded_imm[] = { 128, 1, 2, 3, 4, 7, 8, 15, 16,
12644                                 31, 32, 63, 64, 255, 32768, 65535 };
12645    int rd = mmreg(uMIPS_RD(ctx->opcode));
12646    int rs = mmreg(uMIPS_RS(ctx->opcode));
12647    int encoded = ZIMM(ctx->opcode, 0, 4);
12648
12649    gen_logic_imm(ctx, OPC_ANDI, rd, rs, decoded_imm[encoded]);
12650}
12651
12652static void gen_ldst_multiple (DisasContext *ctx, uint32_t opc, int reglist,
12653                               int base, int16_t offset)
12654{
12655    TCGv t0, t1;
12656    TCGv_i32 t2;
12657
12658    if (ctx->hflags & MIPS_HFLAG_BMASK) {
12659        generate_exception_end(ctx, EXCP_RI);
12660        return;
12661    }
12662
12663    t0 = tcg_temp_new();
12664
12665    gen_base_offset_addr(ctx, t0, base, offset);
12666
12667    t1 = tcg_const_tl(reglist);
12668    t2 = tcg_const_i32(ctx->mem_idx);
12669
12670    save_cpu_state(ctx, 1);
12671    switch (opc) {
12672    case LWM32:
12673        gen_helper_lwm(cpu_env, t0, t1, t2);
12674        break;
12675    case SWM32:
12676        gen_helper_swm(cpu_env, t0, t1, t2);
12677        break;
12678#ifdef TARGET_MIPS64
12679    case LDM:
12680        gen_helper_ldm(cpu_env, t0, t1, t2);
12681        break;
12682    case SDM:
12683        gen_helper_sdm(cpu_env, t0, t1, t2);
12684        break;
12685#endif
12686    }
12687    tcg_temp_free(t0);
12688    tcg_temp_free(t1);
12689    tcg_temp_free_i32(t2);
12690}
12691
12692
12693static void gen_pool16c_insn(DisasContext *ctx)
12694{
12695    int rd = mmreg((ctx->opcode >> 3) & 0x7);
12696    int rs = mmreg(ctx->opcode & 0x7);
12697
12698    switch (((ctx->opcode) >> 4) & 0x3f) {
12699    case NOT16 + 0:
12700    case NOT16 + 1:
12701    case NOT16 + 2:
12702    case NOT16 + 3:
12703        gen_logic(ctx, OPC_NOR, rd, rs, 0);
12704        break;
12705    case XOR16 + 0:
12706    case XOR16 + 1:
12707    case XOR16 + 2:
12708    case XOR16 + 3:
12709        gen_logic(ctx, OPC_XOR, rd, rd, rs);
12710        break;
12711    case AND16 + 0:
12712    case AND16 + 1:
12713    case AND16 + 2:
12714    case AND16 + 3:
12715        gen_logic(ctx, OPC_AND, rd, rd, rs);
12716        break;
12717    case OR16 + 0:
12718    case OR16 + 1:
12719    case OR16 + 2:
12720    case OR16 + 3:
12721        gen_logic(ctx, OPC_OR, rd, rd, rs);
12722        break;
12723    case LWM16 + 0:
12724    case LWM16 + 1:
12725    case LWM16 + 2:
12726    case LWM16 + 3:
12727        {
12728            static const int lwm_convert[] = { 0x11, 0x12, 0x13, 0x14 };
12729            int offset = ZIMM(ctx->opcode, 0, 4);
12730
12731            gen_ldst_multiple(ctx, LWM32, lwm_convert[(ctx->opcode >> 4) & 0x3],
12732                              29, offset << 2);
12733        }
12734        break;
12735    case SWM16 + 0:
12736    case SWM16 + 1:
12737    case SWM16 + 2:
12738    case SWM16 + 3:
12739        {
12740            static const int swm_convert[] = { 0x11, 0x12, 0x13, 0x14 };
12741            int offset = ZIMM(ctx->opcode, 0, 4);
12742
12743            gen_ldst_multiple(ctx, SWM32, swm_convert[(ctx->opcode >> 4) & 0x3],
12744                              29, offset << 2);
12745        }
12746        break;
12747    case JR16 + 0:
12748    case JR16 + 1:
12749        {
12750            int reg = ctx->opcode & 0x1f;
12751
12752            gen_compute_branch(ctx, OPC_JR, 2, reg, 0, 0, 4);
12753        }
12754        break;
12755    case JRC16 + 0:
12756    case JRC16 + 1:
12757        {
12758            int reg = ctx->opcode & 0x1f;
12759            gen_compute_branch(ctx, OPC_JR, 2, reg, 0, 0, 0);
12760            /* Let normal delay slot handling in our caller take us
12761               to the branch target.  */
12762        }
12763        break;
12764    case JALR16 + 0:
12765    case JALR16 + 1:
12766        gen_compute_branch(ctx, OPC_JALR, 2, ctx->opcode & 0x1f, 31, 0, 4);
12767        ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
12768        break;
12769    case JALR16S + 0:
12770    case JALR16S + 1:
12771        gen_compute_branch(ctx, OPC_JALR, 2, ctx->opcode & 0x1f, 31, 0, 2);
12772        ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
12773        break;
12774    case MFHI16 + 0:
12775    case MFHI16 + 1:
12776        gen_HILO(ctx, OPC_MFHI, 0, uMIPS_RS5(ctx->opcode));
12777        break;
12778    case MFLO16 + 0:
12779    case MFLO16 + 1:
12780        gen_HILO(ctx, OPC_MFLO, 0, uMIPS_RS5(ctx->opcode));
12781        break;
12782    case BREAK16:
12783        generate_exception_end(ctx, EXCP_BREAK);
12784        break;
12785    case SDBBP16:
12786        if (is_uhi(extract32(ctx->opcode, 0, 4))) {
12787            gen_helper_do_semihosting(cpu_env);
12788        } else {
12789            /* XXX: not clear which exception should be raised
12790             *      when in debug mode...
12791             */
12792            check_insn(ctx, ISA_MIPS32);
12793            generate_exception_end(ctx, EXCP_DBp);
12794        }
12795        break;
12796    case JRADDIUSP + 0:
12797    case JRADDIUSP + 1:
12798        {
12799            int imm = ZIMM(ctx->opcode, 0, 5);
12800            gen_compute_branch(ctx, OPC_JR, 2, 31, 0, 0, 0);
12801            gen_arith_imm(ctx, OPC_ADDIU, 29, 29, imm << 2);
12802            /* Let normal delay slot handling in our caller take us
12803               to the branch target.  */
12804        }
12805        break;
12806    default:
12807        generate_exception_end(ctx, EXCP_RI);
12808        break;
12809    }
12810}
12811
12812static inline void gen_movep(DisasContext *ctx, int enc_dest, int enc_rt,
12813                             int enc_rs)
12814{
12815    int rd, rs, re, rt;
12816    static const int rd_enc[] = { 5, 5, 6, 4, 4, 4, 4, 4 };
12817    static const int re_enc[] = { 6, 7, 7, 21, 22, 5, 6, 7 };
12818    static const int rs_rt_enc[] = { 0, 17, 2, 3, 16, 18, 19, 20 };
12819    rd = rd_enc[enc_dest];
12820    re = re_enc[enc_dest];
12821    rs = rs_rt_enc[enc_rs];
12822    rt = rs_rt_enc[enc_rt];
12823    if (rs) {
12824        tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
12825    } else {
12826        tcg_gen_movi_tl(cpu_gpr[rd], 0);
12827    }
12828    if (rt) {
12829        tcg_gen_mov_tl(cpu_gpr[re], cpu_gpr[rt]);
12830    } else {
12831        tcg_gen_movi_tl(cpu_gpr[re], 0);
12832    }
12833}
12834
12835static void gen_pool16c_r6_insn(DisasContext *ctx)
12836{
12837    int rt = mmreg((ctx->opcode >> 7) & 0x7);
12838    int rs = mmreg((ctx->opcode >> 4) & 0x7);
12839
12840    switch (ctx->opcode & 0xf) {
12841    case R6_NOT16:
12842        gen_logic(ctx, OPC_NOR, rt, rs, 0);
12843        break;
12844    case R6_AND16:
12845        gen_logic(ctx, OPC_AND, rt, rt, rs);
12846        break;
12847    case R6_LWM16:
12848        {
12849            int lwm_converted = 0x11 + extract32(ctx->opcode, 8, 2);
12850            int offset = extract32(ctx->opcode, 4, 4);
12851            gen_ldst_multiple(ctx, LWM32, lwm_converted, 29, offset << 2);
12852        }
12853        break;
12854    case R6_JRC16: /* JRCADDIUSP */
12855        if ((ctx->opcode >> 4) & 1) {
12856            /* JRCADDIUSP */
12857            int imm = extract32(ctx->opcode, 5, 5);
12858            gen_compute_branch(ctx, OPC_JR, 2, 31, 0, 0, 0);
12859            gen_arith_imm(ctx, OPC_ADDIU, 29, 29, imm << 2);
12860        } else {
12861            /* JRC16 */
12862            int rs = extract32(ctx->opcode, 5, 5);
12863            gen_compute_branch(ctx, OPC_JR, 2, rs, 0, 0, 0);
12864        }
12865        break;
12866    case MOVEP ... MOVEP_07:
12867    case MOVEP_0C ... MOVEP_0F:
12868        {
12869            int enc_dest = uMIPS_RD(ctx->opcode);
12870            int enc_rt = uMIPS_RS2(ctx->opcode);
12871            int enc_rs = (ctx->opcode & 3) | ((ctx->opcode >> 1) & 4);
12872            gen_movep(ctx, enc_dest, enc_rt, enc_rs);
12873        }
12874        break;
12875    case R6_XOR16:
12876        gen_logic(ctx, OPC_XOR, rt, rt, rs);
12877        break;
12878    case R6_OR16:
12879        gen_logic(ctx, OPC_OR, rt, rt, rs);
12880        break;
12881    case R6_SWM16:
12882        {
12883            int swm_converted = 0x11 + extract32(ctx->opcode, 8, 2);
12884            int offset = extract32(ctx->opcode, 4, 4);
12885            gen_ldst_multiple(ctx, SWM32, swm_converted, 29, offset << 2);
12886        }
12887        break;
12888    case JALRC16: /* BREAK16, SDBBP16 */
12889        switch (ctx->opcode & 0x3f) {
12890        case JALRC16:
12891        case JALRC16 + 0x20:
12892            /* JALRC16 */
12893            gen_compute_branch(ctx, OPC_JALR, 2, (ctx->opcode >> 5) & 0x1f,
12894                               31, 0, 0);
12895            break;
12896        case R6_BREAK16:
12897            /* BREAK16 */
12898            generate_exception(ctx, EXCP_BREAK);
12899            break;
12900        case R6_SDBBP16:
12901            /* SDBBP16 */
12902            if (is_uhi(extract32(ctx->opcode, 6, 4))) {
12903                gen_helper_do_semihosting(cpu_env);
12904            } else {
12905                if (ctx->hflags & MIPS_HFLAG_SBRI) {
12906                    generate_exception(ctx, EXCP_RI);
12907                } else {
12908                    generate_exception(ctx, EXCP_DBp);
12909                }
12910            }
12911            break;
12912        }
12913        break;
12914    default:
12915        generate_exception(ctx, EXCP_RI);
12916        break;
12917    }
12918}
12919
12920static void gen_ldxs (DisasContext *ctx, int base, int index, int rd)
12921{
12922    TCGv t0 = tcg_temp_new();
12923    TCGv t1 = tcg_temp_new();
12924
12925    gen_load_gpr(t0, base);
12926
12927    if (index != 0) {
12928        gen_load_gpr(t1, index);
12929        tcg_gen_shli_tl(t1, t1, 2);
12930        gen_op_addr_add(ctx, t0, t1, t0);
12931    }
12932
12933    tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TESL);
12934    gen_store_gpr(t1, rd);
12935
12936    tcg_temp_free(t0);
12937    tcg_temp_free(t1);
12938}
12939
12940static void gen_ldst_pair (DisasContext *ctx, uint32_t opc, int rd,
12941                           int base, int16_t offset)
12942{
12943    TCGv t0, t1;
12944
12945    if (ctx->hflags & MIPS_HFLAG_BMASK || rd == 31) {
12946        generate_exception_end(ctx, EXCP_RI);
12947        return;
12948    }
12949
12950    t0 = tcg_temp_new();
12951    t1 = tcg_temp_new();
12952
12953    gen_base_offset_addr(ctx, t0, base, offset);
12954
12955    switch (opc) {
12956    case LWP:
12957        if (rd == base) {
12958            generate_exception_end(ctx, EXCP_RI);
12959            return;
12960        }
12961        tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TESL);
12962        gen_store_gpr(t1, rd);
12963        tcg_gen_movi_tl(t1, 4);
12964        gen_op_addr_add(ctx, t0, t0, t1);
12965        tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TESL);
12966        gen_store_gpr(t1, rd+1);
12967        break;
12968    case SWP:
12969        gen_load_gpr(t1, rd);
12970        tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL);
12971        tcg_gen_movi_tl(t1, 4);
12972        gen_op_addr_add(ctx, t0, t0, t1);
12973        gen_load_gpr(t1, rd+1);
12974        tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL);
12975        break;
12976#ifdef TARGET_MIPS64
12977    case LDP:
12978        if (rd == base) {
12979            generate_exception_end(ctx, EXCP_RI);
12980            return;
12981        }
12982        tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TEQ);
12983        gen_store_gpr(t1, rd);
12984        tcg_gen_movi_tl(t1, 8);
12985        gen_op_addr_add(ctx, t0, t0, t1);
12986        tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TEQ);
12987        gen_store_gpr(t1, rd+1);
12988        break;
12989    case SDP:
12990        gen_load_gpr(t1, rd);
12991        tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEQ);
12992        tcg_gen_movi_tl(t1, 8);
12993        gen_op_addr_add(ctx, t0, t0, t1);
12994        gen_load_gpr(t1, rd+1);
12995        tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEQ);
12996        break;
12997#endif
12998    }
12999    tcg_temp_free(t0);
13000    tcg_temp_free(t1);
13001}
13002
13003static void gen_pool32axf (CPUMIPSState *env, DisasContext *ctx, int rt, int rs)
13004{
13005    int extension = (ctx->opcode >> 6) & 0x3f;
13006    int minor = (ctx->opcode >> 12) & 0xf;
13007    uint32_t mips32_op;
13008
13009    switch (extension) {
13010    case TEQ:
13011        mips32_op = OPC_TEQ;
13012        goto do_trap;
13013    case TGE:
13014        mips32_op = OPC_TGE;
13015        goto do_trap;
13016    case TGEU:
13017        mips32_op = OPC_TGEU;
13018        goto do_trap;
13019    case TLT:
13020        mips32_op = OPC_TLT;
13021        goto do_trap;
13022    case TLTU:
13023        mips32_op = OPC_TLTU;
13024        goto do_trap;
13025    case TNE:
13026        mips32_op = OPC_TNE;
13027    do_trap:
13028        gen_trap(ctx, mips32_op, rs, rt, -1);
13029        break;
13030#ifndef CONFIG_USER_ONLY
13031    case MFC0:
13032    case MFC0 + 32:
13033        check_cp0_enabled(ctx);
13034        if (rt == 0) {
13035            /* Treat as NOP. */
13036            break;
13037        }
13038        gen_mfc0(ctx, cpu_gpr[rt], rs, (ctx->opcode >> 11) & 0x7);
13039        break;
13040    case MTC0:
13041    case MTC0 + 32:
13042        check_cp0_enabled(ctx);
13043        {
13044            TCGv t0 = tcg_temp_new();
13045
13046            gen_load_gpr(t0, rt);
13047            gen_mtc0(ctx, t0, rs, (ctx->opcode >> 11) & 0x7);
13048            tcg_temp_free(t0);
13049        }
13050        break;
13051#endif
13052    case 0x2a:
13053        switch (minor & 3) {
13054        case MADD_ACC:
13055            gen_muldiv(ctx, OPC_MADD, (ctx->opcode >> 14) & 3, rs, rt);
13056            break;
13057        case MADDU_ACC:
13058            gen_muldiv(ctx, OPC_MADDU, (ctx->opcode >> 14) & 3, rs, rt);
13059            break;
13060        case MSUB_ACC:
13061            gen_muldiv(ctx, OPC_MSUB, (ctx->opcode >> 14) & 3, rs, rt);
13062            break;
13063        case MSUBU_ACC:
13064            gen_muldiv(ctx, OPC_MSUBU, (ctx->opcode >> 14) & 3, rs, rt);
13065            break;
13066        default:
13067            goto pool32axf_invalid;
13068        }
13069        break;
13070    case 0x32:
13071        switch (minor & 3) {
13072        case MULT_ACC:
13073            gen_muldiv(ctx, OPC_MULT, (ctx->opcode >> 14) & 3, rs, rt);
13074            break;
13075        case MULTU_ACC:
13076            gen_muldiv(ctx, OPC_MULTU, (ctx->opcode >> 14) & 3, rs, rt);
13077            break;
13078        default:
13079            goto pool32axf_invalid;
13080        }
13081        break;
13082    case 0x2c:
13083        switch (minor) {
13084        case BITSWAP:
13085            check_insn(ctx, ISA_MIPS32R6);
13086            gen_bitswap(ctx, OPC_BITSWAP, rs, rt);
13087            break;
13088        case SEB:
13089            gen_bshfl(ctx, OPC_SEB, rs, rt);
13090            break;
13091        case SEH:
13092            gen_bshfl(ctx, OPC_SEH, rs, rt);
13093            break;
13094        case CLO:
13095            mips32_op = OPC_CLO;
13096            goto do_cl;
13097        case CLZ:
13098            mips32_op = OPC_CLZ;
13099        do_cl:
13100            check_insn(ctx, ISA_MIPS32);
13101            gen_cl(ctx, mips32_op, rt, rs);
13102            break;
13103        case RDHWR:
13104            check_insn_opc_removed(ctx, ISA_MIPS32R6);
13105            gen_rdhwr(ctx, rt, rs, 0);
13106            break;
13107        case WSBH:
13108            gen_bshfl(ctx, OPC_WSBH, rs, rt);
13109            break;
13110        case MULT:
13111            check_insn_opc_removed(ctx, ISA_MIPS32R6);
13112            mips32_op = OPC_MULT;
13113            goto do_mul;
13114        case MULTU:
13115            check_insn_opc_removed(ctx, ISA_MIPS32R6);
13116            mips32_op = OPC_MULTU;
13117            goto do_mul;
13118        case DIV:
13119            check_insn_opc_removed(ctx, ISA_MIPS32R6);
13120            mips32_op = OPC_DIV;
13121            goto do_div;
13122        case DIVU:
13123            check_insn_opc_removed(ctx, ISA_MIPS32R6);
13124            mips32_op = OPC_DIVU;
13125            goto do_div;
13126        do_div:
13127            check_insn(ctx, ISA_MIPS32);
13128            gen_muldiv(ctx, mips32_op, 0, rs, rt);
13129            break;
13130        case MADD:
13131            check_insn_opc_removed(ctx, ISA_MIPS32R6);
13132            mips32_op = OPC_MADD;
13133            goto do_mul;
13134        case MADDU:
13135            check_insn_opc_removed(ctx, ISA_MIPS32R6);
13136            mips32_op = OPC_MADDU;
13137            goto do_mul;
13138        case MSUB:
13139            check_insn_opc_removed(ctx, ISA_MIPS32R6);
13140            mips32_op = OPC_MSUB;
13141            goto do_mul;
13142        case MSUBU:
13143            check_insn_opc_removed(ctx, ISA_MIPS32R6);
13144            mips32_op = OPC_MSUBU;
13145        do_mul:
13146            check_insn(ctx, ISA_MIPS32);
13147            gen_muldiv(ctx, mips32_op, 0, rs, rt);
13148            break;
13149        default:
13150            goto pool32axf_invalid;
13151        }
13152        break;
13153    case 0x34:
13154        switch (minor) {
13155        case MFC2:
13156        case MTC2:
13157        case MFHC2:
13158        case MTHC2:
13159        case CFC2:
13160        case CTC2:
13161            generate_exception_err(ctx, EXCP_CpU, 2);
13162            break;
13163        default:
13164            goto pool32axf_invalid;
13165        }
13166        break;
13167    case 0x3c:
13168        switch (minor) {
13169        case JALR:    /* JALRC */
13170        case JALR_HB: /* JALRC_HB */
13171            if (ctx->insn_flags & ISA_MIPS32R6) {
13172                /* JALRC, JALRC_HB */
13173                gen_compute_branch(ctx, OPC_JALR, 4, rs, rt, 0, 0);
13174            } else {
13175                /* JALR, JALR_HB */
13176                gen_compute_branch(ctx, OPC_JALR, 4, rs, rt, 0, 4);
13177                ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
13178            }
13179            break;
13180        case JALRS:
13181        case JALRS_HB:
13182            check_insn_opc_removed(ctx, ISA_MIPS32R6);
13183            gen_compute_branch(ctx, OPC_JALR, 4, rs, rt, 0, 2);
13184            ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
13185            break;
13186        default:
13187            goto pool32axf_invalid;
13188        }
13189        break;
13190    case 0x05:
13191        switch (minor) {
13192        case RDPGPR:
13193            check_cp0_enabled(ctx);
13194            check_insn(ctx, ISA_MIPS32R2);
13195            gen_load_srsgpr(rs, rt);
13196            break;
13197        case WRPGPR:
13198            check_cp0_enabled(ctx);
13199            check_insn(ctx, ISA_MIPS32R2);
13200            gen_store_srsgpr(rs, rt);
13201            break;
13202        default:
13203            goto pool32axf_invalid;
13204        }
13205        break;
13206#ifndef CONFIG_USER_ONLY
13207    case 0x0d:
13208        switch (minor) {
13209        case TLBP:
13210            mips32_op = OPC_TLBP;
13211            goto do_cp0;
13212        case TLBR:
13213            mips32_op = OPC_TLBR;
13214            goto do_cp0;
13215        case TLBWI:
13216            mips32_op = OPC_TLBWI;
13217            goto do_cp0;
13218        case TLBWR:
13219            mips32_op = OPC_TLBWR;
13220            goto do_cp0;
13221        case TLBINV:
13222            mips32_op = OPC_TLBINV;
13223            goto do_cp0;
13224        case TLBINVF:
13225            mips32_op = OPC_TLBINVF;
13226            goto do_cp0;
13227        case WAIT:
13228            mips32_op = OPC_WAIT;
13229            goto do_cp0;
13230        case DERET:
13231            mips32_op = OPC_DERET;
13232            goto do_cp0;
13233        case ERET:
13234            mips32_op = OPC_ERET;
13235        do_cp0:
13236            gen_cp0(env, ctx, mips32_op, rt, rs);
13237            break;
13238        default:
13239            goto pool32axf_invalid;
13240        }
13241        break;
13242    case 0x1d:
13243        switch (minor) {
13244        case DI:
13245            check_cp0_enabled(ctx);
13246            {
13247                TCGv t0 = tcg_temp_new();
13248
13249                save_cpu_state(ctx, 1);
13250                gen_helper_di(t0, cpu_env);
13251                gen_store_gpr(t0, rs);
13252                /* Stop translation as we may have switched the execution mode */
13253                ctx->bstate = BS_STOP;
13254                tcg_temp_free(t0);
13255            }
13256            break;
13257        case EI:
13258            check_cp0_enabled(ctx);
13259            {
13260                TCGv t0 = tcg_temp_new();
13261
13262                save_cpu_state(ctx, 1);
13263                gen_helper_ei(t0, cpu_env);
13264                gen_store_gpr(t0, rs);
13265                /* Stop translation as we may have switched the execution mode */
13266                ctx->bstate = BS_STOP;
13267                tcg_temp_free(t0);
13268            }
13269            break;
13270        default:
13271            goto pool32axf_invalid;
13272        }
13273        break;
13274#endif
13275    case 0x2d:
13276        switch (minor) {
13277        case SYNC:
13278            /* NOP */
13279            break;
13280        case SYSCALL:
13281            generate_exception_end(ctx, EXCP_SYSCALL);
13282            break;
13283        case SDBBP:
13284            if (is_uhi(extract32(ctx->opcode, 16, 10))) {
13285                gen_helper_do_semihosting(cpu_env);
13286            } else {
13287                check_insn(ctx, ISA_MIPS32);
13288                if (ctx->hflags & MIPS_HFLAG_SBRI) {
13289                    generate_exception_end(ctx, EXCP_RI);
13290                } else {
13291                    generate_exception_end(ctx, EXCP_DBp);
13292                }
13293            }
13294            break;
13295        default:
13296            goto pool32axf_invalid;
13297        }
13298        break;
13299    case 0x01:
13300        switch (minor & 3) {
13301        case MFHI_ACC:
13302            gen_HILO(ctx, OPC_MFHI, minor >> 2, rs);
13303            break;
13304        case MFLO_ACC:
13305            gen_HILO(ctx, OPC_MFLO, minor >> 2, rs);
13306            break;
13307        case MTHI_ACC:
13308            gen_HILO(ctx, OPC_MTHI, minor >> 2, rs);
13309            break;
13310        case MTLO_ACC:
13311            gen_HILO(ctx, OPC_MTLO, minor >> 2, rs);
13312            break;
13313        default:
13314            goto pool32axf_invalid;
13315        }
13316        break;
13317    case 0x35:
13318        check_insn_opc_removed(ctx, ISA_MIPS32R6);
13319        switch (minor) {
13320        case MFHI32:
13321            gen_HILO(ctx, OPC_MFHI, 0, rs);
13322            break;
13323        case MFLO32:
13324            gen_HILO(ctx, OPC_MFLO, 0, rs);
13325            break;
13326        case MTHI32:
13327            gen_HILO(ctx, OPC_MTHI, 0, rs);
13328            break;
13329        case MTLO32:
13330            gen_HILO(ctx, OPC_MTLO, 0, rs);
13331            break;
13332        default:
13333            goto pool32axf_invalid;
13334        }
13335        break;
13336    default:
13337    pool32axf_invalid:
13338        MIPS_INVAL("pool32axf");
13339        generate_exception_end(ctx, EXCP_RI);
13340        break;
13341    }
13342}
13343
13344/* Values for microMIPS fmt field.  Variable-width, depending on which
13345   formats the instruction supports.  */
13346
13347enum {
13348    FMT_SD_S = 0,
13349    FMT_SD_D = 1,
13350
13351    FMT_SDPS_S = 0,
13352    FMT_SDPS_D = 1,
13353    FMT_SDPS_PS = 2,
13354
13355    FMT_SWL_S = 0,
13356    FMT_SWL_W = 1,
13357    FMT_SWL_L = 2,
13358
13359    FMT_DWL_D = 0,
13360    FMT_DWL_W = 1,
13361    FMT_DWL_L = 2
13362};
13363
13364static void gen_pool32fxf(DisasContext *ctx, int rt, int rs)
13365{
13366    int extension = (ctx->opcode >> 6) & 0x3ff;
13367    uint32_t mips32_op;
13368
13369#define FLOAT_1BIT_FMT(opc, fmt) (fmt << 8) | opc
13370#define FLOAT_2BIT_FMT(opc, fmt) (fmt << 7) | opc
13371#define COND_FLOAT_MOV(opc, cond) (cond << 7) | opc
13372
13373    switch (extension) {
13374    case FLOAT_1BIT_FMT(CFC1, 0):
13375        mips32_op = OPC_CFC1;
13376        goto do_cp1;
13377    case FLOAT_1BIT_FMT(CTC1, 0):
13378        mips32_op = OPC_CTC1;
13379        goto do_cp1;
13380    case FLOAT_1BIT_FMT(MFC1, 0):
13381        mips32_op = OPC_MFC1;
13382        goto do_cp1;
13383    case FLOAT_1BIT_FMT(MTC1, 0):
13384        mips32_op = OPC_MTC1;
13385        goto do_cp1;
13386    case FLOAT_1BIT_FMT(MFHC1, 0):
13387        mips32_op = OPC_MFHC1;
13388        goto do_cp1;
13389    case FLOAT_1BIT_FMT(MTHC1, 0):
13390        mips32_op = OPC_MTHC1;
13391    do_cp1:
13392        gen_cp1(ctx, mips32_op, rt, rs);
13393        break;
13394
13395        /* Reciprocal square root */
13396    case FLOAT_1BIT_FMT(RSQRT_FMT, FMT_SD_S):
13397        mips32_op = OPC_RSQRT_S;
13398        goto do_unaryfp;
13399    case FLOAT_1BIT_FMT(RSQRT_FMT, FMT_SD_D):
13400        mips32_op = OPC_RSQRT_D;
13401        goto do_unaryfp;
13402
13403        /* Square root */
13404    case FLOAT_1BIT_FMT(SQRT_FMT, FMT_SD_S):
13405        mips32_op = OPC_SQRT_S;
13406        goto do_unaryfp;
13407    case FLOAT_1BIT_FMT(SQRT_FMT, FMT_SD_D):
13408        mips32_op = OPC_SQRT_D;
13409        goto do_unaryfp;
13410
13411        /* Reciprocal */
13412    case FLOAT_1BIT_FMT(RECIP_FMT, FMT_SD_S):
13413        mips32_op = OPC_RECIP_S;
13414        goto do_unaryfp;
13415    case FLOAT_1BIT_FMT(RECIP_FMT, FMT_SD_D):
13416        mips32_op = OPC_RECIP_D;
13417        goto do_unaryfp;
13418
13419        /* Floor */
13420    case FLOAT_1BIT_FMT(FLOOR_L, FMT_SD_S):
13421        mips32_op = OPC_FLOOR_L_S;
13422        goto do_unaryfp;
13423    case FLOAT_1BIT_FMT(FLOOR_L, FMT_SD_D):
13424        mips32_op = OPC_FLOOR_L_D;
13425        goto do_unaryfp;
13426    case FLOAT_1BIT_FMT(FLOOR_W, FMT_SD_S):
13427        mips32_op = OPC_FLOOR_W_S;
13428        goto do_unaryfp;
13429    case FLOAT_1BIT_FMT(FLOOR_W, FMT_SD_D):
13430        mips32_op = OPC_FLOOR_W_D;
13431        goto do_unaryfp;
13432
13433        /* Ceiling */
13434    case FLOAT_1BIT_FMT(CEIL_L, FMT_SD_S):
13435        mips32_op = OPC_CEIL_L_S;
13436        goto do_unaryfp;
13437    case FLOAT_1BIT_FMT(CEIL_L, FMT_SD_D):
13438        mips32_op = OPC_CEIL_L_D;
13439        goto do_unaryfp;
13440    case FLOAT_1BIT_FMT(CEIL_W, FMT_SD_S):
13441        mips32_op = OPC_CEIL_W_S;
13442        goto do_unaryfp;
13443    case FLOAT_1BIT_FMT(CEIL_W, FMT_SD_D):
13444        mips32_op = OPC_CEIL_W_D;
13445        goto do_unaryfp;
13446
13447        /* Truncation */
13448    case FLOAT_1BIT_FMT(TRUNC_L, FMT_SD_S):
13449        mips32_op = OPC_TRUNC_L_S;
13450        goto do_unaryfp;
13451    case FLOAT_1BIT_FMT(TRUNC_L, FMT_SD_D):
13452        mips32_op = OPC_TRUNC_L_D;
13453        goto do_unaryfp;
13454    case FLOAT_1BIT_FMT(TRUNC_W, FMT_SD_S):
13455        mips32_op = OPC_TRUNC_W_S;
13456        goto do_unaryfp;
13457    case FLOAT_1BIT_FMT(TRUNC_W, FMT_SD_D):
13458        mips32_op = OPC_TRUNC_W_D;
13459        goto do_unaryfp;
13460
13461        /* Round */
13462    case FLOAT_1BIT_FMT(ROUND_L, FMT_SD_S):
13463        mips32_op = OPC_ROUND_L_S;
13464        goto do_unaryfp;
13465    case FLOAT_1BIT_FMT(ROUND_L, FMT_SD_D):
13466        mips32_op = OPC_ROUND_L_D;
13467        goto do_unaryfp;
13468    case FLOAT_1BIT_FMT(ROUND_W, FMT_SD_S):
13469        mips32_op = OPC_ROUND_W_S;
13470        goto do_unaryfp;
13471    case FLOAT_1BIT_FMT(ROUND_W, FMT_SD_D):
13472        mips32_op = OPC_ROUND_W_D;
13473        goto do_unaryfp;
13474
13475        /* Integer to floating-point conversion */
13476    case FLOAT_1BIT_FMT(CVT_L, FMT_SD_S):
13477        mips32_op = OPC_CVT_L_S;
13478        goto do_unaryfp;
13479    case FLOAT_1BIT_FMT(CVT_L, FMT_SD_D):
13480        mips32_op = OPC_CVT_L_D;
13481        goto do_unaryfp;
13482    case FLOAT_1BIT_FMT(CVT_W, FMT_SD_S):
13483        mips32_op = OPC_CVT_W_S;
13484        goto do_unaryfp;
13485    case FLOAT_1BIT_FMT(CVT_W, FMT_SD_D):
13486        mips32_op = OPC_CVT_W_D;
13487        goto do_unaryfp;
13488
13489        /* Paired-foo conversions */
13490    case FLOAT_1BIT_FMT(CVT_S_PL, 0):
13491        mips32_op = OPC_CVT_S_PL;
13492        goto do_unaryfp;
13493    case FLOAT_1BIT_FMT(CVT_S_PU, 0):
13494        mips32_op = OPC_CVT_S_PU;
13495        goto do_unaryfp;
13496    case FLOAT_1BIT_FMT(CVT_PW_PS, 0):
13497        mips32_op = OPC_CVT_PW_PS;
13498        goto do_unaryfp;
13499    case FLOAT_1BIT_FMT(CVT_PS_PW, 0):
13500        mips32_op = OPC_CVT_PS_PW;
13501        goto do_unaryfp;
13502
13503        /* Floating-point moves */
13504    case FLOAT_2BIT_FMT(MOV_FMT, FMT_SDPS_S):
13505        mips32_op = OPC_MOV_S;
13506        goto do_unaryfp;
13507    case FLOAT_2BIT_FMT(MOV_FMT, FMT_SDPS_D):
13508        mips32_op = OPC_MOV_D;
13509        goto do_unaryfp;
13510    case FLOAT_2BIT_FMT(MOV_FMT, FMT_SDPS_PS):
13511        mips32_op = OPC_MOV_PS;
13512        goto do_unaryfp;
13513
13514        /* Absolute value */
13515    case FLOAT_2BIT_FMT(ABS_FMT, FMT_SDPS_S):
13516        mips32_op = OPC_ABS_S;
13517        goto do_unaryfp;
13518    case FLOAT_2BIT_FMT(ABS_FMT, FMT_SDPS_D):
13519        mips32_op = OPC_ABS_D;
13520        goto do_unaryfp;
13521    case FLOAT_2BIT_FMT(ABS_FMT, FMT_SDPS_PS):
13522        mips32_op = OPC_ABS_PS;
13523        goto do_unaryfp;
13524
13525        /* Negation */
13526    case FLOAT_2BIT_FMT(NEG_FMT, FMT_SDPS_S):
13527        mips32_op = OPC_NEG_S;
13528        goto do_unaryfp;
13529    case FLOAT_2BIT_FMT(NEG_FMT, FMT_SDPS_D):
13530        mips32_op = OPC_NEG_D;
13531        goto do_unaryfp;
13532    case FLOAT_2BIT_FMT(NEG_FMT, FMT_SDPS_PS):
13533        mips32_op = OPC_NEG_PS;
13534        goto do_unaryfp;
13535
13536        /* Reciprocal square root step */
13537    case FLOAT_2BIT_FMT(RSQRT1_FMT, FMT_SDPS_S):
13538        mips32_op = OPC_RSQRT1_S;
13539        goto do_unaryfp;
13540    case FLOAT_2BIT_FMT(RSQRT1_FMT, FMT_SDPS_D):
13541        mips32_op = OPC_RSQRT1_D;
13542        goto do_unaryfp;
13543    case FLOAT_2BIT_FMT(RSQRT1_FMT, FMT_SDPS_PS):
13544        mips32_op = OPC_RSQRT1_PS;
13545        goto do_unaryfp;
13546
13547        /* Reciprocal step */
13548    case FLOAT_2BIT_FMT(RECIP1_FMT, FMT_SDPS_S):
13549        mips32_op = OPC_RECIP1_S;
13550        goto do_unaryfp;
13551    case FLOAT_2BIT_FMT(RECIP1_FMT, FMT_SDPS_D):
13552        mips32_op = OPC_RECIP1_S;
13553        goto do_unaryfp;
13554    case FLOAT_2BIT_FMT(RECIP1_FMT, FMT_SDPS_PS):
13555        mips32_op = OPC_RECIP1_PS;
13556        goto do_unaryfp;
13557
13558        /* Conversions from double */
13559    case FLOAT_2BIT_FMT(CVT_D, FMT_SWL_S):
13560        mips32_op = OPC_CVT_D_S;
13561        goto do_unaryfp;
13562    case FLOAT_2BIT_FMT(CVT_D, FMT_SWL_W):
13563        mips32_op = OPC_CVT_D_W;
13564        goto do_unaryfp;
13565    case FLOAT_2BIT_FMT(CVT_D, FMT_SWL_L):
13566        mips32_op = OPC_CVT_D_L;
13567        goto do_unaryfp;
13568
13569        /* Conversions from single */
13570    case FLOAT_2BIT_FMT(CVT_S, FMT_DWL_D):
13571        mips32_op = OPC_CVT_S_D;
13572        goto do_unaryfp;
13573    case FLOAT_2BIT_FMT(CVT_S, FMT_DWL_W):
13574        mips32_op = OPC_CVT_S_W;
13575        goto do_unaryfp;
13576    case FLOAT_2BIT_FMT(CVT_S, FMT_DWL_L):
13577        mips32_op = OPC_CVT_S_L;
13578    do_unaryfp:
13579        gen_farith(ctx, mips32_op, -1, rs, rt, 0);
13580        break;
13581
13582        /* Conditional moves on floating-point codes */
13583    case COND_FLOAT_MOV(MOVT, 0):
13584    case COND_FLOAT_MOV(MOVT, 1):
13585    case COND_FLOAT_MOV(MOVT, 2):
13586    case COND_FLOAT_MOV(MOVT, 3):
13587    case COND_FLOAT_MOV(MOVT, 4):
13588    case COND_FLOAT_MOV(MOVT, 5):
13589    case COND_FLOAT_MOV(MOVT, 6):
13590    case COND_FLOAT_MOV(MOVT, 7):
13591        check_insn_opc_removed(ctx, ISA_MIPS32R6);
13592        gen_movci(ctx, rt, rs, (ctx->opcode >> 13) & 0x7, 1);
13593        break;
13594    case COND_FLOAT_MOV(MOVF, 0):
13595    case COND_FLOAT_MOV(MOVF, 1):
13596    case COND_FLOAT_MOV(MOVF, 2):
13597    case COND_FLOAT_MOV(MOVF, 3):
13598    case COND_FLOAT_MOV(MOVF, 4):
13599    case COND_FLOAT_MOV(MOVF, 5):
13600    case COND_FLOAT_MOV(MOVF, 6):
13601    case COND_FLOAT_MOV(MOVF, 7):
13602        check_insn_opc_removed(ctx, ISA_MIPS32R6);
13603        gen_movci(ctx, rt, rs, (ctx->opcode >> 13) & 0x7, 0);
13604        break;
13605    default:
13606        MIPS_INVAL("pool32fxf");
13607        generate_exception_end(ctx, EXCP_RI);
13608        break;
13609    }
13610}
13611
13612static void decode_micromips32_opc(CPUMIPSState *env, DisasContext *ctx)
13613{
13614    int32_t offset;
13615    uint16_t insn;
13616    int rt, rs, rd, rr;
13617    int16_t imm;
13618    uint32_t op, minor, mips32_op;
13619    uint32_t cond, fmt, cc;
13620
13621    insn = cpu_lduw_code(env, ctx->pc + 2);
13622    ctx->opcode = (ctx->opcode << 16) | insn;
13623
13624    rt = (ctx->opcode >> 21) & 0x1f;
13625    rs = (ctx->opcode >> 16) & 0x1f;
13626    rd = (ctx->opcode >> 11) & 0x1f;
13627    rr = (ctx->opcode >> 6) & 0x1f;
13628    imm = (int16_t) ctx->opcode;
13629
13630    op = (ctx->opcode >> 26) & 0x3f;
13631    switch (op) {
13632    case POOL32A:
13633        minor = ctx->opcode & 0x3f;
13634        switch (minor) {
13635        case 0x00:
13636            minor = (ctx->opcode >> 6) & 0xf;
13637            switch (minor) {
13638            case SLL32:
13639                mips32_op = OPC_SLL;
13640                goto do_shifti;
13641            case SRA:
13642                mips32_op = OPC_SRA;
13643                goto do_shifti;
13644            case SRL32:
13645                mips32_op = OPC_SRL;
13646                goto do_shifti;
13647            case ROTR:
13648                mips32_op = OPC_ROTR;
13649            do_shifti:
13650                gen_shift_imm(ctx, mips32_op, rt, rs, rd);
13651                break;
13652            case SELEQZ:
13653                check_insn(ctx, ISA_MIPS32R6);
13654                gen_cond_move(ctx, OPC_SELEQZ, rd, rs, rt);
13655                break;
13656            case SELNEZ:
13657                check_insn(ctx, ISA_MIPS32R6);
13658                gen_cond_move(ctx, OPC_SELNEZ, rd, rs, rt);
13659                break;
13660            case R6_RDHWR:
13661                check_insn(ctx, ISA_MIPS32R6);
13662                gen_rdhwr(ctx, rt, rs, extract32(ctx->opcode, 11, 3));
13663                break;
13664            default:
13665                goto pool32a_invalid;
13666            }
13667            break;
13668        case 0x10:
13669            minor = (ctx->opcode >> 6) & 0xf;
13670            switch (minor) {
13671                /* Arithmetic */
13672            case ADD:
13673                mips32_op = OPC_ADD;
13674                goto do_arith;
13675            case ADDU32:
13676                mips32_op = OPC_ADDU;
13677                goto do_arith;
13678            case SUB:
13679                mips32_op = OPC_SUB;
13680                goto do_arith;
13681            case SUBU32:
13682                mips32_op = OPC_SUBU;
13683                goto do_arith;
13684            case MUL:
13685                check_insn_opc_removed(ctx, ISA_MIPS32R6);
13686                mips32_op = OPC_MUL;
13687            do_arith:
13688                gen_arith(ctx, mips32_op, rd, rs, rt);
13689                break;
13690                /* Shifts */
13691            case SLLV:
13692                mips32_op = OPC_SLLV;
13693                goto do_shift;
13694            case SRLV:
13695                mips32_op = OPC_SRLV;
13696                goto do_shift;
13697            case SRAV:
13698                mips32_op = OPC_SRAV;
13699                goto do_shift;
13700            case ROTRV:
13701                mips32_op = OPC_ROTRV;
13702            do_shift:
13703                gen_shift(ctx, mips32_op, rd, rs, rt);
13704                break;
13705                /* Logical operations */
13706            case AND:
13707                mips32_op = OPC_AND;
13708                goto do_logic;
13709            case OR32:
13710                mips32_op = OPC_OR;
13711                goto do_logic;
13712            case NOR:
13713                mips32_op = OPC_NOR;
13714                goto do_logic;
13715            case XOR32:
13716                mips32_op = OPC_XOR;
13717            do_logic:
13718                gen_logic(ctx, mips32_op, rd, rs, rt);
13719                break;
13720                /* Set less than */
13721            case SLT:
13722                mips32_op = OPC_SLT;
13723                goto do_slt;
13724            case SLTU:
13725                mips32_op = OPC_SLTU;
13726            do_slt:
13727                gen_slt(ctx, mips32_op, rd, rs, rt);
13728                break;
13729            default:
13730                goto pool32a_invalid;
13731            }
13732            break;
13733        case 0x18:
13734            minor = (ctx->opcode >> 6) & 0xf;
13735            switch (minor) {
13736                /* Conditional moves */
13737            case MOVN: /* MUL */
13738                if (ctx->insn_flags & ISA_MIPS32R6) {
13739                    /* MUL */
13740                    gen_r6_muldiv(ctx, R6_OPC_MUL, rd, rs, rt);
13741                } else {
13742                    /* MOVN */
13743                    gen_cond_move(ctx, OPC_MOVN, rd, rs, rt);
13744                }
13745                break;
13746            case MOVZ: /* MUH */
13747                if (ctx->insn_flags & ISA_MIPS32R6) {
13748                    /* MUH */
13749                    gen_r6_muldiv(ctx, R6_OPC_MUH, rd, rs, rt);
13750                } else {
13751                    /* MOVZ */
13752                    gen_cond_move(ctx, OPC_MOVZ, rd, rs, rt);
13753                }
13754                break;
13755            case MULU:
13756                check_insn(ctx, ISA_MIPS32R6);
13757                gen_r6_muldiv(ctx, R6_OPC_MULU, rd, rs, rt);
13758                break;
13759            case MUHU:
13760                check_insn(ctx, ISA_MIPS32R6);
13761                gen_r6_muldiv(ctx, R6_OPC_MUHU, rd, rs, rt);
13762                break;
13763            case LWXS: /* DIV */
13764                if (ctx->insn_flags & ISA_MIPS32R6) {
13765                    /* DIV */
13766                    gen_r6_muldiv(ctx, R6_OPC_DIV, rd, rs, rt);
13767                } else {
13768                    /* LWXS */
13769                    gen_ldxs(ctx, rs, rt, rd);
13770                }
13771                break;
13772            case MOD:
13773                check_insn(ctx, ISA_MIPS32R6);
13774                gen_r6_muldiv(ctx, R6_OPC_MOD, rd, rs, rt);
13775                break;
13776            case R6_DIVU:
13777                check_insn(ctx, ISA_MIPS32R6);
13778                gen_r6_muldiv(ctx, R6_OPC_DIVU, rd, rs, rt);
13779                break;
13780            case MODU:
13781                check_insn(ctx, ISA_MIPS32R6);
13782                gen_r6_muldiv(ctx, R6_OPC_MODU, rd, rs, rt);
13783                break;
13784            default:
13785                goto pool32a_invalid;
13786            }
13787            break;
13788        case INS:
13789            gen_bitops(ctx, OPC_INS, rt, rs, rr, rd);
13790            return;
13791        case LSA:
13792            check_insn(ctx, ISA_MIPS32R6);
13793            gen_lsa(ctx, OPC_LSA, rd, rs, rt,
13794                    extract32(ctx->opcode, 9, 2));
13795            break;
13796        case ALIGN:
13797            check_insn(ctx, ISA_MIPS32R6);
13798            gen_align(ctx, OPC_ALIGN, rd, rs, rt,
13799                      extract32(ctx->opcode, 9, 2));
13800            break;
13801        case EXT:
13802            gen_bitops(ctx, OPC_EXT, rt, rs, rr, rd);
13803            return;
13804        case POOL32AXF:
13805            gen_pool32axf(env, ctx, rt, rs);
13806            break;
13807        case BREAK32:
13808            generate_exception_end(ctx, EXCP_BREAK);
13809            break;
13810        case SIGRIE:
13811            check_insn(ctx, ISA_MIPS32R6);
13812            generate_exception_end(ctx, EXCP_RI);
13813            break;
13814        default:
13815        pool32a_invalid:
13816                MIPS_INVAL("pool32a");
13817                generate_exception_end(ctx, EXCP_RI);
13818                break;
13819        }
13820        break;
13821    case POOL32B:
13822        minor = (ctx->opcode >> 12) & 0xf;
13823        switch (minor) {
13824        case CACHE:
13825            check_cp0_enabled(ctx);
13826            if (ctx->hflags & MIPS_HFLAG_ITC_CACHE) {
13827                gen_cache_operation(ctx, rt, rs, imm);
13828            }
13829            break;
13830        case LWC2:
13831        case SWC2:
13832            /* COP2: Not implemented. */
13833            generate_exception_err(ctx, EXCP_CpU, 2);
13834            break;
13835#ifdef TARGET_MIPS64
13836        case LDP:
13837        case SDP:
13838            check_insn(ctx, ISA_MIPS3);
13839            check_mips_64(ctx);
13840            /* Fallthrough */
13841#endif
13842        case LWP:
13843        case SWP:
13844            gen_ldst_pair(ctx, minor, rt, rs, SIMM(ctx->opcode, 0, 12));
13845            break;
13846#ifdef TARGET_MIPS64
13847        case LDM:
13848        case SDM:
13849            check_insn(ctx, ISA_MIPS3);
13850            check_mips_64(ctx);
13851            /* Fallthrough */
13852#endif
13853        case LWM32:
13854        case SWM32:
13855            gen_ldst_multiple(ctx, minor, rt, rs, SIMM(ctx->opcode, 0, 12));
13856            break;
13857        default:
13858            MIPS_INVAL("pool32b");
13859            generate_exception_end(ctx, EXCP_RI);
13860            break;
13861        }
13862        break;
13863    case POOL32F:
13864        if (ctx->CP0_Config1 & (1 << CP0C1_FP)) {
13865            minor = ctx->opcode & 0x3f;
13866            check_cp1_enabled(ctx);
13867            switch (minor) {
13868            case ALNV_PS:
13869                check_insn_opc_removed(ctx, ISA_MIPS32R6);
13870                mips32_op = OPC_ALNV_PS;
13871                goto do_madd;
13872            case MADD_S:
13873                check_insn_opc_removed(ctx, ISA_MIPS32R6);
13874                mips32_op = OPC_MADD_S;
13875                goto do_madd;
13876            case MADD_D:
13877                check_insn_opc_removed(ctx, ISA_MIPS32R6);
13878                mips32_op = OPC_MADD_D;
13879                goto do_madd;
13880            case MADD_PS:
13881                check_insn_opc_removed(ctx, ISA_MIPS32R6);
13882                mips32_op = OPC_MADD_PS;
13883                goto do_madd;
13884            case MSUB_S:
13885                check_insn_opc_removed(ctx, ISA_MIPS32R6);
13886                mips32_op = OPC_MSUB_S;
13887                goto do_madd;
13888            case MSUB_D:
13889                check_insn_opc_removed(ctx, ISA_MIPS32R6);
13890                mips32_op = OPC_MSUB_D;
13891                goto do_madd;
13892            case MSUB_PS:
13893                check_insn_opc_removed(ctx, ISA_MIPS32R6);
13894                mips32_op = OPC_MSUB_PS;
13895                goto do_madd;
13896            case NMADD_S:
13897                check_insn_opc_removed(ctx, ISA_MIPS32R6);
13898                mips32_op = OPC_NMADD_S;
13899                goto do_madd;
13900            case NMADD_D:
13901                check_insn_opc_removed(ctx, ISA_MIPS32R6);
13902                mips32_op = OPC_NMADD_D;
13903                goto do_madd;
13904            case NMADD_PS:
13905                check_insn_opc_removed(ctx, ISA_MIPS32R6);
13906                mips32_op = OPC_NMADD_PS;
13907                goto do_madd;
13908            case NMSUB_S:
13909                check_insn_opc_removed(ctx, ISA_MIPS32R6);
13910                mips32_op = OPC_NMSUB_S;
13911                goto do_madd;
13912            case NMSUB_D:
13913                check_insn_opc_removed(ctx, ISA_MIPS32R6);
13914                mips32_op = OPC_NMSUB_D;
13915                goto do_madd;
13916            case NMSUB_PS:
13917                check_insn_opc_removed(ctx, ISA_MIPS32R6);
13918                mips32_op = OPC_NMSUB_PS;
13919            do_madd:
13920                gen_flt3_arith(ctx, mips32_op, rd, rr, rs, rt);
13921                break;
13922            case CABS_COND_FMT:
13923                check_insn_opc_removed(ctx, ISA_MIPS32R6);
13924                cond = (ctx->opcode >> 6) & 0xf;
13925                cc = (ctx->opcode >> 13) & 0x7;
13926                fmt = (ctx->opcode >> 10) & 0x3;
13927                switch (fmt) {
13928                case 0x0:
13929                    gen_cmpabs_s(ctx, cond, rt, rs, cc);
13930                    break;
13931                case 0x1:
13932                    gen_cmpabs_d(ctx, cond, rt, rs, cc);
13933                    break;
13934                case 0x2:
13935                    gen_cmpabs_ps(ctx, cond, rt, rs, cc);
13936                    break;
13937                default:
13938                    goto pool32f_invalid;
13939                }
13940                break;
13941            case C_COND_FMT:
13942                check_insn_opc_removed(ctx, ISA_MIPS32R6);
13943                cond = (ctx->opcode >> 6) & 0xf;
13944                cc = (ctx->opcode >> 13) & 0x7;
13945                fmt = (ctx->opcode >> 10) & 0x3;
13946                switch (fmt) {
13947                case 0x0:
13948                    gen_cmp_s(ctx, cond, rt, rs, cc);
13949                    break;
13950                case 0x1:
13951                    gen_cmp_d(ctx, cond, rt, rs, cc);
13952                    break;
13953                case 0x2:
13954                    gen_cmp_ps(ctx, cond, rt, rs, cc);
13955                    break;
13956                default:
13957                    goto pool32f_invalid;
13958                }
13959                break;
13960            case CMP_CONDN_S:
13961                check_insn(ctx, ISA_MIPS32R6);
13962                gen_r6_cmp_s(ctx, (ctx->opcode >> 6) & 0x1f, rt, rs, rd);
13963                break;
13964            case CMP_CONDN_D:
13965                check_insn(ctx, ISA_MIPS32R6);
13966                gen_r6_cmp_d(ctx, (ctx->opcode >> 6) & 0x1f, rt, rs, rd);
13967                break;
13968            case POOL32FXF:
13969                gen_pool32fxf(ctx, rt, rs);
13970                break;
13971            case 0x00:
13972                /* PLL foo */
13973                switch ((ctx->opcode >> 6) & 0x7) {
13974                case PLL_PS:
13975                    mips32_op = OPC_PLL_PS;
13976                    goto do_ps;
13977                case PLU_PS:
13978                    mips32_op = OPC_PLU_PS;
13979                    goto do_ps;
13980                case PUL_PS:
13981                    mips32_op = OPC_PUL_PS;
13982                    goto do_ps;
13983                case PUU_PS:
13984                    mips32_op = OPC_PUU_PS;
13985                    goto do_ps;
13986                case CVT_PS_S:
13987                    check_insn_opc_removed(ctx, ISA_MIPS32R6);
13988                    mips32_op = OPC_CVT_PS_S;
13989                do_ps:
13990                    gen_farith(ctx, mips32_op, rt, rs, rd, 0);
13991                    break;
13992                default:
13993                    goto pool32f_invalid;
13994                }
13995                break;
13996            case MIN_FMT:
13997                check_insn(ctx, ISA_MIPS32R6);
13998                switch ((ctx->opcode >> 9) & 0x3) {
13999                case FMT_SDPS_S:
14000                    gen_farith(ctx, OPC_MIN_S, rt, rs, rd, 0);
14001                    break;
14002                case FMT_SDPS_D:
14003                    gen_farith(ctx, OPC_MIN_D, rt, rs, rd, 0);
14004                    break;
14005                default:
14006                    goto pool32f_invalid;
14007                }
14008                break;
14009            case 0x08:
14010                /* [LS][WDU]XC1 */
14011                switch ((ctx->opcode >> 6) & 0x7) {
14012                case LWXC1:
14013                    check_insn_opc_removed(ctx, ISA_MIPS32R6);
14014                    mips32_op = OPC_LWXC1;
14015                    goto do_ldst_cp1;
14016                case SWXC1:
14017                    check_insn_opc_removed(ctx, ISA_MIPS32R6);
14018                    mips32_op = OPC_SWXC1;
14019                    goto do_ldst_cp1;
14020                case LDXC1:
14021                    check_insn_opc_removed(ctx, ISA_MIPS32R6);
14022                    mips32_op = OPC_LDXC1;
14023                    goto do_ldst_cp1;
14024                case SDXC1:
14025                    check_insn_opc_removed(ctx, ISA_MIPS32R6);
14026                    mips32_op = OPC_SDXC1;
14027                    goto do_ldst_cp1;
14028                case LUXC1:
14029                    check_insn_opc_removed(ctx, ISA_MIPS32R6);
14030                    mips32_op = OPC_LUXC1;
14031                    goto do_ldst_cp1;
14032                case SUXC1:
14033                    check_insn_opc_removed(ctx, ISA_MIPS32R6);
14034                    mips32_op = OPC_SUXC1;
14035                do_ldst_cp1:
14036                    gen_flt3_ldst(ctx, mips32_op, rd, rd, rt, rs);
14037                    break;
14038                default:
14039                    goto pool32f_invalid;
14040                }
14041                break;
14042            case MAX_FMT:
14043                check_insn(ctx, ISA_MIPS32R6);
14044                switch ((ctx->opcode >> 9) & 0x3) {
14045                case FMT_SDPS_S:
14046                    gen_farith(ctx, OPC_MAX_S, rt, rs, rd, 0);
14047                    break;
14048                case FMT_SDPS_D:
14049                    gen_farith(ctx, OPC_MAX_D, rt, rs, rd, 0);
14050                    break;
14051                default:
14052                    goto pool32f_invalid;
14053                }
14054                break;
14055            case 0x18:
14056                /* 3D insns */
14057                check_insn_opc_removed(ctx, ISA_MIPS32R6);
14058                fmt = (ctx->opcode >> 9) & 0x3;
14059                switch ((ctx->opcode >> 6) & 0x7) {
14060                case RSQRT2_FMT:
14061                    switch (fmt) {
14062                    case FMT_SDPS_S:
14063                        mips32_op = OPC_RSQRT2_S;
14064                        goto do_3d;
14065                    case FMT_SDPS_D:
14066                        mips32_op = OPC_RSQRT2_D;
14067                        goto do_3d;
14068                    case FMT_SDPS_PS:
14069                        mips32_op = OPC_RSQRT2_PS;
14070                        goto do_3d;
14071                    default:
14072                        goto pool32f_invalid;
14073                    }
14074                    break;
14075                case RECIP2_FMT:
14076                    switch (fmt) {
14077                    case FMT_SDPS_S:
14078                        mips32_op = OPC_RECIP2_S;
14079                        goto do_3d;
14080                    case FMT_SDPS_D:
14081                        mips32_op = OPC_RECIP2_D;
14082                        goto do_3d;
14083                    case FMT_SDPS_PS:
14084                        mips32_op = OPC_RECIP2_PS;
14085                        goto do_3d;
14086                    default:
14087                        goto pool32f_invalid;
14088                    }
14089                    break;
14090                case ADDR_PS:
14091                    mips32_op = OPC_ADDR_PS;
14092                    goto do_3d;
14093                case MULR_PS:
14094                    mips32_op = OPC_MULR_PS;
14095                do_3d:
14096                    gen_farith(ctx, mips32_op, rt, rs, rd, 0);
14097                    break;
14098                default:
14099                    goto pool32f_invalid;
14100                }
14101                break;
14102            case 0x20:
14103                /* MOV[FT].fmt, PREFX, RINT.fmt, CLASS.fmt*/
14104                cc = (ctx->opcode >> 13) & 0x7;
14105                fmt = (ctx->opcode >> 9) & 0x3;
14106                switch ((ctx->opcode >> 6) & 0x7) {
14107                case MOVF_FMT: /* RINT_FMT */
14108                    if (ctx->insn_flags & ISA_MIPS32R6) {
14109                        /* RINT_FMT */
14110                        switch (fmt) {
14111                        case FMT_SDPS_S:
14112                            gen_farith(ctx, OPC_RINT_S, 0, rt, rs, 0);
14113                            break;
14114                        case FMT_SDPS_D:
14115                            gen_farith(ctx, OPC_RINT_D, 0, rt, rs, 0);
14116                            break;
14117                        default:
14118                            goto pool32f_invalid;
14119                        }
14120                    } else {
14121                        /* MOVF_FMT */
14122                        switch (fmt) {
14123                        case FMT_SDPS_S:
14124                            gen_movcf_s(ctx, rs, rt, cc, 0);
14125                            break;
14126                        case FMT_SDPS_D:
14127                            gen_movcf_d(ctx, rs, rt, cc, 0);
14128                            break;
14129                        case FMT_SDPS_PS:
14130                            check_ps(ctx);
14131                            gen_movcf_ps(ctx, rs, rt, cc, 0);
14132                            break;
14133                        default:
14134                            goto pool32f_invalid;
14135                        }
14136                    }
14137                    break;
14138                case MOVT_FMT: /* CLASS_FMT */
14139                    if (ctx->insn_flags & ISA_MIPS32R6) {
14140                        /* CLASS_FMT */
14141                        switch (fmt) {
14142                        case FMT_SDPS_S:
14143                            gen_farith(ctx, OPC_CLASS_S, 0, rt, rs, 0);
14144                            break;
14145                        case FMT_SDPS_D:
14146                            gen_farith(ctx, OPC_CLASS_D, 0, rt, rs, 0);
14147                            break;
14148                        default:
14149                            goto pool32f_invalid;
14150                        }
14151                    } else {
14152                        /* MOVT_FMT */
14153                        switch (fmt) {
14154                        case FMT_SDPS_S:
14155                            gen_movcf_s(ctx, rs, rt, cc, 1);
14156                            break;
14157                        case FMT_SDPS_D:
14158                            gen_movcf_d(ctx, rs, rt, cc, 1);
14159                            break;
14160                        case FMT_SDPS_PS:
14161                            check_ps(ctx);
14162                            gen_movcf_ps(ctx, rs, rt, cc, 1);
14163                            break;
14164                        default:
14165                            goto pool32f_invalid;
14166                        }
14167                    }
14168                    break;
14169                case PREFX:
14170                    check_insn_opc_removed(ctx, ISA_MIPS32R6);
14171                    break;
14172                default:
14173                    goto pool32f_invalid;
14174                }
14175                break;
14176#define FINSN_3ARG_SDPS(prfx)                           \
14177                switch ((ctx->opcode >> 8) & 0x3) {     \
14178                case FMT_SDPS_S:                        \
14179                    mips32_op = OPC_##prfx##_S;         \
14180                    goto do_fpop;                       \
14181                case FMT_SDPS_D:                        \
14182                    mips32_op = OPC_##prfx##_D;         \
14183                    goto do_fpop;                       \
14184                case FMT_SDPS_PS:                       \
14185                    check_ps(ctx);                      \
14186                    mips32_op = OPC_##prfx##_PS;        \
14187                    goto do_fpop;                       \
14188                default:                                \
14189                    goto pool32f_invalid;               \
14190                }
14191            case MINA_FMT:
14192                check_insn(ctx, ISA_MIPS32R6);
14193                switch ((ctx->opcode >> 9) & 0x3) {
14194                case FMT_SDPS_S:
14195                    gen_farith(ctx, OPC_MINA_S, rt, rs, rd, 0);
14196                    break;
14197                case FMT_SDPS_D:
14198                    gen_farith(ctx, OPC_MINA_D, rt, rs, rd, 0);
14199                    break;
14200                default:
14201                    goto pool32f_invalid;
14202                }
14203                break;
14204            case MAXA_FMT:
14205                check_insn(ctx, ISA_MIPS32R6);
14206                switch ((ctx->opcode >> 9) & 0x3) {
14207                case FMT_SDPS_S:
14208                    gen_farith(ctx, OPC_MAXA_S, rt, rs, rd, 0);
14209                    break;
14210                case FMT_SDPS_D:
14211                    gen_farith(ctx, OPC_MAXA_D, rt, rs, rd, 0);
14212                    break;
14213                default:
14214                    goto pool32f_invalid;
14215                }
14216                break;
14217            case 0x30:
14218                /* regular FP ops */
14219                switch ((ctx->opcode >> 6) & 0x3) {
14220                case ADD_FMT:
14221                    FINSN_3ARG_SDPS(ADD);
14222                    break;
14223                case SUB_FMT:
14224                    FINSN_3ARG_SDPS(SUB);
14225                    break;
14226                case MUL_FMT:
14227                    FINSN_3ARG_SDPS(MUL);
14228                    break;
14229                case DIV_FMT:
14230                    fmt = (ctx->opcode >> 8) & 0x3;
14231                    if (fmt == 1) {
14232                        mips32_op = OPC_DIV_D;
14233                    } else if (fmt == 0) {
14234                        mips32_op = OPC_DIV_S;
14235                    } else {
14236                        goto pool32f_invalid;
14237                    }
14238                    goto do_fpop;
14239                default:
14240                    goto pool32f_invalid;
14241                }
14242                break;
14243            case 0x38:
14244                /* cmovs */
14245                switch ((ctx->opcode >> 6) & 0x7) {
14246                case MOVN_FMT: /* SELNEZ_FMT */
14247                    if (ctx->insn_flags & ISA_MIPS32R6) {
14248                        /* SELNEZ_FMT */
14249                        switch ((ctx->opcode >> 9) & 0x3) {
14250                        case FMT_SDPS_S:
14251                            gen_sel_s(ctx, OPC_SELNEZ_S, rd, rt, rs);
14252                            break;
14253                        case FMT_SDPS_D:
14254                            gen_sel_d(ctx, OPC_SELNEZ_D, rd, rt, rs);
14255                            break;
14256                        default:
14257                            goto pool32f_invalid;
14258                        }
14259                    } else {
14260                        /* MOVN_FMT */
14261                        FINSN_3ARG_SDPS(MOVN);
14262                    }
14263                    break;
14264                case MOVN_FMT_04:
14265                    check_insn_opc_removed(ctx, ISA_MIPS32R6);
14266                    FINSN_3ARG_SDPS(MOVN);
14267                    break;
14268                case MOVZ_FMT: /* SELEQZ_FMT */
14269                    if (ctx->insn_flags & ISA_MIPS32R6) {
14270                        /* SELEQZ_FMT */
14271                        switch ((ctx->opcode >> 9) & 0x3) {
14272                        case FMT_SDPS_S:
14273                            gen_sel_s(ctx, OPC_SELEQZ_S, rd, rt, rs);
14274                            break;
14275                        case FMT_SDPS_D:
14276                            gen_sel_d(ctx, OPC_SELEQZ_D, rd, rt, rs);
14277                            break;
14278                        default:
14279                            goto pool32f_invalid;
14280                        }
14281                    } else {
14282                        /* MOVZ_FMT */
14283                        FINSN_3ARG_SDPS(MOVZ);
14284                    }
14285                    break;
14286                case MOVZ_FMT_05:
14287                    check_insn_opc_removed(ctx, ISA_MIPS32R6);
14288                    FINSN_3ARG_SDPS(MOVZ);
14289                    break;
14290                case SEL_FMT:
14291                    check_insn(ctx, ISA_MIPS32R6);
14292                    switch ((ctx->opcode >> 9) & 0x3) {
14293                    case FMT_SDPS_S:
14294                        gen_sel_s(ctx, OPC_SEL_S, rd, rt, rs);
14295                        break;
14296                    case FMT_SDPS_D:
14297                        gen_sel_d(ctx, OPC_SEL_D, rd, rt, rs);
14298                        break;
14299                    default:
14300                        goto pool32f_invalid;
14301                    }
14302                    break;
14303                case MADDF_FMT:
14304                    check_insn(ctx, ISA_MIPS32R6);
14305                    switch ((ctx->opcode >> 9) & 0x3) {
14306                    case FMT_SDPS_S:
14307                        mips32_op = OPC_MADDF_S;
14308                        goto do_fpop;
14309                    case FMT_SDPS_D:
14310                        mips32_op = OPC_MADDF_D;
14311                        goto do_fpop;
14312                    default:
14313                        goto pool32f_invalid;
14314                    }
14315                    break;
14316                case MSUBF_FMT:
14317                    check_insn(ctx, ISA_MIPS32R6);
14318                    switch ((ctx->opcode >> 9) & 0x3) {
14319                    case FMT_SDPS_S:
14320                        mips32_op = OPC_MSUBF_S;
14321                        goto do_fpop;
14322                    case FMT_SDPS_D:
14323                        mips32_op = OPC_MSUBF_D;
14324                        goto do_fpop;
14325                    default:
14326                        goto pool32f_invalid;
14327                    }
14328                    break;
14329                default:
14330                    goto pool32f_invalid;
14331                }
14332                break;
14333            do_fpop:
14334                gen_farith(ctx, mips32_op, rt, rs, rd, 0);
14335                break;
14336            default:
14337            pool32f_invalid:
14338                MIPS_INVAL("pool32f");
14339                generate_exception_end(ctx, EXCP_RI);
14340                break;
14341            }
14342        } else {
14343            generate_exception_err(ctx, EXCP_CpU, 1);
14344        }
14345        break;
14346    case POOL32I:
14347        minor = (ctx->opcode >> 21) & 0x1f;
14348        switch (minor) {
14349        case BLTZ:
14350            check_insn_opc_removed(ctx, ISA_MIPS32R6);
14351            gen_compute_branch(ctx, OPC_BLTZ, 4, rs, -1, imm << 1, 4);
14352            break;
14353        case BLTZAL:
14354            check_insn_opc_removed(ctx, ISA_MIPS32R6);
14355            gen_compute_branch(ctx, OPC_BLTZAL, 4, rs, -1, imm << 1, 4);
14356            ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
14357            break;
14358        case BLTZALS:
14359            check_insn_opc_removed(ctx, ISA_MIPS32R6);
14360            gen_compute_branch(ctx, OPC_BLTZAL, 4, rs, -1, imm << 1, 2);
14361            ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
14362            break;
14363        case BGEZ:
14364            check_insn_opc_removed(ctx, ISA_MIPS32R6);
14365            gen_compute_branch(ctx, OPC_BGEZ, 4, rs, -1, imm << 1, 4);
14366            break;
14367        case BGEZAL:
14368            check_insn_opc_removed(ctx, ISA_MIPS32R6);
14369            gen_compute_branch(ctx, OPC_BGEZAL, 4, rs, -1, imm << 1, 4);
14370            ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
14371            break;
14372        case BGEZALS:
14373            check_insn_opc_removed(ctx, ISA_MIPS32R6);
14374            gen_compute_branch(ctx, OPC_BGEZAL, 4, rs, -1, imm << 1, 2);
14375            ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
14376            break;
14377        case BLEZ:
14378            check_insn_opc_removed(ctx, ISA_MIPS32R6);
14379            gen_compute_branch(ctx, OPC_BLEZ, 4, rs, -1, imm << 1, 4);
14380            break;
14381        case BGTZ:
14382            check_insn_opc_removed(ctx, ISA_MIPS32R6);
14383            gen_compute_branch(ctx, OPC_BGTZ, 4, rs, -1, imm << 1, 4);
14384            break;
14385
14386            /* Traps */
14387        case TLTI: /* BC1EQZC */
14388            if (ctx->insn_flags & ISA_MIPS32R6) {
14389                /* BC1EQZC */
14390                check_cp1_enabled(ctx);
14391                gen_compute_branch1_r6(ctx, OPC_BC1EQZ, rs, imm << 1, 0);
14392            } else {
14393                /* TLTI */
14394                mips32_op = OPC_TLTI;
14395                goto do_trapi;
14396            }
14397            break;
14398        case TGEI: /* BC1NEZC */
14399            if (ctx->insn_flags & ISA_MIPS32R6) {
14400                /* BC1NEZC */
14401                check_cp1_enabled(ctx);
14402                gen_compute_branch1_r6(ctx, OPC_BC1NEZ, rs, imm << 1, 0);
14403            } else {
14404                /* TGEI */
14405                mips32_op = OPC_TGEI;
14406                goto do_trapi;
14407            }
14408            break;
14409        case TLTIU:
14410            check_insn_opc_removed(ctx, ISA_MIPS32R6);
14411            mips32_op = OPC_TLTIU;
14412            goto do_trapi;
14413        case TGEIU:
14414            check_insn_opc_removed(ctx, ISA_MIPS32R6);
14415            mips32_op = OPC_TGEIU;
14416            goto do_trapi;
14417        case TNEI: /* SYNCI */
14418            if (ctx->insn_flags & ISA_MIPS32R6) {
14419                /* SYNCI */
14420                /* Break the TB to be able to sync copied instructions
14421                   immediately */
14422                ctx->bstate = BS_STOP;
14423            } else {
14424                /* TNEI */
14425                mips32_op = OPC_TNEI;
14426                goto do_trapi;
14427            }
14428            break;
14429        case TEQI:
14430            check_insn_opc_removed(ctx, ISA_MIPS32R6);
14431            mips32_op = OPC_TEQI;
14432        do_trapi:
14433            gen_trap(ctx, mips32_op, rs, -1, imm);
14434            break;
14435
14436        case BNEZC:
14437        case BEQZC:
14438            check_insn_opc_removed(ctx, ISA_MIPS32R6);
14439            gen_compute_branch(ctx, minor == BNEZC ? OPC_BNE : OPC_BEQ,
14440                               4, rs, 0, imm << 1, 0);
14441            /* Compact branches don't have a delay slot, so just let
14442               the normal delay slot handling take us to the branch
14443               target. */
14444            break;
14445        case LUI:
14446            check_insn_opc_removed(ctx, ISA_MIPS32R6);
14447            gen_logic_imm(ctx, OPC_LUI, rs, 0, imm);
14448            break;
14449        case SYNCI:
14450            check_insn_opc_removed(ctx, ISA_MIPS32R6);
14451            /* Break the TB to be able to sync copied instructions
14452               immediately */
14453            ctx->bstate = BS_STOP;
14454            break;
14455        case BC2F:
14456        case BC2T:
14457            check_insn_opc_removed(ctx, ISA_MIPS32R6);
14458            /* COP2: Not implemented. */
14459            generate_exception_err(ctx, EXCP_CpU, 2);
14460            break;
14461        case BC1F:
14462            check_insn_opc_removed(ctx, ISA_MIPS32R6);
14463            mips32_op = (ctx->opcode & (1 << 16)) ? OPC_BC1FANY2 : OPC_BC1F;
14464            goto do_cp1branch;
14465        case BC1T:
14466            check_insn_opc_removed(ctx, ISA_MIPS32R6);
14467            mips32_op = (ctx->opcode & (1 << 16)) ? OPC_BC1TANY2 : OPC_BC1T;
14468            goto do_cp1branch;
14469        case BC1ANY4F:
14470            check_insn_opc_removed(ctx, ISA_MIPS32R6);
14471            mips32_op = OPC_BC1FANY4;
14472            goto do_cp1mips3d;
14473        case BC1ANY4T:
14474            check_insn_opc_removed(ctx, ISA_MIPS32R6);
14475            mips32_op = OPC_BC1TANY4;
14476        do_cp1mips3d:
14477            check_cop1x(ctx);
14478            check_insn(ctx, ASE_MIPS3D);
14479            /* Fall through */
14480        do_cp1branch:
14481            if (env->CP0_Config1 & (1 << CP0C1_FP)) {
14482                check_cp1_enabled(ctx);
14483                gen_compute_branch1(ctx, mips32_op,
14484                                    (ctx->opcode >> 18) & 0x7, imm << 1);
14485            } else {
14486                generate_exception_err(ctx, EXCP_CpU, 1);
14487            }
14488            break;
14489        case BPOSGE64:
14490        case BPOSGE32:
14491            /* MIPS DSP: not implemented */
14492            /* Fall through */
14493        default:
14494            MIPS_INVAL("pool32i");
14495            generate_exception_end(ctx, EXCP_RI);
14496            break;
14497        }
14498        break;
14499    case POOL32C:
14500        minor = (ctx->opcode >> 12) & 0xf;
14501        offset = sextract32(ctx->opcode, 0,
14502                            (ctx->insn_flags & ISA_MIPS32R6) ? 9 : 12);
14503        switch (minor) {
14504        case LWL:
14505            check_insn_opc_removed(ctx, ISA_MIPS32R6);
14506            mips32_op = OPC_LWL;
14507            goto do_ld_lr;
14508        case SWL:
14509            check_insn_opc_removed(ctx, ISA_MIPS32R6);
14510            mips32_op = OPC_SWL;
14511            goto do_st_lr;
14512        case LWR:
14513            check_insn_opc_removed(ctx, ISA_MIPS32R6);
14514            mips32_op = OPC_LWR;
14515            goto do_ld_lr;
14516        case SWR:
14517            check_insn_opc_removed(ctx, ISA_MIPS32R6);
14518            mips32_op = OPC_SWR;
14519            goto do_st_lr;
14520#if defined(TARGET_MIPS64)
14521        case LDL:
14522            check_insn(ctx, ISA_MIPS3);
14523            check_mips_64(ctx);
14524            check_insn_opc_removed(ctx, ISA_MIPS32R6);
14525            mips32_op = OPC_LDL;
14526            goto do_ld_lr;
14527        case SDL:
14528            check_insn(ctx, ISA_MIPS3);
14529            check_mips_64(ctx);
14530            check_insn_opc_removed(ctx, ISA_MIPS32R6);
14531            mips32_op = OPC_SDL;
14532            goto do_st_lr;
14533        case LDR:
14534            check_insn(ctx, ISA_MIPS3);
14535            check_mips_64(ctx);
14536            check_insn_opc_removed(ctx, ISA_MIPS32R6);
14537            mips32_op = OPC_LDR;
14538            goto do_ld_lr;
14539        case SDR:
14540            check_insn(ctx, ISA_MIPS3);
14541            check_mips_64(ctx);
14542            check_insn_opc_removed(ctx, ISA_MIPS32R6);
14543            mips32_op = OPC_SDR;
14544            goto do_st_lr;
14545        case LWU:
14546            check_insn(ctx, ISA_MIPS3);
14547            check_mips_64(ctx);
14548            mips32_op = OPC_LWU;
14549            goto do_ld_lr;
14550        case LLD:
14551            check_insn(ctx, ISA_MIPS3);
14552            check_mips_64(ctx);
14553            mips32_op = OPC_LLD;
14554            goto do_ld_lr;
14555#endif
14556        case LL:
14557            mips32_op = OPC_LL;
14558            goto do_ld_lr;
14559        do_ld_lr:
14560            gen_ld(ctx, mips32_op, rt, rs, offset);
14561            break;
14562        do_st_lr:
14563            gen_st(ctx, mips32_op, rt, rs, SIMM(ctx->opcode, 0, 12));
14564            break;
14565        case SC:
14566            gen_st_cond(ctx, OPC_SC, rt, rs, offset);
14567            break;
14568#if defined(TARGET_MIPS64)
14569        case SCD:
14570            check_insn(ctx, ISA_MIPS3);
14571            check_mips_64(ctx);
14572            gen_st_cond(ctx, OPC_SCD, rt, rs, offset);
14573            break;
14574#endif
14575        case PREF:
14576            /* Treat as no-op */
14577            if ((ctx->insn_flags & ISA_MIPS32R6) && (rt >= 24)) {
14578                /* hint codes 24-31 are reserved and signal RI */
14579                generate_exception(ctx, EXCP_RI);
14580            }
14581            break;
14582        default:
14583            MIPS_INVAL("pool32c");
14584            generate_exception_end(ctx, EXCP_RI);
14585            break;
14586        }
14587        break;
14588    case ADDI32: /* AUI, LUI */
14589        if (ctx->insn_flags & ISA_MIPS32R6) {
14590            /* AUI, LUI */
14591            gen_logic_imm(ctx, OPC_LUI, rt, rs, imm);
14592        } else {
14593            /* ADDI32 */
14594            mips32_op = OPC_ADDI;
14595            goto do_addi;
14596        }
14597        break;
14598    case ADDIU32:
14599        mips32_op = OPC_ADDIU;
14600    do_addi:
14601        gen_arith_imm(ctx, mips32_op, rt, rs, imm);
14602        break;
14603
14604        /* Logical operations */
14605    case ORI32:
14606        mips32_op = OPC_ORI;
14607        goto do_logici;
14608    case XORI32:
14609        mips32_op = OPC_XORI;
14610        goto do_logici;
14611    case ANDI32:
14612        mips32_op = OPC_ANDI;
14613    do_logici:
14614        gen_logic_imm(ctx, mips32_op, rt, rs, imm);
14615        break;
14616
14617        /* Set less than immediate */
14618    case SLTI32:
14619        mips32_op = OPC_SLTI;
14620        goto do_slti;
14621    case SLTIU32:
14622        mips32_op = OPC_SLTIU;
14623    do_slti:
14624        gen_slt_imm(ctx, mips32_op, rt, rs, imm);
14625        break;
14626    case JALX32:
14627        check_insn_opc_removed(ctx, ISA_MIPS32R6);
14628        offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 2;
14629        gen_compute_branch(ctx, OPC_JALX, 4, rt, rs, offset, 4);
14630        ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
14631        break;
14632    case JALS32: /* BOVC, BEQC, BEQZALC */
14633        if (ctx->insn_flags & ISA_MIPS32R6) {
14634            if (rs >= rt) {
14635                /* BOVC */
14636                mips32_op = OPC_BOVC;
14637            } else if (rs < rt && rs == 0) {
14638                /* BEQZALC */
14639                mips32_op = OPC_BEQZALC;
14640            } else {
14641                /* BEQC */
14642                mips32_op = OPC_BEQC;
14643            }
14644            gen_compute_compact_branch(ctx, mips32_op, rs, rt, imm << 1);
14645        } else {
14646            /* JALS32 */
14647            offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 1;
14648            gen_compute_branch(ctx, OPC_JAL, 4, rt, rs, offset, 2);
14649            ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
14650        }
14651        break;
14652    case BEQ32: /* BC */
14653        if (ctx->insn_flags & ISA_MIPS32R6) {
14654            /* BC */
14655            gen_compute_compact_branch(ctx, OPC_BC, 0, 0,
14656                                       sextract32(ctx->opcode << 1, 0, 27));
14657        } else {
14658            /* BEQ32 */
14659            gen_compute_branch(ctx, OPC_BEQ, 4, rt, rs, imm << 1, 4);
14660        }
14661        break;
14662    case BNE32: /* BALC */
14663        if (ctx->insn_flags & ISA_MIPS32R6) {
14664            /* BALC */
14665            gen_compute_compact_branch(ctx, OPC_BALC, 0, 0,
14666                                       sextract32(ctx->opcode << 1, 0, 27));
14667        } else {
14668            /* BNE32 */
14669            gen_compute_branch(ctx, OPC_BNE, 4, rt, rs, imm << 1, 4);
14670        }
14671        break;
14672    case J32: /* BGTZC, BLTZC, BLTC */
14673        if (ctx->insn_flags & ISA_MIPS32R6) {
14674            if (rs == 0 && rt != 0) {
14675                /* BGTZC */
14676                mips32_op = OPC_BGTZC;
14677            } else if (rs != 0 && rt != 0 && rs == rt) {
14678                /* BLTZC */
14679                mips32_op = OPC_BLTZC;
14680            } else {
14681                /* BLTC */
14682                mips32_op = OPC_BLTC;
14683            }
14684            gen_compute_compact_branch(ctx, mips32_op, rs, rt, imm << 1);
14685        } else {
14686            /* J32 */
14687            gen_compute_branch(ctx, OPC_J, 4, rt, rs,
14688                               (int32_t)(ctx->opcode & 0x3FFFFFF) << 1, 4);
14689        }
14690        break;
14691    case JAL32: /* BLEZC, BGEZC, BGEC */
14692        if (ctx->insn_flags & ISA_MIPS32R6) {
14693            if (rs == 0 && rt != 0) {
14694                /* BLEZC */
14695                mips32_op = OPC_BLEZC;
14696            } else if (rs != 0 && rt != 0 && rs == rt) {
14697                /* BGEZC */
14698                mips32_op = OPC_BGEZC;
14699            } else {
14700                /* BGEC */
14701                mips32_op = OPC_BGEC;
14702            }
14703            gen_compute_compact_branch(ctx, mips32_op, rs, rt, imm << 1);
14704        } else {
14705            /* JAL32 */
14706            gen_compute_branch(ctx, OPC_JAL, 4, rt, rs,
14707                               (int32_t)(ctx->opcode & 0x3FFFFFF) << 1, 4);
14708            ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
14709        }
14710        break;
14711        /* Floating point (COP1) */
14712    case LWC132:
14713        mips32_op = OPC_LWC1;
14714        goto do_cop1;
14715    case LDC132:
14716        mips32_op = OPC_LDC1;
14717        goto do_cop1;
14718    case SWC132:
14719        mips32_op = OPC_SWC1;
14720        goto do_cop1;
14721    case SDC132:
14722        mips32_op = OPC_SDC1;
14723    do_cop1:
14724        gen_cop1_ldst(ctx, mips32_op, rt, rs, imm);
14725        break;
14726    case ADDIUPC: /* PCREL: ADDIUPC, AUIPC, ALUIPC, LWPC */
14727        if (ctx->insn_flags & ISA_MIPS32R6) {
14728            /* PCREL: ADDIUPC, AUIPC, ALUIPC, LWPC */
14729            switch ((ctx->opcode >> 16) & 0x1f) {
14730            case ADDIUPC_00 ... ADDIUPC_07:
14731                gen_pcrel(ctx, OPC_ADDIUPC, ctx->pc & ~0x3, rt);
14732                break;
14733            case AUIPC:
14734                gen_pcrel(ctx, OPC_AUIPC, ctx->pc, rt);
14735                break;
14736            case ALUIPC:
14737                gen_pcrel(ctx, OPC_ALUIPC, ctx->pc, rt);
14738                break;
14739            case LWPC_08 ... LWPC_0F:
14740                gen_pcrel(ctx, R6_OPC_LWPC, ctx->pc & ~0x3, rt);
14741                break;
14742            default:
14743                generate_exception(ctx, EXCP_RI);
14744                break;
14745            }
14746        } else {
14747            /* ADDIUPC */
14748            int reg = mmreg(ZIMM(ctx->opcode, 23, 3));
14749            int offset = SIMM(ctx->opcode, 0, 23) << 2;
14750
14751            gen_addiupc(ctx, reg, offset, 0, 0);
14752        }
14753        break;
14754    case BNVC: /* BNEC, BNEZALC */
14755        check_insn(ctx, ISA_MIPS32R6);
14756        if (rs >= rt) {
14757            /* BNVC */
14758            mips32_op = OPC_BNVC;
14759        } else if (rs < rt && rs == 0) {
14760            /* BNEZALC */
14761            mips32_op = OPC_BNEZALC;
14762        } else {
14763            /* BNEC */
14764            mips32_op = OPC_BNEC;
14765        }
14766        gen_compute_compact_branch(ctx, mips32_op, rs, rt, imm << 1);
14767        break;
14768    case R6_BNEZC: /* JIALC */
14769        check_insn(ctx, ISA_MIPS32R6);
14770        if (rt != 0) {
14771            /* BNEZC */
14772            gen_compute_compact_branch(ctx, OPC_BNEZC, rt, 0,
14773                                       sextract32(ctx->opcode << 1, 0, 22));
14774        } else {
14775            /* JIALC */
14776            gen_compute_compact_branch(ctx, OPC_JIALC, 0, rs, imm);
14777        }
14778        break;
14779    case R6_BEQZC: /* JIC */
14780        check_insn(ctx, ISA_MIPS32R6);
14781        if (rt != 0) {
14782            /* BEQZC */
14783            gen_compute_compact_branch(ctx, OPC_BEQZC, rt, 0,
14784                                       sextract32(ctx->opcode << 1, 0, 22));
14785        } else {
14786            /* JIC */
14787            gen_compute_compact_branch(ctx, OPC_JIC, 0, rs, imm);
14788        }
14789        break;
14790    case BLEZALC: /* BGEZALC, BGEUC */
14791        check_insn(ctx, ISA_MIPS32R6);
14792        if (rs == 0 && rt != 0) {
14793            /* BLEZALC */
14794            mips32_op = OPC_BLEZALC;
14795        } else if (rs != 0 && rt != 0 && rs == rt) {
14796            /* BGEZALC */
14797            mips32_op = OPC_BGEZALC;
14798        } else {
14799            /* BGEUC */
14800            mips32_op = OPC_BGEUC;
14801        }
14802        gen_compute_compact_branch(ctx, mips32_op, rs, rt, imm << 1);
14803        break;
14804    case BGTZALC: /* BLTZALC, BLTUC */
14805        check_insn(ctx, ISA_MIPS32R6);
14806        if (rs == 0 && rt != 0) {
14807            /* BGTZALC */
14808            mips32_op = OPC_BGTZALC;
14809        } else if (rs != 0 && rt != 0 && rs == rt) {
14810            /* BLTZALC */
14811            mips32_op = OPC_BLTZALC;
14812        } else {
14813            /* BLTUC */
14814            mips32_op = OPC_BLTUC;
14815        }
14816        gen_compute_compact_branch(ctx, mips32_op, rs, rt, imm << 1);
14817        break;
14818        /* Loads and stores */
14819    case LB32:
14820        mips32_op = OPC_LB;
14821        goto do_ld;
14822    case LBU32:
14823        mips32_op = OPC_LBU;
14824        goto do_ld;
14825    case LH32:
14826        mips32_op = OPC_LH;
14827        goto do_ld;
14828    case LHU32:
14829        mips32_op = OPC_LHU;
14830        goto do_ld;
14831    case LW32:
14832        mips32_op = OPC_LW;
14833        goto do_ld;
14834#ifdef TARGET_MIPS64
14835    case LD32:
14836        check_insn(ctx, ISA_MIPS3);
14837        check_mips_64(ctx);
14838        mips32_op = OPC_LD;
14839        goto do_ld;
14840    case SD32:
14841        check_insn(ctx, ISA_MIPS3);
14842        check_mips_64(ctx);
14843        mips32_op = OPC_SD;
14844        goto do_st;
14845#endif
14846    case SB32:
14847        mips32_op = OPC_SB;
14848        goto do_st;
14849    case SH32:
14850        mips32_op = OPC_SH;
14851        goto do_st;
14852    case SW32:
14853        mips32_op = OPC_SW;
14854        goto do_st;
14855    do_ld:
14856        gen_ld(ctx, mips32_op, rt, rs, imm);
14857        break;
14858    do_st:
14859        gen_st(ctx, mips32_op, rt, rs, imm);
14860        break;
14861    default:
14862        generate_exception_end(ctx, EXCP_RI);
14863        break;
14864    }
14865}
14866
14867static int decode_micromips_opc (CPUMIPSState *env, DisasContext *ctx)
14868{
14869    uint32_t op;
14870
14871    /* make sure instructions are on a halfword boundary */
14872    if (ctx->pc & 0x1) {
14873        env->CP0_BadVAddr = ctx->pc;
14874        generate_exception_end(ctx, EXCP_AdEL);
14875        return 2;
14876    }
14877
14878    op = (ctx->opcode >> 10) & 0x3f;
14879    /* Enforce properly-sized instructions in a delay slot */
14880    if (ctx->hflags & MIPS_HFLAG_BDS_STRICT) {
14881        switch (op & 0x7) { /* MSB-3..MSB-5 */
14882        case 0:
14883        /* POOL32A, POOL32B, POOL32I, POOL32C */
14884        case 4:
14885        /* ADDI32, ADDIU32, ORI32, XORI32, SLTI32, SLTIU32, ANDI32, JALX32 */
14886        case 5:
14887        /* LBU32, LHU32, POOL32F, JALS32, BEQ32, BNE32, J32, JAL32 */
14888        case 6:
14889        /* SB32, SH32, ADDIUPC, SWC132, SDC132, SW32 */
14890        case 7:
14891        /* LB32, LH32, LWC132, LDC132, LW32 */
14892            if (ctx->hflags & MIPS_HFLAG_BDS16) {
14893                generate_exception_end(ctx, EXCP_RI);
14894                return 2;
14895            }
14896            break;
14897        case 1:
14898        /* POOL16A, POOL16B, POOL16C, LWGP16, POOL16F */
14899        case 2:
14900        /* LBU16, LHU16, LWSP16, LW16, SB16, SH16, SWSP16, SW16 */
14901        case 3:
14902        /* MOVE16, ANDI16, POOL16D, POOL16E, BEQZ16, BNEZ16, B16, LI16 */
14903            if (ctx->hflags & MIPS_HFLAG_BDS32) {
14904                generate_exception_end(ctx, EXCP_RI);
14905                return 2;
14906            }
14907            break;
14908        }
14909    }
14910
14911    switch (op) {
14912    case POOL16A:
14913        {
14914            int rd = mmreg(uMIPS_RD(ctx->opcode));
14915            int rs1 = mmreg(uMIPS_RS1(ctx->opcode));
14916            int rs2 = mmreg(uMIPS_RS2(ctx->opcode));
14917            uint32_t opc = 0;
14918
14919            switch (ctx->opcode & 0x1) {
14920            case ADDU16:
14921                opc = OPC_ADDU;
14922                break;
14923            case SUBU16:
14924                opc = OPC_SUBU;
14925                break;
14926            }
14927            if (ctx->insn_flags & ISA_MIPS32R6) {
14928                /* In the Release 6 the register number location in
14929                 * the instruction encoding has changed.
14930                 */
14931                gen_arith(ctx, opc, rs1, rd, rs2);
14932            } else {
14933                gen_arith(ctx, opc, rd, rs1, rs2);
14934            }
14935        }
14936        break;
14937    case POOL16B:
14938        {
14939            int rd = mmreg(uMIPS_RD(ctx->opcode));
14940            int rs = mmreg(uMIPS_RS(ctx->opcode));
14941            int amount = (ctx->opcode >> 1) & 0x7;
14942            uint32_t opc = 0;
14943            amount = amount == 0 ? 8 : amount;
14944
14945            switch (ctx->opcode & 0x1) {
14946            case SLL16:
14947                opc = OPC_SLL;
14948                break;
14949            case SRL16:
14950                opc = OPC_SRL;
14951                break;
14952            }
14953
14954            gen_shift_imm(ctx, opc, rd, rs, amount);
14955        }
14956        break;
14957    case POOL16C:
14958        if (ctx->insn_flags & ISA_MIPS32R6) {
14959            gen_pool16c_r6_insn(ctx);
14960        } else {
14961            gen_pool16c_insn(ctx);
14962        }
14963        break;
14964    case LWGP16:
14965        {
14966            int rd = mmreg(uMIPS_RD(ctx->opcode));
14967            int rb = 28;            /* GP */
14968            int16_t offset = SIMM(ctx->opcode, 0, 7) << 2;
14969
14970            gen_ld(ctx, OPC_LW, rd, rb, offset);
14971        }
14972        break;
14973    case POOL16F:
14974        check_insn_opc_removed(ctx, ISA_MIPS32R6);
14975        if (ctx->opcode & 1) {
14976            generate_exception_end(ctx, EXCP_RI);
14977        } else {
14978            /* MOVEP */
14979            int enc_dest = uMIPS_RD(ctx->opcode);
14980            int enc_rt = uMIPS_RS2(ctx->opcode);
14981            int enc_rs = uMIPS_RS1(ctx->opcode);
14982            gen_movep(ctx, enc_dest, enc_rt, enc_rs);
14983        }
14984        break;
14985    case LBU16:
14986        {
14987            int rd = mmreg(uMIPS_RD(ctx->opcode));
14988            int rb = mmreg(uMIPS_RS(ctx->opcode));
14989            int16_t offset = ZIMM(ctx->opcode, 0, 4);
14990            offset = (offset == 0xf ? -1 : offset);
14991
14992            gen_ld(ctx, OPC_LBU, rd, rb, offset);
14993        }
14994        break;
14995    case LHU16:
14996        {
14997            int rd = mmreg(uMIPS_RD(ctx->opcode));
14998            int rb = mmreg(uMIPS_RS(ctx->opcode));
14999            int16_t offset = ZIMM(ctx->opcode, 0, 4) << 1;
15000
15001            gen_ld(ctx, OPC_LHU, rd, rb, offset);
15002        }
15003        break;
15004    case LWSP16:
15005        {
15006            int rd = (ctx->opcode >> 5) & 0x1f;
15007            int rb = 29;            /* SP */
15008            int16_t offset = ZIMM(ctx->opcode, 0, 5) << 2;
15009
15010            gen_ld(ctx, OPC_LW, rd, rb, offset);
15011        }
15012        break;
15013    case LW16:
15014        {
15015            int rd = mmreg(uMIPS_RD(ctx->opcode));
15016            int rb = mmreg(uMIPS_RS(ctx->opcode));
15017            int16_t offset = ZIMM(ctx->opcode, 0, 4) << 2;
15018
15019            gen_ld(ctx, OPC_LW, rd, rb, offset);
15020        }
15021        break;
15022    case SB16:
15023        {
15024            int rd = mmreg2(uMIPS_RD(ctx->opcode));
15025            int rb = mmreg(uMIPS_RS(ctx->opcode));
15026            int16_t offset = ZIMM(ctx->opcode, 0, 4);
15027
15028            gen_st(ctx, OPC_SB, rd, rb, offset);
15029        }
15030        break;
15031    case SH16:
15032        {
15033            int rd = mmreg2(uMIPS_RD(ctx->opcode));
15034            int rb = mmreg(uMIPS_RS(ctx->opcode));
15035            int16_t offset = ZIMM(ctx->opcode, 0, 4) << 1;
15036
15037            gen_st(ctx, OPC_SH, rd, rb, offset);
15038        }
15039        break;
15040    case SWSP16:
15041        {
15042            int rd = (ctx->opcode >> 5) & 0x1f;
15043            int rb = 29;            /* SP */
15044            int16_t offset = ZIMM(ctx->opcode, 0, 5) << 2;
15045
15046            gen_st(ctx, OPC_SW, rd, rb, offset);
15047        }
15048        break;
15049    case SW16:
15050        {
15051            int rd = mmreg2(uMIPS_RD(ctx->opcode));
15052            int rb = mmreg(uMIPS_RS(ctx->opcode));
15053            int16_t offset = ZIMM(ctx->opcode, 0, 4) << 2;
15054
15055            gen_st(ctx, OPC_SW, rd, rb, offset);
15056        }
15057        break;
15058    case MOVE16:
15059        {
15060            int rd = uMIPS_RD5(ctx->opcode);
15061            int rs = uMIPS_RS5(ctx->opcode);
15062
15063            gen_arith(ctx, OPC_ADDU, rd, rs, 0);
15064        }
15065        break;
15066    case ANDI16:
15067        gen_andi16(ctx);
15068        break;
15069    case POOL16D:
15070        switch (ctx->opcode & 0x1) {
15071        case ADDIUS5:
15072            gen_addius5(ctx);
15073            break;
15074        case ADDIUSP:
15075            gen_addiusp(ctx);
15076            break;
15077        }
15078        break;
15079    case POOL16E:
15080        switch (ctx->opcode & 0x1) {
15081        case ADDIUR2:
15082            gen_addiur2(ctx);
15083            break;
15084        case ADDIUR1SP:
15085            gen_addiur1sp(ctx);
15086            break;
15087        }
15088        break;
15089    case B16: /* BC16 */
15090        gen_compute_branch(ctx, OPC_BEQ, 2, 0, 0,
15091                           sextract32(ctx->opcode, 0, 10) << 1,
15092                           (ctx->insn_flags & ISA_MIPS32R6) ? 0 : 4);
15093        break;
15094    case BNEZ16: /* BNEZC16 */
15095    case BEQZ16: /* BEQZC16 */
15096        gen_compute_branch(ctx, op == BNEZ16 ? OPC_BNE : OPC_BEQ, 2,
15097                           mmreg(uMIPS_RD(ctx->opcode)),
15098                           0, sextract32(ctx->opcode, 0, 7) << 1,
15099                           (ctx->insn_flags & ISA_MIPS32R6) ? 0 : 4);
15100
15101        break;
15102    case LI16:
15103        {
15104            int reg = mmreg(uMIPS_RD(ctx->opcode));
15105            int imm = ZIMM(ctx->opcode, 0, 7);
15106
15107            imm = (imm == 0x7f ? -1 : imm);
15108            tcg_gen_movi_tl(cpu_gpr[reg], imm);
15109        }
15110        break;
15111    case RES_29:
15112    case RES_31:
15113    case RES_39:
15114        generate_exception_end(ctx, EXCP_RI);
15115        break;
15116    default:
15117        decode_micromips32_opc(env, ctx);
15118        return 4;
15119    }
15120
15121    return 2;
15122}
15123
15124/* SmartMIPS extension to MIPS32 */
15125
15126#if defined(TARGET_MIPS64)
15127
15128/* MDMX extension to MIPS64 */
15129
15130#endif
15131
15132/* MIPSDSP functions. */
15133static void gen_mipsdsp_ld(DisasContext *ctx, uint32_t opc,
15134                           int rd, int base, int offset)
15135{
15136    TCGv t0;
15137
15138    check_dsp(ctx);
15139    t0 = tcg_temp_new();
15140
15141    if (base == 0) {
15142        gen_load_gpr(t0, offset);
15143    } else if (offset == 0) {
15144        gen_load_gpr(t0, base);
15145    } else {
15146        gen_op_addr_add(ctx, t0, cpu_gpr[base], cpu_gpr[offset]);
15147    }
15148
15149    switch (opc) {
15150    case OPC_LBUX:
15151        tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_UB);
15152        gen_store_gpr(t0, rd);
15153        break;
15154    case OPC_LHX:
15155        tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TESW);
15156        gen_store_gpr(t0, rd);
15157        break;
15158    case OPC_LWX:
15159        tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TESL);
15160        gen_store_gpr(t0, rd);
15161        break;
15162#if defined(TARGET_MIPS64)
15163    case OPC_LDX:
15164        tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEQ);
15165        gen_store_gpr(t0, rd);
15166        break;
15167#endif
15168    }
15169    tcg_temp_free(t0);
15170}
15171
15172static void gen_mipsdsp_arith(DisasContext *ctx, uint32_t op1, uint32_t op2,
15173                              int ret, int v1, int v2)
15174{
15175    TCGv v1_t;
15176    TCGv v2_t;
15177
15178    if (ret == 0) {
15179        /* Treat as NOP. */
15180        return;
15181    }
15182
15183    v1_t = tcg_temp_new();
15184    v2_t = tcg_temp_new();
15185
15186    gen_load_gpr(v1_t, v1);
15187    gen_load_gpr(v2_t, v2);
15188
15189    switch (op1) {
15190    /* OPC_MULT_G_2E is equal OPC_ADDUH_QB_DSP */
15191    case OPC_MULT_G_2E:
15192        check_dspr2(ctx);
15193        switch (op2) {
15194        case OPC_ADDUH_QB:
15195            gen_helper_adduh_qb(cpu_gpr[ret], v1_t, v2_t);
15196            break;
15197        case OPC_ADDUH_R_QB:
15198            gen_helper_adduh_r_qb(cpu_gpr[ret], v1_t, v2_t);
15199            break;
15200        case OPC_ADDQH_PH:
15201            gen_helper_addqh_ph(cpu_gpr[ret], v1_t, v2_t);
15202            break;
15203        case OPC_ADDQH_R_PH:
15204            gen_helper_addqh_r_ph(cpu_gpr[ret], v1_t, v2_t);
15205            break;
15206        case OPC_ADDQH_W:
15207            gen_helper_addqh_w(cpu_gpr[ret], v1_t, v2_t);
15208            break;
15209        case OPC_ADDQH_R_W:
15210            gen_helper_addqh_r_w(cpu_gpr[ret], v1_t, v2_t);
15211            break;
15212        case OPC_SUBUH_QB:
15213            gen_helper_subuh_qb(cpu_gpr[ret], v1_t, v2_t);
15214            break;
15215        case OPC_SUBUH_R_QB:
15216            gen_helper_subuh_r_qb(cpu_gpr[ret], v1_t, v2_t);
15217            break;
15218        case OPC_SUBQH_PH:
15219            gen_helper_subqh_ph(cpu_gpr[ret], v1_t, v2_t);
15220            break;
15221        case OPC_SUBQH_R_PH:
15222            gen_helper_subqh_r_ph(cpu_gpr[ret], v1_t, v2_t);
15223            break;
15224        case OPC_SUBQH_W:
15225            gen_helper_subqh_w(cpu_gpr[ret], v1_t, v2_t);
15226            break;
15227        case OPC_SUBQH_R_W:
15228            gen_helper_subqh_r_w(cpu_gpr[ret], v1_t, v2_t);
15229            break;
15230        }
15231        break;
15232    case OPC_ABSQ_S_PH_DSP:
15233        switch (op2) {
15234        case OPC_ABSQ_S_QB:
15235            check_dspr2(ctx);
15236            gen_helper_absq_s_qb(cpu_gpr[ret], v2_t, cpu_env);
15237            break;
15238        case OPC_ABSQ_S_PH:
15239            check_dsp(ctx);
15240            gen_helper_absq_s_ph(cpu_gpr[ret], v2_t, cpu_env);
15241            break;
15242        case OPC_ABSQ_S_W:
15243            check_dsp(ctx);
15244            gen_helper_absq_s_w(cpu_gpr[ret], v2_t, cpu_env);
15245            break;
15246        case OPC_PRECEQ_W_PHL:
15247            check_dsp(ctx);
15248            tcg_gen_andi_tl(cpu_gpr[ret], v2_t, 0xFFFF0000);
15249            tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]);
15250            break;
15251        case OPC_PRECEQ_W_PHR:
15252            check_dsp(ctx);
15253            tcg_gen_andi_tl(cpu_gpr[ret], v2_t, 0x0000FFFF);
15254            tcg_gen_shli_tl(cpu_gpr[ret], cpu_gpr[ret], 16);
15255            tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]);
15256            break;
15257        case OPC_PRECEQU_PH_QBL:
15258            check_dsp(ctx);
15259            gen_helper_precequ_ph_qbl(cpu_gpr[ret], v2_t);
15260            break;
15261        case OPC_PRECEQU_PH_QBR:
15262            check_dsp(ctx);
15263            gen_helper_precequ_ph_qbr(cpu_gpr[ret], v2_t);
15264            break;
15265        case OPC_PRECEQU_PH_QBLA:
15266            check_dsp(ctx);
15267            gen_helper_precequ_ph_qbla(cpu_gpr[ret], v2_t);
15268            break;
15269        case OPC_PRECEQU_PH_QBRA:
15270            check_dsp(ctx);
15271            gen_helper_precequ_ph_qbra(cpu_gpr[ret], v2_t);
15272            break;
15273        case OPC_PRECEU_PH_QBL:
15274            check_dsp(ctx);
15275            gen_helper_preceu_ph_qbl(cpu_gpr[ret], v2_t);
15276            break;
15277        case OPC_PRECEU_PH_QBR:
15278            check_dsp(ctx);
15279            gen_helper_preceu_ph_qbr(cpu_gpr[ret], v2_t);
15280            break;
15281        case OPC_PRECEU_PH_QBLA:
15282            check_dsp(ctx);
15283            gen_helper_preceu_ph_qbla(cpu_gpr[ret], v2_t);
15284            break;
15285        case OPC_PRECEU_PH_QBRA:
15286            check_dsp(ctx);
15287            gen_helper_preceu_ph_qbra(cpu_gpr[ret], v2_t);
15288            break;
15289        }
15290        break;
15291    case OPC_ADDU_QB_DSP:
15292        switch (op2) {
15293        case OPC_ADDQ_PH:
15294            check_dsp(ctx);
15295            gen_helper_addq_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15296            break;
15297        case OPC_ADDQ_S_PH:
15298            check_dsp(ctx);
15299            gen_helper_addq_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15300            break;
15301        case OPC_ADDQ_S_W:
15302            check_dsp(ctx);
15303            gen_helper_addq_s_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15304            break;
15305        case OPC_ADDU_QB:
15306            check_dsp(ctx);
15307            gen_helper_addu_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15308            break;
15309        case OPC_ADDU_S_QB:
15310            check_dsp(ctx);
15311            gen_helper_addu_s_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15312            break;
15313        case OPC_ADDU_PH:
15314            check_dspr2(ctx);
15315            gen_helper_addu_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15316            break;
15317        case OPC_ADDU_S_PH:
15318            check_dspr2(ctx);
15319            gen_helper_addu_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15320            break;
15321        case OPC_SUBQ_PH:
15322            check_dsp(ctx);
15323            gen_helper_subq_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15324            break;
15325        case OPC_SUBQ_S_PH:
15326            check_dsp(ctx);
15327            gen_helper_subq_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15328            break;
15329        case OPC_SUBQ_S_W:
15330            check_dsp(ctx);
15331            gen_helper_subq_s_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15332            break;
15333        case OPC_SUBU_QB:
15334            check_dsp(ctx);
15335            gen_helper_subu_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15336            break;
15337        case OPC_SUBU_S_QB:
15338            check_dsp(ctx);
15339            gen_helper_subu_s_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15340            break;
15341        case OPC_SUBU_PH:
15342            check_dspr2(ctx);
15343            gen_helper_subu_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15344            break;
15345        case OPC_SUBU_S_PH:
15346            check_dspr2(ctx);
15347            gen_helper_subu_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15348            break;
15349        case OPC_ADDSC:
15350            check_dsp(ctx);
15351            gen_helper_addsc(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15352            break;
15353        case OPC_ADDWC:
15354            check_dsp(ctx);
15355            gen_helper_addwc(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15356            break;
15357        case OPC_MODSUB:
15358            check_dsp(ctx);
15359            gen_helper_modsub(cpu_gpr[ret], v1_t, v2_t);
15360            break;
15361        case OPC_RADDU_W_QB:
15362            check_dsp(ctx);
15363            gen_helper_raddu_w_qb(cpu_gpr[ret], v1_t);
15364            break;
15365        }
15366        break;
15367    case OPC_CMPU_EQ_QB_DSP:
15368        switch (op2) {
15369        case OPC_PRECR_QB_PH:
15370            check_dspr2(ctx);
15371            gen_helper_precr_qb_ph(cpu_gpr[ret], v1_t, v2_t);
15372            break;
15373        case OPC_PRECRQ_QB_PH:
15374            check_dsp(ctx);
15375            gen_helper_precrq_qb_ph(cpu_gpr[ret], v1_t, v2_t);
15376            break;
15377        case OPC_PRECR_SRA_PH_W:
15378            check_dspr2(ctx);
15379            {
15380                TCGv_i32 sa_t = tcg_const_i32(v2);
15381                gen_helper_precr_sra_ph_w(cpu_gpr[ret], sa_t, v1_t,
15382                                          cpu_gpr[ret]);
15383                tcg_temp_free_i32(sa_t);
15384                break;
15385            }
15386        case OPC_PRECR_SRA_R_PH_W:
15387            check_dspr2(ctx);
15388            {
15389                TCGv_i32 sa_t = tcg_const_i32(v2);
15390                gen_helper_precr_sra_r_ph_w(cpu_gpr[ret], sa_t, v1_t,
15391                                            cpu_gpr[ret]);
15392                tcg_temp_free_i32(sa_t);
15393                break;
15394            }
15395        case OPC_PRECRQ_PH_W:
15396            check_dsp(ctx);
15397            gen_helper_precrq_ph_w(cpu_gpr[ret], v1_t, v2_t);
15398            break;
15399        case OPC_PRECRQ_RS_PH_W:
15400            check_dsp(ctx);
15401            gen_helper_precrq_rs_ph_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15402            break;
15403        case OPC_PRECRQU_S_QB_PH:
15404            check_dsp(ctx);
15405            gen_helper_precrqu_s_qb_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15406            break;
15407        }
15408        break;
15409#ifdef TARGET_MIPS64
15410    case OPC_ABSQ_S_QH_DSP:
15411        switch (op2) {
15412        case OPC_PRECEQ_L_PWL:
15413            check_dsp(ctx);
15414            tcg_gen_andi_tl(cpu_gpr[ret], v2_t, 0xFFFFFFFF00000000ull);
15415            break;
15416        case OPC_PRECEQ_L_PWR:
15417            check_dsp(ctx);
15418            tcg_gen_shli_tl(cpu_gpr[ret], v2_t, 32);
15419            break;
15420        case OPC_PRECEQ_PW_QHL:
15421            check_dsp(ctx);
15422            gen_helper_preceq_pw_qhl(cpu_gpr[ret], v2_t);
15423            break;
15424        case OPC_PRECEQ_PW_QHR:
15425            check_dsp(ctx);
15426            gen_helper_preceq_pw_qhr(cpu_gpr[ret], v2_t);
15427            break;
15428        case OPC_PRECEQ_PW_QHLA:
15429            check_dsp(ctx);
15430            gen_helper_preceq_pw_qhla(cpu_gpr[ret], v2_t);
15431            break;
15432        case OPC_PRECEQ_PW_QHRA:
15433            check_dsp(ctx);
15434            gen_helper_preceq_pw_qhra(cpu_gpr[ret], v2_t);
15435            break;
15436        case OPC_PRECEQU_QH_OBL:
15437            check_dsp(ctx);
15438            gen_helper_precequ_qh_obl(cpu_gpr[ret], v2_t);
15439            break;
15440        case OPC_PRECEQU_QH_OBR:
15441            check_dsp(ctx);
15442            gen_helper_precequ_qh_obr(cpu_gpr[ret], v2_t);
15443            break;
15444        case OPC_PRECEQU_QH_OBLA:
15445            check_dsp(ctx);
15446            gen_helper_precequ_qh_obla(cpu_gpr[ret], v2_t);
15447            break;
15448        case OPC_PRECEQU_QH_OBRA:
15449            check_dsp(ctx);
15450            gen_helper_precequ_qh_obra(cpu_gpr[ret], v2_t);
15451            break;
15452        case OPC_PRECEU_QH_OBL:
15453            check_dsp(ctx);
15454            gen_helper_preceu_qh_obl(cpu_gpr[ret], v2_t);
15455            break;
15456        case OPC_PRECEU_QH_OBR:
15457            check_dsp(ctx);
15458            gen_helper_preceu_qh_obr(cpu_gpr[ret], v2_t);
15459            break;
15460        case OPC_PRECEU_QH_OBLA:
15461            check_dsp(ctx);
15462            gen_helper_preceu_qh_obla(cpu_gpr[ret], v2_t);
15463            break;
15464        case OPC_PRECEU_QH_OBRA:
15465            check_dsp(ctx);
15466            gen_helper_preceu_qh_obra(cpu_gpr[ret], v2_t);
15467            break;
15468        case OPC_ABSQ_S_OB:
15469            check_dspr2(ctx);
15470            gen_helper_absq_s_ob(cpu_gpr[ret], v2_t, cpu_env);
15471            break;
15472        case OPC_ABSQ_S_PW:
15473            check_dsp(ctx);
15474            gen_helper_absq_s_pw(cpu_gpr[ret], v2_t, cpu_env);
15475            break;
15476        case OPC_ABSQ_S_QH:
15477            check_dsp(ctx);
15478            gen_helper_absq_s_qh(cpu_gpr[ret], v2_t, cpu_env);
15479            break;
15480        }
15481        break;
15482    case OPC_ADDU_OB_DSP:
15483        switch (op2) {
15484        case OPC_RADDU_L_OB:
15485            check_dsp(ctx);
15486            gen_helper_raddu_l_ob(cpu_gpr[ret], v1_t);
15487            break;
15488        case OPC_SUBQ_PW:
15489            check_dsp(ctx);
15490            gen_helper_subq_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15491            break;
15492        case OPC_SUBQ_S_PW:
15493            check_dsp(ctx);
15494            gen_helper_subq_s_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15495            break;
15496        case OPC_SUBQ_QH:
15497            check_dsp(ctx);
15498            gen_helper_subq_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15499            break;
15500        case OPC_SUBQ_S_QH:
15501            check_dsp(ctx);
15502            gen_helper_subq_s_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15503            break;
15504        case OPC_SUBU_OB:
15505            check_dsp(ctx);
15506            gen_helper_subu_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15507            break;
15508        case OPC_SUBU_S_OB:
15509            check_dsp(ctx);
15510            gen_helper_subu_s_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15511            break;
15512        case OPC_SUBU_QH:
15513            check_dspr2(ctx);
15514            gen_helper_subu_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15515            break;
15516        case OPC_SUBU_S_QH:
15517            check_dspr2(ctx);
15518            gen_helper_subu_s_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15519            break;
15520        case OPC_SUBUH_OB:
15521            check_dspr2(ctx);
15522            gen_helper_subuh_ob(cpu_gpr[ret], v1_t, v2_t);
15523            break;
15524        case OPC_SUBUH_R_OB:
15525            check_dspr2(ctx);
15526            gen_helper_subuh_r_ob(cpu_gpr[ret], v1_t, v2_t);
15527            break;
15528        case OPC_ADDQ_PW:
15529            check_dsp(ctx);
15530            gen_helper_addq_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15531            break;
15532        case OPC_ADDQ_S_PW:
15533            check_dsp(ctx);
15534            gen_helper_addq_s_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15535            break;
15536        case OPC_ADDQ_QH:
15537            check_dsp(ctx);
15538            gen_helper_addq_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15539            break;
15540        case OPC_ADDQ_S_QH:
15541            check_dsp(ctx);
15542            gen_helper_addq_s_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15543            break;
15544        case OPC_ADDU_OB:
15545            check_dsp(ctx);
15546            gen_helper_addu_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15547            break;
15548        case OPC_ADDU_S_OB:
15549            check_dsp(ctx);
15550            gen_helper_addu_s_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15551            break;
15552        case OPC_ADDU_QH:
15553            check_dspr2(ctx);
15554            gen_helper_addu_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15555            break;
15556        case OPC_ADDU_S_QH:
15557            check_dspr2(ctx);
15558            gen_helper_addu_s_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15559            break;
15560        case OPC_ADDUH_OB:
15561            check_dspr2(ctx);
15562            gen_helper_adduh_ob(cpu_gpr[ret], v1_t, v2_t);
15563            break;
15564        case OPC_ADDUH_R_OB:
15565            check_dspr2(ctx);
15566            gen_helper_adduh_r_ob(cpu_gpr[ret], v1_t, v2_t);
15567            break;
15568        }
15569        break;
15570    case OPC_CMPU_EQ_OB_DSP:
15571        switch (op2) {
15572        case OPC_PRECR_OB_QH:
15573            check_dspr2(ctx);
15574            gen_helper_precr_ob_qh(cpu_gpr[ret], v1_t, v2_t);
15575            break;
15576        case OPC_PRECR_SRA_QH_PW:
15577            check_dspr2(ctx);
15578            {
15579                TCGv_i32 ret_t = tcg_const_i32(ret);
15580                gen_helper_precr_sra_qh_pw(v2_t, v1_t, v2_t, ret_t);
15581                tcg_temp_free_i32(ret_t);
15582                break;
15583            }
15584        case OPC_PRECR_SRA_R_QH_PW:
15585            check_dspr2(ctx);
15586            {
15587                TCGv_i32 sa_v = tcg_const_i32(ret);
15588                gen_helper_precr_sra_r_qh_pw(v2_t, v1_t, v2_t, sa_v);
15589                tcg_temp_free_i32(sa_v);
15590                break;
15591            }
15592        case OPC_PRECRQ_OB_QH:
15593            check_dsp(ctx);
15594            gen_helper_precrq_ob_qh(cpu_gpr[ret], v1_t, v2_t);
15595            break;
15596        case OPC_PRECRQ_PW_L:
15597            check_dsp(ctx);
15598            gen_helper_precrq_pw_l(cpu_gpr[ret], v1_t, v2_t);
15599            break;
15600        case OPC_PRECRQ_QH_PW:
15601            check_dsp(ctx);
15602            gen_helper_precrq_qh_pw(cpu_gpr[ret], v1_t, v2_t);
15603            break;
15604        case OPC_PRECRQ_RS_QH_PW:
15605            check_dsp(ctx);
15606            gen_helper_precrq_rs_qh_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15607            break;
15608        case OPC_PRECRQU_S_OB_QH:
15609            check_dsp(ctx);
15610            gen_helper_precrqu_s_ob_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15611            break;
15612        }
15613        break;
15614#endif
15615    }
15616
15617    tcg_temp_free(v1_t);
15618    tcg_temp_free(v2_t);
15619}
15620
15621static void gen_mipsdsp_shift(DisasContext *ctx, uint32_t opc,
15622                              int ret, int v1, int v2)
15623{
15624    uint32_t op2;
15625    TCGv t0;
15626    TCGv v1_t;
15627    TCGv v2_t;
15628
15629    if (ret == 0) {
15630        /* Treat as NOP. */
15631        return;
15632    }
15633
15634    t0 = tcg_temp_new();
15635    v1_t = tcg_temp_new();
15636    v2_t = tcg_temp_new();
15637
15638    tcg_gen_movi_tl(t0, v1);
15639    gen_load_gpr(v1_t, v1);
15640    gen_load_gpr(v2_t, v2);
15641
15642    switch (opc) {
15643    case OPC_SHLL_QB_DSP:
15644        {
15645            op2 = MASK_SHLL_QB(ctx->opcode);
15646            switch (op2) {
15647            case OPC_SHLL_QB:
15648                check_dsp(ctx);
15649                gen_helper_shll_qb(cpu_gpr[ret], t0, v2_t, cpu_env);
15650                break;
15651            case OPC_SHLLV_QB:
15652                check_dsp(ctx);
15653                gen_helper_shll_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15654                break;
15655            case OPC_SHLL_PH:
15656                check_dsp(ctx);
15657                gen_helper_shll_ph(cpu_gpr[ret], t0, v2_t, cpu_env);
15658                break;
15659            case OPC_SHLLV_PH:
15660                check_dsp(ctx);
15661                gen_helper_shll_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15662                break;
15663            case OPC_SHLL_S_PH:
15664                check_dsp(ctx);
15665                gen_helper_shll_s_ph(cpu_gpr[ret], t0, v2_t, cpu_env);
15666                break;
15667            case OPC_SHLLV_S_PH:
15668                check_dsp(ctx);
15669                gen_helper_shll_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15670                break;
15671            case OPC_SHLL_S_W:
15672                check_dsp(ctx);
15673                gen_helper_shll_s_w(cpu_gpr[ret], t0, v2_t, cpu_env);
15674                break;
15675            case OPC_SHLLV_S_W:
15676                check_dsp(ctx);
15677                gen_helper_shll_s_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15678                break;
15679            case OPC_SHRL_QB:
15680                check_dsp(ctx);
15681                gen_helper_shrl_qb(cpu_gpr[ret], t0, v2_t);
15682                break;
15683            case OPC_SHRLV_QB:
15684                check_dsp(ctx);
15685                gen_helper_shrl_qb(cpu_gpr[ret], v1_t, v2_t);
15686                break;
15687            case OPC_SHRL_PH:
15688                check_dspr2(ctx);
15689                gen_helper_shrl_ph(cpu_gpr[ret], t0, v2_t);
15690                break;
15691            case OPC_SHRLV_PH:
15692                check_dspr2(ctx);
15693                gen_helper_shrl_ph(cpu_gpr[ret], v1_t, v2_t);
15694                break;
15695            case OPC_SHRA_QB:
15696                check_dspr2(ctx);
15697                gen_helper_shra_qb(cpu_gpr[ret], t0, v2_t);
15698                break;
15699            case OPC_SHRA_R_QB:
15700                check_dspr2(ctx);
15701                gen_helper_shra_r_qb(cpu_gpr[ret], t0, v2_t);
15702                break;
15703            case OPC_SHRAV_QB:
15704                check_dspr2(ctx);
15705                gen_helper_shra_qb(cpu_gpr[ret], v1_t, v2_t);
15706                break;
15707            case OPC_SHRAV_R_QB:
15708                check_dspr2(ctx);
15709                gen_helper_shra_r_qb(cpu_gpr[ret], v1_t, v2_t);
15710                break;
15711            case OPC_SHRA_PH:
15712                check_dsp(ctx);
15713                gen_helper_shra_ph(cpu_gpr[ret], t0, v2_t);
15714                break;
15715            case OPC_SHRA_R_PH:
15716                check_dsp(ctx);
15717                gen_helper_shra_r_ph(cpu_gpr[ret], t0, v2_t);
15718                break;
15719            case OPC_SHRAV_PH:
15720                check_dsp(ctx);
15721                gen_helper_shra_ph(cpu_gpr[ret], v1_t, v2_t);
15722                break;
15723            case OPC_SHRAV_R_PH:
15724                check_dsp(ctx);
15725                gen_helper_shra_r_ph(cpu_gpr[ret], v1_t, v2_t);
15726                break;
15727            case OPC_SHRA_R_W:
15728                check_dsp(ctx);
15729                gen_helper_shra_r_w(cpu_gpr[ret], t0, v2_t);
15730                break;
15731            case OPC_SHRAV_R_W:
15732                check_dsp(ctx);
15733                gen_helper_shra_r_w(cpu_gpr[ret], v1_t, v2_t);
15734                break;
15735            default:            /* Invalid */
15736                MIPS_INVAL("MASK SHLL.QB");
15737                generate_exception_end(ctx, EXCP_RI);
15738                break;
15739            }
15740            break;
15741        }
15742#ifdef TARGET_MIPS64
15743    case OPC_SHLL_OB_DSP:
15744        op2 = MASK_SHLL_OB(ctx->opcode);
15745        switch (op2) {
15746        case OPC_SHLL_PW:
15747            check_dsp(ctx);
15748            gen_helper_shll_pw(cpu_gpr[ret], v2_t, t0, cpu_env);
15749            break;
15750        case OPC_SHLLV_PW:
15751            check_dsp(ctx);
15752            gen_helper_shll_pw(cpu_gpr[ret], v2_t, v1_t, cpu_env);
15753            break;
15754        case OPC_SHLL_S_PW:
15755            check_dsp(ctx);
15756            gen_helper_shll_s_pw(cpu_gpr[ret], v2_t, t0, cpu_env);
15757            break;
15758        case OPC_SHLLV_S_PW:
15759            check_dsp(ctx);
15760            gen_helper_shll_s_pw(cpu_gpr[ret], v2_t, v1_t, cpu_env);
15761            break;
15762        case OPC_SHLL_OB:
15763            check_dsp(ctx);
15764            gen_helper_shll_ob(cpu_gpr[ret], v2_t, t0, cpu_env);
15765            break;
15766        case OPC_SHLLV_OB:
15767            check_dsp(ctx);
15768            gen_helper_shll_ob(cpu_gpr[ret], v2_t, v1_t, cpu_env);
15769            break;
15770        case OPC_SHLL_QH:
15771            check_dsp(ctx);
15772            gen_helper_shll_qh(cpu_gpr[ret], v2_t, t0, cpu_env);
15773            break;
15774        case OPC_SHLLV_QH:
15775            check_dsp(ctx);
15776            gen_helper_shll_qh(cpu_gpr[ret], v2_t, v1_t, cpu_env);
15777            break;
15778        case OPC_SHLL_S_QH:
15779            check_dsp(ctx);
15780            gen_helper_shll_s_qh(cpu_gpr[ret], v2_t, t0, cpu_env);
15781            break;
15782        case OPC_SHLLV_S_QH:
15783            check_dsp(ctx);
15784            gen_helper_shll_s_qh(cpu_gpr[ret], v2_t, v1_t, cpu_env);
15785            break;
15786        case OPC_SHRA_OB:
15787            check_dspr2(ctx);
15788            gen_helper_shra_ob(cpu_gpr[ret], v2_t, t0);
15789            break;
15790        case OPC_SHRAV_OB:
15791            check_dspr2(ctx);
15792            gen_helper_shra_ob(cpu_gpr[ret], v2_t, v1_t);
15793            break;
15794        case OPC_SHRA_R_OB:
15795            check_dspr2(ctx);
15796            gen_helper_shra_r_ob(cpu_gpr[ret], v2_t, t0);
15797            break;
15798        case OPC_SHRAV_R_OB:
15799            check_dspr2(ctx);
15800            gen_helper_shra_r_ob(cpu_gpr[ret], v2_t, v1_t);
15801            break;
15802        case OPC_SHRA_PW:
15803            check_dsp(ctx);
15804            gen_helper_shra_pw(cpu_gpr[ret], v2_t, t0);
15805            break;
15806        case OPC_SHRAV_PW:
15807            check_dsp(ctx);
15808            gen_helper_shra_pw(cpu_gpr[ret], v2_t, v1_t);
15809            break;
15810        case OPC_SHRA_R_PW:
15811            check_dsp(ctx);
15812            gen_helper_shra_r_pw(cpu_gpr[ret], v2_t, t0);
15813            break;
15814        case OPC_SHRAV_R_PW:
15815            check_dsp(ctx);
15816            gen_helper_shra_r_pw(cpu_gpr[ret], v2_t, v1_t);
15817            break;
15818        case OPC_SHRA_QH:
15819            check_dsp(ctx);
15820            gen_helper_shra_qh(cpu_gpr[ret], v2_t, t0);
15821            break;
15822        case OPC_SHRAV_QH:
15823            check_dsp(ctx);
15824            gen_helper_shra_qh(cpu_gpr[ret], v2_t, v1_t);
15825            break;
15826        case OPC_SHRA_R_QH:
15827            check_dsp(ctx);
15828            gen_helper_shra_r_qh(cpu_gpr[ret], v2_t, t0);
15829            break;
15830        case OPC_SHRAV_R_QH:
15831            check_dsp(ctx);
15832            gen_helper_shra_r_qh(cpu_gpr[ret], v2_t, v1_t);
15833            break;
15834        case OPC_SHRL_OB:
15835            check_dsp(ctx);
15836            gen_helper_shrl_ob(cpu_gpr[ret], v2_t, t0);
15837            break;
15838        case OPC_SHRLV_OB:
15839            check_dsp(ctx);
15840            gen_helper_shrl_ob(cpu_gpr[ret], v2_t, v1_t);
15841            break;
15842        case OPC_SHRL_QH:
15843            check_dspr2(ctx);
15844            gen_helper_shrl_qh(cpu_gpr[ret], v2_t, t0);
15845            break;
15846        case OPC_SHRLV_QH:
15847            check_dspr2(ctx);
15848            gen_helper_shrl_qh(cpu_gpr[ret], v2_t, v1_t);
15849            break;
15850        default:            /* Invalid */
15851            MIPS_INVAL("MASK SHLL.OB");
15852            generate_exception_end(ctx, EXCP_RI);
15853            break;
15854        }
15855        break;
15856#endif
15857    }
15858
15859    tcg_temp_free(t0);
15860    tcg_temp_free(v1_t);
15861    tcg_temp_free(v2_t);
15862}
15863
15864static void gen_mipsdsp_multiply(DisasContext *ctx, uint32_t op1, uint32_t op2,
15865                                 int ret, int v1, int v2, int check_ret)
15866{
15867    TCGv_i32 t0;
15868    TCGv v1_t;
15869    TCGv v2_t;
15870
15871    if ((ret == 0) && (check_ret == 1)) {
15872        /* Treat as NOP. */
15873        return;
15874    }
15875
15876    t0 = tcg_temp_new_i32();
15877    v1_t = tcg_temp_new();
15878    v2_t = tcg_temp_new();
15879
15880    tcg_gen_movi_i32(t0, ret);
15881    gen_load_gpr(v1_t, v1);
15882    gen_load_gpr(v2_t, v2);
15883
15884    switch (op1) {
15885    /* OPC_MULT_G_2E, OPC_ADDUH_QB_DSP, OPC_MUL_PH_DSP have
15886     * the same mask and op1. */
15887    case OPC_MULT_G_2E:
15888        check_dspr2(ctx);
15889        switch (op2) {
15890        case  OPC_MUL_PH:
15891            gen_helper_mul_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15892            break;
15893        case  OPC_MUL_S_PH:
15894            gen_helper_mul_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15895            break;
15896        case OPC_MULQ_S_W:
15897            gen_helper_mulq_s_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15898            break;
15899        case OPC_MULQ_RS_W:
15900            gen_helper_mulq_rs_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15901            break;
15902        }
15903        break;
15904    case OPC_DPA_W_PH_DSP:
15905        switch (op2) {
15906        case OPC_DPAU_H_QBL:
15907            check_dsp(ctx);
15908            gen_helper_dpau_h_qbl(t0, v1_t, v2_t, cpu_env);
15909            break;
15910        case OPC_DPAU_H_QBR:
15911            check_dsp(ctx);
15912            gen_helper_dpau_h_qbr(t0, v1_t, v2_t, cpu_env);
15913            break;
15914        case OPC_DPSU_H_QBL:
15915            check_dsp(ctx);
15916            gen_helper_dpsu_h_qbl(t0, v1_t, v2_t, cpu_env);
15917            break;
15918        case OPC_DPSU_H_QBR:
15919            check_dsp(ctx);
15920            gen_helper_dpsu_h_qbr(t0, v1_t, v2_t, cpu_env);
15921            break;
15922        case OPC_DPA_W_PH:
15923            check_dspr2(ctx);
15924            gen_helper_dpa_w_ph(t0, v1_t, v2_t, cpu_env);
15925            break;
15926        case OPC_DPAX_W_PH:
15927            check_dspr2(ctx);
15928            gen_helper_dpax_w_ph(t0, v1_t, v2_t, cpu_env);
15929            break;
15930        case OPC_DPAQ_S_W_PH:
15931            check_dsp(ctx);
15932            gen_helper_dpaq_s_w_ph(t0, v1_t, v2_t, cpu_env);
15933            break;
15934        case OPC_DPAQX_S_W_PH:
15935            check_dspr2(ctx);
15936            gen_helper_dpaqx_s_w_ph(t0, v1_t, v2_t, cpu_env);
15937            break;
15938        case OPC_DPAQX_SA_W_PH:
15939            check_dspr2(ctx);
15940            gen_helper_dpaqx_sa_w_ph(t0, v1_t, v2_t, cpu_env);
15941            break;
15942        case OPC_DPS_W_PH:
15943            check_dspr2(ctx);
15944            gen_helper_dps_w_ph(t0, v1_t, v2_t, cpu_env);
15945            break;
15946        case OPC_DPSX_W_PH:
15947            check_dspr2(ctx);
15948            gen_helper_dpsx_w_ph(t0, v1_t, v2_t, cpu_env);
15949            break;
15950        case OPC_DPSQ_S_W_PH:
15951            check_dsp(ctx);
15952            gen_helper_dpsq_s_w_ph(t0, v1_t, v2_t, cpu_env);
15953            break;
15954        case OPC_DPSQX_S_W_PH:
15955            check_dspr2(ctx);
15956            gen_helper_dpsqx_s_w_ph(t0, v1_t, v2_t, cpu_env);
15957            break;
15958        case OPC_DPSQX_SA_W_PH:
15959            check_dspr2(ctx);
15960            gen_helper_dpsqx_sa_w_ph(t0, v1_t, v2_t, cpu_env);
15961            break;
15962        case OPC_MULSAQ_S_W_PH:
15963            check_dsp(ctx);
15964            gen_helper_mulsaq_s_w_ph(t0, v1_t, v2_t, cpu_env);
15965            break;
15966        case OPC_DPAQ_SA_L_W:
15967            check_dsp(ctx);
15968            gen_helper_dpaq_sa_l_w(t0, v1_t, v2_t, cpu_env);
15969            break;
15970        case OPC_DPSQ_SA_L_W:
15971            check_dsp(ctx);
15972            gen_helper_dpsq_sa_l_w(t0, v1_t, v2_t, cpu_env);
15973            break;
15974        case OPC_MAQ_S_W_PHL:
15975            check_dsp(ctx);
15976            gen_helper_maq_s_w_phl(t0, v1_t, v2_t, cpu_env);
15977            break;
15978        case OPC_MAQ_S_W_PHR:
15979            check_dsp(ctx);
15980            gen_helper_maq_s_w_phr(t0, v1_t, v2_t, cpu_env);
15981            break;
15982        case OPC_MAQ_SA_W_PHL:
15983            check_dsp(ctx);
15984            gen_helper_maq_sa_w_phl(t0, v1_t, v2_t, cpu_env);
15985            break;
15986        case OPC_MAQ_SA_W_PHR:
15987            check_dsp(ctx);
15988            gen_helper_maq_sa_w_phr(t0, v1_t, v2_t, cpu_env);
15989            break;
15990        case OPC_MULSA_W_PH:
15991            check_dspr2(ctx);
15992            gen_helper_mulsa_w_ph(t0, v1_t, v2_t, cpu_env);
15993            break;
15994        }
15995        break;
15996#ifdef TARGET_MIPS64
15997    case OPC_DPAQ_W_QH_DSP:
15998        {
15999            int ac = ret & 0x03;
16000            tcg_gen_movi_i32(t0, ac);
16001
16002            switch (op2) {
16003            case OPC_DMADD:
16004                check_dsp(ctx);
16005                gen_helper_dmadd(v1_t, v2_t, t0, cpu_env);
16006                break;
16007            case OPC_DMADDU:
16008                check_dsp(ctx);
16009                gen_helper_dmaddu(v1_t, v2_t, t0, cpu_env);
16010                break;
16011            case OPC_DMSUB:
16012                check_dsp(ctx);
16013                gen_helper_dmsub(v1_t, v2_t, t0, cpu_env);
16014                break;
16015            case OPC_DMSUBU:
16016                check_dsp(ctx);
16017                gen_helper_dmsubu(v1_t, v2_t, t0, cpu_env);
16018                break;
16019            case OPC_DPA_W_QH:
16020                check_dspr2(ctx);
16021                gen_helper_dpa_w_qh(v1_t, v2_t, t0, cpu_env);
16022                break;
16023            case OPC_DPAQ_S_W_QH:
16024                check_dsp(ctx);
16025                gen_helper_dpaq_s_w_qh(v1_t, v2_t, t0, cpu_env);
16026                break;
16027            case OPC_DPAQ_SA_L_PW:
16028                check_dsp(ctx);
16029                gen_helper_dpaq_sa_l_pw(v1_t, v2_t, t0, cpu_env);
16030                break;
16031            case OPC_DPAU_H_OBL:
16032                check_dsp(ctx);
16033                gen_helper_dpau_h_obl(v1_t, v2_t, t0, cpu_env);
16034                break;
16035            case OPC_DPAU_H_OBR:
16036                check_dsp(ctx);
16037                gen_helper_dpau_h_obr(v1_t, v2_t, t0, cpu_env);
16038                break;
16039            case OPC_DPS_W_QH:
16040                check_dspr2(ctx);
16041                gen_helper_dps_w_qh(v1_t, v2_t, t0, cpu_env);
16042                break;
16043            case OPC_DPSQ_S_W_QH:
16044                check_dsp(ctx);
16045                gen_helper_dpsq_s_w_qh(v1_t, v2_t, t0, cpu_env);
16046                break;
16047            case OPC_DPSQ_SA_L_PW:
16048                check_dsp(ctx);
16049                gen_helper_dpsq_sa_l_pw(v1_t, v2_t, t0, cpu_env);
16050                break;
16051            case OPC_DPSU_H_OBL:
16052                check_dsp(ctx);
16053                gen_helper_dpsu_h_obl(v1_t, v2_t, t0, cpu_env);
16054                break;
16055            case OPC_DPSU_H_OBR:
16056                check_dsp(ctx);
16057                gen_helper_dpsu_h_obr(v1_t, v2_t, t0, cpu_env);
16058                break;
16059            case OPC_MAQ_S_L_PWL:
16060                check_dsp(ctx);
16061                gen_helper_maq_s_l_pwl(v1_t, v2_t, t0, cpu_env);
16062                break;
16063            case OPC_MAQ_S_L_PWR:
16064                check_dsp(ctx);
16065                gen_helper_maq_s_l_pwr(v1_t, v2_t, t0, cpu_env);
16066                break;
16067            case OPC_MAQ_S_W_QHLL:
16068                check_dsp(ctx);
16069                gen_helper_maq_s_w_qhll(v1_t, v2_t, t0, cpu_env);
16070                break;
16071            case OPC_MAQ_SA_W_QHLL:
16072                check_dsp(ctx);
16073                gen_helper_maq_sa_w_qhll(v1_t, v2_t, t0, cpu_env);
16074                break;
16075            case OPC_MAQ_S_W_QHLR:
16076                check_dsp(ctx);
16077                gen_helper_maq_s_w_qhlr(v1_t, v2_t, t0, cpu_env);
16078                break;
16079            case OPC_MAQ_SA_W_QHLR:
16080                check_dsp(ctx);
16081                gen_helper_maq_sa_w_qhlr(v1_t, v2_t, t0, cpu_env);
16082                break;
16083            case OPC_MAQ_S_W_QHRL:
16084                check_dsp(ctx);
16085                gen_helper_maq_s_w_qhrl(v1_t, v2_t, t0, cpu_env);
16086                break;
16087            case OPC_MAQ_SA_W_QHRL:
16088                check_dsp(ctx);
16089                gen_helper_maq_sa_w_qhrl(v1_t, v2_t, t0, cpu_env);
16090                break;
16091            case OPC_MAQ_S_W_QHRR:
16092                check_dsp(ctx);
16093                gen_helper_maq_s_w_qhrr(v1_t, v2_t, t0, cpu_env);
16094                break;
16095            case OPC_MAQ_SA_W_QHRR:
16096                check_dsp(ctx);
16097                gen_helper_maq_sa_w_qhrr(v1_t, v2_t, t0, cpu_env);
16098                break;
16099            case OPC_MULSAQ_S_L_PW:
16100                check_dsp(ctx);
16101                gen_helper_mulsaq_s_l_pw(v1_t, v2_t, t0, cpu_env);
16102                break;
16103            case OPC_MULSAQ_S_W_QH:
16104                check_dsp(ctx);
16105                gen_helper_mulsaq_s_w_qh(v1_t, v2_t, t0, cpu_env);
16106                break;
16107            }
16108        }
16109        break;
16110#endif
16111    case OPC_ADDU_QB_DSP:
16112        switch (op2) {
16113        case OPC_MULEU_S_PH_QBL:
16114            check_dsp(ctx);
16115            gen_helper_muleu_s_ph_qbl(cpu_gpr[ret], v1_t, v2_t, cpu_env);
16116            break;
16117        case OPC_MULEU_S_PH_QBR:
16118            check_dsp(ctx);
16119            gen_helper_muleu_s_ph_qbr(cpu_gpr[ret], v1_t, v2_t, cpu_env);
16120            break;
16121        case OPC_MULQ_RS_PH:
16122            check_dsp(ctx);
16123            gen_helper_mulq_rs_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
16124            break;
16125        case OPC_MULEQ_S_W_PHL:
16126            check_dsp(ctx);
16127            gen_helper_muleq_s_w_phl(cpu_gpr[ret], v1_t, v2_t, cpu_env);
16128            break;
16129        case OPC_MULEQ_S_W_PHR:
16130            check_dsp(ctx);
16131            gen_helper_muleq_s_w_phr(cpu_gpr[ret], v1_t, v2_t, cpu_env);
16132            break;
16133        case OPC_MULQ_S_PH:
16134            check_dspr2(ctx);
16135            gen_helper_mulq_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
16136            break;
16137        }
16138        break;
16139#ifdef TARGET_MIPS64
16140    case OPC_ADDU_OB_DSP:
16141        switch (op2) {
16142        case OPC_MULEQ_S_PW_QHL:
16143            check_dsp(ctx);
16144            gen_helper_muleq_s_pw_qhl(cpu_gpr[ret], v1_t, v2_t, cpu_env);
16145            break;
16146        case OPC_MULEQ_S_PW_QHR:
16147            check_dsp(ctx);
16148            gen_helper_muleq_s_pw_qhr(cpu_gpr[ret], v1_t, v2_t, cpu_env);
16149            break;
16150        case OPC_MULEU_S_QH_OBL:
16151            check_dsp(ctx);
16152            gen_helper_muleu_s_qh_obl(cpu_gpr[ret], v1_t, v2_t, cpu_env);
16153            break;
16154        case OPC_MULEU_S_QH_OBR:
16155            check_dsp(ctx);
16156            gen_helper_muleu_s_qh_obr(cpu_gpr[ret], v1_t, v2_t, cpu_env);
16157            break;
16158        case OPC_MULQ_RS_QH:
16159            check_dsp(ctx);
16160            gen_helper_mulq_rs_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
16161            break;
16162        }
16163        break;
16164#endif
16165    }
16166
16167    tcg_temp_free_i32(t0);
16168    tcg_temp_free(v1_t);
16169    tcg_temp_free(v2_t);
16170}
16171
16172static void gen_mipsdsp_bitinsn(DisasContext *ctx, uint32_t op1, uint32_t op2,
16173                                int ret, int val)
16174{
16175    int16_t imm;
16176    TCGv t0;
16177    TCGv val_t;
16178
16179    if (ret == 0) {
16180        /* Treat as NOP. */
16181        return;
16182    }
16183
16184    t0 = tcg_temp_new();
16185    val_t = tcg_temp_new();
16186    gen_load_gpr(val_t, val);
16187
16188    switch (op1) {
16189    case OPC_ABSQ_S_PH_DSP:
16190        switch (op2) {
16191        case OPC_BITREV:
16192            check_dsp(ctx);
16193            gen_helper_bitrev(cpu_gpr[ret], val_t);
16194            break;
16195        case OPC_REPL_QB:
16196            check_dsp(ctx);
16197            {
16198                target_long result;
16199                imm = (ctx->opcode >> 16) & 0xFF;
16200                result = (uint32_t)imm << 24 |
16201                         (uint32_t)imm << 16 |
16202                         (uint32_t)imm << 8  |
16203                         (uint32_t)imm;
16204                result = (int32_t)result;
16205                tcg_gen_movi_tl(cpu_gpr[ret], result);
16206            }
16207            break;
16208        case OPC_REPLV_QB:
16209            check_dsp(ctx);
16210            tcg_gen_ext8u_tl(cpu_gpr[ret], val_t);
16211            tcg_gen_shli_tl(t0, cpu_gpr[ret], 8);
16212            tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
16213            tcg_gen_shli_tl(t0, cpu_gpr[ret], 16);
16214            tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
16215            tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]);
16216            break;
16217        case OPC_REPL_PH:
16218            check_dsp(ctx);
16219            {
16220                imm = (ctx->opcode >> 16) & 0x03FF;
16221                imm = (int16_t)(imm << 6) >> 6;
16222                tcg_gen_movi_tl(cpu_gpr[ret], \
16223                                (target_long)((int32_t)imm << 16 | \
16224                                (uint16_t)imm));
16225            }
16226            break;
16227        case OPC_REPLV_PH:
16228            check_dsp(ctx);
16229            tcg_gen_ext16u_tl(cpu_gpr[ret], val_t);
16230            tcg_gen_shli_tl(t0, cpu_gpr[ret], 16);
16231            tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
16232            tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]);
16233            break;
16234        }
16235        break;
16236#ifdef TARGET_MIPS64
16237    case OPC_ABSQ_S_QH_DSP:
16238        switch (op2) {
16239        case OPC_REPL_OB:
16240            check_dsp(ctx);
16241            {
16242                target_long temp;
16243
16244                imm = (ctx->opcode >> 16) & 0xFF;
16245                temp = ((uint64_t)imm << 8) | (uint64_t)imm;
16246                temp = (temp << 16) | temp;
16247                temp = (temp << 32) | temp;
16248                tcg_gen_movi_tl(cpu_gpr[ret], temp);
16249                break;
16250            }
16251        case OPC_REPL_PW:
16252            check_dsp(ctx);
16253            {
16254                target_long temp;
16255
16256                imm = (ctx->opcode >> 16) & 0x03FF;
16257                imm = (int16_t)(imm << 6) >> 6;
16258                temp = ((target_long)imm << 32) \
16259                       | ((target_long)imm & 0xFFFFFFFF);
16260                tcg_gen_movi_tl(cpu_gpr[ret], temp);
16261                break;
16262            }
16263        case OPC_REPL_QH:
16264            check_dsp(ctx);
16265            {
16266                target_long temp;
16267
16268                imm = (ctx->opcode >> 16) & 0x03FF;
16269                imm = (int16_t)(imm << 6) >> 6;
16270
16271                temp = ((uint64_t)(uint16_t)imm << 48) |
16272                       ((uint64_t)(uint16_t)imm << 32) |
16273                       ((uint64_t)(uint16_t)imm << 16) |
16274                       (uint64_t)(uint16_t)imm;
16275                tcg_gen_movi_tl(cpu_gpr[ret], temp);
16276                break;
16277            }
16278        case OPC_REPLV_OB:
16279            check_dsp(ctx);
16280            tcg_gen_ext8u_tl(cpu_gpr[ret], val_t);
16281            tcg_gen_shli_tl(t0, cpu_gpr[ret], 8);
16282            tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
16283            tcg_gen_shli_tl(t0, cpu_gpr[ret], 16);
16284            tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
16285            tcg_gen_shli_tl(t0, cpu_gpr[ret], 32);
16286            tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
16287            break;
16288        case OPC_REPLV_PW:
16289            check_dsp(ctx);
16290            tcg_gen_ext32u_i64(cpu_gpr[ret], val_t);
16291            tcg_gen_shli_tl(t0, cpu_gpr[ret], 32);
16292            tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
16293            break;
16294        case OPC_REPLV_QH:
16295            check_dsp(ctx);
16296            tcg_gen_ext16u_tl(cpu_gpr[ret], val_t);
16297            tcg_gen_shli_tl(t0, cpu_gpr[ret], 16);
16298            tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
16299            tcg_gen_shli_tl(t0, cpu_gpr[ret], 32);
16300            tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
16301            break;
16302        }
16303        break;
16304#endif
16305    }
16306    tcg_temp_free(t0);
16307    tcg_temp_free(val_t);
16308}
16309
16310static void gen_mipsdsp_add_cmp_pick(DisasContext *ctx,
16311                                     uint32_t op1, uint32_t op2,
16312                                     int ret, int v1, int v2, int check_ret)
16313{
16314    TCGv t1;
16315    TCGv v1_t;
16316    TCGv v2_t;
16317
16318    if ((ret == 0) && (check_ret == 1)) {
16319        /* Treat as NOP. */
16320        return;
16321    }
16322
16323    t1 = tcg_temp_new();
16324    v1_t = tcg_temp_new();
16325    v2_t = tcg_temp_new();
16326
16327    gen_load_gpr(v1_t, v1);
16328    gen_load_gpr(v2_t, v2);
16329
16330    switch (op1) {
16331    case OPC_CMPU_EQ_QB_DSP:
16332        switch (op2) {
16333        case OPC_CMPU_EQ_QB:
16334            check_dsp(ctx);
16335            gen_helper_cmpu_eq_qb(v1_t, v2_t, cpu_env);
16336            break;
16337        case OPC_CMPU_LT_QB:
16338            check_dsp(ctx);
16339            gen_helper_cmpu_lt_qb(v1_t, v2_t, cpu_env);
16340            break;
16341        case OPC_CMPU_LE_QB:
16342            check_dsp(ctx);
16343            gen_helper_cmpu_le_qb(v1_t, v2_t, cpu_env);
16344            break;
16345        case OPC_CMPGU_EQ_QB:
16346            check_dsp(ctx);
16347            gen_helper_cmpgu_eq_qb(cpu_gpr[ret], v1_t, v2_t);
16348            break;
16349        case OPC_CMPGU_LT_QB:
16350            check_dsp(ctx);
16351            gen_helper_cmpgu_lt_qb(cpu_gpr[ret], v1_t, v2_t);
16352            break;
16353        case OPC_CMPGU_LE_QB:
16354            check_dsp(ctx);
16355            gen_helper_cmpgu_le_qb(cpu_gpr[ret], v1_t, v2_t);
16356            break;
16357        case OPC_CMPGDU_EQ_QB:
16358            check_dspr2(ctx);
16359            gen_helper_cmpgu_eq_qb(t1, v1_t, v2_t);
16360            tcg_gen_mov_tl(cpu_gpr[ret], t1);
16361            tcg_gen_andi_tl(cpu_dspctrl, cpu_dspctrl, 0xF0FFFFFF);
16362            tcg_gen_shli_tl(t1, t1, 24);
16363            tcg_gen_or_tl(cpu_dspctrl, cpu_dspctrl, t1);
16364            break;
16365        case OPC_CMPGDU_LT_QB:
16366            check_dspr2(ctx);
16367            gen_helper_cmpgu_lt_qb(t1, v1_t, v2_t);
16368            tcg_gen_mov_tl(cpu_gpr[ret], t1);
16369            tcg_gen_andi_tl(cpu_dspctrl, cpu_dspctrl, 0xF0FFFFFF);
16370            tcg_gen_shli_tl(t1, t1, 24);
16371            tcg_gen_or_tl(cpu_dspctrl, cpu_dspctrl, t1);
16372            break;
16373        case OPC_CMPGDU_LE_QB:
16374            check_dspr2(ctx);
16375            gen_helper_cmpgu_le_qb(t1, v1_t, v2_t);
16376            tcg_gen_mov_tl(cpu_gpr[ret], t1);
16377            tcg_gen_andi_tl(cpu_dspctrl, cpu_dspctrl, 0xF0FFFFFF);
16378            tcg_gen_shli_tl(t1, t1, 24);
16379            tcg_gen_or_tl(cpu_dspctrl, cpu_dspctrl, t1);
16380            break;
16381        case OPC_CMP_EQ_PH:
16382            check_dsp(ctx);
16383            gen_helper_cmp_eq_ph(v1_t, v2_t, cpu_env);
16384            break;
16385        case OPC_CMP_LT_PH:
16386            check_dsp(ctx);
16387            gen_helper_cmp_lt_ph(v1_t, v2_t, cpu_env);
16388            break;
16389        case OPC_CMP_LE_PH:
16390            check_dsp(ctx);
16391            gen_helper_cmp_le_ph(v1_t, v2_t, cpu_env);
16392            break;
16393        case OPC_PICK_QB:
16394            check_dsp(ctx);
16395            gen_helper_pick_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
16396            break;
16397        case OPC_PICK_PH:
16398            check_dsp(ctx);
16399            gen_helper_pick_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
16400            break;
16401        case OPC_PACKRL_PH:
16402            check_dsp(ctx);
16403            gen_helper_packrl_ph(cpu_gpr[ret], v1_t, v2_t);
16404            break;
16405        }
16406        break;
16407#ifdef TARGET_MIPS64
16408    case OPC_CMPU_EQ_OB_DSP:
16409        switch (op2) {
16410        case OPC_CMP_EQ_PW:
16411            check_dsp(ctx);
16412            gen_helper_cmp_eq_pw(v1_t, v2_t, cpu_env);
16413            break;
16414        case OPC_CMP_LT_PW:
16415            check_dsp(ctx);
16416            gen_helper_cmp_lt_pw(v1_t, v2_t, cpu_env);
16417            break;
16418        case OPC_CMP_LE_PW:
16419            check_dsp(ctx);
16420            gen_helper_cmp_le_pw(v1_t, v2_t, cpu_env);
16421            break;
16422        case OPC_CMP_EQ_QH:
16423            check_dsp(ctx);
16424            gen_helper_cmp_eq_qh(v1_t, v2_t, cpu_env);
16425            break;
16426        case OPC_CMP_LT_QH:
16427            check_dsp(ctx);
16428            gen_helper_cmp_lt_qh(v1_t, v2_t, cpu_env);
16429            break;
16430        case OPC_CMP_LE_QH:
16431            check_dsp(ctx);
16432            gen_helper_cmp_le_qh(v1_t, v2_t, cpu_env);
16433            break;
16434        case OPC_CMPGDU_EQ_OB:
16435            check_dspr2(ctx);
16436            gen_helper_cmpgdu_eq_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
16437            break;
16438        case OPC_CMPGDU_LT_OB:
16439            check_dspr2(ctx);
16440            gen_helper_cmpgdu_lt_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
16441            break;
16442        case OPC_CMPGDU_LE_OB:
16443            check_dspr2(ctx);
16444            gen_helper_cmpgdu_le_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
16445            break;
16446        case OPC_CMPGU_EQ_OB:
16447            check_dsp(ctx);
16448            gen_helper_cmpgu_eq_ob(cpu_gpr[ret], v1_t, v2_t);
16449            break;
16450        case OPC_CMPGU_LT_OB:
16451            check_dsp(ctx);
16452            gen_helper_cmpgu_lt_ob(cpu_gpr[ret], v1_t, v2_t);
16453            break;
16454        case OPC_CMPGU_LE_OB:
16455            check_dsp(ctx);
16456            gen_helper_cmpgu_le_ob(cpu_gpr[ret], v1_t, v2_t);
16457            break;
16458        case OPC_CMPU_EQ_OB:
16459            check_dsp(ctx);
16460            gen_helper_cmpu_eq_ob(v1_t, v2_t, cpu_env);
16461            break;
16462        case OPC_CMPU_LT_OB:
16463            check_dsp(ctx);
16464            gen_helper_cmpu_lt_ob(v1_t, v2_t, cpu_env);
16465            break;
16466        case OPC_CMPU_LE_OB:
16467            check_dsp(ctx);
16468            gen_helper_cmpu_le_ob(v1_t, v2_t, cpu_env);
16469            break;
16470        case OPC_PACKRL_PW:
16471            check_dsp(ctx);
16472            gen_helper_packrl_pw(cpu_gpr[ret], v1_t, v2_t);
16473            break;
16474        case OPC_PICK_OB:
16475            check_dsp(ctx);
16476            gen_helper_pick_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
16477            break;
16478        case OPC_PICK_PW:
16479            check_dsp(ctx);
16480            gen_helper_pick_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
16481            break;
16482        case OPC_PICK_QH:
16483            check_dsp(ctx);
16484            gen_helper_pick_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
16485            break;
16486        }
16487        break;
16488#endif
16489    }
16490
16491    tcg_temp_free(t1);
16492    tcg_temp_free(v1_t);
16493    tcg_temp_free(v2_t);
16494}
16495
16496static void gen_mipsdsp_append(CPUMIPSState *env, DisasContext *ctx,
16497                               uint32_t op1, int rt, int rs, int sa)
16498{
16499    TCGv t0;
16500
16501    check_dspr2(ctx);
16502
16503    if (rt == 0) {
16504        /* Treat as NOP. */
16505        return;
16506    }
16507
16508    t0 = tcg_temp_new();
16509    gen_load_gpr(t0, rs);
16510
16511    switch (op1) {
16512    case OPC_APPEND_DSP:
16513        switch (MASK_APPEND(ctx->opcode)) {
16514        case OPC_APPEND:
16515            if (sa != 0) {
16516                tcg_gen_deposit_tl(cpu_gpr[rt], t0, cpu_gpr[rt], sa, 32 - sa);
16517            }
16518            tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
16519            break;
16520        case OPC_PREPEND:
16521            if (sa != 0) {
16522                tcg_gen_ext32u_tl(cpu_gpr[rt], cpu_gpr[rt]);
16523                tcg_gen_shri_tl(cpu_gpr[rt], cpu_gpr[rt], sa);
16524                tcg_gen_shli_tl(t0, t0, 32 - sa);
16525                tcg_gen_or_tl(cpu_gpr[rt], cpu_gpr[rt], t0);
16526            }
16527            tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
16528            break;
16529        case OPC_BALIGN:
16530            sa &= 3;
16531            if (sa != 0 && sa != 2) {
16532                tcg_gen_shli_tl(cpu_gpr[rt], cpu_gpr[rt], 8 * sa);
16533                tcg_gen_ext32u_tl(t0, t0);
16534                tcg_gen_shri_tl(t0, t0, 8 * (4 - sa));
16535                tcg_gen_or_tl(cpu_gpr[rt], cpu_gpr[rt], t0);
16536            }
16537            tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
16538            break;
16539        default:            /* Invalid */
16540            MIPS_INVAL("MASK APPEND");
16541            generate_exception_end(ctx, EXCP_RI);
16542            break;
16543        }
16544        break;
16545#ifdef TARGET_MIPS64
16546    case OPC_DAPPEND_DSP:
16547        switch (MASK_DAPPEND(ctx->opcode)) {
16548        case OPC_DAPPEND:
16549            if (sa != 0) {
16550                tcg_gen_deposit_tl(cpu_gpr[rt], t0, cpu_gpr[rt], sa, 64 - sa);
16551            }
16552            break;
16553        case OPC_PREPENDD:
16554            tcg_gen_shri_tl(cpu_gpr[rt], cpu_gpr[rt], 0x20 | sa);
16555            tcg_gen_shli_tl(t0, t0, 64 - (0x20 | sa));
16556            tcg_gen_or_tl(cpu_gpr[rt], t0, t0);
16557            break;
16558        case OPC_PREPENDW:
16559            if (sa != 0) {
16560                tcg_gen_shri_tl(cpu_gpr[rt], cpu_gpr[rt], sa);
16561                tcg_gen_shli_tl(t0, t0, 64 - sa);
16562                tcg_gen_or_tl(cpu_gpr[rt], cpu_gpr[rt], t0);
16563            }
16564            break;
16565        case OPC_DBALIGN:
16566            sa &= 7;
16567            if (sa != 0 && sa != 2 && sa != 4) {
16568                tcg_gen_shli_tl(cpu_gpr[rt], cpu_gpr[rt], 8 * sa);
16569                tcg_gen_shri_tl(t0, t0, 8 * (8 - sa));
16570                tcg_gen_or_tl(cpu_gpr[rt], cpu_gpr[rt], t0);
16571            }
16572            break;
16573        default:            /* Invalid */
16574            MIPS_INVAL("MASK DAPPEND");
16575            generate_exception_end(ctx, EXCP_RI);
16576            break;
16577        }
16578        break;
16579#endif
16580    }
16581    tcg_temp_free(t0);
16582}
16583
16584static void gen_mipsdsp_accinsn(DisasContext *ctx, uint32_t op1, uint32_t op2,
16585                                int ret, int v1, int v2, int check_ret)
16586
16587{
16588    TCGv t0;
16589    TCGv t1;
16590    TCGv v1_t;
16591    TCGv v2_t;
16592    int16_t imm;
16593
16594    if ((ret == 0) && (check_ret == 1)) {
16595        /* Treat as NOP. */
16596        return;
16597    }
16598
16599    t0 = tcg_temp_new();
16600    t1 = tcg_temp_new();
16601    v1_t = tcg_temp_new();
16602    v2_t = tcg_temp_new();
16603
16604    gen_load_gpr(v1_t, v1);
16605    gen_load_gpr(v2_t, v2);
16606
16607    switch (op1) {
16608    case OPC_EXTR_W_DSP:
16609        check_dsp(ctx);
16610        switch (op2) {
16611        case OPC_EXTR_W:
16612            tcg_gen_movi_tl(t0, v2);
16613            tcg_gen_movi_tl(t1, v1);
16614            gen_helper_extr_w(cpu_gpr[ret], t0, t1, cpu_env);
16615            break;
16616        case OPC_EXTR_R_W:
16617            tcg_gen_movi_tl(t0, v2);
16618            tcg_gen_movi_tl(t1, v1);
16619            gen_helper_extr_r_w(cpu_gpr[ret], t0, t1, cpu_env);
16620            break;
16621        case OPC_EXTR_RS_W:
16622            tcg_gen_movi_tl(t0, v2);
16623            tcg_gen_movi_tl(t1, v1);
16624            gen_helper_extr_rs_w(cpu_gpr[ret], t0, t1, cpu_env);
16625            break;
16626        case OPC_EXTR_S_H:
16627            tcg_gen_movi_tl(t0, v2);
16628            tcg_gen_movi_tl(t1, v1);
16629            gen_helper_extr_s_h(cpu_gpr[ret], t0, t1, cpu_env);
16630            break;
16631        case OPC_EXTRV_S_H:
16632            tcg_gen_movi_tl(t0, v2);
16633            gen_helper_extr_s_h(cpu_gpr[ret], t0, v1_t, cpu_env);
16634            break;
16635        case OPC_EXTRV_W:
16636            tcg_gen_movi_tl(t0, v2);
16637            gen_helper_extr_w(cpu_gpr[ret], t0, v1_t, cpu_env);
16638            break;
16639        case OPC_EXTRV_R_W:
16640            tcg_gen_movi_tl(t0, v2);
16641            gen_helper_extr_r_w(cpu_gpr[ret], t0, v1_t, cpu_env);
16642            break;
16643        case OPC_EXTRV_RS_W:
16644            tcg_gen_movi_tl(t0, v2);
16645            gen_helper_extr_rs_w(cpu_gpr[ret], t0, v1_t, cpu_env);
16646            break;
16647        case OPC_EXTP:
16648            tcg_gen_movi_tl(t0, v2);
16649            tcg_gen_movi_tl(t1, v1);
16650            gen_helper_extp(cpu_gpr[ret], t0, t1, cpu_env);
16651            break;
16652        case OPC_EXTPV:
16653            tcg_gen_movi_tl(t0, v2);
16654            gen_helper_extp(cpu_gpr[ret], t0, v1_t, cpu_env);
16655            break;
16656        case OPC_EXTPDP:
16657            tcg_gen_movi_tl(t0, v2);
16658            tcg_gen_movi_tl(t1, v1);
16659            gen_helper_extpdp(cpu_gpr[ret], t0, t1, cpu_env);
16660            break;
16661        case OPC_EXTPDPV:
16662            tcg_gen_movi_tl(t0, v2);
16663            gen_helper_extpdp(cpu_gpr[ret], t0, v1_t, cpu_env);
16664            break;
16665        case OPC_SHILO:
16666            imm = (ctx->opcode >> 20) & 0x3F;
16667            tcg_gen_movi_tl(t0, ret);
16668            tcg_gen_movi_tl(t1, imm);
16669            gen_helper_shilo(t0, t1, cpu_env);
16670            break;
16671        case OPC_SHILOV:
16672            tcg_gen_movi_tl(t0, ret);
16673            gen_helper_shilo(t0, v1_t, cpu_env);
16674            break;
16675        case OPC_MTHLIP:
16676            tcg_gen_movi_tl(t0, ret);
16677            gen_helper_mthlip(t0, v1_t, cpu_env);
16678            break;
16679        case OPC_WRDSP:
16680            imm = (ctx->opcode >> 11) & 0x3FF;
16681            tcg_gen_movi_tl(t0, imm);
16682            gen_helper_wrdsp(v1_t, t0, cpu_env);
16683            break;
16684        case OPC_RDDSP:
16685            imm = (ctx->opcode >> 16) & 0x03FF;
16686            tcg_gen_movi_tl(t0, imm);
16687            gen_helper_rddsp(cpu_gpr[ret], t0, cpu_env);
16688            break;
16689        }
16690        break;
16691#ifdef TARGET_MIPS64
16692    case OPC_DEXTR_W_DSP:
16693        check_dsp(ctx);
16694        switch (op2) {
16695        case OPC_DMTHLIP:
16696            tcg_gen_movi_tl(t0, ret);
16697            gen_helper_dmthlip(v1_t, t0, cpu_env);
16698            break;
16699        case OPC_DSHILO:
16700            {
16701                int shift = (ctx->opcode >> 19) & 0x7F;
16702                int ac = (ctx->opcode >> 11) & 0x03;
16703                tcg_gen_movi_tl(t0, shift);
16704                tcg_gen_movi_tl(t1, ac);
16705                gen_helper_dshilo(t0, t1, cpu_env);
16706                break;
16707            }
16708        case OPC_DSHILOV:
16709            {
16710                int ac = (ctx->opcode >> 11) & 0x03;
16711                tcg_gen_movi_tl(t0, ac);
16712                gen_helper_dshilo(v1_t, t0, cpu_env);
16713                break;
16714            }
16715        case OPC_DEXTP:
16716            tcg_gen_movi_tl(t0, v2);
16717            tcg_gen_movi_tl(t1, v1);
16718
16719            gen_helper_dextp(cpu_gpr[ret], t0, t1, cpu_env);
16720            break;
16721        case OPC_DEXTPV:
16722            tcg_gen_movi_tl(t0, v2);
16723            gen_helper_dextp(cpu_gpr[ret], t0, v1_t, cpu_env);
16724            break;
16725        case OPC_DEXTPDP:
16726            tcg_gen_movi_tl(t0, v2);
16727            tcg_gen_movi_tl(t1, v1);
16728            gen_helper_dextpdp(cpu_gpr[ret], t0, t1, cpu_env);
16729            break;
16730        case OPC_DEXTPDPV:
16731            tcg_gen_movi_tl(t0, v2);
16732            gen_helper_dextpdp(cpu_gpr[ret], t0, v1_t, cpu_env);
16733            break;
16734        case OPC_DEXTR_L:
16735            tcg_gen_movi_tl(t0, v2);
16736            tcg_gen_movi_tl(t1, v1);
16737            gen_helper_dextr_l(cpu_gpr[ret], t0, t1, cpu_env);
16738            break;
16739        case OPC_DEXTR_R_L:
16740            tcg_gen_movi_tl(t0, v2);
16741            tcg_gen_movi_tl(t1, v1);
16742            gen_helper_dextr_r_l(cpu_gpr[ret], t0, t1, cpu_env);
16743            break;
16744        case OPC_DEXTR_RS_L:
16745            tcg_gen_movi_tl(t0, v2);
16746            tcg_gen_movi_tl(t1, v1);
16747            gen_helper_dextr_rs_l(cpu_gpr[ret], t0, t1, cpu_env);
16748            break;
16749        case OPC_DEXTR_W:
16750            tcg_gen_movi_tl(t0, v2);
16751            tcg_gen_movi_tl(t1, v1);
16752            gen_helper_dextr_w(cpu_gpr[ret], t0, t1, cpu_env);
16753            break;
16754        case OPC_DEXTR_R_W:
16755            tcg_gen_movi_tl(t0, v2);
16756            tcg_gen_movi_tl(t1, v1);
16757            gen_helper_dextr_r_w(cpu_gpr[ret], t0, t1, cpu_env);
16758            break;
16759        case OPC_DEXTR_RS_W:
16760            tcg_gen_movi_tl(t0, v2);
16761            tcg_gen_movi_tl(t1, v1);
16762            gen_helper_dextr_rs_w(cpu_gpr[ret], t0, t1, cpu_env);
16763            break;
16764        case OPC_DEXTR_S_H:
16765            tcg_gen_movi_tl(t0, v2);
16766            tcg_gen_movi_tl(t1, v1);
16767            gen_helper_dextr_s_h(cpu_gpr[ret], t0, t1, cpu_env);
16768            break;
16769        case OPC_DEXTRV_S_H:
16770            tcg_gen_movi_tl(t0, v2);
16771            tcg_gen_movi_tl(t1, v1);
16772            gen_helper_dextr_s_h(cpu_gpr[ret], t0, t1, cpu_env);
16773            break;
16774        case OPC_DEXTRV_L:
16775            tcg_gen_movi_tl(t0, v2);
16776            gen_helper_dextr_l(cpu_gpr[ret], t0, v1_t, cpu_env);
16777            break;
16778        case OPC_DEXTRV_R_L:
16779            tcg_gen_movi_tl(t0, v2);
16780            gen_helper_dextr_r_l(cpu_gpr[ret], t0, v1_t, cpu_env);
16781            break;
16782        case OPC_DEXTRV_RS_L:
16783            tcg_gen_movi_tl(t0, v2);
16784            gen_helper_dextr_rs_l(cpu_gpr[ret], t0, v1_t, cpu_env);
16785            break;
16786        case OPC_DEXTRV_W:
16787            tcg_gen_movi_tl(t0, v2);
16788            gen_helper_dextr_w(cpu_gpr[ret], t0, v1_t, cpu_env);
16789            break;
16790        case OPC_DEXTRV_R_W:
16791            tcg_gen_movi_tl(t0, v2);
16792            gen_helper_dextr_r_w(cpu_gpr[ret], t0, v1_t, cpu_env);
16793            break;
16794        case OPC_DEXTRV_RS_W:
16795            tcg_gen_movi_tl(t0, v2);
16796            gen_helper_dextr_rs_w(cpu_gpr[ret], t0, v1_t, cpu_env);
16797            break;
16798        }
16799        break;
16800#endif
16801    }
16802
16803    tcg_temp_free(t0);
16804    tcg_temp_free(t1);
16805    tcg_temp_free(v1_t);
16806    tcg_temp_free(v2_t);
16807}
16808
16809/* End MIPSDSP functions. */
16810
16811static void decode_opc_special_r6(CPUMIPSState *env, DisasContext *ctx)
16812{
16813    int rs, rt, rd, sa;
16814    uint32_t op1, op2;
16815
16816    rs = (ctx->opcode >> 21) & 0x1f;
16817    rt = (ctx->opcode >> 16) & 0x1f;
16818    rd = (ctx->opcode >> 11) & 0x1f;
16819    sa = (ctx->opcode >> 6) & 0x1f;
16820
16821    op1 = MASK_SPECIAL(ctx->opcode);
16822    switch (op1) {
16823    case OPC_LSA:
16824        gen_lsa(ctx, op1, rd, rs, rt, extract32(ctx->opcode, 6, 2));
16825        break;
16826    case OPC_MULT ... OPC_DIVU:
16827        op2 = MASK_R6_MULDIV(ctx->opcode);
16828        switch (op2) {
16829        case R6_OPC_MUL:
16830        case R6_OPC_MUH:
16831        case R6_OPC_MULU:
16832        case R6_OPC_MUHU:
16833        case R6_OPC_DIV:
16834        case R6_OPC_MOD:
16835        case R6_OPC_DIVU:
16836        case R6_OPC_MODU:
16837            gen_r6_muldiv(ctx, op2, rd, rs, rt);
16838            break;
16839        default:
16840            MIPS_INVAL("special_r6 muldiv");
16841            generate_exception_end(ctx, EXCP_RI);
16842            break;
16843        }
16844        break;
16845    case OPC_SELEQZ:
16846    case OPC_SELNEZ:
16847        gen_cond_move(ctx, op1, rd, rs, rt);
16848        break;
16849    case R6_OPC_CLO:
16850    case R6_OPC_CLZ:
16851        if (rt == 0 && sa == 1) {
16852            /* Major opcode and function field is shared with preR6 MFHI/MTHI.
16853               We need additionally to check other fields */
16854            gen_cl(ctx, op1, rd, rs);
16855        } else {
16856            generate_exception_end(ctx, EXCP_RI);
16857        }
16858        break;
16859    case R6_OPC_SDBBP:
16860        if (is_uhi(extract32(ctx->opcode, 6, 20))) {
16861            gen_helper_do_semihosting(cpu_env);
16862        } else {
16863            if (ctx->hflags & MIPS_HFLAG_SBRI) {
16864                generate_exception_end(ctx, EXCP_RI);
16865            } else {
16866                generate_exception_end(ctx, EXCP_DBp);
16867            }
16868        }
16869        break;
16870#if defined(TARGET_MIPS64)
16871    case OPC_DLSA:
16872        check_mips_64(ctx);
16873        gen_lsa(ctx, op1, rd, rs, rt, extract32(ctx->opcode, 6, 2));
16874        break;
16875    case R6_OPC_DCLO:
16876    case R6_OPC_DCLZ:
16877        if (rt == 0 && sa == 1) {
16878            /* Major opcode and function field is shared with preR6 MFHI/MTHI.
16879               We need additionally to check other fields */
16880            check_mips_64(ctx);
16881            gen_cl(ctx, op1, rd, rs);
16882        } else {
16883            generate_exception_end(ctx, EXCP_RI);
16884        }
16885        break;
16886    case OPC_DMULT ... OPC_DDIVU:
16887        op2 = MASK_R6_MULDIV(ctx->opcode);
16888        switch (op2) {
16889        case R6_OPC_DMUL:
16890        case R6_OPC_DMUH:
16891        case R6_OPC_DMULU:
16892        case R6_OPC_DMUHU:
16893        case R6_OPC_DDIV:
16894        case R6_OPC_DMOD:
16895        case R6_OPC_DDIVU:
16896        case R6_OPC_DMODU:
16897            check_mips_64(ctx);
16898            gen_r6_muldiv(ctx, op2, rd, rs, rt);
16899            break;
16900        default:
16901            MIPS_INVAL("special_r6 muldiv");
16902            generate_exception_end(ctx, EXCP_RI);
16903            break;
16904        }
16905        break;
16906#endif
16907    default:            /* Invalid */
16908        MIPS_INVAL("special_r6");
16909        generate_exception_end(ctx, EXCP_RI);
16910        break;
16911    }
16912}
16913
16914static void decode_opc_special_legacy(CPUMIPSState *env, DisasContext *ctx)
16915{
16916    int rs, rt, rd, sa;
16917    uint32_t op1;
16918
16919    rs = (ctx->opcode >> 21) & 0x1f;
16920    rt = (ctx->opcode >> 16) & 0x1f;
16921    rd = (ctx->opcode >> 11) & 0x1f;
16922    sa = (ctx->opcode >> 6) & 0x1f;
16923
16924    op1 = MASK_SPECIAL(ctx->opcode);
16925    switch (op1) {
16926    case OPC_MOVN:         /* Conditional move */
16927    case OPC_MOVZ:
16928        check_insn(ctx, ISA_MIPS4 | ISA_MIPS32 |
16929                   INSN_LOONGSON2E | INSN_LOONGSON2F);
16930        gen_cond_move(ctx, op1, rd, rs, rt);
16931        break;
16932    case OPC_MFHI:          /* Move from HI/LO */
16933    case OPC_MFLO:
16934        gen_HILO(ctx, op1, rs & 3, rd);
16935        break;
16936    case OPC_MTHI:
16937    case OPC_MTLO:          /* Move to HI/LO */
16938        gen_HILO(ctx, op1, rd & 3, rs);
16939        break;
16940    case OPC_MOVCI:
16941        check_insn(ctx, ISA_MIPS4 | ISA_MIPS32);
16942        if (env->CP0_Config1 & (1 << CP0C1_FP)) {
16943            check_cp1_enabled(ctx);
16944            gen_movci(ctx, rd, rs, (ctx->opcode >> 18) & 0x7,
16945                      (ctx->opcode >> 16) & 1);
16946        } else {
16947            generate_exception_err(ctx, EXCP_CpU, 1);
16948        }
16949        break;
16950    case OPC_MULT:
16951    case OPC_MULTU:
16952        if (sa) {
16953            check_insn(ctx, INSN_VR54XX);
16954            op1 = MASK_MUL_VR54XX(ctx->opcode);
16955            gen_mul_vr54xx(ctx, op1, rd, rs, rt);
16956        } else {
16957            gen_muldiv(ctx, op1, rd & 3, rs, rt);
16958        }
16959        break;
16960    case OPC_DIV:
16961    case OPC_DIVU:
16962        gen_muldiv(ctx, op1, 0, rs, rt);
16963        break;
16964#if defined(TARGET_MIPS64)
16965    case OPC_DMULT ... OPC_DDIVU:
16966        check_insn(ctx, ISA_MIPS3);
16967        check_mips_64(ctx);
16968        gen_muldiv(ctx, op1, 0, rs, rt);
16969        break;
16970#endif
16971    case OPC_JR:
16972        gen_compute_branch(ctx, op1, 4, rs, rd, sa, 4);
16973        break;
16974    case OPC_SPIM:
16975#ifdef MIPS_STRICT_STANDARD
16976        MIPS_INVAL("SPIM");
16977        generate_exception_end(ctx, EXCP_RI);
16978#else
16979        /* Implemented as RI exception for now. */
16980        MIPS_INVAL("spim (unofficial)");
16981        generate_exception_end(ctx, EXCP_RI);
16982#endif
16983        break;
16984    default:            /* Invalid */
16985        MIPS_INVAL("special_legacy");
16986        generate_exception_end(ctx, EXCP_RI);
16987        break;
16988    }
16989}
16990
16991static void decode_opc_special(CPUMIPSState *env, DisasContext *ctx)
16992{
16993    int rs, rt, rd, sa;
16994    uint32_t op1;
16995
16996    rs = (ctx->opcode >> 21) & 0x1f;
16997    rt = (ctx->opcode >> 16) & 0x1f;
16998    rd = (ctx->opcode >> 11) & 0x1f;
16999    sa = (ctx->opcode >> 6) & 0x1f;
17000
17001    op1 = MASK_SPECIAL(ctx->opcode);
17002    switch (op1) {
17003    case OPC_SLL:          /* Shift with immediate */
17004        if (sa == 5 && rd == 0 &&
17005            rs == 0 && rt == 0) { /* PAUSE */
17006            if ((ctx->insn_flags & ISA_MIPS32R6) &&
17007                (ctx->hflags & MIPS_HFLAG_BMASK)) {
17008                generate_exception_end(ctx, EXCP_RI);
17009                break;
17010            }
17011        }
17012        /* Fallthrough */
17013    case OPC_SRA:
17014        gen_shift_imm(ctx, op1, rd, rt, sa);
17015        break;
17016    case OPC_SRL:
17017        switch ((ctx->opcode >> 21) & 0x1f) {
17018        case 1:
17019            /* rotr is decoded as srl on non-R2 CPUs */
17020            if (ctx->insn_flags & ISA_MIPS32R2) {
17021                op1 = OPC_ROTR;
17022            }
17023            /* Fallthrough */
17024        case 0:
17025            gen_shift_imm(ctx, op1, rd, rt, sa);
17026            break;
17027        default:
17028            generate_exception_end(ctx, EXCP_RI);
17029            break;
17030        }
17031        break;
17032    case OPC_ADD ... OPC_SUBU:
17033        gen_arith(ctx, op1, rd, rs, rt);
17034        break;
17035    case OPC_SLLV:         /* Shifts */
17036    case OPC_SRAV:
17037        gen_shift(ctx, op1, rd, rs, rt);
17038        break;
17039    case OPC_SRLV:
17040        switch ((ctx->opcode >> 6) & 0x1f) {
17041        case 1:
17042            /* rotrv is decoded as srlv on non-R2 CPUs */
17043            if (ctx->insn_flags & ISA_MIPS32R2) {
17044                op1 = OPC_ROTRV;
17045            }
17046            /* Fallthrough */
17047        case 0:
17048            gen_shift(ctx, op1, rd, rs, rt);
17049            break;
17050        default:
17051            generate_exception_end(ctx, EXCP_RI);
17052            break;
17053        }
17054        break;
17055    case OPC_SLT:          /* Set on less than */
17056    case OPC_SLTU:
17057        gen_slt(ctx, op1, rd, rs, rt);
17058        break;
17059    case OPC_AND:          /* Logic*/
17060    case OPC_OR:
17061    case OPC_NOR:
17062    case OPC_XOR:
17063        gen_logic(ctx, op1, rd, rs, rt);
17064        break;
17065    case OPC_JALR:
17066        gen_compute_branch(ctx, op1, 4, rs, rd, sa, 4);
17067        break;
17068    case OPC_TGE ... OPC_TEQ: /* Traps */
17069    case OPC_TNE:
17070        check_insn(ctx, ISA_MIPS2);
17071        gen_trap(ctx, op1, rs, rt, -1);
17072        break;
17073    case OPC_LSA: /* OPC_PMON */
17074        if ((ctx->insn_flags & ISA_MIPS32R6) ||
17075            (env->CP0_Config3 & (1 << CP0C3_MSAP))) {
17076            decode_opc_special_r6(env, ctx);
17077        } else {
17078            /* Pmon entry point, also R4010 selsl */
17079#ifdef MIPS_STRICT_STANDARD
17080            MIPS_INVAL("PMON / selsl");
17081            generate_exception_end(ctx, EXCP_RI);
17082#else
17083            gen_helper_0e0i(pmon, sa);
17084#endif
17085        }
17086        break;
17087    case OPC_SYSCALL:
17088        generate_exception_end(ctx, EXCP_SYSCALL);
17089        break;
17090    case OPC_BREAK:
17091        generate_exception_end(ctx, EXCP_BREAK);
17092        break;
17093    case OPC_SYNC:
17094        check_insn(ctx, ISA_MIPS2);
17095        /* Treat as NOP. */
17096        break;
17097
17098#if defined(TARGET_MIPS64)
17099        /* MIPS64 specific opcodes */
17100    case OPC_DSLL:
17101    case OPC_DSRA:
17102    case OPC_DSLL32:
17103    case OPC_DSRA32:
17104        check_insn(ctx, ISA_MIPS3);
17105        check_mips_64(ctx);
17106        gen_shift_imm(ctx, op1, rd, rt, sa);
17107        break;
17108    case OPC_DSRL:
17109        switch ((ctx->opcode >> 21) & 0x1f) {
17110        case 1:
17111            /* drotr is decoded as dsrl on non-R2 CPUs */
17112            if (ctx->insn_flags & ISA_MIPS32R2) {
17113                op1 = OPC_DROTR;
17114            }
17115            /* Fallthrough */
17116        case 0:
17117            check_insn(ctx, ISA_MIPS3);
17118            check_mips_64(ctx);
17119            gen_shift_imm(ctx, op1, rd, rt, sa);
17120            break;
17121        default:
17122            generate_exception_end(ctx, EXCP_RI);
17123            break;
17124        }
17125        break;
17126    case OPC_DSRL32:
17127        switch ((ctx->opcode >> 21) & 0x1f) {
17128        case 1:
17129            /* drotr32 is decoded as dsrl32 on non-R2 CPUs */
17130            if (ctx->insn_flags & ISA_MIPS32R2) {
17131                op1 = OPC_DROTR32;
17132            }
17133            /* Fallthrough */
17134        case 0:
17135            check_insn(ctx, ISA_MIPS3);
17136            check_mips_64(ctx);
17137            gen_shift_imm(ctx, op1, rd, rt, sa);
17138            break;
17139        default:
17140            generate_exception_end(ctx, EXCP_RI);
17141            break;
17142        }
17143        break;
17144    case OPC_DADD ... OPC_DSUBU:
17145        check_insn(ctx, ISA_MIPS3);
17146        check_mips_64(ctx);
17147        gen_arith(ctx, op1, rd, rs, rt);
17148        break;
17149    case OPC_DSLLV:
17150    case OPC_DSRAV:
17151        check_insn(ctx, ISA_MIPS3);
17152        check_mips_64(ctx);
17153        gen_shift(ctx, op1, rd, rs, rt);
17154        break;
17155    case OPC_DSRLV:
17156        switch ((ctx->opcode >> 6) & 0x1f) {
17157        case 1:
17158            /* drotrv is decoded as dsrlv on non-R2 CPUs */
17159            if (ctx->insn_flags & ISA_MIPS32R2) {
17160                op1 = OPC_DROTRV;
17161            }
17162            /* Fallthrough */
17163        case 0:
17164            check_insn(ctx, ISA_MIPS3);
17165            check_mips_64(ctx);
17166            gen_shift(ctx, op1, rd, rs, rt);
17167            break;
17168        default:
17169            generate_exception_end(ctx, EXCP_RI);
17170            break;
17171        }
17172        break;
17173    case OPC_DLSA:
17174        if ((ctx->insn_flags & ISA_MIPS32R6) ||
17175            (env->CP0_Config3 & (1 << CP0C3_MSAP))) {
17176            decode_opc_special_r6(env, ctx);
17177        }
17178        break;
17179#endif
17180    default:
17181        if (ctx->insn_flags & ISA_MIPS32R6) {
17182            decode_opc_special_r6(env, ctx);
17183        } else {
17184            decode_opc_special_legacy(env, ctx);
17185        }
17186    }
17187}
17188
17189static void decode_opc_special2_legacy(CPUMIPSState *env, DisasContext *ctx)
17190{
17191    int rs, rt, rd;
17192    uint32_t op1;
17193
17194    check_insn_opc_removed(ctx, ISA_MIPS32R6);
17195
17196    rs = (ctx->opcode >> 21) & 0x1f;
17197    rt = (ctx->opcode >> 16) & 0x1f;
17198    rd = (ctx->opcode >> 11) & 0x1f;
17199
17200    op1 = MASK_SPECIAL2(ctx->opcode);
17201    switch (op1) {
17202    case OPC_MADD ... OPC_MADDU: /* Multiply and add/sub */
17203    case OPC_MSUB ... OPC_MSUBU:
17204        check_insn(ctx, ISA_MIPS32);
17205        gen_muldiv(ctx, op1, rd & 3, rs, rt);
17206        break;
17207    case OPC_MUL:
17208        gen_arith(ctx, op1, rd, rs, rt);
17209        break;
17210    case OPC_DIV_G_2F:
17211    case OPC_DIVU_G_2F:
17212    case OPC_MULT_G_2F:
17213    case OPC_MULTU_G_2F:
17214    case OPC_MOD_G_2F:
17215    case OPC_MODU_G_2F:
17216        check_insn(ctx, INSN_LOONGSON2F);
17217        gen_loongson_integer(ctx, op1, rd, rs, rt);
17218        break;
17219    case OPC_CLO:
17220    case OPC_CLZ:
17221        check_insn(ctx, ISA_MIPS32);
17222        gen_cl(ctx, op1, rd, rs);
17223        break;
17224    case OPC_SDBBP:
17225        if (is_uhi(extract32(ctx->opcode, 6, 20))) {
17226            gen_helper_do_semihosting(cpu_env);
17227        } else {
17228            /* XXX: not clear which exception should be raised
17229             *      when in debug mode...
17230             */
17231            check_insn(ctx, ISA_MIPS32);
17232            generate_exception_end(ctx, EXCP_DBp);
17233        }
17234        break;
17235#if defined(TARGET_MIPS64)
17236    case OPC_DCLO:
17237    case OPC_DCLZ:
17238        check_insn(ctx, ISA_MIPS64);
17239        check_mips_64(ctx);
17240        gen_cl(ctx, op1, rd, rs);
17241        break;
17242    case OPC_DMULT_G_2F:
17243    case OPC_DMULTU_G_2F:
17244    case OPC_DDIV_G_2F:
17245    case OPC_DDIVU_G_2F:
17246    case OPC_DMOD_G_2F:
17247    case OPC_DMODU_G_2F:
17248        check_insn(ctx, INSN_LOONGSON2F);
17249        gen_loongson_integer(ctx, op1, rd, rs, rt);
17250        break;
17251#endif
17252    default:            /* Invalid */
17253        MIPS_INVAL("special2_legacy");
17254        generate_exception_end(ctx, EXCP_RI);
17255        break;
17256    }
17257}
17258
17259static void decode_opc_special3_r6(CPUMIPSState *env, DisasContext *ctx)
17260{
17261    int rs, rt, rd, sa;
17262    uint32_t op1, op2;
17263    int16_t imm;
17264
17265    rs = (ctx->opcode >> 21) & 0x1f;
17266    rt = (ctx->opcode >> 16) & 0x1f;
17267    rd = (ctx->opcode >> 11) & 0x1f;
17268    sa = (ctx->opcode >> 6) & 0x1f;
17269    imm = (int16_t)ctx->opcode >> 7;
17270
17271    op1 = MASK_SPECIAL3(ctx->opcode);
17272    switch (op1) {
17273    case R6_OPC_PREF:
17274        if (rt >= 24) {
17275            /* hint codes 24-31 are reserved and signal RI */
17276            generate_exception_end(ctx, EXCP_RI);
17277        }
17278        /* Treat as NOP. */
17279        break;
17280    case R6_OPC_CACHE:
17281        check_cp0_enabled(ctx);
17282        if (ctx->hflags & MIPS_HFLAG_ITC_CACHE) {
17283            gen_cache_operation(ctx, rt, rs, imm);
17284        }
17285        break;
17286    case R6_OPC_SC:
17287        gen_st_cond(ctx, op1, rt, rs, imm);
17288        break;
17289    case R6_OPC_LL:
17290        gen_ld(ctx, op1, rt, rs, imm);
17291        break;
17292    case OPC_BSHFL:
17293        {
17294            if (rd == 0) {
17295                /* Treat as NOP. */
17296                break;
17297            }
17298            op2 = MASK_BSHFL(ctx->opcode);
17299            switch (op2) {
17300            case OPC_ALIGN ... OPC_ALIGN_END:
17301                gen_align(ctx, OPC_ALIGN, rd, rs, rt, sa & 3);
17302                break;
17303            case OPC_BITSWAP:
17304                gen_bitswap(ctx, op2, rd, rt);
17305                break;
17306            }
17307        }
17308        break;
17309#if defined(TARGET_MIPS64)
17310    case R6_OPC_SCD:
17311        gen_st_cond(ctx, op1, rt, rs, imm);
17312        break;
17313    case R6_OPC_LLD:
17314        gen_ld(ctx, op1, rt, rs, imm);
17315        break;
17316    case OPC_DBSHFL:
17317        check_mips_64(ctx);
17318        {
17319            if (rd == 0) {
17320                /* Treat as NOP. */
17321                break;
17322            }
17323            op2 = MASK_DBSHFL(ctx->opcode);
17324            switch (op2) {
17325            case OPC_DALIGN ... OPC_DALIGN_END:
17326                gen_align(ctx, OPC_DALIGN, rd, rs, rt, sa & 7);
17327                break;
17328            case OPC_DBITSWAP:
17329                gen_bitswap(ctx, op2, rd, rt);
17330                break;
17331            }
17332
17333        }
17334        break;
17335#endif
17336    default:            /* Invalid */
17337        MIPS_INVAL("special3_r6");
17338        generate_exception_end(ctx, EXCP_RI);
17339        break;
17340    }
17341}
17342
17343static void decode_opc_special3_legacy(CPUMIPSState *env, DisasContext *ctx)
17344{
17345    int rs, rt, rd;
17346    uint32_t op1, op2;
17347
17348    rs = (ctx->opcode >> 21) & 0x1f;
17349    rt = (ctx->opcode >> 16) & 0x1f;
17350    rd = (ctx->opcode >> 11) & 0x1f;
17351
17352    op1 = MASK_SPECIAL3(ctx->opcode);
17353    switch (op1) {
17354    case OPC_DIV_G_2E ... OPC_DIVU_G_2E:
17355    case OPC_MOD_G_2E ... OPC_MODU_G_2E:
17356    case OPC_MULT_G_2E ... OPC_MULTU_G_2E:
17357        /* OPC_MULT_G_2E, OPC_ADDUH_QB_DSP, OPC_MUL_PH_DSP have
17358         * the same mask and op1. */
17359        if ((ctx->insn_flags & ASE_DSPR2) && (op1 == OPC_MULT_G_2E)) {
17360            op2 = MASK_ADDUH_QB(ctx->opcode);
17361            switch (op2) {
17362            case OPC_ADDUH_QB:
17363            case OPC_ADDUH_R_QB:
17364            case OPC_ADDQH_PH:
17365            case OPC_ADDQH_R_PH:
17366            case OPC_ADDQH_W:
17367            case OPC_ADDQH_R_W:
17368            case OPC_SUBUH_QB:
17369            case OPC_SUBUH_R_QB:
17370            case OPC_SUBQH_PH:
17371            case OPC_SUBQH_R_PH:
17372            case OPC_SUBQH_W:
17373            case OPC_SUBQH_R_W:
17374                gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
17375                break;
17376            case OPC_MUL_PH:
17377            case OPC_MUL_S_PH:
17378            case OPC_MULQ_S_W:
17379            case OPC_MULQ_RS_W:
17380                gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 1);
17381                break;
17382            default:
17383                MIPS_INVAL("MASK ADDUH.QB");
17384                generate_exception_end(ctx, EXCP_RI);
17385                break;
17386            }
17387        } else if (ctx->insn_flags & INSN_LOONGSON2E) {
17388            gen_loongson_integer(ctx, op1, rd, rs, rt);
17389        } else {
17390            generate_exception_end(ctx, EXCP_RI);
17391        }
17392        break;
17393    case OPC_LX_DSP:
17394        op2 = MASK_LX(ctx->opcode);
17395        switch (op2) {
17396#if defined(TARGET_MIPS64)
17397        case OPC_LDX:
17398#endif
17399        case OPC_LBUX:
17400        case OPC_LHX:
17401        case OPC_LWX:
17402            gen_mipsdsp_ld(ctx, op2, rd, rs, rt);
17403            break;
17404        default:            /* Invalid */
17405            MIPS_INVAL("MASK LX");
17406            generate_exception_end(ctx, EXCP_RI);
17407            break;
17408        }
17409        break;
17410    case OPC_ABSQ_S_PH_DSP:
17411        op2 = MASK_ABSQ_S_PH(ctx->opcode);
17412        switch (op2) {
17413        case OPC_ABSQ_S_QB:
17414        case OPC_ABSQ_S_PH:
17415        case OPC_ABSQ_S_W:
17416        case OPC_PRECEQ_W_PHL:
17417        case OPC_PRECEQ_W_PHR:
17418        case OPC_PRECEQU_PH_QBL:
17419        case OPC_PRECEQU_PH_QBR:
17420        case OPC_PRECEQU_PH_QBLA:
17421        case OPC_PRECEQU_PH_QBRA:
17422        case OPC_PRECEU_PH_QBL:
17423        case OPC_PRECEU_PH_QBR:
17424        case OPC_PRECEU_PH_QBLA:
17425        case OPC_PRECEU_PH_QBRA:
17426            gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
17427            break;
17428        case OPC_BITREV:
17429        case OPC_REPL_QB:
17430        case OPC_REPLV_QB:
17431        case OPC_REPL_PH:
17432        case OPC_REPLV_PH:
17433            gen_mipsdsp_bitinsn(ctx, op1, op2, rd, rt);
17434            break;
17435        default:
17436            MIPS_INVAL("MASK ABSQ_S.PH");
17437            generate_exception_end(ctx, EXCP_RI);
17438            break;
17439        }
17440        break;
17441    case OPC_ADDU_QB_DSP:
17442        op2 = MASK_ADDU_QB(ctx->opcode);
17443        switch (op2) {
17444        case OPC_ADDQ_PH:
17445        case OPC_ADDQ_S_PH:
17446        case OPC_ADDQ_S_W:
17447        case OPC_ADDU_QB:
17448        case OPC_ADDU_S_QB:
17449        case OPC_ADDU_PH:
17450        case OPC_ADDU_S_PH:
17451        case OPC_SUBQ_PH:
17452        case OPC_SUBQ_S_PH:
17453        case OPC_SUBQ_S_W:
17454        case OPC_SUBU_QB:
17455        case OPC_SUBU_S_QB:
17456        case OPC_SUBU_PH:
17457        case OPC_SUBU_S_PH:
17458        case OPC_ADDSC:
17459        case OPC_ADDWC:
17460        case OPC_MODSUB:
17461        case OPC_RADDU_W_QB:
17462            gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
17463            break;
17464        case OPC_MULEU_S_PH_QBL:
17465        case OPC_MULEU_S_PH_QBR:
17466        case OPC_MULQ_RS_PH:
17467        case OPC_MULEQ_S_W_PHL:
17468        case OPC_MULEQ_S_W_PHR:
17469        case OPC_MULQ_S_PH:
17470            gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 1);
17471            break;
17472        default:            /* Invalid */
17473            MIPS_INVAL("MASK ADDU.QB");
17474            generate_exception_end(ctx, EXCP_RI);
17475            break;
17476
17477        }
17478        break;
17479    case OPC_CMPU_EQ_QB_DSP:
17480        op2 = MASK_CMPU_EQ_QB(ctx->opcode);
17481        switch (op2) {
17482        case OPC_PRECR_SRA_PH_W:
17483        case OPC_PRECR_SRA_R_PH_W:
17484            gen_mipsdsp_arith(ctx, op1, op2, rt, rs, rd);
17485            break;
17486        case OPC_PRECR_QB_PH:
17487        case OPC_PRECRQ_QB_PH:
17488        case OPC_PRECRQ_PH_W:
17489        case OPC_PRECRQ_RS_PH_W:
17490        case OPC_PRECRQU_S_QB_PH:
17491            gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
17492            break;
17493        case OPC_CMPU_EQ_QB:
17494        case OPC_CMPU_LT_QB:
17495        case OPC_CMPU_LE_QB:
17496        case OPC_CMP_EQ_PH:
17497        case OPC_CMP_LT_PH:
17498        case OPC_CMP_LE_PH:
17499            gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 0);
17500            break;
17501        case OPC_CMPGU_EQ_QB:
17502        case OPC_CMPGU_LT_QB:
17503        case OPC_CMPGU_LE_QB:
17504        case OPC_CMPGDU_EQ_QB:
17505        case OPC_CMPGDU_LT_QB:
17506        case OPC_CMPGDU_LE_QB:
17507        case OPC_PICK_QB:
17508        case OPC_PICK_PH:
17509        case OPC_PACKRL_PH:
17510            gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 1);
17511            break;
17512        default:            /* Invalid */
17513            MIPS_INVAL("MASK CMPU.EQ.QB");
17514            generate_exception_end(ctx, EXCP_RI);
17515            break;
17516        }
17517        break;
17518    case OPC_SHLL_QB_DSP:
17519        gen_mipsdsp_shift(ctx, op1, rd, rs, rt);
17520        break;
17521    case OPC_DPA_W_PH_DSP:
17522        op2 = MASK_DPA_W_PH(ctx->opcode);
17523        switch (op2) {
17524        case OPC_DPAU_H_QBL:
17525        case OPC_DPAU_H_QBR:
17526        case OPC_DPSU_H_QBL:
17527        case OPC_DPSU_H_QBR:
17528        case OPC_DPA_W_PH:
17529        case OPC_DPAX_W_PH:
17530        case OPC_DPAQ_S_W_PH:
17531        case OPC_DPAQX_S_W_PH:
17532        case OPC_DPAQX_SA_W_PH:
17533        case OPC_DPS_W_PH:
17534        case OPC_DPSX_W_PH:
17535        case OPC_DPSQ_S_W_PH:
17536        case OPC_DPSQX_S_W_PH:
17537        case OPC_DPSQX_SA_W_PH:
17538        case OPC_MULSAQ_S_W_PH:
17539        case OPC_DPAQ_SA_L_W:
17540        case OPC_DPSQ_SA_L_W:
17541        case OPC_MAQ_S_W_PHL:
17542        case OPC_MAQ_S_W_PHR:
17543        case OPC_MAQ_SA_W_PHL:
17544        case OPC_MAQ_SA_W_PHR:
17545        case OPC_MULSA_W_PH:
17546            gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 0);
17547            break;
17548        default:            /* Invalid */
17549            MIPS_INVAL("MASK DPAW.PH");
17550            generate_exception_end(ctx, EXCP_RI);
17551            break;
17552        }
17553        break;
17554    case OPC_INSV_DSP:
17555        op2 = MASK_INSV(ctx->opcode);
17556        switch (op2) {
17557        case OPC_INSV:
17558            check_dsp(ctx);
17559            {
17560                TCGv t0, t1;
17561
17562                if (rt == 0) {
17563                    break;
17564                }
17565
17566                t0 = tcg_temp_new();
17567                t1 = tcg_temp_new();
17568
17569                gen_load_gpr(t0, rt);
17570                gen_load_gpr(t1, rs);
17571
17572                gen_helper_insv(cpu_gpr[rt], cpu_env, t1, t0);
17573
17574                tcg_temp_free(t0);
17575                tcg_temp_free(t1);
17576                break;
17577            }
17578        default:            /* Invalid */
17579            MIPS_INVAL("MASK INSV");
17580            generate_exception_end(ctx, EXCP_RI);
17581            break;
17582        }
17583        break;
17584    case OPC_APPEND_DSP:
17585        gen_mipsdsp_append(env, ctx, op1, rt, rs, rd);
17586        break;
17587    case OPC_EXTR_W_DSP:
17588        op2 = MASK_EXTR_W(ctx->opcode);
17589        switch (op2) {
17590        case OPC_EXTR_W:
17591        case OPC_EXTR_R_W:
17592        case OPC_EXTR_RS_W:
17593        case OPC_EXTR_S_H:
17594        case OPC_EXTRV_S_H:
17595        case OPC_EXTRV_W:
17596        case OPC_EXTRV_R_W:
17597        case OPC_EXTRV_RS_W:
17598        case OPC_EXTP:
17599        case OPC_EXTPV:
17600        case OPC_EXTPDP:
17601        case OPC_EXTPDPV:
17602            gen_mipsdsp_accinsn(ctx, op1, op2, rt, rs, rd, 1);
17603            break;
17604        case OPC_RDDSP:
17605            gen_mipsdsp_accinsn(ctx, op1, op2, rd, rs, rt, 1);
17606            break;
17607        case OPC_SHILO:
17608        case OPC_SHILOV:
17609        case OPC_MTHLIP:
17610        case OPC_WRDSP:
17611            gen_mipsdsp_accinsn(ctx, op1, op2, rd, rs, rt, 0);
17612            break;
17613        default:            /* Invalid */
17614            MIPS_INVAL("MASK EXTR.W");
17615            generate_exception_end(ctx, EXCP_RI);
17616            break;
17617        }
17618        break;
17619#if defined(TARGET_MIPS64)
17620    case OPC_DDIV_G_2E ... OPC_DDIVU_G_2E:
17621    case OPC_DMULT_G_2E ... OPC_DMULTU_G_2E:
17622    case OPC_DMOD_G_2E ... OPC_DMODU_G_2E:
17623        check_insn(ctx, INSN_LOONGSON2E);
17624        gen_loongson_integer(ctx, op1, rd, rs, rt);
17625        break;
17626    case OPC_ABSQ_S_QH_DSP:
17627        op2 = MASK_ABSQ_S_QH(ctx->opcode);
17628        switch (op2) {
17629        case OPC_PRECEQ_L_PWL:
17630        case OPC_PRECEQ_L_PWR:
17631        case OPC_PRECEQ_PW_QHL:
17632        case OPC_PRECEQ_PW_QHR:
17633        case OPC_PRECEQ_PW_QHLA:
17634        case OPC_PRECEQ_PW_QHRA:
17635        case OPC_PRECEQU_QH_OBL:
17636        case OPC_PRECEQU_QH_OBR:
17637        case OPC_PRECEQU_QH_OBLA:
17638        case OPC_PRECEQU_QH_OBRA:
17639        case OPC_PRECEU_QH_OBL:
17640        case OPC_PRECEU_QH_OBR:
17641        case OPC_PRECEU_QH_OBLA:
17642        case OPC_PRECEU_QH_OBRA:
17643        case OPC_ABSQ_S_OB:
17644        case OPC_ABSQ_S_PW:
17645        case OPC_ABSQ_S_QH:
17646            gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
17647            break;
17648        case OPC_REPL_OB:
17649        case OPC_REPL_PW:
17650        case OPC_REPL_QH:
17651        case OPC_REPLV_OB:
17652        case OPC_REPLV_PW:
17653        case OPC_REPLV_QH:
17654            gen_mipsdsp_bitinsn(ctx, op1, op2, rd, rt);
17655            break;
17656        default:            /* Invalid */
17657            MIPS_INVAL("MASK ABSQ_S.QH");
17658            generate_exception_end(ctx, EXCP_RI);
17659            break;
17660        }
17661        break;
17662    case OPC_ADDU_OB_DSP:
17663        op2 = MASK_ADDU_OB(ctx->opcode);
17664        switch (op2) {
17665        case OPC_RADDU_L_OB:
17666        case OPC_SUBQ_PW:
17667        case OPC_SUBQ_S_PW:
17668        case OPC_SUBQ_QH:
17669        case OPC_SUBQ_S_QH:
17670        case OPC_SUBU_OB:
17671        case OPC_SUBU_S_OB:
17672        case OPC_SUBU_QH:
17673        case OPC_SUBU_S_QH:
17674        case OPC_SUBUH_OB:
17675        case OPC_SUBUH_R_OB:
17676        case OPC_ADDQ_PW:
17677        case OPC_ADDQ_S_PW:
17678        case OPC_ADDQ_QH:
17679        case OPC_ADDQ_S_QH:
17680        case OPC_ADDU_OB:
17681        case OPC_ADDU_S_OB:
17682        case OPC_ADDU_QH:
17683        case OPC_ADDU_S_QH:
17684        case OPC_ADDUH_OB:
17685        case OPC_ADDUH_R_OB:
17686            gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
17687            break;
17688        case OPC_MULEQ_S_PW_QHL:
17689        case OPC_MULEQ_S_PW_QHR:
17690        case OPC_MULEU_S_QH_OBL:
17691        case OPC_MULEU_S_QH_OBR:
17692        case OPC_MULQ_RS_QH:
17693            gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 1);
17694            break;
17695        default:            /* Invalid */
17696            MIPS_INVAL("MASK ADDU.OB");
17697            generate_exception_end(ctx, EXCP_RI);
17698            break;
17699        }
17700        break;
17701    case OPC_CMPU_EQ_OB_DSP:
17702        op2 = MASK_CMPU_EQ_OB(ctx->opcode);
17703        switch (op2) {
17704        case OPC_PRECR_SRA_QH_PW:
17705        case OPC_PRECR_SRA_R_QH_PW:
17706            /* Return value is rt. */
17707            gen_mipsdsp_arith(ctx, op1, op2, rt, rs, rd);
17708            break;
17709        case OPC_PRECR_OB_QH:
17710        case OPC_PRECRQ_OB_QH:
17711        case OPC_PRECRQ_PW_L:
17712        case OPC_PRECRQ_QH_PW:
17713        case OPC_PRECRQ_RS_QH_PW:
17714        case OPC_PRECRQU_S_OB_QH:
17715            gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
17716            break;
17717        case OPC_CMPU_EQ_OB:
17718        case OPC_CMPU_LT_OB:
17719        case OPC_CMPU_LE_OB:
17720        case OPC_CMP_EQ_QH:
17721        case OPC_CMP_LT_QH:
17722        case OPC_CMP_LE_QH:
17723        case OPC_CMP_EQ_PW:
17724        case OPC_CMP_LT_PW:
17725        case OPC_CMP_LE_PW:
17726            gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 0);
17727            break;
17728        case OPC_CMPGDU_EQ_OB:
17729        case OPC_CMPGDU_LT_OB:
17730        case OPC_CMPGDU_LE_OB:
17731        case OPC_CMPGU_EQ_OB:
17732        case OPC_CMPGU_LT_OB:
17733        case OPC_CMPGU_LE_OB:
17734        case OPC_PACKRL_PW:
17735        case OPC_PICK_OB:
17736        case OPC_PICK_PW:
17737        case OPC_PICK_QH:
17738            gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 1);
17739            break;
17740        default:            /* Invalid */
17741            MIPS_INVAL("MASK CMPU_EQ.OB");
17742            generate_exception_end(ctx, EXCP_RI);
17743            break;
17744        }
17745        break;
17746    case OPC_DAPPEND_DSP:
17747        gen_mipsdsp_append(env, ctx, op1, rt, rs, rd);
17748        break;
17749    case OPC_DEXTR_W_DSP:
17750        op2 = MASK_DEXTR_W(ctx->opcode);
17751        switch (op2) {
17752        case OPC_DEXTP:
17753        case OPC_DEXTPDP:
17754        case OPC_DEXTPDPV:
17755        case OPC_DEXTPV:
17756        case OPC_DEXTR_L:
17757        case OPC_DEXTR_R_L:
17758        case OPC_DEXTR_RS_L:
17759        case OPC_DEXTR_W:
17760        case OPC_DEXTR_R_W:
17761        case OPC_DEXTR_RS_W:
17762        case OPC_DEXTR_S_H:
17763        case OPC_DEXTRV_L:
17764        case OPC_DEXTRV_R_L:
17765        case OPC_DEXTRV_RS_L:
17766        case OPC_DEXTRV_S_H:
17767        case OPC_DEXTRV_W:
17768        case OPC_DEXTRV_R_W:
17769        case OPC_DEXTRV_RS_W:
17770            gen_mipsdsp_accinsn(ctx, op1, op2, rt, rs, rd, 1);
17771            break;
17772        case OPC_DMTHLIP:
17773        case OPC_DSHILO:
17774        case OPC_DSHILOV:
17775            gen_mipsdsp_accinsn(ctx, op1, op2, rd, rs, rt, 0);
17776            break;
17777        default:            /* Invalid */
17778            MIPS_INVAL("MASK EXTR.W");
17779            generate_exception_end(ctx, EXCP_RI);
17780            break;
17781        }
17782        break;
17783    case OPC_DPAQ_W_QH_DSP:
17784        op2 = MASK_DPAQ_W_QH(ctx->opcode);
17785        switch (op2) {
17786        case OPC_DPAU_H_OBL:
17787        case OPC_DPAU_H_OBR:
17788        case OPC_DPSU_H_OBL:
17789        case OPC_DPSU_H_OBR:
17790        case OPC_DPA_W_QH:
17791        case OPC_DPAQ_S_W_QH:
17792        case OPC_DPS_W_QH:
17793        case OPC_DPSQ_S_W_QH:
17794        case OPC_MULSAQ_S_W_QH:
17795        case OPC_DPAQ_SA_L_PW:
17796        case OPC_DPSQ_SA_L_PW:
17797        case OPC_MULSAQ_S_L_PW:
17798            gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 0);
17799            break;
17800        case OPC_MAQ_S_W_QHLL:
17801        case OPC_MAQ_S_W_QHLR:
17802        case OPC_MAQ_S_W_QHRL:
17803        case OPC_MAQ_S_W_QHRR:
17804        case OPC_MAQ_SA_W_QHLL:
17805        case OPC_MAQ_SA_W_QHLR:
17806        case OPC_MAQ_SA_W_QHRL:
17807        case OPC_MAQ_SA_W_QHRR:
17808        case OPC_MAQ_S_L_PWL:
17809        case OPC_MAQ_S_L_PWR:
17810        case OPC_DMADD:
17811        case OPC_DMADDU:
17812        case OPC_DMSUB:
17813        case OPC_DMSUBU:
17814            gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 0);
17815            break;
17816        default:            /* Invalid */
17817            MIPS_INVAL("MASK DPAQ.W.QH");
17818            generate_exception_end(ctx, EXCP_RI);
17819            break;
17820        }
17821        break;
17822    case OPC_DINSV_DSP:
17823        op2 = MASK_INSV(ctx->opcode);
17824        switch (op2) {
17825        case OPC_DINSV:
17826        {
17827            TCGv t0, t1;
17828
17829            if (rt == 0) {
17830                break;
17831            }
17832            check_dsp(ctx);
17833
17834            t0 = tcg_temp_new();
17835            t1 = tcg_temp_new();
17836
17837            gen_load_gpr(t0, rt);
17838            gen_load_gpr(t1, rs);
17839
17840            gen_helper_dinsv(cpu_gpr[rt], cpu_env, t1, t0);
17841
17842            tcg_temp_free(t0);
17843            tcg_temp_free(t1);
17844            break;
17845        }
17846        default:            /* Invalid */
17847            MIPS_INVAL("MASK DINSV");
17848            generate_exception_end(ctx, EXCP_RI);
17849            break;
17850        }
17851        break;
17852    case OPC_SHLL_OB_DSP:
17853        gen_mipsdsp_shift(ctx, op1, rd, rs, rt);
17854        break;
17855#endif
17856    default:            /* Invalid */
17857        MIPS_INVAL("special3_legacy");
17858        generate_exception_end(ctx, EXCP_RI);
17859        break;
17860    }
17861}
17862
17863static void decode_opc_special3(CPUMIPSState *env, DisasContext *ctx)
17864{
17865    int rs, rt, rd, sa;
17866    uint32_t op1, op2;
17867
17868    rs = (ctx->opcode >> 21) & 0x1f;
17869    rt = (ctx->opcode >> 16) & 0x1f;
17870    rd = (ctx->opcode >> 11) & 0x1f;
17871    sa = (ctx->opcode >> 6) & 0x1f;
17872
17873    op1 = MASK_SPECIAL3(ctx->opcode);
17874    switch (op1) {
17875    case OPC_EXT:
17876    case OPC_INS:
17877        check_insn(ctx, ISA_MIPS32R2);
17878        gen_bitops(ctx, op1, rt, rs, sa, rd);
17879        break;
17880    case OPC_BSHFL:
17881        op2 = MASK_BSHFL(ctx->opcode);
17882        switch (op2) {
17883        case OPC_ALIGN ... OPC_ALIGN_END:
17884        case OPC_BITSWAP:
17885            check_insn(ctx, ISA_MIPS32R6);
17886            decode_opc_special3_r6(env, ctx);
17887            break;
17888        default:
17889            check_insn(ctx, ISA_MIPS32R2);
17890            gen_bshfl(ctx, op2, rt, rd);
17891            break;
17892        }
17893        break;
17894#if defined(TARGET_MIPS64)
17895    case OPC_DEXTM ... OPC_DEXT:
17896    case OPC_DINSM ... OPC_DINS:
17897        check_insn(ctx, ISA_MIPS64R2);
17898        check_mips_64(ctx);
17899        gen_bitops(ctx, op1, rt, rs, sa, rd);
17900        break;
17901    case OPC_DBSHFL:
17902        op2 = MASK_DBSHFL(ctx->opcode);
17903        switch (op2) {
17904        case OPC_DALIGN ... OPC_DALIGN_END:
17905        case OPC_DBITSWAP:
17906            check_insn(ctx, ISA_MIPS32R6);
17907            decode_opc_special3_r6(env, ctx);
17908            break;
17909        default:
17910            check_insn(ctx, ISA_MIPS64R2);
17911            check_mips_64(ctx);
17912            op2 = MASK_DBSHFL(ctx->opcode);
17913            gen_bshfl(ctx, op2, rt, rd);
17914            break;
17915        }
17916        break;
17917#endif
17918    case OPC_RDHWR:
17919        gen_rdhwr(ctx, rt, rd, extract32(ctx->opcode, 6, 3));
17920        break;
17921    case OPC_FORK:
17922        check_insn(ctx, ASE_MT);
17923        {
17924            TCGv t0 = tcg_temp_new();
17925            TCGv t1 = tcg_temp_new();
17926
17927            gen_load_gpr(t0, rt);
17928            gen_load_gpr(t1, rs);
17929            gen_helper_fork(t0, t1);
17930            tcg_temp_free(t0);
17931            tcg_temp_free(t1);
17932        }
17933        break;
17934    case OPC_YIELD:
17935        check_insn(ctx, ASE_MT);
17936        {
17937            TCGv t0 = tcg_temp_new();
17938
17939            gen_load_gpr(t0, rs);
17940            gen_helper_yield(t0, cpu_env, t0);
17941            gen_store_gpr(t0, rd);
17942            tcg_temp_free(t0);
17943        }
17944        break;
17945    default:
17946        if (ctx->insn_flags & ISA_MIPS32R6) {
17947            decode_opc_special3_r6(env, ctx);
17948        } else {
17949            decode_opc_special3_legacy(env, ctx);
17950        }
17951    }
17952}
17953
17954/* MIPS SIMD Architecture (MSA)  */
17955static inline int check_msa_access(DisasContext *ctx)
17956{
17957    if (unlikely((ctx->hflags & MIPS_HFLAG_FPU) &&
17958                 !(ctx->hflags & MIPS_HFLAG_F64))) {
17959        generate_exception_end(ctx, EXCP_RI);
17960        return 0;
17961    }
17962
17963    if (unlikely(!(ctx->hflags & MIPS_HFLAG_MSA))) {
17964        if (ctx->insn_flags & ASE_MSA) {
17965            generate_exception_end(ctx, EXCP_MSADIS);
17966            return 0;
17967        } else {
17968            generate_exception_end(ctx, EXCP_RI);
17969            return 0;
17970        }
17971    }
17972    return 1;
17973}
17974
17975static void gen_check_zero_element(TCGv tresult, uint8_t df, uint8_t wt)
17976{
17977    /* generates tcg ops to check if any element is 0 */
17978    /* Note this function only works with MSA_WRLEN = 128 */
17979    uint64_t eval_zero_or_big = 0;
17980    uint64_t eval_big = 0;
17981    TCGv_i64 t0 = tcg_temp_new_i64();
17982    TCGv_i64 t1 = tcg_temp_new_i64();
17983    switch (df) {
17984    case DF_BYTE:
17985        eval_zero_or_big = 0x0101010101010101ULL;
17986        eval_big = 0x8080808080808080ULL;
17987        break;
17988    case DF_HALF:
17989        eval_zero_or_big = 0x0001000100010001ULL;
17990        eval_big = 0x8000800080008000ULL;
17991        break;
17992    case DF_WORD:
17993        eval_zero_or_big = 0x0000000100000001ULL;
17994        eval_big = 0x8000000080000000ULL;
17995        break;
17996    case DF_DOUBLE:
17997        eval_zero_or_big = 0x0000000000000001ULL;
17998        eval_big = 0x8000000000000000ULL;
17999        break;
18000    }
18001    tcg_gen_subi_i64(t0, msa_wr_d[wt<<1], eval_zero_or_big);
18002    tcg_gen_andc_i64(t0, t0, msa_wr_d[wt<<1]);
18003    tcg_gen_andi_i64(t0, t0, eval_big);
18004    tcg_gen_subi_i64(t1, msa_wr_d[(wt<<1)+1], eval_zero_or_big);
18005    tcg_gen_andc_i64(t1, t1, msa_wr_d[(wt<<1)+1]);
18006    tcg_gen_andi_i64(t1, t1, eval_big);
18007    tcg_gen_or_i64(t0, t0, t1);
18008    /* if all bits are zero then all elements are not zero */
18009    /* if some bit is non-zero then some element is zero */
18010    tcg_gen_setcondi_i64(TCG_COND_NE, t0, t0, 0);
18011    tcg_gen_trunc_i64_tl(tresult, t0);
18012    tcg_temp_free_i64(t0);
18013    tcg_temp_free_i64(t1);
18014}
18015
18016static void gen_msa_branch(CPUMIPSState *env, DisasContext *ctx, uint32_t op1)
18017{
18018    uint8_t df = (ctx->opcode >> 21) & 0x3;
18019    uint8_t wt = (ctx->opcode >> 16) & 0x1f;
18020    int64_t s16 = (int16_t)ctx->opcode;
18021
18022    check_msa_access(ctx);
18023
18024    if (ctx->insn_flags & ISA_MIPS32R6 && ctx->hflags & MIPS_HFLAG_BMASK) {
18025        generate_exception_end(ctx, EXCP_RI);
18026        return;
18027    }
18028    switch (op1) {
18029    case OPC_BZ_V:
18030    case OPC_BNZ_V:
18031        {
18032            TCGv_i64 t0 = tcg_temp_new_i64();
18033            tcg_gen_or_i64(t0, msa_wr_d[wt<<1], msa_wr_d[(wt<<1)+1]);
18034            tcg_gen_setcondi_i64((op1 == OPC_BZ_V) ?
18035                    TCG_COND_EQ : TCG_COND_NE, t0, t0, 0);
18036            tcg_gen_trunc_i64_tl(bcond, t0);
18037            tcg_temp_free_i64(t0);
18038        }
18039        break;
18040    case OPC_BZ_B:
18041    case OPC_BZ_H:
18042    case OPC_BZ_W:
18043    case OPC_BZ_D:
18044        gen_check_zero_element(bcond, df, wt);
18045        break;
18046    case OPC_BNZ_B:
18047    case OPC_BNZ_H:
18048    case OPC_BNZ_W:
18049    case OPC_BNZ_D:
18050        gen_check_zero_element(bcond, df, wt);
18051        tcg_gen_setcondi_tl(TCG_COND_EQ, bcond, bcond, 0);
18052        break;
18053    }
18054
18055    ctx->btarget = ctx->pc + (s16 << 2) + 4;
18056
18057    ctx->hflags |= MIPS_HFLAG_BC;
18058    ctx->hflags |= MIPS_HFLAG_BDS32;
18059}
18060
18061static void gen_msa_i8(CPUMIPSState *env, DisasContext *ctx)
18062{
18063#define MASK_MSA_I8(op)    (MASK_MSA_MINOR(op) | (op & (0x03 << 24)))
18064    uint8_t i8 = (ctx->opcode >> 16) & 0xff;
18065    uint8_t ws = (ctx->opcode >> 11) & 0x1f;
18066    uint8_t wd = (ctx->opcode >> 6) & 0x1f;
18067
18068    TCGv_i32 twd = tcg_const_i32(wd);
18069    TCGv_i32 tws = tcg_const_i32(ws);
18070    TCGv_i32 ti8 = tcg_const_i32(i8);
18071
18072    switch (MASK_MSA_I8(ctx->opcode)) {
18073    case OPC_ANDI_B:
18074        gen_helper_msa_andi_b(cpu_env, twd, tws, ti8);
18075        break;
18076    case OPC_ORI_B:
18077        gen_helper_msa_ori_b(cpu_env, twd, tws, ti8);
18078        break;
18079    case OPC_NORI_B:
18080        gen_helper_msa_nori_b(cpu_env, twd, tws, ti8);
18081        break;
18082    case OPC_XORI_B:
18083        gen_helper_msa_xori_b(cpu_env, twd, tws, ti8);
18084        break;
18085    case OPC_BMNZI_B:
18086        gen_helper_msa_bmnzi_b(cpu_env, twd, tws, ti8);
18087        break;
18088    case OPC_BMZI_B:
18089        gen_helper_msa_bmzi_b(cpu_env, twd, tws, ti8);
18090        break;
18091    case OPC_BSELI_B:
18092        gen_helper_msa_bseli_b(cpu_env, twd, tws, ti8);
18093        break;
18094    case OPC_SHF_B:
18095    case OPC_SHF_H:
18096    case OPC_SHF_W:
18097        {
18098            uint8_t df = (ctx->opcode >> 24) & 0x3;
18099            if (df == DF_DOUBLE) {
18100                generate_exception_end(ctx, EXCP_RI);
18101            } else {
18102                TCGv_i32 tdf = tcg_const_i32(df);
18103                gen_helper_msa_shf_df(cpu_env, tdf, twd, tws, ti8);
18104                tcg_temp_free_i32(tdf);
18105            }
18106        }
18107        break;
18108    default:
18109        MIPS_INVAL("MSA instruction");
18110        generate_exception_end(ctx, EXCP_RI);
18111        break;
18112    }
18113
18114    tcg_temp_free_i32(twd);
18115    tcg_temp_free_i32(tws);
18116    tcg_temp_free_i32(ti8);
18117}
18118
18119static void gen_msa_i5(CPUMIPSState *env, DisasContext *ctx)
18120{
18121#define MASK_MSA_I5(op)    (MASK_MSA_MINOR(op) | (op & (0x7 << 23)))
18122    uint8_t df = (ctx->opcode >> 21) & 0x3;
18123    int8_t s5 = (int8_t) sextract32(ctx->opcode, 16, 5);
18124    uint8_t u5 = (ctx->opcode >> 16) & 0x1f;
18125    uint8_t ws = (ctx->opcode >> 11) & 0x1f;
18126    uint8_t wd = (ctx->opcode >> 6) & 0x1f;
18127
18128    TCGv_i32 tdf = tcg_const_i32(df);
18129    TCGv_i32 twd = tcg_const_i32(wd);
18130    TCGv_i32 tws = tcg_const_i32(ws);
18131    TCGv_i32 timm = tcg_temp_new_i32();
18132    tcg_gen_movi_i32(timm, u5);
18133
18134    switch (MASK_MSA_I5(ctx->opcode)) {
18135    case OPC_ADDVI_df:
18136        gen_helper_msa_addvi_df(cpu_env, tdf, twd, tws, timm);
18137        break;
18138    case OPC_SUBVI_df:
18139        gen_helper_msa_subvi_df(cpu_env, tdf, twd, tws, timm);
18140        break;
18141    case OPC_MAXI_S_df:
18142        tcg_gen_movi_i32(timm, s5);
18143        gen_helper_msa_maxi_s_df(cpu_env, tdf, twd, tws, timm);
18144        break;
18145    case OPC_MAXI_U_df:
18146        gen_helper_msa_maxi_u_df(cpu_env, tdf, twd, tws, timm);
18147        break;
18148    case OPC_MINI_S_df:
18149        tcg_gen_movi_i32(timm, s5);
18150        gen_helper_msa_mini_s_df(cpu_env, tdf, twd, tws, timm);
18151        break;
18152    case OPC_MINI_U_df:
18153        gen_helper_msa_mini_u_df(cpu_env, tdf, twd, tws, timm);
18154        break;
18155    case OPC_CEQI_df:
18156        tcg_gen_movi_i32(timm, s5);
18157        gen_helper_msa_ceqi_df(cpu_env, tdf, twd, tws, timm);
18158        break;
18159    case OPC_CLTI_S_df:
18160        tcg_gen_movi_i32(timm, s5);
18161        gen_helper_msa_clti_s_df(cpu_env, tdf, twd, tws, timm);
18162        break;
18163    case OPC_CLTI_U_df:
18164        gen_helper_msa_clti_u_df(cpu_env, tdf, twd, tws, timm);
18165        break;
18166    case OPC_CLEI_S_df:
18167        tcg_gen_movi_i32(timm, s5);
18168        gen_helper_msa_clei_s_df(cpu_env, tdf, twd, tws, timm);
18169        break;
18170    case OPC_CLEI_U_df:
18171        gen_helper_msa_clei_u_df(cpu_env, tdf, twd, tws, timm);
18172        break;
18173    case OPC_LDI_df:
18174        {
18175            int32_t s10 = sextract32(ctx->opcode, 11, 10);
18176            tcg_gen_movi_i32(timm, s10);
18177            gen_helper_msa_ldi_df(cpu_env, tdf, twd, timm);
18178        }
18179        break;
18180    default:
18181        MIPS_INVAL("MSA instruction");
18182        generate_exception_end(ctx, EXCP_RI);
18183        break;
18184    }
18185
18186    tcg_temp_free_i32(tdf);
18187    tcg_temp_free_i32(twd);
18188    tcg_temp_free_i32(tws);
18189    tcg_temp_free_i32(timm);
18190}
18191
18192static void gen_msa_bit(CPUMIPSState *env, DisasContext *ctx)
18193{
18194#define MASK_MSA_BIT(op)    (MASK_MSA_MINOR(op) | (op & (0x7 << 23)))
18195    uint8_t dfm = (ctx->opcode >> 16) & 0x7f;
18196    uint32_t df = 0, m = 0;
18197    uint8_t ws = (ctx->opcode >> 11) & 0x1f;
18198    uint8_t wd = (ctx->opcode >> 6) & 0x1f;
18199
18200    TCGv_i32 tdf;
18201    TCGv_i32 tm;
18202    TCGv_i32 twd;
18203    TCGv_i32 tws;
18204
18205    if ((dfm & 0x40) == 0x00) {
18206        m = dfm & 0x3f;
18207        df = DF_DOUBLE;
18208    } else if ((dfm & 0x60) == 0x40) {
18209        m = dfm & 0x1f;
18210        df = DF_WORD;
18211    } else if ((dfm & 0x70) == 0x60) {
18212        m = dfm & 0x0f;
18213        df = DF_HALF;
18214    } else if ((dfm & 0x78) == 0x70) {
18215        m = dfm & 0x7;
18216        df = DF_BYTE;
18217    } else {
18218        generate_exception_end(ctx, EXCP_RI);
18219        return;
18220    }
18221
18222    tdf = tcg_const_i32(df);
18223    tm  = tcg_const_i32(m);
18224    twd = tcg_const_i32(wd);
18225    tws = tcg_const_i32(ws);
18226
18227    switch (MASK_MSA_BIT(ctx->opcode)) {
18228    case OPC_SLLI_df:
18229        gen_helper_msa_slli_df(cpu_env, tdf, twd, tws, tm);
18230        break;
18231    case OPC_SRAI_df:
18232        gen_helper_msa_srai_df(cpu_env, tdf, twd, tws, tm);
18233        break;
18234    case OPC_SRLI_df:
18235        gen_helper_msa_srli_df(cpu_env, tdf, twd, tws, tm);
18236        break;
18237    case OPC_BCLRI_df:
18238        gen_helper_msa_bclri_df(cpu_env, tdf, twd, tws, tm);
18239        break;
18240    case OPC_BSETI_df:
18241        gen_helper_msa_bseti_df(cpu_env, tdf, twd, tws, tm);
18242        break;
18243    case OPC_BNEGI_df:
18244        gen_helper_msa_bnegi_df(cpu_env, tdf, twd, tws, tm);
18245        break;
18246    case OPC_BINSLI_df:
18247        gen_helper_msa_binsli_df(cpu_env, tdf, twd, tws, tm);
18248        break;
18249    case OPC_BINSRI_df:
18250        gen_helper_msa_binsri_df(cpu_env, tdf, twd, tws, tm);
18251        break;
18252    case OPC_SAT_S_df:
18253        gen_helper_msa_sat_s_df(cpu_env, tdf, twd, tws, tm);
18254        break;
18255    case OPC_SAT_U_df:
18256        gen_helper_msa_sat_u_df(cpu_env, tdf, twd, tws, tm);
18257        break;
18258    case OPC_SRARI_df:
18259        gen_helper_msa_srari_df(cpu_env, tdf, twd, tws, tm);
18260        break;
18261    case OPC_SRLRI_df:
18262        gen_helper_msa_srlri_df(cpu_env, tdf, twd, tws, tm);
18263        break;
18264    default:
18265        MIPS_INVAL("MSA instruction");
18266        generate_exception_end(ctx, EXCP_RI);
18267        break;
18268    }
18269
18270    tcg_temp_free_i32(tdf);
18271    tcg_temp_free_i32(tm);
18272    tcg_temp_free_i32(twd);
18273    tcg_temp_free_i32(tws);
18274}
18275
18276static void gen_msa_3r(CPUMIPSState *env, DisasContext *ctx)
18277{
18278#define MASK_MSA_3R(op)    (MASK_MSA_MINOR(op) | (op & (0x7 << 23)))
18279    uint8_t df = (ctx->opcode >> 21) & 0x3;
18280    uint8_t wt = (ctx->opcode >> 16) & 0x1f;
18281    uint8_t ws = (ctx->opcode >> 11) & 0x1f;
18282    uint8_t wd = (ctx->opcode >> 6) & 0x1f;
18283
18284    TCGv_i32 tdf = tcg_const_i32(df);
18285    TCGv_i32 twd = tcg_const_i32(wd);
18286    TCGv_i32 tws = tcg_const_i32(ws);
18287    TCGv_i32 twt = tcg_const_i32(wt);
18288
18289    switch (MASK_MSA_3R(ctx->opcode)) {
18290    case OPC_SLL_df:
18291        gen_helper_msa_sll_df(cpu_env, tdf, twd, tws, twt);
18292        break;
18293    case OPC_ADDV_df:
18294        gen_helper_msa_addv_df(cpu_env, tdf, twd, tws, twt);
18295        break;
18296    case OPC_CEQ_df:
18297        gen_helper_msa_ceq_df(cpu_env, tdf, twd, tws, twt);
18298        break;
18299    case OPC_ADD_A_df:
18300        gen_helper_msa_add_a_df(cpu_env, tdf, twd, tws, twt);
18301        break;
18302    case OPC_SUBS_S_df:
18303        gen_helper_msa_subs_s_df(cpu_env, tdf, twd, tws, twt);
18304        break;
18305    case OPC_MULV_df:
18306        gen_helper_msa_mulv_df(cpu_env, tdf, twd, tws, twt);
18307        break;
18308    case OPC_SLD_df:
18309        gen_helper_msa_sld_df(cpu_env, tdf, twd, tws, twt);
18310        break;
18311    case OPC_VSHF_df:
18312        gen_helper_msa_vshf_df(cpu_env, tdf, twd, tws, twt);
18313        break;
18314    case OPC_SRA_df:
18315        gen_helper_msa_sra_df(cpu_env, tdf, twd, tws, twt);
18316        break;
18317    case OPC_SUBV_df:
18318        gen_helper_msa_subv_df(cpu_env, tdf, twd, tws, twt);
18319        break;
18320    case OPC_ADDS_A_df:
18321        gen_helper_msa_adds_a_df(cpu_env, tdf, twd, tws, twt);
18322        break;
18323    case OPC_SUBS_U_df:
18324        gen_helper_msa_subs_u_df(cpu_env, tdf, twd, tws, twt);
18325        break;
18326    case OPC_MADDV_df:
18327        gen_helper_msa_maddv_df(cpu_env, tdf, twd, tws, twt);
18328        break;
18329    case OPC_SPLAT_df:
18330        gen_helper_msa_splat_df(cpu_env, tdf, twd, tws, twt);
18331        break;
18332    case OPC_SRAR_df:
18333        gen_helper_msa_srar_df(cpu_env, tdf, twd, tws, twt);
18334        break;
18335    case OPC_SRL_df:
18336        gen_helper_msa_srl_df(cpu_env, tdf, twd, tws, twt);
18337        break;
18338    case OPC_MAX_S_df:
18339        gen_helper_msa_max_s_df(cpu_env, tdf, twd, tws, twt);
18340        break;
18341    case OPC_CLT_S_df:
18342        gen_helper_msa_clt_s_df(cpu_env, tdf, twd, tws, twt);
18343        break;
18344    case OPC_ADDS_S_df:
18345        gen_helper_msa_adds_s_df(cpu_env, tdf, twd, tws, twt);
18346        break;
18347    case OPC_SUBSUS_U_df:
18348        gen_helper_msa_subsus_u_df(cpu_env, tdf, twd, tws, twt);
18349        break;
18350    case OPC_MSUBV_df:
18351        gen_helper_msa_msubv_df(cpu_env, tdf, twd, tws, twt);
18352        break;
18353    case OPC_PCKEV_df:
18354        gen_helper_msa_pckev_df(cpu_env, tdf, twd, tws, twt);
18355        break;
18356    case OPC_SRLR_df:
18357        gen_helper_msa_srlr_df(cpu_env, tdf, twd, tws, twt);
18358        break;
18359    case OPC_BCLR_df:
18360        gen_helper_msa_bclr_df(cpu_env, tdf, twd, tws, twt);
18361        break;
18362    case OPC_MAX_U_df:
18363        gen_helper_msa_max_u_df(cpu_env, tdf, twd, tws, twt);
18364        break;
18365    case OPC_CLT_U_df:
18366        gen_helper_msa_clt_u_df(cpu_env, tdf, twd, tws, twt);
18367        break;
18368    case OPC_ADDS_U_df:
18369        gen_helper_msa_adds_u_df(cpu_env, tdf, twd, tws, twt);
18370        break;
18371    case OPC_SUBSUU_S_df:
18372        gen_helper_msa_subsuu_s_df(cpu_env, tdf, twd, tws, twt);
18373        break;
18374    case OPC_PCKOD_df:
18375        gen_helper_msa_pckod_df(cpu_env, tdf, twd, tws, twt);
18376        break;
18377    case OPC_BSET_df:
18378        gen_helper_msa_bset_df(cpu_env, tdf, twd, tws, twt);
18379        break;
18380    case OPC_MIN_S_df:
18381        gen_helper_msa_min_s_df(cpu_env, tdf, twd, tws, twt);
18382        break;
18383    case OPC_CLE_S_df:
18384        gen_helper_msa_cle_s_df(cpu_env, tdf, twd, tws, twt);
18385        break;
18386    case OPC_AVE_S_df:
18387        gen_helper_msa_ave_s_df(cpu_env, tdf, twd, tws, twt);
18388        break;
18389    case OPC_ASUB_S_df:
18390        gen_helper_msa_asub_s_df(cpu_env, tdf, twd, tws, twt);
18391        break;
18392    case OPC_DIV_S_df:
18393        gen_helper_msa_div_s_df(cpu_env, tdf, twd, tws, twt);
18394        break;
18395    case OPC_ILVL_df:
18396        gen_helper_msa_ilvl_df(cpu_env, tdf, twd, tws, twt);
18397        break;
18398    case OPC_BNEG_df:
18399        gen_helper_msa_bneg_df(cpu_env, tdf, twd, tws, twt);
18400        break;
18401    case OPC_MIN_U_df:
18402        gen_helper_msa_min_u_df(cpu_env, tdf, twd, tws, twt);
18403        break;
18404    case OPC_CLE_U_df:
18405        gen_helper_msa_cle_u_df(cpu_env, tdf, twd, tws, twt);
18406        break;
18407    case OPC_AVE_U_df:
18408        gen_helper_msa_ave_u_df(cpu_env, tdf, twd, tws, twt);
18409        break;
18410    case OPC_ASUB_U_df:
18411        gen_helper_msa_asub_u_df(cpu_env, tdf, twd, tws, twt);
18412        break;
18413    case OPC_DIV_U_df:
18414        gen_helper_msa_div_u_df(cpu_env, tdf, twd, tws, twt);
18415        break;
18416    case OPC_ILVR_df:
18417        gen_helper_msa_ilvr_df(cpu_env, tdf, twd, tws, twt);
18418        break;
18419    case OPC_BINSL_df:
18420        gen_helper_msa_binsl_df(cpu_env, tdf, twd, tws, twt);
18421        break;
18422    case OPC_MAX_A_df:
18423        gen_helper_msa_max_a_df(cpu_env, tdf, twd, tws, twt);
18424        break;
18425    case OPC_AVER_S_df:
18426        gen_helper_msa_aver_s_df(cpu_env, tdf, twd, tws, twt);
18427        break;
18428    case OPC_MOD_S_df:
18429        gen_helper_msa_mod_s_df(cpu_env, tdf, twd, tws, twt);
18430        break;
18431    case OPC_ILVEV_df:
18432        gen_helper_msa_ilvev_df(cpu_env, tdf, twd, tws, twt);
18433        break;
18434    case OPC_BINSR_df:
18435        gen_helper_msa_binsr_df(cpu_env, tdf, twd, tws, twt);
18436        break;
18437    case OPC_MIN_A_df:
18438        gen_helper_msa_min_a_df(cpu_env, tdf, twd, tws, twt);
18439        break;
18440    case OPC_AVER_U_df:
18441        gen_helper_msa_aver_u_df(cpu_env, tdf, twd, tws, twt);
18442        break;
18443    case OPC_MOD_U_df:
18444        gen_helper_msa_mod_u_df(cpu_env, tdf, twd, tws, twt);
18445        break;
18446    case OPC_ILVOD_df:
18447        gen_helper_msa_ilvod_df(cpu_env, tdf, twd, tws, twt);
18448        break;
18449
18450    case OPC_DOTP_S_df:
18451    case OPC_DOTP_U_df:
18452    case OPC_DPADD_S_df:
18453    case OPC_DPADD_U_df:
18454    case OPC_DPSUB_S_df:
18455    case OPC_HADD_S_df:
18456    case OPC_DPSUB_U_df:
18457    case OPC_HADD_U_df:
18458    case OPC_HSUB_S_df:
18459    case OPC_HSUB_U_df:
18460        if (df == DF_BYTE) {
18461            generate_exception_end(ctx, EXCP_RI);
18462            break;
18463        }
18464        switch (MASK_MSA_3R(ctx->opcode)) {
18465        case OPC_DOTP_S_df:
18466            gen_helper_msa_dotp_s_df(cpu_env, tdf, twd, tws, twt);
18467            break;
18468        case OPC_DOTP_U_df:
18469            gen_helper_msa_dotp_u_df(cpu_env, tdf, twd, tws, twt);
18470            break;
18471        case OPC_DPADD_S_df:
18472            gen_helper_msa_dpadd_s_df(cpu_env, tdf, twd, tws, twt);
18473            break;
18474        case OPC_DPADD_U_df:
18475            gen_helper_msa_dpadd_u_df(cpu_env, tdf, twd, tws, twt);
18476            break;
18477        case OPC_DPSUB_S_df:
18478            gen_helper_msa_dpsub_s_df(cpu_env, tdf, twd, tws, twt);
18479            break;
18480        case OPC_HADD_S_df:
18481            gen_helper_msa_hadd_s_df(cpu_env, tdf, twd, tws, twt);
18482            break;
18483        case OPC_DPSUB_U_df:
18484            gen_helper_msa_dpsub_u_df(cpu_env, tdf, twd, tws, twt);
18485            break;
18486        case OPC_HADD_U_df:
18487            gen_helper_msa_hadd_u_df(cpu_env, tdf, twd, tws, twt);
18488            break;
18489        case OPC_HSUB_S_df:
18490            gen_helper_msa_hsub_s_df(cpu_env, tdf, twd, tws, twt);
18491            break;
18492        case OPC_HSUB_U_df:
18493            gen_helper_msa_hsub_u_df(cpu_env, tdf, twd, tws, twt);
18494            break;
18495        }
18496        break;
18497    default:
18498        MIPS_INVAL("MSA instruction");
18499        generate_exception_end(ctx, EXCP_RI);
18500        break;
18501    }
18502    tcg_temp_free_i32(twd);
18503    tcg_temp_free_i32(tws);
18504    tcg_temp_free_i32(twt);
18505    tcg_temp_free_i32(tdf);
18506}
18507
18508static void gen_msa_elm_3e(CPUMIPSState *env, DisasContext *ctx)
18509{
18510#define MASK_MSA_ELM_DF3E(op)   (MASK_MSA_MINOR(op) | (op & (0x3FF << 16)))
18511    uint8_t source = (ctx->opcode >> 11) & 0x1f;
18512    uint8_t dest = (ctx->opcode >> 6) & 0x1f;
18513    TCGv telm = tcg_temp_new();
18514    TCGv_i32 tsr = tcg_const_i32(source);
18515    TCGv_i32 tdt = tcg_const_i32(dest);
18516
18517    switch (MASK_MSA_ELM_DF3E(ctx->opcode)) {
18518    case OPC_CTCMSA:
18519        gen_load_gpr(telm, source);
18520        gen_helper_msa_ctcmsa(cpu_env, telm, tdt);
18521        break;
18522    case OPC_CFCMSA:
18523        gen_helper_msa_cfcmsa(telm, cpu_env, tsr);
18524        gen_store_gpr(telm, dest);
18525        break;
18526    case OPC_MOVE_V:
18527        gen_helper_msa_move_v(cpu_env, tdt, tsr);
18528        break;
18529    default:
18530        MIPS_INVAL("MSA instruction");
18531        generate_exception_end(ctx, EXCP_RI);
18532        break;
18533    }
18534
18535    tcg_temp_free(telm);
18536    tcg_temp_free_i32(tdt);
18537    tcg_temp_free_i32(tsr);
18538}
18539
18540static void gen_msa_elm_df(CPUMIPSState *env, DisasContext *ctx, uint32_t df,
18541        uint32_t n)
18542{
18543#define MASK_MSA_ELM(op)    (MASK_MSA_MINOR(op) | (op & (0xf << 22)))
18544    uint8_t ws = (ctx->opcode >> 11) & 0x1f;
18545    uint8_t wd = (ctx->opcode >> 6) & 0x1f;
18546
18547    TCGv_i32 tws = tcg_const_i32(ws);
18548    TCGv_i32 twd = tcg_const_i32(wd);
18549    TCGv_i32 tn  = tcg_const_i32(n);
18550    TCGv_i32 tdf = tcg_const_i32(df);
18551
18552    switch (MASK_MSA_ELM(ctx->opcode)) {
18553    case OPC_SLDI_df:
18554        gen_helper_msa_sldi_df(cpu_env, tdf, twd, tws, tn);
18555        break;
18556    case OPC_SPLATI_df:
18557        gen_helper_msa_splati_df(cpu_env, tdf, twd, tws, tn);
18558        break;
18559    case OPC_INSVE_df:
18560        gen_helper_msa_insve_df(cpu_env, tdf, twd, tws, tn);
18561        break;
18562    case OPC_COPY_S_df:
18563    case OPC_COPY_U_df:
18564    case OPC_INSERT_df:
18565#if !defined(TARGET_MIPS64)
18566        /* Double format valid only for MIPS64 */
18567        if (df == DF_DOUBLE) {
18568            generate_exception_end(ctx, EXCP_RI);
18569            break;
18570        }
18571#endif
18572        switch (MASK_MSA_ELM(ctx->opcode)) {
18573        case OPC_COPY_S_df:
18574            gen_helper_msa_copy_s_df(cpu_env, tdf, twd, tws, tn);
18575            break;
18576        case OPC_COPY_U_df:
18577            gen_helper_msa_copy_u_df(cpu_env, tdf, twd, tws, tn);
18578            break;
18579        case OPC_INSERT_df:
18580            gen_helper_msa_insert_df(cpu_env, tdf, twd, tws, tn);
18581            break;
18582        }
18583        break;
18584    default:
18585        MIPS_INVAL("MSA instruction");
18586        generate_exception_end(ctx, EXCP_RI);
18587    }
18588    tcg_temp_free_i32(twd);
18589    tcg_temp_free_i32(tws);
18590    tcg_temp_free_i32(tn);
18591    tcg_temp_free_i32(tdf);
18592}
18593
18594static void gen_msa_elm(CPUMIPSState *env, DisasContext *ctx)
18595{
18596    uint8_t dfn = (ctx->opcode >> 16) & 0x3f;
18597    uint32_t df = 0, n = 0;
18598
18599    if ((dfn & 0x30) == 0x00) {
18600        n = dfn & 0x0f;
18601        df = DF_BYTE;
18602    } else if ((dfn & 0x38) == 0x20) {
18603        n = dfn & 0x07;
18604        df = DF_HALF;
18605    } else if ((dfn & 0x3c) == 0x30) {
18606        n = dfn & 0x03;
18607        df = DF_WORD;
18608    } else if ((dfn & 0x3e) == 0x38) {
18609        n = dfn & 0x01;
18610        df = DF_DOUBLE;
18611    } else if (dfn == 0x3E) {
18612        /* CTCMSA, CFCMSA, MOVE.V */
18613        gen_msa_elm_3e(env, ctx);
18614        return;
18615    } else {
18616        generate_exception_end(ctx, EXCP_RI);
18617        return;
18618    }
18619
18620    gen_msa_elm_df(env, ctx, df, n);
18621}
18622
18623static void gen_msa_3rf(CPUMIPSState *env, DisasContext *ctx)
18624{
18625#define MASK_MSA_3RF(op)    (MASK_MSA_MINOR(op) | (op & (0xf << 22)))
18626    uint8_t df = (ctx->opcode >> 21) & 0x1;
18627    uint8_t wt = (ctx->opcode >> 16) & 0x1f;
18628    uint8_t ws = (ctx->opcode >> 11) & 0x1f;
18629    uint8_t wd = (ctx->opcode >> 6) & 0x1f;
18630
18631    TCGv_i32 twd = tcg_const_i32(wd);
18632    TCGv_i32 tws = tcg_const_i32(ws);
18633    TCGv_i32 twt = tcg_const_i32(wt);
18634    TCGv_i32 tdf = tcg_temp_new_i32();
18635
18636    /* adjust df value for floating-point instruction */
18637    tcg_gen_movi_i32(tdf, df + 2);
18638
18639    switch (MASK_MSA_3RF(ctx->opcode)) {
18640    case OPC_FCAF_df:
18641        gen_helper_msa_fcaf_df(cpu_env, tdf, twd, tws, twt);
18642        break;
18643    case OPC_FADD_df:
18644        gen_helper_msa_fadd_df(cpu_env, tdf, twd, tws, twt);
18645        break;
18646    case OPC_FCUN_df:
18647        gen_helper_msa_fcun_df(cpu_env, tdf, twd, tws, twt);
18648        break;
18649    case OPC_FSUB_df:
18650        gen_helper_msa_fsub_df(cpu_env, tdf, twd, tws, twt);
18651        break;
18652    case OPC_FCOR_df:
18653        gen_helper_msa_fcor_df(cpu_env, tdf, twd, tws, twt);
18654        break;
18655    case OPC_FCEQ_df:
18656        gen_helper_msa_fceq_df(cpu_env, tdf, twd, tws, twt);
18657        break;
18658    case OPC_FMUL_df:
18659        gen_helper_msa_fmul_df(cpu_env, tdf, twd, tws, twt);
18660        break;
18661    case OPC_FCUNE_df:
18662        gen_helper_msa_fcune_df(cpu_env, tdf, twd, tws, twt);
18663        break;
18664    case OPC_FCUEQ_df:
18665        gen_helper_msa_fcueq_df(cpu_env, tdf, twd, tws, twt);
18666        break;
18667    case OPC_FDIV_df:
18668        gen_helper_msa_fdiv_df(cpu_env, tdf, twd, tws, twt);
18669        break;
18670    case OPC_FCNE_df:
18671        gen_helper_msa_fcne_df(cpu_env, tdf, twd, tws, twt);
18672        break;
18673    case OPC_FCLT_df:
18674        gen_helper_msa_fclt_df(cpu_env, tdf, twd, tws, twt);
18675        break;
18676    case OPC_FMADD_df:
18677        gen_helper_msa_fmadd_df(cpu_env, tdf, twd, tws, twt);
18678        break;
18679    case OPC_MUL_Q_df:
18680        tcg_gen_movi_i32(tdf, df + 1);
18681        gen_helper_msa_mul_q_df(cpu_env, tdf, twd, tws, twt);
18682        break;
18683    case OPC_FCULT_df:
18684        gen_helper_msa_fcult_df(cpu_env, tdf, twd, tws, twt);
18685        break;
18686    case OPC_FMSUB_df:
18687        gen_helper_msa_fmsub_df(cpu_env, tdf, twd, tws, twt);
18688        break;
18689    case OPC_MADD_Q_df:
18690        tcg_gen_movi_i32(tdf, df + 1);
18691        gen_helper_msa_madd_q_df(cpu_env, tdf, twd, tws, twt);
18692        break;
18693    case OPC_FCLE_df:
18694        gen_helper_msa_fcle_df(cpu_env, tdf, twd, tws, twt);
18695        break;
18696    case OPC_MSUB_Q_df:
18697        tcg_gen_movi_i32(tdf, df + 1);
18698        gen_helper_msa_msub_q_df(cpu_env, tdf, twd, tws, twt);
18699        break;
18700    case OPC_FCULE_df:
18701        gen_helper_msa_fcule_df(cpu_env, tdf, twd, tws, twt);
18702        break;
18703    case OPC_FEXP2_df:
18704        gen_helper_msa_fexp2_df(cpu_env, tdf, twd, tws, twt);
18705        break;
18706    case OPC_FSAF_df:
18707        gen_helper_msa_fsaf_df(cpu_env, tdf, twd, tws, twt);
18708        break;
18709    case OPC_FEXDO_df:
18710        gen_helper_msa_fexdo_df(cpu_env, tdf, twd, tws, twt);
18711        break;
18712    case OPC_FSUN_df:
18713        gen_helper_msa_fsun_df(cpu_env, tdf, twd, tws, twt);
18714        break;
18715    case OPC_FSOR_df:
18716        gen_helper_msa_fsor_df(cpu_env, tdf, twd, tws, twt);
18717        break;
18718    case OPC_FSEQ_df:
18719        gen_helper_msa_fseq_df(cpu_env, tdf, twd, tws, twt);
18720        break;
18721    case OPC_FTQ_df:
18722        gen_helper_msa_ftq_df(cpu_env, tdf, twd, tws, twt);
18723        break;
18724    case OPC_FSUNE_df:
18725        gen_helper_msa_fsune_df(cpu_env, tdf, twd, tws, twt);
18726        break;
18727    case OPC_FSUEQ_df:
18728        gen_helper_msa_fsueq_df(cpu_env, tdf, twd, tws, twt);
18729        break;
18730    case OPC_FSNE_df:
18731        gen_helper_msa_fsne_df(cpu_env, tdf, twd, tws, twt);
18732        break;
18733    case OPC_FSLT_df:
18734        gen_helper_msa_fslt_df(cpu_env, tdf, twd, tws, twt);
18735        break;
18736    case OPC_FMIN_df:
18737        gen_helper_msa_fmin_df(cpu_env, tdf, twd, tws, twt);
18738        break;
18739    case OPC_MULR_Q_df:
18740        tcg_gen_movi_i32(tdf, df + 1);
18741        gen_helper_msa_mulr_q_df(cpu_env, tdf, twd, tws, twt);
18742        break;
18743    case OPC_FSULT_df:
18744        gen_helper_msa_fsult_df(cpu_env, tdf, twd, tws, twt);
18745        break;
18746    case OPC_FMIN_A_df:
18747        gen_helper_msa_fmin_a_df(cpu_env, tdf, twd, tws, twt);
18748        break;
18749    case OPC_MADDR_Q_df:
18750        tcg_gen_movi_i32(tdf, df + 1);
18751        gen_helper_msa_maddr_q_df(cpu_env, tdf, twd, tws, twt);
18752        break;
18753    case OPC_FSLE_df:
18754        gen_helper_msa_fsle_df(cpu_env, tdf, twd, tws, twt);
18755        break;
18756    case OPC_FMAX_df:
18757        gen_helper_msa_fmax_df(cpu_env, tdf, twd, tws, twt);
18758        break;
18759    case OPC_MSUBR_Q_df:
18760        tcg_gen_movi_i32(tdf, df + 1);
18761        gen_helper_msa_msubr_q_df(cpu_env, tdf, twd, tws, twt);
18762        break;
18763    case OPC_FSULE_df:
18764        gen_helper_msa_fsule_df(cpu_env, tdf, twd, tws, twt);
18765        break;
18766    case OPC_FMAX_A_df:
18767        gen_helper_msa_fmax_a_df(cpu_env, tdf, twd, tws, twt);
18768        break;
18769    default:
18770        MIPS_INVAL("MSA instruction");
18771        generate_exception_end(ctx, EXCP_RI);
18772        break;
18773    }
18774
18775    tcg_temp_free_i32(twd);
18776    tcg_temp_free_i32(tws);
18777    tcg_temp_free_i32(twt);
18778    tcg_temp_free_i32(tdf);
18779}
18780
18781static void gen_msa_2r(CPUMIPSState *env, DisasContext *ctx)
18782{
18783#define MASK_MSA_2R(op)     (MASK_MSA_MINOR(op) | (op & (0x1f << 21)) | \
18784                            (op & (0x7 << 18)))
18785    uint8_t wt = (ctx->opcode >> 16) & 0x1f;
18786    uint8_t ws = (ctx->opcode >> 11) & 0x1f;
18787    uint8_t wd = (ctx->opcode >> 6) & 0x1f;
18788    uint8_t df = (ctx->opcode >> 16) & 0x3;
18789    TCGv_i32 twd = tcg_const_i32(wd);
18790    TCGv_i32 tws = tcg_const_i32(ws);
18791    TCGv_i32 twt = tcg_const_i32(wt);
18792    TCGv_i32 tdf = tcg_const_i32(df);
18793
18794    switch (MASK_MSA_2R(ctx->opcode)) {
18795    case OPC_FILL_df:
18796#if !defined(TARGET_MIPS64)
18797        /* Double format valid only for MIPS64 */
18798        if (df == DF_DOUBLE) {
18799            generate_exception_end(ctx, EXCP_RI);
18800            break;
18801        }
18802#endif
18803        gen_helper_msa_fill_df(cpu_env, tdf, twd, tws); /* trs */
18804        break;
18805    case OPC_PCNT_df:
18806        gen_helper_msa_pcnt_df(cpu_env, tdf, twd, tws);
18807        break;
18808    case OPC_NLOC_df:
18809        gen_helper_msa_nloc_df(cpu_env, tdf, twd, tws);
18810        break;
18811    case OPC_NLZC_df:
18812        gen_helper_msa_nlzc_df(cpu_env, tdf, twd, tws);
18813        break;
18814    default:
18815        MIPS_INVAL("MSA instruction");
18816        generate_exception_end(ctx, EXCP_RI);
18817        break;
18818    }
18819
18820    tcg_temp_free_i32(twd);
18821    tcg_temp_free_i32(tws);
18822    tcg_temp_free_i32(twt);
18823    tcg_temp_free_i32(tdf);
18824}
18825
18826static void gen_msa_2rf(CPUMIPSState *env, DisasContext *ctx)
18827{
18828#define MASK_MSA_2RF(op)    (MASK_MSA_MINOR(op) | (op & (0x1f << 21)) | \
18829                            (op & (0xf << 17)))
18830    uint8_t wt = (ctx->opcode >> 16) & 0x1f;
18831    uint8_t ws = (ctx->opcode >> 11) & 0x1f;
18832    uint8_t wd = (ctx->opcode >> 6) & 0x1f;
18833    uint8_t df = (ctx->opcode >> 16) & 0x1;
18834    TCGv_i32 twd = tcg_const_i32(wd);
18835    TCGv_i32 tws = tcg_const_i32(ws);
18836    TCGv_i32 twt = tcg_const_i32(wt);
18837    /* adjust df value for floating-point instruction */
18838    TCGv_i32 tdf = tcg_const_i32(df + 2);
18839
18840    switch (MASK_MSA_2RF(ctx->opcode)) {
18841    case OPC_FCLASS_df:
18842        gen_helper_msa_fclass_df(cpu_env, tdf, twd, tws);
18843        break;
18844    case OPC_FTRUNC_S_df:
18845        gen_helper_msa_ftrunc_s_df(cpu_env, tdf, twd, tws);
18846        break;
18847    case OPC_FTRUNC_U_df:
18848        gen_helper_msa_ftrunc_u_df(cpu_env, tdf, twd, tws);
18849        break;
18850    case OPC_FSQRT_df:
18851        gen_helper_msa_fsqrt_df(cpu_env, tdf, twd, tws);
18852        break;
18853    case OPC_FRSQRT_df:
18854        gen_helper_msa_frsqrt_df(cpu_env, tdf, twd, tws);
18855        break;
18856    case OPC_FRCP_df:
18857        gen_helper_msa_frcp_df(cpu_env, tdf, twd, tws);
18858        break;
18859    case OPC_FRINT_df:
18860        gen_helper_msa_frint_df(cpu_env, tdf, twd, tws);
18861        break;
18862    case OPC_FLOG2_df:
18863        gen_helper_msa_flog2_df(cpu_env, tdf, twd, tws);
18864        break;
18865    case OPC_FEXUPL_df:
18866        gen_helper_msa_fexupl_df(cpu_env, tdf, twd, tws);
18867        break;
18868    case OPC_FEXUPR_df:
18869        gen_helper_msa_fexupr_df(cpu_env, tdf, twd, tws);
18870        break;
18871    case OPC_FFQL_df:
18872        gen_helper_msa_ffql_df(cpu_env, tdf, twd, tws);
18873        break;
18874    case OPC_FFQR_df:
18875        gen_helper_msa_ffqr_df(cpu_env, tdf, twd, tws);
18876        break;
18877    case OPC_FTINT_S_df:
18878        gen_helper_msa_ftint_s_df(cpu_env, tdf, twd, tws);
18879        break;
18880    case OPC_FTINT_U_df:
18881        gen_helper_msa_ftint_u_df(cpu_env, tdf, twd, tws);
18882        break;
18883    case OPC_FFINT_S_df:
18884        gen_helper_msa_ffint_s_df(cpu_env, tdf, twd, tws);
18885        break;
18886    case OPC_FFINT_U_df:
18887        gen_helper_msa_ffint_u_df(cpu_env, tdf, twd, tws);
18888        break;
18889    }
18890
18891    tcg_temp_free_i32(twd);
18892    tcg_temp_free_i32(tws);
18893    tcg_temp_free_i32(twt);
18894    tcg_temp_free_i32(tdf);
18895}
18896
18897static void gen_msa_vec_v(CPUMIPSState *env, DisasContext *ctx)
18898{
18899#define MASK_MSA_VEC(op)    (MASK_MSA_MINOR(op) | (op & (0x1f << 21)))
18900    uint8_t wt = (ctx->opcode >> 16) & 0x1f;
18901    uint8_t ws = (ctx->opcode >> 11) & 0x1f;
18902    uint8_t wd = (ctx->opcode >> 6) & 0x1f;
18903    TCGv_i32 twd = tcg_const_i32(wd);
18904    TCGv_i32 tws = tcg_const_i32(ws);
18905    TCGv_i32 twt = tcg_const_i32(wt);
18906
18907    switch (MASK_MSA_VEC(ctx->opcode)) {
18908    case OPC_AND_V:
18909        gen_helper_msa_and_v(cpu_env, twd, tws, twt);
18910        break;
18911    case OPC_OR_V:
18912        gen_helper_msa_or_v(cpu_env, twd, tws, twt);
18913        break;
18914    case OPC_NOR_V:
18915        gen_helper_msa_nor_v(cpu_env, twd, tws, twt);
18916        break;
18917    case OPC_XOR_V:
18918        gen_helper_msa_xor_v(cpu_env, twd, tws, twt);
18919        break;
18920    case OPC_BMNZ_V:
18921        gen_helper_msa_bmnz_v(cpu_env, twd, tws, twt);
18922        break;
18923    case OPC_BMZ_V:
18924        gen_helper_msa_bmz_v(cpu_env, twd, tws, twt);
18925        break;
18926    case OPC_BSEL_V:
18927        gen_helper_msa_bsel_v(cpu_env, twd, tws, twt);
18928        break;
18929    default:
18930        MIPS_INVAL("MSA instruction");
18931        generate_exception_end(ctx, EXCP_RI);
18932        break;
18933    }
18934
18935    tcg_temp_free_i32(twd);
18936    tcg_temp_free_i32(tws);
18937    tcg_temp_free_i32(twt);
18938}
18939
18940static void gen_msa_vec(CPUMIPSState *env, DisasContext *ctx)
18941{
18942    switch (MASK_MSA_VEC(ctx->opcode)) {
18943    case OPC_AND_V:
18944    case OPC_OR_V:
18945    case OPC_NOR_V:
18946    case OPC_XOR_V:
18947    case OPC_BMNZ_V:
18948    case OPC_BMZ_V:
18949    case OPC_BSEL_V:
18950        gen_msa_vec_v(env, ctx);
18951        break;
18952    case OPC_MSA_2R:
18953        gen_msa_2r(env, ctx);
18954        break;
18955    case OPC_MSA_2RF:
18956        gen_msa_2rf(env, ctx);
18957        break;
18958    default:
18959        MIPS_INVAL("MSA instruction");
18960        generate_exception_end(ctx, EXCP_RI);
18961        break;
18962    }
18963}
18964
18965static void gen_msa(CPUMIPSState *env, DisasContext *ctx)
18966{
18967    uint32_t opcode = ctx->opcode;
18968    check_insn(ctx, ASE_MSA);
18969    check_msa_access(ctx);
18970
18971    switch (MASK_MSA_MINOR(opcode)) {
18972    case OPC_MSA_I8_00:
18973    case OPC_MSA_I8_01:
18974    case OPC_MSA_I8_02:
18975        gen_msa_i8(env, ctx);
18976        break;
18977    case OPC_MSA_I5_06:
18978    case OPC_MSA_I5_07:
18979        gen_msa_i5(env, ctx);
18980        break;
18981    case OPC_MSA_BIT_09:
18982    case OPC_MSA_BIT_0A:
18983        gen_msa_bit(env, ctx);
18984        break;
18985    case OPC_MSA_3R_0D:
18986    case OPC_MSA_3R_0E:
18987    case OPC_MSA_3R_0F:
18988    case OPC_MSA_3R_10:
18989    case OPC_MSA_3R_11:
18990    case OPC_MSA_3R_12:
18991    case OPC_MSA_3R_13:
18992    case OPC_MSA_3R_14:
18993    case OPC_MSA_3R_15:
18994        gen_msa_3r(env, ctx);
18995        break;
18996    case OPC_MSA_ELM:
18997        gen_msa_elm(env, ctx);
18998        break;
18999    case OPC_MSA_3RF_1A:
19000    case OPC_MSA_3RF_1B:
19001    case OPC_MSA_3RF_1C:
19002        gen_msa_3rf(env, ctx);
19003        break;
19004    case OPC_MSA_VEC:
19005        gen_msa_vec(env, ctx);
19006        break;
19007    case OPC_LD_B:
19008    case OPC_LD_H:
19009    case OPC_LD_W:
19010    case OPC_LD_D:
19011    case OPC_ST_B:
19012    case OPC_ST_H:
19013    case OPC_ST_W:
19014    case OPC_ST_D:
19015        {
19016            int32_t s10 = sextract32(ctx->opcode, 16, 10);
19017            uint8_t rs = (ctx->opcode >> 11) & 0x1f;
19018            uint8_t wd = (ctx->opcode >> 6) & 0x1f;
19019            uint8_t df = (ctx->opcode >> 0) & 0x3;
19020
19021            TCGv_i32 twd = tcg_const_i32(wd);
19022            TCGv taddr = tcg_temp_new();
19023            gen_base_offset_addr(ctx, taddr, rs, s10 << df);
19024
19025            switch (MASK_MSA_MINOR(opcode)) {
19026            case OPC_LD_B:
19027                gen_helper_msa_ld_b(cpu_env, twd, taddr);
19028                break;
19029            case OPC_LD_H:
19030                gen_helper_msa_ld_h(cpu_env, twd, taddr);
19031                break;
19032            case OPC_LD_W:
19033                gen_helper_msa_ld_w(cpu_env, twd, taddr);
19034                break;
19035            case OPC_LD_D:
19036                gen_helper_msa_ld_d(cpu_env, twd, taddr);
19037                break;
19038            case OPC_ST_B:
19039                gen_helper_msa_st_b(cpu_env, twd, taddr);
19040                break;
19041            case OPC_ST_H:
19042                gen_helper_msa_st_h(cpu_env, twd, taddr);
19043                break;
19044            case OPC_ST_W:
19045                gen_helper_msa_st_w(cpu_env, twd, taddr);
19046                break;
19047            case OPC_ST_D:
19048                gen_helper_msa_st_d(cpu_env, twd, taddr);
19049                break;
19050            }
19051
19052            tcg_temp_free_i32(twd);
19053            tcg_temp_free(taddr);
19054        }
19055        break;
19056    default:
19057        MIPS_INVAL("MSA instruction");
19058        generate_exception_end(ctx, EXCP_RI);
19059        break;
19060    }
19061
19062}
19063
19064static void decode_opc(CPUMIPSState *env, DisasContext *ctx)
19065{
19066    int32_t offset;
19067    int rs, rt, rd, sa;
19068    uint32_t op, op1;
19069    int16_t imm;
19070
19071    /* make sure instructions are on a word boundary */
19072    if (ctx->pc & 0x3) {
19073        env->CP0_BadVAddr = ctx->pc;
19074        generate_exception_err(ctx, EXCP_AdEL, EXCP_INST_NOTAVAIL);
19075        return;
19076    }
19077
19078    /* Handle blikely not taken case */
19079    if ((ctx->hflags & MIPS_HFLAG_BMASK_BASE) == MIPS_HFLAG_BL) {
19080        TCGLabel *l1 = gen_new_label();
19081
19082        tcg_gen_brcondi_tl(TCG_COND_NE, bcond, 0, l1);
19083        tcg_gen_movi_i32(hflags, ctx->hflags & ~MIPS_HFLAG_BMASK);
19084        gen_goto_tb(ctx, 1, ctx->pc + 4);
19085        gen_set_label(l1);
19086    }
19087
19088    op = MASK_OP_MAJOR(ctx->opcode);
19089    rs = (ctx->opcode >> 21) & 0x1f;
19090    rt = (ctx->opcode >> 16) & 0x1f;
19091    rd = (ctx->opcode >> 11) & 0x1f;
19092    sa = (ctx->opcode >> 6) & 0x1f;
19093    imm = (int16_t)ctx->opcode;
19094    switch (op) {
19095    case OPC_SPECIAL:
19096        decode_opc_special(env, ctx);
19097        break;
19098    case OPC_SPECIAL2:
19099        decode_opc_special2_legacy(env, ctx);
19100        break;
19101    case OPC_SPECIAL3:
19102        decode_opc_special3(env, ctx);
19103        break;
19104    case OPC_REGIMM:
19105        op1 = MASK_REGIMM(ctx->opcode);
19106        switch (op1) {
19107        case OPC_BLTZL: /* REGIMM branches */
19108        case OPC_BGEZL:
19109        case OPC_BLTZALL:
19110        case OPC_BGEZALL:
19111            check_insn(ctx, ISA_MIPS2);
19112            check_insn_opc_removed(ctx, ISA_MIPS32R6);
19113            /* Fallthrough */
19114        case OPC_BLTZ:
19115        case OPC_BGEZ:
19116            gen_compute_branch(ctx, op1, 4, rs, -1, imm << 2, 4);
19117            break;
19118        case OPC_BLTZAL:
19119        case OPC_BGEZAL:
19120            if (ctx->insn_flags & ISA_MIPS32R6) {
19121                if (rs == 0) {
19122                    /* OPC_NAL, OPC_BAL */
19123                    gen_compute_branch(ctx, op1, 4, 0, -1, imm << 2, 4);
19124                } else {
19125                    generate_exception_end(ctx, EXCP_RI);
19126                }
19127            } else {
19128                gen_compute_branch(ctx, op1, 4, rs, -1, imm << 2, 4);
19129            }
19130            break;
19131        case OPC_TGEI ... OPC_TEQI: /* REGIMM traps */
19132        case OPC_TNEI:
19133            check_insn(ctx, ISA_MIPS2);
19134            check_insn_opc_removed(ctx, ISA_MIPS32R6);
19135            gen_trap(ctx, op1, rs, -1, imm);
19136            break;
19137        case OPC_SIGRIE:
19138            check_insn(ctx, ISA_MIPS32R6);
19139            generate_exception_end(ctx, EXCP_RI);
19140            break;
19141        case OPC_SYNCI:
19142            check_insn(ctx, ISA_MIPS32R2);
19143            /* Break the TB to be able to sync copied instructions
19144               immediately */
19145            ctx->bstate = BS_STOP;
19146            break;
19147        case OPC_BPOSGE32:    /* MIPS DSP branch */
19148#if defined(TARGET_MIPS64)
19149        case OPC_BPOSGE64:
19150#endif
19151            check_dsp(ctx);
19152            gen_compute_branch(ctx, op1, 4, -1, -2, (int32_t)imm << 2, 4);
19153            break;
19154#if defined(TARGET_MIPS64)
19155        case OPC_DAHI:
19156            check_insn(ctx, ISA_MIPS32R6);
19157            check_mips_64(ctx);
19158            if (rs != 0) {
19159                tcg_gen_addi_tl(cpu_gpr[rs], cpu_gpr[rs], (int64_t)imm << 32);
19160            }
19161            break;
19162        case OPC_DATI:
19163            check_insn(ctx, ISA_MIPS32R6);
19164            check_mips_64(ctx);
19165            if (rs != 0) {
19166                tcg_gen_addi_tl(cpu_gpr[rs], cpu_gpr[rs], (int64_t)imm << 48);
19167            }
19168            break;
19169#endif
19170        default:            /* Invalid */
19171            MIPS_INVAL("regimm");
19172            generate_exception_end(ctx, EXCP_RI);
19173            break;
19174        }
19175        break;
19176    case OPC_CP0:
19177        check_cp0_enabled(ctx);
19178        op1 = MASK_CP0(ctx->opcode);
19179        switch (op1) {
19180        case OPC_MFC0:
19181        case OPC_MTC0:
19182        case OPC_MFTR:
19183        case OPC_MTTR:
19184        case OPC_MFHC0:
19185        case OPC_MTHC0:
19186#if defined(TARGET_MIPS64)
19187        case OPC_DMFC0:
19188        case OPC_DMTC0:
19189#endif
19190#ifndef CONFIG_USER_ONLY
19191            gen_cp0(env, ctx, op1, rt, rd);
19192#endif /* !CONFIG_USER_ONLY */
19193            break;
19194        case OPC_C0_FIRST ... OPC_C0_LAST:
19195#ifndef CONFIG_USER_ONLY
19196            gen_cp0(env, ctx, MASK_C0(ctx->opcode), rt, rd);
19197#endif /* !CONFIG_USER_ONLY */
19198            break;
19199        case OPC_MFMC0:
19200#ifndef CONFIG_USER_ONLY
19201            {
19202                uint32_t op2;
19203                TCGv t0 = tcg_temp_new();
19204
19205                op2 = MASK_MFMC0(ctx->opcode);
19206                switch (op2) {
19207                case OPC_DMT:
19208                    check_insn(ctx, ASE_MT);
19209                    gen_helper_dmt(t0);
19210                    gen_store_gpr(t0, rt);
19211                    break;
19212                case OPC_EMT:
19213                    check_insn(ctx, ASE_MT);
19214                    gen_helper_emt(t0);
19215                    gen_store_gpr(t0, rt);
19216                    break;
19217                case OPC_DVPE:
19218                    check_insn(ctx, ASE_MT);
19219                    gen_helper_dvpe(t0, cpu_env);
19220                    gen_store_gpr(t0, rt);
19221                    break;
19222                case OPC_EVPE:
19223                    check_insn(ctx, ASE_MT);
19224                    gen_helper_evpe(t0, cpu_env);
19225                    gen_store_gpr(t0, rt);
19226                    break;
19227                case OPC_DVP:
19228                    check_insn(ctx, ISA_MIPS32R6);
19229                    if (ctx->vp) {
19230                        gen_helper_dvp(t0, cpu_env);
19231                        gen_store_gpr(t0, rt);
19232                    }
19233                    break;
19234                case OPC_EVP:
19235                    check_insn(ctx, ISA_MIPS32R6);
19236                    if (ctx->vp) {
19237                        gen_helper_evp(t0, cpu_env);
19238                        gen_store_gpr(t0, rt);
19239                    }
19240                    break;
19241                case OPC_DI:
19242                    check_insn(ctx, ISA_MIPS32R2);
19243                    save_cpu_state(ctx, 1);
19244                    gen_helper_di(t0, cpu_env);
19245                    gen_store_gpr(t0, rt);
19246                    /* Stop translation as we may have switched
19247                       the execution mode.  */
19248                    ctx->bstate = BS_STOP;
19249                    break;
19250                case OPC_EI:
19251                    check_insn(ctx, ISA_MIPS32R2);
19252                    save_cpu_state(ctx, 1);
19253                    gen_helper_ei(t0, cpu_env);
19254                    gen_store_gpr(t0, rt);
19255                    /* Stop translation as we may have switched
19256                       the execution mode.  */
19257                    ctx->bstate = BS_STOP;
19258                    break;
19259                default:            /* Invalid */
19260                    MIPS_INVAL("mfmc0");
19261                    generate_exception_end(ctx, EXCP_RI);
19262                    break;
19263                }
19264                tcg_temp_free(t0);
19265            }
19266#endif /* !CONFIG_USER_ONLY */
19267            break;
19268        case OPC_RDPGPR:
19269            check_insn(ctx, ISA_MIPS32R2);
19270            gen_load_srsgpr(rt, rd);
19271            break;
19272        case OPC_WRPGPR:
19273            check_insn(ctx, ISA_MIPS32R2);
19274            gen_store_srsgpr(rt, rd);
19275            break;
19276        default:
19277            MIPS_INVAL("cp0");
19278            generate_exception_end(ctx, EXCP_RI);
19279            break;
19280        }
19281        break;
19282    case OPC_BOVC: /* OPC_BEQZALC, OPC_BEQC, OPC_ADDI */
19283        if (ctx->insn_flags & ISA_MIPS32R6) {
19284            /* OPC_BOVC, OPC_BEQZALC, OPC_BEQC */
19285            gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
19286        } else {
19287            /* OPC_ADDI */
19288            /* Arithmetic with immediate opcode */
19289            gen_arith_imm(ctx, op, rt, rs, imm);
19290        }
19291        break;
19292    case OPC_ADDIU:
19293         gen_arith_imm(ctx, op, rt, rs, imm);
19294         break;
19295    case OPC_SLTI: /* Set on less than with immediate opcode */
19296    case OPC_SLTIU:
19297         gen_slt_imm(ctx, op, rt, rs, imm);
19298         break;
19299    case OPC_ANDI: /* Arithmetic with immediate opcode */
19300    case OPC_LUI: /* OPC_AUI */
19301    case OPC_ORI:
19302    case OPC_XORI:
19303         gen_logic_imm(ctx, op, rt, rs, imm);
19304         break;
19305    case OPC_J ... OPC_JAL: /* Jump */
19306         offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 2;
19307         gen_compute_branch(ctx, op, 4, rs, rt, offset, 4);
19308         break;
19309    /* Branch */
19310    case OPC_BLEZC: /* OPC_BGEZC, OPC_BGEC, OPC_BLEZL */
19311        if (ctx->insn_flags & ISA_MIPS32R6) {
19312            if (rt == 0) {
19313                generate_exception_end(ctx, EXCP_RI);
19314                break;
19315            }
19316            /* OPC_BLEZC, OPC_BGEZC, OPC_BGEC */
19317            gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
19318        } else {
19319            /* OPC_BLEZL */
19320            gen_compute_branch(ctx, op, 4, rs, rt, imm << 2, 4);
19321        }
19322        break;
19323    case OPC_BGTZC: /* OPC_BLTZC, OPC_BLTC, OPC_BGTZL */
19324        if (ctx->insn_flags & ISA_MIPS32R6) {
19325            if (rt == 0) {
19326                generate_exception_end(ctx, EXCP_RI);
19327                break;
19328            }
19329            /* OPC_BGTZC, OPC_BLTZC, OPC_BLTC */
19330            gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
19331        } else {
19332            /* OPC_BGTZL */
19333            gen_compute_branch(ctx, op, 4, rs, rt, imm << 2, 4);
19334        }
19335        break;
19336    case OPC_BLEZALC: /* OPC_BGEZALC, OPC_BGEUC, OPC_BLEZ */
19337        if (rt == 0) {
19338            /* OPC_BLEZ */
19339            gen_compute_branch(ctx, op, 4, rs, rt, imm << 2, 4);
19340        } else {
19341            check_insn(ctx, ISA_MIPS32R6);
19342            /* OPC_BLEZALC, OPC_BGEZALC, OPC_BGEUC */
19343            gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
19344        }
19345        break;
19346    case OPC_BGTZALC: /* OPC_BLTZALC, OPC_BLTUC, OPC_BGTZ */
19347        if (rt == 0) {
19348            /* OPC_BGTZ */
19349            gen_compute_branch(ctx, op, 4, rs, rt, imm << 2, 4);
19350        } else {
19351            check_insn(ctx, ISA_MIPS32R6);
19352            /* OPC_BGTZALC, OPC_BLTZALC, OPC_BLTUC */
19353            gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
19354        }
19355        break;
19356    case OPC_BEQL:
19357    case OPC_BNEL:
19358        check_insn(ctx, ISA_MIPS2);
19359         check_insn_opc_removed(ctx, ISA_MIPS32R6);
19360        /* Fallthrough */
19361    case OPC_BEQ:
19362    case OPC_BNE:
19363         gen_compute_branch(ctx, op, 4, rs, rt, imm << 2, 4);
19364         break;
19365    case OPC_LL: /* Load and stores */
19366        check_insn(ctx, ISA_MIPS2);
19367        /* Fallthrough */
19368    case OPC_LWL:
19369    case OPC_LWR:
19370        check_insn_opc_removed(ctx, ISA_MIPS32R6);
19371         /* Fallthrough */
19372    case OPC_LB ... OPC_LH:
19373    case OPC_LW ... OPC_LHU:
19374         gen_ld(ctx, op, rt, rs, imm);
19375         break;
19376    case OPC_SWL:
19377    case OPC_SWR:
19378        check_insn_opc_removed(ctx, ISA_MIPS32R6);
19379        /* fall through */
19380    case OPC_SB ... OPC_SH:
19381    case OPC_SW:
19382         gen_st(ctx, op, rt, rs, imm);
19383         break;
19384    case OPC_SC:
19385        check_insn(ctx, ISA_MIPS2);
19386         check_insn_opc_removed(ctx, ISA_MIPS32R6);
19387         gen_st_cond(ctx, op, rt, rs, imm);
19388         break;
19389    case OPC_CACHE:
19390        check_insn_opc_removed(ctx, ISA_MIPS32R6);
19391        check_cp0_enabled(ctx);
19392        check_insn(ctx, ISA_MIPS3 | ISA_MIPS32);
19393        if (ctx->hflags & MIPS_HFLAG_ITC_CACHE) {
19394            gen_cache_operation(ctx, rt, rs, imm);
19395        }
19396        /* Treat as NOP. */
19397        break;
19398    case OPC_PREF:
19399        check_insn_opc_removed(ctx, ISA_MIPS32R6);
19400        check_insn(ctx, ISA_MIPS4 | ISA_MIPS32);
19401        /* Treat as NOP. */
19402        break;
19403
19404    /* Floating point (COP1). */
19405    case OPC_LWC1:
19406    case OPC_LDC1:
19407    case OPC_SWC1:
19408    case OPC_SDC1:
19409        gen_cop1_ldst(ctx, op, rt, rs, imm);
19410        break;
19411
19412    case OPC_CP1:
19413        op1 = MASK_CP1(ctx->opcode);
19414
19415        switch (op1) {
19416        case OPC_MFHC1:
19417        case OPC_MTHC1:
19418            check_cp1_enabled(ctx);
19419            check_insn(ctx, ISA_MIPS32R2);
19420        case OPC_MFC1:
19421        case OPC_CFC1:
19422        case OPC_MTC1:
19423        case OPC_CTC1:
19424            check_cp1_enabled(ctx);
19425            gen_cp1(ctx, op1, rt, rd);
19426            break;
19427#if defined(TARGET_MIPS64)
19428        case OPC_DMFC1:
19429        case OPC_DMTC1:
19430            check_cp1_enabled(ctx);
19431            check_insn(ctx, ISA_MIPS3);
19432            check_mips_64(ctx);
19433            gen_cp1(ctx, op1, rt, rd);
19434            break;
19435#endif
19436        case OPC_BC1EQZ: /* OPC_BC1ANY2 */
19437            check_cp1_enabled(ctx);
19438            if (ctx->insn_flags & ISA_MIPS32R6) {
19439                /* OPC_BC1EQZ */
19440                gen_compute_branch1_r6(ctx, MASK_CP1(ctx->opcode),
19441                                       rt, imm << 2, 4);
19442            } else {
19443                /* OPC_BC1ANY2 */
19444                check_cop1x(ctx);
19445                check_insn(ctx, ASE_MIPS3D);
19446                gen_compute_branch1(ctx, MASK_BC1(ctx->opcode),
19447                                    (rt >> 2) & 0x7, imm << 2);
19448            }
19449            break;
19450        case OPC_BC1NEZ:
19451            check_cp1_enabled(ctx);
19452            check_insn(ctx, ISA_MIPS32R6);
19453            gen_compute_branch1_r6(ctx, MASK_CP1(ctx->opcode),
19454                                   rt, imm << 2, 4);
19455            break;
19456        case OPC_BC1ANY4:
19457            check_cp1_enabled(ctx);
19458            check_insn_opc_removed(ctx, ISA_MIPS32R6);
19459            check_cop1x(ctx);
19460            check_insn(ctx, ASE_MIPS3D);
19461            /* fall through */
19462        case OPC_BC1:
19463            check_cp1_enabled(ctx);
19464            check_insn_opc_removed(ctx, ISA_MIPS32R6);
19465            gen_compute_branch1(ctx, MASK_BC1(ctx->opcode),
19466                                (rt >> 2) & 0x7, imm << 2);
19467            break;
19468        case OPC_PS_FMT:
19469            check_ps(ctx);
19470            /* fall through */
19471        case OPC_S_FMT:
19472        case OPC_D_FMT:
19473            check_cp1_enabled(ctx);
19474            gen_farith(ctx, ctx->opcode & FOP(0x3f, 0x1f), rt, rd, sa,
19475                       (imm >> 8) & 0x7);
19476            break;
19477        case OPC_W_FMT:
19478        case OPC_L_FMT:
19479        {
19480            int r6_op = ctx->opcode & FOP(0x3f, 0x1f);
19481            check_cp1_enabled(ctx);
19482            if (ctx->insn_flags & ISA_MIPS32R6) {
19483                switch (r6_op) {
19484                case R6_OPC_CMP_AF_S:
19485                case R6_OPC_CMP_UN_S:
19486                case R6_OPC_CMP_EQ_S:
19487                case R6_OPC_CMP_UEQ_S:
19488                case R6_OPC_CMP_LT_S:
19489                case R6_OPC_CMP_ULT_S:
19490                case R6_OPC_CMP_LE_S:
19491                case R6_OPC_CMP_ULE_S:
19492                case R6_OPC_CMP_SAF_S:
19493                case R6_OPC_CMP_SUN_S:
19494                case R6_OPC_CMP_SEQ_S:
19495                case R6_OPC_CMP_SEUQ_S:
19496                case R6_OPC_CMP_SLT_S:
19497                case R6_OPC_CMP_SULT_S:
19498                case R6_OPC_CMP_SLE_S:
19499                case R6_OPC_CMP_SULE_S:
19500                case R6_OPC_CMP_OR_S:
19501                case R6_OPC_CMP_UNE_S:
19502                case R6_OPC_CMP_NE_S:
19503                case R6_OPC_CMP_SOR_S:
19504                case R6_OPC_CMP_SUNE_S:
19505                case R6_OPC_CMP_SNE_S:
19506                    gen_r6_cmp_s(ctx, ctx->opcode & 0x1f, rt, rd, sa);
19507                    break;
19508                case R6_OPC_CMP_AF_D:
19509                case R6_OPC_CMP_UN_D:
19510                case R6_OPC_CMP_EQ_D:
19511                case R6_OPC_CMP_UEQ_D:
19512                case R6_OPC_CMP_LT_D:
19513                case R6_OPC_CMP_ULT_D:
19514                case R6_OPC_CMP_LE_D:
19515                case R6_OPC_CMP_ULE_D:
19516                case R6_OPC_CMP_SAF_D:
19517                case R6_OPC_CMP_SUN_D:
19518                case R6_OPC_CMP_SEQ_D:
19519                case R6_OPC_CMP_SEUQ_D:
19520                case R6_OPC_CMP_SLT_D:
19521                case R6_OPC_CMP_SULT_D:
19522                case R6_OPC_CMP_SLE_D:
19523                case R6_OPC_CMP_SULE_D:
19524                case R6_OPC_CMP_OR_D:
19525                case R6_OPC_CMP_UNE_D:
19526                case R6_OPC_CMP_NE_D:
19527                case R6_OPC_CMP_SOR_D:
19528                case R6_OPC_CMP_SUNE_D:
19529                case R6_OPC_CMP_SNE_D:
19530                    gen_r6_cmp_d(ctx, ctx->opcode & 0x1f, rt, rd, sa);
19531                    break;
19532                default:
19533                    gen_farith(ctx, ctx->opcode & FOP(0x3f, 0x1f),
19534                               rt, rd, sa, (imm >> 8) & 0x7);
19535
19536                    break;
19537                }
19538            } else {
19539                gen_farith(ctx, ctx->opcode & FOP(0x3f, 0x1f), rt, rd, sa,
19540                           (imm >> 8) & 0x7);
19541            }
19542            break;
19543        }
19544        case OPC_BZ_V:
19545        case OPC_BNZ_V:
19546        case OPC_BZ_B:
19547        case OPC_BZ_H:
19548        case OPC_BZ_W:
19549        case OPC_BZ_D:
19550        case OPC_BNZ_B:
19551        case OPC_BNZ_H:
19552        case OPC_BNZ_W:
19553        case OPC_BNZ_D:
19554            check_insn(ctx, ASE_MSA);
19555            gen_msa_branch(env, ctx, op1);
19556            break;
19557        default:
19558            MIPS_INVAL("cp1");
19559            generate_exception_end(ctx, EXCP_RI);
19560            break;
19561        }
19562        break;
19563
19564    /* Compact branches [R6] and COP2 [non-R6] */
19565    case OPC_BC: /* OPC_LWC2 */
19566    case OPC_BALC: /* OPC_SWC2 */
19567        if (ctx->insn_flags & ISA_MIPS32R6) {
19568            /* OPC_BC, OPC_BALC */
19569            gen_compute_compact_branch(ctx, op, 0, 0,
19570                                       sextract32(ctx->opcode << 2, 0, 28));
19571        } else {
19572            /* OPC_LWC2, OPC_SWC2 */
19573            /* COP2: Not implemented. */
19574            generate_exception_err(ctx, EXCP_CpU, 2);
19575        }
19576        break;
19577    case OPC_BEQZC: /* OPC_JIC, OPC_LDC2 */
19578    case OPC_BNEZC: /* OPC_JIALC, OPC_SDC2 */
19579        if (ctx->insn_flags & ISA_MIPS32R6) {
19580            if (rs != 0) {
19581                /* OPC_BEQZC, OPC_BNEZC */
19582                gen_compute_compact_branch(ctx, op, rs, 0,
19583                                           sextract32(ctx->opcode << 2, 0, 23));
19584            } else {
19585                /* OPC_JIC, OPC_JIALC */
19586                gen_compute_compact_branch(ctx, op, 0, rt, imm);
19587            }
19588        } else {
19589            /* OPC_LWC2, OPC_SWC2 */
19590            /* COP2: Not implemented. */
19591            generate_exception_err(ctx, EXCP_CpU, 2);
19592        }
19593        break;
19594    case OPC_CP2:
19595        check_insn(ctx, INSN_LOONGSON2F);
19596        /* Note that these instructions use different fields.  */
19597        gen_loongson_multimedia(ctx, sa, rd, rt);
19598        break;
19599
19600    case OPC_CP3:
19601        check_insn_opc_removed(ctx, ISA_MIPS32R6);
19602        if (ctx->CP0_Config1 & (1 << CP0C1_FP)) {
19603            check_cp1_enabled(ctx);
19604            op1 = MASK_CP3(ctx->opcode);
19605            switch (op1) {
19606            case OPC_LUXC1:
19607            case OPC_SUXC1:
19608                check_insn(ctx, ISA_MIPS5 | ISA_MIPS32R2);
19609                /* Fallthrough */
19610            case OPC_LWXC1:
19611            case OPC_LDXC1:
19612            case OPC_SWXC1:
19613            case OPC_SDXC1:
19614                check_insn(ctx, ISA_MIPS4 | ISA_MIPS32R2);
19615                gen_flt3_ldst(ctx, op1, sa, rd, rs, rt);
19616                break;
19617            case OPC_PREFX:
19618                check_insn(ctx, ISA_MIPS4 | ISA_MIPS32R2);
19619                /* Treat as NOP. */
19620                break;
19621            case OPC_ALNV_PS:
19622                check_insn(ctx, ISA_MIPS5 | ISA_MIPS32R2);
19623                /* Fallthrough */
19624            case OPC_MADD_S:
19625            case OPC_MADD_D:
19626            case OPC_MADD_PS:
19627            case OPC_MSUB_S:
19628            case OPC_MSUB_D:
19629            case OPC_MSUB_PS:
19630            case OPC_NMADD_S:
19631            case OPC_NMADD_D:
19632            case OPC_NMADD_PS:
19633            case OPC_NMSUB_S:
19634            case OPC_NMSUB_D:
19635            case OPC_NMSUB_PS:
19636                check_insn(ctx, ISA_MIPS4 | ISA_MIPS32R2);
19637                gen_flt3_arith(ctx, op1, sa, rs, rd, rt);
19638                break;
19639            default:
19640                MIPS_INVAL("cp3");
19641                generate_exception_end(ctx, EXCP_RI);
19642                break;
19643            }
19644        } else {
19645            generate_exception_err(ctx, EXCP_CpU, 1);
19646        }
19647        break;
19648
19649#if defined(TARGET_MIPS64)
19650    /* MIPS64 opcodes */
19651    case OPC_LDL ... OPC_LDR:
19652    case OPC_LLD:
19653        check_insn_opc_removed(ctx, ISA_MIPS32R6);
19654        /* fall through */
19655    case OPC_LWU:
19656    case OPC_LD:
19657        check_insn(ctx, ISA_MIPS3);
19658        check_mips_64(ctx);
19659        gen_ld(ctx, op, rt, rs, imm);
19660        break;
19661    case OPC_SDL ... OPC_SDR:
19662        check_insn_opc_removed(ctx, ISA_MIPS32R6);
19663        /* fall through */
19664    case OPC_SD:
19665        check_insn(ctx, ISA_MIPS3);
19666        check_mips_64(ctx);
19667        gen_st(ctx, op, rt, rs, imm);
19668        break;
19669    case OPC_SCD:
19670        check_insn_opc_removed(ctx, ISA_MIPS32R6);
19671        check_insn(ctx, ISA_MIPS3);
19672        check_mips_64(ctx);
19673        gen_st_cond(ctx, op, rt, rs, imm);
19674        break;
19675    case OPC_BNVC: /* OPC_BNEZALC, OPC_BNEC, OPC_DADDI */
19676        if (ctx->insn_flags & ISA_MIPS32R6) {
19677            /* OPC_BNVC, OPC_BNEZALC, OPC_BNEC */
19678            gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
19679        } else {
19680            /* OPC_DADDI */
19681            check_insn(ctx, ISA_MIPS3);
19682            check_mips_64(ctx);
19683            gen_arith_imm(ctx, op, rt, rs, imm);
19684        }
19685        break;
19686    case OPC_DADDIU:
19687        check_insn(ctx, ISA_MIPS3);
19688        check_mips_64(ctx);
19689        gen_arith_imm(ctx, op, rt, rs, imm);
19690        break;
19691#else
19692    case OPC_BNVC: /* OPC_BNEZALC, OPC_BNEC */
19693        if (ctx->insn_flags & ISA_MIPS32R6) {
19694            gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
19695        } else {
19696            MIPS_INVAL("major opcode");
19697            generate_exception_end(ctx, EXCP_RI);
19698        }
19699        break;
19700#endif
19701    case OPC_DAUI: /* OPC_JALX */
19702        if (ctx->insn_flags & ISA_MIPS32R6) {
19703#if defined(TARGET_MIPS64)
19704            /* OPC_DAUI */
19705            check_mips_64(ctx);
19706            if (rs == 0) {
19707                generate_exception(ctx, EXCP_RI);
19708            } else if (rt != 0) {
19709                TCGv t0 = tcg_temp_new();
19710                gen_load_gpr(t0, rs);
19711                tcg_gen_addi_tl(cpu_gpr[rt], t0, imm << 16);
19712                tcg_temp_free(t0);
19713            }
19714#else
19715            generate_exception_end(ctx, EXCP_RI);
19716            MIPS_INVAL("major opcode");
19717#endif
19718        } else {
19719            /* OPC_JALX */
19720            check_insn(ctx, ASE_MIPS16 | ASE_MICROMIPS);
19721            offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 2;
19722            gen_compute_branch(ctx, op, 4, rs, rt, offset, 4);
19723        }
19724        break;
19725    case OPC_MSA: /* OPC_MDMX */
19726        /* MDMX: Not implemented. */
19727        gen_msa(env, ctx);
19728        break;
19729    case OPC_PCREL:
19730        check_insn(ctx, ISA_MIPS32R6);
19731        gen_pcrel(ctx, ctx->opcode, ctx->pc, rs);
19732        break;
19733    default:            /* Invalid */
19734        MIPS_INVAL("major opcode");
19735        generate_exception_end(ctx, EXCP_RI);
19736        break;
19737    }
19738}
19739
19740void gen_intermediate_code(CPUMIPSState *env, struct TranslationBlock *tb)
19741{
19742    MIPSCPU *cpu = mips_env_get_cpu(env);
19743    CPUState *cs = CPU(cpu);
19744    DisasContext ctx;
19745    target_ulong pc_start;
19746    target_ulong next_page_start;
19747    int num_insns;
19748    int max_insns;
19749    int insn_bytes;
19750    int is_slot;
19751
19752    pc_start = tb->pc;
19753    next_page_start = (pc_start & TARGET_PAGE_MASK) + TARGET_PAGE_SIZE;
19754    ctx.pc = pc_start;
19755    ctx.saved_pc = -1;
19756    ctx.singlestep_enabled = cs->singlestep_enabled;
19757    ctx.insn_flags = env->insn_flags;
19758    ctx.CP0_Config1 = env->CP0_Config1;
19759    ctx.tb = tb;
19760    ctx.bstate = BS_NONE;
19761    ctx.btarget = 0;
19762    ctx.kscrexist = (env->CP0_Config4 >> CP0C4_KScrExist) & 0xff;
19763    ctx.rxi = (env->CP0_Config3 >> CP0C3_RXI) & 1;
19764    ctx.ie = (env->CP0_Config4 >> CP0C4_IE) & 3;
19765    ctx.bi = (env->CP0_Config3 >> CP0C3_BI) & 1;
19766    ctx.bp = (env->CP0_Config3 >> CP0C3_BP) & 1;
19767    ctx.PAMask = env->PAMask;
19768    ctx.mvh = (env->CP0_Config5 >> CP0C5_MVH) & 1;
19769    ctx.CP0_LLAddr_shift = env->CP0_LLAddr_shift;
19770    ctx.cmgcr = (env->CP0_Config3 >> CP0C3_CMGCR) & 1;
19771    /* Restore delay slot state from the tb context.  */
19772    ctx.hflags = (uint32_t)tb->flags; /* FIXME: maybe use 64 bits here? */
19773    ctx.ulri = (env->CP0_Config3 >> CP0C3_ULRI) & 1;
19774    ctx.ps = ((env->active_fpu.fcr0 >> FCR0_PS) & 1) ||
19775             (env->insn_flags & (INSN_LOONGSON2E | INSN_LOONGSON2F));
19776    ctx.vp = (env->CP0_Config5 >> CP0C5_VP) & 1;
19777    ctx.mrp = (env->CP0_Config5 >> CP0C5_MRP) & 1;
19778    restore_cpu_state(env, &ctx);
19779#ifdef CONFIG_USER_ONLY
19780        ctx.mem_idx = MIPS_HFLAG_UM;
19781#else
19782        ctx.mem_idx = ctx.hflags & MIPS_HFLAG_KSU;
19783#endif
19784    ctx.default_tcg_memop_mask = (ctx.insn_flags & ISA_MIPS32R6) ?
19785                                 MO_UNALN : MO_ALIGN;
19786    num_insns = 0;
19787    max_insns = tb->cflags & CF_COUNT_MASK;
19788    if (max_insns == 0) {
19789        max_insns = CF_COUNT_MASK;
19790    }
19791    if (max_insns > TCG_MAX_INSNS) {
19792        max_insns = TCG_MAX_INSNS;
19793    }
19794
19795    LOG_DISAS("\ntb %p idx %d hflags %04x\n", tb, ctx.mem_idx, ctx.hflags);
19796    gen_tb_start(tb);
19797    while (ctx.bstate == BS_NONE) {
19798        tcg_gen_insn_start(ctx.pc, ctx.hflags & MIPS_HFLAG_BMASK, ctx.btarget);
19799        num_insns++;
19800
19801        if (unlikely(cpu_breakpoint_test(cs, ctx.pc, BP_ANY))) {
19802            save_cpu_state(&ctx, 1);
19803            ctx.bstate = BS_BRANCH;
19804            gen_helper_raise_exception_debug(cpu_env);
19805            /* The address covered by the breakpoint must be included in
19806               [tb->pc, tb->pc + tb->size) in order to for it to be
19807               properly cleared -- thus we increment the PC here so that
19808               the logic setting tb->size below does the right thing.  */
19809            ctx.pc += 4;
19810            goto done_generating;
19811        }
19812
19813        if (num_insns == max_insns && (tb->cflags & CF_LAST_IO)) {
19814            gen_io_start();
19815        }
19816
19817        is_slot = ctx.hflags & MIPS_HFLAG_BMASK;
19818        if (!(ctx.hflags & MIPS_HFLAG_M16)) {
19819            ctx.opcode = cpu_ldl_code(env, ctx.pc);
19820            insn_bytes = 4;
19821            decode_opc(env, &ctx);
19822        } else if (ctx.insn_flags & ASE_MICROMIPS) {
19823            ctx.opcode = cpu_lduw_code(env, ctx.pc);
19824            insn_bytes = decode_micromips_opc(env, &ctx);
19825        } else if (ctx.insn_flags & ASE_MIPS16) {
19826            ctx.opcode = cpu_lduw_code(env, ctx.pc);
19827            insn_bytes = decode_mips16_opc(env, &ctx);
19828        } else {
19829            generate_exception_end(&ctx, EXCP_RI);
19830            break;
19831        }
19832
19833        if (ctx.hflags & MIPS_HFLAG_BMASK) {
19834            if (!(ctx.hflags & (MIPS_HFLAG_BDS16 | MIPS_HFLAG_BDS32 |
19835                                MIPS_HFLAG_FBNSLOT))) {
19836                /* force to generate branch as there is neither delay nor
19837                   forbidden slot */
19838                is_slot = 1;
19839            }
19840            if ((ctx.hflags & MIPS_HFLAG_M16) &&
19841                (ctx.hflags & MIPS_HFLAG_FBNSLOT)) {
19842                /* Force to generate branch as microMIPS R6 doesn't restrict
19843                   branches in the forbidden slot. */
19844                is_slot = 1;
19845            }
19846        }
19847        if (is_slot) {
19848            gen_branch(&ctx, insn_bytes);
19849        }
19850        ctx.pc += insn_bytes;
19851
19852        /* Execute a branch and its delay slot as a single instruction.
19853           This is what GDB expects and is consistent with what the
19854           hardware does (e.g. if a delay slot instruction faults, the
19855           reported PC is the PC of the branch).  */
19856        if (cs->singlestep_enabled && (ctx.hflags & MIPS_HFLAG_BMASK) == 0) {
19857            break;
19858        }
19859
19860        if (ctx.pc >= next_page_start) {
19861            break;
19862        }
19863
19864        if (tcg_op_buf_full()) {
19865            break;
19866        }
19867
19868        if (num_insns >= max_insns)
19869            break;
19870
19871        if (singlestep)
19872            break;
19873    }
19874    if (tb->cflags & CF_LAST_IO) {
19875        gen_io_end();
19876    }
19877    if (cs->singlestep_enabled && ctx.bstate != BS_BRANCH) {
19878        save_cpu_state(&ctx, ctx.bstate != BS_EXCP);
19879        gen_helper_raise_exception_debug(cpu_env);
19880    } else {
19881        switch (ctx.bstate) {
19882        case BS_STOP:
19883            gen_goto_tb(&ctx, 0, ctx.pc);
19884            break;
19885        case BS_NONE:
19886            save_cpu_state(&ctx, 0);
19887            gen_goto_tb(&ctx, 0, ctx.pc);
19888            break;
19889        case BS_EXCP:
19890            tcg_gen_exit_tb(0);
19891            break;
19892        case BS_BRANCH:
19893        default:
19894            break;
19895        }
19896    }
19897done_generating:
19898    gen_tb_end(tb, num_insns);
19899
19900    tb->size = ctx.pc - pc_start;
19901    tb->icount = num_insns;
19902
19903#ifdef DEBUG_DISAS
19904    LOG_DISAS("\n");
19905    if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM)) {
19906        qemu_log("IN: %s\n", lookup_symbol(pc_start));
19907        log_target_disas(cs, pc_start, ctx.pc - pc_start, 0);
19908        qemu_log("\n");
19909    }
19910#endif
19911}
19912
19913static void fpu_dump_state(CPUMIPSState *env, FILE *f, fprintf_function fpu_fprintf,
19914                           int flags)
19915{
19916    int i;
19917    int is_fpu64 = !!(env->hflags & MIPS_HFLAG_F64);
19918
19919#define printfpr(fp)                                                    \
19920    do {                                                                \
19921        if (is_fpu64)                                                   \
19922            fpu_fprintf(f, "w:%08x d:%016" PRIx64                       \
19923                        " fd:%13g fs:%13g psu: %13g\n",                 \
19924                        (fp)->w[FP_ENDIAN_IDX], (fp)->d,                \
19925                        (double)(fp)->fd,                               \
19926                        (double)(fp)->fs[FP_ENDIAN_IDX],                \
19927                        (double)(fp)->fs[!FP_ENDIAN_IDX]);              \
19928        else {                                                          \
19929            fpr_t tmp;                                                  \
19930            tmp.w[FP_ENDIAN_IDX] = (fp)->w[FP_ENDIAN_IDX];              \
19931            tmp.w[!FP_ENDIAN_IDX] = ((fp) + 1)->w[FP_ENDIAN_IDX];       \
19932            fpu_fprintf(f, "w:%08x d:%016" PRIx64                       \
19933                        " fd:%13g fs:%13g psu:%13g\n",                  \
19934                        tmp.w[FP_ENDIAN_IDX], tmp.d,                    \
19935                        (double)tmp.fd,                                 \
19936                        (double)tmp.fs[FP_ENDIAN_IDX],                  \
19937                        (double)tmp.fs[!FP_ENDIAN_IDX]);                \
19938        }                                                               \
19939    } while(0)
19940
19941
19942    fpu_fprintf(f, "CP1 FCR0 0x%08x  FCR31 0x%08x  SR.FR %d  fp_status 0x%02x\n",
19943                env->active_fpu.fcr0, env->active_fpu.fcr31, is_fpu64,
19944                get_float_exception_flags(&env->active_fpu.fp_status));
19945    for (i = 0; i < 32; (is_fpu64) ? i++ : (i += 2)) {
19946        fpu_fprintf(f, "%3s: ", fregnames[i]);
19947        printfpr(&env->active_fpu.fpr[i]);
19948    }
19949
19950#undef printfpr
19951}
19952
19953void mips_cpu_dump_state(CPUState *cs, FILE *f, fprintf_function cpu_fprintf,
19954                         int flags)
19955{
19956    MIPSCPU *cpu = MIPS_CPU(cs);
19957    CPUMIPSState *env = &cpu->env;
19958    int i;
19959
19960    cpu_fprintf(f, "pc=0x" TARGET_FMT_lx " HI=0x" TARGET_FMT_lx
19961                " LO=0x" TARGET_FMT_lx " ds %04x "
19962                TARGET_FMT_lx " " TARGET_FMT_ld "\n",
19963                env->active_tc.PC, env->active_tc.HI[0], env->active_tc.LO[0],
19964                env->hflags, env->btarget, env->bcond);
19965    for (i = 0; i < 32; i++) {
19966        if ((i & 3) == 0)
19967            cpu_fprintf(f, "GPR%02d:", i);
19968        cpu_fprintf(f, " %s " TARGET_FMT_lx, regnames[i], env->active_tc.gpr[i]);
19969        if ((i & 3) == 3)
19970            cpu_fprintf(f, "\n");
19971    }
19972
19973    cpu_fprintf(f, "CP0 Status  0x%08x Cause   0x%08x EPC    0x" TARGET_FMT_lx "\n",
19974                env->CP0_Status, env->CP0_Cause, env->CP0_EPC);
19975    cpu_fprintf(f, "    Config0 0x%08x Config1 0x%08x LLAddr 0x%016"
19976                PRIx64 "\n",
19977                env->CP0_Config0, env->CP0_Config1, env->lladdr);
19978    cpu_fprintf(f, "    Config2 0x%08x Config3 0x%08x\n",
19979                env->CP0_Config2, env->CP0_Config3);
19980    cpu_fprintf(f, "    Config4 0x%08x Config5 0x%08x\n",
19981                env->CP0_Config4, env->CP0_Config5);
19982    if (env->hflags & MIPS_HFLAG_FPU)
19983        fpu_dump_state(env, f, cpu_fprintf, flags);
19984}
19985
19986void mips_tcg_init(void)
19987{
19988    int i;
19989    static int inited;
19990
19991    /* Initialize various static tables. */
19992    if (inited)
19993        return;
19994
19995    cpu_env = tcg_global_reg_new_ptr(TCG_AREG0, "env");
19996
19997    TCGV_UNUSED(cpu_gpr[0]);
19998    for (i = 1; i < 32; i++)
19999        cpu_gpr[i] = tcg_global_mem_new(cpu_env,
20000                                        offsetof(CPUMIPSState, active_tc.gpr[i]),
20001                                        regnames[i]);
20002
20003    for (i = 0; i < 32; i++) {
20004        int off = offsetof(CPUMIPSState, active_fpu.fpr[i].wr.d[0]);
20005        msa_wr_d[i * 2] =
20006                tcg_global_mem_new_i64(cpu_env, off, msaregnames[i * 2]);
20007        /* The scalar floating-point unit (FPU) registers are mapped on
20008         * the MSA vector registers. */
20009        fpu_f64[i] = msa_wr_d[i * 2];
20010        off = offsetof(CPUMIPSState, active_fpu.fpr[i].wr.d[1]);
20011        msa_wr_d[i * 2 + 1] =
20012                tcg_global_mem_new_i64(cpu_env, off, msaregnames[i * 2 + 1]);
20013    }
20014
20015    cpu_PC = tcg_global_mem_new(cpu_env,
20016                                offsetof(CPUMIPSState, active_tc.PC), "PC");
20017    for (i = 0; i < MIPS_DSP_ACC; i++) {
20018        cpu_HI[i] = tcg_global_mem_new(cpu_env,
20019                                       offsetof(CPUMIPSState, active_tc.HI[i]),
20020                                       regnames_HI[i]);
20021        cpu_LO[i] = tcg_global_mem_new(cpu_env,
20022                                       offsetof(CPUMIPSState, active_tc.LO[i]),
20023                                       regnames_LO[i]);
20024    }
20025    cpu_dspctrl = tcg_global_mem_new(cpu_env,
20026                                     offsetof(CPUMIPSState, active_tc.DSPControl),
20027                                     "DSPControl");
20028    bcond = tcg_global_mem_new(cpu_env,
20029                               offsetof(CPUMIPSState, bcond), "bcond");
20030    btarget = tcg_global_mem_new(cpu_env,
20031                                 offsetof(CPUMIPSState, btarget), "btarget");
20032    hflags = tcg_global_mem_new_i32(cpu_env,
20033                                    offsetof(CPUMIPSState, hflags), "hflags");
20034
20035    fpu_fcr0 = tcg_global_mem_new_i32(cpu_env,
20036                                      offsetof(CPUMIPSState, active_fpu.fcr0),
20037                                      "fcr0");
20038    fpu_fcr31 = tcg_global_mem_new_i32(cpu_env,
20039                                       offsetof(CPUMIPSState, active_fpu.fcr31),
20040                                       "fcr31");
20041
20042    inited = 1;
20043}
20044
20045#include "translate_init.c"
20046
20047MIPSCPU *cpu_mips_init(const char *cpu_model)
20048{
20049    MIPSCPU *cpu;
20050    CPUMIPSState *env;
20051    const mips_def_t *def;
20052
20053    def = cpu_mips_find_by_name(cpu_model);
20054    if (!def)
20055        return NULL;
20056    cpu = MIPS_CPU(object_new(TYPE_MIPS_CPU));
20057    env = &cpu->env;
20058    env->cpu_model = def;
20059
20060#ifndef CONFIG_USER_ONLY
20061    mmu_init(env, def);
20062#endif
20063    fpu_init(env, def);
20064    mvp_init(env, def);
20065
20066    object_property_set_bool(OBJECT(cpu), true, "realized", NULL);
20067
20068    return cpu;
20069}
20070
20071bool cpu_supports_cps_smp(const char *cpu_model)
20072{
20073    const mips_def_t *def = cpu_mips_find_by_name(cpu_model);
20074    if (!def) {
20075        return false;
20076    }
20077
20078    return (def->CP0_Config3 & (1 << CP0C3_CMGCR)) != 0;
20079}
20080
20081void cpu_state_reset(CPUMIPSState *env)
20082{
20083    MIPSCPU *cpu = mips_env_get_cpu(env);
20084    CPUState *cs = CPU(cpu);
20085
20086    /* Reset registers to their default values */
20087    env->CP0_PRid = env->cpu_model->CP0_PRid;
20088    env->CP0_Config0 = env->cpu_model->CP0_Config0;
20089#ifdef TARGET_WORDS_BIGENDIAN
20090    env->CP0_Config0 |= (1 << CP0C0_BE);
20091#endif
20092    env->CP0_Config1 = env->cpu_model->CP0_Config1;
20093    env->CP0_Config2 = env->cpu_model->CP0_Config2;
20094    env->CP0_Config3 = env->cpu_model->CP0_Config3;
20095    env->CP0_Config4 = env->cpu_model->CP0_Config4;
20096    env->CP0_Config4_rw_bitmask = env->cpu_model->CP0_Config4_rw_bitmask;
20097    env->CP0_Config5 = env->cpu_model->CP0_Config5;
20098    env->CP0_Config5_rw_bitmask = env->cpu_model->CP0_Config5_rw_bitmask;
20099    env->CP0_Config6 = env->cpu_model->CP0_Config6;
20100    env->CP0_Config7 = env->cpu_model->CP0_Config7;
20101    env->CP0_LLAddr_rw_bitmask = env->cpu_model->CP0_LLAddr_rw_bitmask
20102                                 << env->cpu_model->CP0_LLAddr_shift;
20103    env->CP0_LLAddr_shift = env->cpu_model->CP0_LLAddr_shift;
20104    env->SYNCI_Step = env->cpu_model->SYNCI_Step;
20105    env->CCRes = env->cpu_model->CCRes;
20106    env->CP0_Status_rw_bitmask = env->cpu_model->CP0_Status_rw_bitmask;
20107    env->CP0_TCStatus_rw_bitmask = env->cpu_model->CP0_TCStatus_rw_bitmask;
20108    env->CP0_SRSCtl = env->cpu_model->CP0_SRSCtl;
20109    env->current_tc = 0;
20110    env->SEGBITS = env->cpu_model->SEGBITS;
20111    env->SEGMask = (target_ulong)((1ULL << env->cpu_model->SEGBITS) - 1);
20112#if defined(TARGET_MIPS64)
20113    if (env->cpu_model->insn_flags & ISA_MIPS3) {
20114        env->SEGMask |= 3ULL << 62;
20115    }
20116#endif
20117    env->PABITS = env->cpu_model->PABITS;
20118    env->CP0_SRSConf0_rw_bitmask = env->cpu_model->CP0_SRSConf0_rw_bitmask;
20119    env->CP0_SRSConf0 = env->cpu_model->CP0_SRSConf0;
20120    env->CP0_SRSConf1_rw_bitmask = env->cpu_model->CP0_SRSConf1_rw_bitmask;
20121    env->CP0_SRSConf1 = env->cpu_model->CP0_SRSConf1;
20122    env->CP0_SRSConf2_rw_bitmask = env->cpu_model->CP0_SRSConf2_rw_bitmask;
20123    env->CP0_SRSConf2 = env->cpu_model->CP0_SRSConf2;
20124    env->CP0_SRSConf3_rw_bitmask = env->cpu_model->CP0_SRSConf3_rw_bitmask;
20125    env->CP0_SRSConf3 = env->cpu_model->CP0_SRSConf3;
20126    env->CP0_SRSConf4_rw_bitmask = env->cpu_model->CP0_SRSConf4_rw_bitmask;
20127    env->CP0_SRSConf4 = env->cpu_model->CP0_SRSConf4;
20128    env->CP0_PageGrain_rw_bitmask = env->cpu_model->CP0_PageGrain_rw_bitmask;
20129    env->CP0_PageGrain = env->cpu_model->CP0_PageGrain;
20130    env->active_fpu.fcr0 = env->cpu_model->CP1_fcr0;
20131    env->active_fpu.fcr31 = env->cpu_model->CP1_fcr31;
20132    env->msair = env->cpu_model->MSAIR;
20133    env->insn_flags = env->cpu_model->insn_flags;
20134
20135#if defined(CONFIG_USER_ONLY)
20136    env->CP0_Status = (MIPS_HFLAG_UM << CP0St_KSU);
20137# ifdef TARGET_MIPS64
20138    /* Enable 64-bit register mode.  */
20139    env->CP0_Status |= (1 << CP0St_PX);
20140# endif
20141# ifdef TARGET_ABI_MIPSN64
20142    /* Enable 64-bit address mode.  */
20143    env->CP0_Status |= (1 << CP0St_UX);
20144# endif
20145    /* Enable access to the CPUNum, SYNCI_Step, CC, and CCRes RDHWR
20146       hardware registers.  */
20147    env->CP0_HWREna |= 0x0000000F;
20148    if (env->CP0_Config1 & (1 << CP0C1_FP)) {
20149        env->CP0_Status |= (1 << CP0St_CU1);
20150    }
20151    if (env->CP0_Config3 & (1 << CP0C3_DSPP)) {
20152        env->CP0_Status |= (1 << CP0St_MX);
20153    }
20154# if defined(TARGET_MIPS64)
20155    /* For MIPS64, init FR bit to 1 if FPU unit is there and bit is writable. */
20156    if ((env->CP0_Config1 & (1 << CP0C1_FP)) &&
20157        (env->CP0_Status_rw_bitmask & (1 << CP0St_FR))) {
20158        env->CP0_Status |= (1 << CP0St_FR);
20159    }
20160# endif
20161#else
20162    if (env->hflags & MIPS_HFLAG_BMASK) {
20163        /* If the exception was raised from a delay slot,
20164           come back to the jump.  */
20165        env->CP0_ErrorEPC = (env->active_tc.PC
20166                             - (env->hflags & MIPS_HFLAG_B16 ? 2 : 4));
20167    } else {
20168        env->CP0_ErrorEPC = env->active_tc.PC;
20169    }
20170    env->active_tc.PC = (int32_t)0xBFC00000;
20171    env->CP0_Random = env->tlb->nb_tlb - 1;
20172    env->tlb->tlb_in_use = env->tlb->nb_tlb;
20173    env->CP0_Wired = 0;
20174    env->CP0_GlobalNumber = (cs->cpu_index & 0xFF) << CP0GN_VPId;
20175    env->CP0_EBase = (cs->cpu_index & 0x3FF);
20176    if (kvm_enabled()) {
20177        env->CP0_EBase |= 0x40000000;
20178    } else {
20179        env->CP0_EBase |= 0x80000000;
20180    }
20181    if (env->CP0_Config3 & (1 << CP0C3_CMGCR)) {
20182        env->CP0_CMGCRBase = 0x1fbf8000 >> 4;
20183    }
20184    env->CP0_Status = (1 << CP0St_BEV) | (1 << CP0St_ERL);
20185    /* vectored interrupts not implemented, timer on int 7,
20186       no performance counters. */
20187    env->CP0_IntCtl = 0xe0000000;
20188    {
20189        int i;
20190
20191        for (i = 0; i < 7; i++) {
20192            env->CP0_WatchLo[i] = 0;
20193            env->CP0_WatchHi[i] = 0x80000000;
20194        }
20195        env->CP0_WatchLo[7] = 0;
20196        env->CP0_WatchHi[7] = 0;
20197    }
20198    /* Count register increments in debug mode, EJTAG version 1 */
20199    env->CP0_Debug = (1 << CP0DB_CNT) | (0x1 << CP0DB_VER);
20200
20201    cpu_mips_store_count(env, 1);
20202
20203    if (env->CP0_Config3 & (1 << CP0C3_MT)) {
20204        int i;
20205
20206        /* Only TC0 on VPE 0 starts as active.  */
20207        for (i = 0; i < ARRAY_SIZE(env->tcs); i++) {
20208            env->tcs[i].CP0_TCBind = cs->cpu_index << CP0TCBd_CurVPE;
20209            env->tcs[i].CP0_TCHalt = 1;
20210        }
20211        env->active_tc.CP0_TCHalt = 1;
20212        cs->halted = 1;
20213
20214        if (cs->cpu_index == 0) {
20215            /* VPE0 starts up enabled.  */
20216            env->mvp->CP0_MVPControl |= (1 << CP0MVPCo_EVP);
20217            env->CP0_VPEConf0 |= (1 << CP0VPEC0_MVP) | (1 << CP0VPEC0_VPA);
20218
20219            /* TC0 starts up unhalted.  */
20220            cs->halted = 0;
20221            env->active_tc.CP0_TCHalt = 0;
20222            env->tcs[0].CP0_TCHalt = 0;
20223            /* With thread 0 active.  */
20224            env->active_tc.CP0_TCStatus = (1 << CP0TCSt_A);
20225            env->tcs[0].CP0_TCStatus = (1 << CP0TCSt_A);
20226        }
20227    }
20228#endif
20229    if ((env->insn_flags & ISA_MIPS32R6) &&
20230        (env->active_fpu.fcr0 & (1 << FCR0_F64))) {
20231        /* Status.FR = 0 mode in 64-bit FPU not allowed in R6 */
20232        env->CP0_Status |= (1 << CP0St_FR);
20233    }
20234
20235    /* MSA */
20236    if (env->CP0_Config3 & (1 << CP0C3_MSAP)) {
20237        msa_reset(env);
20238    }
20239
20240    compute_hflags(env);
20241    restore_rounding_mode(env);
20242    restore_flush_mode(env);
20243    restore_pamask(env);
20244    cs->exception_index = EXCP_NONE;
20245
20246    if (semihosting_get_argc()) {
20247        /* UHI interface can be used to obtain argc and argv */
20248        env->active_tc.gpr[4] = -1;
20249    }
20250}
20251
20252void restore_state_to_opc(CPUMIPSState *env, TranslationBlock *tb,
20253                          target_ulong *data)
20254{
20255    env->active_tc.PC = data[0];
20256    env->hflags &= ~MIPS_HFLAG_BMASK;
20257    env->hflags |= data[1];
20258    switch (env->hflags & MIPS_HFLAG_BMASK_BASE) {
20259    case MIPS_HFLAG_BR:
20260        break;
20261    case MIPS_HFLAG_BC:
20262    case MIPS_HFLAG_BL:
20263    case MIPS_HFLAG_B:
20264        env->btarget = data[2];
20265        break;
20266    }
20267}
20268