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 "internal.h"
  27#include "disas/disas.h"
  28#include "exec/exec-all.h"
  29#include "tcg-op.h"
  30#include "exec/cpu_ldst.h"
  31#include "hw/mips/cpudevs.h"
  32
  33#include "exec/helper-proto.h"
  34#include "exec/helper-gen.h"
  35#include "exec/semihost.h"
  36
  37#include "target/mips/trace.h"
  38#include "trace-tcg.h"
  39#include "exec/log.h"
  40
  41#define MIPS_DEBUG_DISAS 0
  42
  43/* MIPS major opcodes */
  44#define MASK_OP_MAJOR(op)  (op & (0x3F << 26))
  45
  46enum {
  47    /* indirect opcode tables */
  48    OPC_SPECIAL  = (0x00 << 26),
  49    OPC_REGIMM   = (0x01 << 26),
  50    OPC_CP0      = (0x10 << 26),
  51    OPC_CP1      = (0x11 << 26),
  52    OPC_CP2      = (0x12 << 26),
  53    OPC_CP3      = (0x13 << 26),
  54    OPC_SPECIAL2 = (0x1C << 26),
  55    OPC_SPECIAL3 = (0x1F << 26),
  56    /* arithmetic with immediate */
  57    OPC_ADDI     = (0x08 << 26),
  58    OPC_ADDIU    = (0x09 << 26),
  59    OPC_SLTI     = (0x0A << 26),
  60    OPC_SLTIU    = (0x0B << 26),
  61    /* logic with immediate */
  62    OPC_ANDI     = (0x0C << 26),
  63    OPC_ORI      = (0x0D << 26),
  64    OPC_XORI     = (0x0E << 26),
  65    OPC_LUI      = (0x0F << 26),
  66    /* arithmetic with immediate */
  67    OPC_DADDI    = (0x18 << 26),
  68    OPC_DADDIU   = (0x19 << 26),
  69    /* Jump and branches */
  70    OPC_J        = (0x02 << 26),
  71    OPC_JAL      = (0x03 << 26),
  72    OPC_BEQ      = (0x04 << 26),  /* Unconditional if rs = rt = 0 (B) */
  73    OPC_BEQL     = (0x14 << 26),
  74    OPC_BNE      = (0x05 << 26),
  75    OPC_BNEL     = (0x15 << 26),
  76    OPC_BLEZ     = (0x06 << 26),
  77    OPC_BLEZL    = (0x16 << 26),
  78    OPC_BGTZ     = (0x07 << 26),
  79    OPC_BGTZL    = (0x17 << 26),
  80    OPC_JALX     = (0x1D << 26),
  81    OPC_DAUI     = (0x1D << 26),
  82    /* Load and stores */
  83    OPC_LDL      = (0x1A << 26),
  84    OPC_LDR      = (0x1B << 26),
  85    OPC_LB       = (0x20 << 26),
  86    OPC_LH       = (0x21 << 26),
  87    OPC_LWL      = (0x22 << 26),
  88    OPC_LW       = (0x23 << 26),
  89    OPC_LWPC     = OPC_LW | 0x5,
  90    OPC_LBU      = (0x24 << 26),
  91    OPC_LHU      = (0x25 << 26),
  92    OPC_LWR      = (0x26 << 26),
  93    OPC_LWU      = (0x27 << 26),
  94    OPC_SB       = (0x28 << 26),
  95    OPC_SH       = (0x29 << 26),
  96    OPC_SWL      = (0x2A << 26),
  97    OPC_SW       = (0x2B << 26),
  98    OPC_SDL      = (0x2C << 26),
  99    OPC_SDR      = (0x2D << 26),
 100    OPC_SWR      = (0x2E << 26),
 101    OPC_LL       = (0x30 << 26),
 102    OPC_LLD      = (0x34 << 26),
 103    OPC_LD       = (0x37 << 26),
 104    OPC_LDPC     = OPC_LD | 0x5,
 105    OPC_SC       = (0x38 << 26),
 106    OPC_SCD      = (0x3C << 26),
 107    OPC_SD       = (0x3F << 26),
 108    /* Floating point load/store */
 109    OPC_LWC1     = (0x31 << 26),
 110    OPC_LWC2     = (0x32 << 26),
 111    OPC_LDC1     = (0x35 << 26),
 112    OPC_LDC2     = (0x36 << 26),
 113    OPC_SWC1     = (0x39 << 26),
 114    OPC_SWC2     = (0x3A << 26),
 115    OPC_SDC1     = (0x3D << 26),
 116    OPC_SDC2     = (0x3E << 26),
 117    /* Compact Branches */
 118    OPC_BLEZALC  = (0x06 << 26),
 119    OPC_BGEZALC  = (0x06 << 26),
 120    OPC_BGEUC    = (0x06 << 26),
 121    OPC_BGTZALC  = (0x07 << 26),
 122    OPC_BLTZALC  = (0x07 << 26),
 123    OPC_BLTUC    = (0x07 << 26),
 124    OPC_BOVC     = (0x08 << 26),
 125    OPC_BEQZALC  = (0x08 << 26),
 126    OPC_BEQC     = (0x08 << 26),
 127    OPC_BLEZC    = (0x16 << 26),
 128    OPC_BGEZC    = (0x16 << 26),
 129    OPC_BGEC     = (0x16 << 26),
 130    OPC_BGTZC    = (0x17 << 26),
 131    OPC_BLTZC    = (0x17 << 26),
 132    OPC_BLTC     = (0x17 << 26),
 133    OPC_BNVC     = (0x18 << 26),
 134    OPC_BNEZALC  = (0x18 << 26),
 135    OPC_BNEC     = (0x18 << 26),
 136    OPC_BC       = (0x32 << 26),
 137    OPC_BEQZC    = (0x36 << 26),
 138    OPC_JIC      = (0x36 << 26),
 139    OPC_BALC     = (0x3A << 26),
 140    OPC_BNEZC    = (0x3E << 26),
 141    OPC_JIALC    = (0x3E << 26),
 142    /* MDMX ASE specific */
 143    OPC_MDMX     = (0x1E << 26),
 144    /* MSA ASE, same as MDMX */
 145    OPC_MSA      = OPC_MDMX,
 146    /* Cache and prefetch */
 147    OPC_CACHE    = (0x2F << 26),
 148    OPC_PREF     = (0x33 << 26),
 149    /* PC-relative address computation / loads */
 150    OPC_PCREL    = (0x3B << 26),
 151};
 152
 153/* PC-relative address computation / loads  */
 154#define MASK_OPC_PCREL_TOP2BITS(op)  (MASK_OP_MAJOR(op) | (op & (3 << 19)))
 155#define MASK_OPC_PCREL_TOP5BITS(op)  (MASK_OP_MAJOR(op) | (op & (0x1f << 16)))
 156enum {
 157    /* Instructions determined by bits 19 and 20 */
 158    OPC_ADDIUPC = OPC_PCREL | (0 << 19),
 159    R6_OPC_LWPC = OPC_PCREL | (1 << 19),
 160    OPC_LWUPC   = OPC_PCREL | (2 << 19),
 161
 162    /* Instructions determined by bits 16 ... 20 */
 163    OPC_AUIPC   = OPC_PCREL | (0x1e << 16),
 164    OPC_ALUIPC  = OPC_PCREL | (0x1f << 16),
 165
 166    /* Other */
 167    R6_OPC_LDPC = OPC_PCREL | (6 << 18),
 168};
 169
 170/* MIPS special opcodes */
 171#define MASK_SPECIAL(op)   MASK_OP_MAJOR(op) | (op & 0x3F)
 172
 173enum {
 174    /* Shifts */
 175    OPC_SLL      = 0x00 | OPC_SPECIAL,
 176    /* NOP is SLL r0, r0, 0   */
 177    /* SSNOP is SLL r0, r0, 1 */
 178    /* EHB is SLL r0, r0, 3 */
 179    OPC_SRL      = 0x02 | OPC_SPECIAL, /* also ROTR */
 180    OPC_ROTR     = OPC_SRL | (1 << 21),
 181    OPC_SRA      = 0x03 | OPC_SPECIAL,
 182    OPC_SLLV     = 0x04 | OPC_SPECIAL,
 183    OPC_SRLV     = 0x06 | OPC_SPECIAL, /* also ROTRV */
 184    OPC_ROTRV    = OPC_SRLV | (1 << 6),
 185    OPC_SRAV     = 0x07 | OPC_SPECIAL,
 186    OPC_DSLLV    = 0x14 | OPC_SPECIAL,
 187    OPC_DSRLV    = 0x16 | OPC_SPECIAL, /* also DROTRV */
 188    OPC_DROTRV   = OPC_DSRLV | (1 << 6),
 189    OPC_DSRAV    = 0x17 | OPC_SPECIAL,
 190    OPC_DSLL     = 0x38 | OPC_SPECIAL,
 191    OPC_DSRL     = 0x3A | OPC_SPECIAL, /* also DROTR */
 192    OPC_DROTR    = OPC_DSRL | (1 << 21),
 193    OPC_DSRA     = 0x3B | OPC_SPECIAL,
 194    OPC_DSLL32   = 0x3C | OPC_SPECIAL,
 195    OPC_DSRL32   = 0x3E | OPC_SPECIAL, /* also DROTR32 */
 196    OPC_DROTR32  = OPC_DSRL32 | (1 << 21),
 197    OPC_DSRA32   = 0x3F | OPC_SPECIAL,
 198    /* Multiplication / division */
 199    OPC_MULT     = 0x18 | OPC_SPECIAL,
 200    OPC_MULTU    = 0x19 | OPC_SPECIAL,
 201    OPC_DIV      = 0x1A | OPC_SPECIAL,
 202    OPC_DIVU     = 0x1B | OPC_SPECIAL,
 203    OPC_DMULT    = 0x1C | OPC_SPECIAL,
 204    OPC_DMULTU   = 0x1D | OPC_SPECIAL,
 205    OPC_DDIV     = 0x1E | OPC_SPECIAL,
 206    OPC_DDIVU    = 0x1F | OPC_SPECIAL,
 207
 208    /* 2 registers arithmetic / logic */
 209    OPC_ADD      = 0x20 | OPC_SPECIAL,
 210    OPC_ADDU     = 0x21 | OPC_SPECIAL,
 211    OPC_SUB      = 0x22 | OPC_SPECIAL,
 212    OPC_SUBU     = 0x23 | OPC_SPECIAL,
 213    OPC_AND      = 0x24 | OPC_SPECIAL,
 214    OPC_OR       = 0x25 | OPC_SPECIAL,
 215    OPC_XOR      = 0x26 | OPC_SPECIAL,
 216    OPC_NOR      = 0x27 | OPC_SPECIAL,
 217    OPC_SLT      = 0x2A | OPC_SPECIAL,
 218    OPC_SLTU     = 0x2B | OPC_SPECIAL,
 219    OPC_DADD     = 0x2C | OPC_SPECIAL,
 220    OPC_DADDU    = 0x2D | OPC_SPECIAL,
 221    OPC_DSUB     = 0x2E | OPC_SPECIAL,
 222    OPC_DSUBU    = 0x2F | OPC_SPECIAL,
 223    /* Jumps */
 224    OPC_JR       = 0x08 | OPC_SPECIAL, /* Also JR.HB */
 225    OPC_JALR     = 0x09 | OPC_SPECIAL, /* Also JALR.HB */
 226    /* Traps */
 227    OPC_TGE      = 0x30 | OPC_SPECIAL,
 228    OPC_TGEU     = 0x31 | OPC_SPECIAL,
 229    OPC_TLT      = 0x32 | OPC_SPECIAL,
 230    OPC_TLTU     = 0x33 | OPC_SPECIAL,
 231    OPC_TEQ      = 0x34 | OPC_SPECIAL,
 232    OPC_TNE      = 0x36 | OPC_SPECIAL,
 233    /* HI / LO registers load & stores */
 234    OPC_MFHI     = 0x10 | OPC_SPECIAL,
 235    OPC_MTHI     = 0x11 | OPC_SPECIAL,
 236    OPC_MFLO     = 0x12 | OPC_SPECIAL,
 237    OPC_MTLO     = 0x13 | OPC_SPECIAL,
 238    /* Conditional moves */
 239    OPC_MOVZ     = 0x0A | OPC_SPECIAL,
 240    OPC_MOVN     = 0x0B | OPC_SPECIAL,
 241
 242    OPC_SELEQZ   = 0x35 | OPC_SPECIAL,
 243    OPC_SELNEZ   = 0x37 | OPC_SPECIAL,
 244
 245    OPC_MOVCI    = 0x01 | OPC_SPECIAL,
 246
 247    /* Special */
 248    OPC_PMON     = 0x05 | OPC_SPECIAL, /* unofficial */
 249    OPC_SYSCALL  = 0x0C | OPC_SPECIAL,
 250    OPC_BREAK    = 0x0D | OPC_SPECIAL,
 251    OPC_SPIM     = 0x0E | OPC_SPECIAL, /* unofficial */
 252    OPC_SYNC     = 0x0F | OPC_SPECIAL,
 253
 254    OPC_SPECIAL28_RESERVED = 0x28 | OPC_SPECIAL,
 255    OPC_SPECIAL29_RESERVED = 0x29 | OPC_SPECIAL,
 256    OPC_SPECIAL39_RESERVED = 0x39 | OPC_SPECIAL,
 257    OPC_SPECIAL3D_RESERVED = 0x3D | OPC_SPECIAL,
 258};
 259
 260/* R6 Multiply and Divide instructions have the same Opcode
 261   and function field as legacy OPC_MULT[U]/OPC_DIV[U] */
 262#define MASK_R6_MULDIV(op)   (MASK_SPECIAL(op) | (op & (0x7ff)))
 263
 264enum {
 265    R6_OPC_MUL   = OPC_MULT  | (2 << 6),
 266    R6_OPC_MUH   = OPC_MULT  | (3 << 6),
 267    R6_OPC_MULU  = OPC_MULTU | (2 << 6),
 268    R6_OPC_MUHU  = OPC_MULTU | (3 << 6),
 269    R6_OPC_DIV   = OPC_DIV   | (2 << 6),
 270    R6_OPC_MOD   = OPC_DIV   | (3 << 6),
 271    R6_OPC_DIVU  = OPC_DIVU  | (2 << 6),
 272    R6_OPC_MODU  = OPC_DIVU  | (3 << 6),
 273
 274    R6_OPC_DMUL   = OPC_DMULT  | (2 << 6),
 275    R6_OPC_DMUH   = OPC_DMULT  | (3 << 6),
 276    R6_OPC_DMULU  = OPC_DMULTU | (2 << 6),
 277    R6_OPC_DMUHU  = OPC_DMULTU | (3 << 6),
 278    R6_OPC_DDIV   = OPC_DDIV   | (2 << 6),
 279    R6_OPC_DMOD   = OPC_DDIV   | (3 << 6),
 280    R6_OPC_DDIVU  = OPC_DDIVU  | (2 << 6),
 281    R6_OPC_DMODU  = OPC_DDIVU  | (3 << 6),
 282
 283    R6_OPC_CLZ      = 0x10 | OPC_SPECIAL,
 284    R6_OPC_CLO      = 0x11 | OPC_SPECIAL,
 285    R6_OPC_DCLZ     = 0x12 | OPC_SPECIAL,
 286    R6_OPC_DCLO     = 0x13 | OPC_SPECIAL,
 287    R6_OPC_SDBBP    = 0x0e | OPC_SPECIAL,
 288
 289    OPC_LSA  = 0x05 | OPC_SPECIAL,
 290    OPC_DLSA = 0x15 | OPC_SPECIAL,
 291};
 292
 293/* Multiplication variants of the vr54xx. */
 294#define MASK_MUL_VR54XX(op)   MASK_SPECIAL(op) | (op & (0x1F << 6))
 295
 296enum {
 297    OPC_VR54XX_MULS    = (0x03 << 6) | OPC_MULT,
 298    OPC_VR54XX_MULSU   = (0x03 << 6) | OPC_MULTU,
 299    OPC_VR54XX_MACC    = (0x05 << 6) | OPC_MULT,
 300    OPC_VR54XX_MACCU   = (0x05 << 6) | OPC_MULTU,
 301    OPC_VR54XX_MSAC    = (0x07 << 6) | OPC_MULT,
 302    OPC_VR54XX_MSACU   = (0x07 << 6) | OPC_MULTU,
 303    OPC_VR54XX_MULHI   = (0x09 << 6) | OPC_MULT,
 304    OPC_VR54XX_MULHIU  = (0x09 << 6) | OPC_MULTU,
 305    OPC_VR54XX_MULSHI  = (0x0B << 6) | OPC_MULT,
 306    OPC_VR54XX_MULSHIU = (0x0B << 6) | OPC_MULTU,
 307    OPC_VR54XX_MACCHI  = (0x0D << 6) | OPC_MULT,
 308    OPC_VR54XX_MACCHIU = (0x0D << 6) | OPC_MULTU,
 309    OPC_VR54XX_MSACHI  = (0x0F << 6) | OPC_MULT,
 310    OPC_VR54XX_MSACHIU = (0x0F << 6) | OPC_MULTU,
 311};
 312
 313/* REGIMM (rt field) opcodes */
 314#define MASK_REGIMM(op)    MASK_OP_MAJOR(op) | (op & (0x1F << 16))
 315
 316enum {
 317    OPC_BLTZ     = (0x00 << 16) | OPC_REGIMM,
 318    OPC_BLTZL    = (0x02 << 16) | OPC_REGIMM,
 319    OPC_BGEZ     = (0x01 << 16) | OPC_REGIMM,
 320    OPC_BGEZL    = (0x03 << 16) | OPC_REGIMM,
 321    OPC_BLTZAL   = (0x10 << 16) | OPC_REGIMM,
 322    OPC_BLTZALL  = (0x12 << 16) | OPC_REGIMM,
 323    OPC_BGEZAL   = (0x11 << 16) | OPC_REGIMM,
 324    OPC_BGEZALL  = (0x13 << 16) | OPC_REGIMM,
 325    OPC_TGEI     = (0x08 << 16) | OPC_REGIMM,
 326    OPC_TGEIU    = (0x09 << 16) | OPC_REGIMM,
 327    OPC_TLTI     = (0x0A << 16) | OPC_REGIMM,
 328    OPC_TLTIU    = (0x0B << 16) | OPC_REGIMM,
 329    OPC_TEQI     = (0x0C << 16) | OPC_REGIMM,
 330    OPC_TNEI     = (0x0E << 16) | OPC_REGIMM,
 331    OPC_SIGRIE   = (0x17 << 16) | OPC_REGIMM,
 332    OPC_SYNCI    = (0x1F << 16) | OPC_REGIMM,
 333
 334    OPC_DAHI     = (0x06 << 16) | OPC_REGIMM,
 335    OPC_DATI     = (0x1e << 16) | OPC_REGIMM,
 336};
 337
 338/* Special2 opcodes */
 339#define MASK_SPECIAL2(op)  MASK_OP_MAJOR(op) | (op & 0x3F)
 340
 341enum {
 342    /* Multiply & xxx operations */
 343    OPC_MADD     = 0x00 | OPC_SPECIAL2,
 344    OPC_MADDU    = 0x01 | OPC_SPECIAL2,
 345    OPC_MUL      = 0x02 | OPC_SPECIAL2,
 346    OPC_MSUB     = 0x04 | OPC_SPECIAL2,
 347    OPC_MSUBU    = 0x05 | OPC_SPECIAL2,
 348    /* Loongson 2F */
 349    OPC_MULT_G_2F   = 0x10 | OPC_SPECIAL2,
 350    OPC_DMULT_G_2F  = 0x11 | OPC_SPECIAL2,
 351    OPC_MULTU_G_2F  = 0x12 | OPC_SPECIAL2,
 352    OPC_DMULTU_G_2F = 0x13 | OPC_SPECIAL2,
 353    OPC_DIV_G_2F    = 0x14 | OPC_SPECIAL2,
 354    OPC_DDIV_G_2F   = 0x15 | OPC_SPECIAL2,
 355    OPC_DIVU_G_2F   = 0x16 | OPC_SPECIAL2,
 356    OPC_DDIVU_G_2F  = 0x17 | OPC_SPECIAL2,
 357    OPC_MOD_G_2F    = 0x1c | OPC_SPECIAL2,
 358    OPC_DMOD_G_2F   = 0x1d | OPC_SPECIAL2,
 359    OPC_MODU_G_2F   = 0x1e | OPC_SPECIAL2,
 360    OPC_DMODU_G_2F  = 0x1f | OPC_SPECIAL2,
 361    /* Misc */
 362    OPC_CLZ      = 0x20 | OPC_SPECIAL2,
 363    OPC_CLO      = 0x21 | OPC_SPECIAL2,
 364    OPC_DCLZ     = 0x24 | OPC_SPECIAL2,
 365    OPC_DCLO     = 0x25 | OPC_SPECIAL2,
 366    /* Special */
 367    OPC_SDBBP    = 0x3F | OPC_SPECIAL2,
 368};
 369
 370/* Special3 opcodes */
 371#define MASK_SPECIAL3(op)  MASK_OP_MAJOR(op) | (op & 0x3F)
 372
 373enum {
 374    OPC_EXT      = 0x00 | OPC_SPECIAL3,
 375    OPC_DEXTM    = 0x01 | OPC_SPECIAL3,
 376    OPC_DEXTU    = 0x02 | OPC_SPECIAL3,
 377    OPC_DEXT     = 0x03 | OPC_SPECIAL3,
 378    OPC_INS      = 0x04 | OPC_SPECIAL3,
 379    OPC_DINSM    = 0x05 | OPC_SPECIAL3,
 380    OPC_DINSU    = 0x06 | OPC_SPECIAL3,
 381    OPC_DINS     = 0x07 | OPC_SPECIAL3,
 382    OPC_FORK     = 0x08 | OPC_SPECIAL3,
 383    OPC_YIELD    = 0x09 | OPC_SPECIAL3,
 384    OPC_BSHFL    = 0x20 | OPC_SPECIAL3,
 385    OPC_DBSHFL   = 0x24 | OPC_SPECIAL3,
 386    OPC_RDHWR    = 0x3B | OPC_SPECIAL3,
 387
 388    /* Loongson 2E */
 389    OPC_MULT_G_2E   = 0x18 | OPC_SPECIAL3,
 390    OPC_MULTU_G_2E  = 0x19 | OPC_SPECIAL3,
 391    OPC_DIV_G_2E    = 0x1A | OPC_SPECIAL3,
 392    OPC_DIVU_G_2E   = 0x1B | OPC_SPECIAL3,
 393    OPC_DMULT_G_2E  = 0x1C | OPC_SPECIAL3,
 394    OPC_DMULTU_G_2E = 0x1D | OPC_SPECIAL3,
 395    OPC_DDIV_G_2E   = 0x1E | OPC_SPECIAL3,
 396    OPC_DDIVU_G_2E  = 0x1F | OPC_SPECIAL3,
 397    OPC_MOD_G_2E    = 0x22 | OPC_SPECIAL3,
 398    OPC_MODU_G_2E   = 0x23 | OPC_SPECIAL3,
 399    OPC_DMOD_G_2E   = 0x26 | OPC_SPECIAL3,
 400    OPC_DMODU_G_2E  = 0x27 | OPC_SPECIAL3,
 401
 402    /* MIPS DSP Load */
 403    OPC_LX_DSP         = 0x0A | OPC_SPECIAL3,
 404    /* MIPS DSP Arithmetic */
 405    OPC_ADDU_QB_DSP    = 0x10 | OPC_SPECIAL3,
 406    OPC_ADDU_OB_DSP    = 0x14 | OPC_SPECIAL3,
 407    OPC_ABSQ_S_PH_DSP  = 0x12 | OPC_SPECIAL3,
 408    OPC_ABSQ_S_QH_DSP  = 0x16 | OPC_SPECIAL3,
 409    /* OPC_ADDUH_QB_DSP is same as OPC_MULT_G_2E.  */
 410    /* OPC_ADDUH_QB_DSP   = 0x18 | OPC_SPECIAL3,  */
 411    OPC_CMPU_EQ_QB_DSP = 0x11 | OPC_SPECIAL3,
 412    OPC_CMPU_EQ_OB_DSP = 0x15 | OPC_SPECIAL3,
 413    /* MIPS DSP GPR-Based Shift Sub-class */
 414    OPC_SHLL_QB_DSP    = 0x13 | OPC_SPECIAL3,
 415    OPC_SHLL_OB_DSP    = 0x17 | OPC_SPECIAL3,
 416    /* MIPS DSP Multiply Sub-class insns */
 417    /* OPC_MUL_PH_DSP is same as OPC_ADDUH_QB_DSP.  */
 418    /* OPC_MUL_PH_DSP     = 0x18 | OPC_SPECIAL3,  */
 419    OPC_DPA_W_PH_DSP   = 0x30 | OPC_SPECIAL3,
 420    OPC_DPAQ_W_QH_DSP  = 0x34 | OPC_SPECIAL3,
 421    /* DSP Bit/Manipulation Sub-class */
 422    OPC_INSV_DSP       = 0x0C | OPC_SPECIAL3,
 423    OPC_DINSV_DSP      = 0x0D | OPC_SPECIAL3,
 424    /* MIPS DSP Append Sub-class */
 425    OPC_APPEND_DSP     = 0x31 | OPC_SPECIAL3,
 426    OPC_DAPPEND_DSP    = 0x35 | OPC_SPECIAL3,
 427    /* MIPS DSP Accumulator and DSPControl Access Sub-class */
 428    OPC_EXTR_W_DSP     = 0x38 | OPC_SPECIAL3,
 429    OPC_DEXTR_W_DSP    = 0x3C | OPC_SPECIAL3,
 430
 431    /* EVA */
 432    OPC_LWLE           = 0x19 | OPC_SPECIAL3,
 433    OPC_LWRE           = 0x1A | OPC_SPECIAL3,
 434    OPC_CACHEE         = 0x1B | OPC_SPECIAL3,
 435    OPC_SBE            = 0x1C | OPC_SPECIAL3,
 436    OPC_SHE            = 0x1D | OPC_SPECIAL3,
 437    OPC_SCE            = 0x1E | OPC_SPECIAL3,
 438    OPC_SWE            = 0x1F | OPC_SPECIAL3,
 439    OPC_SWLE           = 0x21 | OPC_SPECIAL3,
 440    OPC_SWRE           = 0x22 | OPC_SPECIAL3,
 441    OPC_PREFE          = 0x23 | OPC_SPECIAL3,
 442    OPC_LBUE           = 0x28 | OPC_SPECIAL3,
 443    OPC_LHUE           = 0x29 | OPC_SPECIAL3,
 444    OPC_LBE            = 0x2C | OPC_SPECIAL3,
 445    OPC_LHE            = 0x2D | OPC_SPECIAL3,
 446    OPC_LLE            = 0x2E | OPC_SPECIAL3,
 447    OPC_LWE            = 0x2F | OPC_SPECIAL3,
 448
 449    /* R6 */
 450    R6_OPC_PREF        = 0x35 | OPC_SPECIAL3,
 451    R6_OPC_CACHE       = 0x25 | OPC_SPECIAL3,
 452    R6_OPC_LL          = 0x36 | OPC_SPECIAL3,
 453    R6_OPC_SC          = 0x26 | OPC_SPECIAL3,
 454    R6_OPC_LLD         = 0x37 | OPC_SPECIAL3,
 455    R6_OPC_SCD         = 0x27 | OPC_SPECIAL3,
 456};
 457
 458/* BSHFL opcodes */
 459#define MASK_BSHFL(op)     MASK_SPECIAL3(op) | (op & (0x1F << 6))
 460
 461enum {
 462    OPC_WSBH      = (0x02 << 6) | OPC_BSHFL,
 463    OPC_SEB       = (0x10 << 6) | OPC_BSHFL,
 464    OPC_SEH       = (0x18 << 6) | OPC_BSHFL,
 465    OPC_ALIGN     = (0x08 << 6) | OPC_BSHFL, /* 010.bp */
 466    OPC_ALIGN_END = (0x0B << 6) | OPC_BSHFL, /* 010.00 to 010.11 */
 467    OPC_BITSWAP   = (0x00 << 6) | OPC_BSHFL  /* 00000 */
 468};
 469
 470/* DBSHFL opcodes */
 471#define MASK_DBSHFL(op)    MASK_SPECIAL3(op) | (op & (0x1F << 6))
 472
 473enum {
 474    OPC_DSBH       = (0x02 << 6) | OPC_DBSHFL,
 475    OPC_DSHD       = (0x05 << 6) | OPC_DBSHFL,
 476    OPC_DALIGN     = (0x08 << 6) | OPC_DBSHFL, /* 01.bp */
 477    OPC_DALIGN_END = (0x0F << 6) | OPC_DBSHFL, /* 01.000 to 01.111 */
 478    OPC_DBITSWAP   = (0x00 << 6) | OPC_DBSHFL, /* 00000 */
 479};
 480
 481/* MIPS DSP REGIMM opcodes */
 482enum {
 483    OPC_BPOSGE32 = (0x1C << 16) | OPC_REGIMM,
 484    OPC_BPOSGE64 = (0x1D << 16) | OPC_REGIMM,
 485};
 486
 487#define MASK_LX(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
 488/* MIPS DSP Load */
 489enum {
 490    OPC_LBUX = (0x06 << 6) | OPC_LX_DSP,
 491    OPC_LHX  = (0x04 << 6) | OPC_LX_DSP,
 492    OPC_LWX  = (0x00 << 6) | OPC_LX_DSP,
 493    OPC_LDX = (0x08 << 6) | OPC_LX_DSP,
 494};
 495
 496#define MASK_ADDU_QB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
 497enum {
 498    /* MIPS DSP Arithmetic Sub-class */
 499    OPC_ADDQ_PH        = (0x0A << 6) | OPC_ADDU_QB_DSP,
 500    OPC_ADDQ_S_PH      = (0x0E << 6) | OPC_ADDU_QB_DSP,
 501    OPC_ADDQ_S_W       = (0x16 << 6) | OPC_ADDU_QB_DSP,
 502    OPC_ADDU_QB        = (0x00 << 6) | OPC_ADDU_QB_DSP,
 503    OPC_ADDU_S_QB      = (0x04 << 6) | OPC_ADDU_QB_DSP,
 504    OPC_ADDU_PH        = (0x08 << 6) | OPC_ADDU_QB_DSP,
 505    OPC_ADDU_S_PH      = (0x0C << 6) | OPC_ADDU_QB_DSP,
 506    OPC_SUBQ_PH        = (0x0B << 6) | OPC_ADDU_QB_DSP,
 507    OPC_SUBQ_S_PH      = (0x0F << 6) | OPC_ADDU_QB_DSP,
 508    OPC_SUBQ_S_W       = (0x17 << 6) | OPC_ADDU_QB_DSP,
 509    OPC_SUBU_QB        = (0x01 << 6) | OPC_ADDU_QB_DSP,
 510    OPC_SUBU_S_QB      = (0x05 << 6) | OPC_ADDU_QB_DSP,
 511    OPC_SUBU_PH        = (0x09 << 6) | OPC_ADDU_QB_DSP,
 512    OPC_SUBU_S_PH      = (0x0D << 6) | OPC_ADDU_QB_DSP,
 513    OPC_ADDSC          = (0x10 << 6) | OPC_ADDU_QB_DSP,
 514    OPC_ADDWC          = (0x11 << 6) | OPC_ADDU_QB_DSP,
 515    OPC_MODSUB         = (0x12 << 6) | OPC_ADDU_QB_DSP,
 516    OPC_RADDU_W_QB     = (0x14 << 6) | OPC_ADDU_QB_DSP,
 517    /* MIPS DSP Multiply Sub-class insns */
 518    OPC_MULEU_S_PH_QBL = (0x06 << 6) | OPC_ADDU_QB_DSP,
 519    OPC_MULEU_S_PH_QBR = (0x07 << 6) | OPC_ADDU_QB_DSP,
 520    OPC_MULQ_RS_PH     = (0x1F << 6) | OPC_ADDU_QB_DSP,
 521    OPC_MULEQ_S_W_PHL  = (0x1C << 6) | OPC_ADDU_QB_DSP,
 522    OPC_MULEQ_S_W_PHR  = (0x1D << 6) | OPC_ADDU_QB_DSP,
 523    OPC_MULQ_S_PH      = (0x1E << 6) | OPC_ADDU_QB_DSP,
 524};
 525
 526#define OPC_ADDUH_QB_DSP OPC_MULT_G_2E
 527#define MASK_ADDUH_QB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
 528enum {
 529    /* MIPS DSP Arithmetic Sub-class */
 530    OPC_ADDUH_QB   = (0x00 << 6) | OPC_ADDUH_QB_DSP,
 531    OPC_ADDUH_R_QB = (0x02 << 6) | OPC_ADDUH_QB_DSP,
 532    OPC_ADDQH_PH   = (0x08 << 6) | OPC_ADDUH_QB_DSP,
 533    OPC_ADDQH_R_PH = (0x0A << 6) | OPC_ADDUH_QB_DSP,
 534    OPC_ADDQH_W    = (0x10 << 6) | OPC_ADDUH_QB_DSP,
 535    OPC_ADDQH_R_W  = (0x12 << 6) | OPC_ADDUH_QB_DSP,
 536    OPC_SUBUH_QB   = (0x01 << 6) | OPC_ADDUH_QB_DSP,
 537    OPC_SUBUH_R_QB = (0x03 << 6) | OPC_ADDUH_QB_DSP,
 538    OPC_SUBQH_PH   = (0x09 << 6) | OPC_ADDUH_QB_DSP,
 539    OPC_SUBQH_R_PH = (0x0B << 6) | OPC_ADDUH_QB_DSP,
 540    OPC_SUBQH_W    = (0x11 << 6) | OPC_ADDUH_QB_DSP,
 541    OPC_SUBQH_R_W  = (0x13 << 6) | OPC_ADDUH_QB_DSP,
 542    /* MIPS DSP Multiply Sub-class insns */
 543    OPC_MUL_PH     = (0x0C << 6) | OPC_ADDUH_QB_DSP,
 544    OPC_MUL_S_PH   = (0x0E << 6) | OPC_ADDUH_QB_DSP,
 545    OPC_MULQ_S_W   = (0x16 << 6) | OPC_ADDUH_QB_DSP,
 546    OPC_MULQ_RS_W  = (0x17 << 6) | OPC_ADDUH_QB_DSP,
 547};
 548
 549#define MASK_ABSQ_S_PH(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
 550enum {
 551    /* MIPS DSP Arithmetic Sub-class */
 552    OPC_ABSQ_S_QB       = (0x01 << 6) | OPC_ABSQ_S_PH_DSP,
 553    OPC_ABSQ_S_PH       = (0x09 << 6) | OPC_ABSQ_S_PH_DSP,
 554    OPC_ABSQ_S_W        = (0x11 << 6) | OPC_ABSQ_S_PH_DSP,
 555    OPC_PRECEQ_W_PHL    = (0x0C << 6) | OPC_ABSQ_S_PH_DSP,
 556    OPC_PRECEQ_W_PHR    = (0x0D << 6) | OPC_ABSQ_S_PH_DSP,
 557    OPC_PRECEQU_PH_QBL  = (0x04 << 6) | OPC_ABSQ_S_PH_DSP,
 558    OPC_PRECEQU_PH_QBR  = (0x05 << 6) | OPC_ABSQ_S_PH_DSP,
 559    OPC_PRECEQU_PH_QBLA = (0x06 << 6) | OPC_ABSQ_S_PH_DSP,
 560    OPC_PRECEQU_PH_QBRA = (0x07 << 6) | OPC_ABSQ_S_PH_DSP,
 561    OPC_PRECEU_PH_QBL   = (0x1C << 6) | OPC_ABSQ_S_PH_DSP,
 562    OPC_PRECEU_PH_QBR   = (0x1D << 6) | OPC_ABSQ_S_PH_DSP,
 563    OPC_PRECEU_PH_QBLA  = (0x1E << 6) | OPC_ABSQ_S_PH_DSP,
 564    OPC_PRECEU_PH_QBRA  = (0x1F << 6) | OPC_ABSQ_S_PH_DSP,
 565    /* DSP Bit/Manipulation Sub-class */
 566    OPC_BITREV          = (0x1B << 6) | OPC_ABSQ_S_PH_DSP,
 567    OPC_REPL_QB         = (0x02 << 6) | OPC_ABSQ_S_PH_DSP,
 568    OPC_REPLV_QB        = (0x03 << 6) | OPC_ABSQ_S_PH_DSP,
 569    OPC_REPL_PH         = (0x0A << 6) | OPC_ABSQ_S_PH_DSP,
 570    OPC_REPLV_PH        = (0x0B << 6) | OPC_ABSQ_S_PH_DSP,
 571};
 572
 573#define MASK_CMPU_EQ_QB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
 574enum {
 575    /* MIPS DSP Arithmetic Sub-class */
 576    OPC_PRECR_QB_PH      = (0x0D << 6) | OPC_CMPU_EQ_QB_DSP,
 577    OPC_PRECRQ_QB_PH     = (0x0C << 6) | OPC_CMPU_EQ_QB_DSP,
 578    OPC_PRECR_SRA_PH_W   = (0x1E << 6) | OPC_CMPU_EQ_QB_DSP,
 579    OPC_PRECR_SRA_R_PH_W = (0x1F << 6) | OPC_CMPU_EQ_QB_DSP,
 580    OPC_PRECRQ_PH_W      = (0x14 << 6) | OPC_CMPU_EQ_QB_DSP,
 581    OPC_PRECRQ_RS_PH_W   = (0x15 << 6) | OPC_CMPU_EQ_QB_DSP,
 582    OPC_PRECRQU_S_QB_PH  = (0x0F << 6) | OPC_CMPU_EQ_QB_DSP,
 583    /* DSP Compare-Pick Sub-class */
 584    OPC_CMPU_EQ_QB       = (0x00 << 6) | OPC_CMPU_EQ_QB_DSP,
 585    OPC_CMPU_LT_QB       = (0x01 << 6) | OPC_CMPU_EQ_QB_DSP,
 586    OPC_CMPU_LE_QB       = (0x02 << 6) | OPC_CMPU_EQ_QB_DSP,
 587    OPC_CMPGU_EQ_QB      = (0x04 << 6) | OPC_CMPU_EQ_QB_DSP,
 588    OPC_CMPGU_LT_QB      = (0x05 << 6) | OPC_CMPU_EQ_QB_DSP,
 589    OPC_CMPGU_LE_QB      = (0x06 << 6) | OPC_CMPU_EQ_QB_DSP,
 590    OPC_CMPGDU_EQ_QB     = (0x18 << 6) | OPC_CMPU_EQ_QB_DSP,
 591    OPC_CMPGDU_LT_QB     = (0x19 << 6) | OPC_CMPU_EQ_QB_DSP,
 592    OPC_CMPGDU_LE_QB     = (0x1A << 6) | OPC_CMPU_EQ_QB_DSP,
 593    OPC_CMP_EQ_PH        = (0x08 << 6) | OPC_CMPU_EQ_QB_DSP,
 594    OPC_CMP_LT_PH        = (0x09 << 6) | OPC_CMPU_EQ_QB_DSP,
 595    OPC_CMP_LE_PH        = (0x0A << 6) | OPC_CMPU_EQ_QB_DSP,
 596    OPC_PICK_QB          = (0x03 << 6) | OPC_CMPU_EQ_QB_DSP,
 597    OPC_PICK_PH          = (0x0B << 6) | OPC_CMPU_EQ_QB_DSP,
 598    OPC_PACKRL_PH        = (0x0E << 6) | OPC_CMPU_EQ_QB_DSP,
 599};
 600
 601#define MASK_SHLL_QB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
 602enum {
 603    /* MIPS DSP GPR-Based Shift Sub-class */
 604    OPC_SHLL_QB    = (0x00 << 6) | OPC_SHLL_QB_DSP,
 605    OPC_SHLLV_QB   = (0x02 << 6) | OPC_SHLL_QB_DSP,
 606    OPC_SHLL_PH    = (0x08 << 6) | OPC_SHLL_QB_DSP,
 607    OPC_SHLLV_PH   = (0x0A << 6) | OPC_SHLL_QB_DSP,
 608    OPC_SHLL_S_PH  = (0x0C << 6) | OPC_SHLL_QB_DSP,
 609    OPC_SHLLV_S_PH = (0x0E << 6) | OPC_SHLL_QB_DSP,
 610    OPC_SHLL_S_W   = (0x14 << 6) | OPC_SHLL_QB_DSP,
 611    OPC_SHLLV_S_W  = (0x16 << 6) | OPC_SHLL_QB_DSP,
 612    OPC_SHRL_QB    = (0x01 << 6) | OPC_SHLL_QB_DSP,
 613    OPC_SHRLV_QB   = (0x03 << 6) | OPC_SHLL_QB_DSP,
 614    OPC_SHRL_PH    = (0x19 << 6) | OPC_SHLL_QB_DSP,
 615    OPC_SHRLV_PH   = (0x1B << 6) | OPC_SHLL_QB_DSP,
 616    OPC_SHRA_QB    = (0x04 << 6) | OPC_SHLL_QB_DSP,
 617    OPC_SHRA_R_QB  = (0x05 << 6) | OPC_SHLL_QB_DSP,
 618    OPC_SHRAV_QB   = (0x06 << 6) | OPC_SHLL_QB_DSP,
 619    OPC_SHRAV_R_QB = (0x07 << 6) | OPC_SHLL_QB_DSP,
 620    OPC_SHRA_PH    = (0x09 << 6) | OPC_SHLL_QB_DSP,
 621    OPC_SHRAV_PH   = (0x0B << 6) | OPC_SHLL_QB_DSP,
 622    OPC_SHRA_R_PH  = (0x0D << 6) | OPC_SHLL_QB_DSP,
 623    OPC_SHRAV_R_PH = (0x0F << 6) | OPC_SHLL_QB_DSP,
 624    OPC_SHRA_R_W   = (0x15 << 6) | OPC_SHLL_QB_DSP,
 625    OPC_SHRAV_R_W  = (0x17 << 6) | OPC_SHLL_QB_DSP,
 626};
 627
 628#define MASK_DPA_W_PH(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
 629enum {
 630    /* MIPS DSP Multiply Sub-class insns */
 631    OPC_DPAU_H_QBL    = (0x03 << 6) | OPC_DPA_W_PH_DSP,
 632    OPC_DPAU_H_QBR    = (0x07 << 6) | OPC_DPA_W_PH_DSP,
 633    OPC_DPSU_H_QBL    = (0x0B << 6) | OPC_DPA_W_PH_DSP,
 634    OPC_DPSU_H_QBR    = (0x0F << 6) | OPC_DPA_W_PH_DSP,
 635    OPC_DPA_W_PH      = (0x00 << 6) | OPC_DPA_W_PH_DSP,
 636    OPC_DPAX_W_PH     = (0x08 << 6) | OPC_DPA_W_PH_DSP,
 637    OPC_DPAQ_S_W_PH   = (0x04 << 6) | OPC_DPA_W_PH_DSP,
 638    OPC_DPAQX_S_W_PH  = (0x18 << 6) | OPC_DPA_W_PH_DSP,
 639    OPC_DPAQX_SA_W_PH = (0x1A << 6) | OPC_DPA_W_PH_DSP,
 640    OPC_DPS_W_PH      = (0x01 << 6) | OPC_DPA_W_PH_DSP,
 641    OPC_DPSX_W_PH     = (0x09 << 6) | OPC_DPA_W_PH_DSP,
 642    OPC_DPSQ_S_W_PH   = (0x05 << 6) | OPC_DPA_W_PH_DSP,
 643    OPC_DPSQX_S_W_PH  = (0x19 << 6) | OPC_DPA_W_PH_DSP,
 644    OPC_DPSQX_SA_W_PH = (0x1B << 6) | OPC_DPA_W_PH_DSP,
 645    OPC_MULSAQ_S_W_PH = (0x06 << 6) | OPC_DPA_W_PH_DSP,
 646    OPC_DPAQ_SA_L_W   = (0x0C << 6) | OPC_DPA_W_PH_DSP,
 647    OPC_DPSQ_SA_L_W   = (0x0D << 6) | OPC_DPA_W_PH_DSP,
 648    OPC_MAQ_S_W_PHL   = (0x14 << 6) | OPC_DPA_W_PH_DSP,
 649    OPC_MAQ_S_W_PHR   = (0x16 << 6) | OPC_DPA_W_PH_DSP,
 650    OPC_MAQ_SA_W_PHL  = (0x10 << 6) | OPC_DPA_W_PH_DSP,
 651    OPC_MAQ_SA_W_PHR  = (0x12 << 6) | OPC_DPA_W_PH_DSP,
 652    OPC_MULSA_W_PH    = (0x02 << 6) | OPC_DPA_W_PH_DSP,
 653};
 654
 655#define MASK_INSV(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
 656enum {
 657    /* DSP Bit/Manipulation Sub-class */
 658    OPC_INSV = (0x00 << 6) | OPC_INSV_DSP,
 659};
 660
 661#define MASK_APPEND(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
 662enum {
 663    /* MIPS DSP Append Sub-class */
 664    OPC_APPEND  = (0x00 << 6) | OPC_APPEND_DSP,
 665    OPC_PREPEND = (0x01 << 6) | OPC_APPEND_DSP,
 666    OPC_BALIGN  = (0x10 << 6) | OPC_APPEND_DSP,
 667};
 668
 669#define MASK_EXTR_W(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
 670enum {
 671    /* MIPS DSP Accumulator and DSPControl Access Sub-class */
 672    OPC_EXTR_W     = (0x00 << 6) | OPC_EXTR_W_DSP,
 673    OPC_EXTR_R_W   = (0x04 << 6) | OPC_EXTR_W_DSP,
 674    OPC_EXTR_RS_W  = (0x06 << 6) | OPC_EXTR_W_DSP,
 675    OPC_EXTR_S_H   = (0x0E << 6) | OPC_EXTR_W_DSP,
 676    OPC_EXTRV_S_H  = (0x0F << 6) | OPC_EXTR_W_DSP,
 677    OPC_EXTRV_W    = (0x01 << 6) | OPC_EXTR_W_DSP,
 678    OPC_EXTRV_R_W  = (0x05 << 6) | OPC_EXTR_W_DSP,
 679    OPC_EXTRV_RS_W = (0x07 << 6) | OPC_EXTR_W_DSP,
 680    OPC_EXTP       = (0x02 << 6) | OPC_EXTR_W_DSP,
 681    OPC_EXTPV      = (0x03 << 6) | OPC_EXTR_W_DSP,
 682    OPC_EXTPDP     = (0x0A << 6) | OPC_EXTR_W_DSP,
 683    OPC_EXTPDPV    = (0x0B << 6) | OPC_EXTR_W_DSP,
 684    OPC_SHILO      = (0x1A << 6) | OPC_EXTR_W_DSP,
 685    OPC_SHILOV     = (0x1B << 6) | OPC_EXTR_W_DSP,
 686    OPC_MTHLIP     = (0x1F << 6) | OPC_EXTR_W_DSP,
 687    OPC_WRDSP      = (0x13 << 6) | OPC_EXTR_W_DSP,
 688    OPC_RDDSP      = (0x12 << 6) | OPC_EXTR_W_DSP,
 689};
 690
 691#define MASK_ABSQ_S_QH(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
 692enum {
 693    /* MIPS DSP Arithmetic Sub-class */
 694    OPC_PRECEQ_L_PWL    = (0x14 << 6) | OPC_ABSQ_S_QH_DSP,
 695    OPC_PRECEQ_L_PWR    = (0x15 << 6) | OPC_ABSQ_S_QH_DSP,
 696    OPC_PRECEQ_PW_QHL   = (0x0C << 6) | OPC_ABSQ_S_QH_DSP,
 697    OPC_PRECEQ_PW_QHR   = (0x0D << 6) | OPC_ABSQ_S_QH_DSP,
 698    OPC_PRECEQ_PW_QHLA  = (0x0E << 6) | OPC_ABSQ_S_QH_DSP,
 699    OPC_PRECEQ_PW_QHRA  = (0x0F << 6) | OPC_ABSQ_S_QH_DSP,
 700    OPC_PRECEQU_QH_OBL  = (0x04 << 6) | OPC_ABSQ_S_QH_DSP,
 701    OPC_PRECEQU_QH_OBR  = (0x05 << 6) | OPC_ABSQ_S_QH_DSP,
 702    OPC_PRECEQU_QH_OBLA = (0x06 << 6) | OPC_ABSQ_S_QH_DSP,
 703    OPC_PRECEQU_QH_OBRA = (0x07 << 6) | OPC_ABSQ_S_QH_DSP,
 704    OPC_PRECEU_QH_OBL   = (0x1C << 6) | OPC_ABSQ_S_QH_DSP,
 705    OPC_PRECEU_QH_OBR   = (0x1D << 6) | OPC_ABSQ_S_QH_DSP,
 706    OPC_PRECEU_QH_OBLA  = (0x1E << 6) | OPC_ABSQ_S_QH_DSP,
 707    OPC_PRECEU_QH_OBRA  = (0x1F << 6) | OPC_ABSQ_S_QH_DSP,
 708    OPC_ABSQ_S_OB       = (0x01 << 6) | OPC_ABSQ_S_QH_DSP,
 709    OPC_ABSQ_S_PW       = (0x11 << 6) | OPC_ABSQ_S_QH_DSP,
 710    OPC_ABSQ_S_QH       = (0x09 << 6) | OPC_ABSQ_S_QH_DSP,
 711    /* DSP Bit/Manipulation Sub-class */
 712    OPC_REPL_OB         = (0x02 << 6) | OPC_ABSQ_S_QH_DSP,
 713    OPC_REPL_PW         = (0x12 << 6) | OPC_ABSQ_S_QH_DSP,
 714    OPC_REPL_QH         = (0x0A << 6) | OPC_ABSQ_S_QH_DSP,
 715    OPC_REPLV_OB        = (0x03 << 6) | OPC_ABSQ_S_QH_DSP,
 716    OPC_REPLV_PW        = (0x13 << 6) | OPC_ABSQ_S_QH_DSP,
 717    OPC_REPLV_QH        = (0x0B << 6) | OPC_ABSQ_S_QH_DSP,
 718};
 719
 720#define MASK_ADDU_OB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
 721enum {
 722    /* MIPS DSP Multiply Sub-class insns */
 723    OPC_MULEQ_S_PW_QHL = (0x1C << 6) | OPC_ADDU_OB_DSP,
 724    OPC_MULEQ_S_PW_QHR = (0x1D << 6) | OPC_ADDU_OB_DSP,
 725    OPC_MULEU_S_QH_OBL = (0x06 << 6) | OPC_ADDU_OB_DSP,
 726    OPC_MULEU_S_QH_OBR = (0x07 << 6) | OPC_ADDU_OB_DSP,
 727    OPC_MULQ_RS_QH     = (0x1F << 6) | OPC_ADDU_OB_DSP,
 728    /* MIPS DSP Arithmetic Sub-class */
 729    OPC_RADDU_L_OB     = (0x14 << 6) | OPC_ADDU_OB_DSP,
 730    OPC_SUBQ_PW        = (0x13 << 6) | OPC_ADDU_OB_DSP,
 731    OPC_SUBQ_S_PW      = (0x17 << 6) | OPC_ADDU_OB_DSP,
 732    OPC_SUBQ_QH        = (0x0B << 6) | OPC_ADDU_OB_DSP,
 733    OPC_SUBQ_S_QH      = (0x0F << 6) | OPC_ADDU_OB_DSP,
 734    OPC_SUBU_OB        = (0x01 << 6) | OPC_ADDU_OB_DSP,
 735    OPC_SUBU_S_OB      = (0x05 << 6) | OPC_ADDU_OB_DSP,
 736    OPC_SUBU_QH        = (0x09 << 6) | OPC_ADDU_OB_DSP,
 737    OPC_SUBU_S_QH      = (0x0D << 6) | OPC_ADDU_OB_DSP,
 738    OPC_SUBUH_OB       = (0x19 << 6) | OPC_ADDU_OB_DSP,
 739    OPC_SUBUH_R_OB     = (0x1B << 6) | OPC_ADDU_OB_DSP,
 740    OPC_ADDQ_PW        = (0x12 << 6) | OPC_ADDU_OB_DSP,
 741    OPC_ADDQ_S_PW      = (0x16 << 6) | OPC_ADDU_OB_DSP,
 742    OPC_ADDQ_QH        = (0x0A << 6) | OPC_ADDU_OB_DSP,
 743    OPC_ADDQ_S_QH      = (0x0E << 6) | OPC_ADDU_OB_DSP,
 744    OPC_ADDU_OB        = (0x00 << 6) | OPC_ADDU_OB_DSP,
 745    OPC_ADDU_S_OB      = (0x04 << 6) | OPC_ADDU_OB_DSP,
 746    OPC_ADDU_QH        = (0x08 << 6) | OPC_ADDU_OB_DSP,
 747    OPC_ADDU_S_QH      = (0x0C << 6) | OPC_ADDU_OB_DSP,
 748    OPC_ADDUH_OB       = (0x18 << 6) | OPC_ADDU_OB_DSP,
 749    OPC_ADDUH_R_OB     = (0x1A << 6) | OPC_ADDU_OB_DSP,
 750};
 751
 752#define MASK_CMPU_EQ_OB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
 753enum {
 754    /* DSP Compare-Pick Sub-class */
 755    OPC_CMP_EQ_PW         = (0x10 << 6) | OPC_CMPU_EQ_OB_DSP,
 756    OPC_CMP_LT_PW         = (0x11 << 6) | OPC_CMPU_EQ_OB_DSP,
 757    OPC_CMP_LE_PW         = (0x12 << 6) | OPC_CMPU_EQ_OB_DSP,
 758    OPC_CMP_EQ_QH         = (0x08 << 6) | OPC_CMPU_EQ_OB_DSP,
 759    OPC_CMP_LT_QH         = (0x09 << 6) | OPC_CMPU_EQ_OB_DSP,
 760    OPC_CMP_LE_QH         = (0x0A << 6) | OPC_CMPU_EQ_OB_DSP,
 761    OPC_CMPGDU_EQ_OB      = (0x18 << 6) | OPC_CMPU_EQ_OB_DSP,
 762    OPC_CMPGDU_LT_OB      = (0x19 << 6) | OPC_CMPU_EQ_OB_DSP,
 763    OPC_CMPGDU_LE_OB      = (0x1A << 6) | OPC_CMPU_EQ_OB_DSP,
 764    OPC_CMPGU_EQ_OB       = (0x04 << 6) | OPC_CMPU_EQ_OB_DSP,
 765    OPC_CMPGU_LT_OB       = (0x05 << 6) | OPC_CMPU_EQ_OB_DSP,
 766    OPC_CMPGU_LE_OB       = (0x06 << 6) | OPC_CMPU_EQ_OB_DSP,
 767    OPC_CMPU_EQ_OB        = (0x00 << 6) | OPC_CMPU_EQ_OB_DSP,
 768    OPC_CMPU_LT_OB        = (0x01 << 6) | OPC_CMPU_EQ_OB_DSP,
 769    OPC_CMPU_LE_OB        = (0x02 << 6) | OPC_CMPU_EQ_OB_DSP,
 770    OPC_PACKRL_PW         = (0x0E << 6) | OPC_CMPU_EQ_OB_DSP,
 771    OPC_PICK_OB           = (0x03 << 6) | OPC_CMPU_EQ_OB_DSP,
 772    OPC_PICK_PW           = (0x13 << 6) | OPC_CMPU_EQ_OB_DSP,
 773    OPC_PICK_QH           = (0x0B << 6) | OPC_CMPU_EQ_OB_DSP,
 774    /* MIPS DSP Arithmetic Sub-class */
 775    OPC_PRECR_OB_QH       = (0x0D << 6) | OPC_CMPU_EQ_OB_DSP,
 776    OPC_PRECR_SRA_QH_PW   = (0x1E << 6) | OPC_CMPU_EQ_OB_DSP,
 777    OPC_PRECR_SRA_R_QH_PW = (0x1F << 6) | OPC_CMPU_EQ_OB_DSP,
 778    OPC_PRECRQ_OB_QH      = (0x0C << 6) | OPC_CMPU_EQ_OB_DSP,
 779    OPC_PRECRQ_PW_L       = (0x1C << 6) | OPC_CMPU_EQ_OB_DSP,
 780    OPC_PRECRQ_QH_PW      = (0x14 << 6) | OPC_CMPU_EQ_OB_DSP,
 781    OPC_PRECRQ_RS_QH_PW   = (0x15 << 6) | OPC_CMPU_EQ_OB_DSP,
 782    OPC_PRECRQU_S_OB_QH   = (0x0F << 6) | OPC_CMPU_EQ_OB_DSP,
 783};
 784
 785#define MASK_DAPPEND(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
 786enum {
 787    /* DSP Append Sub-class */
 788    OPC_DAPPEND  = (0x00 << 6) | OPC_DAPPEND_DSP,
 789    OPC_PREPENDD = (0x03 << 6) | OPC_DAPPEND_DSP,
 790    OPC_PREPENDW = (0x01 << 6) | OPC_DAPPEND_DSP,
 791    OPC_DBALIGN  = (0x10 << 6) | OPC_DAPPEND_DSP,
 792};
 793
 794#define MASK_DEXTR_W(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
 795enum {
 796    /* MIPS DSP Accumulator and DSPControl Access Sub-class */
 797    OPC_DMTHLIP     = (0x1F << 6) | OPC_DEXTR_W_DSP,
 798    OPC_DSHILO      = (0x1A << 6) | OPC_DEXTR_W_DSP,
 799    OPC_DEXTP       = (0x02 << 6) | OPC_DEXTR_W_DSP,
 800    OPC_DEXTPDP     = (0x0A << 6) | OPC_DEXTR_W_DSP,
 801    OPC_DEXTPDPV    = (0x0B << 6) | OPC_DEXTR_W_DSP,
 802    OPC_DEXTPV      = (0x03 << 6) | OPC_DEXTR_W_DSP,
 803    OPC_DEXTR_L     = (0x10 << 6) | OPC_DEXTR_W_DSP,
 804    OPC_DEXTR_R_L   = (0x14 << 6) | OPC_DEXTR_W_DSP,
 805    OPC_DEXTR_RS_L  = (0x16 << 6) | OPC_DEXTR_W_DSP,
 806    OPC_DEXTR_W     = (0x00 << 6) | OPC_DEXTR_W_DSP,
 807    OPC_DEXTR_R_W   = (0x04 << 6) | OPC_DEXTR_W_DSP,
 808    OPC_DEXTR_RS_W  = (0x06 << 6) | OPC_DEXTR_W_DSP,
 809    OPC_DEXTR_S_H   = (0x0E << 6) | OPC_DEXTR_W_DSP,
 810    OPC_DEXTRV_L    = (0x11 << 6) | OPC_DEXTR_W_DSP,
 811    OPC_DEXTRV_R_L  = (0x15 << 6) | OPC_DEXTR_W_DSP,
 812    OPC_DEXTRV_RS_L = (0x17 << 6) | OPC_DEXTR_W_DSP,
 813    OPC_DEXTRV_S_H  = (0x0F << 6) | OPC_DEXTR_W_DSP,
 814    OPC_DEXTRV_W    = (0x01 << 6) | OPC_DEXTR_W_DSP,
 815    OPC_DEXTRV_R_W  = (0x05 << 6) | OPC_DEXTR_W_DSP,
 816    OPC_DEXTRV_RS_W = (0x07 << 6) | OPC_DEXTR_W_DSP,
 817    OPC_DSHILOV     = (0x1B << 6) | OPC_DEXTR_W_DSP,
 818};
 819
 820#define MASK_DINSV(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
 821enum {
 822    /* DSP Bit/Manipulation Sub-class */
 823    OPC_DINSV = (0x00 << 6) | OPC_DINSV_DSP,
 824};
 825
 826#define MASK_DPAQ_W_QH(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
 827enum {
 828    /* MIPS DSP Multiply Sub-class insns */
 829    OPC_DMADD         = (0x19 << 6) | OPC_DPAQ_W_QH_DSP,
 830    OPC_DMADDU        = (0x1D << 6) | OPC_DPAQ_W_QH_DSP,
 831    OPC_DMSUB         = (0x1B << 6) | OPC_DPAQ_W_QH_DSP,
 832    OPC_DMSUBU        = (0x1F << 6) | OPC_DPAQ_W_QH_DSP,
 833    OPC_DPA_W_QH      = (0x00 << 6) | OPC_DPAQ_W_QH_DSP,
 834    OPC_DPAQ_S_W_QH   = (0x04 << 6) | OPC_DPAQ_W_QH_DSP,
 835    OPC_DPAQ_SA_L_PW  = (0x0C << 6) | OPC_DPAQ_W_QH_DSP,
 836    OPC_DPAU_H_OBL    = (0x03 << 6) | OPC_DPAQ_W_QH_DSP,
 837    OPC_DPAU_H_OBR    = (0x07 << 6) | OPC_DPAQ_W_QH_DSP,
 838    OPC_DPS_W_QH      = (0x01 << 6) | OPC_DPAQ_W_QH_DSP,
 839    OPC_DPSQ_S_W_QH   = (0x05 << 6) | OPC_DPAQ_W_QH_DSP,
 840    OPC_DPSQ_SA_L_PW  = (0x0D << 6) | OPC_DPAQ_W_QH_DSP,
 841    OPC_DPSU_H_OBL    = (0x0B << 6) | OPC_DPAQ_W_QH_DSP,
 842    OPC_DPSU_H_OBR    = (0x0F << 6) | OPC_DPAQ_W_QH_DSP,
 843    OPC_MAQ_S_L_PWL   = (0x1C << 6) | OPC_DPAQ_W_QH_DSP,
 844    OPC_MAQ_S_L_PWR   = (0x1E << 6) | OPC_DPAQ_W_QH_DSP,
 845    OPC_MAQ_S_W_QHLL  = (0x14 << 6) | OPC_DPAQ_W_QH_DSP,
 846    OPC_MAQ_SA_W_QHLL = (0x10 << 6) | OPC_DPAQ_W_QH_DSP,
 847    OPC_MAQ_S_W_QHLR  = (0x15 << 6) | OPC_DPAQ_W_QH_DSP,
 848    OPC_MAQ_SA_W_QHLR = (0x11 << 6) | OPC_DPAQ_W_QH_DSP,
 849    OPC_MAQ_S_W_QHRL  = (0x16 << 6) | OPC_DPAQ_W_QH_DSP,
 850    OPC_MAQ_SA_W_QHRL = (0x12 << 6) | OPC_DPAQ_W_QH_DSP,
 851    OPC_MAQ_S_W_QHRR  = (0x17 << 6) | OPC_DPAQ_W_QH_DSP,
 852    OPC_MAQ_SA_W_QHRR = (0x13 << 6) | OPC_DPAQ_W_QH_DSP,
 853    OPC_MULSAQ_S_L_PW = (0x0E << 6) | OPC_DPAQ_W_QH_DSP,
 854    OPC_MULSAQ_S_W_QH = (0x06 << 6) | OPC_DPAQ_W_QH_DSP,
 855};
 856
 857#define MASK_SHLL_OB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
 858enum {
 859    /* MIPS DSP GPR-Based Shift Sub-class */
 860    OPC_SHLL_PW    = (0x10 << 6) | OPC_SHLL_OB_DSP,
 861    OPC_SHLL_S_PW  = (0x14 << 6) | OPC_SHLL_OB_DSP,
 862    OPC_SHLLV_OB   = (0x02 << 6) | OPC_SHLL_OB_DSP,
 863    OPC_SHLLV_PW   = (0x12 << 6) | OPC_SHLL_OB_DSP,
 864    OPC_SHLLV_S_PW = (0x16 << 6) | OPC_SHLL_OB_DSP,
 865    OPC_SHLLV_QH   = (0x0A << 6) | OPC_SHLL_OB_DSP,
 866    OPC_SHLLV_S_QH = (0x0E << 6) | OPC_SHLL_OB_DSP,
 867    OPC_SHRA_PW    = (0x11 << 6) | OPC_SHLL_OB_DSP,
 868    OPC_SHRA_R_PW  = (0x15 << 6) | OPC_SHLL_OB_DSP,
 869    OPC_SHRAV_OB   = (0x06 << 6) | OPC_SHLL_OB_DSP,
 870    OPC_SHRAV_R_OB = (0x07 << 6) | OPC_SHLL_OB_DSP,
 871    OPC_SHRAV_PW   = (0x13 << 6) | OPC_SHLL_OB_DSP,
 872    OPC_SHRAV_R_PW = (0x17 << 6) | OPC_SHLL_OB_DSP,
 873    OPC_SHRAV_QH   = (0x0B << 6) | OPC_SHLL_OB_DSP,
 874    OPC_SHRAV_R_QH = (0x0F << 6) | OPC_SHLL_OB_DSP,
 875    OPC_SHRLV_OB   = (0x03 << 6) | OPC_SHLL_OB_DSP,
 876    OPC_SHRLV_QH   = (0x1B << 6) | OPC_SHLL_OB_DSP,
 877    OPC_SHLL_OB    = (0x00 << 6) | OPC_SHLL_OB_DSP,
 878    OPC_SHLL_QH    = (0x08 << 6) | OPC_SHLL_OB_DSP,
 879    OPC_SHLL_S_QH  = (0x0C << 6) | OPC_SHLL_OB_DSP,
 880    OPC_SHRA_OB    = (0x04 << 6) | OPC_SHLL_OB_DSP,
 881    OPC_SHRA_R_OB  = (0x05 << 6) | OPC_SHLL_OB_DSP,
 882    OPC_SHRA_QH    = (0x09 << 6) | OPC_SHLL_OB_DSP,
 883    OPC_SHRA_R_QH  = (0x0D << 6) | OPC_SHLL_OB_DSP,
 884    OPC_SHRL_OB    = (0x01 << 6) | OPC_SHLL_OB_DSP,
 885    OPC_SHRL_QH    = (0x19 << 6) | OPC_SHLL_OB_DSP,
 886};
 887
 888/* Coprocessor 0 (rs field) */
 889#define MASK_CP0(op)       MASK_OP_MAJOR(op) | (op & (0x1F << 21))
 890
 891enum {
 892    OPC_MFC0     = (0x00 << 21) | OPC_CP0,
 893    OPC_DMFC0    = (0x01 << 21) | OPC_CP0,
 894    OPC_MFHC0    = (0x02 << 21) | OPC_CP0,
 895    OPC_MTC0     = (0x04 << 21) | OPC_CP0,
 896    OPC_DMTC0    = (0x05 << 21) | OPC_CP0,
 897    OPC_MTHC0    = (0x06 << 21) | OPC_CP0,
 898    OPC_MFTR     = (0x08 << 21) | OPC_CP0,
 899    OPC_RDPGPR   = (0x0A << 21) | OPC_CP0,
 900    OPC_MFMC0    = (0x0B << 21) | OPC_CP0,
 901    OPC_MTTR     = (0x0C << 21) | OPC_CP0,
 902    OPC_WRPGPR   = (0x0E << 21) | OPC_CP0,
 903    OPC_C0       = (0x10 << 21) | OPC_CP0,
 904    OPC_C0_FIRST = (0x10 << 21) | OPC_CP0,
 905    OPC_C0_LAST  = (0x1F << 21) | OPC_CP0,
 906};
 907
 908/* MFMC0 opcodes */
 909#define MASK_MFMC0(op)     MASK_CP0(op) | (op & 0xFFFF)
 910
 911enum {
 912    OPC_DMT      = 0x01 | (0 << 5) | (0x0F << 6) | (0x01 << 11) | OPC_MFMC0,
 913    OPC_EMT      = 0x01 | (1 << 5) | (0x0F << 6) | (0x01 << 11) | OPC_MFMC0,
 914    OPC_DVPE     = 0x01 | (0 << 5) | OPC_MFMC0,
 915    OPC_EVPE     = 0x01 | (1 << 5) | OPC_MFMC0,
 916    OPC_DI       = (0 << 5) | (0x0C << 11) | OPC_MFMC0,
 917    OPC_EI       = (1 << 5) | (0x0C << 11) | OPC_MFMC0,
 918    OPC_DVP      = 0x04 | (0 << 3) | (1 << 5) | (0 << 11) | OPC_MFMC0,
 919    OPC_EVP      = 0x04 | (0 << 3) | (0 << 5) | (0 << 11) | OPC_MFMC0,
 920};
 921
 922/* Coprocessor 0 (with rs == C0) */
 923#define MASK_C0(op)        MASK_CP0(op) | (op & 0x3F)
 924
 925enum {
 926    OPC_TLBR     = 0x01 | OPC_C0,
 927    OPC_TLBWI    = 0x02 | OPC_C0,
 928    OPC_TLBINV   = 0x03 | OPC_C0,
 929    OPC_TLBINVF  = 0x04 | OPC_C0,
 930    OPC_TLBWR    = 0x06 | OPC_C0,
 931    OPC_TLBP     = 0x08 | OPC_C0,
 932    OPC_RFE      = 0x10 | OPC_C0,
 933    OPC_ERET     = 0x18 | OPC_C0,
 934    OPC_DERET    = 0x1F | OPC_C0,
 935    OPC_WAIT     = 0x20 | OPC_C0,
 936};
 937
 938/* Coprocessor 1 (rs field) */
 939#define MASK_CP1(op)       MASK_OP_MAJOR(op) | (op & (0x1F << 21))
 940
 941/* Values for the fmt field in FP instructions */
 942enum {
 943    /* 0 - 15 are reserved */
 944    FMT_S = 16,          /* single fp */
 945    FMT_D = 17,          /* double fp */
 946    FMT_E = 18,          /* extended fp */
 947    FMT_Q = 19,          /* quad fp */
 948    FMT_W = 20,          /* 32-bit fixed */
 949    FMT_L = 21,          /* 64-bit fixed */
 950    FMT_PS = 22,         /* paired single fp */
 951    /* 23 - 31 are reserved */
 952};
 953
 954enum {
 955    OPC_MFC1     = (0x00 << 21) | OPC_CP1,
 956    OPC_DMFC1    = (0x01 << 21) | OPC_CP1,
 957    OPC_CFC1     = (0x02 << 21) | OPC_CP1,
 958    OPC_MFHC1    = (0x03 << 21) | OPC_CP1,
 959    OPC_MTC1     = (0x04 << 21) | OPC_CP1,
 960    OPC_DMTC1    = (0x05 << 21) | OPC_CP1,
 961    OPC_CTC1     = (0x06 << 21) | OPC_CP1,
 962    OPC_MTHC1    = (0x07 << 21) | OPC_CP1,
 963    OPC_BC1      = (0x08 << 21) | OPC_CP1, /* bc */
 964    OPC_BC1ANY2  = (0x09 << 21) | OPC_CP1,
 965    OPC_BC1ANY4  = (0x0A << 21) | OPC_CP1,
 966    OPC_BZ_V     = (0x0B << 21) | OPC_CP1,
 967    OPC_BNZ_V    = (0x0F << 21) | OPC_CP1,
 968    OPC_S_FMT    = (FMT_S << 21) | OPC_CP1,
 969    OPC_D_FMT    = (FMT_D << 21) | OPC_CP1,
 970    OPC_E_FMT    = (FMT_E << 21) | OPC_CP1,
 971    OPC_Q_FMT    = (FMT_Q << 21) | OPC_CP1,
 972    OPC_W_FMT    = (FMT_W << 21) | OPC_CP1,
 973    OPC_L_FMT    = (FMT_L << 21) | OPC_CP1,
 974    OPC_PS_FMT   = (FMT_PS << 21) | OPC_CP1,
 975    OPC_BC1EQZ   = (0x09 << 21) | OPC_CP1,
 976    OPC_BC1NEZ   = (0x0D << 21) | OPC_CP1,
 977    OPC_BZ_B     = (0x18 << 21) | OPC_CP1,
 978    OPC_BZ_H     = (0x19 << 21) | OPC_CP1,
 979    OPC_BZ_W     = (0x1A << 21) | OPC_CP1,
 980    OPC_BZ_D     = (0x1B << 21) | OPC_CP1,
 981    OPC_BNZ_B    = (0x1C << 21) | OPC_CP1,
 982    OPC_BNZ_H    = (0x1D << 21) | OPC_CP1,
 983    OPC_BNZ_W    = (0x1E << 21) | OPC_CP1,
 984    OPC_BNZ_D    = (0x1F << 21) | OPC_CP1,
 985};
 986
 987#define MASK_CP1_FUNC(op)       MASK_CP1(op) | (op & 0x3F)
 988#define MASK_BC1(op)            MASK_CP1(op) | (op & (0x3 << 16))
 989
 990enum {
 991    OPC_BC1F     = (0x00 << 16) | OPC_BC1,
 992    OPC_BC1T     = (0x01 << 16) | OPC_BC1,
 993    OPC_BC1FL    = (0x02 << 16) | OPC_BC1,
 994    OPC_BC1TL    = (0x03 << 16) | OPC_BC1,
 995};
 996
 997enum {
 998    OPC_BC1FANY2     = (0x00 << 16) | OPC_BC1ANY2,
 999    OPC_BC1TANY2     = (0x01 << 16) | OPC_BC1ANY2,
1000};
1001
1002enum {
1003    OPC_BC1FANY4     = (0x00 << 16) | OPC_BC1ANY4,
1004    OPC_BC1TANY4     = (0x01 << 16) | OPC_BC1ANY4,
1005};
1006
1007#define MASK_CP2(op)       MASK_OP_MAJOR(op) | (op & (0x1F << 21))
1008
1009enum {
1010    OPC_MFC2    = (0x00 << 21) | OPC_CP2,
1011    OPC_DMFC2   = (0x01 << 21) | OPC_CP2,
1012    OPC_CFC2    = (0x02 << 21) | OPC_CP2,
1013    OPC_MFHC2   = (0x03 << 21) | OPC_CP2,
1014    OPC_MTC2    = (0x04 << 21) | OPC_CP2,
1015    OPC_DMTC2   = (0x05 << 21) | OPC_CP2,
1016    OPC_CTC2    = (0x06 << 21) | OPC_CP2,
1017    OPC_MTHC2   = (0x07 << 21) | OPC_CP2,
1018    OPC_BC2     = (0x08 << 21) | OPC_CP2,
1019    OPC_BC2EQZ  = (0x09 << 21) | OPC_CP2,
1020    OPC_BC2NEZ  = (0x0D << 21) | OPC_CP2,
1021};
1022
1023#define MASK_LMI(op)  (MASK_OP_MAJOR(op) | (op & (0x1F << 21)) | (op & 0x1F))
1024
1025enum {
1026    OPC_PADDSH  = (24 << 21) | (0x00) | OPC_CP2,
1027    OPC_PADDUSH = (25 << 21) | (0x00) | OPC_CP2,
1028    OPC_PADDH   = (26 << 21) | (0x00) | OPC_CP2,
1029    OPC_PADDW   = (27 << 21) | (0x00) | OPC_CP2,
1030    OPC_PADDSB  = (28 << 21) | (0x00) | OPC_CP2,
1031    OPC_PADDUSB = (29 << 21) | (0x00) | OPC_CP2,
1032    OPC_PADDB   = (30 << 21) | (0x00) | OPC_CP2,
1033    OPC_PADDD   = (31 << 21) | (0x00) | OPC_CP2,
1034
1035    OPC_PSUBSH  = (24 << 21) | (0x01) | OPC_CP2,
1036    OPC_PSUBUSH = (25 << 21) | (0x01) | OPC_CP2,
1037    OPC_PSUBH   = (26 << 21) | (0x01) | OPC_CP2,
1038    OPC_PSUBW   = (27 << 21) | (0x01) | OPC_CP2,
1039    OPC_PSUBSB  = (28 << 21) | (0x01) | OPC_CP2,
1040    OPC_PSUBUSB = (29 << 21) | (0x01) | OPC_CP2,
1041    OPC_PSUBB   = (30 << 21) | (0x01) | OPC_CP2,
1042    OPC_PSUBD   = (31 << 21) | (0x01) | OPC_CP2,
1043
1044    OPC_PSHUFH   = (24 << 21) | (0x02) | OPC_CP2,
1045    OPC_PACKSSWH = (25 << 21) | (0x02) | OPC_CP2,
1046    OPC_PACKSSHB = (26 << 21) | (0x02) | OPC_CP2,
1047    OPC_PACKUSHB = (27 << 21) | (0x02) | OPC_CP2,
1048    OPC_XOR_CP2  = (28 << 21) | (0x02) | OPC_CP2,
1049    OPC_NOR_CP2  = (29 << 21) | (0x02) | OPC_CP2,
1050    OPC_AND_CP2  = (30 << 21) | (0x02) | OPC_CP2,
1051    OPC_PANDN    = (31 << 21) | (0x02) | OPC_CP2,
1052
1053    OPC_PUNPCKLHW = (24 << 21) | (0x03) | OPC_CP2,
1054    OPC_PUNPCKHHW = (25 << 21) | (0x03) | OPC_CP2,
1055    OPC_PUNPCKLBH = (26 << 21) | (0x03) | OPC_CP2,
1056    OPC_PUNPCKHBH = (27 << 21) | (0x03) | OPC_CP2,
1057    OPC_PINSRH_0  = (28 << 21) | (0x03) | OPC_CP2,
1058    OPC_PINSRH_1  = (29 << 21) | (0x03) | OPC_CP2,
1059    OPC_PINSRH_2  = (30 << 21) | (0x03) | OPC_CP2,
1060    OPC_PINSRH_3  = (31 << 21) | (0x03) | OPC_CP2,
1061
1062    OPC_PAVGH   = (24 << 21) | (0x08) | OPC_CP2,
1063    OPC_PAVGB   = (25 << 21) | (0x08) | OPC_CP2,
1064    OPC_PMAXSH  = (26 << 21) | (0x08) | OPC_CP2,
1065    OPC_PMINSH  = (27 << 21) | (0x08) | OPC_CP2,
1066    OPC_PMAXUB  = (28 << 21) | (0x08) | OPC_CP2,
1067    OPC_PMINUB  = (29 << 21) | (0x08) | OPC_CP2,
1068
1069    OPC_PCMPEQW = (24 << 21) | (0x09) | OPC_CP2,
1070    OPC_PCMPGTW = (25 << 21) | (0x09) | OPC_CP2,
1071    OPC_PCMPEQH = (26 << 21) | (0x09) | OPC_CP2,
1072    OPC_PCMPGTH = (27 << 21) | (0x09) | OPC_CP2,
1073    OPC_PCMPEQB = (28 << 21) | (0x09) | OPC_CP2,
1074    OPC_PCMPGTB = (29 << 21) | (0x09) | OPC_CP2,
1075
1076    OPC_PSLLW   = (24 << 21) | (0x0A) | OPC_CP2,
1077    OPC_PSLLH   = (25 << 21) | (0x0A) | OPC_CP2,
1078    OPC_PMULLH  = (26 << 21) | (0x0A) | OPC_CP2,
1079    OPC_PMULHH  = (27 << 21) | (0x0A) | OPC_CP2,
1080    OPC_PMULUW  = (28 << 21) | (0x0A) | OPC_CP2,
1081    OPC_PMULHUH = (29 << 21) | (0x0A) | OPC_CP2,
1082
1083    OPC_PSRLW     = (24 << 21) | (0x0B) | OPC_CP2,
1084    OPC_PSRLH     = (25 << 21) | (0x0B) | OPC_CP2,
1085    OPC_PSRAW     = (26 << 21) | (0x0B) | OPC_CP2,
1086    OPC_PSRAH     = (27 << 21) | (0x0B) | OPC_CP2,
1087    OPC_PUNPCKLWD = (28 << 21) | (0x0B) | OPC_CP2,
1088    OPC_PUNPCKHWD = (29 << 21) | (0x0B) | OPC_CP2,
1089
1090    OPC_ADDU_CP2 = (24 << 21) | (0x0C) | OPC_CP2,
1091    OPC_OR_CP2   = (25 << 21) | (0x0C) | OPC_CP2,
1092    OPC_ADD_CP2  = (26 << 21) | (0x0C) | OPC_CP2,
1093    OPC_DADD_CP2 = (27 << 21) | (0x0C) | OPC_CP2,
1094    OPC_SEQU_CP2 = (28 << 21) | (0x0C) | OPC_CP2,
1095    OPC_SEQ_CP2  = (29 << 21) | (0x0C) | OPC_CP2,
1096
1097    OPC_SUBU_CP2 = (24 << 21) | (0x0D) | OPC_CP2,
1098    OPC_PASUBUB  = (25 << 21) | (0x0D) | OPC_CP2,
1099    OPC_SUB_CP2  = (26 << 21) | (0x0D) | OPC_CP2,
1100    OPC_DSUB_CP2 = (27 << 21) | (0x0D) | OPC_CP2,
1101    OPC_SLTU_CP2 = (28 << 21) | (0x0D) | OPC_CP2,
1102    OPC_SLT_CP2  = (29 << 21) | (0x0D) | OPC_CP2,
1103
1104    OPC_SLL_CP2  = (24 << 21) | (0x0E) | OPC_CP2,
1105    OPC_DSLL_CP2 = (25 << 21) | (0x0E) | OPC_CP2,
1106    OPC_PEXTRH   = (26 << 21) | (0x0E) | OPC_CP2,
1107    OPC_PMADDHW  = (27 << 21) | (0x0E) | OPC_CP2,
1108    OPC_SLEU_CP2 = (28 << 21) | (0x0E) | OPC_CP2,
1109    OPC_SLE_CP2  = (29 << 21) | (0x0E) | OPC_CP2,
1110
1111    OPC_SRL_CP2  = (24 << 21) | (0x0F) | OPC_CP2,
1112    OPC_DSRL_CP2 = (25 << 21) | (0x0F) | OPC_CP2,
1113    OPC_SRA_CP2  = (26 << 21) | (0x0F) | OPC_CP2,
1114    OPC_DSRA_CP2 = (27 << 21) | (0x0F) | OPC_CP2,
1115    OPC_BIADD    = (28 << 21) | (0x0F) | OPC_CP2,
1116    OPC_PMOVMSKB = (29 << 21) | (0x0F) | OPC_CP2,
1117};
1118
1119
1120#define MASK_CP3(op)       MASK_OP_MAJOR(op) | (op & 0x3F)
1121
1122enum {
1123    OPC_LWXC1   = 0x00 | OPC_CP3,
1124    OPC_LDXC1   = 0x01 | OPC_CP3,
1125    OPC_LUXC1   = 0x05 | OPC_CP3,
1126    OPC_SWXC1   = 0x08 | OPC_CP3,
1127    OPC_SDXC1   = 0x09 | OPC_CP3,
1128    OPC_SUXC1   = 0x0D | OPC_CP3,
1129    OPC_PREFX   = 0x0F | OPC_CP3,
1130    OPC_ALNV_PS = 0x1E | OPC_CP3,
1131    OPC_MADD_S  = 0x20 | OPC_CP3,
1132    OPC_MADD_D  = 0x21 | OPC_CP3,
1133    OPC_MADD_PS = 0x26 | OPC_CP3,
1134    OPC_MSUB_S  = 0x28 | OPC_CP3,
1135    OPC_MSUB_D  = 0x29 | OPC_CP3,
1136    OPC_MSUB_PS = 0x2E | OPC_CP3,
1137    OPC_NMADD_S = 0x30 | OPC_CP3,
1138    OPC_NMADD_D = 0x31 | OPC_CP3,
1139    OPC_NMADD_PS= 0x36 | OPC_CP3,
1140    OPC_NMSUB_S = 0x38 | OPC_CP3,
1141    OPC_NMSUB_D = 0x39 | OPC_CP3,
1142    OPC_NMSUB_PS= 0x3E | OPC_CP3,
1143};
1144
1145/* MSA Opcodes */
1146#define MASK_MSA_MINOR(op)    (MASK_OP_MAJOR(op) | (op & 0x3F))
1147enum {
1148    OPC_MSA_I8_00   = 0x00 | OPC_MSA,
1149    OPC_MSA_I8_01   = 0x01 | OPC_MSA,
1150    OPC_MSA_I8_02   = 0x02 | OPC_MSA,
1151    OPC_MSA_I5_06   = 0x06 | OPC_MSA,
1152    OPC_MSA_I5_07   = 0x07 | OPC_MSA,
1153    OPC_MSA_BIT_09  = 0x09 | OPC_MSA,
1154    OPC_MSA_BIT_0A  = 0x0A | OPC_MSA,
1155    OPC_MSA_3R_0D   = 0x0D | OPC_MSA,
1156    OPC_MSA_3R_0E   = 0x0E | OPC_MSA,
1157    OPC_MSA_3R_0F   = 0x0F | OPC_MSA,
1158    OPC_MSA_3R_10   = 0x10 | OPC_MSA,
1159    OPC_MSA_3R_11   = 0x11 | OPC_MSA,
1160    OPC_MSA_3R_12   = 0x12 | OPC_MSA,
1161    OPC_MSA_3R_13   = 0x13 | OPC_MSA,
1162    OPC_MSA_3R_14   = 0x14 | OPC_MSA,
1163    OPC_MSA_3R_15   = 0x15 | OPC_MSA,
1164    OPC_MSA_ELM     = 0x19 | OPC_MSA,
1165    OPC_MSA_3RF_1A  = 0x1A | OPC_MSA,
1166    OPC_MSA_3RF_1B  = 0x1B | OPC_MSA,
1167    OPC_MSA_3RF_1C  = 0x1C | OPC_MSA,
1168    OPC_MSA_VEC     = 0x1E | OPC_MSA,
1169
1170    /* MI10 instruction */
1171    OPC_LD_B    = (0x20) | OPC_MSA,
1172    OPC_LD_H    = (0x21) | OPC_MSA,
1173    OPC_LD_W    = (0x22) | OPC_MSA,
1174    OPC_LD_D    = (0x23) | OPC_MSA,
1175    OPC_ST_B    = (0x24) | OPC_MSA,
1176    OPC_ST_H    = (0x25) | OPC_MSA,
1177    OPC_ST_W    = (0x26) | OPC_MSA,
1178    OPC_ST_D    = (0x27) | OPC_MSA,
1179};
1180
1181enum {
1182    /* I5 instruction df(bits 22..21) = _b, _h, _w, _d */
1183    OPC_ADDVI_df    = (0x0 << 23) | OPC_MSA_I5_06,
1184    OPC_CEQI_df     = (0x0 << 23) | OPC_MSA_I5_07,
1185    OPC_SUBVI_df    = (0x1 << 23) | OPC_MSA_I5_06,
1186    OPC_MAXI_S_df   = (0x2 << 23) | OPC_MSA_I5_06,
1187    OPC_CLTI_S_df   = (0x2 << 23) | OPC_MSA_I5_07,
1188    OPC_MAXI_U_df   = (0x3 << 23) | OPC_MSA_I5_06,
1189    OPC_CLTI_U_df   = (0x3 << 23) | OPC_MSA_I5_07,
1190    OPC_MINI_S_df   = (0x4 << 23) | OPC_MSA_I5_06,
1191    OPC_CLEI_S_df   = (0x4 << 23) | OPC_MSA_I5_07,
1192    OPC_MINI_U_df   = (0x5 << 23) | OPC_MSA_I5_06,
1193    OPC_CLEI_U_df   = (0x5 << 23) | OPC_MSA_I5_07,
1194    OPC_LDI_df      = (0x6 << 23) | OPC_MSA_I5_07,
1195
1196    /* I8 instruction */
1197    OPC_ANDI_B  = (0x0 << 24) | OPC_MSA_I8_00,
1198    OPC_BMNZI_B = (0x0 << 24) | OPC_MSA_I8_01,
1199    OPC_SHF_B   = (0x0 << 24) | OPC_MSA_I8_02,
1200    OPC_ORI_B   = (0x1 << 24) | OPC_MSA_I8_00,
1201    OPC_BMZI_B  = (0x1 << 24) | OPC_MSA_I8_01,
1202    OPC_SHF_H   = (0x1 << 24) | OPC_MSA_I8_02,
1203    OPC_NORI_B  = (0x2 << 24) | OPC_MSA_I8_00,
1204    OPC_BSELI_B = (0x2 << 24) | OPC_MSA_I8_01,
1205    OPC_SHF_W   = (0x2 << 24) | OPC_MSA_I8_02,
1206    OPC_XORI_B  = (0x3 << 24) | OPC_MSA_I8_00,
1207
1208    /* VEC/2R/2RF instruction */
1209    OPC_AND_V   = (0x00 << 21) | OPC_MSA_VEC,
1210    OPC_OR_V    = (0x01 << 21) | OPC_MSA_VEC,
1211    OPC_NOR_V   = (0x02 << 21) | OPC_MSA_VEC,
1212    OPC_XOR_V   = (0x03 << 21) | OPC_MSA_VEC,
1213    OPC_BMNZ_V  = (0x04 << 21) | OPC_MSA_VEC,
1214    OPC_BMZ_V   = (0x05 << 21) | OPC_MSA_VEC,
1215    OPC_BSEL_V  = (0x06 << 21) | OPC_MSA_VEC,
1216
1217    OPC_MSA_2R      = (0x18 << 21) | OPC_MSA_VEC,
1218    OPC_MSA_2RF     = (0x19 << 21) | OPC_MSA_VEC,
1219
1220    /* 2R instruction df(bits 17..16) = _b, _h, _w, _d */
1221    OPC_FILL_df = (0x00 << 18) | OPC_MSA_2R,
1222    OPC_PCNT_df = (0x01 << 18) | OPC_MSA_2R,
1223    OPC_NLOC_df = (0x02 << 18) | OPC_MSA_2R,
1224    OPC_NLZC_df = (0x03 << 18) | OPC_MSA_2R,
1225
1226    /* 2RF instruction df(bit 16) = _w, _d */
1227    OPC_FCLASS_df   = (0x00 << 17) | OPC_MSA_2RF,
1228    OPC_FTRUNC_S_df = (0x01 << 17) | OPC_MSA_2RF,
1229    OPC_FTRUNC_U_df = (0x02 << 17) | OPC_MSA_2RF,
1230    OPC_FSQRT_df    = (0x03 << 17) | OPC_MSA_2RF,
1231    OPC_FRSQRT_df   = (0x04 << 17) | OPC_MSA_2RF,
1232    OPC_FRCP_df     = (0x05 << 17) | OPC_MSA_2RF,
1233    OPC_FRINT_df    = (0x06 << 17) | OPC_MSA_2RF,
1234    OPC_FLOG2_df    = (0x07 << 17) | OPC_MSA_2RF,
1235    OPC_FEXUPL_df   = (0x08 << 17) | OPC_MSA_2RF,
1236    OPC_FEXUPR_df   = (0x09 << 17) | OPC_MSA_2RF,
1237    OPC_FFQL_df     = (0x0A << 17) | OPC_MSA_2RF,
1238    OPC_FFQR_df     = (0x0B << 17) | OPC_MSA_2RF,
1239    OPC_FTINT_S_df  = (0x0C << 17) | OPC_MSA_2RF,
1240    OPC_FTINT_U_df  = (0x0D << 17) | OPC_MSA_2RF,
1241    OPC_FFINT_S_df  = (0x0E << 17) | OPC_MSA_2RF,
1242    OPC_FFINT_U_df  = (0x0F << 17) | OPC_MSA_2RF,
1243
1244    /* 3R instruction df(bits 22..21) = _b, _h, _w, d */
1245    OPC_SLL_df      = (0x0 << 23) | OPC_MSA_3R_0D,
1246    OPC_ADDV_df     = (0x0 << 23) | OPC_MSA_3R_0E,
1247    OPC_CEQ_df      = (0x0 << 23) | OPC_MSA_3R_0F,
1248    OPC_ADD_A_df    = (0x0 << 23) | OPC_MSA_3R_10,
1249    OPC_SUBS_S_df   = (0x0 << 23) | OPC_MSA_3R_11,
1250    OPC_MULV_df     = (0x0 << 23) | OPC_MSA_3R_12,
1251    OPC_DOTP_S_df   = (0x0 << 23) | OPC_MSA_3R_13,
1252    OPC_SLD_df      = (0x0 << 23) | OPC_MSA_3R_14,
1253    OPC_VSHF_df     = (0x0 << 23) | OPC_MSA_3R_15,
1254    OPC_SRA_df      = (0x1 << 23) | OPC_MSA_3R_0D,
1255    OPC_SUBV_df     = (0x1 << 23) | OPC_MSA_3R_0E,
1256    OPC_ADDS_A_df   = (0x1 << 23) | OPC_MSA_3R_10,
1257    OPC_SUBS_U_df   = (0x1 << 23) | OPC_MSA_3R_11,
1258    OPC_MADDV_df    = (0x1 << 23) | OPC_MSA_3R_12,
1259    OPC_DOTP_U_df   = (0x1 << 23) | OPC_MSA_3R_13,
1260    OPC_SPLAT_df    = (0x1 << 23) | OPC_MSA_3R_14,
1261    OPC_SRAR_df     = (0x1 << 23) | OPC_MSA_3R_15,
1262    OPC_SRL_df      = (0x2 << 23) | OPC_MSA_3R_0D,
1263    OPC_MAX_S_df    = (0x2 << 23) | OPC_MSA_3R_0E,
1264    OPC_CLT_S_df    = (0x2 << 23) | OPC_MSA_3R_0F,
1265    OPC_ADDS_S_df   = (0x2 << 23) | OPC_MSA_3R_10,
1266    OPC_SUBSUS_U_df = (0x2 << 23) | OPC_MSA_3R_11,
1267    OPC_MSUBV_df    = (0x2 << 23) | OPC_MSA_3R_12,
1268    OPC_DPADD_S_df  = (0x2 << 23) | OPC_MSA_3R_13,
1269    OPC_PCKEV_df    = (0x2 << 23) | OPC_MSA_3R_14,
1270    OPC_SRLR_df     = (0x2 << 23) | OPC_MSA_3R_15,
1271    OPC_BCLR_df     = (0x3 << 23) | OPC_MSA_3R_0D,
1272    OPC_MAX_U_df    = (0x3 << 23) | OPC_MSA_3R_0E,
1273    OPC_CLT_U_df    = (0x3 << 23) | OPC_MSA_3R_0F,
1274    OPC_ADDS_U_df   = (0x3 << 23) | OPC_MSA_3R_10,
1275    OPC_SUBSUU_S_df = (0x3 << 23) | OPC_MSA_3R_11,
1276    OPC_DPADD_U_df  = (0x3 << 23) | OPC_MSA_3R_13,
1277    OPC_PCKOD_df    = (0x3 << 23) | OPC_MSA_3R_14,
1278    OPC_BSET_df     = (0x4 << 23) | OPC_MSA_3R_0D,
1279    OPC_MIN_S_df    = (0x4 << 23) | OPC_MSA_3R_0E,
1280    OPC_CLE_S_df    = (0x4 << 23) | OPC_MSA_3R_0F,
1281    OPC_AVE_S_df    = (0x4 << 23) | OPC_MSA_3R_10,
1282    OPC_ASUB_S_df   = (0x4 << 23) | OPC_MSA_3R_11,
1283    OPC_DIV_S_df    = (0x4 << 23) | OPC_MSA_3R_12,
1284    OPC_DPSUB_S_df  = (0x4 << 23) | OPC_MSA_3R_13,
1285    OPC_ILVL_df     = (0x4 << 23) | OPC_MSA_3R_14,
1286    OPC_HADD_S_df   = (0x4 << 23) | OPC_MSA_3R_15,
1287    OPC_BNEG_df     = (0x5 << 23) | OPC_MSA_3R_0D,
1288    OPC_MIN_U_df    = (0x5 << 23) | OPC_MSA_3R_0E,
1289    OPC_CLE_U_df    = (0x5 << 23) | OPC_MSA_3R_0F,
1290    OPC_AVE_U_df    = (0x5 << 23) | OPC_MSA_3R_10,
1291    OPC_ASUB_U_df   = (0x5 << 23) | OPC_MSA_3R_11,
1292    OPC_DIV_U_df    = (0x5 << 23) | OPC_MSA_3R_12,
1293    OPC_DPSUB_U_df  = (0x5 << 23) | OPC_MSA_3R_13,
1294    OPC_ILVR_df     = (0x5 << 23) | OPC_MSA_3R_14,
1295    OPC_HADD_U_df   = (0x5 << 23) | OPC_MSA_3R_15,
1296    OPC_BINSL_df    = (0x6 << 23) | OPC_MSA_3R_0D,
1297    OPC_MAX_A_df    = (0x6 << 23) | OPC_MSA_3R_0E,
1298    OPC_AVER_S_df   = (0x6 << 23) | OPC_MSA_3R_10,
1299    OPC_MOD_S_df    = (0x6 << 23) | OPC_MSA_3R_12,
1300    OPC_ILVEV_df    = (0x6 << 23) | OPC_MSA_3R_14,
1301    OPC_HSUB_S_df   = (0x6 << 23) | OPC_MSA_3R_15,
1302    OPC_BINSR_df    = (0x7 << 23) | OPC_MSA_3R_0D,
1303    OPC_MIN_A_df    = (0x7 << 23) | OPC_MSA_3R_0E,
1304    OPC_AVER_U_df   = (0x7 << 23) | OPC_MSA_3R_10,
1305    OPC_MOD_U_df    = (0x7 << 23) | OPC_MSA_3R_12,
1306    OPC_ILVOD_df    = (0x7 << 23) | OPC_MSA_3R_14,
1307    OPC_HSUB_U_df   = (0x7 << 23) | OPC_MSA_3R_15,
1308
1309    /* ELM instructions df(bits 21..16) = _b, _h, _w, _d */
1310    OPC_SLDI_df     = (0x0 << 22) | (0x00 << 16) | OPC_MSA_ELM,
1311    OPC_CTCMSA      = (0x0 << 22) | (0x3E << 16) | OPC_MSA_ELM,
1312    OPC_SPLATI_df   = (0x1 << 22) | (0x00 << 16) | OPC_MSA_ELM,
1313    OPC_CFCMSA      = (0x1 << 22) | (0x3E << 16) | OPC_MSA_ELM,
1314    OPC_COPY_S_df   = (0x2 << 22) | (0x00 << 16) | OPC_MSA_ELM,
1315    OPC_MOVE_V      = (0x2 << 22) | (0x3E << 16) | OPC_MSA_ELM,
1316    OPC_COPY_U_df   = (0x3 << 22) | (0x00 << 16) | OPC_MSA_ELM,
1317    OPC_INSERT_df   = (0x4 << 22) | (0x00 << 16) | OPC_MSA_ELM,
1318    OPC_INSVE_df    = (0x5 << 22) | (0x00 << 16) | OPC_MSA_ELM,
1319
1320    /* 3RF instruction _df(bit 21) = _w, _d */
1321    OPC_FCAF_df     = (0x0 << 22) | OPC_MSA_3RF_1A,
1322    OPC_FADD_df     = (0x0 << 22) | OPC_MSA_3RF_1B,
1323    OPC_FCUN_df     = (0x1 << 22) | OPC_MSA_3RF_1A,
1324    OPC_FSUB_df     = (0x1 << 22) | OPC_MSA_3RF_1B,
1325    OPC_FCOR_df     = (0x1 << 22) | OPC_MSA_3RF_1C,
1326    OPC_FCEQ_df     = (0x2 << 22) | OPC_MSA_3RF_1A,
1327    OPC_FMUL_df     = (0x2 << 22) | OPC_MSA_3RF_1B,
1328    OPC_FCUNE_df    = (0x2 << 22) | OPC_MSA_3RF_1C,
1329    OPC_FCUEQ_df    = (0x3 << 22) | OPC_MSA_3RF_1A,
1330    OPC_FDIV_df     = (0x3 << 22) | OPC_MSA_3RF_1B,
1331    OPC_FCNE_df     = (0x3 << 22) | OPC_MSA_3RF_1C,
1332    OPC_FCLT_df     = (0x4 << 22) | OPC_MSA_3RF_1A,
1333    OPC_FMADD_df    = (0x4 << 22) | OPC_MSA_3RF_1B,
1334    OPC_MUL_Q_df    = (0x4 << 22) | OPC_MSA_3RF_1C,
1335    OPC_FCULT_df    = (0x5 << 22) | OPC_MSA_3RF_1A,
1336    OPC_FMSUB_df    = (0x5 << 22) | OPC_MSA_3RF_1B,
1337    OPC_MADD_Q_df   = (0x5 << 22) | OPC_MSA_3RF_1C,
1338    OPC_FCLE_df     = (0x6 << 22) | OPC_MSA_3RF_1A,
1339    OPC_MSUB_Q_df   = (0x6 << 22) | OPC_MSA_3RF_1C,
1340    OPC_FCULE_df    = (0x7 << 22) | OPC_MSA_3RF_1A,
1341    OPC_FEXP2_df    = (0x7 << 22) | OPC_MSA_3RF_1B,
1342    OPC_FSAF_df     = (0x8 << 22) | OPC_MSA_3RF_1A,
1343    OPC_FEXDO_df    = (0x8 << 22) | OPC_MSA_3RF_1B,
1344    OPC_FSUN_df     = (0x9 << 22) | OPC_MSA_3RF_1A,
1345    OPC_FSOR_df     = (0x9 << 22) | OPC_MSA_3RF_1C,
1346    OPC_FSEQ_df     = (0xA << 22) | OPC_MSA_3RF_1A,
1347    OPC_FTQ_df      = (0xA << 22) | OPC_MSA_3RF_1B,
1348    OPC_FSUNE_df    = (0xA << 22) | OPC_MSA_3RF_1C,
1349    OPC_FSUEQ_df    = (0xB << 22) | OPC_MSA_3RF_1A,
1350    OPC_FSNE_df     = (0xB << 22) | OPC_MSA_3RF_1C,
1351    OPC_FSLT_df     = (0xC << 22) | OPC_MSA_3RF_1A,
1352    OPC_FMIN_df     = (0xC << 22) | OPC_MSA_3RF_1B,
1353    OPC_MULR_Q_df   = (0xC << 22) | OPC_MSA_3RF_1C,
1354    OPC_FSULT_df    = (0xD << 22) | OPC_MSA_3RF_1A,
1355    OPC_FMIN_A_df   = (0xD << 22) | OPC_MSA_3RF_1B,
1356    OPC_MADDR_Q_df  = (0xD << 22) | OPC_MSA_3RF_1C,
1357    OPC_FSLE_df     = (0xE << 22) | OPC_MSA_3RF_1A,
1358    OPC_FMAX_df     = (0xE << 22) | OPC_MSA_3RF_1B,
1359    OPC_MSUBR_Q_df  = (0xE << 22) | OPC_MSA_3RF_1C,
1360    OPC_FSULE_df    = (0xF << 22) | OPC_MSA_3RF_1A,
1361    OPC_FMAX_A_df   = (0xF << 22) | OPC_MSA_3RF_1B,
1362
1363    /* BIT instruction df(bits 22..16) = _B _H _W _D */
1364    OPC_SLLI_df     = (0x0 << 23) | OPC_MSA_BIT_09,
1365    OPC_SAT_S_df    = (0x0 << 23) | OPC_MSA_BIT_0A,
1366    OPC_SRAI_df     = (0x1 << 23) | OPC_MSA_BIT_09,
1367    OPC_SAT_U_df    = (0x1 << 23) | OPC_MSA_BIT_0A,
1368    OPC_SRLI_df     = (0x2 << 23) | OPC_MSA_BIT_09,
1369    OPC_SRARI_df    = (0x2 << 23) | OPC_MSA_BIT_0A,
1370    OPC_BCLRI_df    = (0x3 << 23) | OPC_MSA_BIT_09,
1371    OPC_SRLRI_df    = (0x3 << 23) | OPC_MSA_BIT_0A,
1372    OPC_BSETI_df    = (0x4 << 23) | OPC_MSA_BIT_09,
1373    OPC_BNEGI_df    = (0x5 << 23) | OPC_MSA_BIT_09,
1374    OPC_BINSLI_df   = (0x6 << 23) | OPC_MSA_BIT_09,
1375    OPC_BINSRI_df   = (0x7 << 23) | OPC_MSA_BIT_09,
1376};
1377
1378/* global register indices */
1379static TCGv cpu_gpr[32], cpu_PC;
1380static TCGv cpu_HI[MIPS_DSP_ACC], cpu_LO[MIPS_DSP_ACC];
1381static TCGv cpu_dspctrl, btarget, bcond;
1382static TCGv_i32 hflags;
1383static TCGv_i32 fpu_fcr0, fpu_fcr31;
1384static TCGv_i64 fpu_f64[32];
1385static TCGv_i64 msa_wr_d[64];
1386
1387#include "exec/gen-icount.h"
1388
1389#define gen_helper_0e0i(name, arg) do {                           \
1390    TCGv_i32 helper_tmp = tcg_const_i32(arg);                     \
1391    gen_helper_##name(cpu_env, helper_tmp);                       \
1392    tcg_temp_free_i32(helper_tmp);                                \
1393    } while(0)
1394
1395#define gen_helper_0e1i(name, arg1, arg2) do {                    \
1396    TCGv_i32 helper_tmp = tcg_const_i32(arg2);                    \
1397    gen_helper_##name(cpu_env, arg1, helper_tmp);                 \
1398    tcg_temp_free_i32(helper_tmp);                                \
1399    } while(0)
1400
1401#define gen_helper_1e0i(name, ret, arg1) do {                     \
1402    TCGv_i32 helper_tmp = tcg_const_i32(arg1);                    \
1403    gen_helper_##name(ret, cpu_env, helper_tmp);                  \
1404    tcg_temp_free_i32(helper_tmp);                                \
1405    } while(0)
1406
1407#define gen_helper_1e1i(name, ret, arg1, arg2) do {               \
1408    TCGv_i32 helper_tmp = tcg_const_i32(arg2);                    \
1409    gen_helper_##name(ret, cpu_env, arg1, helper_tmp);            \
1410    tcg_temp_free_i32(helper_tmp);                                \
1411    } while(0)
1412
1413#define gen_helper_0e2i(name, arg1, arg2, arg3) do {              \
1414    TCGv_i32 helper_tmp = tcg_const_i32(arg3);                    \
1415    gen_helper_##name(cpu_env, arg1, arg2, helper_tmp);           \
1416    tcg_temp_free_i32(helper_tmp);                                \
1417    } while(0)
1418
1419#define gen_helper_1e2i(name, ret, arg1, arg2, arg3) do {         \
1420    TCGv_i32 helper_tmp = tcg_const_i32(arg3);                    \
1421    gen_helper_##name(ret, cpu_env, arg1, arg2, helper_tmp);      \
1422    tcg_temp_free_i32(helper_tmp);                                \
1423    } while(0)
1424
1425#define gen_helper_0e3i(name, arg1, arg2, arg3, arg4) do {        \
1426    TCGv_i32 helper_tmp = tcg_const_i32(arg4);                    \
1427    gen_helper_##name(cpu_env, arg1, arg2, arg3, helper_tmp);     \
1428    tcg_temp_free_i32(helper_tmp);                                \
1429    } while(0)
1430
1431typedef struct DisasContext {
1432    struct TranslationBlock *tb;
1433    target_ulong pc, saved_pc;
1434    uint32_t opcode;
1435    int singlestep_enabled;
1436    int insn_flags;
1437    int32_t CP0_Config1;
1438    /* Routine used to access memory */
1439    int mem_idx;
1440    TCGMemOp default_tcg_memop_mask;
1441    uint32_t hflags, saved_hflags;
1442    int bstate;
1443    target_ulong btarget;
1444    bool ulri;
1445    int kscrexist;
1446    bool rxi;
1447    int ie;
1448    bool bi;
1449    bool bp;
1450    uint64_t PAMask;
1451    bool mvh;
1452    bool eva;
1453    bool sc;
1454    int CP0_LLAddr_shift;
1455    bool ps;
1456    bool vp;
1457    bool cmgcr;
1458    bool mrp;
1459    bool nan2008;
1460    bool abs2008;
1461} DisasContext;
1462
1463enum {
1464    BS_NONE     = 0, /* We go out of the TB without reaching a branch or an
1465                      * exception condition */
1466    BS_STOP     = 1, /* We want to stop translation for any reason */
1467    BS_BRANCH   = 2, /* We reached a branch condition     */
1468    BS_EXCP     = 3, /* We reached an exception condition */
1469};
1470
1471static const char * const regnames[] = {
1472    "r0", "at", "v0", "v1", "a0", "a1", "a2", "a3",
1473    "t0", "t1", "t2", "t3", "t4", "t5", "t6", "t7",
1474    "s0", "s1", "s2", "s3", "s4", "s5", "s6", "s7",
1475    "t8", "t9", "k0", "k1", "gp", "sp", "s8", "ra",
1476};
1477
1478static const char * const regnames_HI[] = {
1479    "HI0", "HI1", "HI2", "HI3",
1480};
1481
1482static const char * const regnames_LO[] = {
1483    "LO0", "LO1", "LO2", "LO3",
1484};
1485
1486static const char * const fregnames[] = {
1487    "f0",  "f1",  "f2",  "f3",  "f4",  "f5",  "f6",  "f7",
1488    "f8",  "f9",  "f10", "f11", "f12", "f13", "f14", "f15",
1489    "f16", "f17", "f18", "f19", "f20", "f21", "f22", "f23",
1490    "f24", "f25", "f26", "f27", "f28", "f29", "f30", "f31",
1491};
1492
1493static const char * const msaregnames[] = {
1494    "w0.d0",  "w0.d1",  "w1.d0",  "w1.d1",
1495    "w2.d0",  "w2.d1",  "w3.d0",  "w3.d1",
1496    "w4.d0",  "w4.d1",  "w5.d0",  "w5.d1",
1497    "w6.d0",  "w6.d1",  "w7.d0",  "w7.d1",
1498    "w8.d0",  "w8.d1",  "w9.d0",  "w9.d1",
1499    "w10.d0", "w10.d1", "w11.d0", "w11.d1",
1500    "w12.d0", "w12.d1", "w13.d0", "w13.d1",
1501    "w14.d0", "w14.d1", "w15.d0", "w15.d1",
1502    "w16.d0", "w16.d1", "w17.d0", "w17.d1",
1503    "w18.d0", "w18.d1", "w19.d0", "w19.d1",
1504    "w20.d0", "w20.d1", "w21.d0", "w21.d1",
1505    "w22.d0", "w22.d1", "w23.d0", "w23.d1",
1506    "w24.d0", "w24.d1", "w25.d0", "w25.d1",
1507    "w26.d0", "w26.d1", "w27.d0", "w27.d1",
1508    "w28.d0", "w28.d1", "w29.d0", "w29.d1",
1509    "w30.d0", "w30.d1", "w31.d0", "w31.d1",
1510};
1511
1512#define LOG_DISAS(...)                                                        \
1513    do {                                                                      \
1514        if (MIPS_DEBUG_DISAS) {                                               \
1515            qemu_log_mask(CPU_LOG_TB_IN_ASM, ## __VA_ARGS__);                 \
1516        }                                                                     \
1517    } while (0)
1518
1519#define MIPS_INVAL(op)                                                        \
1520    do {                                                                      \
1521        if (MIPS_DEBUG_DISAS) {                                               \
1522            qemu_log_mask(CPU_LOG_TB_IN_ASM,                                  \
1523                          TARGET_FMT_lx ": %08x Invalid %s %03x %03x %03x\n", \
1524                          ctx->pc, ctx->opcode, op, ctx->opcode >> 26,        \
1525                          ctx->opcode & 0x3F, ((ctx->opcode >> 16) & 0x1F));  \
1526        }                                                                     \
1527    } while (0)
1528
1529/* General purpose registers moves. */
1530static inline void gen_load_gpr (TCGv t, int reg)
1531{
1532    if (reg == 0)
1533        tcg_gen_movi_tl(t, 0);
1534    else
1535        tcg_gen_mov_tl(t, cpu_gpr[reg]);
1536}
1537
1538static inline void gen_store_gpr (TCGv t, int reg)
1539{
1540    if (reg != 0)
1541        tcg_gen_mov_tl(cpu_gpr[reg], t);
1542}
1543
1544/* Moves to/from shadow registers. */
1545static inline void gen_load_srsgpr (int from, int to)
1546{
1547    TCGv t0 = tcg_temp_new();
1548
1549    if (from == 0)
1550        tcg_gen_movi_tl(t0, 0);
1551    else {
1552        TCGv_i32 t2 = tcg_temp_new_i32();
1553        TCGv_ptr addr = tcg_temp_new_ptr();
1554
1555        tcg_gen_ld_i32(t2, cpu_env, offsetof(CPUMIPSState, CP0_SRSCtl));
1556        tcg_gen_shri_i32(t2, t2, CP0SRSCtl_PSS);
1557        tcg_gen_andi_i32(t2, t2, 0xf);
1558        tcg_gen_muli_i32(t2, t2, sizeof(target_ulong) * 32);
1559        tcg_gen_ext_i32_ptr(addr, t2);
1560        tcg_gen_add_ptr(addr, cpu_env, addr);
1561
1562        tcg_gen_ld_tl(t0, addr, sizeof(target_ulong) * from);
1563        tcg_temp_free_ptr(addr);
1564        tcg_temp_free_i32(t2);
1565    }
1566    gen_store_gpr(t0, to);
1567    tcg_temp_free(t0);
1568}
1569
1570static inline void gen_store_srsgpr (int from, int to)
1571{
1572    if (to != 0) {
1573        TCGv t0 = tcg_temp_new();
1574        TCGv_i32 t2 = tcg_temp_new_i32();
1575        TCGv_ptr addr = tcg_temp_new_ptr();
1576
1577        gen_load_gpr(t0, from);
1578        tcg_gen_ld_i32(t2, cpu_env, offsetof(CPUMIPSState, CP0_SRSCtl));
1579        tcg_gen_shri_i32(t2, t2, CP0SRSCtl_PSS);
1580        tcg_gen_andi_i32(t2, t2, 0xf);
1581        tcg_gen_muli_i32(t2, t2, sizeof(target_ulong) * 32);
1582        tcg_gen_ext_i32_ptr(addr, t2);
1583        tcg_gen_add_ptr(addr, cpu_env, addr);
1584
1585        tcg_gen_st_tl(t0, addr, sizeof(target_ulong) * to);
1586        tcg_temp_free_ptr(addr);
1587        tcg_temp_free_i32(t2);
1588        tcg_temp_free(t0);
1589    }
1590}
1591
1592/* Tests */
1593static inline void gen_save_pc(target_ulong pc)
1594{
1595    tcg_gen_movi_tl(cpu_PC, pc);
1596}
1597
1598static inline void save_cpu_state(DisasContext *ctx, int do_save_pc)
1599{
1600    LOG_DISAS("hflags %08x saved %08x\n", ctx->hflags, ctx->saved_hflags);
1601    if (do_save_pc && ctx->pc != ctx->saved_pc) {
1602        gen_save_pc(ctx->pc);
1603        ctx->saved_pc = ctx->pc;
1604    }
1605    if (ctx->hflags != ctx->saved_hflags) {
1606        tcg_gen_movi_i32(hflags, ctx->hflags);
1607        ctx->saved_hflags = ctx->hflags;
1608        switch (ctx->hflags & MIPS_HFLAG_BMASK_BASE) {
1609        case MIPS_HFLAG_BR:
1610            break;
1611        case MIPS_HFLAG_BC:
1612        case MIPS_HFLAG_BL:
1613        case MIPS_HFLAG_B:
1614            tcg_gen_movi_tl(btarget, ctx->btarget);
1615            break;
1616        }
1617    }
1618}
1619
1620static inline void restore_cpu_state(CPUMIPSState *env, DisasContext *ctx)
1621{
1622    ctx->saved_hflags = ctx->hflags;
1623    switch (ctx->hflags & MIPS_HFLAG_BMASK_BASE) {
1624    case MIPS_HFLAG_BR:
1625        break;
1626    case MIPS_HFLAG_BC:
1627    case MIPS_HFLAG_BL:
1628    case MIPS_HFLAG_B:
1629        ctx->btarget = env->btarget;
1630        break;
1631    }
1632}
1633
1634static inline void generate_exception_err(DisasContext *ctx, int excp, int err)
1635{
1636    TCGv_i32 texcp = tcg_const_i32(excp);
1637    TCGv_i32 terr = tcg_const_i32(err);
1638    save_cpu_state(ctx, 1);
1639    gen_helper_raise_exception_err(cpu_env, texcp, terr);
1640    tcg_temp_free_i32(terr);
1641    tcg_temp_free_i32(texcp);
1642    ctx->bstate = BS_EXCP;
1643}
1644
1645static inline void generate_exception(DisasContext *ctx, int excp)
1646{
1647    gen_helper_0e0i(raise_exception, excp);
1648}
1649
1650static inline void generate_exception_end(DisasContext *ctx, int excp)
1651{
1652    generate_exception_err(ctx, excp, 0);
1653}
1654
1655/* Floating point register moves. */
1656static void gen_load_fpr32(DisasContext *ctx, TCGv_i32 t, int reg)
1657{
1658    if (ctx->hflags & MIPS_HFLAG_FRE) {
1659        generate_exception(ctx, EXCP_RI);
1660    }
1661    tcg_gen_extrl_i64_i32(t, fpu_f64[reg]);
1662}
1663
1664static void gen_store_fpr32(DisasContext *ctx, TCGv_i32 t, int reg)
1665{
1666    TCGv_i64 t64;
1667    if (ctx->hflags & MIPS_HFLAG_FRE) {
1668        generate_exception(ctx, EXCP_RI);
1669    }
1670    t64 = tcg_temp_new_i64();
1671    tcg_gen_extu_i32_i64(t64, t);
1672    tcg_gen_deposit_i64(fpu_f64[reg], fpu_f64[reg], t64, 0, 32);
1673    tcg_temp_free_i64(t64);
1674}
1675
1676static void gen_load_fpr32h(DisasContext *ctx, TCGv_i32 t, int reg)
1677{
1678    if (ctx->hflags & MIPS_HFLAG_F64) {
1679        tcg_gen_extrh_i64_i32(t, fpu_f64[reg]);
1680    } else {
1681        gen_load_fpr32(ctx, t, reg | 1);
1682    }
1683}
1684
1685static void gen_store_fpr32h(DisasContext *ctx, TCGv_i32 t, int reg)
1686{
1687    if (ctx->hflags & MIPS_HFLAG_F64) {
1688        TCGv_i64 t64 = tcg_temp_new_i64();
1689        tcg_gen_extu_i32_i64(t64, t);
1690        tcg_gen_deposit_i64(fpu_f64[reg], fpu_f64[reg], t64, 32, 32);
1691        tcg_temp_free_i64(t64);
1692    } else {
1693        gen_store_fpr32(ctx, t, reg | 1);
1694    }
1695}
1696
1697static void gen_load_fpr64(DisasContext *ctx, TCGv_i64 t, int reg)
1698{
1699    if (ctx->hflags & MIPS_HFLAG_F64) {
1700        tcg_gen_mov_i64(t, fpu_f64[reg]);
1701    } else {
1702        tcg_gen_concat32_i64(t, fpu_f64[reg & ~1], fpu_f64[reg | 1]);
1703    }
1704}
1705
1706static void gen_store_fpr64(DisasContext *ctx, TCGv_i64 t, int reg)
1707{
1708    if (ctx->hflags & MIPS_HFLAG_F64) {
1709        tcg_gen_mov_i64(fpu_f64[reg], t);
1710    } else {
1711        TCGv_i64 t0;
1712        tcg_gen_deposit_i64(fpu_f64[reg & ~1], fpu_f64[reg & ~1], t, 0, 32);
1713        t0 = tcg_temp_new_i64();
1714        tcg_gen_shri_i64(t0, t, 32);
1715        tcg_gen_deposit_i64(fpu_f64[reg | 1], fpu_f64[reg | 1], t0, 0, 32);
1716        tcg_temp_free_i64(t0);
1717    }
1718}
1719
1720static inline int get_fp_bit (int cc)
1721{
1722    if (cc)
1723        return 24 + cc;
1724    else
1725        return 23;
1726}
1727
1728/* Addresses computation */
1729static inline void gen_op_addr_add (DisasContext *ctx, TCGv ret, TCGv arg0, TCGv arg1)
1730{
1731    tcg_gen_add_tl(ret, arg0, arg1);
1732
1733#if defined(TARGET_MIPS64)
1734    if (ctx->hflags & MIPS_HFLAG_AWRAP) {
1735        tcg_gen_ext32s_i64(ret, ret);
1736    }
1737#endif
1738}
1739
1740/* Addresses computation (translation time) */
1741static target_long addr_add(DisasContext *ctx, target_long base,
1742                            target_long offset)
1743{
1744    target_long sum = base + offset;
1745
1746#if defined(TARGET_MIPS64)
1747    if (ctx->hflags & MIPS_HFLAG_AWRAP) {
1748        sum = (int32_t)sum;
1749    }
1750#endif
1751    return sum;
1752}
1753
1754/* Sign-extract the low 32-bits to a target_long.  */
1755static inline void gen_move_low32(TCGv ret, TCGv_i64 arg)
1756{
1757#if defined(TARGET_MIPS64)
1758    tcg_gen_ext32s_i64(ret, arg);
1759#else
1760    tcg_gen_extrl_i64_i32(ret, arg);
1761#endif
1762}
1763
1764/* Sign-extract the high 32-bits to a target_long.  */
1765static inline void gen_move_high32(TCGv ret, TCGv_i64 arg)
1766{
1767#if defined(TARGET_MIPS64)
1768    tcg_gen_sari_i64(ret, arg, 32);
1769#else
1770    tcg_gen_extrh_i64_i32(ret, arg);
1771#endif
1772}
1773
1774static inline void check_cp0_enabled(DisasContext *ctx)
1775{
1776    if (unlikely(!(ctx->hflags & MIPS_HFLAG_CP0)))
1777        generate_exception_err(ctx, EXCP_CpU, 0);
1778}
1779
1780static inline void check_cp1_enabled(DisasContext *ctx)
1781{
1782    if (unlikely(!(ctx->hflags & MIPS_HFLAG_FPU)))
1783        generate_exception_err(ctx, EXCP_CpU, 1);
1784}
1785
1786/* Verify that the processor is running with COP1X instructions enabled.
1787   This is associated with the nabla symbol in the MIPS32 and MIPS64
1788   opcode tables.  */
1789
1790static inline void check_cop1x(DisasContext *ctx)
1791{
1792    if (unlikely(!(ctx->hflags & MIPS_HFLAG_COP1X)))
1793        generate_exception_end(ctx, EXCP_RI);
1794}
1795
1796/* Verify that the processor is running with 64-bit floating-point
1797   operations enabled.  */
1798
1799static inline void check_cp1_64bitmode(DisasContext *ctx)
1800{
1801    if (unlikely(~ctx->hflags & (MIPS_HFLAG_F64 | MIPS_HFLAG_COP1X)))
1802        generate_exception_end(ctx, EXCP_RI);
1803}
1804
1805/*
1806 * Verify if floating point register is valid; an operation is not defined
1807 * if bit 0 of any register specification is set and the FR bit in the
1808 * Status register equals zero, since the register numbers specify an
1809 * even-odd pair of adjacent coprocessor general registers. When the FR bit
1810 * in the Status register equals one, both even and odd register numbers
1811 * are valid. This limitation exists only for 64 bit wide (d,l,ps) registers.
1812 *
1813 * Multiple 64 bit wide registers can be checked by calling
1814 * gen_op_cp1_registers(freg1 | freg2 | ... | fregN);
1815 */
1816static inline void check_cp1_registers(DisasContext *ctx, int regs)
1817{
1818    if (unlikely(!(ctx->hflags & MIPS_HFLAG_F64) && (regs & 1)))
1819        generate_exception_end(ctx, EXCP_RI);
1820}
1821
1822/* Verify that the processor is running with DSP instructions enabled.
1823   This is enabled by CP0 Status register MX(24) bit.
1824 */
1825
1826static inline void check_dsp(DisasContext *ctx)
1827{
1828    if (unlikely(!(ctx->hflags & MIPS_HFLAG_DSP))) {
1829        if (ctx->insn_flags & ASE_DSP) {
1830            generate_exception_end(ctx, EXCP_DSPDIS);
1831        } else {
1832            generate_exception_end(ctx, EXCP_RI);
1833        }
1834    }
1835}
1836
1837static inline void check_dspr2(DisasContext *ctx)
1838{
1839    if (unlikely(!(ctx->hflags & MIPS_HFLAG_DSPR2))) {
1840        if (ctx->insn_flags & ASE_DSP) {
1841            generate_exception_end(ctx, EXCP_DSPDIS);
1842        } else {
1843            generate_exception_end(ctx, EXCP_RI);
1844        }
1845    }
1846}
1847
1848/* This code generates a "reserved instruction" exception if the
1849   CPU does not support the instruction set corresponding to flags. */
1850static inline void check_insn(DisasContext *ctx, int flags)
1851{
1852    if (unlikely(!(ctx->insn_flags & flags))) {
1853        generate_exception_end(ctx, EXCP_RI);
1854    }
1855}
1856
1857/* This code generates a "reserved instruction" exception if the
1858   CPU has corresponding flag set which indicates that the instruction
1859   has been removed. */
1860static inline void check_insn_opc_removed(DisasContext *ctx, int flags)
1861{
1862    if (unlikely(ctx->insn_flags & flags)) {
1863        generate_exception_end(ctx, EXCP_RI);
1864    }
1865}
1866
1867/* This code generates a "reserved instruction" exception if the
1868   CPU does not support 64-bit paired-single (PS) floating point data type */
1869static inline void check_ps(DisasContext *ctx)
1870{
1871    if (unlikely(!ctx->ps)) {
1872        generate_exception(ctx, EXCP_RI);
1873    }
1874    check_cp1_64bitmode(ctx);
1875}
1876
1877#ifdef TARGET_MIPS64
1878/* This code generates a "reserved instruction" exception if 64-bit
1879   instructions are not enabled. */
1880static inline void check_mips_64(DisasContext *ctx)
1881{
1882    if (unlikely(!(ctx->hflags & MIPS_HFLAG_64)))
1883        generate_exception_end(ctx, EXCP_RI);
1884}
1885#endif
1886
1887#ifndef CONFIG_USER_ONLY
1888static inline void check_mvh(DisasContext *ctx)
1889{
1890    if (unlikely(!ctx->mvh)) {
1891        generate_exception(ctx, EXCP_RI);
1892    }
1893}
1894#endif
1895
1896/* Define small wrappers for gen_load_fpr* so that we have a uniform
1897   calling interface for 32 and 64-bit FPRs.  No sense in changing
1898   all callers for gen_load_fpr32 when we need the CTX parameter for
1899   this one use.  */
1900#define gen_ldcmp_fpr32(ctx, x, y) gen_load_fpr32(ctx, x, y)
1901#define gen_ldcmp_fpr64(ctx, x, y) gen_load_fpr64(ctx, x, y)
1902#define FOP_CONDS(type, abs, fmt, ifmt, bits)                                 \
1903static inline void gen_cmp ## type ## _ ## fmt(DisasContext *ctx, int n,      \
1904                                               int ft, int fs, int cc)        \
1905{                                                                             \
1906    TCGv_i##bits fp0 = tcg_temp_new_i##bits ();                               \
1907    TCGv_i##bits fp1 = tcg_temp_new_i##bits ();                               \
1908    switch (ifmt) {                                                           \
1909    case FMT_PS:                                                              \
1910        check_ps(ctx);                                                        \
1911        break;                                                                \
1912    case FMT_D:                                                               \
1913        if (abs) {                                                            \
1914            check_cop1x(ctx);                                                 \
1915        }                                                                     \
1916        check_cp1_registers(ctx, fs | ft);                                    \
1917        break;                                                                \
1918    case FMT_S:                                                               \
1919        if (abs) {                                                            \
1920            check_cop1x(ctx);                                                 \
1921        }                                                                     \
1922        break;                                                                \
1923    }                                                                         \
1924    gen_ldcmp_fpr##bits (ctx, fp0, fs);                                       \
1925    gen_ldcmp_fpr##bits (ctx, fp1, ft);                                       \
1926    switch (n) {                                                              \
1927    case  0: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _f, fp0, fp1, cc);    break;\
1928    case  1: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _un, fp0, fp1, cc);   break;\
1929    case  2: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _eq, fp0, fp1, cc);   break;\
1930    case  3: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ueq, fp0, fp1, cc);  break;\
1931    case  4: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _olt, fp0, fp1, cc);  break;\
1932    case  5: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ult, fp0, fp1, cc);  break;\
1933    case  6: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ole, fp0, fp1, cc);  break;\
1934    case  7: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ule, fp0, fp1, cc);  break;\
1935    case  8: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _sf, fp0, fp1, cc);   break;\
1936    case  9: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ngle, fp0, fp1, cc); break;\
1937    case 10: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _seq, fp0, fp1, cc);  break;\
1938    case 11: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ngl, fp0, fp1, cc);  break;\
1939    case 12: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _lt, fp0, fp1, cc);   break;\
1940    case 13: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _nge, fp0, fp1, cc);  break;\
1941    case 14: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _le, fp0, fp1, cc);   break;\
1942    case 15: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ngt, fp0, fp1, cc);  break;\
1943    default: abort();                                                         \
1944    }                                                                         \
1945    tcg_temp_free_i##bits (fp0);                                              \
1946    tcg_temp_free_i##bits (fp1);                                              \
1947}
1948
1949FOP_CONDS(, 0, d, FMT_D, 64)
1950FOP_CONDS(abs, 1, d, FMT_D, 64)
1951FOP_CONDS(, 0, s, FMT_S, 32)
1952FOP_CONDS(abs, 1, s, FMT_S, 32)
1953FOP_CONDS(, 0, ps, FMT_PS, 64)
1954FOP_CONDS(abs, 1, ps, FMT_PS, 64)
1955#undef FOP_CONDS
1956
1957#define FOP_CONDNS(fmt, ifmt, bits, STORE)                              \
1958static inline void gen_r6_cmp_ ## fmt(DisasContext * ctx, int n,        \
1959                                      int ft, int fs, int fd)           \
1960{                                                                       \
1961    TCGv_i ## bits fp0 = tcg_temp_new_i ## bits();                      \
1962    TCGv_i ## bits fp1 = tcg_temp_new_i ## bits();                      \
1963    if (ifmt == FMT_D) {                                                \
1964        check_cp1_registers(ctx, fs | ft | fd);                         \
1965    }                                                                   \
1966    gen_ldcmp_fpr ## bits(ctx, fp0, fs);                                \
1967    gen_ldcmp_fpr ## bits(ctx, fp1, ft);                                \
1968    switch (n) {                                                        \
1969    case  0:                                                            \
1970        gen_helper_r6_cmp_ ## fmt ## _af(fp0, cpu_env, fp0, fp1);       \
1971        break;                                                          \
1972    case  1:                                                            \
1973        gen_helper_r6_cmp_ ## fmt ## _un(fp0, cpu_env, fp0, fp1);       \
1974        break;                                                          \
1975    case  2:                                                            \
1976        gen_helper_r6_cmp_ ## fmt ## _eq(fp0, cpu_env, fp0, fp1);       \
1977        break;                                                          \
1978    case  3:                                                            \
1979        gen_helper_r6_cmp_ ## fmt ## _ueq(fp0, cpu_env, fp0, fp1);      \
1980        break;                                                          \
1981    case  4:                                                            \
1982        gen_helper_r6_cmp_ ## fmt ## _lt(fp0, cpu_env, fp0, fp1);       \
1983        break;                                                          \
1984    case  5:                                                            \
1985        gen_helper_r6_cmp_ ## fmt ## _ult(fp0, cpu_env, fp0, fp1);      \
1986        break;                                                          \
1987    case  6:                                                            \
1988        gen_helper_r6_cmp_ ## fmt ## _le(fp0, cpu_env, fp0, fp1);       \
1989        break;                                                          \
1990    case  7:                                                            \
1991        gen_helper_r6_cmp_ ## fmt ## _ule(fp0, cpu_env, fp0, fp1);      \
1992        break;                                                          \
1993    case  8:                                                            \
1994        gen_helper_r6_cmp_ ## fmt ## _saf(fp0, cpu_env, fp0, fp1);      \
1995        break;                                                          \
1996    case  9:                                                            \
1997        gen_helper_r6_cmp_ ## fmt ## _sun(fp0, cpu_env, fp0, fp1);      \
1998        break;                                                          \
1999    case 10:                                                            \
2000        gen_helper_r6_cmp_ ## fmt ## _seq(fp0, cpu_env, fp0, fp1);      \
2001        break;                                                          \
2002    case 11:                                                            \
2003        gen_helper_r6_cmp_ ## fmt ## _sueq(fp0, cpu_env, fp0, fp1);     \
2004        break;                                                          \
2005    case 12:                                                            \
2006        gen_helper_r6_cmp_ ## fmt ## _slt(fp0, cpu_env, fp0, fp1);      \
2007        break;                                                          \
2008    case 13:                                                            \
2009        gen_helper_r6_cmp_ ## fmt ## _sult(fp0, cpu_env, fp0, fp1);     \
2010        break;                                                          \
2011    case 14:                                                            \
2012        gen_helper_r6_cmp_ ## fmt ## _sle(fp0, cpu_env, fp0, fp1);      \
2013        break;                                                          \
2014    case 15:                                                            \
2015        gen_helper_r6_cmp_ ## fmt ## _sule(fp0, cpu_env, fp0, fp1);     \
2016        break;                                                          \
2017    case 17:                                                            \
2018        gen_helper_r6_cmp_ ## fmt ## _or(fp0, cpu_env, fp0, fp1);       \
2019        break;                                                          \
2020    case 18:                                                            \
2021        gen_helper_r6_cmp_ ## fmt ## _une(fp0, cpu_env, fp0, fp1);      \
2022        break;                                                          \
2023    case 19:                                                            \
2024        gen_helper_r6_cmp_ ## fmt ## _ne(fp0, cpu_env, fp0, fp1);       \
2025        break;                                                          \
2026    case 25:                                                            \
2027        gen_helper_r6_cmp_ ## fmt ## _sor(fp0, cpu_env, fp0, fp1);      \
2028        break;                                                          \
2029    case 26:                                                            \
2030        gen_helper_r6_cmp_ ## fmt ## _sune(fp0, cpu_env, fp0, fp1);     \
2031        break;                                                          \
2032    case 27:                                                            \
2033        gen_helper_r6_cmp_ ## fmt ## _sne(fp0, cpu_env, fp0, fp1);      \
2034        break;                                                          \
2035    default:                                                            \
2036        abort();                                                        \
2037    }                                                                   \
2038    STORE;                                                              \
2039    tcg_temp_free_i ## bits (fp0);                                      \
2040    tcg_temp_free_i ## bits (fp1);                                      \
2041}
2042
2043FOP_CONDNS(d, FMT_D, 64, gen_store_fpr64(ctx, fp0, fd))
2044FOP_CONDNS(s, FMT_S, 32, gen_store_fpr32(ctx, fp0, fd))
2045#undef FOP_CONDNS
2046#undef gen_ldcmp_fpr32
2047#undef gen_ldcmp_fpr64
2048
2049/* load/store instructions. */
2050#ifdef CONFIG_USER_ONLY
2051#define OP_LD_ATOMIC(insn,fname)                                           \
2052static inline void op_ld_##insn(TCGv ret, TCGv arg1, int mem_idx,          \
2053                                DisasContext *ctx)                         \
2054{                                                                          \
2055    TCGv t0 = tcg_temp_new();                                              \
2056    tcg_gen_mov_tl(t0, arg1);                                              \
2057    tcg_gen_qemu_##fname(ret, arg1, ctx->mem_idx);                         \
2058    tcg_gen_st_tl(t0, cpu_env, offsetof(CPUMIPSState, lladdr));                \
2059    tcg_gen_st_tl(ret, cpu_env, offsetof(CPUMIPSState, llval));                \
2060    tcg_temp_free(t0);                                                     \
2061}
2062#else
2063#define OP_LD_ATOMIC(insn,fname)                                           \
2064static inline void op_ld_##insn(TCGv ret, TCGv arg1, int mem_idx,          \
2065                                DisasContext *ctx)                         \
2066{                                                                          \
2067    gen_helper_1e1i(insn, ret, arg1, mem_idx);                             \
2068}
2069#endif
2070OP_LD_ATOMIC(ll,ld32s);
2071#if defined(TARGET_MIPS64)
2072OP_LD_ATOMIC(lld,ld64);
2073#endif
2074#undef OP_LD_ATOMIC
2075
2076#ifdef CONFIG_USER_ONLY
2077#define OP_ST_ATOMIC(insn,fname,ldname,almask)                               \
2078static inline void op_st_##insn(TCGv arg1, TCGv arg2, int rt, int mem_idx,   \
2079                                DisasContext *ctx)                           \
2080{                                                                            \
2081    TCGv t0 = tcg_temp_new();                                                \
2082    TCGLabel *l1 = gen_new_label();                                          \
2083    TCGLabel *l2 = gen_new_label();                                          \
2084                                                                             \
2085    tcg_gen_andi_tl(t0, arg2, almask);                                       \
2086    tcg_gen_brcondi_tl(TCG_COND_EQ, t0, 0, l1);                              \
2087    tcg_gen_st_tl(arg2, cpu_env, offsetof(CPUMIPSState, CP0_BadVAddr));          \
2088    generate_exception(ctx, EXCP_AdES);                                      \
2089    gen_set_label(l1);                                                       \
2090    tcg_gen_ld_tl(t0, cpu_env, offsetof(CPUMIPSState, lladdr));                  \
2091    tcg_gen_brcond_tl(TCG_COND_NE, arg2, t0, l2);                            \
2092    tcg_gen_movi_tl(t0, rt | ((almask << 3) & 0x20));                        \
2093    tcg_gen_st_tl(t0, cpu_env, offsetof(CPUMIPSState, llreg));                   \
2094    tcg_gen_st_tl(arg1, cpu_env, offsetof(CPUMIPSState, llnewval));              \
2095    generate_exception_end(ctx, EXCP_SC);                                    \
2096    gen_set_label(l2);                                                       \
2097    tcg_gen_movi_tl(t0, 0);                                                  \
2098    gen_store_gpr(t0, rt);                                                   \
2099    tcg_temp_free(t0);                                                       \
2100}
2101#else
2102#define OP_ST_ATOMIC(insn,fname,ldname,almask)                               \
2103static inline void op_st_##insn(TCGv arg1, TCGv arg2, int rt, int mem_idx,   \
2104                                DisasContext *ctx)                           \
2105{                                                                            \
2106    TCGv t0 = tcg_temp_new();                                                \
2107    gen_helper_1e2i(insn, t0, arg1, arg2, mem_idx);                          \
2108    gen_store_gpr(t0, rt);                                                   \
2109    tcg_temp_free(t0);                                                       \
2110}
2111#endif
2112OP_ST_ATOMIC(sc,st32,ld32s,0x3);
2113#if defined(TARGET_MIPS64)
2114OP_ST_ATOMIC(scd,st64,ld64,0x7);
2115#endif
2116#undef OP_ST_ATOMIC
2117
2118static void gen_base_offset_addr (DisasContext *ctx, TCGv addr,
2119                                  int base, int16_t offset)
2120{
2121    if (base == 0) {
2122        tcg_gen_movi_tl(addr, offset);
2123    } else if (offset == 0) {
2124        gen_load_gpr(addr, base);
2125    } else {
2126        tcg_gen_movi_tl(addr, offset);
2127        gen_op_addr_add(ctx, addr, cpu_gpr[base], addr);
2128    }
2129}
2130
2131static target_ulong pc_relative_pc (DisasContext *ctx)
2132{
2133    target_ulong pc = ctx->pc;
2134
2135    if (ctx->hflags & MIPS_HFLAG_BMASK) {
2136        int branch_bytes = ctx->hflags & MIPS_HFLAG_BDS16 ? 2 : 4;
2137
2138        pc -= branch_bytes;
2139    }
2140
2141    pc &= ~(target_ulong)3;
2142    return pc;
2143}
2144
2145/* Load */
2146static void gen_ld(DisasContext *ctx, uint32_t opc,
2147                   int rt, int base, int16_t offset)
2148{
2149    TCGv t0, t1, t2;
2150    int mem_idx = ctx->mem_idx;
2151
2152    if (rt == 0 && ctx->insn_flags & (INSN_LOONGSON2E | INSN_LOONGSON2F)) {
2153        /* Loongson CPU uses a load to zero register for prefetch.
2154           We emulate it as a NOP. On other CPU we must perform the
2155           actual memory access. */
2156        return;
2157    }
2158
2159    t0 = tcg_temp_new();
2160    gen_base_offset_addr(ctx, t0, base, offset);
2161
2162    switch (opc) {
2163#if defined(TARGET_MIPS64)
2164    case OPC_LWU:
2165        tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TEUL |
2166                           ctx->default_tcg_memop_mask);
2167        gen_store_gpr(t0, rt);
2168        break;
2169    case OPC_LD:
2170        tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TEQ |
2171                           ctx->default_tcg_memop_mask);
2172        gen_store_gpr(t0, rt);
2173        break;
2174    case OPC_LLD:
2175    case R6_OPC_LLD:
2176        op_ld_lld(t0, t0, mem_idx, ctx);
2177        gen_store_gpr(t0, rt);
2178        break;
2179    case OPC_LDL:
2180        t1 = tcg_temp_new();
2181        /* Do a byte access to possibly trigger a page
2182           fault with the unaligned address.  */
2183        tcg_gen_qemu_ld_tl(t1, t0, mem_idx, MO_UB);
2184        tcg_gen_andi_tl(t1, t0, 7);
2185#ifndef TARGET_WORDS_BIGENDIAN
2186        tcg_gen_xori_tl(t1, t1, 7);
2187#endif
2188        tcg_gen_shli_tl(t1, t1, 3);
2189        tcg_gen_andi_tl(t0, t0, ~7);
2190        tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TEQ);
2191        tcg_gen_shl_tl(t0, t0, t1);
2192        t2 = tcg_const_tl(-1);
2193        tcg_gen_shl_tl(t2, t2, t1);
2194        gen_load_gpr(t1, rt);
2195        tcg_gen_andc_tl(t1, t1, t2);
2196        tcg_temp_free(t2);
2197        tcg_gen_or_tl(t0, t0, t1);
2198        tcg_temp_free(t1);
2199        gen_store_gpr(t0, rt);
2200        break;
2201    case OPC_LDR:
2202        t1 = tcg_temp_new();
2203        /* Do a byte access to possibly trigger a page
2204           fault with the unaligned address.  */
2205        tcg_gen_qemu_ld_tl(t1, t0, mem_idx, MO_UB);
2206        tcg_gen_andi_tl(t1, t0, 7);
2207#ifdef TARGET_WORDS_BIGENDIAN
2208        tcg_gen_xori_tl(t1, t1, 7);
2209#endif
2210        tcg_gen_shli_tl(t1, t1, 3);
2211        tcg_gen_andi_tl(t0, t0, ~7);
2212        tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TEQ);
2213        tcg_gen_shr_tl(t0, t0, t1);
2214        tcg_gen_xori_tl(t1, t1, 63);
2215        t2 = tcg_const_tl(0xfffffffffffffffeull);
2216        tcg_gen_shl_tl(t2, t2, t1);
2217        gen_load_gpr(t1, rt);
2218        tcg_gen_and_tl(t1, t1, t2);
2219        tcg_temp_free(t2);
2220        tcg_gen_or_tl(t0, t0, t1);
2221        tcg_temp_free(t1);
2222        gen_store_gpr(t0, rt);
2223        break;
2224    case OPC_LDPC:
2225        t1 = tcg_const_tl(pc_relative_pc(ctx));
2226        gen_op_addr_add(ctx, t0, t0, t1);
2227        tcg_temp_free(t1);
2228        tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TEQ);
2229        gen_store_gpr(t0, rt);
2230        break;
2231#endif
2232    case OPC_LWPC:
2233        t1 = tcg_const_tl(pc_relative_pc(ctx));
2234        gen_op_addr_add(ctx, t0, t0, t1);
2235        tcg_temp_free(t1);
2236        tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TESL);
2237        gen_store_gpr(t0, rt);
2238        break;
2239    case OPC_LWE:
2240        mem_idx = MIPS_HFLAG_UM;
2241        /* fall through */
2242    case OPC_LW:
2243        tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TESL |
2244                           ctx->default_tcg_memop_mask);
2245        gen_store_gpr(t0, rt);
2246        break;
2247    case OPC_LHE:
2248        mem_idx = MIPS_HFLAG_UM;
2249        /* fall through */
2250    case OPC_LH:
2251        tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TESW |
2252                           ctx->default_tcg_memop_mask);
2253        gen_store_gpr(t0, rt);
2254        break;
2255    case OPC_LHUE:
2256        mem_idx = MIPS_HFLAG_UM;
2257        /* fall through */
2258    case OPC_LHU:
2259        tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TEUW |
2260                           ctx->default_tcg_memop_mask);
2261        gen_store_gpr(t0, rt);
2262        break;
2263    case OPC_LBE:
2264        mem_idx = MIPS_HFLAG_UM;
2265        /* fall through */
2266    case OPC_LB:
2267        tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_SB);
2268        gen_store_gpr(t0, rt);
2269        break;
2270    case OPC_LBUE:
2271        mem_idx = MIPS_HFLAG_UM;
2272        /* fall through */
2273    case OPC_LBU:
2274        tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_UB);
2275        gen_store_gpr(t0, rt);
2276        break;
2277    case OPC_LWLE:
2278        mem_idx = MIPS_HFLAG_UM;
2279        /* fall through */
2280    case OPC_LWL:
2281        t1 = tcg_temp_new();
2282        /* Do a byte access to possibly trigger a page
2283           fault with the unaligned address.  */
2284        tcg_gen_qemu_ld_tl(t1, t0, mem_idx, MO_UB);
2285        tcg_gen_andi_tl(t1, t0, 3);
2286#ifndef TARGET_WORDS_BIGENDIAN
2287        tcg_gen_xori_tl(t1, t1, 3);
2288#endif
2289        tcg_gen_shli_tl(t1, t1, 3);
2290        tcg_gen_andi_tl(t0, t0, ~3);
2291        tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TEUL);
2292        tcg_gen_shl_tl(t0, t0, t1);
2293        t2 = tcg_const_tl(-1);
2294        tcg_gen_shl_tl(t2, t2, t1);
2295        gen_load_gpr(t1, rt);
2296        tcg_gen_andc_tl(t1, t1, t2);
2297        tcg_temp_free(t2);
2298        tcg_gen_or_tl(t0, t0, t1);
2299        tcg_temp_free(t1);
2300        tcg_gen_ext32s_tl(t0, t0);
2301        gen_store_gpr(t0, rt);
2302        break;
2303    case OPC_LWRE:
2304        mem_idx = MIPS_HFLAG_UM;
2305        /* fall through */
2306    case OPC_LWR:
2307        t1 = tcg_temp_new();
2308        /* Do a byte access to possibly trigger a page
2309           fault with the unaligned address.  */
2310        tcg_gen_qemu_ld_tl(t1, t0, mem_idx, MO_UB);
2311        tcg_gen_andi_tl(t1, t0, 3);
2312#ifdef TARGET_WORDS_BIGENDIAN
2313        tcg_gen_xori_tl(t1, t1, 3);
2314#endif
2315        tcg_gen_shli_tl(t1, t1, 3);
2316        tcg_gen_andi_tl(t0, t0, ~3);
2317        tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TEUL);
2318        tcg_gen_shr_tl(t0, t0, t1);
2319        tcg_gen_xori_tl(t1, t1, 31);
2320        t2 = tcg_const_tl(0xfffffffeull);
2321        tcg_gen_shl_tl(t2, t2, t1);
2322        gen_load_gpr(t1, rt);
2323        tcg_gen_and_tl(t1, t1, t2);
2324        tcg_temp_free(t2);
2325        tcg_gen_or_tl(t0, t0, t1);
2326        tcg_temp_free(t1);
2327        tcg_gen_ext32s_tl(t0, t0);
2328        gen_store_gpr(t0, rt);
2329        break;
2330    case OPC_LLE:
2331        mem_idx = MIPS_HFLAG_UM;
2332        /* fall through */
2333    case OPC_LL:
2334    case R6_OPC_LL:
2335        op_ld_ll(t0, t0, mem_idx, ctx);
2336        gen_store_gpr(t0, rt);
2337        break;
2338    }
2339    tcg_temp_free(t0);
2340}
2341
2342/* Store */
2343static void gen_st (DisasContext *ctx, uint32_t opc, int rt,
2344                    int base, int16_t offset)
2345{
2346    TCGv t0 = tcg_temp_new();
2347    TCGv t1 = tcg_temp_new();
2348    int mem_idx = ctx->mem_idx;
2349
2350    gen_base_offset_addr(ctx, t0, base, offset);
2351    gen_load_gpr(t1, rt);
2352    switch (opc) {
2353#if defined(TARGET_MIPS64)
2354    case OPC_SD:
2355        tcg_gen_qemu_st_tl(t1, t0, mem_idx, MO_TEQ |
2356                           ctx->default_tcg_memop_mask);
2357        break;
2358    case OPC_SDL:
2359        gen_helper_0e2i(sdl, t1, t0, mem_idx);
2360        break;
2361    case OPC_SDR:
2362        gen_helper_0e2i(sdr, t1, t0, mem_idx);
2363        break;
2364#endif
2365    case OPC_SWE:
2366        mem_idx = MIPS_HFLAG_UM;
2367        /* fall through */
2368    case OPC_SW:
2369        tcg_gen_qemu_st_tl(t1, t0, mem_idx, MO_TEUL |
2370                           ctx->default_tcg_memop_mask);
2371        break;
2372    case OPC_SHE:
2373        mem_idx = MIPS_HFLAG_UM;
2374        /* fall through */
2375    case OPC_SH:
2376        tcg_gen_qemu_st_tl(t1, t0, mem_idx, MO_TEUW |
2377                           ctx->default_tcg_memop_mask);
2378        break;
2379    case OPC_SBE:
2380        mem_idx = MIPS_HFLAG_UM;
2381        /* fall through */
2382    case OPC_SB:
2383        tcg_gen_qemu_st_tl(t1, t0, mem_idx, MO_8);
2384        break;
2385    case OPC_SWLE:
2386        mem_idx = MIPS_HFLAG_UM;
2387        /* fall through */
2388    case OPC_SWL:
2389        gen_helper_0e2i(swl, t1, t0, mem_idx);
2390        break;
2391    case OPC_SWRE:
2392        mem_idx = MIPS_HFLAG_UM;
2393        /* fall through */
2394    case OPC_SWR:
2395        gen_helper_0e2i(swr, t1, t0, mem_idx);
2396        break;
2397    }
2398    tcg_temp_free(t0);
2399    tcg_temp_free(t1);
2400}
2401
2402
2403/* Store conditional */
2404static void gen_st_cond (DisasContext *ctx, uint32_t opc, int rt,
2405                         int base, int16_t offset)
2406{
2407    TCGv t0, t1;
2408    int mem_idx = ctx->mem_idx;
2409
2410#ifdef CONFIG_USER_ONLY
2411    t0 = tcg_temp_local_new();
2412    t1 = tcg_temp_local_new();
2413#else
2414    t0 = tcg_temp_new();
2415    t1 = tcg_temp_new();
2416#endif
2417    gen_base_offset_addr(ctx, t0, base, offset);
2418    gen_load_gpr(t1, rt);
2419    switch (opc) {
2420#if defined(TARGET_MIPS64)
2421    case OPC_SCD:
2422    case R6_OPC_SCD:
2423        op_st_scd(t1, t0, rt, mem_idx, ctx);
2424        break;
2425#endif
2426    case OPC_SCE:
2427        mem_idx = MIPS_HFLAG_UM;
2428        /* fall through */
2429    case OPC_SC:
2430    case R6_OPC_SC:
2431        op_st_sc(t1, t0, rt, mem_idx, ctx);
2432        break;
2433    }
2434    tcg_temp_free(t1);
2435    tcg_temp_free(t0);
2436}
2437
2438/* Load and store */
2439static void gen_flt_ldst (DisasContext *ctx, uint32_t opc, int ft,
2440                          int base, int16_t offset)
2441{
2442    TCGv t0 = tcg_temp_new();
2443
2444    gen_base_offset_addr(ctx, t0, base, offset);
2445    /* Don't do NOP if destination is zero: we must perform the actual
2446       memory access. */
2447    switch (opc) {
2448    case OPC_LWC1:
2449        {
2450            TCGv_i32 fp0 = tcg_temp_new_i32();
2451            tcg_gen_qemu_ld_i32(fp0, t0, ctx->mem_idx, MO_TESL |
2452                                ctx->default_tcg_memop_mask);
2453            gen_store_fpr32(ctx, fp0, ft);
2454            tcg_temp_free_i32(fp0);
2455        }
2456        break;
2457    case OPC_SWC1:
2458        {
2459            TCGv_i32 fp0 = tcg_temp_new_i32();
2460            gen_load_fpr32(ctx, fp0, ft);
2461            tcg_gen_qemu_st_i32(fp0, t0, ctx->mem_idx, MO_TEUL |
2462                                ctx->default_tcg_memop_mask);
2463            tcg_temp_free_i32(fp0);
2464        }
2465        break;
2466    case OPC_LDC1:
2467        {
2468            TCGv_i64 fp0 = tcg_temp_new_i64();
2469            tcg_gen_qemu_ld_i64(fp0, t0, ctx->mem_idx, MO_TEQ |
2470                                ctx->default_tcg_memop_mask);
2471            gen_store_fpr64(ctx, fp0, ft);
2472            tcg_temp_free_i64(fp0);
2473        }
2474        break;
2475    case OPC_SDC1:
2476        {
2477            TCGv_i64 fp0 = tcg_temp_new_i64();
2478            gen_load_fpr64(ctx, fp0, ft);
2479            tcg_gen_qemu_st_i64(fp0, t0, ctx->mem_idx, MO_TEQ |
2480                                ctx->default_tcg_memop_mask);
2481            tcg_temp_free_i64(fp0);
2482        }
2483        break;
2484    default:
2485        MIPS_INVAL("flt_ldst");
2486        generate_exception_end(ctx, EXCP_RI);
2487        goto out;
2488    }
2489 out:
2490    tcg_temp_free(t0);
2491}
2492
2493static void gen_cop1_ldst(DisasContext *ctx, uint32_t op, int rt,
2494                          int rs, int16_t imm)
2495{
2496    if (ctx->CP0_Config1 & (1 << CP0C1_FP)) {
2497        check_cp1_enabled(ctx);
2498        switch (op) {
2499        case OPC_LDC1:
2500        case OPC_SDC1:
2501            check_insn(ctx, ISA_MIPS2);
2502            /* Fallthrough */
2503        default:
2504            gen_flt_ldst(ctx, op, rt, rs, imm);
2505        }
2506    } else {
2507        generate_exception_err(ctx, EXCP_CpU, 1);
2508    }
2509}
2510
2511/* Arithmetic with immediate operand */
2512static void gen_arith_imm(DisasContext *ctx, uint32_t opc,
2513                          int rt, int rs, int16_t imm)
2514{
2515    target_ulong uimm = (target_long)imm; /* Sign extend to 32/64 bits */
2516
2517    if (rt == 0 && opc != OPC_ADDI && opc != OPC_DADDI) {
2518        /* If no destination, treat it as a NOP.
2519           For addi, we must generate the overflow exception when needed. */
2520        return;
2521    }
2522    switch (opc) {
2523    case OPC_ADDI:
2524        {
2525            TCGv t0 = tcg_temp_local_new();
2526            TCGv t1 = tcg_temp_new();
2527            TCGv t2 = tcg_temp_new();
2528            TCGLabel *l1 = gen_new_label();
2529
2530            gen_load_gpr(t1, rs);
2531            tcg_gen_addi_tl(t0, t1, uimm);
2532            tcg_gen_ext32s_tl(t0, t0);
2533
2534            tcg_gen_xori_tl(t1, t1, ~uimm);
2535            tcg_gen_xori_tl(t2, t0, uimm);
2536            tcg_gen_and_tl(t1, t1, t2);
2537            tcg_temp_free(t2);
2538            tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
2539            tcg_temp_free(t1);
2540            /* operands of same sign, result different sign */
2541            generate_exception(ctx, EXCP_OVERFLOW);
2542            gen_set_label(l1);
2543            tcg_gen_ext32s_tl(t0, t0);
2544            gen_store_gpr(t0, rt);
2545            tcg_temp_free(t0);
2546        }
2547        break;
2548    case OPC_ADDIU:
2549        if (rs != 0) {
2550            tcg_gen_addi_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
2551            tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
2552        } else {
2553            tcg_gen_movi_tl(cpu_gpr[rt], uimm);
2554        }
2555        break;
2556#if defined(TARGET_MIPS64)
2557    case OPC_DADDI:
2558        {
2559            TCGv t0 = tcg_temp_local_new();
2560            TCGv t1 = tcg_temp_new();
2561            TCGv t2 = tcg_temp_new();
2562            TCGLabel *l1 = gen_new_label();
2563
2564            gen_load_gpr(t1, rs);
2565            tcg_gen_addi_tl(t0, t1, uimm);
2566
2567            tcg_gen_xori_tl(t1, t1, ~uimm);
2568            tcg_gen_xori_tl(t2, t0, uimm);
2569            tcg_gen_and_tl(t1, t1, t2);
2570            tcg_temp_free(t2);
2571            tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
2572            tcg_temp_free(t1);
2573            /* operands of same sign, result different sign */
2574            generate_exception(ctx, EXCP_OVERFLOW);
2575            gen_set_label(l1);
2576            gen_store_gpr(t0, rt);
2577            tcg_temp_free(t0);
2578        }
2579        break;
2580    case OPC_DADDIU:
2581        if (rs != 0) {
2582            tcg_gen_addi_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
2583        } else {
2584            tcg_gen_movi_tl(cpu_gpr[rt], uimm);
2585        }
2586        break;
2587#endif
2588    }
2589}
2590
2591/* Logic with immediate operand */
2592static void gen_logic_imm(DisasContext *ctx, uint32_t opc,
2593                          int rt, int rs, int16_t imm)
2594{
2595    target_ulong uimm;
2596
2597    if (rt == 0) {
2598        /* If no destination, treat it as a NOP. */
2599        return;
2600    }
2601    uimm = (uint16_t)imm;
2602    switch (opc) {
2603    case OPC_ANDI:
2604        if (likely(rs != 0))
2605            tcg_gen_andi_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
2606        else
2607            tcg_gen_movi_tl(cpu_gpr[rt], 0);
2608        break;
2609    case OPC_ORI:
2610        if (rs != 0)
2611            tcg_gen_ori_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
2612        else
2613            tcg_gen_movi_tl(cpu_gpr[rt], uimm);
2614        break;
2615    case OPC_XORI:
2616        if (likely(rs != 0))
2617            tcg_gen_xori_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
2618        else
2619            tcg_gen_movi_tl(cpu_gpr[rt], uimm);
2620        break;
2621    case OPC_LUI:
2622        if (rs != 0 && (ctx->insn_flags & ISA_MIPS32R6)) {
2623            /* OPC_AUI */
2624            tcg_gen_addi_tl(cpu_gpr[rt], cpu_gpr[rs], imm << 16);
2625            tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
2626        } else {
2627            tcg_gen_movi_tl(cpu_gpr[rt], imm << 16);
2628        }
2629        break;
2630
2631    default:
2632        break;
2633    }
2634}
2635
2636/* Set on less than with immediate operand */
2637static void gen_slt_imm(DisasContext *ctx, uint32_t opc,
2638                        int rt, int rs, int16_t imm)
2639{
2640    target_ulong uimm = (target_long)imm; /* Sign extend to 32/64 bits */
2641    TCGv t0;
2642
2643    if (rt == 0) {
2644        /* If no destination, treat it as a NOP. */
2645        return;
2646    }
2647    t0 = tcg_temp_new();
2648    gen_load_gpr(t0, rs);
2649    switch (opc) {
2650    case OPC_SLTI:
2651        tcg_gen_setcondi_tl(TCG_COND_LT, cpu_gpr[rt], t0, uimm);
2652        break;
2653    case OPC_SLTIU:
2654        tcg_gen_setcondi_tl(TCG_COND_LTU, cpu_gpr[rt], t0, uimm);
2655        break;
2656    }
2657    tcg_temp_free(t0);
2658}
2659
2660/* Shifts with immediate operand */
2661static void gen_shift_imm(DisasContext *ctx, uint32_t opc,
2662                          int rt, int rs, int16_t imm)
2663{
2664    target_ulong uimm = ((uint16_t)imm) & 0x1f;
2665    TCGv t0;
2666
2667    if (rt == 0) {
2668        /* If no destination, treat it as a NOP. */
2669        return;
2670    }
2671
2672    t0 = tcg_temp_new();
2673    gen_load_gpr(t0, rs);
2674    switch (opc) {
2675    case OPC_SLL:
2676        tcg_gen_shli_tl(t0, t0, uimm);
2677        tcg_gen_ext32s_tl(cpu_gpr[rt], t0);
2678        break;
2679    case OPC_SRA:
2680        tcg_gen_sari_tl(cpu_gpr[rt], t0, uimm);
2681        break;
2682    case OPC_SRL:
2683        if (uimm != 0) {
2684            tcg_gen_ext32u_tl(t0, t0);
2685            tcg_gen_shri_tl(cpu_gpr[rt], t0, uimm);
2686        } else {
2687            tcg_gen_ext32s_tl(cpu_gpr[rt], t0);
2688        }
2689        break;
2690    case OPC_ROTR:
2691        if (uimm != 0) {
2692            TCGv_i32 t1 = tcg_temp_new_i32();
2693
2694            tcg_gen_trunc_tl_i32(t1, t0);
2695            tcg_gen_rotri_i32(t1, t1, uimm);
2696            tcg_gen_ext_i32_tl(cpu_gpr[rt], t1);
2697            tcg_temp_free_i32(t1);
2698        } else {
2699            tcg_gen_ext32s_tl(cpu_gpr[rt], t0);
2700        }
2701        break;
2702#if defined(TARGET_MIPS64)
2703    case OPC_DSLL:
2704        tcg_gen_shli_tl(cpu_gpr[rt], t0, uimm);
2705        break;
2706    case OPC_DSRA:
2707        tcg_gen_sari_tl(cpu_gpr[rt], t0, uimm);
2708        break;
2709    case OPC_DSRL:
2710        tcg_gen_shri_tl(cpu_gpr[rt], t0, uimm);
2711        break;
2712    case OPC_DROTR:
2713        if (uimm != 0) {
2714            tcg_gen_rotri_tl(cpu_gpr[rt], t0, uimm);
2715        } else {
2716            tcg_gen_mov_tl(cpu_gpr[rt], t0);
2717        }
2718        break;
2719    case OPC_DSLL32:
2720        tcg_gen_shli_tl(cpu_gpr[rt], t0, uimm + 32);
2721        break;
2722    case OPC_DSRA32:
2723        tcg_gen_sari_tl(cpu_gpr[rt], t0, uimm + 32);
2724        break;
2725    case OPC_DSRL32:
2726        tcg_gen_shri_tl(cpu_gpr[rt], t0, uimm + 32);
2727        break;
2728    case OPC_DROTR32:
2729        tcg_gen_rotri_tl(cpu_gpr[rt], t0, uimm + 32);
2730        break;
2731#endif
2732    }
2733    tcg_temp_free(t0);
2734}
2735
2736/* Arithmetic */
2737static void gen_arith(DisasContext *ctx, uint32_t opc,
2738                      int rd, int rs, int rt)
2739{
2740    if (rd == 0 && opc != OPC_ADD && opc != OPC_SUB
2741       && opc != OPC_DADD && opc != OPC_DSUB) {
2742        /* If no destination, treat it as a NOP.
2743           For add & sub, we must generate the overflow exception when needed. */
2744        return;
2745    }
2746
2747    switch (opc) {
2748    case OPC_ADD:
2749        {
2750            TCGv t0 = tcg_temp_local_new();
2751            TCGv t1 = tcg_temp_new();
2752            TCGv t2 = tcg_temp_new();
2753            TCGLabel *l1 = gen_new_label();
2754
2755            gen_load_gpr(t1, rs);
2756            gen_load_gpr(t2, rt);
2757            tcg_gen_add_tl(t0, t1, t2);
2758            tcg_gen_ext32s_tl(t0, t0);
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_ADDU:
2773        if (rs != 0 && rt != 0) {
2774            tcg_gen_add_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2775            tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
2776        } else if (rs == 0 && rt != 0) {
2777            tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
2778        } else if (rs != 0 && rt == 0) {
2779            tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
2780        } else {
2781            tcg_gen_movi_tl(cpu_gpr[rd], 0);
2782        }
2783        break;
2784    case OPC_SUB:
2785        {
2786            TCGv t0 = tcg_temp_local_new();
2787            TCGv t1 = tcg_temp_new();
2788            TCGv t2 = tcg_temp_new();
2789            TCGLabel *l1 = gen_new_label();
2790
2791            gen_load_gpr(t1, rs);
2792            gen_load_gpr(t2, rt);
2793            tcg_gen_sub_tl(t0, t1, t2);
2794            tcg_gen_ext32s_tl(t0, t0);
2795            tcg_gen_xor_tl(t2, t1, t2);
2796            tcg_gen_xor_tl(t1, t0, t1);
2797            tcg_gen_and_tl(t1, t1, t2);
2798            tcg_temp_free(t2);
2799            tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
2800            tcg_temp_free(t1);
2801            /* operands of different sign, first operand and result different sign */
2802            generate_exception(ctx, EXCP_OVERFLOW);
2803            gen_set_label(l1);
2804            gen_store_gpr(t0, rd);
2805            tcg_temp_free(t0);
2806        }
2807        break;
2808    case OPC_SUBU:
2809        if (rs != 0 && rt != 0) {
2810            tcg_gen_sub_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2811            tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
2812        } else if (rs == 0 && rt != 0) {
2813            tcg_gen_neg_tl(cpu_gpr[rd], cpu_gpr[rt]);
2814            tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
2815        } else if (rs != 0 && rt == 0) {
2816            tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
2817        } else {
2818            tcg_gen_movi_tl(cpu_gpr[rd], 0);
2819        }
2820        break;
2821#if defined(TARGET_MIPS64)
2822    case OPC_DADD:
2823        {
2824            TCGv t0 = tcg_temp_local_new();
2825            TCGv t1 = tcg_temp_new();
2826            TCGv t2 = tcg_temp_new();
2827            TCGLabel *l1 = gen_new_label();
2828
2829            gen_load_gpr(t1, rs);
2830            gen_load_gpr(t2, rt);
2831            tcg_gen_add_tl(t0, t1, t2);
2832            tcg_gen_xor_tl(t1, t1, t2);
2833            tcg_gen_xor_tl(t2, t0, t2);
2834            tcg_gen_andc_tl(t1, t2, t1);
2835            tcg_temp_free(t2);
2836            tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
2837            tcg_temp_free(t1);
2838            /* operands of same sign, result different sign */
2839            generate_exception(ctx, EXCP_OVERFLOW);
2840            gen_set_label(l1);
2841            gen_store_gpr(t0, rd);
2842            tcg_temp_free(t0);
2843        }
2844        break;
2845    case OPC_DADDU:
2846        if (rs != 0 && rt != 0) {
2847            tcg_gen_add_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2848        } else if (rs == 0 && rt != 0) {
2849            tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
2850        } else if (rs != 0 && rt == 0) {
2851            tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
2852        } else {
2853            tcg_gen_movi_tl(cpu_gpr[rd], 0);
2854        }
2855        break;
2856    case OPC_DSUB:
2857        {
2858            TCGv t0 = tcg_temp_local_new();
2859            TCGv t1 = tcg_temp_new();
2860            TCGv t2 = tcg_temp_new();
2861            TCGLabel *l1 = gen_new_label();
2862
2863            gen_load_gpr(t1, rs);
2864            gen_load_gpr(t2, rt);
2865            tcg_gen_sub_tl(t0, t1, t2);
2866            tcg_gen_xor_tl(t2, t1, t2);
2867            tcg_gen_xor_tl(t1, t0, t1);
2868            tcg_gen_and_tl(t1, t1, t2);
2869            tcg_temp_free(t2);
2870            tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
2871            tcg_temp_free(t1);
2872            /* operands of different sign, first operand and result different sign */
2873            generate_exception(ctx, EXCP_OVERFLOW);
2874            gen_set_label(l1);
2875            gen_store_gpr(t0, rd);
2876            tcg_temp_free(t0);
2877        }
2878        break;
2879    case OPC_DSUBU:
2880        if (rs != 0 && rt != 0) {
2881            tcg_gen_sub_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2882        } else if (rs == 0 && rt != 0) {
2883            tcg_gen_neg_tl(cpu_gpr[rd], cpu_gpr[rt]);
2884        } else if (rs != 0 && rt == 0) {
2885            tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
2886        } else {
2887            tcg_gen_movi_tl(cpu_gpr[rd], 0);
2888        }
2889        break;
2890#endif
2891    case OPC_MUL:
2892        if (likely(rs != 0 && rt != 0)) {
2893            tcg_gen_mul_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2894            tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
2895        } else {
2896            tcg_gen_movi_tl(cpu_gpr[rd], 0);
2897        }
2898        break;
2899    }
2900}
2901
2902/* Conditional move */
2903static void gen_cond_move(DisasContext *ctx, uint32_t opc,
2904                          int rd, int rs, int rt)
2905{
2906    TCGv t0, t1, t2;
2907
2908    if (rd == 0) {
2909        /* If no destination, treat it as a NOP. */
2910        return;
2911    }
2912
2913    t0 = tcg_temp_new();
2914    gen_load_gpr(t0, rt);
2915    t1 = tcg_const_tl(0);
2916    t2 = tcg_temp_new();
2917    gen_load_gpr(t2, rs);
2918    switch (opc) {
2919    case OPC_MOVN:
2920        tcg_gen_movcond_tl(TCG_COND_NE, cpu_gpr[rd], t0, t1, t2, cpu_gpr[rd]);
2921        break;
2922    case OPC_MOVZ:
2923        tcg_gen_movcond_tl(TCG_COND_EQ, cpu_gpr[rd], t0, t1, t2, cpu_gpr[rd]);
2924        break;
2925    case OPC_SELNEZ:
2926        tcg_gen_movcond_tl(TCG_COND_NE, cpu_gpr[rd], t0, t1, t2, t1);
2927        break;
2928    case OPC_SELEQZ:
2929        tcg_gen_movcond_tl(TCG_COND_EQ, cpu_gpr[rd], t0, t1, t2, t1);
2930        break;
2931    }
2932    tcg_temp_free(t2);
2933    tcg_temp_free(t1);
2934    tcg_temp_free(t0);
2935}
2936
2937/* Logic */
2938static void gen_logic(DisasContext *ctx, uint32_t opc,
2939                      int rd, int rs, int rt)
2940{
2941    if (rd == 0) {
2942        /* If no destination, treat it as a NOP. */
2943        return;
2944    }
2945
2946    switch (opc) {
2947    case OPC_AND:
2948        if (likely(rs != 0 && rt != 0)) {
2949            tcg_gen_and_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2950        } else {
2951            tcg_gen_movi_tl(cpu_gpr[rd], 0);
2952        }
2953        break;
2954    case OPC_NOR:
2955        if (rs != 0 && rt != 0) {
2956            tcg_gen_nor_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2957        } else if (rs == 0 && rt != 0) {
2958            tcg_gen_not_tl(cpu_gpr[rd], cpu_gpr[rt]);
2959        } else if (rs != 0 && rt == 0) {
2960            tcg_gen_not_tl(cpu_gpr[rd], cpu_gpr[rs]);
2961        } else {
2962            tcg_gen_movi_tl(cpu_gpr[rd], ~((target_ulong)0));
2963        }
2964        break;
2965    case OPC_OR:
2966        if (likely(rs != 0 && rt != 0)) {
2967            tcg_gen_or_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2968        } else if (rs == 0 && rt != 0) {
2969            tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
2970        } else if (rs != 0 && rt == 0) {
2971            tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
2972        } else {
2973            tcg_gen_movi_tl(cpu_gpr[rd], 0);
2974        }
2975        break;
2976    case OPC_XOR:
2977        if (likely(rs != 0 && rt != 0)) {
2978            tcg_gen_xor_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2979        } else if (rs == 0 && rt != 0) {
2980            tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
2981        } else if (rs != 0 && rt == 0) {
2982            tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
2983        } else {
2984            tcg_gen_movi_tl(cpu_gpr[rd], 0);
2985        }
2986        break;
2987    }
2988}
2989
2990/* Set on lower than */
2991static void gen_slt(DisasContext *ctx, uint32_t opc,
2992                    int rd, int rs, int rt)
2993{
2994    TCGv t0, t1;
2995
2996    if (rd == 0) {
2997        /* If no destination, treat it as a NOP. */
2998        return;
2999    }
3000
3001    t0 = tcg_temp_new();
3002    t1 = tcg_temp_new();
3003    gen_load_gpr(t0, rs);
3004    gen_load_gpr(t1, rt);
3005    switch (opc) {
3006    case OPC_SLT:
3007        tcg_gen_setcond_tl(TCG_COND_LT, cpu_gpr[rd], t0, t1);
3008        break;
3009    case OPC_SLTU:
3010        tcg_gen_setcond_tl(TCG_COND_LTU, cpu_gpr[rd], t0, t1);
3011        break;
3012    }
3013    tcg_temp_free(t0);
3014    tcg_temp_free(t1);
3015}
3016
3017/* Shifts */
3018static void gen_shift(DisasContext *ctx, uint32_t opc,
3019                      int rd, int rs, int rt)
3020{
3021    TCGv t0, t1;
3022
3023    if (rd == 0) {
3024        /* If no destination, treat it as a NOP.
3025           For add & sub, we must generate the overflow exception when needed. */
3026        return;
3027    }
3028
3029    t0 = tcg_temp_new();
3030    t1 = tcg_temp_new();
3031    gen_load_gpr(t0, rs);
3032    gen_load_gpr(t1, rt);
3033    switch (opc) {
3034    case OPC_SLLV:
3035        tcg_gen_andi_tl(t0, t0, 0x1f);
3036        tcg_gen_shl_tl(t0, t1, t0);
3037        tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
3038        break;
3039    case OPC_SRAV:
3040        tcg_gen_andi_tl(t0, t0, 0x1f);
3041        tcg_gen_sar_tl(cpu_gpr[rd], t1, t0);
3042        break;
3043    case OPC_SRLV:
3044        tcg_gen_ext32u_tl(t1, t1);
3045        tcg_gen_andi_tl(t0, t0, 0x1f);
3046        tcg_gen_shr_tl(t0, t1, t0);
3047        tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
3048        break;
3049    case OPC_ROTRV:
3050        {
3051            TCGv_i32 t2 = tcg_temp_new_i32();
3052            TCGv_i32 t3 = tcg_temp_new_i32();
3053
3054            tcg_gen_trunc_tl_i32(t2, t0);
3055            tcg_gen_trunc_tl_i32(t3, t1);
3056            tcg_gen_andi_i32(t2, t2, 0x1f);
3057            tcg_gen_rotr_i32(t2, t3, t2);
3058            tcg_gen_ext_i32_tl(cpu_gpr[rd], t2);
3059            tcg_temp_free_i32(t2);
3060            tcg_temp_free_i32(t3);
3061        }
3062        break;
3063#if defined(TARGET_MIPS64)
3064    case OPC_DSLLV:
3065        tcg_gen_andi_tl(t0, t0, 0x3f);
3066        tcg_gen_shl_tl(cpu_gpr[rd], t1, t0);
3067        break;
3068    case OPC_DSRAV:
3069        tcg_gen_andi_tl(t0, t0, 0x3f);
3070        tcg_gen_sar_tl(cpu_gpr[rd], t1, t0);
3071        break;
3072    case OPC_DSRLV:
3073        tcg_gen_andi_tl(t0, t0, 0x3f);
3074        tcg_gen_shr_tl(cpu_gpr[rd], t1, t0);
3075        break;
3076    case OPC_DROTRV:
3077        tcg_gen_andi_tl(t0, t0, 0x3f);
3078        tcg_gen_rotr_tl(cpu_gpr[rd], t1, t0);
3079        break;
3080#endif
3081    }
3082    tcg_temp_free(t0);
3083    tcg_temp_free(t1);
3084}
3085
3086/* Arithmetic on HI/LO registers */
3087static void gen_HILO(DisasContext *ctx, uint32_t opc, int acc, int reg)
3088{
3089    if (reg == 0 && (opc == OPC_MFHI || opc == OPC_MFLO)) {
3090        /* Treat as NOP. */
3091        return;
3092    }
3093
3094    if (acc != 0) {
3095        check_dsp(ctx);
3096    }
3097
3098    switch (opc) {
3099    case OPC_MFHI:
3100#if defined(TARGET_MIPS64)
3101        if (acc != 0) {
3102            tcg_gen_ext32s_tl(cpu_gpr[reg], cpu_HI[acc]);
3103        } else
3104#endif
3105        {
3106            tcg_gen_mov_tl(cpu_gpr[reg], cpu_HI[acc]);
3107        }
3108        break;
3109    case OPC_MFLO:
3110#if defined(TARGET_MIPS64)
3111        if (acc != 0) {
3112            tcg_gen_ext32s_tl(cpu_gpr[reg], cpu_LO[acc]);
3113        } else
3114#endif
3115        {
3116            tcg_gen_mov_tl(cpu_gpr[reg], cpu_LO[acc]);
3117        }
3118        break;
3119    case OPC_MTHI:
3120        if (reg != 0) {
3121#if defined(TARGET_MIPS64)
3122            if (acc != 0) {
3123                tcg_gen_ext32s_tl(cpu_HI[acc], cpu_gpr[reg]);
3124            } else
3125#endif
3126            {
3127                tcg_gen_mov_tl(cpu_HI[acc], cpu_gpr[reg]);
3128            }
3129        } else {
3130            tcg_gen_movi_tl(cpu_HI[acc], 0);
3131        }
3132        break;
3133    case OPC_MTLO:
3134        if (reg != 0) {
3135#if defined(TARGET_MIPS64)
3136            if (acc != 0) {
3137                tcg_gen_ext32s_tl(cpu_LO[acc], cpu_gpr[reg]);
3138            } else
3139#endif
3140            {
3141                tcg_gen_mov_tl(cpu_LO[acc], cpu_gpr[reg]);
3142            }
3143        } else {
3144            tcg_gen_movi_tl(cpu_LO[acc], 0);
3145        }
3146        break;
3147    }
3148}
3149
3150static inline void gen_r6_ld(target_long addr, int reg, int memidx,
3151                             TCGMemOp memop)
3152{
3153    TCGv t0 = tcg_const_tl(addr);
3154    tcg_gen_qemu_ld_tl(t0, t0, memidx, memop);
3155    gen_store_gpr(t0, reg);
3156    tcg_temp_free(t0);
3157}
3158
3159static inline void gen_pcrel(DisasContext *ctx, int opc, target_ulong pc,
3160                             int rs)
3161{
3162    target_long offset;
3163    target_long addr;
3164
3165    switch (MASK_OPC_PCREL_TOP2BITS(opc)) {
3166    case OPC_ADDIUPC:
3167        if (rs != 0) {
3168            offset = sextract32(ctx->opcode << 2, 0, 21);
3169            addr = addr_add(ctx, pc, offset);
3170            tcg_gen_movi_tl(cpu_gpr[rs], addr);
3171        }
3172        break;
3173    case R6_OPC_LWPC:
3174        offset = sextract32(ctx->opcode << 2, 0, 21);
3175        addr = addr_add(ctx, pc, offset);
3176        gen_r6_ld(addr, rs, ctx->mem_idx, MO_TESL);
3177        break;
3178#if defined(TARGET_MIPS64)
3179    case OPC_LWUPC:
3180        check_mips_64(ctx);
3181        offset = sextract32(ctx->opcode << 2, 0, 21);
3182        addr = addr_add(ctx, pc, offset);
3183        gen_r6_ld(addr, rs, ctx->mem_idx, MO_TEUL);
3184        break;
3185#endif
3186    default:
3187        switch (MASK_OPC_PCREL_TOP5BITS(opc)) {
3188        case OPC_AUIPC:
3189            if (rs != 0) {
3190                offset = sextract32(ctx->opcode, 0, 16) << 16;
3191                addr = addr_add(ctx, pc, offset);
3192                tcg_gen_movi_tl(cpu_gpr[rs], addr);
3193            }
3194            break;
3195        case OPC_ALUIPC:
3196            if (rs != 0) {
3197                offset = sextract32(ctx->opcode, 0, 16) << 16;
3198                addr = ~0xFFFF & addr_add(ctx, pc, offset);
3199                tcg_gen_movi_tl(cpu_gpr[rs], addr);
3200            }
3201            break;
3202#if defined(TARGET_MIPS64)
3203        case R6_OPC_LDPC: /* bits 16 and 17 are part of immediate */
3204        case R6_OPC_LDPC + (1 << 16):
3205        case R6_OPC_LDPC + (2 << 16):
3206        case R6_OPC_LDPC + (3 << 16):
3207            check_mips_64(ctx);
3208            offset = sextract32(ctx->opcode << 3, 0, 21);
3209            addr = addr_add(ctx, (pc & ~0x7), offset);
3210            gen_r6_ld(addr, rs, ctx->mem_idx, MO_TEQ);
3211            break;
3212#endif
3213        default:
3214            MIPS_INVAL("OPC_PCREL");
3215            generate_exception_end(ctx, EXCP_RI);
3216            break;
3217        }
3218        break;
3219    }
3220}
3221
3222static void gen_r6_muldiv(DisasContext *ctx, int opc, int rd, int rs, int rt)
3223{
3224    TCGv t0, t1;
3225
3226    if (rd == 0) {
3227        /* Treat as NOP. */
3228        return;
3229    }
3230
3231    t0 = tcg_temp_new();
3232    t1 = tcg_temp_new();
3233
3234    gen_load_gpr(t0, rs);
3235    gen_load_gpr(t1, rt);
3236
3237    switch (opc) {
3238    case R6_OPC_DIV:
3239        {
3240            TCGv t2 = tcg_temp_new();
3241            TCGv t3 = tcg_temp_new();
3242            tcg_gen_ext32s_tl(t0, t0);
3243            tcg_gen_ext32s_tl(t1, t1);
3244            tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, INT_MIN);
3245            tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1);
3246            tcg_gen_and_tl(t2, t2, t3);
3247            tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
3248            tcg_gen_or_tl(t2, t2, t3);
3249            tcg_gen_movi_tl(t3, 0);
3250            tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
3251            tcg_gen_div_tl(cpu_gpr[rd], t0, t1);
3252            tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3253            tcg_temp_free(t3);
3254            tcg_temp_free(t2);
3255        }
3256        break;
3257    case R6_OPC_MOD:
3258        {
3259            TCGv t2 = tcg_temp_new();
3260            TCGv t3 = tcg_temp_new();
3261            tcg_gen_ext32s_tl(t0, t0);
3262            tcg_gen_ext32s_tl(t1, t1);
3263            tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, INT_MIN);
3264            tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1);
3265            tcg_gen_and_tl(t2, t2, t3);
3266            tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
3267            tcg_gen_or_tl(t2, t2, t3);
3268            tcg_gen_movi_tl(t3, 0);
3269            tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
3270            tcg_gen_rem_tl(cpu_gpr[rd], t0, t1);
3271            tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3272            tcg_temp_free(t3);
3273            tcg_temp_free(t2);
3274        }
3275        break;
3276    case R6_OPC_DIVU:
3277        {
3278            TCGv t2 = tcg_const_tl(0);
3279            TCGv t3 = tcg_const_tl(1);
3280            tcg_gen_ext32u_tl(t0, t0);
3281            tcg_gen_ext32u_tl(t1, t1);
3282            tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
3283            tcg_gen_divu_tl(cpu_gpr[rd], t0, t1);
3284            tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3285            tcg_temp_free(t3);
3286            tcg_temp_free(t2);
3287        }
3288        break;
3289    case R6_OPC_MODU:
3290        {
3291            TCGv t2 = tcg_const_tl(0);
3292            TCGv t3 = tcg_const_tl(1);
3293            tcg_gen_ext32u_tl(t0, t0);
3294            tcg_gen_ext32u_tl(t1, t1);
3295            tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
3296            tcg_gen_remu_tl(cpu_gpr[rd], t0, t1);
3297            tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3298            tcg_temp_free(t3);
3299            tcg_temp_free(t2);
3300        }
3301        break;
3302    case R6_OPC_MUL:
3303        {
3304            TCGv_i32 t2 = tcg_temp_new_i32();
3305            TCGv_i32 t3 = tcg_temp_new_i32();
3306            tcg_gen_trunc_tl_i32(t2, t0);
3307            tcg_gen_trunc_tl_i32(t3, t1);
3308            tcg_gen_mul_i32(t2, t2, t3);
3309            tcg_gen_ext_i32_tl(cpu_gpr[rd], t2);
3310            tcg_temp_free_i32(t2);
3311            tcg_temp_free_i32(t3);
3312        }
3313        break;
3314    case R6_OPC_MUH:
3315        {
3316            TCGv_i32 t2 = tcg_temp_new_i32();
3317            TCGv_i32 t3 = tcg_temp_new_i32();
3318            tcg_gen_trunc_tl_i32(t2, t0);
3319            tcg_gen_trunc_tl_i32(t3, t1);
3320            tcg_gen_muls2_i32(t2, t3, t2, t3);
3321            tcg_gen_ext_i32_tl(cpu_gpr[rd], t3);
3322            tcg_temp_free_i32(t2);
3323            tcg_temp_free_i32(t3);
3324        }
3325        break;
3326    case R6_OPC_MULU:
3327        {
3328            TCGv_i32 t2 = tcg_temp_new_i32();
3329            TCGv_i32 t3 = tcg_temp_new_i32();
3330            tcg_gen_trunc_tl_i32(t2, t0);
3331            tcg_gen_trunc_tl_i32(t3, t1);
3332            tcg_gen_mul_i32(t2, t2, t3);
3333            tcg_gen_ext_i32_tl(cpu_gpr[rd], t2);
3334            tcg_temp_free_i32(t2);
3335            tcg_temp_free_i32(t3);
3336        }
3337        break;
3338    case R6_OPC_MUHU:
3339        {
3340            TCGv_i32 t2 = tcg_temp_new_i32();
3341            TCGv_i32 t3 = tcg_temp_new_i32();
3342            tcg_gen_trunc_tl_i32(t2, t0);
3343            tcg_gen_trunc_tl_i32(t3, t1);
3344            tcg_gen_mulu2_i32(t2, t3, t2, t3);
3345            tcg_gen_ext_i32_tl(cpu_gpr[rd], t3);
3346            tcg_temp_free_i32(t2);
3347            tcg_temp_free_i32(t3);
3348        }
3349        break;
3350#if defined(TARGET_MIPS64)
3351    case R6_OPC_DDIV:
3352        {
3353            TCGv t2 = tcg_temp_new();
3354            TCGv t3 = tcg_temp_new();
3355            tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, -1LL << 63);
3356            tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1LL);
3357            tcg_gen_and_tl(t2, t2, t3);
3358            tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
3359            tcg_gen_or_tl(t2, t2, t3);
3360            tcg_gen_movi_tl(t3, 0);
3361            tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
3362            tcg_gen_div_tl(cpu_gpr[rd], t0, t1);
3363            tcg_temp_free(t3);
3364            tcg_temp_free(t2);
3365        }
3366        break;
3367    case R6_OPC_DMOD:
3368        {
3369            TCGv t2 = tcg_temp_new();
3370            TCGv t3 = tcg_temp_new();
3371            tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, -1LL << 63);
3372            tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1LL);
3373            tcg_gen_and_tl(t2, t2, t3);
3374            tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
3375            tcg_gen_or_tl(t2, t2, t3);
3376            tcg_gen_movi_tl(t3, 0);
3377            tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
3378            tcg_gen_rem_tl(cpu_gpr[rd], t0, t1);
3379            tcg_temp_free(t3);
3380            tcg_temp_free(t2);
3381        }
3382        break;
3383    case R6_OPC_DDIVU:
3384        {
3385            TCGv t2 = tcg_const_tl(0);
3386            TCGv t3 = tcg_const_tl(1);
3387            tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
3388            tcg_gen_divu_i64(cpu_gpr[rd], t0, t1);
3389            tcg_temp_free(t3);
3390            tcg_temp_free(t2);
3391        }
3392        break;
3393    case R6_OPC_DMODU:
3394        {
3395            TCGv t2 = tcg_const_tl(0);
3396            TCGv t3 = tcg_const_tl(1);
3397            tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
3398            tcg_gen_remu_i64(cpu_gpr[rd], t0, t1);
3399            tcg_temp_free(t3);
3400            tcg_temp_free(t2);
3401        }
3402        break;
3403    case R6_OPC_DMUL:
3404        tcg_gen_mul_i64(cpu_gpr[rd], t0, t1);
3405        break;
3406    case R6_OPC_DMUH:
3407        {
3408            TCGv t2 = tcg_temp_new();
3409            tcg_gen_muls2_i64(t2, cpu_gpr[rd], t0, t1);
3410            tcg_temp_free(t2);
3411        }
3412        break;
3413    case R6_OPC_DMULU:
3414        tcg_gen_mul_i64(cpu_gpr[rd], t0, t1);
3415        break;
3416    case R6_OPC_DMUHU:
3417        {
3418            TCGv t2 = tcg_temp_new();
3419            tcg_gen_mulu2_i64(t2, cpu_gpr[rd], t0, t1);
3420            tcg_temp_free(t2);
3421        }
3422        break;
3423#endif
3424    default:
3425        MIPS_INVAL("r6 mul/div");
3426        generate_exception_end(ctx, EXCP_RI);
3427        goto out;
3428    }
3429 out:
3430    tcg_temp_free(t0);
3431    tcg_temp_free(t1);
3432}
3433
3434static void gen_muldiv(DisasContext *ctx, uint32_t opc,
3435                       int acc, int rs, int rt)
3436{
3437    TCGv t0, t1;
3438
3439    t0 = tcg_temp_new();
3440    t1 = tcg_temp_new();
3441
3442    gen_load_gpr(t0, rs);
3443    gen_load_gpr(t1, rt);
3444
3445    if (acc != 0) {
3446        check_dsp(ctx);
3447    }
3448
3449    switch (opc) {
3450    case OPC_DIV:
3451        {
3452            TCGv t2 = tcg_temp_new();
3453            TCGv t3 = tcg_temp_new();
3454            tcg_gen_ext32s_tl(t0, t0);
3455            tcg_gen_ext32s_tl(t1, t1);
3456            tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, INT_MIN);
3457            tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1);
3458            tcg_gen_and_tl(t2, t2, t3);
3459            tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
3460            tcg_gen_or_tl(t2, t2, t3);
3461            tcg_gen_movi_tl(t3, 0);
3462            tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
3463            tcg_gen_div_tl(cpu_LO[acc], t0, t1);
3464            tcg_gen_rem_tl(cpu_HI[acc], t0, t1);
3465            tcg_gen_ext32s_tl(cpu_LO[acc], cpu_LO[acc]);
3466            tcg_gen_ext32s_tl(cpu_HI[acc], cpu_HI[acc]);
3467            tcg_temp_free(t3);
3468            tcg_temp_free(t2);
3469        }
3470        break;
3471    case OPC_DIVU:
3472        {
3473            TCGv t2 = tcg_const_tl(0);
3474            TCGv t3 = tcg_const_tl(1);
3475            tcg_gen_ext32u_tl(t0, t0);
3476            tcg_gen_ext32u_tl(t1, t1);
3477            tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
3478            tcg_gen_divu_tl(cpu_LO[acc], t0, t1);
3479            tcg_gen_remu_tl(cpu_HI[acc], t0, t1);
3480            tcg_gen_ext32s_tl(cpu_LO[acc], cpu_LO[acc]);
3481            tcg_gen_ext32s_tl(cpu_HI[acc], cpu_HI[acc]);
3482            tcg_temp_free(t3);
3483            tcg_temp_free(t2);
3484        }
3485        break;
3486    case OPC_MULT:
3487        {
3488            TCGv_i32 t2 = tcg_temp_new_i32();
3489            TCGv_i32 t3 = tcg_temp_new_i32();
3490            tcg_gen_trunc_tl_i32(t2, t0);
3491            tcg_gen_trunc_tl_i32(t3, t1);
3492            tcg_gen_muls2_i32(t2, t3, t2, t3);
3493            tcg_gen_ext_i32_tl(cpu_LO[acc], t2);
3494            tcg_gen_ext_i32_tl(cpu_HI[acc], t3);
3495            tcg_temp_free_i32(t2);
3496            tcg_temp_free_i32(t3);
3497        }
3498        break;
3499    case OPC_MULTU:
3500        {
3501            TCGv_i32 t2 = tcg_temp_new_i32();
3502            TCGv_i32 t3 = tcg_temp_new_i32();
3503            tcg_gen_trunc_tl_i32(t2, t0);
3504            tcg_gen_trunc_tl_i32(t3, t1);
3505            tcg_gen_mulu2_i32(t2, t3, t2, t3);
3506            tcg_gen_ext_i32_tl(cpu_LO[acc], t2);
3507            tcg_gen_ext_i32_tl(cpu_HI[acc], t3);
3508            tcg_temp_free_i32(t2);
3509            tcg_temp_free_i32(t3);
3510        }
3511        break;
3512#if defined(TARGET_MIPS64)
3513    case OPC_DDIV:
3514        {
3515            TCGv t2 = tcg_temp_new();
3516            TCGv t3 = tcg_temp_new();
3517            tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, -1LL << 63);
3518            tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1LL);
3519            tcg_gen_and_tl(t2, t2, t3);
3520            tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
3521            tcg_gen_or_tl(t2, t2, t3);
3522            tcg_gen_movi_tl(t3, 0);
3523            tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
3524            tcg_gen_div_tl(cpu_LO[acc], t0, t1);
3525            tcg_gen_rem_tl(cpu_HI[acc], t0, t1);
3526            tcg_temp_free(t3);
3527            tcg_temp_free(t2);
3528        }
3529        break;
3530    case OPC_DDIVU:
3531        {
3532            TCGv t2 = tcg_const_tl(0);
3533            TCGv t3 = tcg_const_tl(1);
3534            tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
3535            tcg_gen_divu_i64(cpu_LO[acc], t0, t1);
3536            tcg_gen_remu_i64(cpu_HI[acc], t0, t1);
3537            tcg_temp_free(t3);
3538            tcg_temp_free(t2);
3539        }
3540        break;
3541    case OPC_DMULT:
3542        tcg_gen_muls2_i64(cpu_LO[acc], cpu_HI[acc], t0, t1);
3543        break;
3544    case OPC_DMULTU:
3545        tcg_gen_mulu2_i64(cpu_LO[acc], cpu_HI[acc], t0, t1);
3546        break;
3547#endif
3548    case OPC_MADD:
3549        {
3550            TCGv_i64 t2 = tcg_temp_new_i64();
3551            TCGv_i64 t3 = tcg_temp_new_i64();
3552
3553            tcg_gen_ext_tl_i64(t2, t0);
3554            tcg_gen_ext_tl_i64(t3, t1);
3555            tcg_gen_mul_i64(t2, t2, t3);
3556            tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
3557            tcg_gen_add_i64(t2, t2, t3);
3558            tcg_temp_free_i64(t3);
3559            gen_move_low32(cpu_LO[acc], t2);
3560            gen_move_high32(cpu_HI[acc], t2);
3561            tcg_temp_free_i64(t2);
3562        }
3563        break;
3564    case OPC_MADDU:
3565        {
3566            TCGv_i64 t2 = tcg_temp_new_i64();
3567            TCGv_i64 t3 = tcg_temp_new_i64();
3568
3569            tcg_gen_ext32u_tl(t0, t0);
3570            tcg_gen_ext32u_tl(t1, t1);
3571            tcg_gen_extu_tl_i64(t2, t0);
3572            tcg_gen_extu_tl_i64(t3, t1);
3573            tcg_gen_mul_i64(t2, t2, t3);
3574            tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
3575            tcg_gen_add_i64(t2, t2, t3);
3576            tcg_temp_free_i64(t3);
3577            gen_move_low32(cpu_LO[acc], t2);
3578            gen_move_high32(cpu_HI[acc], t2);
3579            tcg_temp_free_i64(t2);
3580        }
3581        break;
3582    case OPC_MSUB:
3583        {
3584            TCGv_i64 t2 = tcg_temp_new_i64();
3585            TCGv_i64 t3 = tcg_temp_new_i64();
3586
3587            tcg_gen_ext_tl_i64(t2, t0);
3588            tcg_gen_ext_tl_i64(t3, t1);
3589            tcg_gen_mul_i64(t2, t2, t3);
3590            tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
3591            tcg_gen_sub_i64(t2, t3, t2);
3592            tcg_temp_free_i64(t3);
3593            gen_move_low32(cpu_LO[acc], t2);
3594            gen_move_high32(cpu_HI[acc], t2);
3595            tcg_temp_free_i64(t2);
3596        }
3597        break;
3598    case OPC_MSUBU:
3599        {
3600            TCGv_i64 t2 = tcg_temp_new_i64();
3601            TCGv_i64 t3 = tcg_temp_new_i64();
3602
3603            tcg_gen_ext32u_tl(t0, t0);
3604            tcg_gen_ext32u_tl(t1, t1);
3605            tcg_gen_extu_tl_i64(t2, t0);
3606            tcg_gen_extu_tl_i64(t3, t1);
3607            tcg_gen_mul_i64(t2, t2, t3);
3608            tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
3609            tcg_gen_sub_i64(t2, t3, t2);
3610            tcg_temp_free_i64(t3);
3611            gen_move_low32(cpu_LO[acc], t2);
3612            gen_move_high32(cpu_HI[acc], t2);
3613            tcg_temp_free_i64(t2);
3614        }
3615        break;
3616    default:
3617        MIPS_INVAL("mul/div");
3618        generate_exception_end(ctx, EXCP_RI);
3619        goto out;
3620    }
3621 out:
3622    tcg_temp_free(t0);
3623    tcg_temp_free(t1);
3624}
3625
3626static void gen_mul_vr54xx (DisasContext *ctx, uint32_t opc,
3627                            int rd, int rs, int rt)
3628{
3629    TCGv t0 = tcg_temp_new();
3630    TCGv t1 = tcg_temp_new();
3631
3632    gen_load_gpr(t0, rs);
3633    gen_load_gpr(t1, rt);
3634
3635    switch (opc) {
3636    case OPC_VR54XX_MULS:
3637        gen_helper_muls(t0, cpu_env, t0, t1);
3638        break;
3639    case OPC_VR54XX_MULSU:
3640        gen_helper_mulsu(t0, cpu_env, t0, t1);
3641        break;
3642    case OPC_VR54XX_MACC:
3643        gen_helper_macc(t0, cpu_env, t0, t1);
3644        break;
3645    case OPC_VR54XX_MACCU:
3646        gen_helper_maccu(t0, cpu_env, t0, t1);
3647        break;
3648    case OPC_VR54XX_MSAC:
3649        gen_helper_msac(t0, cpu_env, t0, t1);
3650        break;
3651    case OPC_VR54XX_MSACU:
3652        gen_helper_msacu(t0, cpu_env, t0, t1);
3653        break;
3654    case OPC_VR54XX_MULHI:
3655        gen_helper_mulhi(t0, cpu_env, t0, t1);
3656        break;
3657    case OPC_VR54XX_MULHIU:
3658        gen_helper_mulhiu(t0, cpu_env, t0, t1);
3659        break;
3660    case OPC_VR54XX_MULSHI:
3661        gen_helper_mulshi(t0, cpu_env, t0, t1);
3662        break;
3663    case OPC_VR54XX_MULSHIU:
3664        gen_helper_mulshiu(t0, cpu_env, t0, t1);
3665        break;
3666    case OPC_VR54XX_MACCHI:
3667        gen_helper_macchi(t0, cpu_env, t0, t1);
3668        break;
3669    case OPC_VR54XX_MACCHIU:
3670        gen_helper_macchiu(t0, cpu_env, t0, t1);
3671        break;
3672    case OPC_VR54XX_MSACHI:
3673        gen_helper_msachi(t0, cpu_env, t0, t1);
3674        break;
3675    case OPC_VR54XX_MSACHIU:
3676        gen_helper_msachiu(t0, cpu_env, t0, t1);
3677        break;
3678    default:
3679        MIPS_INVAL("mul vr54xx");
3680        generate_exception_end(ctx, EXCP_RI);
3681        goto out;
3682    }
3683    gen_store_gpr(t0, rd);
3684
3685 out:
3686    tcg_temp_free(t0);
3687    tcg_temp_free(t1);
3688}
3689
3690static void gen_cl (DisasContext *ctx, uint32_t opc,
3691                    int rd, int rs)
3692{
3693    TCGv t0;
3694
3695    if (rd == 0) {
3696        /* Treat as NOP. */
3697        return;
3698    }
3699    t0 = cpu_gpr[rd];
3700    gen_load_gpr(t0, rs);
3701
3702    switch (opc) {
3703    case OPC_CLO:
3704    case R6_OPC_CLO:
3705#if defined(TARGET_MIPS64)
3706    case OPC_DCLO:
3707    case R6_OPC_DCLO:
3708#endif
3709        tcg_gen_not_tl(t0, t0);
3710        break;
3711    }
3712
3713    switch (opc) {
3714    case OPC_CLO:
3715    case R6_OPC_CLO:
3716    case OPC_CLZ:
3717    case R6_OPC_CLZ:
3718        tcg_gen_ext32u_tl(t0, t0);
3719        tcg_gen_clzi_tl(t0, t0, TARGET_LONG_BITS);
3720        tcg_gen_subi_tl(t0, t0, TARGET_LONG_BITS - 32);
3721        break;
3722#if defined(TARGET_MIPS64)
3723    case OPC_DCLO:
3724    case R6_OPC_DCLO:
3725    case OPC_DCLZ:
3726    case R6_OPC_DCLZ:
3727        tcg_gen_clzi_i64(t0, t0, 64);
3728        break;
3729#endif
3730    }
3731}
3732
3733/* Godson integer instructions */
3734static void gen_loongson_integer(DisasContext *ctx, uint32_t opc,
3735                                 int rd, int rs, int rt)
3736{
3737    TCGv t0, t1;
3738
3739    if (rd == 0) {
3740        /* Treat as NOP. */
3741        return;
3742    }
3743
3744    switch (opc) {
3745    case OPC_MULT_G_2E:
3746    case OPC_MULT_G_2F:
3747    case OPC_MULTU_G_2E:
3748    case OPC_MULTU_G_2F:
3749#if defined(TARGET_MIPS64)
3750    case OPC_DMULT_G_2E:
3751    case OPC_DMULT_G_2F:
3752    case OPC_DMULTU_G_2E:
3753    case OPC_DMULTU_G_2F:
3754#endif
3755        t0 = tcg_temp_new();
3756        t1 = tcg_temp_new();
3757        break;
3758    default:
3759        t0 = tcg_temp_local_new();
3760        t1 = tcg_temp_local_new();
3761        break;
3762    }
3763
3764    gen_load_gpr(t0, rs);
3765    gen_load_gpr(t1, rt);
3766
3767    switch (opc) {
3768    case OPC_MULT_G_2E:
3769    case OPC_MULT_G_2F:
3770        tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
3771        tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3772        break;
3773    case OPC_MULTU_G_2E:
3774    case OPC_MULTU_G_2F:
3775        tcg_gen_ext32u_tl(t0, t0);
3776        tcg_gen_ext32u_tl(t1, t1);
3777        tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
3778        tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3779        break;
3780    case OPC_DIV_G_2E:
3781    case OPC_DIV_G_2F:
3782        {
3783            TCGLabel *l1 = gen_new_label();
3784            TCGLabel *l2 = gen_new_label();
3785            TCGLabel *l3 = gen_new_label();
3786            tcg_gen_ext32s_tl(t0, t0);
3787            tcg_gen_ext32s_tl(t1, t1);
3788            tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
3789            tcg_gen_movi_tl(cpu_gpr[rd], 0);
3790            tcg_gen_br(l3);
3791            gen_set_label(l1);
3792            tcg_gen_brcondi_tl(TCG_COND_NE, t0, INT_MIN, l2);
3793            tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1, l2);
3794            tcg_gen_mov_tl(cpu_gpr[rd], t0);
3795            tcg_gen_br(l3);
3796            gen_set_label(l2);
3797            tcg_gen_div_tl(cpu_gpr[rd], t0, t1);
3798            tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3799            gen_set_label(l3);
3800        }
3801        break;
3802    case OPC_DIVU_G_2E:
3803    case OPC_DIVU_G_2F:
3804        {
3805            TCGLabel *l1 = gen_new_label();
3806            TCGLabel *l2 = gen_new_label();
3807            tcg_gen_ext32u_tl(t0, t0);
3808            tcg_gen_ext32u_tl(t1, t1);
3809            tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
3810            tcg_gen_movi_tl(cpu_gpr[rd], 0);
3811            tcg_gen_br(l2);
3812            gen_set_label(l1);
3813            tcg_gen_divu_tl(cpu_gpr[rd], t0, t1);
3814            tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3815            gen_set_label(l2);
3816        }
3817        break;
3818    case OPC_MOD_G_2E:
3819    case OPC_MOD_G_2F:
3820        {
3821            TCGLabel *l1 = gen_new_label();
3822            TCGLabel *l2 = gen_new_label();
3823            TCGLabel *l3 = gen_new_label();
3824            tcg_gen_ext32u_tl(t0, t0);
3825            tcg_gen_ext32u_tl(t1, t1);
3826            tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
3827            tcg_gen_brcondi_tl(TCG_COND_NE, t0, INT_MIN, l2);
3828            tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1, l2);
3829            gen_set_label(l1);
3830            tcg_gen_movi_tl(cpu_gpr[rd], 0);
3831            tcg_gen_br(l3);
3832            gen_set_label(l2);
3833            tcg_gen_rem_tl(cpu_gpr[rd], t0, t1);
3834            tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3835            gen_set_label(l3);
3836        }
3837        break;
3838    case OPC_MODU_G_2E:
3839    case OPC_MODU_G_2F:
3840        {
3841            TCGLabel *l1 = gen_new_label();
3842            TCGLabel *l2 = gen_new_label();
3843            tcg_gen_ext32u_tl(t0, t0);
3844            tcg_gen_ext32u_tl(t1, t1);
3845            tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
3846            tcg_gen_movi_tl(cpu_gpr[rd], 0);
3847            tcg_gen_br(l2);
3848            gen_set_label(l1);
3849            tcg_gen_remu_tl(cpu_gpr[rd], t0, t1);
3850            tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3851            gen_set_label(l2);
3852        }
3853        break;
3854#if defined(TARGET_MIPS64)
3855    case OPC_DMULT_G_2E:
3856    case OPC_DMULT_G_2F:
3857        tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
3858        break;
3859    case OPC_DMULTU_G_2E:
3860    case OPC_DMULTU_G_2F:
3861        tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
3862        break;
3863    case OPC_DDIV_G_2E:
3864    case OPC_DDIV_G_2F:
3865        {
3866            TCGLabel *l1 = gen_new_label();
3867            TCGLabel *l2 = gen_new_label();
3868            TCGLabel *l3 = gen_new_label();
3869            tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
3870            tcg_gen_movi_tl(cpu_gpr[rd], 0);
3871            tcg_gen_br(l3);
3872            gen_set_label(l1);
3873            tcg_gen_brcondi_tl(TCG_COND_NE, t0, -1LL << 63, l2);
3874            tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1LL, l2);
3875            tcg_gen_mov_tl(cpu_gpr[rd], t0);
3876            tcg_gen_br(l3);
3877            gen_set_label(l2);
3878            tcg_gen_div_tl(cpu_gpr[rd], t0, t1);
3879            gen_set_label(l3);
3880        }
3881        break;
3882    case OPC_DDIVU_G_2E:
3883    case OPC_DDIVU_G_2F:
3884        {
3885            TCGLabel *l1 = gen_new_label();
3886            TCGLabel *l2 = gen_new_label();
3887            tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
3888            tcg_gen_movi_tl(cpu_gpr[rd], 0);
3889            tcg_gen_br(l2);
3890            gen_set_label(l1);
3891            tcg_gen_divu_tl(cpu_gpr[rd], t0, t1);
3892            gen_set_label(l2);
3893        }
3894        break;
3895    case OPC_DMOD_G_2E:
3896    case OPC_DMOD_G_2F:
3897        {
3898            TCGLabel *l1 = gen_new_label();
3899            TCGLabel *l2 = gen_new_label();
3900            TCGLabel *l3 = gen_new_label();
3901            tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
3902            tcg_gen_brcondi_tl(TCG_COND_NE, t0, -1LL << 63, l2);
3903            tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1LL, l2);
3904            gen_set_label(l1);
3905            tcg_gen_movi_tl(cpu_gpr[rd], 0);
3906            tcg_gen_br(l3);
3907            gen_set_label(l2);
3908            tcg_gen_rem_tl(cpu_gpr[rd], t0, t1);
3909            gen_set_label(l3);
3910        }
3911        break;
3912    case OPC_DMODU_G_2E:
3913    case OPC_DMODU_G_2F:
3914        {
3915            TCGLabel *l1 = gen_new_label();
3916            TCGLabel *l2 = gen_new_label();
3917            tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
3918            tcg_gen_movi_tl(cpu_gpr[rd], 0);
3919            tcg_gen_br(l2);
3920            gen_set_label(l1);
3921            tcg_gen_remu_tl(cpu_gpr[rd], t0, t1);
3922            gen_set_label(l2);
3923        }
3924        break;
3925#endif
3926    }
3927
3928    tcg_temp_free(t0);
3929    tcg_temp_free(t1);
3930}
3931
3932/* Loongson multimedia instructions */
3933static void gen_loongson_multimedia(DisasContext *ctx, int rd, int rs, int rt)
3934{
3935    uint32_t opc, shift_max;
3936    TCGv_i64 t0, t1;
3937
3938    opc = MASK_LMI(ctx->opcode);
3939    switch (opc) {
3940    case OPC_ADD_CP2:
3941    case OPC_SUB_CP2:
3942    case OPC_DADD_CP2:
3943    case OPC_DSUB_CP2:
3944        t0 = tcg_temp_local_new_i64();
3945        t1 = tcg_temp_local_new_i64();
3946        break;
3947    default:
3948        t0 = tcg_temp_new_i64();
3949        t1 = tcg_temp_new_i64();
3950        break;
3951    }
3952
3953    check_cp1_enabled(ctx);
3954    gen_load_fpr64(ctx, t0, rs);
3955    gen_load_fpr64(ctx, t1, rt);
3956
3957#define LMI_HELPER(UP, LO) \
3958    case OPC_##UP: gen_helper_##LO(t0, t0, t1); break
3959#define LMI_HELPER_1(UP, LO) \
3960    case OPC_##UP: gen_helper_##LO(t0, t0); break
3961#define LMI_DIRECT(UP, LO, OP) \
3962    case OPC_##UP: tcg_gen_##OP##_i64(t0, t0, t1); break
3963
3964    switch (opc) {
3965    LMI_HELPER(PADDSH, paddsh);
3966    LMI_HELPER(PADDUSH, paddush);
3967    LMI_HELPER(PADDH, paddh);
3968    LMI_HELPER(PADDW, paddw);
3969    LMI_HELPER(PADDSB, paddsb);
3970    LMI_HELPER(PADDUSB, paddusb);
3971    LMI_HELPER(PADDB, paddb);
3972
3973    LMI_HELPER(PSUBSH, psubsh);
3974    LMI_HELPER(PSUBUSH, psubush);
3975    LMI_HELPER(PSUBH, psubh);
3976    LMI_HELPER(PSUBW, psubw);
3977    LMI_HELPER(PSUBSB, psubsb);
3978    LMI_HELPER(PSUBUSB, psubusb);
3979    LMI_HELPER(PSUBB, psubb);
3980
3981    LMI_HELPER(PSHUFH, pshufh);
3982    LMI_HELPER(PACKSSWH, packsswh);
3983    LMI_HELPER(PACKSSHB, packsshb);
3984    LMI_HELPER(PACKUSHB, packushb);
3985
3986    LMI_HELPER(PUNPCKLHW, punpcklhw);
3987    LMI_HELPER(PUNPCKHHW, punpckhhw);
3988    LMI_HELPER(PUNPCKLBH, punpcklbh);
3989    LMI_HELPER(PUNPCKHBH, punpckhbh);
3990    LMI_HELPER(PUNPCKLWD, punpcklwd);
3991    LMI_HELPER(PUNPCKHWD, punpckhwd);
3992
3993    LMI_HELPER(PAVGH, pavgh);
3994    LMI_HELPER(PAVGB, pavgb);
3995    LMI_HELPER(PMAXSH, pmaxsh);
3996    LMI_HELPER(PMINSH, pminsh);
3997    LMI_HELPER(PMAXUB, pmaxub);
3998    LMI_HELPER(PMINUB, pminub);
3999
4000    LMI_HELPER(PCMPEQW, pcmpeqw);
4001    LMI_HELPER(PCMPGTW, pcmpgtw);
4002    LMI_HELPER(PCMPEQH, pcmpeqh);
4003    LMI_HELPER(PCMPGTH, pcmpgth);
4004    LMI_HELPER(PCMPEQB, pcmpeqb);
4005    LMI_HELPER(PCMPGTB, pcmpgtb);
4006
4007    LMI_HELPER(PSLLW, psllw);
4008    LMI_HELPER(PSLLH, psllh);
4009    LMI_HELPER(PSRLW, psrlw);
4010    LMI_HELPER(PSRLH, psrlh);
4011    LMI_HELPER(PSRAW, psraw);
4012    LMI_HELPER(PSRAH, psrah);
4013
4014    LMI_HELPER(PMULLH, pmullh);
4015    LMI_HELPER(PMULHH, pmulhh);
4016    LMI_HELPER(PMULHUH, pmulhuh);
4017    LMI_HELPER(PMADDHW, pmaddhw);
4018
4019    LMI_HELPER(PASUBUB, pasubub);
4020    LMI_HELPER_1(BIADD, biadd);
4021    LMI_HELPER_1(PMOVMSKB, pmovmskb);
4022
4023    LMI_DIRECT(PADDD, paddd, add);
4024    LMI_DIRECT(PSUBD, psubd, sub);
4025    LMI_DIRECT(XOR_CP2, xor, xor);
4026    LMI_DIRECT(NOR_CP2, nor, nor);
4027    LMI_DIRECT(AND_CP2, and, and);
4028    LMI_DIRECT(OR_CP2, or, or);
4029
4030    case OPC_PANDN:
4031        tcg_gen_andc_i64(t0, t1, t0);
4032        break;
4033
4034    case OPC_PINSRH_0:
4035        tcg_gen_deposit_i64(t0, t0, t1, 0, 16);
4036        break;
4037    case OPC_PINSRH_1:
4038        tcg_gen_deposit_i64(t0, t0, t1, 16, 16);
4039        break;
4040    case OPC_PINSRH_2:
4041        tcg_gen_deposit_i64(t0, t0, t1, 32, 16);
4042        break;
4043    case OPC_PINSRH_3:
4044        tcg_gen_deposit_i64(t0, t0, t1, 48, 16);
4045        break;
4046
4047    case OPC_PEXTRH:
4048        tcg_gen_andi_i64(t1, t1, 3);
4049        tcg_gen_shli_i64(t1, t1, 4);
4050        tcg_gen_shr_i64(t0, t0, t1);
4051        tcg_gen_ext16u_i64(t0, t0);
4052        break;
4053
4054    case OPC_ADDU_CP2:
4055        tcg_gen_add_i64(t0, t0, t1);
4056        tcg_gen_ext32s_i64(t0, t0);
4057        break;
4058    case OPC_SUBU_CP2:
4059        tcg_gen_sub_i64(t0, t0, t1);
4060        tcg_gen_ext32s_i64(t0, t0);
4061        break;
4062
4063    case OPC_SLL_CP2:
4064        shift_max = 32;
4065        goto do_shift;
4066    case OPC_SRL_CP2:
4067        shift_max = 32;
4068        goto do_shift;
4069    case OPC_SRA_CP2:
4070        shift_max = 32;
4071        goto do_shift;
4072    case OPC_DSLL_CP2:
4073        shift_max = 64;
4074        goto do_shift;
4075    case OPC_DSRL_CP2:
4076        shift_max = 64;
4077        goto do_shift;
4078    case OPC_DSRA_CP2:
4079        shift_max = 64;
4080        goto do_shift;
4081    do_shift:
4082        /* Make sure shift count isn't TCG undefined behaviour.  */
4083        tcg_gen_andi_i64(t1, t1, shift_max - 1);
4084
4085        switch (opc) {
4086        case OPC_SLL_CP2:
4087        case OPC_DSLL_CP2:
4088            tcg_gen_shl_i64(t0, t0, t1);
4089            break;
4090        case OPC_SRA_CP2:
4091        case OPC_DSRA_CP2:
4092            /* Since SRA is UndefinedResult without sign-extended inputs,
4093               we can treat SRA and DSRA the same.  */
4094            tcg_gen_sar_i64(t0, t0, t1);
4095            break;
4096        case OPC_SRL_CP2:
4097            /* We want to shift in zeros for SRL; zero-extend first.  */
4098            tcg_gen_ext32u_i64(t0, t0);
4099            /* FALLTHRU */
4100        case OPC_DSRL_CP2:
4101            tcg_gen_shr_i64(t0, t0, t1);
4102            break;
4103        }
4104
4105        if (shift_max == 32) {
4106            tcg_gen_ext32s_i64(t0, t0);
4107        }
4108
4109        /* Shifts larger than MAX produce zero.  */
4110        tcg_gen_setcondi_i64(TCG_COND_LTU, t1, t1, shift_max);
4111        tcg_gen_neg_i64(t1, t1);
4112        tcg_gen_and_i64(t0, t0, t1);
4113        break;
4114
4115    case OPC_ADD_CP2:
4116    case OPC_DADD_CP2:
4117        {
4118            TCGv_i64 t2 = tcg_temp_new_i64();
4119            TCGLabel *lab = gen_new_label();
4120
4121            tcg_gen_mov_i64(t2, t0);
4122            tcg_gen_add_i64(t0, t1, t2);
4123            if (opc == OPC_ADD_CP2) {
4124                tcg_gen_ext32s_i64(t0, t0);
4125            }
4126            tcg_gen_xor_i64(t1, t1, t2);
4127            tcg_gen_xor_i64(t2, t2, t0);
4128            tcg_gen_andc_i64(t1, t2, t1);
4129            tcg_temp_free_i64(t2);
4130            tcg_gen_brcondi_i64(TCG_COND_GE, t1, 0, lab);
4131            generate_exception(ctx, EXCP_OVERFLOW);
4132            gen_set_label(lab);
4133            break;
4134        }
4135
4136    case OPC_SUB_CP2:
4137    case OPC_DSUB_CP2:
4138        {
4139            TCGv_i64 t2 = tcg_temp_new_i64();
4140            TCGLabel *lab = gen_new_label();
4141
4142            tcg_gen_mov_i64(t2, t0);
4143            tcg_gen_sub_i64(t0, t1, t2);
4144            if (opc == OPC_SUB_CP2) {
4145                tcg_gen_ext32s_i64(t0, t0);
4146            }
4147            tcg_gen_xor_i64(t1, t1, t2);
4148            tcg_gen_xor_i64(t2, t2, t0);
4149            tcg_gen_and_i64(t1, t1, t2);
4150            tcg_temp_free_i64(t2);
4151            tcg_gen_brcondi_i64(TCG_COND_GE, t1, 0, lab);
4152            generate_exception(ctx, EXCP_OVERFLOW);
4153            gen_set_label(lab);
4154            break;
4155        }
4156
4157    case OPC_PMULUW:
4158        tcg_gen_ext32u_i64(t0, t0);
4159        tcg_gen_ext32u_i64(t1, t1);
4160        tcg_gen_mul_i64(t0, t0, t1);
4161        break;
4162
4163    case OPC_SEQU_CP2:
4164    case OPC_SEQ_CP2:
4165    case OPC_SLTU_CP2:
4166    case OPC_SLT_CP2:
4167    case OPC_SLEU_CP2:
4168    case OPC_SLE_CP2:
4169        /* ??? Document is unclear: Set FCC[CC].  Does that mean the
4170           FD field is the CC field?  */
4171    default:
4172        MIPS_INVAL("loongson_cp2");
4173        generate_exception_end(ctx, EXCP_RI);
4174        return;
4175    }
4176
4177#undef LMI_HELPER
4178#undef LMI_DIRECT
4179
4180    gen_store_fpr64(ctx, t0, rd);
4181
4182    tcg_temp_free_i64(t0);
4183    tcg_temp_free_i64(t1);
4184}
4185
4186/* Traps */
4187static void gen_trap (DisasContext *ctx, uint32_t opc,
4188                      int rs, int rt, int16_t imm)
4189{
4190    int cond;
4191    TCGv t0 = tcg_temp_new();
4192    TCGv t1 = tcg_temp_new();
4193
4194    cond = 0;
4195    /* Load needed operands */
4196    switch (opc) {
4197    case OPC_TEQ:
4198    case OPC_TGE:
4199    case OPC_TGEU:
4200    case OPC_TLT:
4201    case OPC_TLTU:
4202    case OPC_TNE:
4203        /* Compare two registers */
4204        if (rs != rt) {
4205            gen_load_gpr(t0, rs);
4206            gen_load_gpr(t1, rt);
4207            cond = 1;
4208        }
4209        break;
4210    case OPC_TEQI:
4211    case OPC_TGEI:
4212    case OPC_TGEIU:
4213    case OPC_TLTI:
4214    case OPC_TLTIU:
4215    case OPC_TNEI:
4216        /* Compare register to immediate */
4217        if (rs != 0 || imm != 0) {
4218            gen_load_gpr(t0, rs);
4219            tcg_gen_movi_tl(t1, (int32_t)imm);
4220            cond = 1;
4221        }
4222        break;
4223    }
4224    if (cond == 0) {
4225        switch (opc) {
4226        case OPC_TEQ:   /* rs == rs */
4227        case OPC_TEQI:  /* r0 == 0  */
4228        case OPC_TGE:   /* rs >= rs */
4229        case OPC_TGEI:  /* r0 >= 0  */
4230        case OPC_TGEU:  /* rs >= rs unsigned */
4231        case OPC_TGEIU: /* r0 >= 0  unsigned */
4232            /* Always trap */
4233            generate_exception_end(ctx, EXCP_TRAP);
4234            break;
4235        case OPC_TLT:   /* rs < rs           */
4236        case OPC_TLTI:  /* r0 < 0            */
4237        case OPC_TLTU:  /* rs < rs unsigned  */
4238        case OPC_TLTIU: /* r0 < 0  unsigned  */
4239        case OPC_TNE:   /* rs != rs          */
4240        case OPC_TNEI:  /* r0 != 0           */
4241            /* Never trap: treat as NOP. */
4242            break;
4243        }
4244    } else {
4245        TCGLabel *l1 = gen_new_label();
4246
4247        switch (opc) {
4248        case OPC_TEQ:
4249        case OPC_TEQI:
4250            tcg_gen_brcond_tl(TCG_COND_NE, t0, t1, l1);
4251            break;
4252        case OPC_TGE:
4253        case OPC_TGEI:
4254            tcg_gen_brcond_tl(TCG_COND_LT, t0, t1, l1);
4255            break;
4256        case OPC_TGEU:
4257        case OPC_TGEIU:
4258            tcg_gen_brcond_tl(TCG_COND_LTU, t0, t1, l1);
4259            break;
4260        case OPC_TLT:
4261        case OPC_TLTI:
4262            tcg_gen_brcond_tl(TCG_COND_GE, t0, t1, l1);
4263            break;
4264        case OPC_TLTU:
4265        case OPC_TLTIU:
4266            tcg_gen_brcond_tl(TCG_COND_GEU, t0, t1, l1);
4267            break;
4268        case OPC_TNE:
4269        case OPC_TNEI:
4270            tcg_gen_brcond_tl(TCG_COND_EQ, t0, t1, l1);
4271            break;
4272        }
4273        generate_exception(ctx, EXCP_TRAP);
4274        gen_set_label(l1);
4275    }
4276    tcg_temp_free(t0);
4277    tcg_temp_free(t1);
4278}
4279
4280static inline bool use_goto_tb(DisasContext *ctx, target_ulong dest)
4281{
4282    if (unlikely(ctx->singlestep_enabled)) {
4283        return false;
4284    }
4285
4286#ifndef CONFIG_USER_ONLY
4287    return (ctx->tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK);
4288#else
4289    return true;
4290#endif
4291}
4292
4293static inline void gen_goto_tb(DisasContext *ctx, int n, target_ulong dest)
4294{
4295    if (use_goto_tb(ctx, dest)) {
4296        tcg_gen_goto_tb(n);
4297        gen_save_pc(dest);
4298        tcg_gen_exit_tb((uintptr_t)ctx->tb + n);
4299    } else {
4300        gen_save_pc(dest);
4301        if (ctx->singlestep_enabled) {
4302            save_cpu_state(ctx, 0);
4303            gen_helper_raise_exception_debug(cpu_env);
4304        }
4305        tcg_gen_lookup_and_goto_ptr();
4306    }
4307}
4308
4309/* Branches (before delay slot) */
4310static void gen_compute_branch (DisasContext *ctx, uint32_t opc,
4311                                int insn_bytes,
4312                                int rs, int rt, int32_t offset,
4313                                int delayslot_size)
4314{
4315    target_ulong btgt = -1;
4316    int blink = 0;
4317    int bcond_compute = 0;
4318    TCGv t0 = tcg_temp_new();
4319    TCGv t1 = tcg_temp_new();
4320
4321    if (ctx->hflags & MIPS_HFLAG_BMASK) {
4322#ifdef MIPS_DEBUG_DISAS
4323        LOG_DISAS("Branch in delay / forbidden slot at PC 0x"
4324                  TARGET_FMT_lx "\n", ctx->pc);
4325#endif
4326        generate_exception_end(ctx, EXCP_RI);
4327        goto out;
4328    }
4329
4330    /* Load needed operands */
4331    switch (opc) {
4332    case OPC_BEQ:
4333    case OPC_BEQL:
4334    case OPC_BNE:
4335    case OPC_BNEL:
4336        /* Compare two registers */
4337        if (rs != rt) {
4338            gen_load_gpr(t0, rs);
4339            gen_load_gpr(t1, rt);
4340            bcond_compute = 1;
4341        }
4342        btgt = ctx->pc + insn_bytes + offset;
4343        break;
4344    case OPC_BGEZ:
4345    case OPC_BGEZAL:
4346    case OPC_BGEZALL:
4347    case OPC_BGEZL:
4348    case OPC_BGTZ:
4349    case OPC_BGTZL:
4350    case OPC_BLEZ:
4351    case OPC_BLEZL:
4352    case OPC_BLTZ:
4353    case OPC_BLTZAL:
4354    case OPC_BLTZALL:
4355    case OPC_BLTZL:
4356        /* Compare to zero */
4357        if (rs != 0) {
4358            gen_load_gpr(t0, rs);
4359            bcond_compute = 1;
4360        }
4361        btgt = ctx->pc + insn_bytes + offset;
4362        break;
4363    case OPC_BPOSGE32:
4364#if defined(TARGET_MIPS64)
4365    case OPC_BPOSGE64:
4366        tcg_gen_andi_tl(t0, cpu_dspctrl, 0x7F);
4367#else
4368        tcg_gen_andi_tl(t0, cpu_dspctrl, 0x3F);
4369#endif
4370        bcond_compute = 1;
4371        btgt = ctx->pc + insn_bytes + offset;
4372        break;
4373    case OPC_J:
4374    case OPC_JAL:
4375    case OPC_JALX:
4376        /* Jump to immediate */
4377        btgt = ((ctx->pc + insn_bytes) & (int32_t)0xF0000000) | (uint32_t)offset;
4378        break;
4379    case OPC_JR:
4380    case OPC_JALR:
4381        /* Jump to register */
4382        if (offset != 0 && offset != 16) {
4383            /* Hint = 0 is JR/JALR, hint 16 is JR.HB/JALR.HB, the
4384               others are reserved. */
4385            MIPS_INVAL("jump hint");
4386            generate_exception_end(ctx, EXCP_RI);
4387            goto out;
4388        }
4389        gen_load_gpr(btarget, rs);
4390        break;
4391    default:
4392        MIPS_INVAL("branch/jump");
4393        generate_exception_end(ctx, EXCP_RI);
4394        goto out;
4395    }
4396    if (bcond_compute == 0) {
4397        /* No condition to be computed */
4398        switch (opc) {
4399        case OPC_BEQ:     /* rx == rx        */
4400        case OPC_BEQL:    /* rx == rx likely */
4401        case OPC_BGEZ:    /* 0 >= 0          */
4402        case OPC_BGEZL:   /* 0 >= 0 likely   */
4403        case OPC_BLEZ:    /* 0 <= 0          */
4404        case OPC_BLEZL:   /* 0 <= 0 likely   */
4405            /* Always take */
4406            ctx->hflags |= MIPS_HFLAG_B;
4407            break;
4408        case OPC_BGEZAL:  /* 0 >= 0          */
4409        case OPC_BGEZALL: /* 0 >= 0 likely   */
4410            /* Always take and link */
4411            blink = 31;
4412            ctx->hflags |= MIPS_HFLAG_B;
4413            break;
4414        case OPC_BNE:     /* rx != rx        */
4415        case OPC_BGTZ:    /* 0 > 0           */
4416        case OPC_BLTZ:    /* 0 < 0           */
4417            /* Treat as NOP. */
4418            goto out;
4419        case OPC_BLTZAL:  /* 0 < 0           */
4420            /* Handle as an unconditional branch to get correct delay
4421               slot checking.  */
4422            blink = 31;
4423            btgt = ctx->pc + insn_bytes + delayslot_size;
4424            ctx->hflags |= MIPS_HFLAG_B;
4425            break;
4426        case OPC_BLTZALL: /* 0 < 0 likely */
4427            tcg_gen_movi_tl(cpu_gpr[31], ctx->pc + 8);
4428            /* Skip the instruction in the delay slot */
4429            ctx->pc += 4;
4430            goto out;
4431        case OPC_BNEL:    /* rx != rx likely */
4432        case OPC_BGTZL:   /* 0 > 0 likely */
4433        case OPC_BLTZL:   /* 0 < 0 likely */
4434            /* Skip the instruction in the delay slot */
4435            ctx->pc += 4;
4436            goto out;
4437        case OPC_J:
4438            ctx->hflags |= MIPS_HFLAG_B;
4439            break;
4440        case OPC_JALX:
4441            ctx->hflags |= MIPS_HFLAG_BX;
4442            /* Fallthrough */
4443        case OPC_JAL:
4444            blink = 31;
4445            ctx->hflags |= MIPS_HFLAG_B;
4446            break;
4447        case OPC_JR:
4448            ctx->hflags |= MIPS_HFLAG_BR;
4449            break;
4450        case OPC_JALR:
4451            blink = rt;
4452            ctx->hflags |= MIPS_HFLAG_BR;
4453            break;
4454        default:
4455            MIPS_INVAL("branch/jump");
4456            generate_exception_end(ctx, EXCP_RI);
4457            goto out;
4458        }
4459    } else {
4460        switch (opc) {
4461        case OPC_BEQ:
4462            tcg_gen_setcond_tl(TCG_COND_EQ, bcond, t0, t1);
4463            goto not_likely;
4464        case OPC_BEQL:
4465            tcg_gen_setcond_tl(TCG_COND_EQ, bcond, t0, t1);
4466            goto likely;
4467        case OPC_BNE:
4468            tcg_gen_setcond_tl(TCG_COND_NE, bcond, t0, t1);
4469            goto not_likely;
4470        case OPC_BNEL:
4471            tcg_gen_setcond_tl(TCG_COND_NE, bcond, t0, t1);
4472            goto likely;
4473        case OPC_BGEZ:
4474            tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
4475            goto not_likely;
4476        case OPC_BGEZL:
4477            tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
4478            goto likely;
4479        case OPC_BGEZAL:
4480            tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
4481            blink = 31;
4482            goto not_likely;
4483        case OPC_BGEZALL:
4484            tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
4485            blink = 31;
4486            goto likely;
4487        case OPC_BGTZ:
4488            tcg_gen_setcondi_tl(TCG_COND_GT, bcond, t0, 0);
4489            goto not_likely;
4490        case OPC_BGTZL:
4491            tcg_gen_setcondi_tl(TCG_COND_GT, bcond, t0, 0);
4492            goto likely;
4493        case OPC_BLEZ:
4494            tcg_gen_setcondi_tl(TCG_COND_LE, bcond, t0, 0);
4495            goto not_likely;
4496        case OPC_BLEZL:
4497            tcg_gen_setcondi_tl(TCG_COND_LE, bcond, t0, 0);
4498            goto likely;
4499        case OPC_BLTZ:
4500            tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
4501            goto not_likely;
4502        case OPC_BLTZL:
4503            tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
4504            goto likely;
4505        case OPC_BPOSGE32:
4506            tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 32);
4507            goto not_likely;
4508#if defined(TARGET_MIPS64)
4509        case OPC_BPOSGE64:
4510            tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 64);
4511            goto not_likely;
4512#endif
4513        case OPC_BLTZAL:
4514            tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
4515            blink = 31;
4516        not_likely:
4517            ctx->hflags |= MIPS_HFLAG_BC;
4518            break;
4519        case OPC_BLTZALL:
4520            tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
4521            blink = 31;
4522        likely:
4523            ctx->hflags |= MIPS_HFLAG_BL;
4524            break;
4525        default:
4526            MIPS_INVAL("conditional branch/jump");
4527            generate_exception_end(ctx, EXCP_RI);
4528            goto out;
4529        }
4530    }
4531
4532    ctx->btarget = btgt;
4533
4534    switch (delayslot_size) {
4535    case 2:
4536        ctx->hflags |= MIPS_HFLAG_BDS16;
4537        break;
4538    case 4:
4539        ctx->hflags |= MIPS_HFLAG_BDS32;
4540        break;
4541    }
4542
4543    if (blink > 0) {
4544        int post_delay = insn_bytes + delayslot_size;
4545        int lowbit = !!(ctx->hflags & MIPS_HFLAG_M16);
4546
4547        tcg_gen_movi_tl(cpu_gpr[blink], ctx->pc + post_delay + lowbit);
4548    }
4549
4550 out:
4551    if (insn_bytes == 2)
4552        ctx->hflags |= MIPS_HFLAG_B16;
4553    tcg_temp_free(t0);
4554    tcg_temp_free(t1);
4555}
4556
4557/* special3 bitfield operations */
4558static void gen_bitops (DisasContext *ctx, uint32_t opc, int rt,
4559                        int rs, int lsb, int msb)
4560{
4561    TCGv t0 = tcg_temp_new();
4562    TCGv t1 = tcg_temp_new();
4563
4564    gen_load_gpr(t1, rs);
4565    switch (opc) {
4566    case OPC_EXT:
4567        if (lsb + msb > 31) {
4568            goto fail;
4569        }
4570        if (msb != 31) {
4571            tcg_gen_extract_tl(t0, t1, lsb, msb + 1);
4572        } else {
4573            /* The two checks together imply that lsb == 0,
4574               so this is a simple sign-extension.  */
4575            tcg_gen_ext32s_tl(t0, t1);
4576        }
4577        break;
4578#if defined(TARGET_MIPS64)
4579    case OPC_DEXTU:
4580        lsb += 32;
4581        goto do_dext;
4582    case OPC_DEXTM:
4583        msb += 32;
4584        goto do_dext;
4585    case OPC_DEXT:
4586    do_dext:
4587        if (lsb + msb > 63) {
4588            goto fail;
4589        }
4590        tcg_gen_extract_tl(t0, t1, lsb, msb + 1);
4591        break;
4592#endif
4593    case OPC_INS:
4594        if (lsb > msb) {
4595            goto fail;
4596        }
4597        gen_load_gpr(t0, rt);
4598        tcg_gen_deposit_tl(t0, t0, t1, lsb, msb - lsb + 1);
4599        tcg_gen_ext32s_tl(t0, t0);
4600        break;
4601#if defined(TARGET_MIPS64)
4602    case OPC_DINSU:
4603        lsb += 32;
4604        /* FALLTHRU */
4605    case OPC_DINSM:
4606        msb += 32;
4607        /* FALLTHRU */
4608    case OPC_DINS:
4609        if (lsb > msb) {
4610            goto fail;
4611        }
4612        gen_load_gpr(t0, rt);
4613        tcg_gen_deposit_tl(t0, t0, t1, lsb, msb - lsb + 1);
4614        break;
4615#endif
4616    default:
4617fail:
4618        MIPS_INVAL("bitops");
4619        generate_exception_end(ctx, EXCP_RI);
4620        tcg_temp_free(t0);
4621        tcg_temp_free(t1);
4622        return;
4623    }
4624    gen_store_gpr(t0, rt);
4625    tcg_temp_free(t0);
4626    tcg_temp_free(t1);
4627}
4628
4629static void gen_bshfl (DisasContext *ctx, uint32_t op2, int rt, int rd)
4630{
4631    TCGv t0;
4632
4633    if (rd == 0) {
4634        /* If no destination, treat it as a NOP. */
4635        return;
4636    }
4637
4638    t0 = tcg_temp_new();
4639    gen_load_gpr(t0, rt);
4640    switch (op2) {
4641    case OPC_WSBH:
4642        {
4643            TCGv t1 = tcg_temp_new();
4644            TCGv t2 = tcg_const_tl(0x00FF00FF);
4645
4646            tcg_gen_shri_tl(t1, t0, 8);
4647            tcg_gen_and_tl(t1, t1, t2);
4648            tcg_gen_and_tl(t0, t0, t2);
4649            tcg_gen_shli_tl(t0, t0, 8);
4650            tcg_gen_or_tl(t0, t0, t1);
4651            tcg_temp_free(t2);
4652            tcg_temp_free(t1);
4653            tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
4654        }
4655        break;
4656    case OPC_SEB:
4657        tcg_gen_ext8s_tl(cpu_gpr[rd], t0);
4658        break;
4659    case OPC_SEH:
4660        tcg_gen_ext16s_tl(cpu_gpr[rd], t0);
4661        break;
4662#if defined(TARGET_MIPS64)
4663    case OPC_DSBH:
4664        {
4665            TCGv t1 = tcg_temp_new();
4666            TCGv t2 = tcg_const_tl(0x00FF00FF00FF00FFULL);
4667
4668            tcg_gen_shri_tl(t1, t0, 8);
4669            tcg_gen_and_tl(t1, t1, t2);
4670            tcg_gen_and_tl(t0, t0, t2);
4671            tcg_gen_shli_tl(t0, t0, 8);
4672            tcg_gen_or_tl(cpu_gpr[rd], t0, t1);
4673            tcg_temp_free(t2);
4674            tcg_temp_free(t1);
4675        }
4676        break;
4677    case OPC_DSHD:
4678        {
4679            TCGv t1 = tcg_temp_new();
4680            TCGv t2 = tcg_const_tl(0x0000FFFF0000FFFFULL);
4681
4682            tcg_gen_shri_tl(t1, t0, 16);
4683            tcg_gen_and_tl(t1, t1, t2);
4684            tcg_gen_and_tl(t0, t0, t2);
4685            tcg_gen_shli_tl(t0, t0, 16);
4686            tcg_gen_or_tl(t0, t0, t1);
4687            tcg_gen_shri_tl(t1, t0, 32);
4688            tcg_gen_shli_tl(t0, t0, 32);
4689            tcg_gen_or_tl(cpu_gpr[rd], t0, t1);
4690            tcg_temp_free(t2);
4691            tcg_temp_free(t1);
4692        }
4693        break;
4694#endif
4695    default:
4696        MIPS_INVAL("bsfhl");
4697        generate_exception_end(ctx, EXCP_RI);
4698        tcg_temp_free(t0);
4699        return;
4700    }
4701    tcg_temp_free(t0);
4702}
4703
4704static void gen_lsa(DisasContext *ctx, int opc, int rd, int rs, int rt,
4705                    int imm2)
4706{
4707    TCGv t0;
4708    TCGv t1;
4709    if (rd == 0) {
4710        /* Treat as NOP. */
4711        return;
4712    }
4713    t0 = tcg_temp_new();
4714    t1 = tcg_temp_new();
4715    gen_load_gpr(t0, rs);
4716    gen_load_gpr(t1, rt);
4717    tcg_gen_shli_tl(t0, t0, imm2 + 1);
4718    tcg_gen_add_tl(cpu_gpr[rd], t0, t1);
4719    if (opc == OPC_LSA) {
4720        tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
4721    }
4722
4723    tcg_temp_free(t1);
4724    tcg_temp_free(t0);
4725
4726    return;
4727}
4728
4729static void gen_align(DisasContext *ctx, int opc, int rd, int rs, int rt,
4730                      int bp)
4731{
4732    TCGv t0;
4733    if (rd == 0) {
4734        /* Treat as NOP. */
4735        return;
4736    }
4737    t0 = tcg_temp_new();
4738    gen_load_gpr(t0, rt);
4739    if (bp == 0) {
4740        switch (opc) {
4741        case OPC_ALIGN:
4742            tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
4743            break;
4744#if defined(TARGET_MIPS64)
4745        case OPC_DALIGN:
4746            tcg_gen_mov_tl(cpu_gpr[rd], t0);
4747            break;
4748#endif
4749        }
4750    } else {
4751        TCGv t1 = tcg_temp_new();
4752        gen_load_gpr(t1, rs);
4753        switch (opc) {
4754        case OPC_ALIGN:
4755            {
4756                TCGv_i64 t2 = tcg_temp_new_i64();
4757                tcg_gen_concat_tl_i64(t2, t1, t0);
4758                tcg_gen_shri_i64(t2, t2, 8 * (4 - bp));
4759                gen_move_low32(cpu_gpr[rd], t2);
4760                tcg_temp_free_i64(t2);
4761            }
4762            break;
4763#if defined(TARGET_MIPS64)
4764        case OPC_DALIGN:
4765            tcg_gen_shli_tl(t0, t0, 8 * bp);
4766            tcg_gen_shri_tl(t1, t1, 8 * (8 - bp));
4767            tcg_gen_or_tl(cpu_gpr[rd], t1, t0);
4768            break;
4769#endif
4770        }
4771        tcg_temp_free(t1);
4772    }
4773
4774    tcg_temp_free(t0);
4775}
4776
4777static void gen_bitswap(DisasContext *ctx, int opc, int rd, int rt)
4778{
4779    TCGv t0;
4780    if (rd == 0) {
4781        /* Treat as NOP. */
4782        return;
4783    }
4784    t0 = tcg_temp_new();
4785    gen_load_gpr(t0, rt);
4786    switch (opc) {
4787    case OPC_BITSWAP:
4788        gen_helper_bitswap(cpu_gpr[rd], t0);
4789        break;
4790#if defined(TARGET_MIPS64)
4791    case OPC_DBITSWAP:
4792        gen_helper_dbitswap(cpu_gpr[rd], t0);
4793        break;
4794#endif
4795    }
4796    tcg_temp_free(t0);
4797}
4798
4799#ifndef CONFIG_USER_ONLY
4800/* CP0 (MMU and control) */
4801static inline void gen_mthc0_entrylo(TCGv arg, target_ulong off)
4802{
4803    TCGv_i64 t0 = tcg_temp_new_i64();
4804    TCGv_i64 t1 = tcg_temp_new_i64();
4805
4806    tcg_gen_ext_tl_i64(t0, arg);
4807    tcg_gen_ld_i64(t1, cpu_env, off);
4808#if defined(TARGET_MIPS64)
4809    tcg_gen_deposit_i64(t1, t1, t0, 30, 32);
4810#else
4811    tcg_gen_concat32_i64(t1, t1, t0);
4812#endif
4813    tcg_gen_st_i64(t1, cpu_env, off);
4814    tcg_temp_free_i64(t1);
4815    tcg_temp_free_i64(t0);
4816}
4817
4818static inline void gen_mthc0_store64(TCGv arg, target_ulong off)
4819{
4820    TCGv_i64 t0 = tcg_temp_new_i64();
4821    TCGv_i64 t1 = tcg_temp_new_i64();
4822
4823    tcg_gen_ext_tl_i64(t0, arg);
4824    tcg_gen_ld_i64(t1, cpu_env, off);
4825    tcg_gen_concat32_i64(t1, t1, t0);
4826    tcg_gen_st_i64(t1, cpu_env, off);
4827    tcg_temp_free_i64(t1);
4828    tcg_temp_free_i64(t0);
4829}
4830
4831static inline void gen_mfhc0_entrylo(TCGv arg, target_ulong off)
4832{
4833    TCGv_i64 t0 = tcg_temp_new_i64();
4834
4835    tcg_gen_ld_i64(t0, cpu_env, off);
4836#if defined(TARGET_MIPS64)
4837    tcg_gen_shri_i64(t0, t0, 30);
4838#else
4839    tcg_gen_shri_i64(t0, t0, 32);
4840#endif
4841    gen_move_low32(arg, t0);
4842    tcg_temp_free_i64(t0);
4843}
4844
4845static inline void gen_mfhc0_load64(TCGv arg, target_ulong off, int shift)
4846{
4847    TCGv_i64 t0 = tcg_temp_new_i64();
4848
4849    tcg_gen_ld_i64(t0, cpu_env, off);
4850    tcg_gen_shri_i64(t0, t0, 32 + shift);
4851    gen_move_low32(arg, t0);
4852    tcg_temp_free_i64(t0);
4853}
4854
4855static inline void gen_mfc0_load32 (TCGv arg, target_ulong off)
4856{
4857    TCGv_i32 t0 = tcg_temp_new_i32();
4858
4859    tcg_gen_ld_i32(t0, cpu_env, off);
4860    tcg_gen_ext_i32_tl(arg, t0);
4861    tcg_temp_free_i32(t0);
4862}
4863
4864static inline void gen_mfc0_load64 (TCGv arg, target_ulong off)
4865{
4866    tcg_gen_ld_tl(arg, cpu_env, off);
4867    tcg_gen_ext32s_tl(arg, arg);
4868}
4869
4870static inline void gen_mtc0_store32 (TCGv arg, target_ulong off)
4871{
4872    TCGv_i32 t0 = tcg_temp_new_i32();
4873
4874    tcg_gen_trunc_tl_i32(t0, arg);
4875    tcg_gen_st_i32(t0, cpu_env, off);
4876    tcg_temp_free_i32(t0);
4877}
4878
4879#define CP0_CHECK(c)                            \
4880    do {                                        \
4881        if (!(c)) {                             \
4882            goto cp0_unimplemented;             \
4883        }                                       \
4884    } while (0)
4885
4886static void gen_mfhc0(DisasContext *ctx, TCGv arg, int reg, int sel)
4887{
4888    const char *rn = "invalid";
4889
4890    CP0_CHECK(ctx->hflags & MIPS_HFLAG_ELPA);
4891
4892    switch (reg) {
4893    case 2:
4894        switch (sel) {
4895        case 0:
4896            gen_mfhc0_entrylo(arg, offsetof(CPUMIPSState, CP0_EntryLo0));
4897            rn = "EntryLo0";
4898            break;
4899        default:
4900            goto cp0_unimplemented;
4901        }
4902        break;
4903    case 3:
4904        switch (sel) {
4905        case 0:
4906            gen_mfhc0_entrylo(arg, offsetof(CPUMIPSState, CP0_EntryLo1));
4907            rn = "EntryLo1";
4908            break;
4909        default:
4910            goto cp0_unimplemented;
4911        }
4912        break;
4913    case 17:
4914        switch (sel) {
4915        case 0:
4916            gen_mfhc0_load64(arg, offsetof(CPUMIPSState, lladdr),
4917                             ctx->CP0_LLAddr_shift);
4918            rn = "LLAddr";
4919            break;
4920        case 1:
4921            CP0_CHECK(ctx->mrp);
4922            gen_helper_mfhc0_maar(arg, cpu_env);
4923            rn = "MAAR";
4924            break;
4925        default:
4926            goto cp0_unimplemented;
4927        }
4928        break;
4929    case 28:
4930        switch (sel) {
4931        case 0:
4932        case 2:
4933        case 4:
4934        case 6:
4935            gen_mfhc0_load64(arg, offsetof(CPUMIPSState, CP0_TagLo), 0);
4936            rn = "TagLo";
4937            break;
4938        default:
4939            goto cp0_unimplemented;
4940        }
4941        break;
4942    default:
4943        goto cp0_unimplemented;
4944    }
4945    trace_mips_translate_c0("mfhc0", rn, reg, sel);
4946    return;
4947
4948cp0_unimplemented:
4949    qemu_log_mask(LOG_UNIMP, "mfhc0 %s (reg %d sel %d)\n", rn, reg, sel);
4950    tcg_gen_movi_tl(arg, 0);
4951}
4952
4953static void gen_mthc0(DisasContext *ctx, TCGv arg, int reg, int sel)
4954{
4955    const char *rn = "invalid";
4956    uint64_t mask = ctx->PAMask >> 36;
4957
4958    CP0_CHECK(ctx->hflags & MIPS_HFLAG_ELPA);
4959
4960    switch (reg) {
4961    case 2:
4962        switch (sel) {
4963        case 0:
4964            tcg_gen_andi_tl(arg, arg, mask);
4965            gen_mthc0_entrylo(arg, offsetof(CPUMIPSState, CP0_EntryLo0));
4966            rn = "EntryLo0";
4967            break;
4968        default:
4969            goto cp0_unimplemented;
4970        }
4971        break;
4972    case 3:
4973        switch (sel) {
4974        case 0:
4975            tcg_gen_andi_tl(arg, arg, mask);
4976            gen_mthc0_entrylo(arg, offsetof(CPUMIPSState, CP0_EntryLo1));
4977            rn = "EntryLo1";
4978            break;
4979        default:
4980            goto cp0_unimplemented;
4981        }
4982        break;
4983    case 17:
4984        switch (sel) {
4985        case 0:
4986            /* LLAddr is read-only (the only exception is bit 0 if LLB is
4987               supported); the CP0_LLAddr_rw_bitmask does not seem to be
4988               relevant for modern MIPS cores supporting MTHC0, therefore
4989               treating MTHC0 to LLAddr as NOP. */
4990            rn = "LLAddr";
4991            break;
4992        case 1:
4993            CP0_CHECK(ctx->mrp);
4994            gen_helper_mthc0_maar(cpu_env, arg);
4995            rn = "MAAR";
4996            break;
4997        default:
4998            goto cp0_unimplemented;
4999        }
5000        break;
5001    case 28:
5002        switch (sel) {
5003        case 0:
5004        case 2:
5005        case 4:
5006        case 6:
5007            tcg_gen_andi_tl(arg, arg, mask);
5008            gen_mthc0_store64(arg, offsetof(CPUMIPSState, CP0_TagLo));
5009            rn = "TagLo";
5010            break;
5011        default:
5012            goto cp0_unimplemented;
5013        }
5014        break;
5015    default:
5016        goto cp0_unimplemented;
5017    }
5018    trace_mips_translate_c0("mthc0", rn, reg, sel);
5019
5020cp0_unimplemented:
5021    qemu_log_mask(LOG_UNIMP, "mthc0 %s (reg %d sel %d)\n", rn, reg, sel);
5022}
5023
5024static inline void gen_mfc0_unimplemented(DisasContext *ctx, TCGv arg)
5025{
5026    if (ctx->insn_flags & ISA_MIPS32R6) {
5027        tcg_gen_movi_tl(arg, 0);
5028    } else {
5029        tcg_gen_movi_tl(arg, ~0);
5030    }
5031}
5032
5033static void gen_mfc0(DisasContext *ctx, TCGv arg, int reg, int sel)
5034{
5035    const char *rn = "invalid";
5036
5037    if (sel != 0)
5038        check_insn(ctx, ISA_MIPS32);
5039
5040    switch (reg) {
5041    case 0:
5042        switch (sel) {
5043        case 0:
5044            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Index));
5045            rn = "Index";
5046            break;
5047        case 1:
5048            CP0_CHECK(ctx->insn_flags & ASE_MT);
5049            gen_helper_mfc0_mvpcontrol(arg, cpu_env);
5050            rn = "MVPControl";
5051            break;
5052        case 2:
5053            CP0_CHECK(ctx->insn_flags & ASE_MT);
5054            gen_helper_mfc0_mvpconf0(arg, cpu_env);
5055            rn = "MVPConf0";
5056            break;
5057        case 3:
5058            CP0_CHECK(ctx->insn_flags & ASE_MT);
5059            gen_helper_mfc0_mvpconf1(arg, cpu_env);
5060            rn = "MVPConf1";
5061            break;
5062        case 4:
5063            CP0_CHECK(ctx->vp);
5064            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPControl));
5065            rn = "VPControl";
5066            break;
5067        default:
5068            goto cp0_unimplemented;
5069        }
5070        break;
5071    case 1:
5072        switch (sel) {
5073        case 0:
5074            CP0_CHECK(!(ctx->insn_flags & ISA_MIPS32R6));
5075            gen_helper_mfc0_random(arg, cpu_env);
5076            rn = "Random";
5077            break;
5078        case 1:
5079            CP0_CHECK(ctx->insn_flags & ASE_MT);
5080            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEControl));
5081            rn = "VPEControl";
5082            break;
5083        case 2:
5084            CP0_CHECK(ctx->insn_flags & ASE_MT);
5085            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf0));
5086            rn = "VPEConf0";
5087            break;
5088        case 3:
5089            CP0_CHECK(ctx->insn_flags & ASE_MT);
5090            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf1));
5091            rn = "VPEConf1";
5092            break;
5093        case 4:
5094            CP0_CHECK(ctx->insn_flags & ASE_MT);
5095            gen_mfc0_load64(arg, offsetof(CPUMIPSState, CP0_YQMask));
5096            rn = "YQMask";
5097            break;
5098        case 5:
5099            CP0_CHECK(ctx->insn_flags & ASE_MT);
5100            gen_mfc0_load64(arg, offsetof(CPUMIPSState, CP0_VPESchedule));
5101            rn = "VPESchedule";
5102            break;
5103        case 6:
5104            CP0_CHECK(ctx->insn_flags & ASE_MT);
5105            gen_mfc0_load64(arg, offsetof(CPUMIPSState, CP0_VPEScheFBack));
5106            rn = "VPEScheFBack";
5107            break;
5108        case 7:
5109            CP0_CHECK(ctx->insn_flags & ASE_MT);
5110            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEOpt));
5111            rn = "VPEOpt";
5112            break;
5113        default:
5114            goto cp0_unimplemented;
5115        }
5116        break;
5117    case 2:
5118        switch (sel) {
5119        case 0:
5120            {
5121                TCGv_i64 tmp = tcg_temp_new_i64();
5122                tcg_gen_ld_i64(tmp, cpu_env,
5123                               offsetof(CPUMIPSState, CP0_EntryLo0));
5124#if defined(TARGET_MIPS64)
5125                if (ctx->rxi) {
5126                    /* Move RI/XI fields to bits 31:30 */
5127                    tcg_gen_shri_tl(arg, tmp, CP0EnLo_XI);
5128                    tcg_gen_deposit_tl(tmp, tmp, arg, 30, 2);
5129                }
5130#endif
5131                gen_move_low32(arg, tmp);
5132                tcg_temp_free_i64(tmp);
5133            }
5134            rn = "EntryLo0";
5135            break;
5136        case 1:
5137            CP0_CHECK(ctx->insn_flags & ASE_MT);
5138            gen_helper_mfc0_tcstatus(arg, cpu_env);
5139            rn = "TCStatus";
5140            break;
5141        case 2:
5142            CP0_CHECK(ctx->insn_flags & ASE_MT);
5143            gen_helper_mfc0_tcbind(arg, cpu_env);
5144            rn = "TCBind";
5145            break;
5146        case 3:
5147            CP0_CHECK(ctx->insn_flags & ASE_MT);
5148            gen_helper_mfc0_tcrestart(arg, cpu_env);
5149            rn = "TCRestart";
5150            break;
5151        case 4:
5152            CP0_CHECK(ctx->insn_flags & ASE_MT);
5153            gen_helper_mfc0_tchalt(arg, cpu_env);
5154            rn = "TCHalt";
5155            break;
5156        case 5:
5157            CP0_CHECK(ctx->insn_flags & ASE_MT);
5158            gen_helper_mfc0_tccontext(arg, cpu_env);
5159            rn = "TCContext";
5160            break;
5161        case 6:
5162            CP0_CHECK(ctx->insn_flags & ASE_MT);
5163            gen_helper_mfc0_tcschedule(arg, cpu_env);
5164            rn = "TCSchedule";
5165            break;
5166        case 7:
5167            CP0_CHECK(ctx->insn_flags & ASE_MT);
5168            gen_helper_mfc0_tcschefback(arg, cpu_env);
5169            rn = "TCScheFBack";
5170            break;
5171        default:
5172            goto cp0_unimplemented;
5173        }
5174        break;
5175    case 3:
5176        switch (sel) {
5177        case 0:
5178            {
5179                TCGv_i64 tmp = tcg_temp_new_i64();
5180                tcg_gen_ld_i64(tmp, cpu_env,
5181                               offsetof(CPUMIPSState, CP0_EntryLo1));
5182#if defined(TARGET_MIPS64)
5183                if (ctx->rxi) {
5184                    /* Move RI/XI fields to bits 31:30 */
5185                    tcg_gen_shri_tl(arg, tmp, CP0EnLo_XI);
5186                    tcg_gen_deposit_tl(tmp, tmp, arg, 30, 2);
5187                }
5188#endif
5189                gen_move_low32(arg, tmp);
5190                tcg_temp_free_i64(tmp);
5191            }
5192            rn = "EntryLo1";
5193            break;
5194        case 1:
5195            CP0_CHECK(ctx->vp);
5196            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_GlobalNumber));
5197            rn = "GlobalNumber";
5198            break;
5199        default:
5200            goto cp0_unimplemented;
5201        }
5202        break;
5203    case 4:
5204        switch (sel) {
5205        case 0:
5206            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_Context));
5207            tcg_gen_ext32s_tl(arg, arg);
5208            rn = "Context";
5209            break;
5210        case 1:
5211//            gen_helper_mfc0_contextconfig(arg); /* SmartMIPS ASE */
5212            rn = "ContextConfig";
5213            goto cp0_unimplemented;
5214        case 2:
5215            CP0_CHECK(ctx->ulri);
5216            tcg_gen_ld_tl(arg, cpu_env,
5217                          offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
5218            tcg_gen_ext32s_tl(arg, arg);
5219            rn = "UserLocal";
5220            break;
5221        default:
5222            goto cp0_unimplemented;
5223        }
5224        break;
5225    case 5:
5226        switch (sel) {
5227        case 0:
5228            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageMask));
5229            rn = "PageMask";
5230            break;
5231        case 1:
5232            check_insn(ctx, ISA_MIPS32R2);
5233            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageGrain));
5234            rn = "PageGrain";
5235            break;
5236        case 2:
5237            CP0_CHECK(ctx->sc);
5238            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_SegCtl0));
5239            tcg_gen_ext32s_tl(arg, arg);
5240            rn = "SegCtl0";
5241            break;
5242        case 3:
5243            CP0_CHECK(ctx->sc);
5244            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_SegCtl1));
5245            tcg_gen_ext32s_tl(arg, arg);
5246            rn = "SegCtl1";
5247            break;
5248        case 4:
5249            CP0_CHECK(ctx->sc);
5250            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_SegCtl2));
5251            tcg_gen_ext32s_tl(arg, arg);
5252            rn = "SegCtl2";
5253            break;
5254        default:
5255            goto cp0_unimplemented;
5256        }
5257        break;
5258    case 6:
5259        switch (sel) {
5260        case 0:
5261            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Wired));
5262            rn = "Wired";
5263            break;
5264        case 1:
5265            check_insn(ctx, ISA_MIPS32R2);
5266            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf0));
5267            rn = "SRSConf0";
5268            break;
5269        case 2:
5270            check_insn(ctx, ISA_MIPS32R2);
5271            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf1));
5272            rn = "SRSConf1";
5273            break;
5274        case 3:
5275            check_insn(ctx, ISA_MIPS32R2);
5276            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf2));
5277            rn = "SRSConf2";
5278            break;
5279        case 4:
5280            check_insn(ctx, ISA_MIPS32R2);
5281            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf3));
5282            rn = "SRSConf3";
5283            break;
5284        case 5:
5285            check_insn(ctx, ISA_MIPS32R2);
5286            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf4));
5287            rn = "SRSConf4";
5288            break;
5289        default:
5290            goto cp0_unimplemented;
5291        }
5292        break;
5293    case 7:
5294        switch (sel) {
5295        case 0:
5296            check_insn(ctx, ISA_MIPS32R2);
5297            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_HWREna));
5298            rn = "HWREna";
5299            break;
5300        default:
5301            goto cp0_unimplemented;
5302        }
5303        break;
5304    case 8:
5305        switch (sel) {
5306        case 0:
5307            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_BadVAddr));
5308            tcg_gen_ext32s_tl(arg, arg);
5309            rn = "BadVAddr";
5310            break;
5311        case 1:
5312            CP0_CHECK(ctx->bi);
5313            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_BadInstr));
5314            rn = "BadInstr";
5315            break;
5316        case 2:
5317            CP0_CHECK(ctx->bp);
5318            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_BadInstrP));
5319            rn = "BadInstrP";
5320            break;
5321        default:
5322            goto cp0_unimplemented;
5323        }
5324        break;
5325    case 9:
5326        switch (sel) {
5327        case 0:
5328            /* Mark as an IO operation because we read the time.  */
5329            if (tb_cflags(ctx->tb) & CF_USE_ICOUNT) {
5330                gen_io_start();
5331            }
5332            gen_helper_mfc0_count(arg, cpu_env);
5333            if (tb_cflags(ctx->tb) & CF_USE_ICOUNT) {
5334                gen_io_end();
5335            }
5336            /* Break the TB to be able to take timer interrupts immediately
5337               after reading count. BS_STOP isn't sufficient, we need to ensure
5338               we break completely out of translated code.  */
5339            gen_save_pc(ctx->pc + 4);
5340            ctx->bstate = BS_EXCP;
5341            rn = "Count";
5342            break;
5343        /* 6,7 are implementation dependent */
5344        default:
5345            goto cp0_unimplemented;
5346        }
5347        break;
5348    case 10:
5349        switch (sel) {
5350        case 0:
5351            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryHi));
5352            tcg_gen_ext32s_tl(arg, arg);
5353            rn = "EntryHi";
5354            break;
5355        default:
5356            goto cp0_unimplemented;
5357        }
5358        break;
5359    case 11:
5360        switch (sel) {
5361        case 0:
5362            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Compare));
5363            rn = "Compare";
5364            break;
5365        /* 6,7 are implementation dependent */
5366        default:
5367            goto cp0_unimplemented;
5368        }
5369        break;
5370    case 12:
5371        switch (sel) {
5372        case 0:
5373            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Status));
5374            rn = "Status";
5375            break;
5376        case 1:
5377            check_insn(ctx, ISA_MIPS32R2);
5378            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_IntCtl));
5379            rn = "IntCtl";
5380            break;
5381        case 2:
5382            check_insn(ctx, ISA_MIPS32R2);
5383            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSCtl));
5384            rn = "SRSCtl";
5385            break;
5386        case 3:
5387            check_insn(ctx, ISA_MIPS32R2);
5388            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSMap));
5389            rn = "SRSMap";
5390            break;
5391        default:
5392            goto cp0_unimplemented;
5393       }
5394        break;
5395    case 13:
5396        switch (sel) {
5397        case 0:
5398            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Cause));
5399            rn = "Cause";
5400            break;
5401        default:
5402            goto cp0_unimplemented;
5403       }
5404        break;
5405    case 14:
5406        switch (sel) {
5407        case 0:
5408            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EPC));
5409            tcg_gen_ext32s_tl(arg, arg);
5410            rn = "EPC";
5411            break;
5412        default:
5413            goto cp0_unimplemented;
5414        }
5415        break;
5416    case 15:
5417        switch (sel) {
5418        case 0:
5419            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PRid));
5420            rn = "PRid";
5421            break;
5422        case 1:
5423            check_insn(ctx, ISA_MIPS32R2);
5424            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EBase));
5425            tcg_gen_ext32s_tl(arg, arg);
5426            rn = "EBase";
5427            break;
5428        case 3:
5429            check_insn(ctx, ISA_MIPS32R2);
5430            CP0_CHECK(ctx->cmgcr);
5431            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_CMGCRBase));
5432            tcg_gen_ext32s_tl(arg, arg);
5433            rn = "CMGCRBase";
5434            break;
5435        default:
5436            goto cp0_unimplemented;
5437       }
5438        break;
5439    case 16:
5440        switch (sel) {
5441        case 0:
5442            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config0));
5443            rn = "Config";
5444            break;
5445        case 1:
5446            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config1));
5447            rn = "Config1";
5448            break;
5449        case 2:
5450            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config2));
5451            rn = "Config2";
5452            break;
5453        case 3:
5454            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config3));
5455            rn = "Config3";
5456            break;
5457        case 4:
5458            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config4));
5459            rn = "Config4";
5460            break;
5461        case 5:
5462            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config5));
5463            rn = "Config5";
5464            break;
5465        /* 6,7 are implementation dependent */
5466        case 6:
5467            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config6));
5468            rn = "Config6";
5469            break;
5470        case 7:
5471            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config7));
5472            rn = "Config7";
5473            break;
5474        default:
5475            goto cp0_unimplemented;
5476        }
5477        break;
5478    case 17:
5479        switch (sel) {
5480        case 0:
5481            gen_helper_mfc0_lladdr(arg, cpu_env);
5482            rn = "LLAddr";
5483            break;
5484        case 1:
5485            CP0_CHECK(ctx->mrp);
5486            gen_helper_mfc0_maar(arg, cpu_env);
5487            rn = "MAAR";
5488            break;
5489        case 2:
5490            CP0_CHECK(ctx->mrp);
5491            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_MAARI));
5492            rn = "MAARI";
5493            break;
5494        default:
5495            goto cp0_unimplemented;
5496        }
5497        break;
5498    case 18:
5499        switch (sel) {
5500        case 0 ... 7:
5501            gen_helper_1e0i(mfc0_watchlo, arg, sel);
5502            rn = "WatchLo";
5503            break;
5504        default:
5505            goto cp0_unimplemented;
5506        }
5507        break;
5508    case 19:
5509        switch (sel) {
5510        case 0 ...7:
5511            gen_helper_1e0i(mfc0_watchhi, arg, sel);
5512            rn = "WatchHi";
5513            break;
5514        default:
5515            goto cp0_unimplemented;
5516        }
5517        break;
5518    case 20:
5519        switch (sel) {
5520        case 0:
5521#if defined(TARGET_MIPS64)
5522            check_insn(ctx, ISA_MIPS3);
5523            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_XContext));
5524            tcg_gen_ext32s_tl(arg, arg);
5525            rn = "XContext";
5526            break;
5527#endif
5528        default:
5529            goto cp0_unimplemented;
5530        }
5531        break;
5532    case 21:
5533       /* Officially reserved, but sel 0 is used for R1x000 framemask */
5534        CP0_CHECK(!(ctx->insn_flags & ISA_MIPS32R6));
5535        switch (sel) {
5536        case 0:
5537            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Framemask));
5538            rn = "Framemask";
5539            break;
5540        default:
5541            goto cp0_unimplemented;
5542        }
5543        break;
5544    case 22:
5545        tcg_gen_movi_tl(arg, 0); /* unimplemented */
5546        rn = "'Diagnostic"; /* implementation dependent */
5547        break;
5548    case 23:
5549        switch (sel) {
5550        case 0:
5551            gen_helper_mfc0_debug(arg, cpu_env); /* EJTAG support */
5552            rn = "Debug";
5553            break;
5554        case 1:
5555//            gen_helper_mfc0_tracecontrol(arg); /* PDtrace support */
5556            rn = "TraceControl";
5557            goto cp0_unimplemented;
5558        case 2:
5559//            gen_helper_mfc0_tracecontrol2(arg); /* PDtrace support */
5560            rn = "TraceControl2";
5561            goto cp0_unimplemented;
5562        case 3:
5563//            gen_helper_mfc0_usertracedata(arg); /* PDtrace support */
5564            rn = "UserTraceData";
5565            goto cp0_unimplemented;
5566        case 4:
5567//            gen_helper_mfc0_tracebpc(arg); /* PDtrace support */
5568            rn = "TraceBPC";
5569            goto cp0_unimplemented;
5570        default:
5571            goto cp0_unimplemented;
5572        }
5573        break;
5574    case 24:
5575        switch (sel) {
5576        case 0:
5577            /* EJTAG support */
5578            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_DEPC));
5579            tcg_gen_ext32s_tl(arg, arg);
5580            rn = "DEPC";
5581            break;
5582        default:
5583            goto cp0_unimplemented;
5584        }
5585        break;
5586    case 25:
5587        switch (sel) {
5588        case 0:
5589            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Performance0));
5590            rn = "Performance0";
5591            break;
5592        case 1:
5593//            gen_helper_mfc0_performance1(arg);
5594            rn = "Performance1";
5595            goto cp0_unimplemented;
5596        case 2:
5597//            gen_helper_mfc0_performance2(arg);
5598            rn = "Performance2";
5599            goto cp0_unimplemented;
5600        case 3:
5601//            gen_helper_mfc0_performance3(arg);
5602            rn = "Performance3";
5603            goto cp0_unimplemented;
5604        case 4:
5605//            gen_helper_mfc0_performance4(arg);
5606            rn = "Performance4";
5607            goto cp0_unimplemented;
5608        case 5:
5609//            gen_helper_mfc0_performance5(arg);
5610            rn = "Performance5";
5611            goto cp0_unimplemented;
5612        case 6:
5613//            gen_helper_mfc0_performance6(arg);
5614            rn = "Performance6";
5615            goto cp0_unimplemented;
5616        case 7:
5617//            gen_helper_mfc0_performance7(arg);
5618            rn = "Performance7";
5619            goto cp0_unimplemented;
5620        default:
5621            goto cp0_unimplemented;
5622        }
5623        break;
5624    case 26:
5625        switch (sel) {
5626        case 0:
5627            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_ErrCtl));
5628            rn = "ErrCtl";
5629            break;
5630        default:
5631            goto cp0_unimplemented;
5632        }
5633        break;
5634    case 27:
5635        switch (sel) {
5636        case 0 ... 3:
5637            tcg_gen_movi_tl(arg, 0); /* unimplemented */
5638            rn = "CacheErr";
5639            break;
5640        default:
5641            goto cp0_unimplemented;
5642        }
5643        break;
5644    case 28:
5645        switch (sel) {
5646        case 0:
5647        case 2:
5648        case 4:
5649        case 6:
5650            {
5651                TCGv_i64 tmp = tcg_temp_new_i64();
5652                tcg_gen_ld_i64(tmp, cpu_env, offsetof(CPUMIPSState, CP0_TagLo));
5653                gen_move_low32(arg, tmp);
5654                tcg_temp_free_i64(tmp);
5655            }
5656            rn = "TagLo";
5657            break;
5658        case 1:
5659        case 3:
5660        case 5:
5661        case 7:
5662            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataLo));
5663            rn = "DataLo";
5664            break;
5665        default:
5666            goto cp0_unimplemented;
5667        }
5668        break;
5669    case 29:
5670        switch (sel) {
5671        case 0:
5672        case 2:
5673        case 4:
5674        case 6:
5675            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_TagHi));
5676            rn = "TagHi";
5677            break;
5678        case 1:
5679        case 3:
5680        case 5:
5681        case 7:
5682            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataHi));
5683            rn = "DataHi";
5684            break;
5685        default:
5686            goto cp0_unimplemented;
5687        }
5688        break;
5689    case 30:
5690        switch (sel) {
5691        case 0:
5692            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_ErrorEPC));
5693            tcg_gen_ext32s_tl(arg, arg);
5694            rn = "ErrorEPC";
5695            break;
5696        default:
5697            goto cp0_unimplemented;
5698        }
5699        break;
5700    case 31:
5701        switch (sel) {
5702        case 0:
5703            /* EJTAG support */
5704            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DESAVE));
5705            rn = "DESAVE";
5706            break;
5707        case 2 ... 7:
5708            CP0_CHECK(ctx->kscrexist & (1 << sel));
5709            tcg_gen_ld_tl(arg, cpu_env,
5710                          offsetof(CPUMIPSState, CP0_KScratch[sel-2]));
5711            tcg_gen_ext32s_tl(arg, arg);
5712            rn = "KScratch";
5713            break;
5714        default:
5715            goto cp0_unimplemented;
5716        }
5717        break;
5718    default:
5719       goto cp0_unimplemented;
5720    }
5721    trace_mips_translate_c0("mfc0", rn, reg, sel);
5722    return;
5723
5724cp0_unimplemented:
5725    qemu_log_mask(LOG_UNIMP, "mfc0 %s (reg %d sel %d)\n", rn, reg, sel);
5726    gen_mfc0_unimplemented(ctx, arg);
5727}
5728
5729static void gen_mtc0(DisasContext *ctx, TCGv arg, int reg, int sel)
5730{
5731    const char *rn = "invalid";
5732
5733    if (sel != 0)
5734        check_insn(ctx, ISA_MIPS32);
5735
5736    if (tb_cflags(ctx->tb) & CF_USE_ICOUNT) {
5737        gen_io_start();
5738    }
5739
5740    switch (reg) {
5741    case 0:
5742        switch (sel) {
5743        case 0:
5744            gen_helper_mtc0_index(cpu_env, arg);
5745            rn = "Index";
5746            break;
5747        case 1:
5748            CP0_CHECK(ctx->insn_flags & ASE_MT);
5749            gen_helper_mtc0_mvpcontrol(cpu_env, arg);
5750            rn = "MVPControl";
5751            break;
5752        case 2:
5753            CP0_CHECK(ctx->insn_flags & ASE_MT);
5754            /* ignored */
5755            rn = "MVPConf0";
5756            break;
5757        case 3:
5758            CP0_CHECK(ctx->insn_flags & ASE_MT);
5759            /* ignored */
5760            rn = "MVPConf1";
5761            break;
5762        case 4:
5763            CP0_CHECK(ctx->vp);
5764            /* ignored */
5765            rn = "VPControl";
5766            break;
5767        default:
5768            goto cp0_unimplemented;
5769        }
5770        break;
5771    case 1:
5772        switch (sel) {
5773        case 0:
5774            /* ignored */
5775            rn = "Random";
5776            break;
5777        case 1:
5778            CP0_CHECK(ctx->insn_flags & ASE_MT);
5779            gen_helper_mtc0_vpecontrol(cpu_env, arg);
5780            rn = "VPEControl";
5781            break;
5782        case 2:
5783            CP0_CHECK(ctx->insn_flags & ASE_MT);
5784            gen_helper_mtc0_vpeconf0(cpu_env, arg);
5785            rn = "VPEConf0";
5786            break;
5787        case 3:
5788            CP0_CHECK(ctx->insn_flags & ASE_MT);
5789            gen_helper_mtc0_vpeconf1(cpu_env, arg);
5790            rn = "VPEConf1";
5791            break;
5792        case 4:
5793            CP0_CHECK(ctx->insn_flags & ASE_MT);
5794            gen_helper_mtc0_yqmask(cpu_env, arg);
5795            rn = "YQMask";
5796            break;
5797        case 5:
5798            CP0_CHECK(ctx->insn_flags & ASE_MT);
5799            tcg_gen_st_tl(arg, cpu_env,
5800                          offsetof(CPUMIPSState, CP0_VPESchedule));
5801            rn = "VPESchedule";
5802            break;
5803        case 6:
5804            CP0_CHECK(ctx->insn_flags & ASE_MT);
5805            tcg_gen_st_tl(arg, cpu_env,
5806                          offsetof(CPUMIPSState, CP0_VPEScheFBack));
5807            rn = "VPEScheFBack";
5808            break;
5809        case 7:
5810            CP0_CHECK(ctx->insn_flags & ASE_MT);
5811            gen_helper_mtc0_vpeopt(cpu_env, arg);
5812            rn = "VPEOpt";
5813            break;
5814        default:
5815            goto cp0_unimplemented;
5816        }
5817        break;
5818    case 2:
5819        switch (sel) {
5820        case 0:
5821            gen_helper_mtc0_entrylo0(cpu_env, arg);
5822            rn = "EntryLo0";
5823            break;
5824        case 1:
5825            CP0_CHECK(ctx->insn_flags & ASE_MT);
5826            gen_helper_mtc0_tcstatus(cpu_env, arg);
5827            rn = "TCStatus";
5828            break;
5829        case 2:
5830            CP0_CHECK(ctx->insn_flags & ASE_MT);
5831            gen_helper_mtc0_tcbind(cpu_env, arg);
5832            rn = "TCBind";
5833            break;
5834        case 3:
5835            CP0_CHECK(ctx->insn_flags & ASE_MT);
5836            gen_helper_mtc0_tcrestart(cpu_env, arg);
5837            rn = "TCRestart";
5838            break;
5839        case 4:
5840            CP0_CHECK(ctx->insn_flags & ASE_MT);
5841            gen_helper_mtc0_tchalt(cpu_env, arg);
5842            rn = "TCHalt";
5843            break;
5844        case 5:
5845            CP0_CHECK(ctx->insn_flags & ASE_MT);
5846            gen_helper_mtc0_tccontext(cpu_env, arg);
5847            rn = "TCContext";
5848            break;
5849        case 6:
5850            CP0_CHECK(ctx->insn_flags & ASE_MT);
5851            gen_helper_mtc0_tcschedule(cpu_env, arg);
5852            rn = "TCSchedule";
5853            break;
5854        case 7:
5855            CP0_CHECK(ctx->insn_flags & ASE_MT);
5856            gen_helper_mtc0_tcschefback(cpu_env, arg);
5857            rn = "TCScheFBack";
5858            break;
5859        default:
5860            goto cp0_unimplemented;
5861        }
5862        break;
5863    case 3:
5864        switch (sel) {
5865        case 0:
5866            gen_helper_mtc0_entrylo1(cpu_env, arg);
5867            rn = "EntryLo1";
5868            break;
5869        case 1:
5870            CP0_CHECK(ctx->vp);
5871            /* ignored */
5872            rn = "GlobalNumber";
5873            break;
5874        default:
5875            goto cp0_unimplemented;
5876        }
5877        break;
5878    case 4:
5879        switch (sel) {
5880        case 0:
5881            gen_helper_mtc0_context(cpu_env, arg);
5882            rn = "Context";
5883            break;
5884        case 1:
5885//            gen_helper_mtc0_contextconfig(cpu_env, arg); /* SmartMIPS ASE */
5886            rn = "ContextConfig";
5887            goto cp0_unimplemented;
5888        case 2:
5889            CP0_CHECK(ctx->ulri);
5890            tcg_gen_st_tl(arg, cpu_env,
5891                          offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
5892            rn = "UserLocal";
5893            break;
5894        default:
5895            goto cp0_unimplemented;
5896        }
5897        break;
5898    case 5:
5899        switch (sel) {
5900        case 0:
5901            gen_helper_mtc0_pagemask(cpu_env, arg);
5902            rn = "PageMask";
5903            break;
5904        case 1:
5905            check_insn(ctx, ISA_MIPS32R2);
5906            gen_helper_mtc0_pagegrain(cpu_env, arg);
5907            rn = "PageGrain";
5908            ctx->bstate = BS_STOP;
5909            break;
5910        case 2:
5911            CP0_CHECK(ctx->sc);
5912            gen_helper_mtc0_segctl0(cpu_env, arg);
5913            rn = "SegCtl0";
5914            break;
5915        case 3:
5916            CP0_CHECK(ctx->sc);
5917            gen_helper_mtc0_segctl1(cpu_env, arg);
5918            rn = "SegCtl1";
5919            break;
5920        case 4:
5921            CP0_CHECK(ctx->sc);
5922            gen_helper_mtc0_segctl2(cpu_env, arg);
5923            rn = "SegCtl2";
5924            break;
5925        default:
5926            goto cp0_unimplemented;
5927        }
5928        break;
5929    case 6:
5930        switch (sel) {
5931        case 0:
5932            gen_helper_mtc0_wired(cpu_env, arg);
5933            rn = "Wired";
5934            break;
5935        case 1:
5936            check_insn(ctx, ISA_MIPS32R2);
5937            gen_helper_mtc0_srsconf0(cpu_env, arg);
5938            rn = "SRSConf0";
5939            break;
5940        case 2:
5941            check_insn(ctx, ISA_MIPS32R2);
5942            gen_helper_mtc0_srsconf1(cpu_env, arg);
5943            rn = "SRSConf1";
5944            break;
5945        case 3:
5946            check_insn(ctx, ISA_MIPS32R2);
5947            gen_helper_mtc0_srsconf2(cpu_env, arg);
5948            rn = "SRSConf2";
5949            break;
5950        case 4:
5951            check_insn(ctx, ISA_MIPS32R2);
5952            gen_helper_mtc0_srsconf3(cpu_env, arg);
5953            rn = "SRSConf3";
5954            break;
5955        case 5:
5956            check_insn(ctx, ISA_MIPS32R2);
5957            gen_helper_mtc0_srsconf4(cpu_env, arg);
5958            rn = "SRSConf4";
5959            break;
5960        default:
5961            goto cp0_unimplemented;
5962        }
5963        break;
5964    case 7:
5965        switch (sel) {
5966        case 0:
5967            check_insn(ctx, ISA_MIPS32R2);
5968            gen_helper_mtc0_hwrena(cpu_env, arg);
5969            ctx->bstate = BS_STOP;
5970            rn = "HWREna";
5971            break;
5972        default:
5973            goto cp0_unimplemented;
5974        }
5975        break;
5976    case 8:
5977        switch (sel) {
5978        case 0:
5979            /* ignored */
5980            rn = "BadVAddr";
5981            break;
5982        case 1:
5983            /* ignored */
5984            rn = "BadInstr";
5985            break;
5986        case 2:
5987            /* ignored */
5988            rn = "BadInstrP";
5989            break;
5990        default:
5991            goto cp0_unimplemented;
5992        }
5993        break;
5994    case 9:
5995        switch (sel) {
5996        case 0:
5997            gen_helper_mtc0_count(cpu_env, arg);
5998            rn = "Count";
5999            break;
6000        /* 6,7 are implementation dependent */
6001        default:
6002            goto cp0_unimplemented;
6003        }
6004        break;
6005    case 10:
6006        switch (sel) {
6007        case 0:
6008            gen_helper_mtc0_entryhi(cpu_env, arg);
6009            rn = "EntryHi";
6010            break;
6011        default:
6012            goto cp0_unimplemented;
6013        }
6014        break;
6015    case 11:
6016        switch (sel) {
6017        case 0:
6018            gen_helper_mtc0_compare(cpu_env, arg);
6019            rn = "Compare";
6020            break;
6021        /* 6,7 are implementation dependent */
6022        default:
6023            goto cp0_unimplemented;
6024        }
6025        break;
6026    case 12:
6027        switch (sel) {
6028        case 0:
6029            save_cpu_state(ctx, 1);
6030            gen_helper_mtc0_status(cpu_env, arg);
6031            /* BS_STOP isn't good enough here, hflags may have changed. */
6032            gen_save_pc(ctx->pc + 4);
6033            ctx->bstate = BS_EXCP;
6034            rn = "Status";
6035            break;
6036        case 1:
6037            check_insn(ctx, ISA_MIPS32R2);
6038            gen_helper_mtc0_intctl(cpu_env, arg);
6039            /* Stop translation as we may have switched the execution mode */
6040            ctx->bstate = BS_STOP;
6041            rn = "IntCtl";
6042            break;
6043        case 2:
6044            check_insn(ctx, ISA_MIPS32R2);
6045            gen_helper_mtc0_srsctl(cpu_env, arg);
6046            /* Stop translation as we may have switched the execution mode */
6047            ctx->bstate = BS_STOP;
6048            rn = "SRSCtl";
6049            break;
6050        case 3:
6051            check_insn(ctx, ISA_MIPS32R2);
6052            gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_SRSMap));
6053            /* Stop translation as we may have switched the execution mode */
6054            ctx->bstate = BS_STOP;
6055            rn = "SRSMap";
6056            break;
6057        default:
6058            goto cp0_unimplemented;
6059        }
6060        break;
6061    case 13:
6062        switch (sel) {
6063        case 0:
6064            save_cpu_state(ctx, 1);
6065            gen_helper_mtc0_cause(cpu_env, arg);
6066            /* Stop translation as we may have triggered an interrupt. BS_STOP
6067             * isn't sufficient, we need to ensure we break out of translated
6068             * code to check for pending interrupts.  */
6069            gen_save_pc(ctx->pc + 4);
6070            ctx->bstate = BS_EXCP;
6071            rn = "Cause";
6072            break;
6073        default:
6074            goto cp0_unimplemented;
6075        }
6076        break;
6077    case 14:
6078        switch (sel) {
6079        case 0:
6080            tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EPC));
6081            rn = "EPC";
6082            break;
6083        default:
6084            goto cp0_unimplemented;
6085        }
6086        break;
6087    case 15:
6088        switch (sel) {
6089        case 0:
6090            /* ignored */
6091            rn = "PRid";
6092            break;
6093        case 1:
6094            check_insn(ctx, ISA_MIPS32R2);
6095            gen_helper_mtc0_ebase(cpu_env, arg);
6096            rn = "EBase";
6097            break;
6098        default:
6099            goto cp0_unimplemented;
6100        }
6101        break;
6102    case 16:
6103        switch (sel) {
6104        case 0:
6105            gen_helper_mtc0_config0(cpu_env, arg);
6106            rn = "Config";
6107            /* Stop translation as we may have switched the execution mode */
6108            ctx->bstate = BS_STOP;
6109            break;
6110        case 1:
6111            /* ignored, read only */
6112            rn = "Config1";
6113            break;
6114        case 2:
6115            gen_helper_mtc0_config2(cpu_env, arg);
6116            rn = "Config2";
6117            /* Stop translation as we may have switched the execution mode */
6118            ctx->bstate = BS_STOP;
6119            break;
6120        case 3:
6121            gen_helper_mtc0_config3(cpu_env, arg);
6122            rn = "Config3";
6123            /* Stop translation as we may have switched the execution mode */
6124            ctx->bstate = BS_STOP;
6125            break;
6126        case 4:
6127            gen_helper_mtc0_config4(cpu_env, arg);
6128            rn = "Config4";
6129            ctx->bstate = BS_STOP;
6130            break;
6131        case 5:
6132            gen_helper_mtc0_config5(cpu_env, arg);
6133            rn = "Config5";
6134            /* Stop translation as we may have switched the execution mode */
6135            ctx->bstate = BS_STOP;
6136            break;
6137        /* 6,7 are implementation dependent */
6138        case 6:
6139            /* ignored */
6140            rn = "Config6";
6141            break;
6142        case 7:
6143            /* ignored */
6144            rn = "Config7";
6145            break;
6146        default:
6147            rn = "Invalid config selector";
6148            goto cp0_unimplemented;
6149        }
6150        break;
6151    case 17:
6152        switch (sel) {
6153        case 0:
6154            gen_helper_mtc0_lladdr(cpu_env, arg);
6155            rn = "LLAddr";
6156            break;
6157        case 1:
6158            CP0_CHECK(ctx->mrp);
6159            gen_helper_mtc0_maar(cpu_env, arg);
6160            rn = "MAAR";
6161            break;
6162        case 2:
6163            CP0_CHECK(ctx->mrp);
6164            gen_helper_mtc0_maari(cpu_env, arg);
6165            rn = "MAARI";
6166            break;
6167        default:
6168            goto cp0_unimplemented;
6169        }
6170        break;
6171    case 18:
6172        switch (sel) {
6173        case 0 ... 7:
6174            gen_helper_0e1i(mtc0_watchlo, arg, sel);
6175            rn = "WatchLo";
6176            break;
6177        default:
6178            goto cp0_unimplemented;
6179        }
6180        break;
6181    case 19:
6182        switch (sel) {
6183        case 0 ... 7:
6184            gen_helper_0e1i(mtc0_watchhi, arg, sel);
6185            rn = "WatchHi";
6186            break;
6187        default:
6188            goto cp0_unimplemented;
6189        }
6190        break;
6191    case 20:
6192        switch (sel) {
6193        case 0:
6194#if defined(TARGET_MIPS64)
6195            check_insn(ctx, ISA_MIPS3);
6196            gen_helper_mtc0_xcontext(cpu_env, arg);
6197            rn = "XContext";
6198            break;
6199#endif
6200        default:
6201            goto cp0_unimplemented;
6202        }
6203        break;
6204    case 21:
6205       /* Officially reserved, but sel 0 is used for R1x000 framemask */
6206        CP0_CHECK(!(ctx->insn_flags & ISA_MIPS32R6));
6207        switch (sel) {
6208        case 0:
6209            gen_helper_mtc0_framemask(cpu_env, arg);
6210            rn = "Framemask";
6211            break;
6212        default:
6213            goto cp0_unimplemented;
6214        }
6215        break;
6216    case 22:
6217        /* ignored */
6218        rn = "Diagnostic"; /* implementation dependent */
6219        break;
6220    case 23:
6221        switch (sel) {
6222        case 0:
6223            gen_helper_mtc0_debug(cpu_env, arg); /* EJTAG support */
6224            /* BS_STOP isn't good enough here, hflags may have changed. */
6225            gen_save_pc(ctx->pc + 4);
6226            ctx->bstate = BS_EXCP;
6227            rn = "Debug";
6228            break;
6229        case 1:
6230//            gen_helper_mtc0_tracecontrol(cpu_env, arg); /* PDtrace support */
6231            rn = "TraceControl";
6232            /* Stop translation as we may have switched the execution mode */
6233            ctx->bstate = BS_STOP;
6234            goto cp0_unimplemented;
6235        case 2:
6236//            gen_helper_mtc0_tracecontrol2(cpu_env, arg); /* PDtrace support */
6237            rn = "TraceControl2";
6238            /* Stop translation as we may have switched the execution mode */
6239            ctx->bstate = BS_STOP;
6240            goto cp0_unimplemented;
6241        case 3:
6242            /* Stop translation as we may have switched the execution mode */
6243            ctx->bstate = BS_STOP;
6244//            gen_helper_mtc0_usertracedata(cpu_env, arg); /* PDtrace support */
6245            rn = "UserTraceData";
6246            /* Stop translation as we may have switched the execution mode */
6247            ctx->bstate = BS_STOP;
6248            goto cp0_unimplemented;
6249        case 4:
6250//            gen_helper_mtc0_tracebpc(cpu_env, arg); /* PDtrace support */
6251            /* Stop translation as we may have switched the execution mode */
6252            ctx->bstate = BS_STOP;
6253            rn = "TraceBPC";
6254            goto cp0_unimplemented;
6255        default:
6256            goto cp0_unimplemented;
6257        }
6258        break;
6259    case 24:
6260        switch (sel) {
6261        case 0:
6262            /* EJTAG support */
6263            tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_DEPC));
6264            rn = "DEPC";
6265            break;
6266        default:
6267            goto cp0_unimplemented;
6268        }
6269        break;
6270    case 25:
6271        switch (sel) {
6272        case 0:
6273            gen_helper_mtc0_performance0(cpu_env, arg);
6274            rn = "Performance0";
6275            break;
6276        case 1:
6277//            gen_helper_mtc0_performance1(arg);
6278            rn = "Performance1";
6279            goto cp0_unimplemented;
6280        case 2:
6281//            gen_helper_mtc0_performance2(arg);
6282            rn = "Performance2";
6283            goto cp0_unimplemented;
6284        case 3:
6285//            gen_helper_mtc0_performance3(arg);
6286            rn = "Performance3";
6287            goto cp0_unimplemented;
6288        case 4:
6289//            gen_helper_mtc0_performance4(arg);
6290            rn = "Performance4";
6291            goto cp0_unimplemented;
6292        case 5:
6293//            gen_helper_mtc0_performance5(arg);
6294            rn = "Performance5";
6295            goto cp0_unimplemented;
6296        case 6:
6297//            gen_helper_mtc0_performance6(arg);
6298            rn = "Performance6";
6299            goto cp0_unimplemented;
6300        case 7:
6301//            gen_helper_mtc0_performance7(arg);
6302            rn = "Performance7";
6303            goto cp0_unimplemented;
6304        default:
6305            goto cp0_unimplemented;
6306        }
6307       break;
6308    case 26:
6309        switch (sel) {
6310        case 0:
6311            gen_helper_mtc0_errctl(cpu_env, arg);
6312            ctx->bstate = BS_STOP;
6313            rn = "ErrCtl";
6314            break;
6315        default:
6316            goto cp0_unimplemented;
6317        }
6318        break;
6319    case 27:
6320        switch (sel) {
6321        case 0 ... 3:
6322            /* ignored */
6323            rn = "CacheErr";
6324            break;
6325        default:
6326            goto cp0_unimplemented;
6327        }
6328       break;
6329    case 28:
6330        switch (sel) {
6331        case 0:
6332        case 2:
6333        case 4:
6334        case 6:
6335            gen_helper_mtc0_taglo(cpu_env, arg);
6336            rn = "TagLo";
6337            break;
6338        case 1:
6339        case 3:
6340        case 5:
6341        case 7:
6342            gen_helper_mtc0_datalo(cpu_env, arg);
6343            rn = "DataLo";
6344            break;
6345        default:
6346            goto cp0_unimplemented;
6347        }
6348        break;
6349    case 29:
6350        switch (sel) {
6351        case 0:
6352        case 2:
6353        case 4:
6354        case 6:
6355            gen_helper_mtc0_taghi(cpu_env, arg);
6356            rn = "TagHi";
6357            break;
6358        case 1:
6359        case 3:
6360        case 5:
6361        case 7:
6362            gen_helper_mtc0_datahi(cpu_env, arg);
6363            rn = "DataHi";
6364            break;
6365        default:
6366            rn = "invalid sel";
6367            goto cp0_unimplemented;
6368        }
6369       break;
6370    case 30:
6371        switch (sel) {
6372        case 0:
6373            tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_ErrorEPC));
6374            rn = "ErrorEPC";
6375            break;
6376        default:
6377            goto cp0_unimplemented;
6378        }
6379        break;
6380    case 31:
6381        switch (sel) {
6382        case 0:
6383            /* EJTAG support */
6384            gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_DESAVE));
6385            rn = "DESAVE";
6386            break;
6387        case 2 ... 7:
6388            CP0_CHECK(ctx->kscrexist & (1 << sel));
6389            tcg_gen_st_tl(arg, cpu_env,
6390                          offsetof(CPUMIPSState, CP0_KScratch[sel-2]));
6391            rn = "KScratch";
6392            break;
6393        default:
6394            goto cp0_unimplemented;
6395        }
6396        break;
6397    default:
6398       goto cp0_unimplemented;
6399    }
6400    trace_mips_translate_c0("mtc0", rn, reg, sel);
6401
6402    /* For simplicity assume that all writes can cause interrupts.  */
6403    if (tb_cflags(ctx->tb) & CF_USE_ICOUNT) {
6404        gen_io_end();
6405        /* BS_STOP isn't sufficient, we need to ensure we break out of
6406         * translated code to check for pending interrupts.  */
6407        gen_save_pc(ctx->pc + 4);
6408        ctx->bstate = BS_EXCP;
6409    }
6410    return;
6411
6412cp0_unimplemented:
6413    qemu_log_mask(LOG_UNIMP, "mtc0 %s (reg %d sel %d)\n", rn, reg, sel);
6414}
6415
6416#if defined(TARGET_MIPS64)
6417static void gen_dmfc0(DisasContext *ctx, TCGv arg, int reg, int sel)
6418{
6419    const char *rn = "invalid";
6420
6421    if (sel != 0)
6422        check_insn(ctx, ISA_MIPS64);
6423
6424    switch (reg) {
6425    case 0:
6426        switch (sel) {
6427        case 0:
6428            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Index));
6429            rn = "Index";
6430            break;
6431        case 1:
6432            CP0_CHECK(ctx->insn_flags & ASE_MT);
6433            gen_helper_mfc0_mvpcontrol(arg, cpu_env);
6434            rn = "MVPControl";
6435            break;
6436        case 2:
6437            CP0_CHECK(ctx->insn_flags & ASE_MT);
6438            gen_helper_mfc0_mvpconf0(arg, cpu_env);
6439            rn = "MVPConf0";
6440            break;
6441        case 3:
6442            CP0_CHECK(ctx->insn_flags & ASE_MT);
6443            gen_helper_mfc0_mvpconf1(arg, cpu_env);
6444            rn = "MVPConf1";
6445            break;
6446        case 4:
6447            CP0_CHECK(ctx->vp);
6448            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPControl));
6449            rn = "VPControl";
6450            break;
6451        default:
6452            goto cp0_unimplemented;
6453        }
6454        break;
6455    case 1:
6456        switch (sel) {
6457        case 0:
6458            CP0_CHECK(!(ctx->insn_flags & ISA_MIPS32R6));
6459            gen_helper_mfc0_random(arg, cpu_env);
6460            rn = "Random";
6461            break;
6462        case 1:
6463            CP0_CHECK(ctx->insn_flags & ASE_MT);
6464            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEControl));
6465            rn = "VPEControl";
6466            break;
6467        case 2:
6468            CP0_CHECK(ctx->insn_flags & ASE_MT);
6469            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf0));
6470            rn = "VPEConf0";
6471            break;
6472        case 3:
6473            CP0_CHECK(ctx->insn_flags & ASE_MT);
6474            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf1));
6475            rn = "VPEConf1";
6476            break;
6477        case 4:
6478            CP0_CHECK(ctx->insn_flags & ASE_MT);
6479            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_YQMask));
6480            rn = "YQMask";
6481            break;
6482        case 5:
6483            CP0_CHECK(ctx->insn_flags & ASE_MT);
6484            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_VPESchedule));
6485            rn = "VPESchedule";
6486            break;
6487        case 6:
6488            CP0_CHECK(ctx->insn_flags & ASE_MT);
6489            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_VPEScheFBack));
6490            rn = "VPEScheFBack";
6491            break;
6492        case 7:
6493            CP0_CHECK(ctx->insn_flags & ASE_MT);
6494            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEOpt));
6495            rn = "VPEOpt";
6496            break;
6497        default:
6498            goto cp0_unimplemented;
6499        }
6500        break;
6501    case 2:
6502        switch (sel) {
6503        case 0:
6504            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryLo0));
6505            rn = "EntryLo0";
6506            break;
6507        case 1:
6508            CP0_CHECK(ctx->insn_flags & ASE_MT);
6509            gen_helper_mfc0_tcstatus(arg, cpu_env);
6510            rn = "TCStatus";
6511            break;
6512        case 2:
6513            CP0_CHECK(ctx->insn_flags & ASE_MT);
6514            gen_helper_mfc0_tcbind(arg, cpu_env);
6515            rn = "TCBind";
6516            break;
6517        case 3:
6518            CP0_CHECK(ctx->insn_flags & ASE_MT);
6519            gen_helper_dmfc0_tcrestart(arg, cpu_env);
6520            rn = "TCRestart";
6521            break;
6522        case 4:
6523            CP0_CHECK(ctx->insn_flags & ASE_MT);
6524            gen_helper_dmfc0_tchalt(arg, cpu_env);
6525            rn = "TCHalt";
6526            break;
6527        case 5:
6528            CP0_CHECK(ctx->insn_flags & ASE_MT);
6529            gen_helper_dmfc0_tccontext(arg, cpu_env);
6530            rn = "TCContext";
6531            break;
6532        case 6:
6533            CP0_CHECK(ctx->insn_flags & ASE_MT);
6534            gen_helper_dmfc0_tcschedule(arg, cpu_env);
6535            rn = "TCSchedule";
6536            break;
6537        case 7:
6538            CP0_CHECK(ctx->insn_flags & ASE_MT);
6539            gen_helper_dmfc0_tcschefback(arg, cpu_env);
6540            rn = "TCScheFBack";
6541            break;
6542        default:
6543            goto cp0_unimplemented;
6544        }
6545        break;
6546    case 3:
6547        switch (sel) {
6548        case 0:
6549            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryLo1));
6550            rn = "EntryLo1";
6551            break;
6552        case 1:
6553            CP0_CHECK(ctx->vp);
6554            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_GlobalNumber));
6555            rn = "GlobalNumber";
6556            break;
6557        default:
6558            goto cp0_unimplemented;
6559        }
6560        break;
6561    case 4:
6562        switch (sel) {
6563        case 0:
6564            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_Context));
6565            rn = "Context";
6566            break;
6567        case 1:
6568//            gen_helper_dmfc0_contextconfig(arg); /* SmartMIPS ASE */
6569            rn = "ContextConfig";
6570            goto cp0_unimplemented;
6571        case 2:
6572            CP0_CHECK(ctx->ulri);
6573            tcg_gen_ld_tl(arg, cpu_env,
6574                          offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
6575            rn = "UserLocal";
6576            break;
6577        default:
6578            goto cp0_unimplemented;
6579        }
6580        break;
6581    case 5:
6582        switch (sel) {
6583        case 0:
6584            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageMask));
6585            rn = "PageMask";
6586            break;
6587        case 1:
6588            check_insn(ctx, ISA_MIPS32R2);
6589            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageGrain));
6590            rn = "PageGrain";
6591            break;
6592        case 2:
6593            CP0_CHECK(ctx->sc);
6594            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_SegCtl0));
6595            rn = "SegCtl0";
6596            break;
6597        case 3:
6598            CP0_CHECK(ctx->sc);
6599            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_SegCtl1));
6600            rn = "SegCtl1";
6601            break;
6602        case 4:
6603            CP0_CHECK(ctx->sc);
6604            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_SegCtl2));
6605            rn = "SegCtl2";
6606            break;
6607        default:
6608            goto cp0_unimplemented;
6609        }
6610        break;
6611    case 6:
6612        switch (sel) {
6613        case 0:
6614            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Wired));
6615            rn = "Wired";
6616            break;
6617        case 1:
6618            check_insn(ctx, ISA_MIPS32R2);
6619            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf0));
6620            rn = "SRSConf0";
6621            break;
6622        case 2:
6623            check_insn(ctx, ISA_MIPS32R2);
6624            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf1));
6625            rn = "SRSConf1";
6626            break;
6627        case 3:
6628            check_insn(ctx, ISA_MIPS32R2);
6629            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf2));
6630            rn = "SRSConf2";
6631            break;
6632        case 4:
6633            check_insn(ctx, ISA_MIPS32R2);
6634            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf3));
6635            rn = "SRSConf3";
6636            break;
6637        case 5:
6638            check_insn(ctx, ISA_MIPS32R2);
6639            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf4));
6640            rn = "SRSConf4";
6641            break;
6642        default:
6643            goto cp0_unimplemented;
6644        }
6645        break;
6646    case 7:
6647        switch (sel) {
6648        case 0:
6649            check_insn(ctx, ISA_MIPS32R2);
6650            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_HWREna));
6651            rn = "HWREna";
6652            break;
6653        default:
6654            goto cp0_unimplemented;
6655        }
6656        break;
6657    case 8:
6658        switch (sel) {
6659        case 0:
6660            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_BadVAddr));
6661            rn = "BadVAddr";
6662            break;
6663        case 1:
6664            CP0_CHECK(ctx->bi);
6665            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_BadInstr));
6666            rn = "BadInstr";
6667            break;
6668        case 2:
6669            CP0_CHECK(ctx->bp);
6670            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_BadInstrP));
6671            rn = "BadInstrP";
6672            break;
6673        default:
6674            goto cp0_unimplemented;
6675        }
6676        break;
6677    case 9:
6678        switch (sel) {
6679        case 0:
6680            /* Mark as an IO operation because we read the time.  */
6681            if (tb_cflags(ctx->tb) & CF_USE_ICOUNT) {
6682                gen_io_start();
6683            }
6684            gen_helper_mfc0_count(arg, cpu_env);
6685            if (tb_cflags(ctx->tb) & CF_USE_ICOUNT) {
6686                gen_io_end();
6687            }
6688            /* Break the TB to be able to take timer interrupts immediately
6689               after reading count. BS_STOP isn't sufficient, we need to ensure
6690               we break completely out of translated code.  */
6691            gen_save_pc(ctx->pc + 4);
6692            ctx->bstate = BS_EXCP;
6693            rn = "Count";
6694            break;
6695        /* 6,7 are implementation dependent */
6696        default:
6697            goto cp0_unimplemented;
6698        }
6699        break;
6700    case 10:
6701        switch (sel) {
6702        case 0:
6703            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryHi));
6704            rn = "EntryHi";
6705            break;
6706        default:
6707            goto cp0_unimplemented;
6708        }
6709        break;
6710    case 11:
6711        switch (sel) {
6712        case 0:
6713            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Compare));
6714            rn = "Compare";
6715            break;
6716        /* 6,7 are implementation dependent */
6717        default:
6718            goto cp0_unimplemented;
6719        }
6720        break;
6721    case 12:
6722        switch (sel) {
6723        case 0:
6724            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Status));
6725            rn = "Status";
6726            break;
6727        case 1:
6728            check_insn(ctx, ISA_MIPS32R2);
6729            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_IntCtl));
6730            rn = "IntCtl";
6731            break;
6732        case 2:
6733            check_insn(ctx, ISA_MIPS32R2);
6734            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSCtl));
6735            rn = "SRSCtl";
6736            break;
6737        case 3:
6738            check_insn(ctx, ISA_MIPS32R2);
6739            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSMap));
6740            rn = "SRSMap";
6741            break;
6742        default:
6743            goto cp0_unimplemented;
6744        }
6745        break;
6746    case 13:
6747        switch (sel) {
6748        case 0:
6749            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Cause));
6750            rn = "Cause";
6751            break;
6752        default:
6753            goto cp0_unimplemented;
6754        }
6755        break;
6756    case 14:
6757        switch (sel) {
6758        case 0:
6759            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EPC));
6760            rn = "EPC";
6761            break;
6762        default:
6763            goto cp0_unimplemented;
6764        }
6765        break;
6766    case 15:
6767        switch (sel) {
6768        case 0:
6769            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PRid));
6770            rn = "PRid";
6771            break;
6772        case 1:
6773            check_insn(ctx, ISA_MIPS32R2);
6774            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EBase));
6775            rn = "EBase";
6776            break;
6777        case 3:
6778            check_insn(ctx, ISA_MIPS32R2);
6779            CP0_CHECK(ctx->cmgcr);
6780            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_CMGCRBase));
6781            rn = "CMGCRBase";
6782            break;
6783        default:
6784            goto cp0_unimplemented;
6785        }
6786        break;
6787    case 16:
6788        switch (sel) {
6789        case 0:
6790            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config0));
6791            rn = "Config";
6792            break;
6793        case 1:
6794            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config1));
6795            rn = "Config1";
6796            break;
6797        case 2:
6798            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config2));
6799            rn = "Config2";
6800            break;
6801        case 3:
6802            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config3));
6803            rn = "Config3";
6804            break;
6805        case 4:
6806            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config4));
6807            rn = "Config4";
6808            break;
6809        case 5:
6810            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config5));
6811            rn = "Config5";
6812            break;
6813       /* 6,7 are implementation dependent */
6814        case 6:
6815            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config6));
6816            rn = "Config6";
6817            break;
6818        case 7:
6819            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config7));
6820            rn = "Config7";
6821            break;
6822        default:
6823            goto cp0_unimplemented;
6824        }
6825        break;
6826    case 17:
6827        switch (sel) {
6828        case 0:
6829            gen_helper_dmfc0_lladdr(arg, cpu_env);
6830            rn = "LLAddr";
6831            break;
6832        case 1:
6833            CP0_CHECK(ctx->mrp);
6834            gen_helper_dmfc0_maar(arg, cpu_env);
6835            rn = "MAAR";
6836            break;
6837        case 2:
6838            CP0_CHECK(ctx->mrp);
6839            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_MAARI));
6840            rn = "MAARI";
6841            break;
6842        default:
6843            goto cp0_unimplemented;
6844        }
6845        break;
6846    case 18:
6847        switch (sel) {
6848        case 0 ... 7:
6849            gen_helper_1e0i(dmfc0_watchlo, arg, sel);
6850            rn = "WatchLo";
6851            break;
6852        default:
6853            goto cp0_unimplemented;
6854        }
6855        break;
6856    case 19:
6857        switch (sel) {
6858        case 0 ... 7:
6859            gen_helper_1e0i(mfc0_watchhi, arg, sel);
6860            rn = "WatchHi";
6861            break;
6862        default:
6863            goto cp0_unimplemented;
6864        }
6865        break;
6866    case 20:
6867        switch (sel) {
6868        case 0:
6869            check_insn(ctx, ISA_MIPS3);
6870            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_XContext));
6871            rn = "XContext";
6872            break;
6873        default:
6874            goto cp0_unimplemented;
6875        }
6876        break;
6877    case 21:
6878       /* Officially reserved, but sel 0 is used for R1x000 framemask */
6879        CP0_CHECK(!(ctx->insn_flags & ISA_MIPS32R6));
6880        switch (sel) {
6881        case 0:
6882            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Framemask));
6883            rn = "Framemask";
6884            break;
6885        default:
6886            goto cp0_unimplemented;
6887        }
6888        break;
6889    case 22:
6890        tcg_gen_movi_tl(arg, 0); /* unimplemented */
6891        rn = "'Diagnostic"; /* implementation dependent */
6892        break;
6893    case 23:
6894        switch (sel) {
6895        case 0:
6896            gen_helper_mfc0_debug(arg, cpu_env); /* EJTAG support */
6897            rn = "Debug";
6898            break;
6899        case 1:
6900//            gen_helper_dmfc0_tracecontrol(arg, cpu_env); /* PDtrace support */
6901            rn = "TraceControl";
6902            goto cp0_unimplemented;
6903        case 2:
6904//            gen_helper_dmfc0_tracecontrol2(arg, cpu_env); /* PDtrace support */
6905            rn = "TraceControl2";
6906            goto cp0_unimplemented;
6907        case 3:
6908//            gen_helper_dmfc0_usertracedata(arg, cpu_env); /* PDtrace support */
6909            rn = "UserTraceData";
6910            goto cp0_unimplemented;
6911        case 4:
6912//            gen_helper_dmfc0_tracebpc(arg, cpu_env); /* PDtrace support */
6913            rn = "TraceBPC";
6914            goto cp0_unimplemented;
6915        default:
6916            goto cp0_unimplemented;
6917        }
6918        break;
6919    case 24:
6920        switch (sel) {
6921        case 0:
6922            /* EJTAG support */
6923            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_DEPC));
6924            rn = "DEPC";
6925            break;
6926        default:
6927            goto cp0_unimplemented;
6928        }
6929        break;
6930    case 25:
6931        switch (sel) {
6932        case 0:
6933            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Performance0));
6934            rn = "Performance0";
6935            break;
6936        case 1:
6937//            gen_helper_dmfc0_performance1(arg);
6938            rn = "Performance1";
6939            goto cp0_unimplemented;
6940        case 2:
6941//            gen_helper_dmfc0_performance2(arg);
6942            rn = "Performance2";
6943            goto cp0_unimplemented;
6944        case 3:
6945//            gen_helper_dmfc0_performance3(arg);
6946            rn = "Performance3";
6947            goto cp0_unimplemented;
6948        case 4:
6949//            gen_helper_dmfc0_performance4(arg);
6950            rn = "Performance4";
6951            goto cp0_unimplemented;
6952        case 5:
6953//            gen_helper_dmfc0_performance5(arg);
6954            rn = "Performance5";
6955            goto cp0_unimplemented;
6956        case 6:
6957//            gen_helper_dmfc0_performance6(arg);
6958            rn = "Performance6";
6959            goto cp0_unimplemented;
6960        case 7:
6961//            gen_helper_dmfc0_performance7(arg);
6962            rn = "Performance7";
6963            goto cp0_unimplemented;
6964        default:
6965            goto cp0_unimplemented;
6966        }
6967        break;
6968    case 26:
6969        switch (sel) {
6970        case 0:
6971            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_ErrCtl));
6972            rn = "ErrCtl";
6973            break;
6974        default:
6975            goto cp0_unimplemented;
6976        }
6977        break;
6978    case 27:
6979        switch (sel) {
6980        /* ignored */
6981        case 0 ... 3:
6982            tcg_gen_movi_tl(arg, 0); /* unimplemented */
6983            rn = "CacheErr";
6984            break;
6985        default:
6986            goto cp0_unimplemented;
6987        }
6988        break;
6989    case 28:
6990        switch (sel) {
6991        case 0:
6992        case 2:
6993        case 4:
6994        case 6:
6995            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_TagLo));
6996            rn = "TagLo";
6997            break;
6998        case 1:
6999        case 3:
7000        case 5:
7001        case 7:
7002            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataLo));
7003            rn = "DataLo";
7004            break;
7005        default:
7006            goto cp0_unimplemented;
7007        }
7008        break;
7009    case 29:
7010        switch (sel) {
7011        case 0:
7012        case 2:
7013        case 4:
7014        case 6:
7015            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_TagHi));
7016            rn = "TagHi";
7017            break;
7018        case 1:
7019        case 3:
7020        case 5:
7021        case 7:
7022            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataHi));
7023            rn = "DataHi";
7024            break;
7025        default:
7026            goto cp0_unimplemented;
7027        }
7028        break;
7029    case 30:
7030        switch (sel) {
7031        case 0:
7032            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_ErrorEPC));
7033            rn = "ErrorEPC";
7034            break;
7035        default:
7036            goto cp0_unimplemented;
7037        }
7038        break;
7039    case 31:
7040        switch (sel) {
7041        case 0:
7042            /* EJTAG support */
7043            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DESAVE));
7044            rn = "DESAVE";
7045            break;
7046        case 2 ... 7:
7047            CP0_CHECK(ctx->kscrexist & (1 << sel));
7048            tcg_gen_ld_tl(arg, cpu_env,
7049                          offsetof(CPUMIPSState, CP0_KScratch[sel-2]));
7050            rn = "KScratch";
7051            break;
7052        default:
7053            goto cp0_unimplemented;
7054        }
7055        break;
7056    default:
7057        goto cp0_unimplemented;
7058    }
7059    trace_mips_translate_c0("dmfc0", rn, reg, sel);
7060    return;
7061
7062cp0_unimplemented:
7063    qemu_log_mask(LOG_UNIMP, "dmfc0 %s (reg %d sel %d)\n", rn, reg, sel);
7064    gen_mfc0_unimplemented(ctx, arg);
7065}
7066
7067static void gen_dmtc0(DisasContext *ctx, TCGv arg, int reg, int sel)
7068{
7069    const char *rn = "invalid";
7070
7071    if (sel != 0)
7072        check_insn(ctx, ISA_MIPS64);
7073
7074    if (tb_cflags(ctx->tb) & CF_USE_ICOUNT) {
7075        gen_io_start();
7076    }
7077
7078    switch (reg) {
7079    case 0:
7080        switch (sel) {
7081        case 0:
7082            gen_helper_mtc0_index(cpu_env, arg);
7083            rn = "Index";
7084            break;
7085        case 1:
7086            CP0_CHECK(ctx->insn_flags & ASE_MT);
7087            gen_helper_mtc0_mvpcontrol(cpu_env, arg);
7088            rn = "MVPControl";
7089            break;
7090        case 2:
7091            CP0_CHECK(ctx->insn_flags & ASE_MT);
7092            /* ignored */
7093            rn = "MVPConf0";
7094            break;
7095        case 3:
7096            CP0_CHECK(ctx->insn_flags & ASE_MT);
7097            /* ignored */
7098            rn = "MVPConf1";
7099            break;
7100        case 4:
7101            CP0_CHECK(ctx->vp);
7102            /* ignored */
7103            rn = "VPControl";
7104            break;
7105        default:
7106            goto cp0_unimplemented;
7107        }
7108        break;
7109    case 1:
7110        switch (sel) {
7111        case 0:
7112            /* ignored */
7113            rn = "Random";
7114            break;
7115        case 1:
7116            CP0_CHECK(ctx->insn_flags & ASE_MT);
7117            gen_helper_mtc0_vpecontrol(cpu_env, arg);
7118            rn = "VPEControl";
7119            break;
7120        case 2:
7121            CP0_CHECK(ctx->insn_flags & ASE_MT);
7122            gen_helper_mtc0_vpeconf0(cpu_env, arg);
7123            rn = "VPEConf0";
7124            break;
7125        case 3:
7126            CP0_CHECK(ctx->insn_flags & ASE_MT);
7127            gen_helper_mtc0_vpeconf1(cpu_env, arg);
7128            rn = "VPEConf1";
7129            break;
7130        case 4:
7131            CP0_CHECK(ctx->insn_flags & ASE_MT);
7132            gen_helper_mtc0_yqmask(cpu_env, arg);
7133            rn = "YQMask";
7134            break;
7135        case 5:
7136            CP0_CHECK(ctx->insn_flags & ASE_MT);
7137            tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_VPESchedule));
7138            rn = "VPESchedule";
7139            break;
7140        case 6:
7141            CP0_CHECK(ctx->insn_flags & ASE_MT);
7142            tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_VPEScheFBack));
7143            rn = "VPEScheFBack";
7144            break;
7145        case 7:
7146            CP0_CHECK(ctx->insn_flags & ASE_MT);
7147            gen_helper_mtc0_vpeopt(cpu_env, arg);
7148            rn = "VPEOpt";
7149            break;
7150        default:
7151            goto cp0_unimplemented;
7152        }
7153        break;
7154    case 2:
7155        switch (sel) {
7156        case 0:
7157            gen_helper_dmtc0_entrylo0(cpu_env, arg);
7158            rn = "EntryLo0";
7159            break;
7160        case 1:
7161            CP0_CHECK(ctx->insn_flags & ASE_MT);
7162            gen_helper_mtc0_tcstatus(cpu_env, arg);
7163            rn = "TCStatus";
7164            break;
7165        case 2:
7166            CP0_CHECK(ctx->insn_flags & ASE_MT);
7167            gen_helper_mtc0_tcbind(cpu_env, arg);
7168            rn = "TCBind";
7169            break;
7170        case 3:
7171            CP0_CHECK(ctx->insn_flags & ASE_MT);
7172            gen_helper_mtc0_tcrestart(cpu_env, arg);
7173            rn = "TCRestart";
7174            break;
7175        case 4:
7176            CP0_CHECK(ctx->insn_flags & ASE_MT);
7177            gen_helper_mtc0_tchalt(cpu_env, arg);
7178            rn = "TCHalt";
7179            break;
7180        case 5:
7181            CP0_CHECK(ctx->insn_flags & ASE_MT);
7182            gen_helper_mtc0_tccontext(cpu_env, arg);
7183            rn = "TCContext";
7184            break;
7185        case 6:
7186            CP0_CHECK(ctx->insn_flags & ASE_MT);
7187            gen_helper_mtc0_tcschedule(cpu_env, arg);
7188            rn = "TCSchedule";
7189            break;
7190        case 7:
7191            CP0_CHECK(ctx->insn_flags & ASE_MT);
7192            gen_helper_mtc0_tcschefback(cpu_env, arg);
7193            rn = "TCScheFBack";
7194            break;
7195        default:
7196            goto cp0_unimplemented;
7197        }
7198        break;
7199    case 3:
7200        switch (sel) {
7201        case 0:
7202            gen_helper_dmtc0_entrylo1(cpu_env, arg);
7203            rn = "EntryLo1";
7204            break;
7205        case 1:
7206            CP0_CHECK(ctx->vp);
7207            /* ignored */
7208            rn = "GlobalNumber";
7209            break;
7210        default:
7211            goto cp0_unimplemented;
7212        }
7213        break;
7214    case 4:
7215        switch (sel) {
7216        case 0:
7217            gen_helper_mtc0_context(cpu_env, arg);
7218            rn = "Context";
7219            break;
7220        case 1:
7221//           gen_helper_mtc0_contextconfig(cpu_env, arg); /* SmartMIPS ASE */
7222            rn = "ContextConfig";
7223            goto cp0_unimplemented;
7224        case 2:
7225            CP0_CHECK(ctx->ulri);
7226            tcg_gen_st_tl(arg, cpu_env,
7227                          offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
7228            rn = "UserLocal";
7229            break;
7230        default:
7231            goto cp0_unimplemented;
7232        }
7233        break;
7234    case 5:
7235        switch (sel) {
7236        case 0:
7237            gen_helper_mtc0_pagemask(cpu_env, arg);
7238            rn = "PageMask";
7239            break;
7240        case 1:
7241            check_insn(ctx, ISA_MIPS32R2);
7242            gen_helper_mtc0_pagegrain(cpu_env, arg);
7243            rn = "PageGrain";
7244            break;
7245        case 2:
7246            CP0_CHECK(ctx->sc);
7247            gen_helper_mtc0_segctl0(cpu_env, arg);
7248            rn = "SegCtl0";
7249            break;
7250        case 3:
7251            CP0_CHECK(ctx->sc);
7252            gen_helper_mtc0_segctl1(cpu_env, arg);
7253            rn = "SegCtl1";
7254            break;
7255        case 4:
7256            CP0_CHECK(ctx->sc);
7257            gen_helper_mtc0_segctl2(cpu_env, arg);
7258            rn = "SegCtl2";
7259            break;
7260        default:
7261            goto cp0_unimplemented;
7262        }
7263        break;
7264    case 6:
7265        switch (sel) {
7266        case 0:
7267            gen_helper_mtc0_wired(cpu_env, arg);
7268            rn = "Wired";
7269            break;
7270        case 1:
7271            check_insn(ctx, ISA_MIPS32R2);
7272            gen_helper_mtc0_srsconf0(cpu_env, arg);
7273            rn = "SRSConf0";
7274            break;
7275        case 2:
7276            check_insn(ctx, ISA_MIPS32R2);
7277            gen_helper_mtc0_srsconf1(cpu_env, arg);
7278            rn = "SRSConf1";
7279            break;
7280        case 3:
7281            check_insn(ctx, ISA_MIPS32R2);
7282            gen_helper_mtc0_srsconf2(cpu_env, arg);
7283            rn = "SRSConf2";
7284            break;
7285        case 4:
7286            check_insn(ctx, ISA_MIPS32R2);
7287            gen_helper_mtc0_srsconf3(cpu_env, arg);
7288            rn = "SRSConf3";
7289            break;
7290        case 5:
7291            check_insn(ctx, ISA_MIPS32R2);
7292            gen_helper_mtc0_srsconf4(cpu_env, arg);
7293            rn = "SRSConf4";
7294            break;
7295        default:
7296            goto cp0_unimplemented;
7297        }
7298        break;
7299    case 7:
7300        switch (sel) {
7301        case 0:
7302            check_insn(ctx, ISA_MIPS32R2);
7303            gen_helper_mtc0_hwrena(cpu_env, arg);
7304            ctx->bstate = BS_STOP;
7305            rn = "HWREna";
7306            break;
7307        default:
7308            goto cp0_unimplemented;
7309        }
7310        break;
7311    case 8:
7312        switch (sel) {
7313        case 0:
7314            /* ignored */
7315            rn = "BadVAddr";
7316            break;
7317        case 1:
7318            /* ignored */
7319            rn = "BadInstr";
7320            break;
7321        case 2:
7322            /* ignored */
7323            rn = "BadInstrP";
7324            break;
7325        default:
7326            goto cp0_unimplemented;
7327        }
7328        break;
7329    case 9:
7330        switch (sel) {
7331        case 0:
7332            gen_helper_mtc0_count(cpu_env, arg);
7333            rn = "Count";
7334            break;
7335        /* 6,7 are implementation dependent */
7336        default:
7337            goto cp0_unimplemented;
7338        }
7339        /* Stop translation as we may have switched the execution mode */
7340        ctx->bstate = BS_STOP;
7341        break;
7342    case 10:
7343        switch (sel) {
7344        case 0:
7345            gen_helper_mtc0_entryhi(cpu_env, arg);
7346            rn = "EntryHi";
7347            break;
7348        default:
7349            goto cp0_unimplemented;
7350        }
7351        break;
7352    case 11:
7353        switch (sel) {
7354        case 0:
7355            gen_helper_mtc0_compare(cpu_env, arg);
7356            rn = "Compare";
7357            break;
7358        /* 6,7 are implementation dependent */
7359        default:
7360            goto cp0_unimplemented;
7361        }
7362        /* Stop translation as we may have switched the execution mode */
7363        ctx->bstate = BS_STOP;
7364        break;
7365    case 12:
7366        switch (sel) {
7367        case 0:
7368            save_cpu_state(ctx, 1);
7369            gen_helper_mtc0_status(cpu_env, arg);
7370            /* BS_STOP isn't good enough here, hflags may have changed. */
7371            gen_save_pc(ctx->pc + 4);
7372            ctx->bstate = BS_EXCP;
7373            rn = "Status";
7374            break;
7375        case 1:
7376            check_insn(ctx, ISA_MIPS32R2);
7377            gen_helper_mtc0_intctl(cpu_env, arg);
7378            /* Stop translation as we may have switched the execution mode */
7379            ctx->bstate = BS_STOP;
7380            rn = "IntCtl";
7381            break;
7382        case 2:
7383            check_insn(ctx, ISA_MIPS32R2);
7384            gen_helper_mtc0_srsctl(cpu_env, arg);
7385            /* Stop translation as we may have switched the execution mode */
7386            ctx->bstate = BS_STOP;
7387            rn = "SRSCtl";
7388            break;
7389        case 3:
7390            check_insn(ctx, ISA_MIPS32R2);
7391            gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_SRSMap));
7392            /* Stop translation as we may have switched the execution mode */
7393            ctx->bstate = BS_STOP;
7394            rn = "SRSMap";
7395            break;
7396        default:
7397            goto cp0_unimplemented;
7398        }
7399        break;
7400    case 13:
7401        switch (sel) {
7402        case 0:
7403            save_cpu_state(ctx, 1);
7404            gen_helper_mtc0_cause(cpu_env, arg);
7405            /* Stop translation as we may have triggered an intetrupt. BS_STOP
7406             * isn't sufficient, we need to ensure we break out of translated
7407             * code to check for pending interrupts.  */
7408            gen_save_pc(ctx->pc + 4);
7409            ctx->bstate = BS_EXCP;
7410            rn = "Cause";
7411            break;
7412        default:
7413            goto cp0_unimplemented;
7414        }
7415        break;
7416    case 14:
7417        switch (sel) {
7418        case 0:
7419            tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EPC));
7420            rn = "EPC";
7421            break;
7422        default:
7423            goto cp0_unimplemented;
7424        }
7425        break;
7426    case 15:
7427        switch (sel) {
7428        case 0:
7429            /* ignored */
7430            rn = "PRid";
7431            break;
7432        case 1:
7433            check_insn(ctx, ISA_MIPS32R2);
7434            gen_helper_mtc0_ebase(cpu_env, arg);
7435            rn = "EBase";
7436            break;
7437        default:
7438            goto cp0_unimplemented;
7439        }
7440        break;
7441    case 16:
7442        switch (sel) {
7443        case 0:
7444            gen_helper_mtc0_config0(cpu_env, arg);
7445            rn = "Config";
7446            /* Stop translation as we may have switched the execution mode */
7447            ctx->bstate = BS_STOP;
7448            break;
7449        case 1:
7450            /* ignored, read only */
7451            rn = "Config1";
7452            break;
7453        case 2:
7454            gen_helper_mtc0_config2(cpu_env, arg);
7455            rn = "Config2";
7456            /* Stop translation as we may have switched the execution mode */
7457            ctx->bstate = BS_STOP;
7458            break;
7459        case 3:
7460            gen_helper_mtc0_config3(cpu_env, arg);
7461            rn = "Config3";
7462            /* Stop translation as we may have switched the execution mode */
7463            ctx->bstate = BS_STOP;
7464            break;
7465        case 4:
7466            /* currently ignored */
7467            rn = "Config4";
7468            break;
7469        case 5:
7470            gen_helper_mtc0_config5(cpu_env, arg);
7471            rn = "Config5";
7472            /* Stop translation as we may have switched the execution mode */
7473            ctx->bstate = BS_STOP;
7474            break;
7475        /* 6,7 are implementation dependent */
7476        default:
7477            rn = "Invalid config selector";
7478            goto cp0_unimplemented;
7479        }
7480        break;
7481    case 17:
7482        switch (sel) {
7483        case 0:
7484            gen_helper_mtc0_lladdr(cpu_env, arg);
7485            rn = "LLAddr";
7486            break;
7487        case 1:
7488            CP0_CHECK(ctx->mrp);
7489            gen_helper_mtc0_maar(cpu_env, arg);
7490            rn = "MAAR";
7491            break;
7492        case 2:
7493            CP0_CHECK(ctx->mrp);
7494            gen_helper_mtc0_maari(cpu_env, arg);
7495            rn = "MAARI";
7496            break;
7497        default:
7498            goto cp0_unimplemented;
7499        }
7500        break;
7501    case 18:
7502        switch (sel) {
7503        case 0 ... 7:
7504            gen_helper_0e1i(mtc0_watchlo, arg, sel);
7505            rn = "WatchLo";
7506            break;
7507        default:
7508            goto cp0_unimplemented;
7509        }
7510        break;
7511    case 19:
7512        switch (sel) {
7513        case 0 ... 7:
7514            gen_helper_0e1i(mtc0_watchhi, arg, sel);
7515            rn = "WatchHi";
7516            break;
7517        default:
7518            goto cp0_unimplemented;
7519        }
7520        break;
7521    case 20:
7522        switch (sel) {
7523        case 0:
7524            check_insn(ctx, ISA_MIPS3);
7525            gen_helper_mtc0_xcontext(cpu_env, arg);
7526            rn = "XContext";
7527            break;
7528        default:
7529            goto cp0_unimplemented;
7530        }
7531        break;
7532    case 21:
7533       /* Officially reserved, but sel 0 is used for R1x000 framemask */
7534        CP0_CHECK(!(ctx->insn_flags & ISA_MIPS32R6));
7535        switch (sel) {
7536        case 0:
7537            gen_helper_mtc0_framemask(cpu_env, arg);
7538            rn = "Framemask";
7539            break;
7540        default:
7541            goto cp0_unimplemented;
7542        }
7543        break;
7544    case 22:
7545        /* ignored */
7546        rn = "Diagnostic"; /* implementation dependent */
7547        break;
7548    case 23:
7549        switch (sel) {
7550        case 0:
7551            gen_helper_mtc0_debug(cpu_env, arg); /* EJTAG support */
7552            /* BS_STOP isn't good enough here, hflags may have changed. */
7553            gen_save_pc(ctx->pc + 4);
7554            ctx->bstate = BS_EXCP;
7555            rn = "Debug";
7556            break;
7557        case 1:
7558//            gen_helper_mtc0_tracecontrol(cpu_env, arg); /* PDtrace support */
7559            /* Stop translation as we may have switched the execution mode */
7560            ctx->bstate = BS_STOP;
7561            rn = "TraceControl";
7562            goto cp0_unimplemented;
7563        case 2:
7564//            gen_helper_mtc0_tracecontrol2(cpu_env, arg); /* PDtrace support */
7565            /* Stop translation as we may have switched the execution mode */
7566            ctx->bstate = BS_STOP;
7567            rn = "TraceControl2";
7568            goto cp0_unimplemented;
7569        case 3:
7570//            gen_helper_mtc0_usertracedata(cpu_env, arg); /* PDtrace support */
7571            /* Stop translation as we may have switched the execution mode */
7572            ctx->bstate = BS_STOP;
7573            rn = "UserTraceData";
7574            goto cp0_unimplemented;
7575        case 4:
7576//            gen_helper_mtc0_tracebpc(cpu_env, arg); /* PDtrace support */
7577            /* Stop translation as we may have switched the execution mode */
7578            ctx->bstate = BS_STOP;
7579            rn = "TraceBPC";
7580            goto cp0_unimplemented;
7581        default:
7582            goto cp0_unimplemented;
7583        }
7584        break;
7585    case 24:
7586        switch (sel) {
7587        case 0:
7588            /* EJTAG support */
7589            tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_DEPC));
7590            rn = "DEPC";
7591            break;
7592        default:
7593            goto cp0_unimplemented;
7594        }
7595        break;
7596    case 25:
7597        switch (sel) {
7598        case 0:
7599            gen_helper_mtc0_performance0(cpu_env, arg);
7600            rn = "Performance0";
7601            break;
7602        case 1:
7603//            gen_helper_mtc0_performance1(cpu_env, arg);
7604            rn = "Performance1";
7605            goto cp0_unimplemented;
7606        case 2:
7607//            gen_helper_mtc0_performance2(cpu_env, arg);
7608            rn = "Performance2";
7609            goto cp0_unimplemented;
7610        case 3:
7611//            gen_helper_mtc0_performance3(cpu_env, arg);
7612            rn = "Performance3";
7613            goto cp0_unimplemented;
7614        case 4:
7615//            gen_helper_mtc0_performance4(cpu_env, arg);
7616            rn = "Performance4";
7617            goto cp0_unimplemented;
7618        case 5:
7619//            gen_helper_mtc0_performance5(cpu_env, arg);
7620            rn = "Performance5";
7621            goto cp0_unimplemented;
7622        case 6:
7623//            gen_helper_mtc0_performance6(cpu_env, arg);
7624            rn = "Performance6";
7625            goto cp0_unimplemented;
7626        case 7:
7627//            gen_helper_mtc0_performance7(cpu_env, arg);
7628            rn = "Performance7";
7629            goto cp0_unimplemented;
7630        default:
7631            goto cp0_unimplemented;
7632        }
7633        break;
7634    case 26:
7635        switch (sel) {
7636        case 0:
7637            gen_helper_mtc0_errctl(cpu_env, arg);
7638            ctx->bstate = BS_STOP;
7639            rn = "ErrCtl";
7640            break;
7641        default:
7642            goto cp0_unimplemented;
7643        }
7644        break;
7645    case 27:
7646        switch (sel) {
7647        case 0 ... 3:
7648            /* ignored */
7649            rn = "CacheErr";
7650            break;
7651        default:
7652            goto cp0_unimplemented;
7653        }
7654        break;
7655    case 28:
7656        switch (sel) {
7657        case 0:
7658        case 2:
7659        case 4:
7660        case 6:
7661            gen_helper_mtc0_taglo(cpu_env, arg);
7662            rn = "TagLo";
7663            break;
7664        case 1:
7665        case 3:
7666        case 5:
7667        case 7:
7668            gen_helper_mtc0_datalo(cpu_env, arg);
7669            rn = "DataLo";
7670            break;
7671        default:
7672            goto cp0_unimplemented;
7673        }
7674        break;
7675    case 29:
7676        switch (sel) {
7677        case 0:
7678        case 2:
7679        case 4:
7680        case 6:
7681            gen_helper_mtc0_taghi(cpu_env, arg);
7682            rn = "TagHi";
7683            break;
7684        case 1:
7685        case 3:
7686        case 5:
7687        case 7:
7688            gen_helper_mtc0_datahi(cpu_env, arg);
7689            rn = "DataHi";
7690            break;
7691        default:
7692            rn = "invalid sel";
7693            goto cp0_unimplemented;
7694        }
7695        break;
7696    case 30:
7697        switch (sel) {
7698        case 0:
7699            tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_ErrorEPC));
7700            rn = "ErrorEPC";
7701            break;
7702        default:
7703            goto cp0_unimplemented;
7704        }
7705        break;
7706    case 31:
7707        switch (sel) {
7708        case 0:
7709            /* EJTAG support */
7710            gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_DESAVE));
7711            rn = "DESAVE";
7712            break;
7713        case 2 ... 7:
7714            CP0_CHECK(ctx->kscrexist & (1 << sel));
7715            tcg_gen_st_tl(arg, cpu_env,
7716                          offsetof(CPUMIPSState, CP0_KScratch[sel-2]));
7717            rn = "KScratch";
7718            break;
7719        default:
7720            goto cp0_unimplemented;
7721        }
7722        break;
7723    default:
7724        goto cp0_unimplemented;
7725    }
7726    trace_mips_translate_c0("dmtc0", rn, reg, sel);
7727
7728    /* For simplicity assume that all writes can cause interrupts.  */
7729    if (tb_cflags(ctx->tb) & CF_USE_ICOUNT) {
7730        gen_io_end();
7731        /* BS_STOP isn't sufficient, we need to ensure we break out of
7732         * translated code to check for pending interrupts.  */
7733        gen_save_pc(ctx->pc + 4);
7734        ctx->bstate = BS_EXCP;
7735    }
7736    return;
7737
7738cp0_unimplemented:
7739    qemu_log_mask(LOG_UNIMP, "dmtc0 %s (reg %d sel %d)\n", rn, reg, sel);
7740}
7741#endif /* TARGET_MIPS64 */
7742
7743static void gen_mftr(CPUMIPSState *env, DisasContext *ctx, int rt, int rd,
7744                     int u, int sel, int h)
7745{
7746    int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
7747    TCGv t0 = tcg_temp_local_new();
7748
7749    if ((env->CP0_VPEConf0 & (1 << CP0VPEC0_MVP)) == 0 &&
7750        ((env->tcs[other_tc].CP0_TCBind & (0xf << CP0TCBd_CurVPE)) !=
7751         (env->active_tc.CP0_TCBind & (0xf << CP0TCBd_CurVPE))))
7752        tcg_gen_movi_tl(t0, -1);
7753    else if ((env->CP0_VPEControl & (0xff << CP0VPECo_TargTC)) >
7754             (env->mvp->CP0_MVPConf0 & (0xff << CP0MVPC0_PTC)))
7755        tcg_gen_movi_tl(t0, -1);
7756    else if (u == 0) {
7757        switch (rt) {
7758        case 1:
7759            switch (sel) {
7760            case 1:
7761                gen_helper_mftc0_vpecontrol(t0, cpu_env);
7762                break;
7763            case 2:
7764                gen_helper_mftc0_vpeconf0(t0, cpu_env);
7765                break;
7766            default:
7767                goto die;
7768                break;
7769            }
7770            break;
7771        case 2:
7772            switch (sel) {
7773            case 1:
7774                gen_helper_mftc0_tcstatus(t0, cpu_env);
7775                break;
7776            case 2:
7777                gen_helper_mftc0_tcbind(t0, cpu_env);
7778                break;
7779            case 3:
7780                gen_helper_mftc0_tcrestart(t0, cpu_env);
7781                break;
7782            case 4:
7783                gen_helper_mftc0_tchalt(t0, cpu_env);
7784                break;
7785            case 5:
7786                gen_helper_mftc0_tccontext(t0, cpu_env);
7787                break;
7788            case 6:
7789                gen_helper_mftc0_tcschedule(t0, cpu_env);
7790                break;
7791            case 7:
7792                gen_helper_mftc0_tcschefback(t0, cpu_env);
7793                break;
7794            default:
7795                gen_mfc0(ctx, t0, rt, sel);
7796                break;
7797            }
7798            break;
7799        case 10:
7800            switch (sel) {
7801            case 0:
7802                gen_helper_mftc0_entryhi(t0, cpu_env);
7803                break;
7804            default:
7805                gen_mfc0(ctx, t0, rt, sel);
7806                break;
7807            }
7808        case 12:
7809            switch (sel) {
7810            case 0:
7811                gen_helper_mftc0_status(t0, cpu_env);
7812                break;
7813            default:
7814                gen_mfc0(ctx, t0, rt, sel);
7815                break;
7816            }
7817        case 13:
7818            switch (sel) {
7819            case 0:
7820                gen_helper_mftc0_cause(t0, cpu_env);
7821                break;
7822            default:
7823                goto die;
7824                break;
7825            }
7826            break;
7827        case 14:
7828            switch (sel) {
7829            case 0:
7830                gen_helper_mftc0_epc(t0, cpu_env);
7831                break;
7832            default:
7833                goto die;
7834                break;
7835            }
7836            break;
7837        case 15:
7838            switch (sel) {
7839            case 1:
7840                gen_helper_mftc0_ebase(t0, cpu_env);
7841                break;
7842            default:
7843                goto die;
7844                break;
7845            }
7846            break;
7847        case 16:
7848            switch (sel) {
7849            case 0 ... 7:
7850                gen_helper_mftc0_configx(t0, cpu_env, tcg_const_tl(sel));
7851                break;
7852            default:
7853                goto die;
7854                break;
7855            }
7856            break;
7857        case 23:
7858            switch (sel) {
7859            case 0:
7860                gen_helper_mftc0_debug(t0, cpu_env);
7861                break;
7862            default:
7863                gen_mfc0(ctx, t0, rt, sel);
7864                break;
7865            }
7866            break;
7867        default:
7868            gen_mfc0(ctx, t0, rt, sel);
7869        }
7870    } else switch (sel) {
7871    /* GPR registers. */
7872    case 0:
7873        gen_helper_1e0i(mftgpr, t0, rt);
7874        break;
7875    /* Auxiliary CPU registers */
7876    case 1:
7877        switch (rt) {
7878        case 0:
7879            gen_helper_1e0i(mftlo, t0, 0);
7880            break;
7881        case 1:
7882            gen_helper_1e0i(mfthi, t0, 0);
7883            break;
7884        case 2:
7885            gen_helper_1e0i(mftacx, t0, 0);
7886            break;
7887        case 4:
7888            gen_helper_1e0i(mftlo, t0, 1);
7889            break;
7890        case 5:
7891            gen_helper_1e0i(mfthi, t0, 1);
7892            break;
7893        case 6:
7894            gen_helper_1e0i(mftacx, t0, 1);
7895            break;
7896        case 8:
7897            gen_helper_1e0i(mftlo, t0, 2);
7898            break;
7899        case 9:
7900            gen_helper_1e0i(mfthi, t0, 2);
7901            break;
7902        case 10:
7903            gen_helper_1e0i(mftacx, t0, 2);
7904            break;
7905        case 12:
7906            gen_helper_1e0i(mftlo, t0, 3);
7907            break;
7908        case 13:
7909            gen_helper_1e0i(mfthi, t0, 3);
7910            break;
7911        case 14:
7912            gen_helper_1e0i(mftacx, t0, 3);
7913            break;
7914        case 16:
7915            gen_helper_mftdsp(t0, cpu_env);
7916            break;
7917        default:
7918            goto die;
7919        }
7920        break;
7921    /* Floating point (COP1). */
7922    case 2:
7923        /* XXX: For now we support only a single FPU context. */
7924        if (h == 0) {
7925            TCGv_i32 fp0 = tcg_temp_new_i32();
7926
7927            gen_load_fpr32(ctx, fp0, rt);
7928            tcg_gen_ext_i32_tl(t0, fp0);
7929            tcg_temp_free_i32(fp0);
7930        } else {
7931            TCGv_i32 fp0 = tcg_temp_new_i32();
7932
7933            gen_load_fpr32h(ctx, fp0, rt);
7934            tcg_gen_ext_i32_tl(t0, fp0);
7935            tcg_temp_free_i32(fp0);
7936        }
7937        break;
7938    case 3:
7939        /* XXX: For now we support only a single FPU context. */
7940        gen_helper_1e0i(cfc1, t0, rt);
7941        break;
7942    /* COP2: Not implemented. */
7943    case 4:
7944    case 5:
7945        /* fall through */
7946    default:
7947        goto die;
7948    }
7949    trace_mips_translate_tr("mftr", rt, u, sel, h);
7950    gen_store_gpr(t0, rd);
7951    tcg_temp_free(t0);
7952    return;
7953
7954die:
7955    tcg_temp_free(t0);
7956    LOG_DISAS("mftr (reg %d u %d sel %d h %d)\n", rt, u, sel, h);
7957    generate_exception_end(ctx, EXCP_RI);
7958}
7959
7960static void gen_mttr(CPUMIPSState *env, DisasContext *ctx, int rd, int rt,
7961                     int u, int sel, int h)
7962{
7963    int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
7964    TCGv t0 = tcg_temp_local_new();
7965
7966    gen_load_gpr(t0, rt);
7967    if ((env->CP0_VPEConf0 & (1 << CP0VPEC0_MVP)) == 0 &&
7968        ((env->tcs[other_tc].CP0_TCBind & (0xf << CP0TCBd_CurVPE)) !=
7969         (env->active_tc.CP0_TCBind & (0xf << CP0TCBd_CurVPE))))
7970        /* NOP */ ;
7971    else if ((env->CP0_VPEControl & (0xff << CP0VPECo_TargTC)) >
7972             (env->mvp->CP0_MVPConf0 & (0xff << CP0MVPC0_PTC)))
7973        /* NOP */ ;
7974    else if (u == 0) {
7975        switch (rd) {
7976        case 1:
7977            switch (sel) {
7978            case 1:
7979                gen_helper_mttc0_vpecontrol(cpu_env, t0);
7980                break;
7981            case 2:
7982                gen_helper_mttc0_vpeconf0(cpu_env, t0);
7983                break;
7984            default:
7985                goto die;
7986                break;
7987            }
7988            break;
7989        case 2:
7990            switch (sel) {
7991            case 1:
7992                gen_helper_mttc0_tcstatus(cpu_env, t0);
7993                break;
7994            case 2:
7995                gen_helper_mttc0_tcbind(cpu_env, t0);
7996                break;
7997            case 3:
7998                gen_helper_mttc0_tcrestart(cpu_env, t0);
7999                break;
8000            case 4:
8001                gen_helper_mttc0_tchalt(cpu_env, t0);
8002                break;
8003            case 5:
8004                gen_helper_mttc0_tccontext(cpu_env, t0);
8005                break;
8006            case 6:
8007                gen_helper_mttc0_tcschedule(cpu_env, t0);
8008                break;
8009            case 7:
8010                gen_helper_mttc0_tcschefback(cpu_env, t0);
8011                break;
8012            default:
8013                gen_mtc0(ctx, t0, rd, sel);
8014                break;
8015            }
8016            break;
8017        case 10:
8018            switch (sel) {
8019            case 0:
8020                gen_helper_mttc0_entryhi(cpu_env, t0);
8021                break;
8022            default:
8023                gen_mtc0(ctx, t0, rd, sel);
8024                break;
8025            }
8026        case 12:
8027            switch (sel) {
8028            case 0:
8029                gen_helper_mttc0_status(cpu_env, t0);
8030                break;
8031            default:
8032                gen_mtc0(ctx, t0, rd, sel);
8033                break;
8034            }
8035        case 13:
8036            switch (sel) {
8037            case 0:
8038                gen_helper_mttc0_cause(cpu_env, t0);
8039                break;
8040            default:
8041                goto die;
8042                break;
8043            }
8044            break;
8045        case 15:
8046            switch (sel) {
8047            case 1:
8048                gen_helper_mttc0_ebase(cpu_env, t0);
8049                break;
8050            default:
8051                goto die;
8052                break;
8053            }
8054            break;
8055        case 23:
8056            switch (sel) {
8057            case 0:
8058                gen_helper_mttc0_debug(cpu_env, t0);
8059                break;
8060            default:
8061                gen_mtc0(ctx, t0, rd, sel);
8062                break;
8063            }
8064            break;
8065        default:
8066            gen_mtc0(ctx, t0, rd, sel);
8067        }
8068    } else switch (sel) {
8069    /* GPR registers. */
8070    case 0:
8071        gen_helper_0e1i(mttgpr, t0, rd);
8072        break;
8073    /* Auxiliary CPU registers */
8074    case 1:
8075        switch (rd) {
8076        case 0:
8077            gen_helper_0e1i(mttlo, t0, 0);
8078            break;
8079        case 1:
8080            gen_helper_0e1i(mtthi, t0, 0);
8081            break;
8082        case 2:
8083            gen_helper_0e1i(mttacx, t0, 0);
8084            break;
8085        case 4:
8086            gen_helper_0e1i(mttlo, t0, 1);
8087            break;
8088        case 5:
8089            gen_helper_0e1i(mtthi, t0, 1);
8090            break;
8091        case 6:
8092            gen_helper_0e1i(mttacx, t0, 1);
8093            break;
8094        case 8:
8095            gen_helper_0e1i(mttlo, t0, 2);
8096            break;
8097        case 9:
8098            gen_helper_0e1i(mtthi, t0, 2);
8099            break;
8100        case 10:
8101            gen_helper_0e1i(mttacx, t0, 2);
8102            break;
8103        case 12:
8104            gen_helper_0e1i(mttlo, t0, 3);
8105            break;
8106        case 13:
8107            gen_helper_0e1i(mtthi, t0, 3);
8108            break;
8109        case 14:
8110            gen_helper_0e1i(mttacx, t0, 3);
8111            break;
8112        case 16:
8113            gen_helper_mttdsp(cpu_env, t0);
8114            break;
8115        default:
8116            goto die;
8117        }
8118        break;
8119    /* Floating point (COP1). */
8120    case 2:
8121        /* XXX: For now we support only a single FPU context. */
8122        if (h == 0) {
8123            TCGv_i32 fp0 = tcg_temp_new_i32();
8124
8125            tcg_gen_trunc_tl_i32(fp0, t0);
8126            gen_store_fpr32(ctx, fp0, rd);
8127            tcg_temp_free_i32(fp0);
8128        } else {
8129            TCGv_i32 fp0 = tcg_temp_new_i32();
8130
8131            tcg_gen_trunc_tl_i32(fp0, t0);
8132            gen_store_fpr32h(ctx, fp0, rd);
8133            tcg_temp_free_i32(fp0);
8134        }
8135        break;
8136    case 3:
8137        /* XXX: For now we support only a single FPU context. */
8138        {
8139            TCGv_i32 fs_tmp = tcg_const_i32(rd);
8140
8141            gen_helper_0e2i(ctc1, t0, fs_tmp, rt);
8142            tcg_temp_free_i32(fs_tmp);
8143        }
8144        /* Stop translation as we may have changed hflags */
8145        ctx->bstate = BS_STOP;
8146        break;
8147    /* COP2: Not implemented. */
8148    case 4:
8149    case 5:
8150        /* fall through */
8151    default:
8152        goto die;
8153    }
8154    trace_mips_translate_tr("mttr", rd, u, sel, h);
8155    tcg_temp_free(t0);
8156    return;
8157
8158die:
8159    tcg_temp_free(t0);
8160    LOG_DISAS("mttr (reg %d u %d sel %d h %d)\n", rd, u, sel, h);
8161    generate_exception_end(ctx, EXCP_RI);
8162}
8163
8164static void gen_cp0 (CPUMIPSState *env, DisasContext *ctx, uint32_t opc, int rt, int rd)
8165{
8166    const char *opn = "ldst";
8167
8168    check_cp0_enabled(ctx);
8169    switch (opc) {
8170    case OPC_MFC0:
8171        if (rt == 0) {
8172            /* Treat as NOP. */
8173            return;
8174        }
8175        gen_mfc0(ctx, cpu_gpr[rt], rd, ctx->opcode & 0x7);
8176        opn = "mfc0";
8177        break;
8178    case OPC_MTC0:
8179        {
8180            TCGv t0 = tcg_temp_new();
8181
8182            gen_load_gpr(t0, rt);
8183            gen_mtc0(ctx, t0, rd, ctx->opcode & 0x7);
8184            tcg_temp_free(t0);
8185        }
8186        opn = "mtc0";
8187        break;
8188#if defined(TARGET_MIPS64)
8189    case OPC_DMFC0:
8190        check_insn(ctx, ISA_MIPS3);
8191        if (rt == 0) {
8192            /* Treat as NOP. */
8193            return;
8194        }
8195        gen_dmfc0(ctx, cpu_gpr[rt], rd, ctx->opcode & 0x7);
8196        opn = "dmfc0";
8197        break;
8198    case OPC_DMTC0:
8199        check_insn(ctx, ISA_MIPS3);
8200        {
8201            TCGv t0 = tcg_temp_new();
8202
8203            gen_load_gpr(t0, rt);
8204            gen_dmtc0(ctx, t0, rd, ctx->opcode & 0x7);
8205            tcg_temp_free(t0);
8206        }
8207        opn = "dmtc0";
8208        break;
8209#endif
8210    case OPC_MFHC0:
8211        check_mvh(ctx);
8212        if (rt == 0) {
8213            /* Treat as NOP. */
8214            return;
8215        }
8216        gen_mfhc0(ctx, cpu_gpr[rt], rd, ctx->opcode & 0x7);
8217        opn = "mfhc0";
8218        break;
8219    case OPC_MTHC0:
8220        check_mvh(ctx);
8221        {
8222            TCGv t0 = tcg_temp_new();
8223            gen_load_gpr(t0, rt);
8224            gen_mthc0(ctx, t0, rd, ctx->opcode & 0x7);
8225            tcg_temp_free(t0);
8226        }
8227        opn = "mthc0";
8228        break;
8229    case OPC_MFTR:
8230        check_insn(ctx, ASE_MT);
8231        if (rd == 0) {
8232            /* Treat as NOP. */
8233            return;
8234        }
8235        gen_mftr(env, ctx, rt, rd, (ctx->opcode >> 5) & 1,
8236                 ctx->opcode & 0x7, (ctx->opcode >> 4) & 1);
8237        opn = "mftr";
8238        break;
8239    case OPC_MTTR:
8240        check_insn(ctx, ASE_MT);
8241        gen_mttr(env, ctx, rd, rt, (ctx->opcode >> 5) & 1,
8242                 ctx->opcode & 0x7, (ctx->opcode >> 4) & 1);
8243        opn = "mttr";
8244        break;
8245    case OPC_TLBWI:
8246        opn = "tlbwi";
8247        if (!env->tlb->helper_tlbwi)
8248            goto die;
8249        gen_helper_tlbwi(cpu_env);
8250        break;
8251    case OPC_TLBINV:
8252        opn = "tlbinv";
8253        if (ctx->ie >= 2) {
8254            if (!env->tlb->helper_tlbinv) {
8255                goto die;
8256            }
8257            gen_helper_tlbinv(cpu_env);
8258        } /* treat as nop if TLBINV not supported */
8259        break;
8260    case OPC_TLBINVF:
8261        opn = "tlbinvf";
8262        if (ctx->ie >= 2) {
8263            if (!env->tlb->helper_tlbinvf) {
8264                goto die;
8265            }
8266            gen_helper_tlbinvf(cpu_env);
8267        } /* treat as nop if TLBINV not supported */
8268        break;
8269    case OPC_TLBWR:
8270        opn = "tlbwr";
8271        if (!env->tlb->helper_tlbwr)
8272            goto die;
8273        gen_helper_tlbwr(cpu_env);
8274        break;
8275    case OPC_TLBP:
8276        opn = "tlbp";
8277        if (!env->tlb->helper_tlbp)
8278            goto die;
8279        gen_helper_tlbp(cpu_env);
8280        break;
8281    case OPC_TLBR:
8282        opn = "tlbr";
8283        if (!env->tlb->helper_tlbr)
8284            goto die;
8285        gen_helper_tlbr(cpu_env);
8286        break;
8287    case OPC_ERET: /* OPC_ERETNC */
8288        if ((ctx->insn_flags & ISA_MIPS32R6) &&
8289            (ctx->hflags & MIPS_HFLAG_BMASK)) {
8290            goto die;
8291        } else {
8292            int bit_shift = (ctx->hflags & MIPS_HFLAG_M16) ? 16 : 6;
8293            if (ctx->opcode & (1 << bit_shift)) {
8294                /* OPC_ERETNC */
8295                opn = "eretnc";
8296                check_insn(ctx, ISA_MIPS32R5);
8297                gen_helper_eretnc(cpu_env);
8298            } else {
8299                /* OPC_ERET */
8300                opn = "eret";
8301                check_insn(ctx, ISA_MIPS2);
8302                gen_helper_eret(cpu_env);
8303            }
8304            ctx->bstate = BS_EXCP;
8305        }
8306        break;
8307    case OPC_DERET:
8308        opn = "deret";
8309        check_insn(ctx, ISA_MIPS32);
8310        if ((ctx->insn_flags & ISA_MIPS32R6) &&
8311            (ctx->hflags & MIPS_HFLAG_BMASK)) {
8312            goto die;
8313        }
8314        if (!(ctx->hflags & MIPS_HFLAG_DM)) {
8315            MIPS_INVAL(opn);
8316            generate_exception_end(ctx, EXCP_RI);
8317        } else {
8318            gen_helper_deret(cpu_env);
8319            ctx->bstate = BS_EXCP;
8320        }
8321        break;
8322    case OPC_WAIT:
8323        opn = "wait";
8324        check_insn(ctx, ISA_MIPS3 | ISA_MIPS32);
8325        if ((ctx->insn_flags & ISA_MIPS32R6) &&
8326            (ctx->hflags & MIPS_HFLAG_BMASK)) {
8327            goto die;
8328        }
8329        /* If we get an exception, we want to restart at next instruction */
8330        ctx->pc += 4;
8331        save_cpu_state(ctx, 1);
8332        ctx->pc -= 4;
8333        gen_helper_wait(cpu_env);
8334        ctx->bstate = BS_EXCP;
8335        break;
8336    default:
8337 die:
8338        MIPS_INVAL(opn);
8339        generate_exception_end(ctx, EXCP_RI);
8340        return;
8341    }
8342    (void)opn; /* avoid a compiler warning */
8343}
8344#endif /* !CONFIG_USER_ONLY */
8345
8346/* CP1 Branches (before delay slot) */
8347static void gen_compute_branch1(DisasContext *ctx, uint32_t op,
8348                                int32_t cc, int32_t offset)
8349{
8350    target_ulong btarget;
8351    TCGv_i32 t0 = tcg_temp_new_i32();
8352
8353    if ((ctx->insn_flags & ISA_MIPS32R6) && (ctx->hflags & MIPS_HFLAG_BMASK)) {
8354        generate_exception_end(ctx, EXCP_RI);
8355        goto out;
8356    }
8357
8358    if (cc != 0)
8359        check_insn(ctx, ISA_MIPS4 | ISA_MIPS32);
8360
8361    btarget = ctx->pc + 4 + offset;
8362
8363    switch (op) {
8364    case OPC_BC1F:
8365        tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
8366        tcg_gen_not_i32(t0, t0);
8367        tcg_gen_andi_i32(t0, t0, 1);
8368        tcg_gen_extu_i32_tl(bcond, t0);
8369        goto not_likely;
8370    case OPC_BC1FL:
8371        tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
8372        tcg_gen_not_i32(t0, t0);
8373        tcg_gen_andi_i32(t0, t0, 1);
8374        tcg_gen_extu_i32_tl(bcond, t0);
8375        goto likely;
8376    case OPC_BC1T:
8377        tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
8378        tcg_gen_andi_i32(t0, t0, 1);
8379        tcg_gen_extu_i32_tl(bcond, t0);
8380        goto not_likely;
8381    case OPC_BC1TL:
8382        tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
8383        tcg_gen_andi_i32(t0, t0, 1);
8384        tcg_gen_extu_i32_tl(bcond, t0);
8385    likely:
8386        ctx->hflags |= MIPS_HFLAG_BL;
8387        break;
8388    case OPC_BC1FANY2:
8389        {
8390            TCGv_i32 t1 = tcg_temp_new_i32();
8391            tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
8392            tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+1));
8393            tcg_gen_nand_i32(t0, t0, t1);
8394            tcg_temp_free_i32(t1);
8395            tcg_gen_andi_i32(t0, t0, 1);
8396            tcg_gen_extu_i32_tl(bcond, t0);
8397        }
8398        goto not_likely;
8399    case OPC_BC1TANY2:
8400        {
8401            TCGv_i32 t1 = tcg_temp_new_i32();
8402            tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
8403            tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+1));
8404            tcg_gen_or_i32(t0, t0, t1);
8405            tcg_temp_free_i32(t1);
8406            tcg_gen_andi_i32(t0, t0, 1);
8407            tcg_gen_extu_i32_tl(bcond, t0);
8408        }
8409        goto not_likely;
8410    case OPC_BC1FANY4:
8411        {
8412            TCGv_i32 t1 = tcg_temp_new_i32();
8413            tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
8414            tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+1));
8415            tcg_gen_and_i32(t0, t0, t1);
8416            tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+2));
8417            tcg_gen_and_i32(t0, t0, t1);
8418            tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+3));
8419            tcg_gen_nand_i32(t0, t0, t1);
8420            tcg_temp_free_i32(t1);
8421            tcg_gen_andi_i32(t0, t0, 1);
8422            tcg_gen_extu_i32_tl(bcond, t0);
8423        }
8424        goto not_likely;
8425    case OPC_BC1TANY4:
8426        {
8427            TCGv_i32 t1 = tcg_temp_new_i32();
8428            tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
8429            tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+1));
8430            tcg_gen_or_i32(t0, t0, t1);
8431            tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+2));
8432            tcg_gen_or_i32(t0, t0, t1);
8433            tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+3));
8434            tcg_gen_or_i32(t0, t0, t1);
8435            tcg_temp_free_i32(t1);
8436            tcg_gen_andi_i32(t0, t0, 1);
8437            tcg_gen_extu_i32_tl(bcond, t0);
8438        }
8439    not_likely:
8440        ctx->hflags |= MIPS_HFLAG_BC;
8441        break;
8442    default:
8443        MIPS_INVAL("cp1 cond branch");
8444        generate_exception_end(ctx, EXCP_RI);
8445        goto out;
8446    }
8447    ctx->btarget = btarget;
8448    ctx->hflags |= MIPS_HFLAG_BDS32;
8449 out:
8450    tcg_temp_free_i32(t0);
8451}
8452
8453/* R6 CP1 Branches */
8454static void gen_compute_branch1_r6(DisasContext *ctx, uint32_t op,
8455                                   int32_t ft, int32_t offset,
8456                                   int delayslot_size)
8457{
8458    target_ulong btarget;
8459    TCGv_i64 t0 = tcg_temp_new_i64();
8460
8461    if (ctx->hflags & MIPS_HFLAG_BMASK) {
8462#ifdef MIPS_DEBUG_DISAS
8463        LOG_DISAS("Branch in delay / forbidden slot at PC 0x" TARGET_FMT_lx
8464                  "\n", ctx->pc);
8465#endif
8466        generate_exception_end(ctx, EXCP_RI);
8467        goto out;
8468    }
8469
8470    gen_load_fpr64(ctx, t0, ft);
8471    tcg_gen_andi_i64(t0, t0, 1);
8472
8473    btarget = addr_add(ctx, ctx->pc + 4, offset);
8474
8475    switch (op) {
8476    case OPC_BC1EQZ:
8477        tcg_gen_xori_i64(t0, t0, 1);
8478        ctx->hflags |= MIPS_HFLAG_BC;
8479        break;
8480    case OPC_BC1NEZ:
8481        /* t0 already set */
8482        ctx->hflags |= MIPS_HFLAG_BC;
8483        break;
8484    default:
8485        MIPS_INVAL("cp1 cond branch");
8486        generate_exception_end(ctx, EXCP_RI);
8487        goto out;
8488    }
8489
8490    tcg_gen_trunc_i64_tl(bcond, t0);
8491
8492    ctx->btarget = btarget;
8493
8494    switch (delayslot_size) {
8495    case 2:
8496        ctx->hflags |= MIPS_HFLAG_BDS16;
8497        break;
8498    case 4:
8499        ctx->hflags |= MIPS_HFLAG_BDS32;
8500        break;
8501    }
8502
8503out:
8504    tcg_temp_free_i64(t0);
8505}
8506
8507/* Coprocessor 1 (FPU) */
8508
8509#define FOP(func, fmt) (((fmt) << 21) | (func))
8510
8511enum fopcode {
8512    OPC_ADD_S = FOP(0, FMT_S),
8513    OPC_SUB_S = FOP(1, FMT_S),
8514    OPC_MUL_S = FOP(2, FMT_S),
8515    OPC_DIV_S = FOP(3, FMT_S),
8516    OPC_SQRT_S = FOP(4, FMT_S),
8517    OPC_ABS_S = FOP(5, FMT_S),
8518    OPC_MOV_S = FOP(6, FMT_S),
8519    OPC_NEG_S = FOP(7, FMT_S),
8520    OPC_ROUND_L_S = FOP(8, FMT_S),
8521    OPC_TRUNC_L_S = FOP(9, FMT_S),
8522    OPC_CEIL_L_S = FOP(10, FMT_S),
8523    OPC_FLOOR_L_S = FOP(11, FMT_S),
8524    OPC_ROUND_W_S = FOP(12, FMT_S),
8525    OPC_TRUNC_W_S = FOP(13, FMT_S),
8526    OPC_CEIL_W_S = FOP(14, FMT_S),
8527    OPC_FLOOR_W_S = FOP(15, FMT_S),
8528    OPC_SEL_S = FOP(16, FMT_S),
8529    OPC_MOVCF_S = FOP(17, FMT_S),
8530    OPC_MOVZ_S = FOP(18, FMT_S),
8531    OPC_MOVN_S = FOP(19, FMT_S),
8532    OPC_SELEQZ_S = FOP(20, FMT_S),
8533    OPC_RECIP_S = FOP(21, FMT_S),
8534    OPC_RSQRT_S = FOP(22, FMT_S),
8535    OPC_SELNEZ_S = FOP(23, FMT_S),
8536    OPC_MADDF_S = FOP(24, FMT_S),
8537    OPC_MSUBF_S = FOP(25, FMT_S),
8538    OPC_RINT_S = FOP(26, FMT_S),
8539    OPC_CLASS_S = FOP(27, FMT_S),
8540    OPC_MIN_S = FOP(28, FMT_S),
8541    OPC_RECIP2_S = FOP(28, FMT_S),
8542    OPC_MINA_S = FOP(29, FMT_S),
8543    OPC_RECIP1_S = FOP(29, FMT_S),
8544    OPC_MAX_S = FOP(30, FMT_S),
8545    OPC_RSQRT1_S = FOP(30, FMT_S),
8546    OPC_MAXA_S = FOP(31, FMT_S),
8547    OPC_RSQRT2_S = FOP(31, FMT_S),
8548    OPC_CVT_D_S = FOP(33, FMT_S),
8549    OPC_CVT_W_S = FOP(36, FMT_S),
8550    OPC_CVT_L_S = FOP(37, FMT_S),
8551    OPC_CVT_PS_S = FOP(38, FMT_S),
8552    OPC_CMP_F_S = FOP (48, FMT_S),
8553    OPC_CMP_UN_S = FOP (49, FMT_S),
8554    OPC_CMP_EQ_S = FOP (50, FMT_S),
8555    OPC_CMP_UEQ_S = FOP (51, FMT_S),
8556    OPC_CMP_OLT_S = FOP (52, FMT_S),
8557    OPC_CMP_ULT_S = FOP (53, FMT_S),
8558    OPC_CMP_OLE_S = FOP (54, FMT_S),
8559    OPC_CMP_ULE_S = FOP (55, FMT_S),
8560    OPC_CMP_SF_S = FOP (56, FMT_S),
8561    OPC_CMP_NGLE_S = FOP (57, FMT_S),
8562    OPC_CMP_SEQ_S = FOP (58, FMT_S),
8563    OPC_CMP_NGL_S = FOP (59, FMT_S),
8564    OPC_CMP_LT_S = FOP (60, FMT_S),
8565    OPC_CMP_NGE_S = FOP (61, FMT_S),
8566    OPC_CMP_LE_S = FOP (62, FMT_S),
8567    OPC_CMP_NGT_S = FOP (63, FMT_S),
8568
8569    OPC_ADD_D = FOP(0, FMT_D),
8570    OPC_SUB_D = FOP(1, FMT_D),
8571    OPC_MUL_D = FOP(2, FMT_D),
8572    OPC_DIV_D = FOP(3, FMT_D),
8573    OPC_SQRT_D = FOP(4, FMT_D),
8574    OPC_ABS_D = FOP(5, FMT_D),
8575    OPC_MOV_D = FOP(6, FMT_D),
8576    OPC_NEG_D = FOP(7, FMT_D),
8577    OPC_ROUND_L_D = FOP(8, FMT_D),
8578    OPC_TRUNC_L_D = FOP(9, FMT_D),
8579    OPC_CEIL_L_D = FOP(10, FMT_D),
8580    OPC_FLOOR_L_D = FOP(11, FMT_D),
8581    OPC_ROUND_W_D = FOP(12, FMT_D),
8582    OPC_TRUNC_W_D = FOP(13, FMT_D),
8583    OPC_CEIL_W_D = FOP(14, FMT_D),
8584    OPC_FLOOR_W_D = FOP(15, FMT_D),
8585    OPC_SEL_D = FOP(16, FMT_D),
8586    OPC_MOVCF_D = FOP(17, FMT_D),
8587    OPC_MOVZ_D = FOP(18, FMT_D),
8588    OPC_MOVN_D = FOP(19, FMT_D),
8589    OPC_SELEQZ_D = FOP(20, FMT_D),
8590    OPC_RECIP_D = FOP(21, FMT_D),
8591    OPC_RSQRT_D = FOP(22, FMT_D),
8592    OPC_SELNEZ_D = FOP(23, FMT_D),
8593    OPC_MADDF_D = FOP(24, FMT_D),
8594    OPC_MSUBF_D = FOP(25, FMT_D),
8595    OPC_RINT_D = FOP(26, FMT_D),
8596    OPC_CLASS_D = FOP(27, FMT_D),
8597    OPC_MIN_D = FOP(28, FMT_D),
8598    OPC_RECIP2_D = FOP(28, FMT_D),
8599    OPC_MINA_D = FOP(29, FMT_D),
8600    OPC_RECIP1_D = FOP(29, FMT_D),
8601    OPC_MAX_D = FOP(30, FMT_D),
8602    OPC_RSQRT1_D = FOP(30, FMT_D),
8603    OPC_MAXA_D = FOP(31, FMT_D),
8604    OPC_RSQRT2_D = FOP(31, FMT_D),
8605    OPC_CVT_S_D = FOP(32, FMT_D),
8606    OPC_CVT_W_D = FOP(36, FMT_D),
8607    OPC_CVT_L_D = FOP(37, FMT_D),
8608    OPC_CMP_F_D = FOP (48, FMT_D),
8609    OPC_CMP_UN_D = FOP (49, FMT_D),
8610    OPC_CMP_EQ_D = FOP (50, FMT_D),
8611    OPC_CMP_UEQ_D = FOP (51, FMT_D),
8612    OPC_CMP_OLT_D = FOP (52, FMT_D),
8613    OPC_CMP_ULT_D = FOP (53, FMT_D),
8614    OPC_CMP_OLE_D = FOP (54, FMT_D),
8615    OPC_CMP_ULE_D = FOP (55, FMT_D),
8616    OPC_CMP_SF_D = FOP (56, FMT_D),
8617    OPC_CMP_NGLE_D = FOP (57, FMT_D),
8618    OPC_CMP_SEQ_D = FOP (58, FMT_D),
8619    OPC_CMP_NGL_D = FOP (59, FMT_D),
8620    OPC_CMP_LT_D = FOP (60, FMT_D),
8621    OPC_CMP_NGE_D = FOP (61, FMT_D),
8622    OPC_CMP_LE_D = FOP (62, FMT_D),
8623    OPC_CMP_NGT_D = FOP (63, FMT_D),
8624
8625    OPC_CVT_S_W = FOP(32, FMT_W),
8626    OPC_CVT_D_W = FOP(33, FMT_W),
8627    OPC_CVT_S_L = FOP(32, FMT_L),
8628    OPC_CVT_D_L = FOP(33, FMT_L),
8629    OPC_CVT_PS_PW = FOP(38, FMT_W),
8630
8631    OPC_ADD_PS = FOP(0, FMT_PS),
8632    OPC_SUB_PS = FOP(1, FMT_PS),
8633    OPC_MUL_PS = FOP(2, FMT_PS),
8634    OPC_DIV_PS = FOP(3, FMT_PS),
8635    OPC_ABS_PS = FOP(5, FMT_PS),
8636    OPC_MOV_PS = FOP(6, FMT_PS),
8637    OPC_NEG_PS = FOP(7, FMT_PS),
8638    OPC_MOVCF_PS = FOP(17, FMT_PS),
8639    OPC_MOVZ_PS = FOP(18, FMT_PS),
8640    OPC_MOVN_PS = FOP(19, FMT_PS),
8641    OPC_ADDR_PS = FOP(24, FMT_PS),
8642    OPC_MULR_PS = FOP(26, FMT_PS),
8643    OPC_RECIP2_PS = FOP(28, FMT_PS),
8644    OPC_RECIP1_PS = FOP(29, FMT_PS),
8645    OPC_RSQRT1_PS = FOP(30, FMT_PS),
8646    OPC_RSQRT2_PS = FOP(31, FMT_PS),
8647
8648    OPC_CVT_S_PU = FOP(32, FMT_PS),
8649    OPC_CVT_PW_PS = FOP(36, FMT_PS),
8650    OPC_CVT_S_PL = FOP(40, FMT_PS),
8651    OPC_PLL_PS = FOP(44, FMT_PS),
8652    OPC_PLU_PS = FOP(45, FMT_PS),
8653    OPC_PUL_PS = FOP(46, FMT_PS),
8654    OPC_PUU_PS = FOP(47, FMT_PS),
8655    OPC_CMP_F_PS = FOP (48, FMT_PS),
8656    OPC_CMP_UN_PS = FOP (49, FMT_PS),
8657    OPC_CMP_EQ_PS = FOP (50, FMT_PS),
8658    OPC_CMP_UEQ_PS = FOP (51, FMT_PS),
8659    OPC_CMP_OLT_PS = FOP (52, FMT_PS),
8660    OPC_CMP_ULT_PS = FOP (53, FMT_PS),
8661    OPC_CMP_OLE_PS = FOP (54, FMT_PS),
8662    OPC_CMP_ULE_PS = FOP (55, FMT_PS),
8663    OPC_CMP_SF_PS = FOP (56, FMT_PS),
8664    OPC_CMP_NGLE_PS = FOP (57, FMT_PS),
8665    OPC_CMP_SEQ_PS = FOP (58, FMT_PS),
8666    OPC_CMP_NGL_PS = FOP (59, FMT_PS),
8667    OPC_CMP_LT_PS = FOP (60, FMT_PS),
8668    OPC_CMP_NGE_PS = FOP (61, FMT_PS),
8669    OPC_CMP_LE_PS = FOP (62, FMT_PS),
8670    OPC_CMP_NGT_PS = FOP (63, FMT_PS),
8671};
8672
8673enum r6_f_cmp_op {
8674    R6_OPC_CMP_AF_S   = FOP(0, FMT_W),
8675    R6_OPC_CMP_UN_S   = FOP(1, FMT_W),
8676    R6_OPC_CMP_EQ_S   = FOP(2, FMT_W),
8677    R6_OPC_CMP_UEQ_S  = FOP(3, FMT_W),
8678    R6_OPC_CMP_LT_S   = FOP(4, FMT_W),
8679    R6_OPC_CMP_ULT_S  = FOP(5, FMT_W),
8680    R6_OPC_CMP_LE_S   = FOP(6, FMT_W),
8681    R6_OPC_CMP_ULE_S  = FOP(7, FMT_W),
8682    R6_OPC_CMP_SAF_S  = FOP(8, FMT_W),
8683    R6_OPC_CMP_SUN_S  = FOP(9, FMT_W),
8684    R6_OPC_CMP_SEQ_S  = FOP(10, FMT_W),
8685    R6_OPC_CMP_SEUQ_S = FOP(11, FMT_W),
8686    R6_OPC_CMP_SLT_S  = FOP(12, FMT_W),
8687    R6_OPC_CMP_SULT_S = FOP(13, FMT_W),
8688    R6_OPC_CMP_SLE_S  = FOP(14, FMT_W),
8689    R6_OPC_CMP_SULE_S = FOP(15, FMT_W),
8690    R6_OPC_CMP_OR_S   = FOP(17, FMT_W),
8691    R6_OPC_CMP_UNE_S  = FOP(18, FMT_W),
8692    R6_OPC_CMP_NE_S   = FOP(19, FMT_W),
8693    R6_OPC_CMP_SOR_S  = FOP(25, FMT_W),
8694    R6_OPC_CMP_SUNE_S = FOP(26, FMT_W),
8695    R6_OPC_CMP_SNE_S  = FOP(27, FMT_W),
8696
8697    R6_OPC_CMP_AF_D   = FOP(0, FMT_L),
8698    R6_OPC_CMP_UN_D   = FOP(1, FMT_L),
8699    R6_OPC_CMP_EQ_D   = FOP(2, FMT_L),
8700    R6_OPC_CMP_UEQ_D  = FOP(3, FMT_L),
8701    R6_OPC_CMP_LT_D   = FOP(4, FMT_L),
8702    R6_OPC_CMP_ULT_D  = FOP(5, FMT_L),
8703    R6_OPC_CMP_LE_D   = FOP(6, FMT_L),
8704    R6_OPC_CMP_ULE_D  = FOP(7, FMT_L),
8705    R6_OPC_CMP_SAF_D  = FOP(8, FMT_L),
8706    R6_OPC_CMP_SUN_D  = FOP(9, FMT_L),
8707    R6_OPC_CMP_SEQ_D  = FOP(10, FMT_L),
8708    R6_OPC_CMP_SEUQ_D = FOP(11, FMT_L),
8709    R6_OPC_CMP_SLT_D  = FOP(12, FMT_L),
8710    R6_OPC_CMP_SULT_D = FOP(13, FMT_L),
8711    R6_OPC_CMP_SLE_D  = FOP(14, FMT_L),
8712    R6_OPC_CMP_SULE_D = FOP(15, FMT_L),
8713    R6_OPC_CMP_OR_D   = FOP(17, FMT_L),
8714    R6_OPC_CMP_UNE_D  = FOP(18, FMT_L),
8715    R6_OPC_CMP_NE_D   = FOP(19, FMT_L),
8716    R6_OPC_CMP_SOR_D  = FOP(25, FMT_L),
8717    R6_OPC_CMP_SUNE_D = FOP(26, FMT_L),
8718    R6_OPC_CMP_SNE_D  = FOP(27, FMT_L),
8719};
8720static void gen_cp1 (DisasContext *ctx, uint32_t opc, int rt, int fs)
8721{
8722    TCGv t0 = tcg_temp_new();
8723
8724    switch (opc) {
8725    case OPC_MFC1:
8726        {
8727            TCGv_i32 fp0 = tcg_temp_new_i32();
8728
8729            gen_load_fpr32(ctx, fp0, fs);
8730            tcg_gen_ext_i32_tl(t0, fp0);
8731            tcg_temp_free_i32(fp0);
8732        }
8733        gen_store_gpr(t0, rt);
8734        break;
8735    case OPC_MTC1:
8736        gen_load_gpr(t0, rt);
8737        {
8738            TCGv_i32 fp0 = tcg_temp_new_i32();
8739
8740            tcg_gen_trunc_tl_i32(fp0, t0);
8741            gen_store_fpr32(ctx, fp0, fs);
8742            tcg_temp_free_i32(fp0);
8743        }
8744        break;
8745    case OPC_CFC1:
8746        gen_helper_1e0i(cfc1, t0, fs);
8747        gen_store_gpr(t0, rt);
8748        break;
8749    case OPC_CTC1:
8750        gen_load_gpr(t0, rt);
8751        save_cpu_state(ctx, 0);
8752        {
8753            TCGv_i32 fs_tmp = tcg_const_i32(fs);
8754
8755            gen_helper_0e2i(ctc1, t0, fs_tmp, rt);
8756            tcg_temp_free_i32(fs_tmp);
8757        }
8758        /* Stop translation as we may have changed hflags */
8759        ctx->bstate = BS_STOP;
8760        break;
8761#if defined(TARGET_MIPS64)
8762    case OPC_DMFC1:
8763        gen_load_fpr64(ctx, t0, fs);
8764        gen_store_gpr(t0, rt);
8765        break;
8766    case OPC_DMTC1:
8767        gen_load_gpr(t0, rt);
8768        gen_store_fpr64(ctx, t0, fs);
8769        break;
8770#endif
8771    case OPC_MFHC1:
8772        {
8773            TCGv_i32 fp0 = tcg_temp_new_i32();
8774
8775            gen_load_fpr32h(ctx, fp0, fs);
8776            tcg_gen_ext_i32_tl(t0, fp0);
8777            tcg_temp_free_i32(fp0);
8778        }
8779        gen_store_gpr(t0, rt);
8780        break;
8781    case OPC_MTHC1:
8782        gen_load_gpr(t0, rt);
8783        {
8784            TCGv_i32 fp0 = tcg_temp_new_i32();
8785
8786            tcg_gen_trunc_tl_i32(fp0, t0);
8787            gen_store_fpr32h(ctx, fp0, fs);
8788            tcg_temp_free_i32(fp0);
8789        }
8790        break;
8791    default:
8792        MIPS_INVAL("cp1 move");
8793        generate_exception_end(ctx, EXCP_RI);
8794        goto out;
8795    }
8796
8797 out:
8798    tcg_temp_free(t0);
8799}
8800
8801static void gen_movci (DisasContext *ctx, int rd, int rs, int cc, int tf)
8802{
8803    TCGLabel *l1;
8804    TCGCond cond;
8805    TCGv_i32 t0;
8806
8807    if (rd == 0) {
8808        /* Treat as NOP. */
8809        return;
8810    }
8811
8812    if (tf)
8813        cond = TCG_COND_EQ;
8814    else
8815        cond = TCG_COND_NE;
8816
8817    l1 = gen_new_label();
8818    t0 = tcg_temp_new_i32();
8819    tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
8820    tcg_gen_brcondi_i32(cond, t0, 0, l1);
8821    tcg_temp_free_i32(t0);
8822    if (rs == 0) {
8823        tcg_gen_movi_tl(cpu_gpr[rd], 0);
8824    } else {
8825        tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
8826    }
8827    gen_set_label(l1);
8828}
8829
8830static inline void gen_movcf_s(DisasContext *ctx, int fs, int fd, int cc,
8831                               int tf)
8832{
8833    int cond;
8834    TCGv_i32 t0 = tcg_temp_new_i32();
8835    TCGLabel *l1 = gen_new_label();
8836
8837    if (tf)
8838        cond = TCG_COND_EQ;
8839    else
8840        cond = TCG_COND_NE;
8841
8842    tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
8843    tcg_gen_brcondi_i32(cond, t0, 0, l1);
8844    gen_load_fpr32(ctx, t0, fs);
8845    gen_store_fpr32(ctx, t0, fd);
8846    gen_set_label(l1);
8847    tcg_temp_free_i32(t0);
8848}
8849
8850static inline void gen_movcf_d (DisasContext *ctx, int fs, int fd, int cc, int tf)
8851{
8852    int cond;
8853    TCGv_i32 t0 = tcg_temp_new_i32();
8854    TCGv_i64 fp0;
8855    TCGLabel *l1 = gen_new_label();
8856
8857    if (tf)
8858        cond = TCG_COND_EQ;
8859    else
8860        cond = TCG_COND_NE;
8861
8862    tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
8863    tcg_gen_brcondi_i32(cond, t0, 0, l1);
8864    tcg_temp_free_i32(t0);
8865    fp0 = tcg_temp_new_i64();
8866    gen_load_fpr64(ctx, fp0, fs);
8867    gen_store_fpr64(ctx, fp0, fd);
8868    tcg_temp_free_i64(fp0);
8869    gen_set_label(l1);
8870}
8871
8872static inline void gen_movcf_ps(DisasContext *ctx, int fs, int fd,
8873                                int cc, int tf)
8874{
8875    int cond;
8876    TCGv_i32 t0 = tcg_temp_new_i32();
8877    TCGLabel *l1 = gen_new_label();
8878    TCGLabel *l2 = gen_new_label();
8879
8880    if (tf)
8881        cond = TCG_COND_EQ;
8882    else
8883        cond = TCG_COND_NE;
8884
8885    tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
8886    tcg_gen_brcondi_i32(cond, t0, 0, l1);
8887    gen_load_fpr32(ctx, t0, fs);
8888    gen_store_fpr32(ctx, t0, fd);
8889    gen_set_label(l1);
8890
8891    tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc+1));
8892    tcg_gen_brcondi_i32(cond, t0, 0, l2);
8893    gen_load_fpr32h(ctx, t0, fs);
8894    gen_store_fpr32h(ctx, t0, fd);
8895    tcg_temp_free_i32(t0);
8896    gen_set_label(l2);
8897}
8898
8899static void gen_sel_s(DisasContext *ctx, enum fopcode op1, int fd, int ft,
8900                      int fs)
8901{
8902    TCGv_i32 t1 = tcg_const_i32(0);
8903    TCGv_i32 fp0 = tcg_temp_new_i32();
8904    TCGv_i32 fp1 = tcg_temp_new_i32();
8905    TCGv_i32 fp2 = tcg_temp_new_i32();
8906    gen_load_fpr32(ctx, fp0, fd);
8907    gen_load_fpr32(ctx, fp1, ft);
8908    gen_load_fpr32(ctx, fp2, fs);
8909
8910    switch (op1) {
8911    case OPC_SEL_S:
8912        tcg_gen_andi_i32(fp0, fp0, 1);
8913        tcg_gen_movcond_i32(TCG_COND_NE, fp0, fp0, t1, fp1, fp2);
8914        break;
8915    case OPC_SELEQZ_S:
8916        tcg_gen_andi_i32(fp1, fp1, 1);
8917        tcg_gen_movcond_i32(TCG_COND_EQ, fp0, fp1, t1, fp2, t1);
8918        break;
8919    case OPC_SELNEZ_S:
8920        tcg_gen_andi_i32(fp1, fp1, 1);
8921        tcg_gen_movcond_i32(TCG_COND_NE, fp0, fp1, t1, fp2, t1);
8922        break;
8923    default:
8924        MIPS_INVAL("gen_sel_s");
8925        generate_exception_end(ctx, EXCP_RI);
8926        break;
8927    }
8928
8929    gen_store_fpr32(ctx, fp0, fd);
8930    tcg_temp_free_i32(fp2);
8931    tcg_temp_free_i32(fp1);
8932    tcg_temp_free_i32(fp0);
8933    tcg_temp_free_i32(t1);
8934}
8935
8936static void gen_sel_d(DisasContext *ctx, enum fopcode op1, int fd, int ft,
8937                      int fs)
8938{
8939    TCGv_i64 t1 = tcg_const_i64(0);
8940    TCGv_i64 fp0 = tcg_temp_new_i64();
8941    TCGv_i64 fp1 = tcg_temp_new_i64();
8942    TCGv_i64 fp2 = tcg_temp_new_i64();
8943    gen_load_fpr64(ctx, fp0, fd);
8944    gen_load_fpr64(ctx, fp1, ft);
8945    gen_load_fpr64(ctx, fp2, fs);
8946
8947    switch (op1) {
8948    case OPC_SEL_D:
8949        tcg_gen_andi_i64(fp0, fp0, 1);
8950        tcg_gen_movcond_i64(TCG_COND_NE, fp0, fp0, t1, fp1, fp2);
8951        break;
8952    case OPC_SELEQZ_D:
8953        tcg_gen_andi_i64(fp1, fp1, 1);
8954        tcg_gen_movcond_i64(TCG_COND_EQ, fp0, fp1, t1, fp2, t1);
8955        break;
8956    case OPC_SELNEZ_D:
8957        tcg_gen_andi_i64(fp1, fp1, 1);
8958        tcg_gen_movcond_i64(TCG_COND_NE, fp0, fp1, t1, fp2, t1);
8959        break;
8960    default:
8961        MIPS_INVAL("gen_sel_d");
8962        generate_exception_end(ctx, EXCP_RI);
8963        break;
8964    }
8965
8966    gen_store_fpr64(ctx, fp0, fd);
8967    tcg_temp_free_i64(fp2);
8968    tcg_temp_free_i64(fp1);
8969    tcg_temp_free_i64(fp0);
8970    tcg_temp_free_i64(t1);
8971}
8972
8973static void gen_farith (DisasContext *ctx, enum fopcode op1,
8974                        int ft, int fs, int fd, int cc)
8975{
8976    uint32_t func = ctx->opcode & 0x3f;
8977    switch (op1) {
8978    case OPC_ADD_S:
8979        {
8980            TCGv_i32 fp0 = tcg_temp_new_i32();
8981            TCGv_i32 fp1 = tcg_temp_new_i32();
8982
8983            gen_load_fpr32(ctx, fp0, fs);
8984            gen_load_fpr32(ctx, fp1, ft);
8985            gen_helper_float_add_s(fp0, cpu_env, fp0, fp1);
8986            tcg_temp_free_i32(fp1);
8987            gen_store_fpr32(ctx, fp0, fd);
8988            tcg_temp_free_i32(fp0);
8989        }
8990        break;
8991    case OPC_SUB_S:
8992        {
8993            TCGv_i32 fp0 = tcg_temp_new_i32();
8994            TCGv_i32 fp1 = tcg_temp_new_i32();
8995
8996            gen_load_fpr32(ctx, fp0, fs);
8997            gen_load_fpr32(ctx, fp1, ft);
8998            gen_helper_float_sub_s(fp0, cpu_env, fp0, fp1);
8999            tcg_temp_free_i32(fp1);
9000            gen_store_fpr32(ctx, fp0, fd);
9001            tcg_temp_free_i32(fp0);
9002        }
9003        break;
9004    case OPC_MUL_S:
9005        {
9006            TCGv_i32 fp0 = tcg_temp_new_i32();
9007            TCGv_i32 fp1 = tcg_temp_new_i32();
9008
9009            gen_load_fpr32(ctx, fp0, fs);
9010            gen_load_fpr32(ctx, fp1, ft);
9011            gen_helper_float_mul_s(fp0, cpu_env, fp0, fp1);
9012            tcg_temp_free_i32(fp1);
9013            gen_store_fpr32(ctx, fp0, fd);
9014            tcg_temp_free_i32(fp0);
9015        }
9016        break;
9017    case OPC_DIV_S:
9018        {
9019            TCGv_i32 fp0 = tcg_temp_new_i32();
9020            TCGv_i32 fp1 = tcg_temp_new_i32();
9021
9022            gen_load_fpr32(ctx, fp0, fs);
9023            gen_load_fpr32(ctx, fp1, ft);
9024            gen_helper_float_div_s(fp0, cpu_env, fp0, fp1);
9025            tcg_temp_free_i32(fp1);
9026            gen_store_fpr32(ctx, fp0, fd);
9027            tcg_temp_free_i32(fp0);
9028        }
9029        break;
9030    case OPC_SQRT_S:
9031        {
9032            TCGv_i32 fp0 = tcg_temp_new_i32();
9033
9034            gen_load_fpr32(ctx, fp0, fs);
9035            gen_helper_float_sqrt_s(fp0, cpu_env, fp0);
9036            gen_store_fpr32(ctx, fp0, fd);
9037            tcg_temp_free_i32(fp0);
9038        }
9039        break;
9040    case OPC_ABS_S:
9041        {
9042            TCGv_i32 fp0 = tcg_temp_new_i32();
9043
9044            gen_load_fpr32(ctx, fp0, fs);
9045            if (ctx->abs2008) {
9046                tcg_gen_andi_i32(fp0, fp0, 0x7fffffffUL);
9047            } else {
9048                gen_helper_float_abs_s(fp0, fp0);
9049            }
9050            gen_store_fpr32(ctx, fp0, fd);
9051            tcg_temp_free_i32(fp0);
9052        }
9053        break;
9054    case OPC_MOV_S:
9055        {
9056            TCGv_i32 fp0 = tcg_temp_new_i32();
9057
9058            gen_load_fpr32(ctx, fp0, fs);
9059            gen_store_fpr32(ctx, fp0, fd);
9060            tcg_temp_free_i32(fp0);
9061        }
9062        break;
9063    case OPC_NEG_S:
9064        {
9065            TCGv_i32 fp0 = tcg_temp_new_i32();
9066
9067            gen_load_fpr32(ctx, fp0, fs);
9068            if (ctx->abs2008) {
9069                tcg_gen_xori_i32(fp0, fp0, 1UL << 31);
9070            } else {
9071                gen_helper_float_chs_s(fp0, fp0);
9072            }
9073            gen_store_fpr32(ctx, fp0, fd);
9074            tcg_temp_free_i32(fp0);
9075        }
9076        break;
9077    case OPC_ROUND_L_S:
9078        check_cp1_64bitmode(ctx);
9079        {
9080            TCGv_i32 fp32 = tcg_temp_new_i32();
9081            TCGv_i64 fp64 = tcg_temp_new_i64();
9082
9083            gen_load_fpr32(ctx, fp32, fs);
9084            if (ctx->nan2008) {
9085                gen_helper_float_round_2008_l_s(fp64, cpu_env, fp32);
9086            } else {
9087                gen_helper_float_round_l_s(fp64, cpu_env, fp32);
9088            }
9089            tcg_temp_free_i32(fp32);
9090            gen_store_fpr64(ctx, fp64, fd);
9091            tcg_temp_free_i64(fp64);
9092        }
9093        break;
9094    case OPC_TRUNC_L_S:
9095        check_cp1_64bitmode(ctx);
9096        {
9097            TCGv_i32 fp32 = tcg_temp_new_i32();
9098            TCGv_i64 fp64 = tcg_temp_new_i64();
9099
9100            gen_load_fpr32(ctx, fp32, fs);
9101            if (ctx->nan2008) {
9102                gen_helper_float_trunc_2008_l_s(fp64, cpu_env, fp32);
9103            } else {
9104                gen_helper_float_trunc_l_s(fp64, cpu_env, fp32);
9105            }
9106            tcg_temp_free_i32(fp32);
9107            gen_store_fpr64(ctx, fp64, fd);
9108            tcg_temp_free_i64(fp64);
9109        }
9110        break;
9111    case OPC_CEIL_L_S:
9112        check_cp1_64bitmode(ctx);
9113        {
9114            TCGv_i32 fp32 = tcg_temp_new_i32();
9115            TCGv_i64 fp64 = tcg_temp_new_i64();
9116
9117            gen_load_fpr32(ctx, fp32, fs);
9118            if (ctx->nan2008) {
9119                gen_helper_float_ceil_2008_l_s(fp64, cpu_env, fp32);
9120            } else {
9121                gen_helper_float_ceil_l_s(fp64, cpu_env, fp32);
9122            }
9123            tcg_temp_free_i32(fp32);
9124            gen_store_fpr64(ctx, fp64, fd);
9125            tcg_temp_free_i64(fp64);
9126        }
9127        break;
9128    case OPC_FLOOR_L_S:
9129        check_cp1_64bitmode(ctx);
9130        {
9131            TCGv_i32 fp32 = tcg_temp_new_i32();
9132            TCGv_i64 fp64 = tcg_temp_new_i64();
9133
9134            gen_load_fpr32(ctx, fp32, fs);
9135            if (ctx->nan2008) {
9136                gen_helper_float_floor_2008_l_s(fp64, cpu_env, fp32);
9137            } else {
9138                gen_helper_float_floor_l_s(fp64, cpu_env, fp32);
9139            }
9140            tcg_temp_free_i32(fp32);
9141            gen_store_fpr64(ctx, fp64, fd);
9142            tcg_temp_free_i64(fp64);
9143        }
9144        break;
9145    case OPC_ROUND_W_S:
9146        {
9147            TCGv_i32 fp0 = tcg_temp_new_i32();
9148
9149            gen_load_fpr32(ctx, fp0, fs);
9150            if (ctx->nan2008) {
9151                gen_helper_float_round_2008_w_s(fp0, cpu_env, fp0);
9152            } else {
9153                gen_helper_float_round_w_s(fp0, cpu_env, fp0);
9154            }
9155            gen_store_fpr32(ctx, fp0, fd);
9156            tcg_temp_free_i32(fp0);
9157        }
9158        break;
9159    case OPC_TRUNC_W_S:
9160        {
9161            TCGv_i32 fp0 = tcg_temp_new_i32();
9162
9163            gen_load_fpr32(ctx, fp0, fs);
9164            if (ctx->nan2008) {
9165                gen_helper_float_trunc_2008_w_s(fp0, cpu_env, fp0);
9166            } else {
9167                gen_helper_float_trunc_w_s(fp0, cpu_env, fp0);
9168            }
9169            gen_store_fpr32(ctx, fp0, fd);
9170            tcg_temp_free_i32(fp0);
9171        }
9172        break;
9173    case OPC_CEIL_W_S:
9174        {
9175            TCGv_i32 fp0 = tcg_temp_new_i32();
9176
9177            gen_load_fpr32(ctx, fp0, fs);
9178            if (ctx->nan2008) {
9179                gen_helper_float_ceil_2008_w_s(fp0, cpu_env, fp0);
9180            } else {
9181                gen_helper_float_ceil_w_s(fp0, cpu_env, fp0);
9182            }
9183            gen_store_fpr32(ctx, fp0, fd);
9184            tcg_temp_free_i32(fp0);
9185        }
9186        break;
9187    case OPC_FLOOR_W_S:
9188        {
9189            TCGv_i32 fp0 = tcg_temp_new_i32();
9190
9191            gen_load_fpr32(ctx, fp0, fs);
9192            if (ctx->nan2008) {
9193                gen_helper_float_floor_2008_w_s(fp0, cpu_env, fp0);
9194            } else {
9195                gen_helper_float_floor_w_s(fp0, cpu_env, fp0);
9196            }
9197            gen_store_fpr32(ctx, fp0, fd);
9198            tcg_temp_free_i32(fp0);
9199        }
9200        break;
9201    case OPC_SEL_S:
9202        check_insn(ctx, ISA_MIPS32R6);
9203        gen_sel_s(ctx, op1, fd, ft, fs);
9204        break;
9205    case OPC_SELEQZ_S:
9206        check_insn(ctx, ISA_MIPS32R6);
9207        gen_sel_s(ctx, op1, fd, ft, fs);
9208        break;
9209    case OPC_SELNEZ_S:
9210        check_insn(ctx, ISA_MIPS32R6);
9211        gen_sel_s(ctx, op1, fd, ft, fs);
9212        break;
9213    case OPC_MOVCF_S:
9214        check_insn_opc_removed(ctx, ISA_MIPS32R6);
9215        gen_movcf_s(ctx, fs, fd, (ft >> 2) & 0x7, ft & 0x1);
9216        break;
9217    case OPC_MOVZ_S:
9218        check_insn_opc_removed(ctx, ISA_MIPS32R6);
9219        {
9220            TCGLabel *l1 = gen_new_label();
9221            TCGv_i32 fp0;
9222
9223            if (ft != 0) {
9224                tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[ft], 0, l1);
9225            }
9226            fp0 = tcg_temp_new_i32();
9227            gen_load_fpr32(ctx, fp0, fs);
9228            gen_store_fpr32(ctx, fp0, fd);
9229            tcg_temp_free_i32(fp0);
9230            gen_set_label(l1);
9231        }
9232        break;
9233    case OPC_MOVN_S:
9234        check_insn_opc_removed(ctx, ISA_MIPS32R6);
9235        {
9236            TCGLabel *l1 = gen_new_label();
9237            TCGv_i32 fp0;
9238
9239            if (ft != 0) {
9240                tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[ft], 0, l1);
9241                fp0 = tcg_temp_new_i32();
9242                gen_load_fpr32(ctx, fp0, fs);
9243                gen_store_fpr32(ctx, fp0, fd);
9244                tcg_temp_free_i32(fp0);
9245                gen_set_label(l1);
9246            }
9247        }
9248        break;
9249    case OPC_RECIP_S:
9250        {
9251            TCGv_i32 fp0 = tcg_temp_new_i32();
9252
9253            gen_load_fpr32(ctx, fp0, fs);
9254            gen_helper_float_recip_s(fp0, cpu_env, fp0);
9255            gen_store_fpr32(ctx, fp0, fd);
9256            tcg_temp_free_i32(fp0);
9257        }
9258        break;
9259    case OPC_RSQRT_S:
9260        {
9261            TCGv_i32 fp0 = tcg_temp_new_i32();
9262
9263            gen_load_fpr32(ctx, fp0, fs);
9264            gen_helper_float_rsqrt_s(fp0, cpu_env, fp0);
9265            gen_store_fpr32(ctx, fp0, fd);
9266            tcg_temp_free_i32(fp0);
9267        }
9268        break;
9269    case OPC_MADDF_S:
9270        check_insn(ctx, ISA_MIPS32R6);
9271        {
9272            TCGv_i32 fp0 = tcg_temp_new_i32();
9273            TCGv_i32 fp1 = tcg_temp_new_i32();
9274            TCGv_i32 fp2 = tcg_temp_new_i32();
9275            gen_load_fpr32(ctx, fp0, fs);
9276            gen_load_fpr32(ctx, fp1, ft);
9277            gen_load_fpr32(ctx, fp2, fd);
9278            gen_helper_float_maddf_s(fp2, cpu_env, fp0, fp1, fp2);
9279            gen_store_fpr32(ctx, fp2, fd);
9280            tcg_temp_free_i32(fp2);
9281            tcg_temp_free_i32(fp1);
9282            tcg_temp_free_i32(fp0);
9283        }
9284        break;
9285    case OPC_MSUBF_S:
9286        check_insn(ctx, ISA_MIPS32R6);
9287        {
9288            TCGv_i32 fp0 = tcg_temp_new_i32();
9289            TCGv_i32 fp1 = tcg_temp_new_i32();
9290            TCGv_i32 fp2 = tcg_temp_new_i32();
9291            gen_load_fpr32(ctx, fp0, fs);
9292            gen_load_fpr32(ctx, fp1, ft);
9293            gen_load_fpr32(ctx, fp2, fd);
9294            gen_helper_float_msubf_s(fp2, cpu_env, fp0, fp1, fp2);
9295            gen_store_fpr32(ctx, fp2, fd);
9296            tcg_temp_free_i32(fp2);
9297            tcg_temp_free_i32(fp1);
9298            tcg_temp_free_i32(fp0);
9299        }
9300        break;
9301    case OPC_RINT_S:
9302        check_insn(ctx, ISA_MIPS32R6);
9303        {
9304            TCGv_i32 fp0 = tcg_temp_new_i32();
9305            gen_load_fpr32(ctx, fp0, fs);
9306            gen_helper_float_rint_s(fp0, cpu_env, fp0);
9307            gen_store_fpr32(ctx, fp0, fd);
9308            tcg_temp_free_i32(fp0);
9309        }
9310        break;
9311    case OPC_CLASS_S:
9312        check_insn(ctx, ISA_MIPS32R6);
9313        {
9314            TCGv_i32 fp0 = tcg_temp_new_i32();
9315            gen_load_fpr32(ctx, fp0, fs);
9316            gen_helper_float_class_s(fp0, cpu_env, fp0);
9317            gen_store_fpr32(ctx, fp0, fd);
9318            tcg_temp_free_i32(fp0);
9319        }
9320        break;
9321    case OPC_MIN_S: /* OPC_RECIP2_S */
9322        if (ctx->insn_flags & ISA_MIPS32R6) {
9323            /* OPC_MIN_S */
9324            TCGv_i32 fp0 = tcg_temp_new_i32();
9325            TCGv_i32 fp1 = tcg_temp_new_i32();
9326            TCGv_i32 fp2 = tcg_temp_new_i32();
9327            gen_load_fpr32(ctx, fp0, fs);
9328            gen_load_fpr32(ctx, fp1, ft);
9329            gen_helper_float_min_s(fp2, cpu_env, fp0, fp1);
9330            gen_store_fpr32(ctx, fp2, fd);
9331            tcg_temp_free_i32(fp2);
9332            tcg_temp_free_i32(fp1);
9333            tcg_temp_free_i32(fp0);
9334        } else {
9335            /* OPC_RECIP2_S */
9336            check_cp1_64bitmode(ctx);
9337            {
9338                TCGv_i32 fp0 = tcg_temp_new_i32();
9339                TCGv_i32 fp1 = tcg_temp_new_i32();
9340
9341                gen_load_fpr32(ctx, fp0, fs);
9342                gen_load_fpr32(ctx, fp1, ft);
9343                gen_helper_float_recip2_s(fp0, cpu_env, fp0, fp1);
9344                tcg_temp_free_i32(fp1);
9345                gen_store_fpr32(ctx, fp0, fd);
9346                tcg_temp_free_i32(fp0);
9347            }
9348        }
9349        break;
9350    case OPC_MINA_S: /* OPC_RECIP1_S */
9351        if (ctx->insn_flags & ISA_MIPS32R6) {
9352            /* OPC_MINA_S */
9353            TCGv_i32 fp0 = tcg_temp_new_i32();
9354            TCGv_i32 fp1 = tcg_temp_new_i32();
9355            TCGv_i32 fp2 = tcg_temp_new_i32();
9356            gen_load_fpr32(ctx, fp0, fs);
9357            gen_load_fpr32(ctx, fp1, ft);
9358            gen_helper_float_mina_s(fp2, cpu_env, fp0, fp1);
9359            gen_store_fpr32(ctx, fp2, fd);
9360            tcg_temp_free_i32(fp2);
9361            tcg_temp_free_i32(fp1);
9362            tcg_temp_free_i32(fp0);
9363        } else {
9364            /* OPC_RECIP1_S */
9365            check_cp1_64bitmode(ctx);
9366            {
9367                TCGv_i32 fp0 = tcg_temp_new_i32();
9368
9369                gen_load_fpr32(ctx, fp0, fs);
9370                gen_helper_float_recip1_s(fp0, cpu_env, fp0);
9371                gen_store_fpr32(ctx, fp0, fd);
9372                tcg_temp_free_i32(fp0);
9373            }
9374        }
9375        break;
9376    case OPC_MAX_S: /* OPC_RSQRT1_S */
9377        if (ctx->insn_flags & ISA_MIPS32R6) {
9378            /* OPC_MAX_S */
9379            TCGv_i32 fp0 = tcg_temp_new_i32();
9380            TCGv_i32 fp1 = tcg_temp_new_i32();
9381            gen_load_fpr32(ctx, fp0, fs);
9382            gen_load_fpr32(ctx, fp1, ft);
9383            gen_helper_float_max_s(fp1, cpu_env, fp0, fp1);
9384            gen_store_fpr32(ctx, fp1, fd);
9385            tcg_temp_free_i32(fp1);
9386            tcg_temp_free_i32(fp0);
9387        } else {
9388            /* OPC_RSQRT1_S */
9389            check_cp1_64bitmode(ctx);
9390            {
9391                TCGv_i32 fp0 = tcg_temp_new_i32();
9392
9393                gen_load_fpr32(ctx, fp0, fs);
9394                gen_helper_float_rsqrt1_s(fp0, cpu_env, fp0);
9395                gen_store_fpr32(ctx, fp0, fd);
9396                tcg_temp_free_i32(fp0);
9397            }
9398        }
9399        break;
9400    case OPC_MAXA_S: /* OPC_RSQRT2_S */
9401        if (ctx->insn_flags & ISA_MIPS32R6) {
9402            /* OPC_MAXA_S */
9403            TCGv_i32 fp0 = tcg_temp_new_i32();
9404            TCGv_i32 fp1 = tcg_temp_new_i32();
9405            gen_load_fpr32(ctx, fp0, fs);
9406            gen_load_fpr32(ctx, fp1, ft);
9407            gen_helper_float_maxa_s(fp1, cpu_env, fp0, fp1);
9408            gen_store_fpr32(ctx, fp1, fd);
9409            tcg_temp_free_i32(fp1);
9410            tcg_temp_free_i32(fp0);
9411        } else {
9412            /* OPC_RSQRT2_S */
9413            check_cp1_64bitmode(ctx);
9414            {
9415                TCGv_i32 fp0 = tcg_temp_new_i32();
9416                TCGv_i32 fp1 = tcg_temp_new_i32();
9417
9418                gen_load_fpr32(ctx, fp0, fs);
9419                gen_load_fpr32(ctx, fp1, ft);
9420                gen_helper_float_rsqrt2_s(fp0, cpu_env, fp0, fp1);
9421                tcg_temp_free_i32(fp1);
9422                gen_store_fpr32(ctx, fp0, fd);
9423                tcg_temp_free_i32(fp0);
9424            }
9425        }
9426        break;
9427    case OPC_CVT_D_S:
9428        check_cp1_registers(ctx, fd);
9429        {
9430            TCGv_i32 fp32 = tcg_temp_new_i32();
9431            TCGv_i64 fp64 = tcg_temp_new_i64();
9432
9433            gen_load_fpr32(ctx, fp32, fs);
9434            gen_helper_float_cvtd_s(fp64, cpu_env, fp32);
9435            tcg_temp_free_i32(fp32);
9436            gen_store_fpr64(ctx, fp64, fd);
9437            tcg_temp_free_i64(fp64);
9438        }
9439        break;
9440    case OPC_CVT_W_S:
9441        {
9442            TCGv_i32 fp0 = tcg_temp_new_i32();
9443
9444            gen_load_fpr32(ctx, fp0, fs);
9445            if (ctx->nan2008) {
9446                gen_helper_float_cvt_2008_w_s(fp0, cpu_env, fp0);
9447            } else {
9448                gen_helper_float_cvt_w_s(fp0, cpu_env, fp0);
9449            }
9450            gen_store_fpr32(ctx, fp0, fd);
9451            tcg_temp_free_i32(fp0);
9452        }
9453        break;
9454    case OPC_CVT_L_S:
9455        check_cp1_64bitmode(ctx);
9456        {
9457            TCGv_i32 fp32 = tcg_temp_new_i32();
9458            TCGv_i64 fp64 = tcg_temp_new_i64();
9459
9460            gen_load_fpr32(ctx, fp32, fs);
9461            if (ctx->nan2008) {
9462                gen_helper_float_cvt_2008_l_s(fp64, cpu_env, fp32);
9463            } else {
9464                gen_helper_float_cvt_l_s(fp64, cpu_env, fp32);
9465            }
9466            tcg_temp_free_i32(fp32);
9467            gen_store_fpr64(ctx, fp64, fd);
9468            tcg_temp_free_i64(fp64);
9469        }
9470        break;
9471    case OPC_CVT_PS_S:
9472        check_ps(ctx);
9473        {
9474            TCGv_i64 fp64 = tcg_temp_new_i64();
9475            TCGv_i32 fp32_0 = tcg_temp_new_i32();
9476            TCGv_i32 fp32_1 = tcg_temp_new_i32();
9477
9478            gen_load_fpr32(ctx, fp32_0, fs);
9479            gen_load_fpr32(ctx, fp32_1, ft);
9480            tcg_gen_concat_i32_i64(fp64, fp32_1, fp32_0);
9481            tcg_temp_free_i32(fp32_1);
9482            tcg_temp_free_i32(fp32_0);
9483            gen_store_fpr64(ctx, fp64, fd);
9484            tcg_temp_free_i64(fp64);
9485        }
9486        break;
9487    case OPC_CMP_F_S:
9488    case OPC_CMP_UN_S:
9489    case OPC_CMP_EQ_S:
9490    case OPC_CMP_UEQ_S:
9491    case OPC_CMP_OLT_S:
9492    case OPC_CMP_ULT_S:
9493    case OPC_CMP_OLE_S:
9494    case OPC_CMP_ULE_S:
9495    case OPC_CMP_SF_S:
9496    case OPC_CMP_NGLE_S:
9497    case OPC_CMP_SEQ_S:
9498    case OPC_CMP_NGL_S:
9499    case OPC_CMP_LT_S:
9500    case OPC_CMP_NGE_S:
9501    case OPC_CMP_LE_S:
9502    case OPC_CMP_NGT_S:
9503        check_insn_opc_removed(ctx, ISA_MIPS32R6);
9504        if (ctx->opcode & (1 << 6)) {
9505            gen_cmpabs_s(ctx, func-48, ft, fs, cc);
9506        } else {
9507            gen_cmp_s(ctx, func-48, ft, fs, cc);
9508        }
9509        break;
9510    case OPC_ADD_D:
9511        check_cp1_registers(ctx, fs | ft | fd);
9512        {
9513            TCGv_i64 fp0 = tcg_temp_new_i64();
9514            TCGv_i64 fp1 = tcg_temp_new_i64();
9515
9516            gen_load_fpr64(ctx, fp0, fs);
9517            gen_load_fpr64(ctx, fp1, ft);
9518            gen_helper_float_add_d(fp0, cpu_env, fp0, fp1);
9519            tcg_temp_free_i64(fp1);
9520            gen_store_fpr64(ctx, fp0, fd);
9521            tcg_temp_free_i64(fp0);
9522        }
9523        break;
9524    case OPC_SUB_D:
9525        check_cp1_registers(ctx, fs | ft | fd);
9526        {
9527            TCGv_i64 fp0 = tcg_temp_new_i64();
9528            TCGv_i64 fp1 = tcg_temp_new_i64();
9529
9530            gen_load_fpr64(ctx, fp0, fs);
9531            gen_load_fpr64(ctx, fp1, ft);
9532            gen_helper_float_sub_d(fp0, cpu_env, fp0, fp1);
9533            tcg_temp_free_i64(fp1);
9534            gen_store_fpr64(ctx, fp0, fd);
9535            tcg_temp_free_i64(fp0);
9536        }
9537        break;
9538    case OPC_MUL_D:
9539        check_cp1_registers(ctx, fs | ft | fd);
9540        {
9541            TCGv_i64 fp0 = tcg_temp_new_i64();
9542            TCGv_i64 fp1 = tcg_temp_new_i64();
9543
9544            gen_load_fpr64(ctx, fp0, fs);
9545            gen_load_fpr64(ctx, fp1, ft);
9546            gen_helper_float_mul_d(fp0, cpu_env, fp0, fp1);
9547            tcg_temp_free_i64(fp1);
9548            gen_store_fpr64(ctx, fp0, fd);
9549            tcg_temp_free_i64(fp0);
9550        }
9551        break;
9552    case OPC_DIV_D:
9553        check_cp1_registers(ctx, fs | ft | fd);
9554        {
9555            TCGv_i64 fp0 = tcg_temp_new_i64();
9556            TCGv_i64 fp1 = tcg_temp_new_i64();
9557
9558            gen_load_fpr64(ctx, fp0, fs);
9559            gen_load_fpr64(ctx, fp1, ft);
9560            gen_helper_float_div_d(fp0, cpu_env, fp0, fp1);
9561            tcg_temp_free_i64(fp1);
9562            gen_store_fpr64(ctx, fp0, fd);
9563            tcg_temp_free_i64(fp0);
9564        }
9565        break;
9566    case OPC_SQRT_D:
9567        check_cp1_registers(ctx, fs | fd);
9568        {
9569            TCGv_i64 fp0 = tcg_temp_new_i64();
9570
9571            gen_load_fpr64(ctx, fp0, fs);
9572            gen_helper_float_sqrt_d(fp0, cpu_env, fp0);
9573            gen_store_fpr64(ctx, fp0, fd);
9574            tcg_temp_free_i64(fp0);
9575        }
9576        break;
9577    case OPC_ABS_D:
9578        check_cp1_registers(ctx, fs | fd);
9579        {
9580            TCGv_i64 fp0 = tcg_temp_new_i64();
9581
9582            gen_load_fpr64(ctx, fp0, fs);
9583            if (ctx->abs2008) {
9584                tcg_gen_andi_i64(fp0, fp0, 0x7fffffffffffffffULL);
9585            } else {
9586                gen_helper_float_abs_d(fp0, fp0);
9587            }
9588            gen_store_fpr64(ctx, fp0, fd);
9589            tcg_temp_free_i64(fp0);
9590        }
9591        break;
9592    case OPC_MOV_D:
9593        check_cp1_registers(ctx, fs | fd);
9594        {
9595            TCGv_i64 fp0 = tcg_temp_new_i64();
9596
9597            gen_load_fpr64(ctx, fp0, fs);
9598            gen_store_fpr64(ctx, fp0, fd);
9599            tcg_temp_free_i64(fp0);
9600        }
9601        break;
9602    case OPC_NEG_D:
9603        check_cp1_registers(ctx, fs | fd);
9604        {
9605            TCGv_i64 fp0 = tcg_temp_new_i64();
9606
9607            gen_load_fpr64(ctx, fp0, fs);
9608            if (ctx->abs2008) {
9609                tcg_gen_xori_i64(fp0, fp0, 1ULL << 63);
9610            } else {
9611                gen_helper_float_chs_d(fp0, fp0);
9612            }
9613            gen_store_fpr64(ctx, fp0, fd);
9614            tcg_temp_free_i64(fp0);
9615        }
9616        break;
9617    case OPC_ROUND_L_D:
9618        check_cp1_64bitmode(ctx);
9619        {
9620            TCGv_i64 fp0 = tcg_temp_new_i64();
9621
9622            gen_load_fpr64(ctx, fp0, fs);
9623            if (ctx->nan2008) {
9624                gen_helper_float_round_2008_l_d(fp0, cpu_env, fp0);
9625            } else {
9626                gen_helper_float_round_l_d(fp0, cpu_env, fp0);
9627            }
9628            gen_store_fpr64(ctx, fp0, fd);
9629            tcg_temp_free_i64(fp0);
9630        }
9631        break;
9632    case OPC_TRUNC_L_D:
9633        check_cp1_64bitmode(ctx);
9634        {
9635            TCGv_i64 fp0 = tcg_temp_new_i64();
9636
9637            gen_load_fpr64(ctx, fp0, fs);
9638            if (ctx->nan2008) {
9639                gen_helper_float_trunc_2008_l_d(fp0, cpu_env, fp0);
9640            } else {
9641                gen_helper_float_trunc_l_d(fp0, cpu_env, fp0);
9642            }
9643            gen_store_fpr64(ctx, fp0, fd);
9644            tcg_temp_free_i64(fp0);
9645        }
9646        break;
9647    case OPC_CEIL_L_D:
9648        check_cp1_64bitmode(ctx);
9649        {
9650            TCGv_i64 fp0 = tcg_temp_new_i64();
9651
9652            gen_load_fpr64(ctx, fp0, fs);
9653            if (ctx->nan2008) {
9654                gen_helper_float_ceil_2008_l_d(fp0, cpu_env, fp0);
9655            } else {
9656                gen_helper_float_ceil_l_d(fp0, cpu_env, fp0);
9657            }
9658            gen_store_fpr64(ctx, fp0, fd);
9659            tcg_temp_free_i64(fp0);
9660        }
9661        break;
9662    case OPC_FLOOR_L_D:
9663        check_cp1_64bitmode(ctx);
9664        {
9665            TCGv_i64 fp0 = tcg_temp_new_i64();
9666
9667            gen_load_fpr64(ctx, fp0, fs);
9668            if (ctx->nan2008) {
9669                gen_helper_float_floor_2008_l_d(fp0, cpu_env, fp0);
9670            } else {
9671                gen_helper_float_floor_l_d(fp0, cpu_env, fp0);
9672            }
9673            gen_store_fpr64(ctx, fp0, fd);
9674            tcg_temp_free_i64(fp0);
9675        }
9676        break;
9677    case OPC_ROUND_W_D:
9678        check_cp1_registers(ctx, fs);
9679        {
9680            TCGv_i32 fp32 = tcg_temp_new_i32();
9681            TCGv_i64 fp64 = tcg_temp_new_i64();
9682
9683            gen_load_fpr64(ctx, fp64, fs);
9684            if (ctx->nan2008) {
9685                gen_helper_float_round_2008_w_d(fp32, cpu_env, fp64);
9686            } else {
9687                gen_helper_float_round_w_d(fp32, cpu_env, fp64);
9688            }
9689            tcg_temp_free_i64(fp64);
9690            gen_store_fpr32(ctx, fp32, fd);
9691            tcg_temp_free_i32(fp32);
9692        }
9693        break;
9694    case OPC_TRUNC_W_D:
9695        check_cp1_registers(ctx, fs);
9696        {
9697            TCGv_i32 fp32 = tcg_temp_new_i32();
9698            TCGv_i64 fp64 = tcg_temp_new_i64();
9699
9700            gen_load_fpr64(ctx, fp64, fs);
9701            if (ctx->nan2008) {
9702                gen_helper_float_trunc_2008_w_d(fp32, cpu_env, fp64);
9703            } else {
9704                gen_helper_float_trunc_w_d(fp32, cpu_env, fp64);
9705            }
9706            tcg_temp_free_i64(fp64);
9707            gen_store_fpr32(ctx, fp32, fd);
9708            tcg_temp_free_i32(fp32);
9709        }
9710        break;
9711    case OPC_CEIL_W_D:
9712        check_cp1_registers(ctx, fs);
9713        {
9714            TCGv_i32 fp32 = tcg_temp_new_i32();
9715            TCGv_i64 fp64 = tcg_temp_new_i64();
9716
9717            gen_load_fpr64(ctx, fp64, fs);
9718            if (ctx->nan2008) {
9719                gen_helper_float_ceil_2008_w_d(fp32, cpu_env, fp64);
9720            } else {
9721                gen_helper_float_ceil_w_d(fp32, cpu_env, fp64);
9722            }
9723            tcg_temp_free_i64(fp64);
9724            gen_store_fpr32(ctx, fp32, fd);
9725            tcg_temp_free_i32(fp32);
9726        }
9727        break;
9728    case OPC_FLOOR_W_D:
9729        check_cp1_registers(ctx, fs);
9730        {
9731            TCGv_i32 fp32 = tcg_temp_new_i32();
9732            TCGv_i64 fp64 = tcg_temp_new_i64();
9733
9734            gen_load_fpr64(ctx, fp64, fs);
9735            if (ctx->nan2008) {
9736                gen_helper_float_floor_2008_w_d(fp32, cpu_env, fp64);
9737            } else {
9738                gen_helper_float_floor_w_d(fp32, cpu_env, fp64);
9739            }
9740            tcg_temp_free_i64(fp64);
9741            gen_store_fpr32(ctx, fp32, fd);
9742            tcg_temp_free_i32(fp32);
9743        }
9744        break;
9745    case OPC_SEL_D:
9746        check_insn(ctx, ISA_MIPS32R6);
9747        gen_sel_d(ctx, op1, fd, ft, fs);
9748        break;
9749    case OPC_SELEQZ_D:
9750        check_insn(ctx, ISA_MIPS32R6);
9751        gen_sel_d(ctx, op1, fd, ft, fs);
9752        break;
9753    case OPC_SELNEZ_D:
9754        check_insn(ctx, ISA_MIPS32R6);
9755        gen_sel_d(ctx, op1, fd, ft, fs);
9756        break;
9757    case OPC_MOVCF_D:
9758        check_insn_opc_removed(ctx, ISA_MIPS32R6);
9759        gen_movcf_d(ctx, fs, fd, (ft >> 2) & 0x7, ft & 0x1);
9760        break;
9761    case OPC_MOVZ_D:
9762        check_insn_opc_removed(ctx, ISA_MIPS32R6);
9763        {
9764            TCGLabel *l1 = gen_new_label();
9765            TCGv_i64 fp0;
9766
9767            if (ft != 0) {
9768                tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[ft], 0, l1);
9769            }
9770            fp0 = tcg_temp_new_i64();
9771            gen_load_fpr64(ctx, fp0, fs);
9772            gen_store_fpr64(ctx, fp0, fd);
9773            tcg_temp_free_i64(fp0);
9774            gen_set_label(l1);
9775        }
9776        break;
9777    case OPC_MOVN_D:
9778        check_insn_opc_removed(ctx, ISA_MIPS32R6);
9779        {
9780            TCGLabel *l1 = gen_new_label();
9781            TCGv_i64 fp0;
9782
9783            if (ft != 0) {
9784                tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[ft], 0, l1);
9785                fp0 = tcg_temp_new_i64();
9786                gen_load_fpr64(ctx, fp0, fs);
9787                gen_store_fpr64(ctx, fp0, fd);
9788                tcg_temp_free_i64(fp0);
9789                gen_set_label(l1);
9790            }
9791        }
9792        break;
9793    case OPC_RECIP_D:
9794        check_cp1_registers(ctx, fs | fd);
9795        {
9796            TCGv_i64 fp0 = tcg_temp_new_i64();
9797
9798            gen_load_fpr64(ctx, fp0, fs);
9799            gen_helper_float_recip_d(fp0, cpu_env, fp0);
9800            gen_store_fpr64(ctx, fp0, fd);
9801            tcg_temp_free_i64(fp0);
9802        }
9803        break;
9804    case OPC_RSQRT_D:
9805        check_cp1_registers(ctx, fs | fd);
9806        {
9807            TCGv_i64 fp0 = tcg_temp_new_i64();
9808
9809            gen_load_fpr64(ctx, fp0, fs);
9810            gen_helper_float_rsqrt_d(fp0, cpu_env, fp0);
9811            gen_store_fpr64(ctx, fp0, fd);
9812            tcg_temp_free_i64(fp0);
9813        }
9814        break;
9815    case OPC_MADDF_D:
9816        check_insn(ctx, ISA_MIPS32R6);
9817        {
9818            TCGv_i64 fp0 = tcg_temp_new_i64();
9819            TCGv_i64 fp1 = tcg_temp_new_i64();
9820            TCGv_i64 fp2 = tcg_temp_new_i64();
9821            gen_load_fpr64(ctx, fp0, fs);
9822            gen_load_fpr64(ctx, fp1, ft);
9823            gen_load_fpr64(ctx, fp2, fd);
9824            gen_helper_float_maddf_d(fp2, cpu_env, fp0, fp1, fp2);
9825            gen_store_fpr64(ctx, fp2, fd);
9826            tcg_temp_free_i64(fp2);
9827            tcg_temp_free_i64(fp1);
9828            tcg_temp_free_i64(fp0);
9829        }
9830        break;
9831    case OPC_MSUBF_D:
9832        check_insn(ctx, ISA_MIPS32R6);
9833        {
9834            TCGv_i64 fp0 = tcg_temp_new_i64();
9835            TCGv_i64 fp1 = tcg_temp_new_i64();
9836            TCGv_i64 fp2 = tcg_temp_new_i64();
9837            gen_load_fpr64(ctx, fp0, fs);
9838            gen_load_fpr64(ctx, fp1, ft);
9839            gen_load_fpr64(ctx, fp2, fd);
9840            gen_helper_float_msubf_d(fp2, cpu_env, fp0, fp1, fp2);
9841            gen_store_fpr64(ctx, fp2, fd);
9842            tcg_temp_free_i64(fp2);
9843            tcg_temp_free_i64(fp1);
9844            tcg_temp_free_i64(fp0);
9845        }
9846        break;
9847    case OPC_RINT_D:
9848        check_insn(ctx, ISA_MIPS32R6);
9849        {
9850            TCGv_i64 fp0 = tcg_temp_new_i64();
9851            gen_load_fpr64(ctx, fp0, fs);
9852            gen_helper_float_rint_d(fp0, cpu_env, fp0);
9853            gen_store_fpr64(ctx, fp0, fd);
9854            tcg_temp_free_i64(fp0);
9855        }
9856        break;
9857    case OPC_CLASS_D:
9858        check_insn(ctx, ISA_MIPS32R6);
9859        {
9860            TCGv_i64 fp0 = tcg_temp_new_i64();
9861            gen_load_fpr64(ctx, fp0, fs);
9862            gen_helper_float_class_d(fp0, cpu_env, fp0);
9863            gen_store_fpr64(ctx, fp0, fd);
9864            tcg_temp_free_i64(fp0);
9865        }
9866        break;
9867    case OPC_MIN_D: /* OPC_RECIP2_D */
9868        if (ctx->insn_flags & ISA_MIPS32R6) {
9869            /* OPC_MIN_D */
9870            TCGv_i64 fp0 = tcg_temp_new_i64();
9871            TCGv_i64 fp1 = tcg_temp_new_i64();
9872            gen_load_fpr64(ctx, fp0, fs);
9873            gen_load_fpr64(ctx, fp1, ft);
9874            gen_helper_float_min_d(fp1, cpu_env, fp0, fp1);
9875            gen_store_fpr64(ctx, fp1, fd);
9876            tcg_temp_free_i64(fp1);
9877            tcg_temp_free_i64(fp0);
9878        } else {
9879            /* OPC_RECIP2_D */
9880            check_cp1_64bitmode(ctx);
9881            {
9882                TCGv_i64 fp0 = tcg_temp_new_i64();
9883                TCGv_i64 fp1 = tcg_temp_new_i64();
9884
9885                gen_load_fpr64(ctx, fp0, fs);
9886                gen_load_fpr64(ctx, fp1, ft);
9887                gen_helper_float_recip2_d(fp0, cpu_env, fp0, fp1);
9888                tcg_temp_free_i64(fp1);
9889                gen_store_fpr64(ctx, fp0, fd);
9890                tcg_temp_free_i64(fp0);
9891            }
9892        }
9893        break;
9894    case OPC_MINA_D: /* OPC_RECIP1_D */
9895        if (ctx->insn_flags & ISA_MIPS32R6) {
9896            /* OPC_MINA_D */
9897            TCGv_i64 fp0 = tcg_temp_new_i64();
9898            TCGv_i64 fp1 = tcg_temp_new_i64();
9899            gen_load_fpr64(ctx, fp0, fs);
9900            gen_load_fpr64(ctx, fp1, ft);
9901            gen_helper_float_mina_d(fp1, cpu_env, fp0, fp1);
9902            gen_store_fpr64(ctx, fp1, fd);
9903            tcg_temp_free_i64(fp1);
9904            tcg_temp_free_i64(fp0);
9905        } else {
9906            /* OPC_RECIP1_D */
9907            check_cp1_64bitmode(ctx);
9908            {
9909                TCGv_i64 fp0 = tcg_temp_new_i64();
9910
9911                gen_load_fpr64(ctx, fp0, fs);
9912                gen_helper_float_recip1_d(fp0, cpu_env, fp0);
9913                gen_store_fpr64(ctx, fp0, fd);
9914                tcg_temp_free_i64(fp0);
9915            }
9916        }
9917        break;
9918    case OPC_MAX_D: /*  OPC_RSQRT1_D */
9919        if (ctx->insn_flags & ISA_MIPS32R6) {
9920            /* OPC_MAX_D */
9921            TCGv_i64 fp0 = tcg_temp_new_i64();
9922            TCGv_i64 fp1 = tcg_temp_new_i64();
9923            gen_load_fpr64(ctx, fp0, fs);
9924            gen_load_fpr64(ctx, fp1, ft);
9925            gen_helper_float_max_d(fp1, cpu_env, fp0, fp1);
9926            gen_store_fpr64(ctx, fp1, fd);
9927            tcg_temp_free_i64(fp1);
9928            tcg_temp_free_i64(fp0);
9929        } else {
9930            /* OPC_RSQRT1_D */
9931            check_cp1_64bitmode(ctx);
9932            {
9933                TCGv_i64 fp0 = tcg_temp_new_i64();
9934
9935                gen_load_fpr64(ctx, fp0, fs);
9936                gen_helper_float_rsqrt1_d(fp0, cpu_env, fp0);
9937                gen_store_fpr64(ctx, fp0, fd);
9938                tcg_temp_free_i64(fp0);
9939            }
9940        }
9941        break;
9942    case OPC_MAXA_D: /* OPC_RSQRT2_D */
9943        if (ctx->insn_flags & ISA_MIPS32R6) {
9944            /* OPC_MAXA_D */
9945            TCGv_i64 fp0 = tcg_temp_new_i64();
9946            TCGv_i64 fp1 = tcg_temp_new_i64();
9947            gen_load_fpr64(ctx, fp0, fs);
9948            gen_load_fpr64(ctx, fp1, ft);
9949            gen_helper_float_maxa_d(fp1, cpu_env, fp0, fp1);
9950            gen_store_fpr64(ctx, fp1, fd);
9951            tcg_temp_free_i64(fp1);
9952            tcg_temp_free_i64(fp0);
9953        } else {
9954            /* OPC_RSQRT2_D */
9955            check_cp1_64bitmode(ctx);
9956            {
9957                TCGv_i64 fp0 = tcg_temp_new_i64();
9958                TCGv_i64 fp1 = tcg_temp_new_i64();
9959
9960                gen_load_fpr64(ctx, fp0, fs);
9961                gen_load_fpr64(ctx, fp1, ft);
9962                gen_helper_float_rsqrt2_d(fp0, cpu_env, fp0, fp1);
9963                tcg_temp_free_i64(fp1);
9964                gen_store_fpr64(ctx, fp0, fd);
9965                tcg_temp_free_i64(fp0);
9966            }
9967        }
9968        break;
9969    case OPC_CMP_F_D:
9970    case OPC_CMP_UN_D:
9971    case OPC_CMP_EQ_D:
9972    case OPC_CMP_UEQ_D:
9973    case OPC_CMP_OLT_D:
9974    case OPC_CMP_ULT_D:
9975    case OPC_CMP_OLE_D:
9976    case OPC_CMP_ULE_D:
9977    case OPC_CMP_SF_D:
9978    case OPC_CMP_NGLE_D:
9979    case OPC_CMP_SEQ_D:
9980    case OPC_CMP_NGL_D:
9981    case OPC_CMP_LT_D:
9982    case OPC_CMP_NGE_D:
9983    case OPC_CMP_LE_D:
9984    case OPC_CMP_NGT_D:
9985        check_insn_opc_removed(ctx, ISA_MIPS32R6);
9986        if (ctx->opcode & (1 << 6)) {
9987            gen_cmpabs_d(ctx, func-48, ft, fs, cc);
9988        } else {
9989            gen_cmp_d(ctx, func-48, ft, fs, cc);
9990        }
9991        break;
9992    case OPC_CVT_S_D:
9993        check_cp1_registers(ctx, fs);
9994        {
9995            TCGv_i32 fp32 = tcg_temp_new_i32();
9996            TCGv_i64 fp64 = tcg_temp_new_i64();
9997
9998            gen_load_fpr64(ctx, fp64, fs);
9999            gen_helper_float_cvts_d(fp32, cpu_env, fp64);
10000            tcg_temp_free_i64(fp64);
10001            gen_store_fpr32(ctx, fp32, fd);
10002            tcg_temp_free_i32(fp32);
10003        }
10004        break;
10005    case OPC_CVT_W_D:
10006        check_cp1_registers(ctx, fs);
10007        {
10008            TCGv_i32 fp32 = tcg_temp_new_i32();
10009            TCGv_i64 fp64 = tcg_temp_new_i64();
10010
10011            gen_load_fpr64(ctx, fp64, fs);
10012            if (ctx->nan2008) {
10013                gen_helper_float_cvt_2008_w_d(fp32, cpu_env, fp64);
10014            } else {
10015                gen_helper_float_cvt_w_d(fp32, cpu_env, fp64);
10016            }
10017            tcg_temp_free_i64(fp64);
10018            gen_store_fpr32(ctx, fp32, fd);
10019            tcg_temp_free_i32(fp32);
10020        }
10021        break;
10022    case OPC_CVT_L_D:
10023        check_cp1_64bitmode(ctx);
10024        {
10025            TCGv_i64 fp0 = tcg_temp_new_i64();
10026
10027            gen_load_fpr64(ctx, fp0, fs);
10028            if (ctx->nan2008) {
10029                gen_helper_float_cvt_2008_l_d(fp0, cpu_env, fp0);
10030            } else {
10031                gen_helper_float_cvt_l_d(fp0, cpu_env, fp0);
10032            }
10033            gen_store_fpr64(ctx, fp0, fd);
10034            tcg_temp_free_i64(fp0);
10035        }
10036        break;
10037    case OPC_CVT_S_W:
10038        {
10039            TCGv_i32 fp0 = tcg_temp_new_i32();
10040
10041            gen_load_fpr32(ctx, fp0, fs);
10042            gen_helper_float_cvts_w(fp0, cpu_env, fp0);
10043            gen_store_fpr32(ctx, fp0, fd);
10044            tcg_temp_free_i32(fp0);
10045        }
10046        break;
10047    case OPC_CVT_D_W:
10048        check_cp1_registers(ctx, fd);
10049        {
10050            TCGv_i32 fp32 = tcg_temp_new_i32();
10051            TCGv_i64 fp64 = tcg_temp_new_i64();
10052
10053            gen_load_fpr32(ctx, fp32, fs);
10054            gen_helper_float_cvtd_w(fp64, cpu_env, fp32);
10055            tcg_temp_free_i32(fp32);
10056            gen_store_fpr64(ctx, fp64, fd);
10057            tcg_temp_free_i64(fp64);
10058        }
10059        break;
10060    case OPC_CVT_S_L:
10061        check_cp1_64bitmode(ctx);
10062        {
10063            TCGv_i32 fp32 = tcg_temp_new_i32();
10064            TCGv_i64 fp64 = tcg_temp_new_i64();
10065
10066            gen_load_fpr64(ctx, fp64, fs);
10067            gen_helper_float_cvts_l(fp32, cpu_env, fp64);
10068            tcg_temp_free_i64(fp64);
10069            gen_store_fpr32(ctx, fp32, fd);
10070            tcg_temp_free_i32(fp32);
10071        }
10072        break;
10073    case OPC_CVT_D_L:
10074        check_cp1_64bitmode(ctx);
10075        {
10076            TCGv_i64 fp0 = tcg_temp_new_i64();
10077
10078            gen_load_fpr64(ctx, fp0, fs);
10079            gen_helper_float_cvtd_l(fp0, cpu_env, fp0);
10080            gen_store_fpr64(ctx, fp0, fd);
10081            tcg_temp_free_i64(fp0);
10082        }
10083        break;
10084    case OPC_CVT_PS_PW:
10085        check_ps(ctx);
10086        {
10087            TCGv_i64 fp0 = tcg_temp_new_i64();
10088
10089            gen_load_fpr64(ctx, fp0, fs);
10090            gen_helper_float_cvtps_pw(fp0, cpu_env, fp0);
10091            gen_store_fpr64(ctx, fp0, fd);
10092            tcg_temp_free_i64(fp0);
10093        }
10094        break;
10095    case OPC_ADD_PS:
10096        check_ps(ctx);
10097        {
10098            TCGv_i64 fp0 = tcg_temp_new_i64();
10099            TCGv_i64 fp1 = tcg_temp_new_i64();
10100
10101            gen_load_fpr64(ctx, fp0, fs);
10102            gen_load_fpr64(ctx, fp1, ft);
10103            gen_helper_float_add_ps(fp0, cpu_env, fp0, fp1);
10104            tcg_temp_free_i64(fp1);
10105            gen_store_fpr64(ctx, fp0, fd);
10106            tcg_temp_free_i64(fp0);
10107        }
10108        break;
10109    case OPC_SUB_PS:
10110        check_ps(ctx);
10111        {
10112            TCGv_i64 fp0 = tcg_temp_new_i64();
10113            TCGv_i64 fp1 = tcg_temp_new_i64();
10114
10115            gen_load_fpr64(ctx, fp0, fs);
10116            gen_load_fpr64(ctx, fp1, ft);
10117            gen_helper_float_sub_ps(fp0, cpu_env, fp0, fp1);
10118            tcg_temp_free_i64(fp1);
10119            gen_store_fpr64(ctx, fp0, fd);
10120            tcg_temp_free_i64(fp0);
10121        }
10122        break;
10123    case OPC_MUL_PS:
10124        check_ps(ctx);
10125        {
10126            TCGv_i64 fp0 = tcg_temp_new_i64();
10127            TCGv_i64 fp1 = tcg_temp_new_i64();
10128
10129            gen_load_fpr64(ctx, fp0, fs);
10130            gen_load_fpr64(ctx, fp1, ft);
10131            gen_helper_float_mul_ps(fp0, cpu_env, fp0, fp1);
10132            tcg_temp_free_i64(fp1);
10133            gen_store_fpr64(ctx, fp0, fd);
10134            tcg_temp_free_i64(fp0);
10135        }
10136        break;
10137    case OPC_ABS_PS:
10138        check_ps(ctx);
10139        {
10140            TCGv_i64 fp0 = tcg_temp_new_i64();
10141
10142            gen_load_fpr64(ctx, fp0, fs);
10143            gen_helper_float_abs_ps(fp0, fp0);
10144            gen_store_fpr64(ctx, fp0, fd);
10145            tcg_temp_free_i64(fp0);
10146        }
10147        break;
10148    case OPC_MOV_PS:
10149        check_ps(ctx);
10150        {
10151            TCGv_i64 fp0 = tcg_temp_new_i64();
10152
10153            gen_load_fpr64(ctx, fp0, fs);
10154            gen_store_fpr64(ctx, fp0, fd);
10155            tcg_temp_free_i64(fp0);
10156        }
10157        break;
10158    case OPC_NEG_PS:
10159        check_ps(ctx);
10160        {
10161            TCGv_i64 fp0 = tcg_temp_new_i64();
10162
10163            gen_load_fpr64(ctx, fp0, fs);
10164            gen_helper_float_chs_ps(fp0, fp0);
10165            gen_store_fpr64(ctx, fp0, fd);
10166            tcg_temp_free_i64(fp0);
10167        }
10168        break;
10169    case OPC_MOVCF_PS:
10170        check_ps(ctx);
10171        gen_movcf_ps(ctx, fs, fd, (ft >> 2) & 0x7, ft & 0x1);
10172        break;
10173    case OPC_MOVZ_PS:
10174        check_ps(ctx);
10175        {
10176            TCGLabel *l1 = gen_new_label();
10177            TCGv_i64 fp0;
10178
10179            if (ft != 0)
10180                tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[ft], 0, l1);
10181            fp0 = tcg_temp_new_i64();
10182            gen_load_fpr64(ctx, fp0, fs);
10183            gen_store_fpr64(ctx, fp0, fd);
10184            tcg_temp_free_i64(fp0);
10185            gen_set_label(l1);
10186        }
10187        break;
10188    case OPC_MOVN_PS:
10189        check_ps(ctx);
10190        {
10191            TCGLabel *l1 = gen_new_label();
10192            TCGv_i64 fp0;
10193
10194            if (ft != 0) {
10195                tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[ft], 0, l1);
10196                fp0 = tcg_temp_new_i64();
10197                gen_load_fpr64(ctx, fp0, fs);
10198                gen_store_fpr64(ctx, fp0, fd);
10199                tcg_temp_free_i64(fp0);
10200                gen_set_label(l1);
10201            }
10202        }
10203        break;
10204    case OPC_ADDR_PS:
10205        check_ps(ctx);
10206        {
10207            TCGv_i64 fp0 = tcg_temp_new_i64();
10208            TCGv_i64 fp1 = tcg_temp_new_i64();
10209
10210            gen_load_fpr64(ctx, fp0, ft);
10211            gen_load_fpr64(ctx, fp1, fs);
10212            gen_helper_float_addr_ps(fp0, cpu_env, fp0, fp1);
10213            tcg_temp_free_i64(fp1);
10214            gen_store_fpr64(ctx, fp0, fd);
10215            tcg_temp_free_i64(fp0);
10216        }
10217        break;
10218    case OPC_MULR_PS:
10219        check_ps(ctx);
10220        {
10221            TCGv_i64 fp0 = tcg_temp_new_i64();
10222            TCGv_i64 fp1 = tcg_temp_new_i64();
10223
10224            gen_load_fpr64(ctx, fp0, ft);
10225            gen_load_fpr64(ctx, fp1, fs);
10226            gen_helper_float_mulr_ps(fp0, cpu_env, fp0, fp1);
10227            tcg_temp_free_i64(fp1);
10228            gen_store_fpr64(ctx, fp0, fd);
10229            tcg_temp_free_i64(fp0);
10230        }
10231        break;
10232    case OPC_RECIP2_PS:
10233        check_ps(ctx);
10234        {
10235            TCGv_i64 fp0 = tcg_temp_new_i64();
10236            TCGv_i64 fp1 = tcg_temp_new_i64();
10237
10238            gen_load_fpr64(ctx, fp0, fs);
10239            gen_load_fpr64(ctx, fp1, ft);
10240            gen_helper_float_recip2_ps(fp0, cpu_env, fp0, fp1);
10241            tcg_temp_free_i64(fp1);
10242            gen_store_fpr64(ctx, fp0, fd);
10243            tcg_temp_free_i64(fp0);
10244        }
10245        break;
10246    case OPC_RECIP1_PS:
10247        check_ps(ctx);
10248        {
10249            TCGv_i64 fp0 = tcg_temp_new_i64();
10250
10251            gen_load_fpr64(ctx, fp0, fs);
10252            gen_helper_float_recip1_ps(fp0, cpu_env, fp0);
10253            gen_store_fpr64(ctx, fp0, fd);
10254            tcg_temp_free_i64(fp0);
10255        }
10256        break;
10257    case OPC_RSQRT1_PS:
10258        check_ps(ctx);
10259        {
10260            TCGv_i64 fp0 = tcg_temp_new_i64();
10261
10262            gen_load_fpr64(ctx, fp0, fs);
10263            gen_helper_float_rsqrt1_ps(fp0, cpu_env, fp0);
10264            gen_store_fpr64(ctx, fp0, fd);
10265            tcg_temp_free_i64(fp0);
10266        }
10267        break;
10268    case OPC_RSQRT2_PS:
10269        check_ps(ctx);
10270        {
10271            TCGv_i64 fp0 = tcg_temp_new_i64();
10272            TCGv_i64 fp1 = tcg_temp_new_i64();
10273
10274            gen_load_fpr64(ctx, fp0, fs);
10275            gen_load_fpr64(ctx, fp1, ft);
10276            gen_helper_float_rsqrt2_ps(fp0, cpu_env, fp0, fp1);
10277            tcg_temp_free_i64(fp1);
10278            gen_store_fpr64(ctx, fp0, fd);
10279            tcg_temp_free_i64(fp0);
10280        }
10281        break;
10282    case OPC_CVT_S_PU:
10283        check_cp1_64bitmode(ctx);
10284        {
10285            TCGv_i32 fp0 = tcg_temp_new_i32();
10286
10287            gen_load_fpr32h(ctx, fp0, fs);
10288            gen_helper_float_cvts_pu(fp0, cpu_env, fp0);
10289            gen_store_fpr32(ctx, fp0, fd);
10290            tcg_temp_free_i32(fp0);
10291        }
10292        break;
10293    case OPC_CVT_PW_PS:
10294        check_ps(ctx);
10295        {
10296            TCGv_i64 fp0 = tcg_temp_new_i64();
10297
10298            gen_load_fpr64(ctx, fp0, fs);
10299            gen_helper_float_cvtpw_ps(fp0, cpu_env, fp0);
10300            gen_store_fpr64(ctx, fp0, fd);
10301            tcg_temp_free_i64(fp0);
10302        }
10303        break;
10304    case OPC_CVT_S_PL:
10305        check_cp1_64bitmode(ctx);
10306        {
10307            TCGv_i32 fp0 = tcg_temp_new_i32();
10308
10309            gen_load_fpr32(ctx, fp0, fs);
10310            gen_helper_float_cvts_pl(fp0, cpu_env, fp0);
10311            gen_store_fpr32(ctx, fp0, fd);
10312            tcg_temp_free_i32(fp0);
10313        }
10314        break;
10315    case OPC_PLL_PS:
10316        check_ps(ctx);
10317        {
10318            TCGv_i32 fp0 = tcg_temp_new_i32();
10319            TCGv_i32 fp1 = tcg_temp_new_i32();
10320
10321            gen_load_fpr32(ctx, fp0, fs);
10322            gen_load_fpr32(ctx, fp1, ft);
10323            gen_store_fpr32h(ctx, fp0, fd);
10324            gen_store_fpr32(ctx, fp1, fd);
10325            tcg_temp_free_i32(fp0);
10326            tcg_temp_free_i32(fp1);
10327        }
10328        break;
10329    case OPC_PLU_PS:
10330        check_ps(ctx);
10331        {
10332            TCGv_i32 fp0 = tcg_temp_new_i32();
10333            TCGv_i32 fp1 = tcg_temp_new_i32();
10334
10335            gen_load_fpr32(ctx, fp0, fs);
10336            gen_load_fpr32h(ctx, fp1, ft);
10337            gen_store_fpr32(ctx, fp1, fd);
10338            gen_store_fpr32h(ctx, fp0, fd);
10339            tcg_temp_free_i32(fp0);
10340            tcg_temp_free_i32(fp1);
10341        }
10342        break;
10343    case OPC_PUL_PS:
10344        check_ps(ctx);
10345        {
10346            TCGv_i32 fp0 = tcg_temp_new_i32();
10347            TCGv_i32 fp1 = tcg_temp_new_i32();
10348
10349            gen_load_fpr32h(ctx, fp0, fs);
10350            gen_load_fpr32(ctx, fp1, ft);
10351            gen_store_fpr32(ctx, fp1, fd);
10352            gen_store_fpr32h(ctx, fp0, fd);
10353            tcg_temp_free_i32(fp0);
10354            tcg_temp_free_i32(fp1);
10355        }
10356        break;
10357    case OPC_PUU_PS:
10358        check_ps(ctx);
10359        {
10360            TCGv_i32 fp0 = tcg_temp_new_i32();
10361            TCGv_i32 fp1 = tcg_temp_new_i32();
10362
10363            gen_load_fpr32h(ctx, fp0, fs);
10364            gen_load_fpr32h(ctx, fp1, ft);
10365            gen_store_fpr32(ctx, fp1, fd);
10366            gen_store_fpr32h(ctx, fp0, fd);
10367            tcg_temp_free_i32(fp0);
10368            tcg_temp_free_i32(fp1);
10369        }
10370        break;
10371    case OPC_CMP_F_PS:
10372    case OPC_CMP_UN_PS:
10373    case OPC_CMP_EQ_PS:
10374    case OPC_CMP_UEQ_PS:
10375    case OPC_CMP_OLT_PS:
10376    case OPC_CMP_ULT_PS:
10377    case OPC_CMP_OLE_PS:
10378    case OPC_CMP_ULE_PS:
10379    case OPC_CMP_SF_PS:
10380    case OPC_CMP_NGLE_PS:
10381    case OPC_CMP_SEQ_PS:
10382    case OPC_CMP_NGL_PS:
10383    case OPC_CMP_LT_PS:
10384    case OPC_CMP_NGE_PS:
10385    case OPC_CMP_LE_PS:
10386    case OPC_CMP_NGT_PS:
10387        if (ctx->opcode & (1 << 6)) {
10388            gen_cmpabs_ps(ctx, func-48, ft, fs, cc);
10389        } else {
10390            gen_cmp_ps(ctx, func-48, ft, fs, cc);
10391        }
10392        break;
10393    default:
10394        MIPS_INVAL("farith");
10395        generate_exception_end(ctx, EXCP_RI);
10396        return;
10397    }
10398}
10399
10400/* Coprocessor 3 (FPU) */
10401static void gen_flt3_ldst (DisasContext *ctx, uint32_t opc,
10402                           int fd, int fs, int base, int index)
10403{
10404    TCGv t0 = tcg_temp_new();
10405
10406    if (base == 0) {
10407        gen_load_gpr(t0, index);
10408    } else if (index == 0) {
10409        gen_load_gpr(t0, base);
10410    } else {
10411        gen_op_addr_add(ctx, t0, cpu_gpr[base], cpu_gpr[index]);
10412    }
10413    /* Don't do NOP if destination is zero: we must perform the actual
10414       memory access. */
10415    switch (opc) {
10416    case OPC_LWXC1:
10417        check_cop1x(ctx);
10418        {
10419            TCGv_i32 fp0 = tcg_temp_new_i32();
10420
10421            tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TESL);
10422            tcg_gen_trunc_tl_i32(fp0, t0);
10423            gen_store_fpr32(ctx, fp0, fd);
10424            tcg_temp_free_i32(fp0);
10425        }
10426        break;
10427    case OPC_LDXC1:
10428        check_cop1x(ctx);
10429        check_cp1_registers(ctx, fd);
10430        {
10431            TCGv_i64 fp0 = tcg_temp_new_i64();
10432            tcg_gen_qemu_ld_i64(fp0, t0, ctx->mem_idx, MO_TEQ);
10433            gen_store_fpr64(ctx, fp0, fd);
10434            tcg_temp_free_i64(fp0);
10435        }
10436        break;
10437    case OPC_LUXC1:
10438        check_cp1_64bitmode(ctx);
10439        tcg_gen_andi_tl(t0, t0, ~0x7);
10440        {
10441            TCGv_i64 fp0 = tcg_temp_new_i64();
10442
10443            tcg_gen_qemu_ld_i64(fp0, t0, ctx->mem_idx, MO_TEQ);
10444            gen_store_fpr64(ctx, fp0, fd);
10445            tcg_temp_free_i64(fp0);
10446        }
10447        break;
10448    case OPC_SWXC1:
10449        check_cop1x(ctx);
10450        {
10451            TCGv_i32 fp0 = tcg_temp_new_i32();
10452            gen_load_fpr32(ctx, fp0, fs);
10453            tcg_gen_qemu_st_i32(fp0, t0, ctx->mem_idx, MO_TEUL);
10454            tcg_temp_free_i32(fp0);
10455        }
10456        break;
10457    case OPC_SDXC1:
10458        check_cop1x(ctx);
10459        check_cp1_registers(ctx, fs);
10460        {
10461            TCGv_i64 fp0 = tcg_temp_new_i64();
10462            gen_load_fpr64(ctx, fp0, fs);
10463            tcg_gen_qemu_st_i64(fp0, t0, ctx->mem_idx, MO_TEQ);
10464            tcg_temp_free_i64(fp0);
10465        }
10466        break;
10467    case OPC_SUXC1:
10468        check_cp1_64bitmode(ctx);
10469        tcg_gen_andi_tl(t0, t0, ~0x7);
10470        {
10471            TCGv_i64 fp0 = tcg_temp_new_i64();
10472            gen_load_fpr64(ctx, fp0, fs);
10473            tcg_gen_qemu_st_i64(fp0, t0, ctx->mem_idx, MO_TEQ);
10474            tcg_temp_free_i64(fp0);
10475        }
10476        break;
10477    }
10478    tcg_temp_free(t0);
10479}
10480
10481static void gen_flt3_arith (DisasContext *ctx, uint32_t opc,
10482                            int fd, int fr, int fs, int ft)
10483{
10484    switch (opc) {
10485    case OPC_ALNV_PS:
10486        check_ps(ctx);
10487        {
10488            TCGv t0 = tcg_temp_local_new();
10489            TCGv_i32 fp = tcg_temp_new_i32();
10490            TCGv_i32 fph = tcg_temp_new_i32();
10491            TCGLabel *l1 = gen_new_label();
10492            TCGLabel *l2 = gen_new_label();
10493
10494            gen_load_gpr(t0, fr);
10495            tcg_gen_andi_tl(t0, t0, 0x7);
10496
10497            tcg_gen_brcondi_tl(TCG_COND_NE, t0, 0, l1);
10498            gen_load_fpr32(ctx, fp, fs);
10499            gen_load_fpr32h(ctx, fph, fs);
10500            gen_store_fpr32(ctx, fp, fd);
10501            gen_store_fpr32h(ctx, fph, fd);
10502            tcg_gen_br(l2);
10503            gen_set_label(l1);
10504            tcg_gen_brcondi_tl(TCG_COND_NE, t0, 4, l2);
10505            tcg_temp_free(t0);
10506#ifdef TARGET_WORDS_BIGENDIAN
10507            gen_load_fpr32(ctx, fp, fs);
10508            gen_load_fpr32h(ctx, fph, ft);
10509            gen_store_fpr32h(ctx, fp, fd);
10510            gen_store_fpr32(ctx, fph, fd);
10511#else
10512            gen_load_fpr32h(ctx, fph, fs);
10513            gen_load_fpr32(ctx, fp, ft);
10514            gen_store_fpr32(ctx, fph, fd);
10515            gen_store_fpr32h(ctx, fp, fd);
10516#endif
10517            gen_set_label(l2);
10518            tcg_temp_free_i32(fp);
10519            tcg_temp_free_i32(fph);
10520        }
10521        break;
10522    case OPC_MADD_S:
10523        check_cop1x(ctx);
10524        {
10525            TCGv_i32 fp0 = tcg_temp_new_i32();
10526            TCGv_i32 fp1 = tcg_temp_new_i32();
10527            TCGv_i32 fp2 = tcg_temp_new_i32();
10528
10529            gen_load_fpr32(ctx, fp0, fs);
10530            gen_load_fpr32(ctx, fp1, ft);
10531            gen_load_fpr32(ctx, fp2, fr);
10532            gen_helper_float_madd_s(fp2, cpu_env, fp0, fp1, fp2);
10533            tcg_temp_free_i32(fp0);
10534            tcg_temp_free_i32(fp1);
10535            gen_store_fpr32(ctx, fp2, fd);
10536            tcg_temp_free_i32(fp2);
10537        }
10538        break;
10539    case OPC_MADD_D:
10540        check_cop1x(ctx);
10541        check_cp1_registers(ctx, fd | fs | ft | fr);
10542        {
10543            TCGv_i64 fp0 = tcg_temp_new_i64();
10544            TCGv_i64 fp1 = tcg_temp_new_i64();
10545            TCGv_i64 fp2 = tcg_temp_new_i64();
10546
10547            gen_load_fpr64(ctx, fp0, fs);
10548            gen_load_fpr64(ctx, fp1, ft);
10549            gen_load_fpr64(ctx, fp2, fr);
10550            gen_helper_float_madd_d(fp2, cpu_env, fp0, fp1, fp2);
10551            tcg_temp_free_i64(fp0);
10552            tcg_temp_free_i64(fp1);
10553            gen_store_fpr64(ctx, fp2, fd);
10554            tcg_temp_free_i64(fp2);
10555        }
10556        break;
10557    case OPC_MADD_PS:
10558        check_ps(ctx);
10559        {
10560            TCGv_i64 fp0 = tcg_temp_new_i64();
10561            TCGv_i64 fp1 = tcg_temp_new_i64();
10562            TCGv_i64 fp2 = tcg_temp_new_i64();
10563
10564            gen_load_fpr64(ctx, fp0, fs);
10565            gen_load_fpr64(ctx, fp1, ft);
10566            gen_load_fpr64(ctx, fp2, fr);
10567            gen_helper_float_madd_ps(fp2, cpu_env, fp0, fp1, fp2);
10568            tcg_temp_free_i64(fp0);
10569            tcg_temp_free_i64(fp1);
10570            gen_store_fpr64(ctx, fp2, fd);
10571            tcg_temp_free_i64(fp2);
10572        }
10573        break;
10574    case OPC_MSUB_S:
10575        check_cop1x(ctx);
10576        {
10577            TCGv_i32 fp0 = tcg_temp_new_i32();
10578            TCGv_i32 fp1 = tcg_temp_new_i32();
10579            TCGv_i32 fp2 = tcg_temp_new_i32();
10580
10581            gen_load_fpr32(ctx, fp0, fs);
10582            gen_load_fpr32(ctx, fp1, ft);
10583            gen_load_fpr32(ctx, fp2, fr);
10584            gen_helper_float_msub_s(fp2, cpu_env, fp0, fp1, fp2);
10585            tcg_temp_free_i32(fp0);
10586            tcg_temp_free_i32(fp1);
10587            gen_store_fpr32(ctx, fp2, fd);
10588            tcg_temp_free_i32(fp2);
10589        }
10590        break;
10591    case OPC_MSUB_D:
10592        check_cop1x(ctx);
10593        check_cp1_registers(ctx, fd | fs | ft | fr);
10594        {
10595            TCGv_i64 fp0 = tcg_temp_new_i64();
10596            TCGv_i64 fp1 = tcg_temp_new_i64();
10597            TCGv_i64 fp2 = tcg_temp_new_i64();
10598
10599            gen_load_fpr64(ctx, fp0, fs);
10600            gen_load_fpr64(ctx, fp1, ft);
10601            gen_load_fpr64(ctx, fp2, fr);
10602            gen_helper_float_msub_d(fp2, cpu_env, fp0, fp1, fp2);
10603            tcg_temp_free_i64(fp0);
10604            tcg_temp_free_i64(fp1);
10605            gen_store_fpr64(ctx, fp2, fd);
10606            tcg_temp_free_i64(fp2);
10607        }
10608        break;
10609    case OPC_MSUB_PS:
10610        check_ps(ctx);
10611        {
10612            TCGv_i64 fp0 = tcg_temp_new_i64();
10613            TCGv_i64 fp1 = tcg_temp_new_i64();
10614            TCGv_i64 fp2 = tcg_temp_new_i64();
10615
10616            gen_load_fpr64(ctx, fp0, fs);
10617            gen_load_fpr64(ctx, fp1, ft);
10618            gen_load_fpr64(ctx, fp2, fr);
10619            gen_helper_float_msub_ps(fp2, cpu_env, fp0, fp1, fp2);
10620            tcg_temp_free_i64(fp0);
10621            tcg_temp_free_i64(fp1);
10622            gen_store_fpr64(ctx, fp2, fd);
10623            tcg_temp_free_i64(fp2);
10624        }
10625        break;
10626    case OPC_NMADD_S:
10627        check_cop1x(ctx);
10628        {
10629            TCGv_i32 fp0 = tcg_temp_new_i32();
10630            TCGv_i32 fp1 = tcg_temp_new_i32();
10631            TCGv_i32 fp2 = tcg_temp_new_i32();
10632
10633            gen_load_fpr32(ctx, fp0, fs);
10634            gen_load_fpr32(ctx, fp1, ft);
10635            gen_load_fpr32(ctx, fp2, fr);
10636            gen_helper_float_nmadd_s(fp2, cpu_env, fp0, fp1, fp2);
10637            tcg_temp_free_i32(fp0);
10638            tcg_temp_free_i32(fp1);
10639            gen_store_fpr32(ctx, fp2, fd);
10640            tcg_temp_free_i32(fp2);
10641        }
10642        break;
10643    case OPC_NMADD_D:
10644        check_cop1x(ctx);
10645        check_cp1_registers(ctx, fd | fs | ft | fr);
10646        {
10647            TCGv_i64 fp0 = tcg_temp_new_i64();
10648            TCGv_i64 fp1 = tcg_temp_new_i64();
10649            TCGv_i64 fp2 = tcg_temp_new_i64();
10650
10651            gen_load_fpr64(ctx, fp0, fs);
10652            gen_load_fpr64(ctx, fp1, ft);
10653            gen_load_fpr64(ctx, fp2, fr);
10654            gen_helper_float_nmadd_d(fp2, cpu_env, fp0, fp1, fp2);
10655            tcg_temp_free_i64(fp0);
10656            tcg_temp_free_i64(fp1);
10657            gen_store_fpr64(ctx, fp2, fd);
10658            tcg_temp_free_i64(fp2);
10659        }
10660        break;
10661    case OPC_NMADD_PS:
10662        check_ps(ctx);
10663        {
10664            TCGv_i64 fp0 = tcg_temp_new_i64();
10665            TCGv_i64 fp1 = tcg_temp_new_i64();
10666            TCGv_i64 fp2 = tcg_temp_new_i64();
10667
10668            gen_load_fpr64(ctx, fp0, fs);
10669            gen_load_fpr64(ctx, fp1, ft);
10670            gen_load_fpr64(ctx, fp2, fr);
10671            gen_helper_float_nmadd_ps(fp2, cpu_env, fp0, fp1, fp2);
10672            tcg_temp_free_i64(fp0);
10673            tcg_temp_free_i64(fp1);
10674            gen_store_fpr64(ctx, fp2, fd);
10675            tcg_temp_free_i64(fp2);
10676        }
10677        break;
10678    case OPC_NMSUB_S:
10679        check_cop1x(ctx);
10680        {
10681            TCGv_i32 fp0 = tcg_temp_new_i32();
10682            TCGv_i32 fp1 = tcg_temp_new_i32();
10683            TCGv_i32 fp2 = tcg_temp_new_i32();
10684
10685            gen_load_fpr32(ctx, fp0, fs);
10686            gen_load_fpr32(ctx, fp1, ft);
10687            gen_load_fpr32(ctx, fp2, fr);
10688            gen_helper_float_nmsub_s(fp2, cpu_env, fp0, fp1, fp2);
10689            tcg_temp_free_i32(fp0);
10690            tcg_temp_free_i32(fp1);
10691            gen_store_fpr32(ctx, fp2, fd);
10692            tcg_temp_free_i32(fp2);
10693        }
10694        break;
10695    case OPC_NMSUB_D:
10696        check_cop1x(ctx);
10697        check_cp1_registers(ctx, fd | fs | ft | fr);
10698        {
10699            TCGv_i64 fp0 = tcg_temp_new_i64();
10700            TCGv_i64 fp1 = tcg_temp_new_i64();
10701            TCGv_i64 fp2 = tcg_temp_new_i64();
10702
10703            gen_load_fpr64(ctx, fp0, fs);
10704            gen_load_fpr64(ctx, fp1, ft);
10705            gen_load_fpr64(ctx, fp2, fr);
10706            gen_helper_float_nmsub_d(fp2, cpu_env, fp0, fp1, fp2);
10707            tcg_temp_free_i64(fp0);
10708            tcg_temp_free_i64(fp1);
10709            gen_store_fpr64(ctx, fp2, fd);
10710            tcg_temp_free_i64(fp2);
10711        }
10712        break;
10713    case OPC_NMSUB_PS:
10714        check_ps(ctx);
10715        {
10716            TCGv_i64 fp0 = tcg_temp_new_i64();
10717            TCGv_i64 fp1 = tcg_temp_new_i64();
10718            TCGv_i64 fp2 = tcg_temp_new_i64();
10719
10720            gen_load_fpr64(ctx, fp0, fs);
10721            gen_load_fpr64(ctx, fp1, ft);
10722            gen_load_fpr64(ctx, fp2, fr);
10723            gen_helper_float_nmsub_ps(fp2, cpu_env, fp0, fp1, fp2);
10724            tcg_temp_free_i64(fp0);
10725            tcg_temp_free_i64(fp1);
10726            gen_store_fpr64(ctx, fp2, fd);
10727            tcg_temp_free_i64(fp2);
10728        }
10729        break;
10730    default:
10731        MIPS_INVAL("flt3_arith");
10732        generate_exception_end(ctx, EXCP_RI);
10733        return;
10734    }
10735}
10736
10737static void gen_rdhwr(DisasContext *ctx, int rt, int rd, int sel)
10738{
10739    TCGv t0;
10740
10741#if !defined(CONFIG_USER_ONLY)
10742    /* The Linux kernel will emulate rdhwr if it's not supported natively.
10743       Therefore only check the ISA in system mode.  */
10744    check_insn(ctx, ISA_MIPS32R2);
10745#endif
10746    t0 = tcg_temp_new();
10747
10748    switch (rd) {
10749    case 0:
10750        gen_helper_rdhwr_cpunum(t0, cpu_env);
10751        gen_store_gpr(t0, rt);
10752        break;
10753    case 1:
10754        gen_helper_rdhwr_synci_step(t0, cpu_env);
10755        gen_store_gpr(t0, rt);
10756        break;
10757    case 2:
10758        if (tb_cflags(ctx->tb) & CF_USE_ICOUNT) {
10759            gen_io_start();
10760        }
10761        gen_helper_rdhwr_cc(t0, cpu_env);
10762        if (tb_cflags(ctx->tb) & CF_USE_ICOUNT) {
10763            gen_io_end();
10764        }
10765        gen_store_gpr(t0, rt);
10766        /* Break the TB to be able to take timer interrupts immediately
10767           after reading count. BS_STOP isn't sufficient, we need to ensure
10768           we break completely out of translated code.  */
10769        gen_save_pc(ctx->pc + 4);
10770        ctx->bstate = BS_EXCP;
10771        break;
10772    case 3:
10773        gen_helper_rdhwr_ccres(t0, cpu_env);
10774        gen_store_gpr(t0, rt);
10775        break;
10776    case 4:
10777        check_insn(ctx, ISA_MIPS32R6);
10778        if (sel != 0) {
10779            /* Performance counter registers are not implemented other than
10780             * control register 0.
10781             */
10782            generate_exception(ctx, EXCP_RI);
10783        }
10784        gen_helper_rdhwr_performance(t0, cpu_env);
10785        gen_store_gpr(t0, rt);
10786        break;
10787    case 5:
10788        check_insn(ctx, ISA_MIPS32R6);
10789        gen_helper_rdhwr_xnp(t0, cpu_env);
10790        gen_store_gpr(t0, rt);
10791        break;
10792    case 29:
10793#if defined(CONFIG_USER_ONLY)
10794        tcg_gen_ld_tl(t0, cpu_env,
10795                      offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
10796        gen_store_gpr(t0, rt);
10797        break;
10798#else
10799        if ((ctx->hflags & MIPS_HFLAG_CP0) ||
10800            (ctx->hflags & MIPS_HFLAG_HWRENA_ULR)) {
10801            tcg_gen_ld_tl(t0, cpu_env,
10802                          offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
10803            gen_store_gpr(t0, rt);
10804        } else {
10805            generate_exception_end(ctx, EXCP_RI);
10806        }
10807        break;
10808#endif
10809    default:            /* Invalid */
10810        MIPS_INVAL("rdhwr");
10811        generate_exception_end(ctx, EXCP_RI);
10812        break;
10813    }
10814    tcg_temp_free(t0);
10815}
10816
10817static inline void clear_branch_hflags(DisasContext *ctx)
10818{
10819    ctx->hflags &= ~MIPS_HFLAG_BMASK;
10820    if (ctx->bstate == BS_NONE) {
10821        save_cpu_state(ctx, 0);
10822    } else {
10823        /* it is not safe to save ctx->hflags as hflags may be changed
10824           in execution time by the instruction in delay / forbidden slot. */
10825        tcg_gen_andi_i32(hflags, hflags, ~MIPS_HFLAG_BMASK);
10826    }
10827}
10828
10829static void gen_branch(DisasContext *ctx, int insn_bytes)
10830{
10831    if (ctx->hflags & MIPS_HFLAG_BMASK) {
10832        int proc_hflags = ctx->hflags & MIPS_HFLAG_BMASK;
10833        /* Branches completion */
10834        clear_branch_hflags(ctx);
10835        ctx->bstate = BS_BRANCH;
10836        /* FIXME: Need to clear can_do_io.  */
10837        switch (proc_hflags & MIPS_HFLAG_BMASK_BASE) {
10838        case MIPS_HFLAG_FBNSLOT:
10839            gen_goto_tb(ctx, 0, ctx->pc + insn_bytes);
10840            break;
10841        case MIPS_HFLAG_B:
10842            /* unconditional branch */
10843            if (proc_hflags & MIPS_HFLAG_BX) {
10844                tcg_gen_xori_i32(hflags, hflags, MIPS_HFLAG_M16);
10845            }
10846            gen_goto_tb(ctx, 0, ctx->btarget);
10847            break;
10848        case MIPS_HFLAG_BL:
10849            /* blikely taken case */
10850            gen_goto_tb(ctx, 0, ctx->btarget);
10851            break;
10852        case MIPS_HFLAG_BC:
10853            /* Conditional branch */
10854            {
10855                TCGLabel *l1 = gen_new_label();
10856
10857                tcg_gen_brcondi_tl(TCG_COND_NE, bcond, 0, l1);
10858                gen_goto_tb(ctx, 1, ctx->pc + insn_bytes);
10859                gen_set_label(l1);
10860                gen_goto_tb(ctx, 0, ctx->btarget);
10861            }
10862            break;
10863        case MIPS_HFLAG_BR:
10864            /* unconditional branch to register */
10865            if (ctx->insn_flags & (ASE_MIPS16 | ASE_MICROMIPS)) {
10866                TCGv t0 = tcg_temp_new();
10867                TCGv_i32 t1 = tcg_temp_new_i32();
10868
10869                tcg_gen_andi_tl(t0, btarget, 0x1);
10870                tcg_gen_trunc_tl_i32(t1, t0);
10871                tcg_temp_free(t0);
10872                tcg_gen_andi_i32(hflags, hflags, ~(uint32_t)MIPS_HFLAG_M16);
10873                tcg_gen_shli_i32(t1, t1, MIPS_HFLAG_M16_SHIFT);
10874                tcg_gen_or_i32(hflags, hflags, t1);
10875                tcg_temp_free_i32(t1);
10876
10877                tcg_gen_andi_tl(cpu_PC, btarget, ~(target_ulong)0x1);
10878            } else {
10879                tcg_gen_mov_tl(cpu_PC, btarget);
10880            }
10881            if (ctx->singlestep_enabled) {
10882                save_cpu_state(ctx, 0);
10883                gen_helper_raise_exception_debug(cpu_env);
10884            }
10885            tcg_gen_lookup_and_goto_ptr();
10886            break;
10887        default:
10888            fprintf(stderr, "unknown branch 0x%x\n", proc_hflags);
10889            abort();
10890        }
10891    }
10892}
10893
10894/* Compact Branches */
10895static void gen_compute_compact_branch(DisasContext *ctx, uint32_t opc,
10896                                       int rs, int rt, int32_t offset)
10897{
10898    int bcond_compute = 0;
10899    TCGv t0 = tcg_temp_new();
10900    TCGv t1 = tcg_temp_new();
10901    int m16_lowbit = (ctx->hflags & MIPS_HFLAG_M16) != 0;
10902
10903    if (ctx->hflags & MIPS_HFLAG_BMASK) {
10904#ifdef MIPS_DEBUG_DISAS
10905        LOG_DISAS("Branch in delay / forbidden slot at PC 0x" TARGET_FMT_lx
10906                  "\n", ctx->pc);
10907#endif
10908        generate_exception_end(ctx, EXCP_RI);
10909        goto out;
10910    }
10911
10912    /* Load needed operands and calculate btarget */
10913    switch (opc) {
10914    /* compact branch */
10915    case OPC_BOVC: /* OPC_BEQZALC, OPC_BEQC */
10916    case OPC_BNVC: /* OPC_BNEZALC, OPC_BNEC */
10917        gen_load_gpr(t0, rs);
10918        gen_load_gpr(t1, rt);
10919        bcond_compute = 1;
10920        ctx->btarget = addr_add(ctx, ctx->pc + 4, offset);
10921        if (rs <= rt && rs == 0) {
10922            /* OPC_BEQZALC, OPC_BNEZALC */
10923            tcg_gen_movi_tl(cpu_gpr[31], ctx->pc + 4 + m16_lowbit);
10924        }
10925        break;
10926    case OPC_BLEZC: /* OPC_BGEZC, OPC_BGEC */
10927    case OPC_BGTZC: /* OPC_BLTZC, OPC_BLTC */
10928        gen_load_gpr(t0, rs);
10929        gen_load_gpr(t1, rt);
10930        bcond_compute = 1;
10931        ctx->btarget = addr_add(ctx, ctx->pc + 4, offset);
10932        break;
10933    case OPC_BLEZALC: /* OPC_BGEZALC, OPC_BGEUC */
10934    case OPC_BGTZALC: /* OPC_BLTZALC, OPC_BLTUC */
10935        if (rs == 0 || rs == rt) {
10936            /* OPC_BLEZALC, OPC_BGEZALC */
10937            /* OPC_BGTZALC, OPC_BLTZALC */
10938            tcg_gen_movi_tl(cpu_gpr[31], ctx->pc + 4 + m16_lowbit);
10939        }
10940        gen_load_gpr(t0, rs);
10941        gen_load_gpr(t1, rt);
10942        bcond_compute = 1;
10943        ctx->btarget = addr_add(ctx, ctx->pc + 4, offset);
10944        break;
10945    case OPC_BC:
10946    case OPC_BALC:
10947        ctx->btarget = addr_add(ctx, ctx->pc + 4, offset);
10948        break;
10949    case OPC_BEQZC:
10950    case OPC_BNEZC:
10951        if (rs != 0) {
10952            /* OPC_BEQZC, OPC_BNEZC */
10953            gen_load_gpr(t0, rs);
10954            bcond_compute = 1;
10955            ctx->btarget = addr_add(ctx, ctx->pc + 4, offset);
10956        } else {
10957            /* OPC_JIC, OPC_JIALC */
10958            TCGv tbase = tcg_temp_new();
10959            TCGv toffset = tcg_temp_new();
10960
10961            gen_load_gpr(tbase, rt);
10962            tcg_gen_movi_tl(toffset, offset);
10963            gen_op_addr_add(ctx, btarget, tbase, toffset);
10964            tcg_temp_free(tbase);
10965            tcg_temp_free(toffset);
10966        }
10967        break;
10968    default:
10969        MIPS_INVAL("Compact branch/jump");
10970        generate_exception_end(ctx, EXCP_RI);
10971        goto out;
10972    }
10973
10974    if (bcond_compute == 0) {
10975        /* Uncoditional compact branch */
10976        switch (opc) {
10977        case OPC_JIALC:
10978            tcg_gen_movi_tl(cpu_gpr[31], ctx->pc + 4 + m16_lowbit);
10979            /* Fallthrough */
10980        case OPC_JIC:
10981            ctx->hflags |= MIPS_HFLAG_BR;
10982            break;
10983        case OPC_BALC:
10984            tcg_gen_movi_tl(cpu_gpr[31], ctx->pc + 4 + m16_lowbit);
10985            /* Fallthrough */
10986        case OPC_BC:
10987            ctx->hflags |= MIPS_HFLAG_B;
10988            break;
10989        default:
10990            MIPS_INVAL("Compact branch/jump");
10991            generate_exception_end(ctx, EXCP_RI);
10992            goto out;
10993        }
10994
10995        /* Generating branch here as compact branches don't have delay slot */
10996        gen_branch(ctx, 4);
10997    } else {
10998        /* Conditional compact branch */
10999        TCGLabel *fs = gen_new_label();
11000        save_cpu_state(ctx, 0);
11001
11002        switch (opc) {
11003        case OPC_BLEZALC: /* OPC_BGEZALC, OPC_BGEUC */
11004            if (rs == 0 && rt != 0) {
11005                /* OPC_BLEZALC */
11006                tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LE), t1, 0, fs);
11007            } else if (rs != 0 && rt != 0 && rs == rt) {
11008                /* OPC_BGEZALC */
11009                tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GE), t1, 0, fs);
11010            } else {
11011                /* OPC_BGEUC */
11012                tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_GEU), t0, t1, fs);
11013            }
11014            break;
11015        case OPC_BGTZALC: /* OPC_BLTZALC, OPC_BLTUC */
11016            if (rs == 0 && rt != 0) {
11017                /* OPC_BGTZALC */
11018                tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GT), t1, 0, fs);
11019            } else if (rs != 0 && rt != 0 && rs == rt) {
11020                /* OPC_BLTZALC */
11021                tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LT), t1, 0, fs);
11022            } else {
11023                /* OPC_BLTUC */
11024                tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_LTU), t0, t1, fs);
11025            }
11026            break;
11027        case OPC_BLEZC: /* OPC_BGEZC, OPC_BGEC */
11028            if (rs == 0 && rt != 0) {
11029                /* OPC_BLEZC */
11030                tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LE), t1, 0, fs);
11031            } else if (rs != 0 && rt != 0 && rs == rt) {
11032                /* OPC_BGEZC */
11033                tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GE), t1, 0, fs);
11034            } else {
11035                /* OPC_BGEC */
11036                tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_GE), t0, t1, fs);
11037            }
11038            break;
11039        case OPC_BGTZC: /* OPC_BLTZC, OPC_BLTC */
11040            if (rs == 0 && rt != 0) {
11041                /* OPC_BGTZC */
11042                tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GT), t1, 0, fs);
11043            } else if (rs != 0 && rt != 0 && rs == rt) {
11044                /* OPC_BLTZC */
11045                tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LT), t1, 0, fs);
11046            } else {
11047                /* OPC_BLTC */
11048                tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_LT), t0, t1, fs);
11049            }
11050            break;
11051        case OPC_BOVC: /* OPC_BEQZALC, OPC_BEQC */
11052        case OPC_BNVC: /* OPC_BNEZALC, OPC_BNEC */
11053            if (rs >= rt) {
11054                /* OPC_BOVC, OPC_BNVC */
11055                TCGv t2 = tcg_temp_new();
11056                TCGv t3 = tcg_temp_new();
11057                TCGv t4 = tcg_temp_new();
11058                TCGv input_overflow = tcg_temp_new();
11059
11060                gen_load_gpr(t0, rs);
11061                gen_load_gpr(t1, rt);
11062                tcg_gen_ext32s_tl(t2, t0);
11063                tcg_gen_setcond_tl(TCG_COND_NE, input_overflow, t2, t0);
11064                tcg_gen_ext32s_tl(t3, t1);
11065                tcg_gen_setcond_tl(TCG_COND_NE, t4, t3, t1);
11066                tcg_gen_or_tl(input_overflow, input_overflow, t4);
11067
11068                tcg_gen_add_tl(t4, t2, t3);
11069                tcg_gen_ext32s_tl(t4, t4);
11070                tcg_gen_xor_tl(t2, t2, t3);
11071                tcg_gen_xor_tl(t3, t4, t3);
11072                tcg_gen_andc_tl(t2, t3, t2);
11073                tcg_gen_setcondi_tl(TCG_COND_LT, t4, t2, 0);
11074                tcg_gen_or_tl(t4, t4, input_overflow);
11075                if (opc == OPC_BOVC) {
11076                    /* OPC_BOVC */
11077                    tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_NE), t4, 0, fs);
11078                } else {
11079                    /* OPC_BNVC */
11080                    tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_EQ), t4, 0, fs);
11081                }
11082                tcg_temp_free(input_overflow);
11083                tcg_temp_free(t4);
11084                tcg_temp_free(t3);
11085                tcg_temp_free(t2);
11086            } else if (rs < rt && rs == 0) {
11087                /* OPC_BEQZALC, OPC_BNEZALC */
11088                if (opc == OPC_BEQZALC) {
11089                    /* OPC_BEQZALC */
11090                    tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_EQ), t1, 0, fs);
11091                } else {
11092                    /* OPC_BNEZALC */
11093                    tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_NE), t1, 0, fs);
11094                }
11095            } else {
11096                /* OPC_BEQC, OPC_BNEC */
11097                if (opc == OPC_BEQC) {
11098                    /* OPC_BEQC */
11099                    tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_EQ), t0, t1, fs);
11100                } else {
11101                    /* OPC_BNEC */
11102                    tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_NE), t0, t1, fs);
11103                }
11104            }
11105            break;
11106        case OPC_BEQZC:
11107            tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_EQ), t0, 0, fs);
11108            break;
11109        case OPC_BNEZC:
11110            tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_NE), t0, 0, fs);
11111            break;
11112        default:
11113            MIPS_INVAL("Compact conditional branch/jump");
11114            generate_exception_end(ctx, EXCP_RI);
11115            goto out;
11116        }
11117
11118        /* Generating branch here as compact branches don't have delay slot */
11119        gen_goto_tb(ctx, 1, ctx->btarget);
11120        gen_set_label(fs);
11121
11122        ctx->hflags |= MIPS_HFLAG_FBNSLOT;
11123    }
11124
11125out:
11126    tcg_temp_free(t0);
11127    tcg_temp_free(t1);
11128}
11129
11130/* ISA extensions (ASEs) */
11131/* MIPS16 extension to MIPS32 */
11132
11133/* MIPS16 major opcodes */
11134enum {
11135  M16_OPC_ADDIUSP = 0x00,
11136  M16_OPC_ADDIUPC = 0x01,
11137  M16_OPC_B = 0x02,
11138  M16_OPC_JAL = 0x03,
11139  M16_OPC_BEQZ = 0x04,
11140  M16_OPC_BNEQZ = 0x05,
11141  M16_OPC_SHIFT = 0x06,
11142  M16_OPC_LD = 0x07,
11143  M16_OPC_RRIA = 0x08,
11144  M16_OPC_ADDIU8 = 0x09,
11145  M16_OPC_SLTI = 0x0a,
11146  M16_OPC_SLTIU = 0x0b,
11147  M16_OPC_I8 = 0x0c,
11148  M16_OPC_LI = 0x0d,
11149  M16_OPC_CMPI = 0x0e,
11150  M16_OPC_SD = 0x0f,
11151  M16_OPC_LB = 0x10,
11152  M16_OPC_LH = 0x11,
11153  M16_OPC_LWSP = 0x12,
11154  M16_OPC_LW = 0x13,
11155  M16_OPC_LBU = 0x14,
11156  M16_OPC_LHU = 0x15,
11157  M16_OPC_LWPC = 0x16,
11158  M16_OPC_LWU = 0x17,
11159  M16_OPC_SB = 0x18,
11160  M16_OPC_SH = 0x19,
11161  M16_OPC_SWSP = 0x1a,
11162  M16_OPC_SW = 0x1b,
11163  M16_OPC_RRR = 0x1c,
11164  M16_OPC_RR = 0x1d,
11165  M16_OPC_EXTEND = 0x1e,
11166  M16_OPC_I64 = 0x1f
11167};
11168
11169/* I8 funct field */
11170enum {
11171  I8_BTEQZ = 0x0,
11172  I8_BTNEZ = 0x1,
11173  I8_SWRASP = 0x2,
11174  I8_ADJSP = 0x3,
11175  I8_SVRS = 0x4,
11176  I8_MOV32R = 0x5,
11177  I8_MOVR32 = 0x7
11178};
11179
11180/* RRR f field */
11181enum {
11182  RRR_DADDU = 0x0,
11183  RRR_ADDU = 0x1,
11184  RRR_DSUBU = 0x2,
11185  RRR_SUBU = 0x3
11186};
11187
11188/* RR funct field */
11189enum {
11190  RR_JR = 0x00,
11191  RR_SDBBP = 0x01,
11192  RR_SLT = 0x02,
11193  RR_SLTU = 0x03,
11194  RR_SLLV = 0x04,
11195  RR_BREAK = 0x05,
11196  RR_SRLV = 0x06,
11197  RR_SRAV = 0x07,
11198  RR_DSRL = 0x08,
11199  RR_CMP = 0x0a,
11200  RR_NEG = 0x0b,
11201  RR_AND = 0x0c,
11202  RR_OR = 0x0d,
11203  RR_XOR = 0x0e,
11204  RR_NOT = 0x0f,
11205  RR_MFHI = 0x10,
11206  RR_CNVT = 0x11,
11207  RR_MFLO = 0x12,
11208  RR_DSRA = 0x13,
11209  RR_DSLLV = 0x14,
11210  RR_DSRLV = 0x16,
11211  RR_DSRAV = 0x17,
11212  RR_MULT = 0x18,
11213  RR_MULTU = 0x19,
11214  RR_DIV = 0x1a,
11215  RR_DIVU = 0x1b,
11216  RR_DMULT = 0x1c,
11217  RR_DMULTU = 0x1d,
11218  RR_DDIV = 0x1e,
11219  RR_DDIVU = 0x1f
11220};
11221
11222/* I64 funct field */
11223enum {
11224  I64_LDSP = 0x0,
11225  I64_SDSP = 0x1,
11226  I64_SDRASP = 0x2,
11227  I64_DADJSP = 0x3,
11228  I64_LDPC = 0x4,
11229  I64_DADDIU5 = 0x5,
11230  I64_DADDIUPC = 0x6,
11231  I64_DADDIUSP = 0x7
11232};
11233
11234/* RR ry field for CNVT */
11235enum {
11236  RR_RY_CNVT_ZEB = 0x0,
11237  RR_RY_CNVT_ZEH = 0x1,
11238  RR_RY_CNVT_ZEW = 0x2,
11239  RR_RY_CNVT_SEB = 0x4,
11240  RR_RY_CNVT_SEH = 0x5,
11241  RR_RY_CNVT_SEW = 0x6,
11242};
11243
11244static int xlat (int r)
11245{
11246  static int map[] = { 16, 17, 2, 3, 4, 5, 6, 7 };
11247
11248  return map[r];
11249}
11250
11251static void gen_mips16_save (DisasContext *ctx,
11252                             int xsregs, int aregs,
11253                             int do_ra, int do_s0, int do_s1,
11254                             int framesize)
11255{
11256    TCGv t0 = tcg_temp_new();
11257    TCGv t1 = tcg_temp_new();
11258    TCGv t2 = tcg_temp_new();
11259    int args, astatic;
11260
11261    switch (aregs) {
11262    case 0:
11263    case 1:
11264    case 2:
11265    case 3:
11266    case 11:
11267        args = 0;
11268        break;
11269    case 4:
11270    case 5:
11271    case 6:
11272    case 7:
11273        args = 1;
11274        break;
11275    case 8:
11276    case 9:
11277    case 10:
11278        args = 2;
11279        break;
11280    case 12:
11281    case 13:
11282        args = 3;
11283        break;
11284    case 14:
11285        args = 4;
11286        break;
11287    default:
11288        generate_exception_end(ctx, EXCP_RI);
11289        return;
11290    }
11291
11292    switch (args) {
11293    case 4:
11294        gen_base_offset_addr(ctx, t0, 29, 12);
11295        gen_load_gpr(t1, 7);
11296        tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL);
11297        /* Fall through */
11298    case 3:
11299        gen_base_offset_addr(ctx, t0, 29, 8);
11300        gen_load_gpr(t1, 6);
11301        tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL);
11302        /* Fall through */
11303    case 2:
11304        gen_base_offset_addr(ctx, t0, 29, 4);
11305        gen_load_gpr(t1, 5);
11306        tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL);
11307        /* Fall through */
11308    case 1:
11309        gen_base_offset_addr(ctx, t0, 29, 0);
11310        gen_load_gpr(t1, 4);
11311        tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL);
11312    }
11313
11314    gen_load_gpr(t0, 29);
11315
11316#define DECR_AND_STORE(reg) do {                                 \
11317        tcg_gen_movi_tl(t2, -4);                                 \
11318        gen_op_addr_add(ctx, t0, t0, t2);                        \
11319        gen_load_gpr(t1, reg);                                   \
11320        tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL); \
11321    } while (0)
11322
11323    if (do_ra) {
11324        DECR_AND_STORE(31);
11325    }
11326
11327    switch (xsregs) {
11328    case 7:
11329        DECR_AND_STORE(30);
11330        /* Fall through */
11331    case 6:
11332        DECR_AND_STORE(23);
11333        /* Fall through */
11334    case 5:
11335        DECR_AND_STORE(22);
11336        /* Fall through */
11337    case 4:
11338        DECR_AND_STORE(21);
11339        /* Fall through */
11340    case 3:
11341        DECR_AND_STORE(20);
11342        /* Fall through */
11343    case 2:
11344        DECR_AND_STORE(19);
11345        /* Fall through */
11346    case 1:
11347        DECR_AND_STORE(18);
11348    }
11349
11350    if (do_s1) {
11351        DECR_AND_STORE(17);
11352    }
11353    if (do_s0) {
11354        DECR_AND_STORE(16);
11355    }
11356
11357    switch (aregs) {
11358    case 0:
11359    case 4:
11360    case 8:
11361    case 12:
11362    case 14:
11363        astatic = 0;
11364        break;
11365    case 1:
11366    case 5:
11367    case 9:
11368    case 13:
11369        astatic = 1;
11370        break;
11371    case 2:
11372    case 6:
11373    case 10:
11374        astatic = 2;
11375        break;
11376    case 3:
11377    case 7:
11378        astatic = 3;
11379        break;
11380    case 11:
11381        astatic = 4;
11382        break;
11383    default:
11384        generate_exception_end(ctx, EXCP_RI);
11385        return;
11386    }
11387
11388    if (astatic > 0) {
11389        DECR_AND_STORE(7);
11390        if (astatic > 1) {
11391            DECR_AND_STORE(6);
11392            if (astatic > 2) {
11393                DECR_AND_STORE(5);
11394                if (astatic > 3) {
11395                    DECR_AND_STORE(4);
11396                }
11397            }
11398        }
11399    }
11400#undef DECR_AND_STORE
11401
11402    tcg_gen_movi_tl(t2, -framesize);
11403    gen_op_addr_add(ctx, cpu_gpr[29], cpu_gpr[29], t2);
11404    tcg_temp_free(t0);
11405    tcg_temp_free(t1);
11406    tcg_temp_free(t2);
11407}
11408
11409static void gen_mips16_restore (DisasContext *ctx,
11410                                int xsregs, int aregs,
11411                                int do_ra, int do_s0, int do_s1,
11412                                int framesize)
11413{
11414    int astatic;
11415    TCGv t0 = tcg_temp_new();
11416    TCGv t1 = tcg_temp_new();
11417    TCGv t2 = tcg_temp_new();
11418
11419    tcg_gen_movi_tl(t2, framesize);
11420    gen_op_addr_add(ctx, t0, cpu_gpr[29], t2);
11421
11422#define DECR_AND_LOAD(reg) do {                            \
11423        tcg_gen_movi_tl(t2, -4);                           \
11424        gen_op_addr_add(ctx, t0, t0, t2);                  \
11425        tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TESL); \
11426        gen_store_gpr(t1, reg);                            \
11427    } while (0)
11428
11429    if (do_ra) {
11430        DECR_AND_LOAD(31);
11431    }
11432
11433    switch (xsregs) {
11434    case 7:
11435        DECR_AND_LOAD(30);
11436        /* Fall through */
11437    case 6:
11438        DECR_AND_LOAD(23);
11439        /* Fall through */
11440    case 5:
11441        DECR_AND_LOAD(22);
11442        /* Fall through */
11443    case 4:
11444        DECR_AND_LOAD(21);
11445        /* Fall through */
11446    case 3:
11447        DECR_AND_LOAD(20);
11448        /* Fall through */
11449    case 2:
11450        DECR_AND_LOAD(19);
11451        /* Fall through */
11452    case 1:
11453        DECR_AND_LOAD(18);
11454    }
11455
11456    if (do_s1) {
11457        DECR_AND_LOAD(17);
11458    }
11459    if (do_s0) {
11460        DECR_AND_LOAD(16);
11461    }
11462
11463    switch (aregs) {
11464    case 0:
11465    case 4:
11466    case 8:
11467    case 12:
11468    case 14:
11469        astatic = 0;
11470        break;
11471    case 1:
11472    case 5:
11473    case 9:
11474    case 13:
11475        astatic = 1;
11476        break;
11477    case 2:
11478    case 6:
11479    case 10:
11480        astatic = 2;
11481        break;
11482    case 3:
11483    case 7:
11484        astatic = 3;
11485        break;
11486    case 11:
11487        astatic = 4;
11488        break;
11489    default:
11490        generate_exception_end(ctx, EXCP_RI);
11491        return;
11492    }
11493
11494    if (astatic > 0) {
11495        DECR_AND_LOAD(7);
11496        if (astatic > 1) {
11497            DECR_AND_LOAD(6);
11498            if (astatic > 2) {
11499                DECR_AND_LOAD(5);
11500                if (astatic > 3) {
11501                    DECR_AND_LOAD(4);
11502                }
11503            }
11504        }
11505    }
11506#undef DECR_AND_LOAD
11507
11508    tcg_gen_movi_tl(t2, framesize);
11509    gen_op_addr_add(ctx, cpu_gpr[29], cpu_gpr[29], t2);
11510    tcg_temp_free(t0);
11511    tcg_temp_free(t1);
11512    tcg_temp_free(t2);
11513}
11514
11515static void gen_addiupc (DisasContext *ctx, int rx, int imm,
11516                         int is_64_bit, int extended)
11517{
11518    TCGv t0;
11519
11520    if (extended && (ctx->hflags & MIPS_HFLAG_BMASK)) {
11521        generate_exception_end(ctx, EXCP_RI);
11522        return;
11523    }
11524
11525    t0 = tcg_temp_new();
11526
11527    tcg_gen_movi_tl(t0, pc_relative_pc(ctx));
11528    tcg_gen_addi_tl(cpu_gpr[rx], t0, imm);
11529    if (!is_64_bit) {
11530        tcg_gen_ext32s_tl(cpu_gpr[rx], cpu_gpr[rx]);
11531    }
11532
11533    tcg_temp_free(t0);
11534}
11535
11536static void gen_cache_operation(DisasContext *ctx, uint32_t op, int base,
11537                                int16_t offset)
11538{
11539    TCGv_i32 t0 = tcg_const_i32(op);
11540    TCGv t1 = tcg_temp_new();
11541    gen_base_offset_addr(ctx, t1, base, offset);
11542    gen_helper_cache(cpu_env, t1, t0);
11543}
11544
11545#if defined(TARGET_MIPS64)
11546static void decode_i64_mips16 (DisasContext *ctx,
11547                               int ry, int funct, int16_t offset,
11548                               int extended)
11549{
11550    switch (funct) {
11551    case I64_LDSP:
11552        check_insn(ctx, ISA_MIPS3);
11553        check_mips_64(ctx);
11554        offset = extended ? offset : offset << 3;
11555        gen_ld(ctx, OPC_LD, ry, 29, offset);
11556        break;
11557    case I64_SDSP:
11558        check_insn(ctx, ISA_MIPS3);
11559        check_mips_64(ctx);
11560        offset = extended ? offset : offset << 3;
11561        gen_st(ctx, OPC_SD, ry, 29, offset);
11562        break;
11563    case I64_SDRASP:
11564        check_insn(ctx, ISA_MIPS3);
11565        check_mips_64(ctx);
11566        offset = extended ? offset : (ctx->opcode & 0xff) << 3;
11567        gen_st(ctx, OPC_SD, 31, 29, offset);
11568        break;
11569    case I64_DADJSP:
11570        check_insn(ctx, ISA_MIPS3);
11571        check_mips_64(ctx);
11572        offset = extended ? offset : ((int8_t)ctx->opcode) << 3;
11573        gen_arith_imm(ctx, OPC_DADDIU, 29, 29, offset);
11574        break;
11575    case I64_LDPC:
11576        check_insn(ctx, ISA_MIPS3);
11577        check_mips_64(ctx);
11578        if (extended && (ctx->hflags & MIPS_HFLAG_BMASK)) {
11579            generate_exception_end(ctx, EXCP_RI);
11580        } else {
11581            offset = extended ? offset : offset << 3;
11582            gen_ld(ctx, OPC_LDPC, ry, 0, offset);
11583        }
11584        break;
11585    case I64_DADDIU5:
11586        check_insn(ctx, ISA_MIPS3);
11587        check_mips_64(ctx);
11588        offset = extended ? offset : ((int8_t)(offset << 3)) >> 3;
11589        gen_arith_imm(ctx, OPC_DADDIU, ry, ry, offset);
11590        break;
11591    case I64_DADDIUPC:
11592        check_insn(ctx, ISA_MIPS3);
11593        check_mips_64(ctx);
11594        offset = extended ? offset : offset << 2;
11595        gen_addiupc(ctx, ry, offset, 1, extended);
11596        break;
11597    case I64_DADDIUSP:
11598        check_insn(ctx, ISA_MIPS3);
11599        check_mips_64(ctx);
11600        offset = extended ? offset : offset << 2;
11601        gen_arith_imm(ctx, OPC_DADDIU, ry, 29, offset);
11602        break;
11603    }
11604}
11605#endif
11606
11607static int decode_extended_mips16_opc (CPUMIPSState *env, DisasContext *ctx)
11608{
11609    int extend = cpu_lduw_code(env, ctx->pc + 2);
11610    int op, rx, ry, funct, sa;
11611    int16_t imm, offset;
11612
11613    ctx->opcode = (ctx->opcode << 16) | extend;
11614    op = (ctx->opcode >> 11) & 0x1f;
11615    sa = (ctx->opcode >> 22) & 0x1f;
11616    funct = (ctx->opcode >> 8) & 0x7;
11617    rx = xlat((ctx->opcode >> 8) & 0x7);
11618    ry = xlat((ctx->opcode >> 5) & 0x7);
11619    offset = imm = (int16_t) (((ctx->opcode >> 16) & 0x1f) << 11
11620                              | ((ctx->opcode >> 21) & 0x3f) << 5
11621                              | (ctx->opcode & 0x1f));
11622
11623    /* The extended opcodes cleverly reuse the opcodes from their 16-bit
11624       counterparts.  */
11625    switch (op) {
11626    case M16_OPC_ADDIUSP:
11627        gen_arith_imm(ctx, OPC_ADDIU, rx, 29, imm);
11628        break;
11629    case M16_OPC_ADDIUPC:
11630        gen_addiupc(ctx, rx, imm, 0, 1);
11631        break;
11632    case M16_OPC_B:
11633        gen_compute_branch(ctx, OPC_BEQ, 4, 0, 0, offset << 1, 0);
11634        /* No delay slot, so just process as a normal instruction */
11635        break;
11636    case M16_OPC_BEQZ:
11637        gen_compute_branch(ctx, OPC_BEQ, 4, rx, 0, offset << 1, 0);
11638        /* No delay slot, so just process as a normal instruction */
11639        break;
11640    case M16_OPC_BNEQZ:
11641        gen_compute_branch(ctx, OPC_BNE, 4, rx, 0, offset << 1, 0);
11642        /* No delay slot, so just process as a normal instruction */
11643        break;
11644    case M16_OPC_SHIFT:
11645        switch (ctx->opcode & 0x3) {
11646        case 0x0:
11647            gen_shift_imm(ctx, OPC_SLL, rx, ry, sa);
11648            break;
11649        case 0x1:
11650#if defined(TARGET_MIPS64)
11651            check_mips_64(ctx);
11652            gen_shift_imm(ctx, OPC_DSLL, rx, ry, sa);
11653#else
11654            generate_exception_end(ctx, EXCP_RI);
11655#endif
11656            break;
11657        case 0x2:
11658            gen_shift_imm(ctx, OPC_SRL, rx, ry, sa);
11659            break;
11660        case 0x3:
11661            gen_shift_imm(ctx, OPC_SRA, rx, ry, sa);
11662            break;
11663        }
11664        break;
11665#if defined(TARGET_MIPS64)
11666    case M16_OPC_LD:
11667        check_insn(ctx, ISA_MIPS3);
11668        check_mips_64(ctx);
11669        gen_ld(ctx, OPC_LD, ry, rx, offset);
11670        break;
11671#endif
11672    case M16_OPC_RRIA:
11673        imm = ctx->opcode & 0xf;
11674        imm = imm | ((ctx->opcode >> 20) & 0x7f) << 4;
11675        imm = imm | ((ctx->opcode >> 16) & 0xf) << 11;
11676        imm = (int16_t) (imm << 1) >> 1;
11677        if ((ctx->opcode >> 4) & 0x1) {
11678#if defined(TARGET_MIPS64)
11679            check_mips_64(ctx);
11680            gen_arith_imm(ctx, OPC_DADDIU, ry, rx, imm);
11681#else
11682            generate_exception_end(ctx, EXCP_RI);
11683#endif
11684        } else {
11685            gen_arith_imm(ctx, OPC_ADDIU, ry, rx, imm);
11686        }
11687        break;
11688    case M16_OPC_ADDIU8:
11689        gen_arith_imm(ctx, OPC_ADDIU, rx, rx, imm);
11690        break;
11691    case M16_OPC_SLTI:
11692        gen_slt_imm(ctx, OPC_SLTI, 24, rx, imm);
11693        break;
11694    case M16_OPC_SLTIU:
11695        gen_slt_imm(ctx, OPC_SLTIU, 24, rx, imm);
11696        break;
11697    case M16_OPC_I8:
11698        switch (funct) {
11699        case I8_BTEQZ:
11700            gen_compute_branch(ctx, OPC_BEQ, 4, 24, 0, offset << 1, 0);
11701            break;
11702        case I8_BTNEZ:
11703            gen_compute_branch(ctx, OPC_BNE, 4, 24, 0, offset << 1, 0);
11704            break;
11705        case I8_SWRASP:
11706            gen_st(ctx, OPC_SW, 31, 29, imm);
11707            break;
11708        case I8_ADJSP:
11709            gen_arith_imm(ctx, OPC_ADDIU, 29, 29, imm);
11710            break;
11711        case I8_SVRS:
11712            check_insn(ctx, ISA_MIPS32);
11713            {
11714                int xsregs = (ctx->opcode >> 24) & 0x7;
11715                int aregs = (ctx->opcode >> 16) & 0xf;
11716                int do_ra = (ctx->opcode >> 6) & 0x1;
11717                int do_s0 = (ctx->opcode >> 5) & 0x1;
11718                int do_s1 = (ctx->opcode >> 4) & 0x1;
11719                int framesize = (((ctx->opcode >> 20) & 0xf) << 4
11720                                 | (ctx->opcode & 0xf)) << 3;
11721
11722                if (ctx->opcode & (1 << 7)) {
11723                    gen_mips16_save(ctx, xsregs, aregs,
11724                                    do_ra, do_s0, do_s1,
11725                                    framesize);
11726                } else {
11727                    gen_mips16_restore(ctx, xsregs, aregs,
11728                                       do_ra, do_s0, do_s1,
11729                                       framesize);
11730                }
11731            }
11732            break;
11733        default:
11734            generate_exception_end(ctx, EXCP_RI);
11735            break;
11736        }
11737        break;
11738    case M16_OPC_LI:
11739        tcg_gen_movi_tl(cpu_gpr[rx], (uint16_t) imm);
11740        break;
11741    case M16_OPC_CMPI:
11742        tcg_gen_xori_tl(cpu_gpr[24], cpu_gpr[rx], (uint16_t) imm);
11743        break;
11744#if defined(TARGET_MIPS64)
11745    case M16_OPC_SD:
11746        check_insn(ctx, ISA_MIPS3);
11747        check_mips_64(ctx);
11748        gen_st(ctx, OPC_SD, ry, rx, offset);
11749        break;
11750#endif
11751    case M16_OPC_LB:
11752        gen_ld(ctx, OPC_LB, ry, rx, offset);
11753        break;
11754    case M16_OPC_LH:
11755        gen_ld(ctx, OPC_LH, ry, rx, offset);
11756        break;
11757    case M16_OPC_LWSP:
11758        gen_ld(ctx, OPC_LW, rx, 29, offset);
11759        break;
11760    case M16_OPC_LW:
11761        gen_ld(ctx, OPC_LW, ry, rx, offset);
11762        break;
11763    case M16_OPC_LBU:
11764        gen_ld(ctx, OPC_LBU, ry, rx, offset);
11765        break;
11766    case M16_OPC_LHU:
11767        gen_ld(ctx, OPC_LHU, ry, rx, offset);
11768        break;
11769    case M16_OPC_LWPC:
11770        gen_ld(ctx, OPC_LWPC, rx, 0, offset);
11771        break;
11772#if defined(TARGET_MIPS64)
11773    case M16_OPC_LWU:
11774        check_insn(ctx, ISA_MIPS3);
11775        check_mips_64(ctx);
11776        gen_ld(ctx, OPC_LWU, ry, rx, offset);
11777        break;
11778#endif
11779    case M16_OPC_SB:
11780        gen_st(ctx, OPC_SB, ry, rx, offset);
11781        break;
11782    case M16_OPC_SH:
11783        gen_st(ctx, OPC_SH, ry, rx, offset);
11784        break;
11785    case M16_OPC_SWSP:
11786        gen_st(ctx, OPC_SW, rx, 29, offset);
11787        break;
11788    case M16_OPC_SW:
11789        gen_st(ctx, OPC_SW, ry, rx, offset);
11790        break;
11791#if defined(TARGET_MIPS64)
11792    case M16_OPC_I64:
11793        decode_i64_mips16(ctx, ry, funct, offset, 1);
11794        break;
11795#endif
11796    default:
11797        generate_exception_end(ctx, EXCP_RI);
11798        break;
11799    }
11800
11801    return 4;
11802}
11803
11804static inline bool is_uhi(int sdbbp_code)
11805{
11806#ifdef CONFIG_USER_ONLY
11807    return false;
11808#else
11809    return semihosting_enabled() && sdbbp_code == 1;
11810#endif
11811}
11812
11813static int decode_mips16_opc (CPUMIPSState *env, DisasContext *ctx)
11814{
11815    int rx, ry;
11816    int sa;
11817    int op, cnvt_op, op1, offset;
11818    int funct;
11819    int n_bytes;
11820
11821    op = (ctx->opcode >> 11) & 0x1f;
11822    sa = (ctx->opcode >> 2) & 0x7;
11823    sa = sa == 0 ? 8 : sa;
11824    rx = xlat((ctx->opcode >> 8) & 0x7);
11825    cnvt_op = (ctx->opcode >> 5) & 0x7;
11826    ry = xlat((ctx->opcode >> 5) & 0x7);
11827    op1 = offset = ctx->opcode & 0x1f;
11828
11829    n_bytes = 2;
11830
11831    switch (op) {
11832    case M16_OPC_ADDIUSP:
11833        {
11834            int16_t imm = ((uint8_t) ctx->opcode) << 2;
11835
11836            gen_arith_imm(ctx, OPC_ADDIU, rx, 29, imm);
11837        }
11838        break;
11839    case M16_OPC_ADDIUPC:
11840        gen_addiupc(ctx, rx, ((uint8_t) ctx->opcode) << 2, 0, 0);
11841        break;
11842    case M16_OPC_B:
11843        offset = (ctx->opcode & 0x7ff) << 1;
11844        offset = (int16_t)(offset << 4) >> 4;
11845        gen_compute_branch(ctx, OPC_BEQ, 2, 0, 0, offset, 0);
11846        /* No delay slot, so just process as a normal instruction */
11847        break;
11848    case M16_OPC_JAL:
11849        offset = cpu_lduw_code(env, ctx->pc + 2);
11850        offset = (((ctx->opcode & 0x1f) << 21)
11851                  | ((ctx->opcode >> 5) & 0x1f) << 16
11852                  | offset) << 2;
11853        op = ((ctx->opcode >> 10) & 0x1) ? OPC_JALX : OPC_JAL;
11854        gen_compute_branch(ctx, op, 4, rx, ry, offset, 2);
11855        n_bytes = 4;
11856        break;
11857    case M16_OPC_BEQZ:
11858        gen_compute_branch(ctx, OPC_BEQ, 2, rx, 0,
11859                           ((int8_t)ctx->opcode) << 1, 0);
11860        /* No delay slot, so just process as a normal instruction */
11861        break;
11862    case M16_OPC_BNEQZ:
11863        gen_compute_branch(ctx, OPC_BNE, 2, rx, 0,
11864                           ((int8_t)ctx->opcode) << 1, 0);
11865        /* No delay slot, so just process as a normal instruction */
11866        break;
11867    case M16_OPC_SHIFT:
11868        switch (ctx->opcode & 0x3) {
11869        case 0x0:
11870            gen_shift_imm(ctx, OPC_SLL, rx, ry, sa);
11871            break;
11872        case 0x1:
11873#if defined(TARGET_MIPS64)
11874            check_insn(ctx, ISA_MIPS3);
11875            check_mips_64(ctx);
11876            gen_shift_imm(ctx, OPC_DSLL, rx, ry, sa);
11877#else
11878            generate_exception_end(ctx, EXCP_RI);
11879#endif
11880            break;
11881        case 0x2:
11882            gen_shift_imm(ctx, OPC_SRL, rx, ry, sa);
11883            break;
11884        case 0x3:
11885            gen_shift_imm(ctx, OPC_SRA, rx, ry, sa);
11886            break;
11887        }
11888        break;
11889#if defined(TARGET_MIPS64)
11890    case M16_OPC_LD:
11891        check_insn(ctx, ISA_MIPS3);
11892        check_mips_64(ctx);
11893        gen_ld(ctx, OPC_LD, ry, rx, offset << 3);
11894        break;
11895#endif
11896    case M16_OPC_RRIA:
11897        {
11898            int16_t imm = (int8_t)((ctx->opcode & 0xf) << 4) >> 4;
11899
11900            if ((ctx->opcode >> 4) & 1) {
11901#if defined(TARGET_MIPS64)
11902                check_insn(ctx, ISA_MIPS3);
11903                check_mips_64(ctx);
11904                gen_arith_imm(ctx, OPC_DADDIU, ry, rx, imm);
11905#else
11906                generate_exception_end(ctx, EXCP_RI);
11907#endif
11908            } else {
11909                gen_arith_imm(ctx, OPC_ADDIU, ry, rx, imm);
11910            }
11911        }
11912        break;
11913    case M16_OPC_ADDIU8:
11914        {
11915            int16_t imm = (int8_t) ctx->opcode;
11916
11917            gen_arith_imm(ctx, OPC_ADDIU, rx, rx, imm);
11918        }
11919        break;
11920    case M16_OPC_SLTI:
11921        {
11922            int16_t imm = (uint8_t) ctx->opcode;
11923            gen_slt_imm(ctx, OPC_SLTI, 24, rx, imm);
11924        }
11925        break;
11926    case M16_OPC_SLTIU:
11927        {
11928            int16_t imm = (uint8_t) ctx->opcode;
11929            gen_slt_imm(ctx, OPC_SLTIU, 24, rx, imm);
11930        }
11931        break;
11932    case M16_OPC_I8:
11933        {
11934            int reg32;
11935
11936            funct = (ctx->opcode >> 8) & 0x7;
11937            switch (funct) {
11938            case I8_BTEQZ:
11939                gen_compute_branch(ctx, OPC_BEQ, 2, 24, 0,
11940                                   ((int8_t)ctx->opcode) << 1, 0);
11941                break;
11942            case I8_BTNEZ:
11943                gen_compute_branch(ctx, OPC_BNE, 2, 24, 0,
11944                                   ((int8_t)ctx->opcode) << 1, 0);
11945                break;
11946            case I8_SWRASP:
11947                gen_st(ctx, OPC_SW, 31, 29, (ctx->opcode & 0xff) << 2);
11948                break;
11949            case I8_ADJSP:
11950                gen_arith_imm(ctx, OPC_ADDIU, 29, 29,
11951                              ((int8_t)ctx->opcode) << 3);
11952                break;
11953            case I8_SVRS:
11954                check_insn(ctx, ISA_MIPS32);
11955                {
11956                    int do_ra = ctx->opcode & (1 << 6);
11957                    int do_s0 = ctx->opcode & (1 << 5);
11958                    int do_s1 = ctx->opcode & (1 << 4);
11959                    int framesize = ctx->opcode & 0xf;
11960
11961                    if (framesize == 0) {
11962                        framesize = 128;
11963                    } else {
11964                        framesize = framesize << 3;
11965                    }
11966
11967                    if (ctx->opcode & (1 << 7)) {
11968                        gen_mips16_save(ctx, 0, 0,
11969                                        do_ra, do_s0, do_s1, framesize);
11970                    } else {
11971                        gen_mips16_restore(ctx, 0, 0,
11972                                           do_ra, do_s0, do_s1, framesize);
11973                    }
11974                }
11975                break;
11976            case I8_MOV32R:
11977                {
11978                    int rz = xlat(ctx->opcode & 0x7);
11979
11980                    reg32 = (((ctx->opcode >> 3) & 0x3) << 3) |
11981                        ((ctx->opcode >> 5) & 0x7);
11982                    gen_arith(ctx, OPC_ADDU, reg32, rz, 0);
11983                }
11984                break;
11985            case I8_MOVR32:
11986                reg32 = ctx->opcode & 0x1f;
11987                gen_arith(ctx, OPC_ADDU, ry, reg32, 0);
11988                break;
11989            default:
11990                generate_exception_end(ctx, EXCP_RI);
11991                break;
11992            }
11993        }
11994        break;
11995    case M16_OPC_LI:
11996        {
11997            int16_t imm = (uint8_t) ctx->opcode;
11998
11999            gen_arith_imm(ctx, OPC_ADDIU, rx, 0, imm);
12000        }
12001        break;
12002    case M16_OPC_CMPI:
12003        {
12004            int16_t imm = (uint8_t) ctx->opcode;
12005            gen_logic_imm(ctx, OPC_XORI, 24, rx, imm);
12006        }
12007        break;
12008#if defined(TARGET_MIPS64)
12009    case M16_OPC_SD:
12010        check_insn(ctx, ISA_MIPS3);
12011        check_mips_64(ctx);
12012        gen_st(ctx, OPC_SD, ry, rx, offset << 3);
12013        break;
12014#endif
12015    case M16_OPC_LB:
12016        gen_ld(ctx, OPC_LB, ry, rx, offset);
12017        break;
12018    case M16_OPC_LH:
12019        gen_ld(ctx, OPC_LH, ry, rx, offset << 1);
12020        break;
12021    case M16_OPC_LWSP:
12022        gen_ld(ctx, OPC_LW, rx, 29, ((uint8_t)ctx->opcode) << 2);
12023        break;
12024    case M16_OPC_LW:
12025        gen_ld(ctx, OPC_LW, ry, rx, offset << 2);
12026        break;
12027    case M16_OPC_LBU:
12028        gen_ld(ctx, OPC_LBU, ry, rx, offset);
12029        break;
12030    case M16_OPC_LHU:
12031        gen_ld(ctx, OPC_LHU, ry, rx, offset << 1);
12032        break;
12033    case M16_OPC_LWPC:
12034        gen_ld(ctx, OPC_LWPC, rx, 0, ((uint8_t)ctx->opcode) << 2);
12035        break;
12036#if defined (TARGET_MIPS64)
12037    case M16_OPC_LWU:
12038        check_insn(ctx, ISA_MIPS3);
12039        check_mips_64(ctx);
12040        gen_ld(ctx, OPC_LWU, ry, rx, offset << 2);
12041        break;
12042#endif
12043    case M16_OPC_SB:
12044        gen_st(ctx, OPC_SB, ry, rx, offset);
12045        break;
12046    case M16_OPC_SH:
12047        gen_st(ctx, OPC_SH, ry, rx, offset << 1);
12048        break;
12049    case M16_OPC_SWSP:
12050        gen_st(ctx, OPC_SW, rx, 29, ((uint8_t)ctx->opcode) << 2);
12051        break;
12052    case M16_OPC_SW:
12053        gen_st(ctx, OPC_SW, ry, rx, offset << 2);
12054        break;
12055    case M16_OPC_RRR:
12056        {
12057            int rz = xlat((ctx->opcode >> 2) & 0x7);
12058            int mips32_op;
12059
12060            switch (ctx->opcode & 0x3) {
12061            case RRR_ADDU:
12062                mips32_op = OPC_ADDU;
12063                break;
12064            case RRR_SUBU:
12065                mips32_op = OPC_SUBU;
12066                break;
12067#if defined(TARGET_MIPS64)
12068            case RRR_DADDU:
12069                mips32_op = OPC_DADDU;
12070                check_insn(ctx, ISA_MIPS3);
12071                check_mips_64(ctx);
12072                break;
12073            case RRR_DSUBU:
12074                mips32_op = OPC_DSUBU;
12075                check_insn(ctx, ISA_MIPS3);
12076                check_mips_64(ctx);
12077                break;
12078#endif
12079            default:
12080                generate_exception_end(ctx, EXCP_RI);
12081                goto done;
12082            }
12083
12084            gen_arith(ctx, mips32_op, rz, rx, ry);
12085        done:
12086            ;
12087        }
12088        break;
12089    case M16_OPC_RR:
12090        switch (op1) {
12091        case RR_JR:
12092            {
12093                int nd = (ctx->opcode >> 7) & 0x1;
12094                int link = (ctx->opcode >> 6) & 0x1;
12095                int ra = (ctx->opcode >> 5) & 0x1;
12096
12097                if (nd) {
12098                    check_insn(ctx, ISA_MIPS32);
12099                }
12100
12101                if (link) {
12102                    op = OPC_JALR;
12103                } else {
12104                    op = OPC_JR;
12105                }
12106
12107                gen_compute_branch(ctx, op, 2, ra ? 31 : rx, 31, 0,
12108                                   (nd ? 0 : 2));
12109            }
12110            break;
12111        case RR_SDBBP:
12112            if (is_uhi(extract32(ctx->opcode, 5, 6))) {
12113                gen_helper_do_semihosting(cpu_env);
12114            } else {
12115                /* XXX: not clear which exception should be raised
12116                 *      when in debug mode...
12117                 */
12118                check_insn(ctx, ISA_MIPS32);
12119                generate_exception_end(ctx, EXCP_DBp);
12120            }
12121            break;
12122        case RR_SLT:
12123            gen_slt(ctx, OPC_SLT, 24, rx, ry);
12124            break;
12125        case RR_SLTU:
12126            gen_slt(ctx, OPC_SLTU, 24, rx, ry);
12127            break;
12128        case RR_BREAK:
12129            generate_exception_end(ctx, EXCP_BREAK);
12130            break;
12131        case RR_SLLV:
12132            gen_shift(ctx, OPC_SLLV, ry, rx, ry);
12133            break;
12134        case RR_SRLV:
12135            gen_shift(ctx, OPC_SRLV, ry, rx, ry);
12136            break;
12137        case RR_SRAV:
12138            gen_shift(ctx, OPC_SRAV, ry, rx, ry);
12139            break;
12140#if defined (TARGET_MIPS64)
12141        case RR_DSRL:
12142            check_insn(ctx, ISA_MIPS3);
12143            check_mips_64(ctx);
12144            gen_shift_imm(ctx, OPC_DSRL, ry, ry, sa);
12145            break;
12146#endif
12147        case RR_CMP:
12148            gen_logic(ctx, OPC_XOR, 24, rx, ry);
12149            break;
12150        case RR_NEG:
12151            gen_arith(ctx, OPC_SUBU, rx, 0, ry);
12152            break;
12153        case RR_AND:
12154            gen_logic(ctx, OPC_AND, rx, rx, ry);
12155            break;
12156        case RR_OR:
12157            gen_logic(ctx, OPC_OR, rx, rx, ry);
12158            break;
12159        case RR_XOR:
12160            gen_logic(ctx, OPC_XOR, rx, rx, ry);
12161            break;
12162        case RR_NOT:
12163            gen_logic(ctx, OPC_NOR, rx, ry, 0);
12164            break;
12165        case RR_MFHI:
12166            gen_HILO(ctx, OPC_MFHI, 0, rx);
12167            break;
12168        case RR_CNVT:
12169            check_insn(ctx, ISA_MIPS32);
12170            switch (cnvt_op) {
12171            case RR_RY_CNVT_ZEB:
12172                tcg_gen_ext8u_tl(cpu_gpr[rx], cpu_gpr[rx]);
12173                break;
12174            case RR_RY_CNVT_ZEH:
12175                tcg_gen_ext16u_tl(cpu_gpr[rx], cpu_gpr[rx]);
12176                break;
12177            case RR_RY_CNVT_SEB:
12178                tcg_gen_ext8s_tl(cpu_gpr[rx], cpu_gpr[rx]);
12179                break;
12180            case RR_RY_CNVT_SEH:
12181                tcg_gen_ext16s_tl(cpu_gpr[rx], cpu_gpr[rx]);
12182                break;
12183#if defined (TARGET_MIPS64)
12184            case RR_RY_CNVT_ZEW:
12185                check_insn(ctx, ISA_MIPS64);
12186                check_mips_64(ctx);
12187                tcg_gen_ext32u_tl(cpu_gpr[rx], cpu_gpr[rx]);
12188                break;
12189            case RR_RY_CNVT_SEW:
12190                check_insn(ctx, ISA_MIPS64);
12191                check_mips_64(ctx);
12192                tcg_gen_ext32s_tl(cpu_gpr[rx], cpu_gpr[rx]);
12193                break;
12194#endif
12195            default:
12196                generate_exception_end(ctx, EXCP_RI);
12197                break;
12198            }
12199            break;
12200        case RR_MFLO:
12201            gen_HILO(ctx, OPC_MFLO, 0, rx);
12202            break;
12203#if defined (TARGET_MIPS64)
12204        case RR_DSRA:
12205            check_insn(ctx, ISA_MIPS3);
12206            check_mips_64(ctx);
12207            gen_shift_imm(ctx, OPC_DSRA, ry, ry, sa);
12208            break;
12209        case RR_DSLLV:
12210            check_insn(ctx, ISA_MIPS3);
12211            check_mips_64(ctx);
12212            gen_shift(ctx, OPC_DSLLV, ry, rx, ry);
12213            break;
12214        case RR_DSRLV:
12215            check_insn(ctx, ISA_MIPS3);
12216            check_mips_64(ctx);
12217            gen_shift(ctx, OPC_DSRLV, ry, rx, ry);
12218            break;
12219        case RR_DSRAV:
12220            check_insn(ctx, ISA_MIPS3);
12221            check_mips_64(ctx);
12222            gen_shift(ctx, OPC_DSRAV, ry, rx, ry);
12223            break;
12224#endif
12225        case RR_MULT:
12226            gen_muldiv(ctx, OPC_MULT, 0, rx, ry);
12227            break;
12228        case RR_MULTU:
12229            gen_muldiv(ctx, OPC_MULTU, 0, rx, ry);
12230            break;
12231        case RR_DIV:
12232            gen_muldiv(ctx, OPC_DIV, 0, rx, ry);
12233            break;
12234        case RR_DIVU:
12235            gen_muldiv(ctx, OPC_DIVU, 0, rx, ry);
12236            break;
12237#if defined (TARGET_MIPS64)
12238        case RR_DMULT:
12239            check_insn(ctx, ISA_MIPS3);
12240            check_mips_64(ctx);
12241            gen_muldiv(ctx, OPC_DMULT, 0, rx, ry);
12242            break;
12243        case RR_DMULTU:
12244            check_insn(ctx, ISA_MIPS3);
12245            check_mips_64(ctx);
12246            gen_muldiv(ctx, OPC_DMULTU, 0, rx, ry);
12247            break;
12248        case RR_DDIV:
12249            check_insn(ctx, ISA_MIPS3);
12250            check_mips_64(ctx);
12251            gen_muldiv(ctx, OPC_DDIV, 0, rx, ry);
12252            break;
12253        case RR_DDIVU:
12254            check_insn(ctx, ISA_MIPS3);
12255            check_mips_64(ctx);
12256            gen_muldiv(ctx, OPC_DDIVU, 0, rx, ry);
12257            break;
12258#endif
12259        default:
12260            generate_exception_end(ctx, EXCP_RI);
12261            break;
12262        }
12263        break;
12264    case M16_OPC_EXTEND:
12265        decode_extended_mips16_opc(env, ctx);
12266        n_bytes = 4;
12267        break;
12268#if defined(TARGET_MIPS64)
12269    case M16_OPC_I64:
12270        funct = (ctx->opcode >> 8) & 0x7;
12271        decode_i64_mips16(ctx, ry, funct, offset, 0);
12272        break;
12273#endif
12274    default:
12275        generate_exception_end(ctx, EXCP_RI);
12276        break;
12277    }
12278
12279    return n_bytes;
12280}
12281
12282/* microMIPS extension to MIPS32/MIPS64 */
12283
12284/*
12285 * microMIPS32/microMIPS64 major opcodes
12286 *
12287 * 1. MIPS Architecture for Programmers Volume II-B:
12288 *      The microMIPS32 Instruction Set (Revision 3.05)
12289 *
12290 *    Table 6.2 microMIPS32 Encoding of Major Opcode Field
12291 *
12292 * 2. MIPS Architecture For Programmers Volume II-A:
12293 *      The MIPS64 Instruction Set (Revision 3.51)
12294 */
12295
12296enum {
12297    POOL32A = 0x00,
12298    POOL16A = 0x01,
12299    LBU16 = 0x02,
12300    MOVE16 = 0x03,
12301    ADDI32 = 0x04,
12302    R6_LUI = 0x04,
12303    AUI = 0x04,
12304    LBU32 = 0x05,
12305    SB32 = 0x06,
12306    LB32 = 0x07,
12307
12308    POOL32B = 0x08,
12309    POOL16B = 0x09,
12310    LHU16 = 0x0a,
12311    ANDI16 = 0x0b,
12312    ADDIU32 = 0x0c,
12313    LHU32 = 0x0d,
12314    SH32 = 0x0e,
12315    LH32 = 0x0f,
12316
12317    POOL32I = 0x10,
12318    POOL16C = 0x11,
12319    LWSP16 = 0x12,
12320    POOL16D = 0x13,
12321    ORI32 = 0x14,
12322    POOL32F = 0x15,
12323    POOL32S = 0x16,  /* MIPS64 */
12324    DADDIU32 = 0x17, /* MIPS64 */
12325
12326    POOL32C = 0x18,
12327    LWGP16 = 0x19,
12328    LW16 = 0x1a,
12329    POOL16E = 0x1b,
12330    XORI32 = 0x1c,
12331    JALS32 = 0x1d,
12332    BOVC = 0x1d,
12333    BEQC = 0x1d,
12334    BEQZALC = 0x1d,
12335    ADDIUPC = 0x1e,
12336    PCREL = 0x1e,
12337    BNVC = 0x1f,
12338    BNEC = 0x1f,
12339    BNEZALC = 0x1f,
12340
12341    R6_BEQZC = 0x20,
12342    JIC = 0x20,
12343    POOL16F = 0x21,
12344    SB16 = 0x22,
12345    BEQZ16 = 0x23,
12346    BEQZC16 = 0x23,
12347    SLTI32 = 0x24,
12348    BEQ32 = 0x25,
12349    BC = 0x25,
12350    SWC132 = 0x26,
12351    LWC132 = 0x27,
12352
12353    /* 0x29 is reserved */
12354    RES_29 = 0x29,
12355    R6_BNEZC = 0x28,
12356    JIALC = 0x28,
12357    SH16 = 0x2a,
12358    BNEZ16 = 0x2b,
12359    BNEZC16 = 0x2b,
12360    SLTIU32 = 0x2c,
12361    BNE32 = 0x2d,
12362    BALC = 0x2d,
12363    SDC132 = 0x2e,
12364    LDC132 = 0x2f,
12365
12366    /* 0x31 is reserved */
12367    RES_31 = 0x31,
12368    BLEZALC = 0x30,
12369    BGEZALC = 0x30,
12370    BGEUC = 0x30,
12371    SWSP16 = 0x32,
12372    B16 = 0x33,
12373    BC16 = 0x33,
12374    ANDI32 = 0x34,
12375    J32 = 0x35,
12376    BGTZC = 0x35,
12377    BLTZC = 0x35,
12378    BLTC = 0x35,
12379    SD32 = 0x36, /* MIPS64 */
12380    LD32 = 0x37, /* MIPS64 */
12381
12382    /* 0x39 is reserved */
12383    RES_39 = 0x39,
12384    BGTZALC = 0x38,
12385    BLTZALC = 0x38,
12386    BLTUC = 0x38,
12387    SW16 = 0x3a,
12388    LI16 = 0x3b,
12389    JALX32 = 0x3c,
12390    JAL32 = 0x3d,
12391    BLEZC = 0x3d,
12392    BGEZC = 0x3d,
12393    BGEC = 0x3d,
12394    SW32 = 0x3e,
12395    LW32 = 0x3f
12396};
12397
12398/* PCREL Instructions perform PC-Relative address calculation. bits 20..16 */
12399enum {
12400    ADDIUPC_00 = 0x00,
12401    ADDIUPC_07 = 0x07,
12402    AUIPC = 0x1e,
12403    ALUIPC = 0x1f,
12404    LWPC_08 = 0x08,
12405    LWPC_0F = 0x0F,
12406};
12407
12408/* POOL32A encoding of minor opcode field */
12409
12410enum {
12411    /* These opcodes are distinguished only by bits 9..6; those bits are
12412     * what are recorded below. */
12413    SLL32 = 0x0,
12414    SRL32 = 0x1,
12415    SRA = 0x2,
12416    ROTR = 0x3,
12417    SELEQZ = 0x5,
12418    SELNEZ = 0x6,
12419    R6_RDHWR = 0x7,
12420
12421    SLLV = 0x0,
12422    SRLV = 0x1,
12423    SRAV = 0x2,
12424    ROTRV = 0x3,
12425    ADD = 0x4,
12426    ADDU32 = 0x5,
12427    SUB = 0x6,
12428    SUBU32 = 0x7,
12429    MUL = 0x8,
12430    AND = 0x9,
12431    OR32 = 0xa,
12432    NOR = 0xb,
12433    XOR32 = 0xc,
12434    SLT = 0xd,
12435    SLTU = 0xe,
12436
12437    MOVN = 0x0,
12438    R6_MUL  = 0x0,
12439    MOVZ = 0x1,
12440    MUH  = 0x1,
12441    MULU = 0x2,
12442    MUHU = 0x3,
12443    LWXS = 0x4,
12444    R6_DIV  = 0x4,
12445    MOD  = 0x5,
12446    R6_DIVU = 0x6,
12447    MODU = 0x7,
12448
12449    /* The following can be distinguished by their lower 6 bits. */
12450    BREAK32 = 0x07,
12451    INS = 0x0c,
12452    LSA = 0x0f,
12453    ALIGN = 0x1f,
12454    EXT = 0x2c,
12455    POOL32AXF = 0x3c,
12456    SIGRIE = 0x3f
12457};
12458
12459/* POOL32AXF encoding of minor opcode field extension */
12460
12461/*
12462 * 1. MIPS Architecture for Programmers Volume II-B:
12463 *      The microMIPS32 Instruction Set (Revision 3.05)
12464 *
12465 *    Table 6.5 POOL32Axf Encoding of Minor Opcode Extension Field
12466 *
12467 * 2. MIPS Architecture for Programmers VolumeIV-e:
12468 *      The MIPS DSP Application-Specific Extension
12469 *        to the microMIPS32 Architecture (Revision 2.34)
12470 *
12471 *    Table 5.5 POOL32Axf Encoding of Minor Opcode Extension Field
12472 */
12473
12474enum {
12475    /* bits 11..6 */
12476    TEQ = 0x00,
12477    TGE = 0x08,
12478    TGEU = 0x10,
12479    TLT = 0x20,
12480    TLTU = 0x28,
12481    TNE = 0x30,
12482
12483    MFC0 = 0x03,
12484    MTC0 = 0x0b,
12485
12486    /* begin of microMIPS32 DSP */
12487
12488    /* bits 13..12 for 0x01 */
12489    MFHI_ACC = 0x0,
12490    MFLO_ACC = 0x1,
12491    MTHI_ACC = 0x2,
12492    MTLO_ACC = 0x3,
12493
12494    /* bits 13..12 for 0x2a */
12495    MADD_ACC = 0x0,
12496    MADDU_ACC = 0x1,
12497    MSUB_ACC = 0x2,
12498    MSUBU_ACC = 0x3,
12499
12500    /* bits 13..12 for 0x32 */
12501    MULT_ACC = 0x0,
12502    MULTU_ACC = 0x1,
12503
12504    /* end of microMIPS32 DSP */
12505
12506    /* bits 15..12 for 0x2c */
12507    BITSWAP = 0x0,
12508    SEB = 0x2,
12509    SEH = 0x3,
12510    CLO = 0x4,
12511    CLZ = 0x5,
12512    RDHWR = 0x6,
12513    WSBH = 0x7,
12514    MULT = 0x8,
12515    MULTU = 0x9,
12516    DIV = 0xa,
12517    DIVU = 0xb,
12518    MADD = 0xc,
12519    MADDU = 0xd,
12520    MSUB = 0xe,
12521    MSUBU = 0xf,
12522
12523    /* bits 15..12 for 0x34 */
12524    MFC2 = 0x4,
12525    MTC2 = 0x5,
12526    MFHC2 = 0x8,
12527    MTHC2 = 0x9,
12528    CFC2 = 0xc,
12529    CTC2 = 0xd,
12530
12531    /* bits 15..12 for 0x3c */
12532    JALR = 0x0,
12533    JR = 0x0,                   /* alias */
12534    JALRC = 0x0,
12535    JRC = 0x0,
12536    JALR_HB = 0x1,
12537    JALRC_HB = 0x1,
12538    JALRS = 0x4,
12539    JALRS_HB = 0x5,
12540
12541    /* bits 15..12 for 0x05 */
12542    RDPGPR = 0xe,
12543    WRPGPR = 0xf,
12544
12545    /* bits 15..12 for 0x0d */
12546    TLBP = 0x0,
12547    TLBR = 0x1,
12548    TLBWI = 0x2,
12549    TLBWR = 0x3,
12550    TLBINV = 0x4,
12551    TLBINVF = 0x5,
12552    WAIT = 0x9,
12553    IRET = 0xd,
12554    DERET = 0xe,
12555    ERET = 0xf,
12556
12557    /* bits 15..12 for 0x15 */
12558    DMT = 0x0,
12559    DVPE = 0x1,
12560    EMT = 0x2,
12561    EVPE = 0x3,
12562
12563    /* bits 15..12 for 0x1d */
12564    DI = 0x4,
12565    EI = 0x5,
12566
12567    /* bits 15..12 for 0x2d */
12568    SYNC = 0x6,
12569    SYSCALL = 0x8,
12570    SDBBP = 0xd,
12571
12572    /* bits 15..12 for 0x35 */
12573    MFHI32 = 0x0,
12574    MFLO32 = 0x1,
12575    MTHI32 = 0x2,
12576    MTLO32 = 0x3,
12577};
12578
12579/* POOL32B encoding of minor opcode field (bits 15..12) */
12580
12581enum {
12582    LWC2 = 0x0,
12583    LWP = 0x1,
12584    LDP = 0x4,
12585    LWM32 = 0x5,
12586    CACHE = 0x6,
12587    LDM = 0x7,
12588    SWC2 = 0x8,
12589    SWP = 0x9,
12590    SDP = 0xc,
12591    SWM32 = 0xd,
12592    SDM = 0xf
12593};
12594
12595/* POOL32C encoding of minor opcode field (bits 15..12) */
12596
12597enum {
12598    LWL = 0x0,
12599    SWL = 0x8,
12600    LWR = 0x1,
12601    SWR = 0x9,
12602    PREF = 0x2,
12603    ST_EVA = 0xa,
12604    LL = 0x3,
12605    SC = 0xb,
12606    LDL = 0x4,
12607    SDL = 0xc,
12608    LDR = 0x5,
12609    SDR = 0xd,
12610    LD_EVA = 0x6,
12611    LWU = 0xe,
12612    LLD = 0x7,
12613    SCD = 0xf
12614};
12615
12616/* POOL32C LD-EVA encoding of minor opcode field (bits 11..9) */
12617
12618enum {
12619    LBUE = 0x0,
12620    LHUE = 0x1,
12621    LWLE = 0x2,
12622    LWRE = 0x3,
12623    LBE = 0x4,
12624    LHE = 0x5,
12625    LLE = 0x6,
12626    LWE = 0x7,
12627};
12628
12629/* POOL32C ST-EVA encoding of minor opcode field (bits 11..9) */
12630
12631enum {
12632    SWLE = 0x0,
12633    SWRE = 0x1,
12634    PREFE = 0x2,
12635    CACHEE = 0x3,
12636    SBE = 0x4,
12637    SHE = 0x5,
12638    SCE = 0x6,
12639    SWE = 0x7,
12640};
12641
12642/* POOL32F encoding of minor opcode field (bits 5..0) */
12643
12644enum {
12645    /* These are the bit 7..6 values */
12646    ADD_FMT = 0x0,
12647
12648    SUB_FMT = 0x1,
12649
12650    MUL_FMT = 0x2,
12651
12652    DIV_FMT = 0x3,
12653
12654    /* These are the bit 8..6 values */
12655    MOVN_FMT = 0x0,
12656    RSQRT2_FMT = 0x0,
12657    MOVF_FMT = 0x0,
12658    RINT_FMT = 0x0,
12659    SELNEZ_FMT = 0x0,
12660
12661    MOVZ_FMT = 0x1,
12662    LWXC1 = 0x1,
12663    MOVT_FMT = 0x1,
12664    CLASS_FMT = 0x1,
12665    SELEQZ_FMT = 0x1,
12666
12667    PLL_PS = 0x2,
12668    SWXC1 = 0x2,
12669    SEL_FMT = 0x2,
12670
12671    PLU_PS = 0x3,
12672    LDXC1 = 0x3,
12673
12674    MOVN_FMT_04 = 0x4,
12675    PUL_PS = 0x4,
12676    SDXC1 = 0x4,
12677    RECIP2_FMT = 0x4,
12678
12679    MOVZ_FMT_05 = 0x05,
12680    PUU_PS = 0x5,
12681    LUXC1 = 0x5,
12682
12683    CVT_PS_S = 0x6,
12684    SUXC1 = 0x6,
12685    ADDR_PS = 0x6,
12686    PREFX = 0x6,
12687    MADDF_FMT = 0x6,
12688
12689    MULR_PS = 0x7,
12690    MSUBF_FMT = 0x7,
12691
12692    MADD_S = 0x01,
12693    MADD_D = 0x09,
12694    MADD_PS = 0x11,
12695    ALNV_PS = 0x19,
12696    MSUB_S = 0x21,
12697    MSUB_D = 0x29,
12698    MSUB_PS = 0x31,
12699
12700    NMADD_S = 0x02,
12701    NMADD_D = 0x0a,
12702    NMADD_PS = 0x12,
12703    NMSUB_S = 0x22,
12704    NMSUB_D = 0x2a,
12705    NMSUB_PS = 0x32,
12706
12707    MIN_FMT = 0x3,
12708    MAX_FMT = 0xb,
12709    MINA_FMT = 0x23,
12710    MAXA_FMT = 0x2b,
12711    POOL32FXF = 0x3b,
12712
12713    CABS_COND_FMT = 0x1c,              /* MIPS3D */
12714    C_COND_FMT = 0x3c,
12715
12716    CMP_CONDN_S = 0x5,
12717    CMP_CONDN_D = 0x15
12718};
12719
12720/* POOL32Fxf encoding of minor opcode extension field */
12721
12722enum {
12723    CVT_L = 0x04,
12724    RSQRT_FMT = 0x08,
12725    FLOOR_L = 0x0c,
12726    CVT_PW_PS = 0x1c,
12727    CVT_W = 0x24,
12728    SQRT_FMT = 0x28,
12729    FLOOR_W = 0x2c,
12730    CVT_PS_PW = 0x3c,
12731    CFC1 = 0x40,
12732    RECIP_FMT = 0x48,
12733    CEIL_L = 0x4c,
12734    CTC1 = 0x60,
12735    CEIL_W = 0x6c,
12736    MFC1 = 0x80,
12737    CVT_S_PL = 0x84,
12738    TRUNC_L = 0x8c,
12739    MTC1 = 0xa0,
12740    CVT_S_PU = 0xa4,
12741    TRUNC_W = 0xac,
12742    MFHC1 = 0xc0,
12743    ROUND_L = 0xcc,
12744    MTHC1 = 0xe0,
12745    ROUND_W = 0xec,
12746
12747    MOV_FMT = 0x01,
12748    MOVF = 0x05,
12749    ABS_FMT = 0x0d,
12750    RSQRT1_FMT = 0x1d,
12751    MOVT = 0x25,
12752    NEG_FMT = 0x2d,
12753    CVT_D = 0x4d,
12754    RECIP1_FMT = 0x5d,
12755    CVT_S = 0x6d
12756};
12757
12758/* POOL32I encoding of minor opcode field (bits 25..21) */
12759
12760enum {
12761    BLTZ = 0x00,
12762    BLTZAL = 0x01,
12763    BGEZ = 0x02,
12764    BGEZAL = 0x03,
12765    BLEZ = 0x04,
12766    BNEZC = 0x05,
12767    BGTZ = 0x06,
12768    BEQZC = 0x07,
12769    TLTI = 0x08,
12770    BC1EQZC = 0x08,
12771    TGEI = 0x09,
12772    BC1NEZC = 0x09,
12773    TLTIU = 0x0a,
12774    BC2EQZC = 0x0a,
12775    TGEIU = 0x0b,
12776    BC2NEZC = 0x0a,
12777    TNEI = 0x0c,
12778    R6_SYNCI = 0x0c,
12779    LUI = 0x0d,
12780    TEQI = 0x0e,
12781    SYNCI = 0x10,
12782    BLTZALS = 0x11,
12783    BGEZALS = 0x13,
12784    BC2F = 0x14,
12785    BC2T = 0x15,
12786    BPOSGE64 = 0x1a,
12787    BPOSGE32 = 0x1b,
12788    /* These overlap and are distinguished by bit16 of the instruction */
12789    BC1F = 0x1c,
12790    BC1T = 0x1d,
12791    BC1ANY2F = 0x1c,
12792    BC1ANY2T = 0x1d,
12793    BC1ANY4F = 0x1e,
12794    BC1ANY4T = 0x1f
12795};
12796
12797/* POOL16A encoding of minor opcode field */
12798
12799enum {
12800    ADDU16 = 0x0,
12801    SUBU16 = 0x1
12802};
12803
12804/* POOL16B encoding of minor opcode field */
12805
12806enum {
12807    SLL16 = 0x0,
12808    SRL16 = 0x1
12809};
12810
12811/* POOL16C encoding of minor opcode field */
12812
12813enum {
12814    NOT16 = 0x00,
12815    XOR16 = 0x04,
12816    AND16 = 0x08,
12817    OR16 = 0x0c,
12818    LWM16 = 0x10,
12819    SWM16 = 0x14,
12820    JR16 = 0x18,
12821    JRC16 = 0x1a,
12822    JALR16 = 0x1c,
12823    JALR16S = 0x1e,
12824    MFHI16 = 0x20,
12825    MFLO16 = 0x24,
12826    BREAK16 = 0x28,
12827    SDBBP16 = 0x2c,
12828    JRADDIUSP = 0x30
12829};
12830
12831/* R6 POOL16C encoding of minor opcode field (bits 0..5) */
12832
12833enum {
12834    R6_NOT16    = 0x00,
12835    R6_AND16    = 0x01,
12836    R6_LWM16    = 0x02,
12837    R6_JRC16    = 0x03,
12838    MOVEP       = 0x04,
12839    MOVEP_07    = 0x07,
12840    R6_XOR16    = 0x08,
12841    R6_OR16     = 0x09,
12842    R6_SWM16    = 0x0a,
12843    JALRC16     = 0x0b,
12844    MOVEP_0C    = 0x0c,
12845    MOVEP_0F    = 0x0f,
12846    JRCADDIUSP  = 0x13,
12847    R6_BREAK16  = 0x1b,
12848    R6_SDBBP16  = 0x3b
12849};
12850
12851/* POOL16D encoding of minor opcode field */
12852
12853enum {
12854    ADDIUS5 = 0x0,
12855    ADDIUSP = 0x1
12856};
12857
12858/* POOL16E encoding of minor opcode field */
12859
12860enum {
12861    ADDIUR2 = 0x0,
12862    ADDIUR1SP = 0x1
12863};
12864
12865static int mmreg (int r)
12866{
12867    static const int map[] = { 16, 17, 2, 3, 4, 5, 6, 7 };
12868
12869    return map[r];
12870}
12871
12872/* Used for 16-bit store instructions.  */
12873static int mmreg2 (int r)
12874{
12875    static const int map[] = { 0, 17, 2, 3, 4, 5, 6, 7 };
12876
12877    return map[r];
12878}
12879
12880#define uMIPS_RD(op) ((op >> 7) & 0x7)
12881#define uMIPS_RS(op) ((op >> 4) & 0x7)
12882#define uMIPS_RS2(op) uMIPS_RS(op)
12883#define uMIPS_RS1(op) ((op >> 1) & 0x7)
12884#define uMIPS_RD5(op) ((op >> 5) & 0x1f)
12885#define uMIPS_RS5(op) (op & 0x1f)
12886
12887/* Signed immediate */
12888#define SIMM(op, start, width)                                          \
12889    ((int32_t)(((op >> start) & ((~0U) >> (32-width)))                 \
12890               << (32-width))                                           \
12891     >> (32-width))
12892/* Zero-extended immediate */
12893#define ZIMM(op, start, width) ((op >> start) & ((~0U) >> (32-width)))
12894
12895static void gen_addiur1sp(DisasContext *ctx)
12896{
12897    int rd = mmreg(uMIPS_RD(ctx->opcode));
12898
12899    gen_arith_imm(ctx, OPC_ADDIU, rd, 29, ((ctx->opcode >> 1) & 0x3f) << 2);
12900}
12901
12902static void gen_addiur2(DisasContext *ctx)
12903{
12904    static const int decoded_imm[] = { 1, 4, 8, 12, 16, 20, 24, -1 };
12905    int rd = mmreg(uMIPS_RD(ctx->opcode));
12906    int rs = mmreg(uMIPS_RS(ctx->opcode));
12907
12908    gen_arith_imm(ctx, OPC_ADDIU, rd, rs, decoded_imm[ZIMM(ctx->opcode, 1, 3)]);
12909}
12910
12911static void gen_addiusp(DisasContext *ctx)
12912{
12913    int encoded = ZIMM(ctx->opcode, 1, 9);
12914    int decoded;
12915
12916    if (encoded <= 1) {
12917        decoded = 256 + encoded;
12918    } else if (encoded <= 255) {
12919        decoded = encoded;
12920    } else if (encoded <= 509) {
12921        decoded = encoded - 512;
12922    } else {
12923        decoded = encoded - 768;
12924    }
12925
12926    gen_arith_imm(ctx, OPC_ADDIU, 29, 29, decoded << 2);
12927}
12928
12929static void gen_addius5(DisasContext *ctx)
12930{
12931    int imm = SIMM(ctx->opcode, 1, 4);
12932    int rd = (ctx->opcode >> 5) & 0x1f;
12933
12934    gen_arith_imm(ctx, OPC_ADDIU, rd, rd, imm);
12935}
12936
12937static void gen_andi16(DisasContext *ctx)
12938{
12939    static const int decoded_imm[] = { 128, 1, 2, 3, 4, 7, 8, 15, 16,
12940                                 31, 32, 63, 64, 255, 32768, 65535 };
12941    int rd = mmreg(uMIPS_RD(ctx->opcode));
12942    int rs = mmreg(uMIPS_RS(ctx->opcode));
12943    int encoded = ZIMM(ctx->opcode, 0, 4);
12944
12945    gen_logic_imm(ctx, OPC_ANDI, rd, rs, decoded_imm[encoded]);
12946}
12947
12948static void gen_ldst_multiple (DisasContext *ctx, uint32_t opc, int reglist,
12949                               int base, int16_t offset)
12950{
12951    TCGv t0, t1;
12952    TCGv_i32 t2;
12953
12954    if (ctx->hflags & MIPS_HFLAG_BMASK) {
12955        generate_exception_end(ctx, EXCP_RI);
12956        return;
12957    }
12958
12959    t0 = tcg_temp_new();
12960
12961    gen_base_offset_addr(ctx, t0, base, offset);
12962
12963    t1 = tcg_const_tl(reglist);
12964    t2 = tcg_const_i32(ctx->mem_idx);
12965
12966    save_cpu_state(ctx, 1);
12967    switch (opc) {
12968    case LWM32:
12969        gen_helper_lwm(cpu_env, t0, t1, t2);
12970        break;
12971    case SWM32:
12972        gen_helper_swm(cpu_env, t0, t1, t2);
12973        break;
12974#ifdef TARGET_MIPS64
12975    case LDM:
12976        gen_helper_ldm(cpu_env, t0, t1, t2);
12977        break;
12978    case SDM:
12979        gen_helper_sdm(cpu_env, t0, t1, t2);
12980        break;
12981#endif
12982    }
12983    tcg_temp_free(t0);
12984    tcg_temp_free(t1);
12985    tcg_temp_free_i32(t2);
12986}
12987
12988
12989static void gen_pool16c_insn(DisasContext *ctx)
12990{
12991    int rd = mmreg((ctx->opcode >> 3) & 0x7);
12992    int rs = mmreg(ctx->opcode & 0x7);
12993
12994    switch (((ctx->opcode) >> 4) & 0x3f) {
12995    case NOT16 + 0:
12996    case NOT16 + 1:
12997    case NOT16 + 2:
12998    case NOT16 + 3:
12999        gen_logic(ctx, OPC_NOR, rd, rs, 0);
13000        break;
13001    case XOR16 + 0:
13002    case XOR16 + 1:
13003    case XOR16 + 2:
13004    case XOR16 + 3:
13005        gen_logic(ctx, OPC_XOR, rd, rd, rs);
13006        break;
13007    case AND16 + 0:
13008    case AND16 + 1:
13009    case AND16 + 2:
13010    case AND16 + 3:
13011        gen_logic(ctx, OPC_AND, rd, rd, rs);
13012        break;
13013    case OR16 + 0:
13014    case OR16 + 1:
13015    case OR16 + 2:
13016    case OR16 + 3:
13017        gen_logic(ctx, OPC_OR, rd, rd, rs);
13018        break;
13019    case LWM16 + 0:
13020    case LWM16 + 1:
13021    case LWM16 + 2:
13022    case LWM16 + 3:
13023        {
13024            static const int lwm_convert[] = { 0x11, 0x12, 0x13, 0x14 };
13025            int offset = ZIMM(ctx->opcode, 0, 4);
13026
13027            gen_ldst_multiple(ctx, LWM32, lwm_convert[(ctx->opcode >> 4) & 0x3],
13028                              29, offset << 2);
13029        }
13030        break;
13031    case SWM16 + 0:
13032    case SWM16 + 1:
13033    case SWM16 + 2:
13034    case SWM16 + 3:
13035        {
13036            static const int swm_convert[] = { 0x11, 0x12, 0x13, 0x14 };
13037            int offset = ZIMM(ctx->opcode, 0, 4);
13038
13039            gen_ldst_multiple(ctx, SWM32, swm_convert[(ctx->opcode >> 4) & 0x3],
13040                              29, offset << 2);
13041        }
13042        break;
13043    case JR16 + 0:
13044    case JR16 + 1:
13045        {
13046            int reg = ctx->opcode & 0x1f;
13047
13048            gen_compute_branch(ctx, OPC_JR, 2, reg, 0, 0, 4);
13049        }
13050        break;
13051    case JRC16 + 0:
13052    case JRC16 + 1:
13053        {
13054            int reg = ctx->opcode & 0x1f;
13055            gen_compute_branch(ctx, OPC_JR, 2, reg, 0, 0, 0);
13056            /* Let normal delay slot handling in our caller take us
13057               to the branch target.  */
13058        }
13059        break;
13060    case JALR16 + 0:
13061    case JALR16 + 1:
13062        gen_compute_branch(ctx, OPC_JALR, 2, ctx->opcode & 0x1f, 31, 0, 4);
13063        ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
13064        break;
13065    case JALR16S + 0:
13066    case JALR16S + 1:
13067        gen_compute_branch(ctx, OPC_JALR, 2, ctx->opcode & 0x1f, 31, 0, 2);
13068        ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
13069        break;
13070    case MFHI16 + 0:
13071    case MFHI16 + 1:
13072        gen_HILO(ctx, OPC_MFHI, 0, uMIPS_RS5(ctx->opcode));
13073        break;
13074    case MFLO16 + 0:
13075    case MFLO16 + 1:
13076        gen_HILO(ctx, OPC_MFLO, 0, uMIPS_RS5(ctx->opcode));
13077        break;
13078    case BREAK16:
13079        generate_exception_end(ctx, EXCP_BREAK);
13080        break;
13081    case SDBBP16:
13082        if (is_uhi(extract32(ctx->opcode, 0, 4))) {
13083            gen_helper_do_semihosting(cpu_env);
13084        } else {
13085            /* XXX: not clear which exception should be raised
13086             *      when in debug mode...
13087             */
13088            check_insn(ctx, ISA_MIPS32);
13089            generate_exception_end(ctx, EXCP_DBp);
13090        }
13091        break;
13092    case JRADDIUSP + 0:
13093    case JRADDIUSP + 1:
13094        {
13095            int imm = ZIMM(ctx->opcode, 0, 5);
13096            gen_compute_branch(ctx, OPC_JR, 2, 31, 0, 0, 0);
13097            gen_arith_imm(ctx, OPC_ADDIU, 29, 29, imm << 2);
13098            /* Let normal delay slot handling in our caller take us
13099               to the branch target.  */
13100        }
13101        break;
13102    default:
13103        generate_exception_end(ctx, EXCP_RI);
13104        break;
13105    }
13106}
13107
13108static inline void gen_movep(DisasContext *ctx, int enc_dest, int enc_rt,
13109                             int enc_rs)
13110{
13111    int rd, rs, re, rt;
13112    static const int rd_enc[] = { 5, 5, 6, 4, 4, 4, 4, 4 };
13113    static const int re_enc[] = { 6, 7, 7, 21, 22, 5, 6, 7 };
13114    static const int rs_rt_enc[] = { 0, 17, 2, 3, 16, 18, 19, 20 };
13115    rd = rd_enc[enc_dest];
13116    re = re_enc[enc_dest];
13117    rs = rs_rt_enc[enc_rs];
13118    rt = rs_rt_enc[enc_rt];
13119    if (rs) {
13120        tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
13121    } else {
13122        tcg_gen_movi_tl(cpu_gpr[rd], 0);
13123    }
13124    if (rt) {
13125        tcg_gen_mov_tl(cpu_gpr[re], cpu_gpr[rt]);
13126    } else {
13127        tcg_gen_movi_tl(cpu_gpr[re], 0);
13128    }
13129}
13130
13131static void gen_pool16c_r6_insn(DisasContext *ctx)
13132{
13133    int rt = mmreg((ctx->opcode >> 7) & 0x7);
13134    int rs = mmreg((ctx->opcode >> 4) & 0x7);
13135
13136    switch (ctx->opcode & 0xf) {
13137    case R6_NOT16:
13138        gen_logic(ctx, OPC_NOR, rt, rs, 0);
13139        break;
13140    case R6_AND16:
13141        gen_logic(ctx, OPC_AND, rt, rt, rs);
13142        break;
13143    case R6_LWM16:
13144        {
13145            int lwm_converted = 0x11 + extract32(ctx->opcode, 8, 2);
13146            int offset = extract32(ctx->opcode, 4, 4);
13147            gen_ldst_multiple(ctx, LWM32, lwm_converted, 29, offset << 2);
13148        }
13149        break;
13150    case R6_JRC16: /* JRCADDIUSP */
13151        if ((ctx->opcode >> 4) & 1) {
13152            /* JRCADDIUSP */
13153            int imm = extract32(ctx->opcode, 5, 5);
13154            gen_compute_branch(ctx, OPC_JR, 2, 31, 0, 0, 0);
13155            gen_arith_imm(ctx, OPC_ADDIU, 29, 29, imm << 2);
13156        } else {
13157            /* JRC16 */
13158            int rs = extract32(ctx->opcode, 5, 5);
13159            gen_compute_branch(ctx, OPC_JR, 2, rs, 0, 0, 0);
13160        }
13161        break;
13162    case MOVEP ... MOVEP_07:
13163    case MOVEP_0C ... MOVEP_0F:
13164        {
13165            int enc_dest = uMIPS_RD(ctx->opcode);
13166            int enc_rt = uMIPS_RS2(ctx->opcode);
13167            int enc_rs = (ctx->opcode & 3) | ((ctx->opcode >> 1) & 4);
13168            gen_movep(ctx, enc_dest, enc_rt, enc_rs);
13169        }
13170        break;
13171    case R6_XOR16:
13172        gen_logic(ctx, OPC_XOR, rt, rt, rs);
13173        break;
13174    case R6_OR16:
13175        gen_logic(ctx, OPC_OR, rt, rt, rs);
13176        break;
13177    case R6_SWM16:
13178        {
13179            int swm_converted = 0x11 + extract32(ctx->opcode, 8, 2);
13180            int offset = extract32(ctx->opcode, 4, 4);
13181            gen_ldst_multiple(ctx, SWM32, swm_converted, 29, offset << 2);
13182        }
13183        break;
13184    case JALRC16: /* BREAK16, SDBBP16 */
13185        switch (ctx->opcode & 0x3f) {
13186        case JALRC16:
13187        case JALRC16 + 0x20:
13188            /* JALRC16 */
13189            gen_compute_branch(ctx, OPC_JALR, 2, (ctx->opcode >> 5) & 0x1f,
13190                               31, 0, 0);
13191            break;
13192        case R6_BREAK16:
13193            /* BREAK16 */
13194            generate_exception(ctx, EXCP_BREAK);
13195            break;
13196        case R6_SDBBP16:
13197            /* SDBBP16 */
13198            if (is_uhi(extract32(ctx->opcode, 6, 4))) {
13199                gen_helper_do_semihosting(cpu_env);
13200            } else {
13201                if (ctx->hflags & MIPS_HFLAG_SBRI) {
13202                    generate_exception(ctx, EXCP_RI);
13203                } else {
13204                    generate_exception(ctx, EXCP_DBp);
13205                }
13206            }
13207            break;
13208        }
13209        break;
13210    default:
13211        generate_exception(ctx, EXCP_RI);
13212        break;
13213    }
13214}
13215
13216static void gen_ldxs (DisasContext *ctx, int base, int index, int rd)
13217{
13218    TCGv t0 = tcg_temp_new();
13219    TCGv t1 = tcg_temp_new();
13220
13221    gen_load_gpr(t0, base);
13222
13223    if (index != 0) {
13224        gen_load_gpr(t1, index);
13225        tcg_gen_shli_tl(t1, t1, 2);
13226        gen_op_addr_add(ctx, t0, t1, t0);
13227    }
13228
13229    tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TESL);
13230    gen_store_gpr(t1, rd);
13231
13232    tcg_temp_free(t0);
13233    tcg_temp_free(t1);
13234}
13235
13236static void gen_ldst_pair (DisasContext *ctx, uint32_t opc, int rd,
13237                           int base, int16_t offset)
13238{
13239    TCGv t0, t1;
13240
13241    if (ctx->hflags & MIPS_HFLAG_BMASK || rd == 31) {
13242        generate_exception_end(ctx, EXCP_RI);
13243        return;
13244    }
13245
13246    t0 = tcg_temp_new();
13247    t1 = tcg_temp_new();
13248
13249    gen_base_offset_addr(ctx, t0, base, offset);
13250
13251    switch (opc) {
13252    case LWP:
13253        if (rd == base) {
13254            generate_exception_end(ctx, EXCP_RI);
13255            return;
13256        }
13257        tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TESL);
13258        gen_store_gpr(t1, rd);
13259        tcg_gen_movi_tl(t1, 4);
13260        gen_op_addr_add(ctx, t0, t0, t1);
13261        tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TESL);
13262        gen_store_gpr(t1, rd+1);
13263        break;
13264    case SWP:
13265        gen_load_gpr(t1, rd);
13266        tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL);
13267        tcg_gen_movi_tl(t1, 4);
13268        gen_op_addr_add(ctx, t0, t0, t1);
13269        gen_load_gpr(t1, rd+1);
13270        tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL);
13271        break;
13272#ifdef TARGET_MIPS64
13273    case LDP:
13274        if (rd == base) {
13275            generate_exception_end(ctx, EXCP_RI);
13276            return;
13277        }
13278        tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TEQ);
13279        gen_store_gpr(t1, rd);
13280        tcg_gen_movi_tl(t1, 8);
13281        gen_op_addr_add(ctx, t0, t0, t1);
13282        tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TEQ);
13283        gen_store_gpr(t1, rd+1);
13284        break;
13285    case SDP:
13286        gen_load_gpr(t1, rd);
13287        tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEQ);
13288        tcg_gen_movi_tl(t1, 8);
13289        gen_op_addr_add(ctx, t0, t0, t1);
13290        gen_load_gpr(t1, rd+1);
13291        tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEQ);
13292        break;
13293#endif
13294    }
13295    tcg_temp_free(t0);
13296    tcg_temp_free(t1);
13297}
13298
13299static void gen_sync(int stype)
13300{
13301    TCGBar tcg_mo = TCG_BAR_SC;
13302
13303    switch (stype) {
13304    case 0x4: /* SYNC_WMB */
13305        tcg_mo |= TCG_MO_ST_ST;
13306        break;
13307    case 0x10: /* SYNC_MB */
13308        tcg_mo |= TCG_MO_ALL;
13309        break;
13310    case 0x11: /* SYNC_ACQUIRE */
13311        tcg_mo |= TCG_MO_LD_LD | TCG_MO_LD_ST;
13312        break;
13313    case 0x12: /* SYNC_RELEASE */
13314        tcg_mo |= TCG_MO_ST_ST | TCG_MO_LD_ST;
13315        break;
13316    case 0x13: /* SYNC_RMB */
13317        tcg_mo |= TCG_MO_LD_LD;
13318        break;
13319    default:
13320        tcg_mo |= TCG_MO_ALL;
13321        break;
13322    }
13323
13324    tcg_gen_mb(tcg_mo);
13325}
13326
13327static void gen_pool32axf (CPUMIPSState *env, DisasContext *ctx, int rt, int rs)
13328{
13329    int extension = (ctx->opcode >> 6) & 0x3f;
13330    int minor = (ctx->opcode >> 12) & 0xf;
13331    uint32_t mips32_op;
13332
13333    switch (extension) {
13334    case TEQ:
13335        mips32_op = OPC_TEQ;
13336        goto do_trap;
13337    case TGE:
13338        mips32_op = OPC_TGE;
13339        goto do_trap;
13340    case TGEU:
13341        mips32_op = OPC_TGEU;
13342        goto do_trap;
13343    case TLT:
13344        mips32_op = OPC_TLT;
13345        goto do_trap;
13346    case TLTU:
13347        mips32_op = OPC_TLTU;
13348        goto do_trap;
13349    case TNE:
13350        mips32_op = OPC_TNE;
13351    do_trap:
13352        gen_trap(ctx, mips32_op, rs, rt, -1);
13353        break;
13354#ifndef CONFIG_USER_ONLY
13355    case MFC0:
13356    case MFC0 + 32:
13357        check_cp0_enabled(ctx);
13358        if (rt == 0) {
13359            /* Treat as NOP. */
13360            break;
13361        }
13362        gen_mfc0(ctx, cpu_gpr[rt], rs, (ctx->opcode >> 11) & 0x7);
13363        break;
13364    case MTC0:
13365    case MTC0 + 32:
13366        check_cp0_enabled(ctx);
13367        {
13368            TCGv t0 = tcg_temp_new();
13369
13370            gen_load_gpr(t0, rt);
13371            gen_mtc0(ctx, t0, rs, (ctx->opcode >> 11) & 0x7);
13372            tcg_temp_free(t0);
13373        }
13374        break;
13375#endif
13376    case 0x2a:
13377        switch (minor & 3) {
13378        case MADD_ACC:
13379            gen_muldiv(ctx, OPC_MADD, (ctx->opcode >> 14) & 3, rs, rt);
13380            break;
13381        case MADDU_ACC:
13382            gen_muldiv(ctx, OPC_MADDU, (ctx->opcode >> 14) & 3, rs, rt);
13383            break;
13384        case MSUB_ACC:
13385            gen_muldiv(ctx, OPC_MSUB, (ctx->opcode >> 14) & 3, rs, rt);
13386            break;
13387        case MSUBU_ACC:
13388            gen_muldiv(ctx, OPC_MSUBU, (ctx->opcode >> 14) & 3, rs, rt);
13389            break;
13390        default:
13391            goto pool32axf_invalid;
13392        }
13393        break;
13394    case 0x32:
13395        switch (minor & 3) {
13396        case MULT_ACC:
13397            gen_muldiv(ctx, OPC_MULT, (ctx->opcode >> 14) & 3, rs, rt);
13398            break;
13399        case MULTU_ACC:
13400            gen_muldiv(ctx, OPC_MULTU, (ctx->opcode >> 14) & 3, rs, rt);
13401            break;
13402        default:
13403            goto pool32axf_invalid;
13404        }
13405        break;
13406    case 0x2c:
13407        switch (minor) {
13408        case BITSWAP:
13409            check_insn(ctx, ISA_MIPS32R6);
13410            gen_bitswap(ctx, OPC_BITSWAP, rs, rt);
13411            break;
13412        case SEB:
13413            gen_bshfl(ctx, OPC_SEB, rs, rt);
13414            break;
13415        case SEH:
13416            gen_bshfl(ctx, OPC_SEH, rs, rt);
13417            break;
13418        case CLO:
13419            mips32_op = OPC_CLO;
13420            goto do_cl;
13421        case CLZ:
13422            mips32_op = OPC_CLZ;
13423        do_cl:
13424            check_insn(ctx, ISA_MIPS32);
13425            gen_cl(ctx, mips32_op, rt, rs);
13426            break;
13427        case RDHWR:
13428            check_insn_opc_removed(ctx, ISA_MIPS32R6);
13429            gen_rdhwr(ctx, rt, rs, 0);
13430            break;
13431        case WSBH:
13432            gen_bshfl(ctx, OPC_WSBH, rs, rt);
13433            break;
13434        case MULT:
13435            check_insn_opc_removed(ctx, ISA_MIPS32R6);
13436            mips32_op = OPC_MULT;
13437            goto do_mul;
13438        case MULTU:
13439            check_insn_opc_removed(ctx, ISA_MIPS32R6);
13440            mips32_op = OPC_MULTU;
13441            goto do_mul;
13442        case DIV:
13443            check_insn_opc_removed(ctx, ISA_MIPS32R6);
13444            mips32_op = OPC_DIV;
13445            goto do_div;
13446        case DIVU:
13447            check_insn_opc_removed(ctx, ISA_MIPS32R6);
13448            mips32_op = OPC_DIVU;
13449            goto do_div;
13450        do_div:
13451            check_insn(ctx, ISA_MIPS32);
13452            gen_muldiv(ctx, mips32_op, 0, rs, rt);
13453            break;
13454        case MADD:
13455            check_insn_opc_removed(ctx, ISA_MIPS32R6);
13456            mips32_op = OPC_MADD;
13457            goto do_mul;
13458        case MADDU:
13459            check_insn_opc_removed(ctx, ISA_MIPS32R6);
13460            mips32_op = OPC_MADDU;
13461            goto do_mul;
13462        case MSUB:
13463            check_insn_opc_removed(ctx, ISA_MIPS32R6);
13464            mips32_op = OPC_MSUB;
13465            goto do_mul;
13466        case MSUBU:
13467            check_insn_opc_removed(ctx, ISA_MIPS32R6);
13468            mips32_op = OPC_MSUBU;
13469        do_mul:
13470            check_insn(ctx, ISA_MIPS32);
13471            gen_muldiv(ctx, mips32_op, 0, rs, rt);
13472            break;
13473        default:
13474            goto pool32axf_invalid;
13475        }
13476        break;
13477    case 0x34:
13478        switch (minor) {
13479        case MFC2:
13480        case MTC2:
13481        case MFHC2:
13482        case MTHC2:
13483        case CFC2:
13484        case CTC2:
13485            generate_exception_err(ctx, EXCP_CpU, 2);
13486            break;
13487        default:
13488            goto pool32axf_invalid;
13489        }
13490        break;
13491    case 0x3c:
13492        switch (minor) {
13493        case JALR:    /* JALRC */
13494        case JALR_HB: /* JALRC_HB */
13495            if (ctx->insn_flags & ISA_MIPS32R6) {
13496                /* JALRC, JALRC_HB */
13497                gen_compute_branch(ctx, OPC_JALR, 4, rs, rt, 0, 0);
13498            } else {
13499                /* JALR, JALR_HB */
13500                gen_compute_branch(ctx, OPC_JALR, 4, rs, rt, 0, 4);
13501                ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
13502            }
13503            break;
13504        case JALRS:
13505        case JALRS_HB:
13506            check_insn_opc_removed(ctx, ISA_MIPS32R6);
13507            gen_compute_branch(ctx, OPC_JALR, 4, rs, rt, 0, 2);
13508            ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
13509            break;
13510        default:
13511            goto pool32axf_invalid;
13512        }
13513        break;
13514    case 0x05:
13515        switch (minor) {
13516        case RDPGPR:
13517            check_cp0_enabled(ctx);
13518            check_insn(ctx, ISA_MIPS32R2);
13519            gen_load_srsgpr(rs, rt);
13520            break;
13521        case WRPGPR:
13522            check_cp0_enabled(ctx);
13523            check_insn(ctx, ISA_MIPS32R2);
13524            gen_store_srsgpr(rs, rt);
13525            break;
13526        default:
13527            goto pool32axf_invalid;
13528        }
13529        break;
13530#ifndef CONFIG_USER_ONLY
13531    case 0x0d:
13532        switch (minor) {
13533        case TLBP:
13534            mips32_op = OPC_TLBP;
13535            goto do_cp0;
13536        case TLBR:
13537            mips32_op = OPC_TLBR;
13538            goto do_cp0;
13539        case TLBWI:
13540            mips32_op = OPC_TLBWI;
13541            goto do_cp0;
13542        case TLBWR:
13543            mips32_op = OPC_TLBWR;
13544            goto do_cp0;
13545        case TLBINV:
13546            mips32_op = OPC_TLBINV;
13547            goto do_cp0;
13548        case TLBINVF:
13549            mips32_op = OPC_TLBINVF;
13550            goto do_cp0;
13551        case WAIT:
13552            mips32_op = OPC_WAIT;
13553            goto do_cp0;
13554        case DERET:
13555            mips32_op = OPC_DERET;
13556            goto do_cp0;
13557        case ERET:
13558            mips32_op = OPC_ERET;
13559        do_cp0:
13560            gen_cp0(env, ctx, mips32_op, rt, rs);
13561            break;
13562        default:
13563            goto pool32axf_invalid;
13564        }
13565        break;
13566    case 0x1d:
13567        switch (minor) {
13568        case DI:
13569            check_cp0_enabled(ctx);
13570            {
13571                TCGv t0 = tcg_temp_new();
13572
13573                save_cpu_state(ctx, 1);
13574                gen_helper_di(t0, cpu_env);
13575                gen_store_gpr(t0, rs);
13576                /* Stop translation as we may have switched the execution mode */
13577                ctx->bstate = BS_STOP;
13578                tcg_temp_free(t0);
13579            }
13580            break;
13581        case EI:
13582            check_cp0_enabled(ctx);
13583            {
13584                TCGv t0 = tcg_temp_new();
13585
13586                save_cpu_state(ctx, 1);
13587                gen_helper_ei(t0, cpu_env);
13588                gen_store_gpr(t0, rs);
13589                /* BS_STOP isn't sufficient, we need to ensure we break out
13590                   of translated code to check for pending interrupts.  */
13591                gen_save_pc(ctx->pc + 4);
13592                ctx->bstate = BS_EXCP;
13593                tcg_temp_free(t0);
13594            }
13595            break;
13596        default:
13597            goto pool32axf_invalid;
13598        }
13599        break;
13600#endif
13601    case 0x2d:
13602        switch (minor) {
13603        case SYNC:
13604            gen_sync(extract32(ctx->opcode, 16, 5));
13605            break;
13606        case SYSCALL:
13607            generate_exception_end(ctx, EXCP_SYSCALL);
13608            break;
13609        case SDBBP:
13610            if (is_uhi(extract32(ctx->opcode, 16, 10))) {
13611                gen_helper_do_semihosting(cpu_env);
13612            } else {
13613                check_insn(ctx, ISA_MIPS32);
13614                if (ctx->hflags & MIPS_HFLAG_SBRI) {
13615                    generate_exception_end(ctx, EXCP_RI);
13616                } else {
13617                    generate_exception_end(ctx, EXCP_DBp);
13618                }
13619            }
13620            break;
13621        default:
13622            goto pool32axf_invalid;
13623        }
13624        break;
13625    case 0x01:
13626        switch (minor & 3) {
13627        case MFHI_ACC:
13628            gen_HILO(ctx, OPC_MFHI, minor >> 2, rs);
13629            break;
13630        case MFLO_ACC:
13631            gen_HILO(ctx, OPC_MFLO, minor >> 2, rs);
13632            break;
13633        case MTHI_ACC:
13634            gen_HILO(ctx, OPC_MTHI, minor >> 2, rs);
13635            break;
13636        case MTLO_ACC:
13637            gen_HILO(ctx, OPC_MTLO, minor >> 2, rs);
13638            break;
13639        default:
13640            goto pool32axf_invalid;
13641        }
13642        break;
13643    case 0x35:
13644        check_insn_opc_removed(ctx, ISA_MIPS32R6);
13645        switch (minor) {
13646        case MFHI32:
13647            gen_HILO(ctx, OPC_MFHI, 0, rs);
13648            break;
13649        case MFLO32:
13650            gen_HILO(ctx, OPC_MFLO, 0, rs);
13651            break;
13652        case MTHI32:
13653            gen_HILO(ctx, OPC_MTHI, 0, rs);
13654            break;
13655        case MTLO32:
13656            gen_HILO(ctx, OPC_MTLO, 0, rs);
13657            break;
13658        default:
13659            goto pool32axf_invalid;
13660        }
13661        break;
13662    default:
13663    pool32axf_invalid:
13664        MIPS_INVAL("pool32axf");
13665        generate_exception_end(ctx, EXCP_RI);
13666        break;
13667    }
13668}
13669
13670/* Values for microMIPS fmt field.  Variable-width, depending on which
13671   formats the instruction supports.  */
13672
13673enum {
13674    FMT_SD_S = 0,
13675    FMT_SD_D = 1,
13676
13677    FMT_SDPS_S = 0,
13678    FMT_SDPS_D = 1,
13679    FMT_SDPS_PS = 2,
13680
13681    FMT_SWL_S = 0,
13682    FMT_SWL_W = 1,
13683    FMT_SWL_L = 2,
13684
13685    FMT_DWL_D = 0,
13686    FMT_DWL_W = 1,
13687    FMT_DWL_L = 2
13688};
13689
13690static void gen_pool32fxf(DisasContext *ctx, int rt, int rs)
13691{
13692    int extension = (ctx->opcode >> 6) & 0x3ff;
13693    uint32_t mips32_op;
13694
13695#define FLOAT_1BIT_FMT(opc, fmt) (fmt << 8) | opc
13696#define FLOAT_2BIT_FMT(opc, fmt) (fmt << 7) | opc
13697#define COND_FLOAT_MOV(opc, cond) (cond << 7) | opc
13698
13699    switch (extension) {
13700    case FLOAT_1BIT_FMT(CFC1, 0):
13701        mips32_op = OPC_CFC1;
13702        goto do_cp1;
13703    case FLOAT_1BIT_FMT(CTC1, 0):
13704        mips32_op = OPC_CTC1;
13705        goto do_cp1;
13706    case FLOAT_1BIT_FMT(MFC1, 0):
13707        mips32_op = OPC_MFC1;
13708        goto do_cp1;
13709    case FLOAT_1BIT_FMT(MTC1, 0):
13710        mips32_op = OPC_MTC1;
13711        goto do_cp1;
13712    case FLOAT_1BIT_FMT(MFHC1, 0):
13713        mips32_op = OPC_MFHC1;
13714        goto do_cp1;
13715    case FLOAT_1BIT_FMT(MTHC1, 0):
13716        mips32_op = OPC_MTHC1;
13717    do_cp1:
13718        gen_cp1(ctx, mips32_op, rt, rs);
13719        break;
13720
13721        /* Reciprocal square root */
13722    case FLOAT_1BIT_FMT(RSQRT_FMT, FMT_SD_S):
13723        mips32_op = OPC_RSQRT_S;
13724        goto do_unaryfp;
13725    case FLOAT_1BIT_FMT(RSQRT_FMT, FMT_SD_D):
13726        mips32_op = OPC_RSQRT_D;
13727        goto do_unaryfp;
13728
13729        /* Square root */
13730    case FLOAT_1BIT_FMT(SQRT_FMT, FMT_SD_S):
13731        mips32_op = OPC_SQRT_S;
13732        goto do_unaryfp;
13733    case FLOAT_1BIT_FMT(SQRT_FMT, FMT_SD_D):
13734        mips32_op = OPC_SQRT_D;
13735        goto do_unaryfp;
13736
13737        /* Reciprocal */
13738    case FLOAT_1BIT_FMT(RECIP_FMT, FMT_SD_S):
13739        mips32_op = OPC_RECIP_S;
13740        goto do_unaryfp;
13741    case FLOAT_1BIT_FMT(RECIP_FMT, FMT_SD_D):
13742        mips32_op = OPC_RECIP_D;
13743        goto do_unaryfp;
13744
13745        /* Floor */
13746    case FLOAT_1BIT_FMT(FLOOR_L, FMT_SD_S):
13747        mips32_op = OPC_FLOOR_L_S;
13748        goto do_unaryfp;
13749    case FLOAT_1BIT_FMT(FLOOR_L, FMT_SD_D):
13750        mips32_op = OPC_FLOOR_L_D;
13751        goto do_unaryfp;
13752    case FLOAT_1BIT_FMT(FLOOR_W, FMT_SD_S):
13753        mips32_op = OPC_FLOOR_W_S;
13754        goto do_unaryfp;
13755    case FLOAT_1BIT_FMT(FLOOR_W, FMT_SD_D):
13756        mips32_op = OPC_FLOOR_W_D;
13757        goto do_unaryfp;
13758
13759        /* Ceiling */
13760    case FLOAT_1BIT_FMT(CEIL_L, FMT_SD_S):
13761        mips32_op = OPC_CEIL_L_S;
13762        goto do_unaryfp;
13763    case FLOAT_1BIT_FMT(CEIL_L, FMT_SD_D):
13764        mips32_op = OPC_CEIL_L_D;
13765        goto do_unaryfp;
13766    case FLOAT_1BIT_FMT(CEIL_W, FMT_SD_S):
13767        mips32_op = OPC_CEIL_W_S;
13768        goto do_unaryfp;
13769    case FLOAT_1BIT_FMT(CEIL_W, FMT_SD_D):
13770        mips32_op = OPC_CEIL_W_D;
13771        goto do_unaryfp;
13772
13773        /* Truncation */
13774    case FLOAT_1BIT_FMT(TRUNC_L, FMT_SD_S):
13775        mips32_op = OPC_TRUNC_L_S;
13776        goto do_unaryfp;
13777    case FLOAT_1BIT_FMT(TRUNC_L, FMT_SD_D):
13778        mips32_op = OPC_TRUNC_L_D;
13779        goto do_unaryfp;
13780    case FLOAT_1BIT_FMT(TRUNC_W, FMT_SD_S):
13781        mips32_op = OPC_TRUNC_W_S;
13782        goto do_unaryfp;
13783    case FLOAT_1BIT_FMT(TRUNC_W, FMT_SD_D):
13784        mips32_op = OPC_TRUNC_W_D;
13785        goto do_unaryfp;
13786
13787        /* Round */
13788    case FLOAT_1BIT_FMT(ROUND_L, FMT_SD_S):
13789        mips32_op = OPC_ROUND_L_S;
13790        goto do_unaryfp;
13791    case FLOAT_1BIT_FMT(ROUND_L, FMT_SD_D):
13792        mips32_op = OPC_ROUND_L_D;
13793        goto do_unaryfp;
13794    case FLOAT_1BIT_FMT(ROUND_W, FMT_SD_S):
13795        mips32_op = OPC_ROUND_W_S;
13796        goto do_unaryfp;
13797    case FLOAT_1BIT_FMT(ROUND_W, FMT_SD_D):
13798        mips32_op = OPC_ROUND_W_D;
13799        goto do_unaryfp;
13800
13801        /* Integer to floating-point conversion */
13802    case FLOAT_1BIT_FMT(CVT_L, FMT_SD_S):
13803        mips32_op = OPC_CVT_L_S;
13804        goto do_unaryfp;
13805    case FLOAT_1BIT_FMT(CVT_L, FMT_SD_D):
13806        mips32_op = OPC_CVT_L_D;
13807        goto do_unaryfp;
13808    case FLOAT_1BIT_FMT(CVT_W, FMT_SD_S):
13809        mips32_op = OPC_CVT_W_S;
13810        goto do_unaryfp;
13811    case FLOAT_1BIT_FMT(CVT_W, FMT_SD_D):
13812        mips32_op = OPC_CVT_W_D;
13813        goto do_unaryfp;
13814
13815        /* Paired-foo conversions */
13816    case FLOAT_1BIT_FMT(CVT_S_PL, 0):
13817        mips32_op = OPC_CVT_S_PL;
13818        goto do_unaryfp;
13819    case FLOAT_1BIT_FMT(CVT_S_PU, 0):
13820        mips32_op = OPC_CVT_S_PU;
13821        goto do_unaryfp;
13822    case FLOAT_1BIT_FMT(CVT_PW_PS, 0):
13823        mips32_op = OPC_CVT_PW_PS;
13824        goto do_unaryfp;
13825    case FLOAT_1BIT_FMT(CVT_PS_PW, 0):
13826        mips32_op = OPC_CVT_PS_PW;
13827        goto do_unaryfp;
13828
13829        /* Floating-point moves */
13830    case FLOAT_2BIT_FMT(MOV_FMT, FMT_SDPS_S):
13831        mips32_op = OPC_MOV_S;
13832        goto do_unaryfp;
13833    case FLOAT_2BIT_FMT(MOV_FMT, FMT_SDPS_D):
13834        mips32_op = OPC_MOV_D;
13835        goto do_unaryfp;
13836    case FLOAT_2BIT_FMT(MOV_FMT, FMT_SDPS_PS):
13837        mips32_op = OPC_MOV_PS;
13838        goto do_unaryfp;
13839
13840        /* Absolute value */
13841    case FLOAT_2BIT_FMT(ABS_FMT, FMT_SDPS_S):
13842        mips32_op = OPC_ABS_S;
13843        goto do_unaryfp;
13844    case FLOAT_2BIT_FMT(ABS_FMT, FMT_SDPS_D):
13845        mips32_op = OPC_ABS_D;
13846        goto do_unaryfp;
13847    case FLOAT_2BIT_FMT(ABS_FMT, FMT_SDPS_PS):
13848        mips32_op = OPC_ABS_PS;
13849        goto do_unaryfp;
13850
13851        /* Negation */
13852    case FLOAT_2BIT_FMT(NEG_FMT, FMT_SDPS_S):
13853        mips32_op = OPC_NEG_S;
13854        goto do_unaryfp;
13855    case FLOAT_2BIT_FMT(NEG_FMT, FMT_SDPS_D):
13856        mips32_op = OPC_NEG_D;
13857        goto do_unaryfp;
13858    case FLOAT_2BIT_FMT(NEG_FMT, FMT_SDPS_PS):
13859        mips32_op = OPC_NEG_PS;
13860        goto do_unaryfp;
13861
13862        /* Reciprocal square root step */
13863    case FLOAT_2BIT_FMT(RSQRT1_FMT, FMT_SDPS_S):
13864        mips32_op = OPC_RSQRT1_S;
13865        goto do_unaryfp;
13866    case FLOAT_2BIT_FMT(RSQRT1_FMT, FMT_SDPS_D):
13867        mips32_op = OPC_RSQRT1_D;
13868        goto do_unaryfp;
13869    case FLOAT_2BIT_FMT(RSQRT1_FMT, FMT_SDPS_PS):
13870        mips32_op = OPC_RSQRT1_PS;
13871        goto do_unaryfp;
13872
13873        /* Reciprocal step */
13874    case FLOAT_2BIT_FMT(RECIP1_FMT, FMT_SDPS_S):
13875        mips32_op = OPC_RECIP1_S;
13876        goto do_unaryfp;
13877    case FLOAT_2BIT_FMT(RECIP1_FMT, FMT_SDPS_D):
13878        mips32_op = OPC_RECIP1_S;
13879        goto do_unaryfp;
13880    case FLOAT_2BIT_FMT(RECIP1_FMT, FMT_SDPS_PS):
13881        mips32_op = OPC_RECIP1_PS;
13882        goto do_unaryfp;
13883
13884        /* Conversions from double */
13885    case FLOAT_2BIT_FMT(CVT_D, FMT_SWL_S):
13886        mips32_op = OPC_CVT_D_S;
13887        goto do_unaryfp;
13888    case FLOAT_2BIT_FMT(CVT_D, FMT_SWL_W):
13889        mips32_op = OPC_CVT_D_W;
13890        goto do_unaryfp;
13891    case FLOAT_2BIT_FMT(CVT_D, FMT_SWL_L):
13892        mips32_op = OPC_CVT_D_L;
13893        goto do_unaryfp;
13894
13895        /* Conversions from single */
13896    case FLOAT_2BIT_FMT(CVT_S, FMT_DWL_D):
13897        mips32_op = OPC_CVT_S_D;
13898        goto do_unaryfp;
13899    case FLOAT_2BIT_FMT(CVT_S, FMT_DWL_W):
13900        mips32_op = OPC_CVT_S_W;
13901        goto do_unaryfp;
13902    case FLOAT_2BIT_FMT(CVT_S, FMT_DWL_L):
13903        mips32_op = OPC_CVT_S_L;
13904    do_unaryfp:
13905        gen_farith(ctx, mips32_op, -1, rs, rt, 0);
13906        break;
13907
13908        /* Conditional moves on floating-point codes */
13909    case COND_FLOAT_MOV(MOVT, 0):
13910    case COND_FLOAT_MOV(MOVT, 1):
13911    case COND_FLOAT_MOV(MOVT, 2):
13912    case COND_FLOAT_MOV(MOVT, 3):
13913    case COND_FLOAT_MOV(MOVT, 4):
13914    case COND_FLOAT_MOV(MOVT, 5):
13915    case COND_FLOAT_MOV(MOVT, 6):
13916    case COND_FLOAT_MOV(MOVT, 7):
13917        check_insn_opc_removed(ctx, ISA_MIPS32R6);
13918        gen_movci(ctx, rt, rs, (ctx->opcode >> 13) & 0x7, 1);
13919        break;
13920    case COND_FLOAT_MOV(MOVF, 0):
13921    case COND_FLOAT_MOV(MOVF, 1):
13922    case COND_FLOAT_MOV(MOVF, 2):
13923    case COND_FLOAT_MOV(MOVF, 3):
13924    case COND_FLOAT_MOV(MOVF, 4):
13925    case COND_FLOAT_MOV(MOVF, 5):
13926    case COND_FLOAT_MOV(MOVF, 6):
13927    case COND_FLOAT_MOV(MOVF, 7):
13928        check_insn_opc_removed(ctx, ISA_MIPS32R6);
13929        gen_movci(ctx, rt, rs, (ctx->opcode >> 13) & 0x7, 0);
13930        break;
13931    default:
13932        MIPS_INVAL("pool32fxf");
13933        generate_exception_end(ctx, EXCP_RI);
13934        break;
13935    }
13936}
13937
13938static void decode_micromips32_opc(CPUMIPSState *env, DisasContext *ctx)
13939{
13940    int32_t offset;
13941    uint16_t insn;
13942    int rt, rs, rd, rr;
13943    int16_t imm;
13944    uint32_t op, minor, minor2, mips32_op;
13945    uint32_t cond, fmt, cc;
13946
13947    insn = cpu_lduw_code(env, ctx->pc + 2);
13948    ctx->opcode = (ctx->opcode << 16) | insn;
13949
13950    rt = (ctx->opcode >> 21) & 0x1f;
13951    rs = (ctx->opcode >> 16) & 0x1f;
13952    rd = (ctx->opcode >> 11) & 0x1f;
13953    rr = (ctx->opcode >> 6) & 0x1f;
13954    imm = (int16_t) ctx->opcode;
13955
13956    op = (ctx->opcode >> 26) & 0x3f;
13957    switch (op) {
13958    case POOL32A:
13959        minor = ctx->opcode & 0x3f;
13960        switch (minor) {
13961        case 0x00:
13962            minor = (ctx->opcode >> 6) & 0xf;
13963            switch (minor) {
13964            case SLL32:
13965                mips32_op = OPC_SLL;
13966                goto do_shifti;
13967            case SRA:
13968                mips32_op = OPC_SRA;
13969                goto do_shifti;
13970            case SRL32:
13971                mips32_op = OPC_SRL;
13972                goto do_shifti;
13973            case ROTR:
13974                mips32_op = OPC_ROTR;
13975            do_shifti:
13976                gen_shift_imm(ctx, mips32_op, rt, rs, rd);
13977                break;
13978            case SELEQZ:
13979                check_insn(ctx, ISA_MIPS32R6);
13980                gen_cond_move(ctx, OPC_SELEQZ, rd, rs, rt);
13981                break;
13982            case SELNEZ:
13983                check_insn(ctx, ISA_MIPS32R6);
13984                gen_cond_move(ctx, OPC_SELNEZ, rd, rs, rt);
13985                break;
13986            case R6_RDHWR:
13987                check_insn(ctx, ISA_MIPS32R6);
13988                gen_rdhwr(ctx, rt, rs, extract32(ctx->opcode, 11, 3));
13989                break;
13990            default:
13991                goto pool32a_invalid;
13992            }
13993            break;
13994        case 0x10:
13995            minor = (ctx->opcode >> 6) & 0xf;
13996            switch (minor) {
13997                /* Arithmetic */
13998            case ADD:
13999                mips32_op = OPC_ADD;
14000                goto do_arith;
14001            case ADDU32:
14002                mips32_op = OPC_ADDU;
14003                goto do_arith;
14004            case SUB:
14005                mips32_op = OPC_SUB;
14006                goto do_arith;
14007            case SUBU32:
14008                mips32_op = OPC_SUBU;
14009                goto do_arith;
14010            case MUL:
14011                check_insn_opc_removed(ctx, ISA_MIPS32R6);
14012                mips32_op = OPC_MUL;
14013            do_arith:
14014                gen_arith(ctx, mips32_op, rd, rs, rt);
14015                break;
14016                /* Shifts */
14017            case SLLV:
14018                mips32_op = OPC_SLLV;
14019                goto do_shift;
14020            case SRLV:
14021                mips32_op = OPC_SRLV;
14022                goto do_shift;
14023            case SRAV:
14024                mips32_op = OPC_SRAV;
14025                goto do_shift;
14026            case ROTRV:
14027                mips32_op = OPC_ROTRV;
14028            do_shift:
14029                gen_shift(ctx, mips32_op, rd, rs, rt);
14030                break;
14031                /* Logical operations */
14032            case AND:
14033                mips32_op = OPC_AND;
14034                goto do_logic;
14035            case OR32:
14036                mips32_op = OPC_OR;
14037                goto do_logic;
14038            case NOR:
14039                mips32_op = OPC_NOR;
14040                goto do_logic;
14041            case XOR32:
14042                mips32_op = OPC_XOR;
14043            do_logic:
14044                gen_logic(ctx, mips32_op, rd, rs, rt);
14045                break;
14046                /* Set less than */
14047            case SLT:
14048                mips32_op = OPC_SLT;
14049                goto do_slt;
14050            case SLTU:
14051                mips32_op = OPC_SLTU;
14052            do_slt:
14053                gen_slt(ctx, mips32_op, rd, rs, rt);
14054                break;
14055            default:
14056                goto pool32a_invalid;
14057            }
14058            break;
14059        case 0x18:
14060            minor = (ctx->opcode >> 6) & 0xf;
14061            switch (minor) {
14062                /* Conditional moves */
14063            case MOVN: /* MUL */
14064                if (ctx->insn_flags & ISA_MIPS32R6) {
14065                    /* MUL */
14066                    gen_r6_muldiv(ctx, R6_OPC_MUL, rd, rs, rt);
14067                } else {
14068                    /* MOVN */
14069                    gen_cond_move(ctx, OPC_MOVN, rd, rs, rt);
14070                }
14071                break;
14072            case MOVZ: /* MUH */
14073                if (ctx->insn_flags & ISA_MIPS32R6) {
14074                    /* MUH */
14075                    gen_r6_muldiv(ctx, R6_OPC_MUH, rd, rs, rt);
14076                } else {
14077                    /* MOVZ */
14078                    gen_cond_move(ctx, OPC_MOVZ, rd, rs, rt);
14079                }
14080                break;
14081            case MULU:
14082                check_insn(ctx, ISA_MIPS32R6);
14083                gen_r6_muldiv(ctx, R6_OPC_MULU, rd, rs, rt);
14084                break;
14085            case MUHU:
14086                check_insn(ctx, ISA_MIPS32R6);
14087                gen_r6_muldiv(ctx, R6_OPC_MUHU, rd, rs, rt);
14088                break;
14089            case LWXS: /* DIV */
14090                if (ctx->insn_flags & ISA_MIPS32R6) {
14091                    /* DIV */
14092                    gen_r6_muldiv(ctx, R6_OPC_DIV, rd, rs, rt);
14093                } else {
14094                    /* LWXS */
14095                    gen_ldxs(ctx, rs, rt, rd);
14096                }
14097                break;
14098            case MOD:
14099                check_insn(ctx, ISA_MIPS32R6);
14100                gen_r6_muldiv(ctx, R6_OPC_MOD, rd, rs, rt);
14101                break;
14102            case R6_DIVU:
14103                check_insn(ctx, ISA_MIPS32R6);
14104                gen_r6_muldiv(ctx, R6_OPC_DIVU, rd, rs, rt);
14105                break;
14106            case MODU:
14107                check_insn(ctx, ISA_MIPS32R6);
14108                gen_r6_muldiv(ctx, R6_OPC_MODU, rd, rs, rt);
14109                break;
14110            default:
14111                goto pool32a_invalid;
14112            }
14113            break;
14114        case INS:
14115            gen_bitops(ctx, OPC_INS, rt, rs, rr, rd);
14116            return;
14117        case LSA:
14118            check_insn(ctx, ISA_MIPS32R6);
14119            gen_lsa(ctx, OPC_LSA, rd, rs, rt,
14120                    extract32(ctx->opcode, 9, 2));
14121            break;
14122        case ALIGN:
14123            check_insn(ctx, ISA_MIPS32R6);
14124            gen_align(ctx, OPC_ALIGN, rd, rs, rt,
14125                      extract32(ctx->opcode, 9, 2));
14126            break;
14127        case EXT:
14128            gen_bitops(ctx, OPC_EXT, rt, rs, rr, rd);
14129            return;
14130        case POOL32AXF:
14131            gen_pool32axf(env, ctx, rt, rs);
14132            break;
14133        case BREAK32:
14134            generate_exception_end(ctx, EXCP_BREAK);
14135            break;
14136        case SIGRIE:
14137            check_insn(ctx, ISA_MIPS32R6);
14138            generate_exception_end(ctx, EXCP_RI);
14139            break;
14140        default:
14141        pool32a_invalid:
14142                MIPS_INVAL("pool32a");
14143                generate_exception_end(ctx, EXCP_RI);
14144                break;
14145        }
14146        break;
14147    case POOL32B:
14148        minor = (ctx->opcode >> 12) & 0xf;
14149        switch (minor) {
14150        case CACHE:
14151            check_cp0_enabled(ctx);
14152            if (ctx->hflags & MIPS_HFLAG_ITC_CACHE) {
14153                gen_cache_operation(ctx, rt, rs, imm);
14154            }
14155            break;
14156        case LWC2:
14157        case SWC2:
14158            /* COP2: Not implemented. */
14159            generate_exception_err(ctx, EXCP_CpU, 2);
14160            break;
14161#ifdef TARGET_MIPS64
14162        case LDP:
14163        case SDP:
14164            check_insn(ctx, ISA_MIPS3);
14165            check_mips_64(ctx);
14166            /* Fallthrough */
14167#endif
14168        case LWP:
14169        case SWP:
14170            gen_ldst_pair(ctx, minor, rt, rs, SIMM(ctx->opcode, 0, 12));
14171            break;
14172#ifdef TARGET_MIPS64
14173        case LDM:
14174        case SDM:
14175            check_insn(ctx, ISA_MIPS3);
14176            check_mips_64(ctx);
14177            /* Fallthrough */
14178#endif
14179        case LWM32:
14180        case SWM32:
14181            gen_ldst_multiple(ctx, minor, rt, rs, SIMM(ctx->opcode, 0, 12));
14182            break;
14183        default:
14184            MIPS_INVAL("pool32b");
14185            generate_exception_end(ctx, EXCP_RI);
14186            break;
14187        }
14188        break;
14189    case POOL32F:
14190        if (ctx->CP0_Config1 & (1 << CP0C1_FP)) {
14191            minor = ctx->opcode & 0x3f;
14192            check_cp1_enabled(ctx);
14193            switch (minor) {
14194            case ALNV_PS:
14195                check_insn_opc_removed(ctx, ISA_MIPS32R6);
14196                mips32_op = OPC_ALNV_PS;
14197                goto do_madd;
14198            case MADD_S:
14199                check_insn_opc_removed(ctx, ISA_MIPS32R6);
14200                mips32_op = OPC_MADD_S;
14201                goto do_madd;
14202            case MADD_D:
14203                check_insn_opc_removed(ctx, ISA_MIPS32R6);
14204                mips32_op = OPC_MADD_D;
14205                goto do_madd;
14206            case MADD_PS:
14207                check_insn_opc_removed(ctx, ISA_MIPS32R6);
14208                mips32_op = OPC_MADD_PS;
14209                goto do_madd;
14210            case MSUB_S:
14211                check_insn_opc_removed(ctx, ISA_MIPS32R6);
14212                mips32_op = OPC_MSUB_S;
14213                goto do_madd;
14214            case MSUB_D:
14215                check_insn_opc_removed(ctx, ISA_MIPS32R6);
14216                mips32_op = OPC_MSUB_D;
14217                goto do_madd;
14218            case MSUB_PS:
14219                check_insn_opc_removed(ctx, ISA_MIPS32R6);
14220                mips32_op = OPC_MSUB_PS;
14221                goto do_madd;
14222            case NMADD_S:
14223                check_insn_opc_removed(ctx, ISA_MIPS32R6);
14224                mips32_op = OPC_NMADD_S;
14225                goto do_madd;
14226            case NMADD_D:
14227                check_insn_opc_removed(ctx, ISA_MIPS32R6);
14228                mips32_op = OPC_NMADD_D;
14229                goto do_madd;
14230            case NMADD_PS:
14231                check_insn_opc_removed(ctx, ISA_MIPS32R6);
14232                mips32_op = OPC_NMADD_PS;
14233                goto do_madd;
14234            case NMSUB_S:
14235                check_insn_opc_removed(ctx, ISA_MIPS32R6);
14236                mips32_op = OPC_NMSUB_S;
14237                goto do_madd;
14238            case NMSUB_D:
14239                check_insn_opc_removed(ctx, ISA_MIPS32R6);
14240                mips32_op = OPC_NMSUB_D;
14241                goto do_madd;
14242            case NMSUB_PS:
14243                check_insn_opc_removed(ctx, ISA_MIPS32R6);
14244                mips32_op = OPC_NMSUB_PS;
14245            do_madd:
14246                gen_flt3_arith(ctx, mips32_op, rd, rr, rs, rt);
14247                break;
14248            case CABS_COND_FMT:
14249                check_insn_opc_removed(ctx, ISA_MIPS32R6);
14250                cond = (ctx->opcode >> 6) & 0xf;
14251                cc = (ctx->opcode >> 13) & 0x7;
14252                fmt = (ctx->opcode >> 10) & 0x3;
14253                switch (fmt) {
14254                case 0x0:
14255                    gen_cmpabs_s(ctx, cond, rt, rs, cc);
14256                    break;
14257                case 0x1:
14258                    gen_cmpabs_d(ctx, cond, rt, rs, cc);
14259                    break;
14260                case 0x2:
14261                    gen_cmpabs_ps(ctx, cond, rt, rs, cc);
14262                    break;
14263                default:
14264                    goto pool32f_invalid;
14265                }
14266                break;
14267            case C_COND_FMT:
14268                check_insn_opc_removed(ctx, ISA_MIPS32R6);
14269                cond = (ctx->opcode >> 6) & 0xf;
14270                cc = (ctx->opcode >> 13) & 0x7;
14271                fmt = (ctx->opcode >> 10) & 0x3;
14272                switch (fmt) {
14273                case 0x0:
14274                    gen_cmp_s(ctx, cond, rt, rs, cc);
14275                    break;
14276                case 0x1:
14277                    gen_cmp_d(ctx, cond, rt, rs, cc);
14278                    break;
14279                case 0x2:
14280                    gen_cmp_ps(ctx, cond, rt, rs, cc);
14281                    break;
14282                default:
14283                    goto pool32f_invalid;
14284                }
14285                break;
14286            case CMP_CONDN_S:
14287                check_insn(ctx, ISA_MIPS32R6);
14288                gen_r6_cmp_s(ctx, (ctx->opcode >> 6) & 0x1f, rt, rs, rd);
14289                break;
14290            case CMP_CONDN_D:
14291                check_insn(ctx, ISA_MIPS32R6);
14292                gen_r6_cmp_d(ctx, (ctx->opcode >> 6) & 0x1f, rt, rs, rd);
14293                break;
14294            case POOL32FXF:
14295                gen_pool32fxf(ctx, rt, rs);
14296                break;
14297            case 0x00:
14298                /* PLL foo */
14299                switch ((ctx->opcode >> 6) & 0x7) {
14300                case PLL_PS:
14301                    mips32_op = OPC_PLL_PS;
14302                    goto do_ps;
14303                case PLU_PS:
14304                    mips32_op = OPC_PLU_PS;
14305                    goto do_ps;
14306                case PUL_PS:
14307                    mips32_op = OPC_PUL_PS;
14308                    goto do_ps;
14309                case PUU_PS:
14310                    mips32_op = OPC_PUU_PS;
14311                    goto do_ps;
14312                case CVT_PS_S:
14313                    check_insn_opc_removed(ctx, ISA_MIPS32R6);
14314                    mips32_op = OPC_CVT_PS_S;
14315                do_ps:
14316                    gen_farith(ctx, mips32_op, rt, rs, rd, 0);
14317                    break;
14318                default:
14319                    goto pool32f_invalid;
14320                }
14321                break;
14322            case MIN_FMT:
14323                check_insn(ctx, ISA_MIPS32R6);
14324                switch ((ctx->opcode >> 9) & 0x3) {
14325                case FMT_SDPS_S:
14326                    gen_farith(ctx, OPC_MIN_S, rt, rs, rd, 0);
14327                    break;
14328                case FMT_SDPS_D:
14329                    gen_farith(ctx, OPC_MIN_D, rt, rs, rd, 0);
14330                    break;
14331                default:
14332                    goto pool32f_invalid;
14333                }
14334                break;
14335            case 0x08:
14336                /* [LS][WDU]XC1 */
14337                switch ((ctx->opcode >> 6) & 0x7) {
14338                case LWXC1:
14339                    check_insn_opc_removed(ctx, ISA_MIPS32R6);
14340                    mips32_op = OPC_LWXC1;
14341                    goto do_ldst_cp1;
14342                case SWXC1:
14343                    check_insn_opc_removed(ctx, ISA_MIPS32R6);
14344                    mips32_op = OPC_SWXC1;
14345                    goto do_ldst_cp1;
14346                case LDXC1:
14347                    check_insn_opc_removed(ctx, ISA_MIPS32R6);
14348                    mips32_op = OPC_LDXC1;
14349                    goto do_ldst_cp1;
14350                case SDXC1:
14351                    check_insn_opc_removed(ctx, ISA_MIPS32R6);
14352                    mips32_op = OPC_SDXC1;
14353                    goto do_ldst_cp1;
14354                case LUXC1:
14355                    check_insn_opc_removed(ctx, ISA_MIPS32R6);
14356                    mips32_op = OPC_LUXC1;
14357                    goto do_ldst_cp1;
14358                case SUXC1:
14359                    check_insn_opc_removed(ctx, ISA_MIPS32R6);
14360                    mips32_op = OPC_SUXC1;
14361                do_ldst_cp1:
14362                    gen_flt3_ldst(ctx, mips32_op, rd, rd, rt, rs);
14363                    break;
14364                default:
14365                    goto pool32f_invalid;
14366                }
14367                break;
14368            case MAX_FMT:
14369                check_insn(ctx, ISA_MIPS32R6);
14370                switch ((ctx->opcode >> 9) & 0x3) {
14371                case FMT_SDPS_S:
14372                    gen_farith(ctx, OPC_MAX_S, rt, rs, rd, 0);
14373                    break;
14374                case FMT_SDPS_D:
14375                    gen_farith(ctx, OPC_MAX_D, rt, rs, rd, 0);
14376                    break;
14377                default:
14378                    goto pool32f_invalid;
14379                }
14380                break;
14381            case 0x18:
14382                /* 3D insns */
14383                check_insn_opc_removed(ctx, ISA_MIPS32R6);
14384                fmt = (ctx->opcode >> 9) & 0x3;
14385                switch ((ctx->opcode >> 6) & 0x7) {
14386                case RSQRT2_FMT:
14387                    switch (fmt) {
14388                    case FMT_SDPS_S:
14389                        mips32_op = OPC_RSQRT2_S;
14390                        goto do_3d;
14391                    case FMT_SDPS_D:
14392                        mips32_op = OPC_RSQRT2_D;
14393                        goto do_3d;
14394                    case FMT_SDPS_PS:
14395                        mips32_op = OPC_RSQRT2_PS;
14396                        goto do_3d;
14397                    default:
14398                        goto pool32f_invalid;
14399                    }
14400                    break;
14401                case RECIP2_FMT:
14402                    switch (fmt) {
14403                    case FMT_SDPS_S:
14404                        mips32_op = OPC_RECIP2_S;
14405                        goto do_3d;
14406                    case FMT_SDPS_D:
14407                        mips32_op = OPC_RECIP2_D;
14408                        goto do_3d;
14409                    case FMT_SDPS_PS:
14410                        mips32_op = OPC_RECIP2_PS;
14411                        goto do_3d;
14412                    default:
14413                        goto pool32f_invalid;
14414                    }
14415                    break;
14416                case ADDR_PS:
14417                    mips32_op = OPC_ADDR_PS;
14418                    goto do_3d;
14419                case MULR_PS:
14420                    mips32_op = OPC_MULR_PS;
14421                do_3d:
14422                    gen_farith(ctx, mips32_op, rt, rs, rd, 0);
14423                    break;
14424                default:
14425                    goto pool32f_invalid;
14426                }
14427                break;
14428            case 0x20:
14429                /* MOV[FT].fmt, PREFX, RINT.fmt, CLASS.fmt*/
14430                cc = (ctx->opcode >> 13) & 0x7;
14431                fmt = (ctx->opcode >> 9) & 0x3;
14432                switch ((ctx->opcode >> 6) & 0x7) {
14433                case MOVF_FMT: /* RINT_FMT */
14434                    if (ctx->insn_flags & ISA_MIPS32R6) {
14435                        /* RINT_FMT */
14436                        switch (fmt) {
14437                        case FMT_SDPS_S:
14438                            gen_farith(ctx, OPC_RINT_S, 0, rt, rs, 0);
14439                            break;
14440                        case FMT_SDPS_D:
14441                            gen_farith(ctx, OPC_RINT_D, 0, rt, rs, 0);
14442                            break;
14443                        default:
14444                            goto pool32f_invalid;
14445                        }
14446                    } else {
14447                        /* MOVF_FMT */
14448                        switch (fmt) {
14449                        case FMT_SDPS_S:
14450                            gen_movcf_s(ctx, rs, rt, cc, 0);
14451                            break;
14452                        case FMT_SDPS_D:
14453                            gen_movcf_d(ctx, rs, rt, cc, 0);
14454                            break;
14455                        case FMT_SDPS_PS:
14456                            check_ps(ctx);
14457                            gen_movcf_ps(ctx, rs, rt, cc, 0);
14458                            break;
14459                        default:
14460                            goto pool32f_invalid;
14461                        }
14462                    }
14463                    break;
14464                case MOVT_FMT: /* CLASS_FMT */
14465                    if (ctx->insn_flags & ISA_MIPS32R6) {
14466                        /* CLASS_FMT */
14467                        switch (fmt) {
14468                        case FMT_SDPS_S:
14469                            gen_farith(ctx, OPC_CLASS_S, 0, rt, rs, 0);
14470                            break;
14471                        case FMT_SDPS_D:
14472                            gen_farith(ctx, OPC_CLASS_D, 0, rt, rs, 0);
14473                            break;
14474                        default:
14475                            goto pool32f_invalid;
14476                        }
14477                    } else {
14478                        /* MOVT_FMT */
14479                        switch (fmt) {
14480                        case FMT_SDPS_S:
14481                            gen_movcf_s(ctx, rs, rt, cc, 1);
14482                            break;
14483                        case FMT_SDPS_D:
14484                            gen_movcf_d(ctx, rs, rt, cc, 1);
14485                            break;
14486                        case FMT_SDPS_PS:
14487                            check_ps(ctx);
14488                            gen_movcf_ps(ctx, rs, rt, cc, 1);
14489                            break;
14490                        default:
14491                            goto pool32f_invalid;
14492                        }
14493                    }
14494                    break;
14495                case PREFX:
14496                    check_insn_opc_removed(ctx, ISA_MIPS32R6);
14497                    break;
14498                default:
14499                    goto pool32f_invalid;
14500                }
14501                break;
14502#define FINSN_3ARG_SDPS(prfx)                           \
14503                switch ((ctx->opcode >> 8) & 0x3) {     \
14504                case FMT_SDPS_S:                        \
14505                    mips32_op = OPC_##prfx##_S;         \
14506                    goto do_fpop;                       \
14507                case FMT_SDPS_D:                        \
14508                    mips32_op = OPC_##prfx##_D;         \
14509                    goto do_fpop;                       \
14510                case FMT_SDPS_PS:                       \
14511                    check_ps(ctx);                      \
14512                    mips32_op = OPC_##prfx##_PS;        \
14513                    goto do_fpop;                       \
14514                default:                                \
14515                    goto pool32f_invalid;               \
14516                }
14517            case MINA_FMT:
14518                check_insn(ctx, ISA_MIPS32R6);
14519                switch ((ctx->opcode >> 9) & 0x3) {
14520                case FMT_SDPS_S:
14521                    gen_farith(ctx, OPC_MINA_S, rt, rs, rd, 0);
14522                    break;
14523                case FMT_SDPS_D:
14524                    gen_farith(ctx, OPC_MINA_D, rt, rs, rd, 0);
14525                    break;
14526                default:
14527                    goto pool32f_invalid;
14528                }
14529                break;
14530            case MAXA_FMT:
14531                check_insn(ctx, ISA_MIPS32R6);
14532                switch ((ctx->opcode >> 9) & 0x3) {
14533                case FMT_SDPS_S:
14534                    gen_farith(ctx, OPC_MAXA_S, rt, rs, rd, 0);
14535                    break;
14536                case FMT_SDPS_D:
14537                    gen_farith(ctx, OPC_MAXA_D, rt, rs, rd, 0);
14538                    break;
14539                default:
14540                    goto pool32f_invalid;
14541                }
14542                break;
14543            case 0x30:
14544                /* regular FP ops */
14545                switch ((ctx->opcode >> 6) & 0x3) {
14546                case ADD_FMT:
14547                    FINSN_3ARG_SDPS(ADD);
14548                    break;
14549                case SUB_FMT:
14550                    FINSN_3ARG_SDPS(SUB);
14551                    break;
14552                case MUL_FMT:
14553                    FINSN_3ARG_SDPS(MUL);
14554                    break;
14555                case DIV_FMT:
14556                    fmt = (ctx->opcode >> 8) & 0x3;
14557                    if (fmt == 1) {
14558                        mips32_op = OPC_DIV_D;
14559                    } else if (fmt == 0) {
14560                        mips32_op = OPC_DIV_S;
14561                    } else {
14562                        goto pool32f_invalid;
14563                    }
14564                    goto do_fpop;
14565                default:
14566                    goto pool32f_invalid;
14567                }
14568                break;
14569            case 0x38:
14570                /* cmovs */
14571                switch ((ctx->opcode >> 6) & 0x7) {
14572                case MOVN_FMT: /* SELNEZ_FMT */
14573                    if (ctx->insn_flags & ISA_MIPS32R6) {
14574                        /* SELNEZ_FMT */
14575                        switch ((ctx->opcode >> 9) & 0x3) {
14576                        case FMT_SDPS_S:
14577                            gen_sel_s(ctx, OPC_SELNEZ_S, rd, rt, rs);
14578                            break;
14579                        case FMT_SDPS_D:
14580                            gen_sel_d(ctx, OPC_SELNEZ_D, rd, rt, rs);
14581                            break;
14582                        default:
14583                            goto pool32f_invalid;
14584                        }
14585                    } else {
14586                        /* MOVN_FMT */
14587                        FINSN_3ARG_SDPS(MOVN);
14588                    }
14589                    break;
14590                case MOVN_FMT_04:
14591                    check_insn_opc_removed(ctx, ISA_MIPS32R6);
14592                    FINSN_3ARG_SDPS(MOVN);
14593                    break;
14594                case MOVZ_FMT: /* SELEQZ_FMT */
14595                    if (ctx->insn_flags & ISA_MIPS32R6) {
14596                        /* SELEQZ_FMT */
14597                        switch ((ctx->opcode >> 9) & 0x3) {
14598                        case FMT_SDPS_S:
14599                            gen_sel_s(ctx, OPC_SELEQZ_S, rd, rt, rs);
14600                            break;
14601                        case FMT_SDPS_D:
14602                            gen_sel_d(ctx, OPC_SELEQZ_D, rd, rt, rs);
14603                            break;
14604                        default:
14605                            goto pool32f_invalid;
14606                        }
14607                    } else {
14608                        /* MOVZ_FMT */
14609                        FINSN_3ARG_SDPS(MOVZ);
14610                    }
14611                    break;
14612                case MOVZ_FMT_05:
14613                    check_insn_opc_removed(ctx, ISA_MIPS32R6);
14614                    FINSN_3ARG_SDPS(MOVZ);
14615                    break;
14616                case SEL_FMT:
14617                    check_insn(ctx, ISA_MIPS32R6);
14618                    switch ((ctx->opcode >> 9) & 0x3) {
14619                    case FMT_SDPS_S:
14620                        gen_sel_s(ctx, OPC_SEL_S, rd, rt, rs);
14621                        break;
14622                    case FMT_SDPS_D:
14623                        gen_sel_d(ctx, OPC_SEL_D, rd, rt, rs);
14624                        break;
14625                    default:
14626                        goto pool32f_invalid;
14627                    }
14628                    break;
14629                case MADDF_FMT:
14630                    check_insn(ctx, ISA_MIPS32R6);
14631                    switch ((ctx->opcode >> 9) & 0x3) {
14632                    case FMT_SDPS_S:
14633                        mips32_op = OPC_MADDF_S;
14634                        goto do_fpop;
14635                    case FMT_SDPS_D:
14636                        mips32_op = OPC_MADDF_D;
14637                        goto do_fpop;
14638                    default:
14639                        goto pool32f_invalid;
14640                    }
14641                    break;
14642                case MSUBF_FMT:
14643                    check_insn(ctx, ISA_MIPS32R6);
14644                    switch ((ctx->opcode >> 9) & 0x3) {
14645                    case FMT_SDPS_S:
14646                        mips32_op = OPC_MSUBF_S;
14647                        goto do_fpop;
14648                    case FMT_SDPS_D:
14649                        mips32_op = OPC_MSUBF_D;
14650                        goto do_fpop;
14651                    default:
14652                        goto pool32f_invalid;
14653                    }
14654                    break;
14655                default:
14656                    goto pool32f_invalid;
14657                }
14658                break;
14659            do_fpop:
14660                gen_farith(ctx, mips32_op, rt, rs, rd, 0);
14661                break;
14662            default:
14663            pool32f_invalid:
14664                MIPS_INVAL("pool32f");
14665                generate_exception_end(ctx, EXCP_RI);
14666                break;
14667            }
14668        } else {
14669            generate_exception_err(ctx, EXCP_CpU, 1);
14670        }
14671        break;
14672    case POOL32I:
14673        minor = (ctx->opcode >> 21) & 0x1f;
14674        switch (minor) {
14675        case BLTZ:
14676            check_insn_opc_removed(ctx, ISA_MIPS32R6);
14677            gen_compute_branch(ctx, OPC_BLTZ, 4, rs, -1, imm << 1, 4);
14678            break;
14679        case BLTZAL:
14680            check_insn_opc_removed(ctx, ISA_MIPS32R6);
14681            gen_compute_branch(ctx, OPC_BLTZAL, 4, rs, -1, imm << 1, 4);
14682            ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
14683            break;
14684        case BLTZALS:
14685            check_insn_opc_removed(ctx, ISA_MIPS32R6);
14686            gen_compute_branch(ctx, OPC_BLTZAL, 4, rs, -1, imm << 1, 2);
14687            ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
14688            break;
14689        case BGEZ:
14690            check_insn_opc_removed(ctx, ISA_MIPS32R6);
14691            gen_compute_branch(ctx, OPC_BGEZ, 4, rs, -1, imm << 1, 4);
14692            break;
14693        case BGEZAL:
14694            check_insn_opc_removed(ctx, ISA_MIPS32R6);
14695            gen_compute_branch(ctx, OPC_BGEZAL, 4, rs, -1, imm << 1, 4);
14696            ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
14697            break;
14698        case BGEZALS:
14699            check_insn_opc_removed(ctx, ISA_MIPS32R6);
14700            gen_compute_branch(ctx, OPC_BGEZAL, 4, rs, -1, imm << 1, 2);
14701            ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
14702            break;
14703        case BLEZ:
14704            check_insn_opc_removed(ctx, ISA_MIPS32R6);
14705            gen_compute_branch(ctx, OPC_BLEZ, 4, rs, -1, imm << 1, 4);
14706            break;
14707        case BGTZ:
14708            check_insn_opc_removed(ctx, ISA_MIPS32R6);
14709            gen_compute_branch(ctx, OPC_BGTZ, 4, rs, -1, imm << 1, 4);
14710            break;
14711
14712            /* Traps */
14713        case TLTI: /* BC1EQZC */
14714            if (ctx->insn_flags & ISA_MIPS32R6) {
14715                /* BC1EQZC */
14716                check_cp1_enabled(ctx);
14717                gen_compute_branch1_r6(ctx, OPC_BC1EQZ, rs, imm << 1, 0);
14718            } else {
14719                /* TLTI */
14720                mips32_op = OPC_TLTI;
14721                goto do_trapi;
14722            }
14723            break;
14724        case TGEI: /* BC1NEZC */
14725            if (ctx->insn_flags & ISA_MIPS32R6) {
14726                /* BC1NEZC */
14727                check_cp1_enabled(ctx);
14728                gen_compute_branch1_r6(ctx, OPC_BC1NEZ, rs, imm << 1, 0);
14729            } else {
14730                /* TGEI */
14731                mips32_op = OPC_TGEI;
14732                goto do_trapi;
14733            }
14734            break;
14735        case TLTIU:
14736            check_insn_opc_removed(ctx, ISA_MIPS32R6);
14737            mips32_op = OPC_TLTIU;
14738            goto do_trapi;
14739        case TGEIU:
14740            check_insn_opc_removed(ctx, ISA_MIPS32R6);
14741            mips32_op = OPC_TGEIU;
14742            goto do_trapi;
14743        case TNEI: /* SYNCI */
14744            if (ctx->insn_flags & ISA_MIPS32R6) {
14745                /* SYNCI */
14746                /* Break the TB to be able to sync copied instructions
14747                   immediately */
14748                ctx->bstate = BS_STOP;
14749            } else {
14750                /* TNEI */
14751                mips32_op = OPC_TNEI;
14752                goto do_trapi;
14753            }
14754            break;
14755        case TEQI:
14756            check_insn_opc_removed(ctx, ISA_MIPS32R6);
14757            mips32_op = OPC_TEQI;
14758        do_trapi:
14759            gen_trap(ctx, mips32_op, rs, -1, imm);
14760            break;
14761
14762        case BNEZC:
14763        case BEQZC:
14764            check_insn_opc_removed(ctx, ISA_MIPS32R6);
14765            gen_compute_branch(ctx, minor == BNEZC ? OPC_BNE : OPC_BEQ,
14766                               4, rs, 0, imm << 1, 0);
14767            /* Compact branches don't have a delay slot, so just let
14768               the normal delay slot handling take us to the branch
14769               target. */
14770            break;
14771        case LUI:
14772            check_insn_opc_removed(ctx, ISA_MIPS32R6);
14773            gen_logic_imm(ctx, OPC_LUI, rs, 0, imm);
14774            break;
14775        case SYNCI:
14776            check_insn_opc_removed(ctx, ISA_MIPS32R6);
14777            /* Break the TB to be able to sync copied instructions
14778               immediately */
14779            ctx->bstate = BS_STOP;
14780            break;
14781        case BC2F:
14782        case BC2T:
14783            check_insn_opc_removed(ctx, ISA_MIPS32R6);
14784            /* COP2: Not implemented. */
14785            generate_exception_err(ctx, EXCP_CpU, 2);
14786            break;
14787        case BC1F:
14788            check_insn_opc_removed(ctx, ISA_MIPS32R6);
14789            mips32_op = (ctx->opcode & (1 << 16)) ? OPC_BC1FANY2 : OPC_BC1F;
14790            goto do_cp1branch;
14791        case BC1T:
14792            check_insn_opc_removed(ctx, ISA_MIPS32R6);
14793            mips32_op = (ctx->opcode & (1 << 16)) ? OPC_BC1TANY2 : OPC_BC1T;
14794            goto do_cp1branch;
14795        case BC1ANY4F:
14796            check_insn_opc_removed(ctx, ISA_MIPS32R6);
14797            mips32_op = OPC_BC1FANY4;
14798            goto do_cp1mips3d;
14799        case BC1ANY4T:
14800            check_insn_opc_removed(ctx, ISA_MIPS32R6);
14801            mips32_op = OPC_BC1TANY4;
14802        do_cp1mips3d:
14803            check_cop1x(ctx);
14804            check_insn(ctx, ASE_MIPS3D);
14805            /* Fall through */
14806        do_cp1branch:
14807            if (env->CP0_Config1 & (1 << CP0C1_FP)) {
14808                check_cp1_enabled(ctx);
14809                gen_compute_branch1(ctx, mips32_op,
14810                                    (ctx->opcode >> 18) & 0x7, imm << 1);
14811            } else {
14812                generate_exception_err(ctx, EXCP_CpU, 1);
14813            }
14814            break;
14815        case BPOSGE64:
14816        case BPOSGE32:
14817            /* MIPS DSP: not implemented */
14818            /* Fall through */
14819        default:
14820            MIPS_INVAL("pool32i");
14821            generate_exception_end(ctx, EXCP_RI);
14822            break;
14823        }
14824        break;
14825    case POOL32C:
14826        minor = (ctx->opcode >> 12) & 0xf;
14827        offset = sextract32(ctx->opcode, 0,
14828                            (ctx->insn_flags & ISA_MIPS32R6) ? 9 : 12);
14829        switch (minor) {
14830        case LWL:
14831            check_insn_opc_removed(ctx, ISA_MIPS32R6);
14832            mips32_op = OPC_LWL;
14833            goto do_ld_lr;
14834        case SWL:
14835            check_insn_opc_removed(ctx, ISA_MIPS32R6);
14836            mips32_op = OPC_SWL;
14837            goto do_st_lr;
14838        case LWR:
14839            check_insn_opc_removed(ctx, ISA_MIPS32R6);
14840            mips32_op = OPC_LWR;
14841            goto do_ld_lr;
14842        case SWR:
14843            check_insn_opc_removed(ctx, ISA_MIPS32R6);
14844            mips32_op = OPC_SWR;
14845            goto do_st_lr;
14846#if defined(TARGET_MIPS64)
14847        case LDL:
14848            check_insn(ctx, ISA_MIPS3);
14849            check_mips_64(ctx);
14850            check_insn_opc_removed(ctx, ISA_MIPS32R6);
14851            mips32_op = OPC_LDL;
14852            goto do_ld_lr;
14853        case SDL:
14854            check_insn(ctx, ISA_MIPS3);
14855            check_mips_64(ctx);
14856            check_insn_opc_removed(ctx, ISA_MIPS32R6);
14857            mips32_op = OPC_SDL;
14858            goto do_st_lr;
14859        case LDR:
14860            check_insn(ctx, ISA_MIPS3);
14861            check_mips_64(ctx);
14862            check_insn_opc_removed(ctx, ISA_MIPS32R6);
14863            mips32_op = OPC_LDR;
14864            goto do_ld_lr;
14865        case SDR:
14866            check_insn(ctx, ISA_MIPS3);
14867            check_mips_64(ctx);
14868            check_insn_opc_removed(ctx, ISA_MIPS32R6);
14869            mips32_op = OPC_SDR;
14870            goto do_st_lr;
14871        case LWU:
14872            check_insn(ctx, ISA_MIPS3);
14873            check_mips_64(ctx);
14874            mips32_op = OPC_LWU;
14875            goto do_ld_lr;
14876        case LLD:
14877            check_insn(ctx, ISA_MIPS3);
14878            check_mips_64(ctx);
14879            mips32_op = OPC_LLD;
14880            goto do_ld_lr;
14881#endif
14882        case LL:
14883            mips32_op = OPC_LL;
14884            goto do_ld_lr;
14885        do_ld_lr:
14886            gen_ld(ctx, mips32_op, rt, rs, offset);
14887            break;
14888        do_st_lr:
14889            gen_st(ctx, mips32_op, rt, rs, offset);
14890            break;
14891        case SC:
14892            gen_st_cond(ctx, OPC_SC, rt, rs, offset);
14893            break;
14894#if defined(TARGET_MIPS64)
14895        case SCD:
14896            check_insn(ctx, ISA_MIPS3);
14897            check_mips_64(ctx);
14898            gen_st_cond(ctx, OPC_SCD, rt, rs, offset);
14899            break;
14900#endif
14901        case LD_EVA:
14902            if (!ctx->eva) {
14903                MIPS_INVAL("pool32c ld-eva");
14904                generate_exception_end(ctx, EXCP_RI);
14905                break;
14906            }
14907            check_cp0_enabled(ctx);
14908
14909            minor2 = (ctx->opcode >> 9) & 0x7;
14910            offset = sextract32(ctx->opcode, 0, 9);
14911            switch (minor2) {
14912            case LBUE:
14913                mips32_op = OPC_LBUE;
14914                goto do_ld_lr;
14915            case LHUE:
14916                mips32_op = OPC_LHUE;
14917                goto do_ld_lr;
14918            case LWLE:
14919                check_insn_opc_removed(ctx, ISA_MIPS32R6);
14920                mips32_op = OPC_LWLE;
14921                goto do_ld_lr;
14922            case LWRE:
14923                check_insn_opc_removed(ctx, ISA_MIPS32R6);
14924                mips32_op = OPC_LWRE;
14925                goto do_ld_lr;
14926            case LBE:
14927                mips32_op = OPC_LBE;
14928                goto do_ld_lr;
14929            case LHE:
14930                mips32_op = OPC_LHE;
14931                goto do_ld_lr;
14932            case LLE:
14933                mips32_op = OPC_LLE;
14934                goto do_ld_lr;
14935            case LWE:
14936                mips32_op = OPC_LWE;
14937                goto do_ld_lr;
14938            };
14939            break;
14940        case ST_EVA:
14941            if (!ctx->eva) {
14942                MIPS_INVAL("pool32c st-eva");
14943                generate_exception_end(ctx, EXCP_RI);
14944                break;
14945            }
14946            check_cp0_enabled(ctx);
14947
14948            minor2 = (ctx->opcode >> 9) & 0x7;
14949            offset = sextract32(ctx->opcode, 0, 9);
14950            switch (minor2) {
14951            case SWLE:
14952                check_insn_opc_removed(ctx, ISA_MIPS32R6);
14953                mips32_op = OPC_SWLE;
14954                goto do_st_lr;
14955            case SWRE:
14956                check_insn_opc_removed(ctx, ISA_MIPS32R6);
14957                mips32_op = OPC_SWRE;
14958                goto do_st_lr;
14959            case PREFE:
14960                /* Treat as no-op */
14961                if ((ctx->insn_flags & ISA_MIPS32R6) && (rt >= 24)) {
14962                    /* hint codes 24-31 are reserved and signal RI */
14963                    generate_exception(ctx, EXCP_RI);
14964                }
14965                break;
14966            case CACHEE:
14967                /* Treat as no-op */
14968                if (ctx->hflags & MIPS_HFLAG_ITC_CACHE) {
14969                    gen_cache_operation(ctx, rt, rs, offset);
14970                }
14971                break;
14972            case SBE:
14973                mips32_op = OPC_SBE;
14974                goto do_st_lr;
14975            case SHE:
14976                mips32_op = OPC_SHE;
14977                goto do_st_lr;
14978            case SCE:
14979                gen_st_cond(ctx, OPC_SCE, rt, rs, offset);
14980                break;
14981            case SWE:
14982                mips32_op = OPC_SWE;
14983                goto do_st_lr;
14984            };
14985            break;
14986        case PREF:
14987            /* Treat as no-op */
14988            if ((ctx->insn_flags & ISA_MIPS32R6) && (rt >= 24)) {
14989                /* hint codes 24-31 are reserved and signal RI */
14990                generate_exception(ctx, EXCP_RI);
14991            }
14992            break;
14993        default:
14994            MIPS_INVAL("pool32c");
14995            generate_exception_end(ctx, EXCP_RI);
14996            break;
14997        }
14998        break;
14999    case ADDI32: /* AUI, LUI */
15000        if (ctx->insn_flags & ISA_MIPS32R6) {
15001            /* AUI, LUI */
15002            gen_logic_imm(ctx, OPC_LUI, rt, rs, imm);
15003        } else {
15004            /* ADDI32 */
15005            mips32_op = OPC_ADDI;
15006            goto do_addi;
15007        }
15008        break;
15009    case ADDIU32:
15010        mips32_op = OPC_ADDIU;
15011    do_addi:
15012        gen_arith_imm(ctx, mips32_op, rt, rs, imm);
15013        break;
15014
15015        /* Logical operations */
15016    case ORI32:
15017        mips32_op = OPC_ORI;
15018        goto do_logici;
15019    case XORI32:
15020        mips32_op = OPC_XORI;
15021        goto do_logici;
15022    case ANDI32:
15023        mips32_op = OPC_ANDI;
15024    do_logici:
15025        gen_logic_imm(ctx, mips32_op, rt, rs, imm);
15026        break;
15027
15028        /* Set less than immediate */
15029    case SLTI32:
15030        mips32_op = OPC_SLTI;
15031        goto do_slti;
15032    case SLTIU32:
15033        mips32_op = OPC_SLTIU;
15034    do_slti:
15035        gen_slt_imm(ctx, mips32_op, rt, rs, imm);
15036        break;
15037    case JALX32:
15038        check_insn_opc_removed(ctx, ISA_MIPS32R6);
15039        offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 2;
15040        gen_compute_branch(ctx, OPC_JALX, 4, rt, rs, offset, 4);
15041        ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
15042        break;
15043    case JALS32: /* BOVC, BEQC, BEQZALC */
15044        if (ctx->insn_flags & ISA_MIPS32R6) {
15045            if (rs >= rt) {
15046                /* BOVC */
15047                mips32_op = OPC_BOVC;
15048            } else if (rs < rt && rs == 0) {
15049                /* BEQZALC */
15050                mips32_op = OPC_BEQZALC;
15051            } else {
15052                /* BEQC */
15053                mips32_op = OPC_BEQC;
15054            }
15055            gen_compute_compact_branch(ctx, mips32_op, rs, rt, imm << 1);
15056        } else {
15057            /* JALS32 */
15058            offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 1;
15059            gen_compute_branch(ctx, OPC_JAL, 4, rt, rs, offset, 2);
15060            ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
15061        }
15062        break;
15063    case BEQ32: /* BC */
15064        if (ctx->insn_flags & ISA_MIPS32R6) {
15065            /* BC */
15066            gen_compute_compact_branch(ctx, OPC_BC, 0, 0,
15067                                       sextract32(ctx->opcode << 1, 0, 27));
15068        } else {
15069            /* BEQ32 */
15070            gen_compute_branch(ctx, OPC_BEQ, 4, rt, rs, imm << 1, 4);
15071        }
15072        break;
15073    case BNE32: /* BALC */
15074        if (ctx->insn_flags & ISA_MIPS32R6) {
15075            /* BALC */
15076            gen_compute_compact_branch(ctx, OPC_BALC, 0, 0,
15077                                       sextract32(ctx->opcode << 1, 0, 27));
15078        } else {
15079            /* BNE32 */
15080            gen_compute_branch(ctx, OPC_BNE, 4, rt, rs, imm << 1, 4);
15081        }
15082        break;
15083    case J32: /* BGTZC, BLTZC, BLTC */
15084        if (ctx->insn_flags & ISA_MIPS32R6) {
15085            if (rs == 0 && rt != 0) {
15086                /* BGTZC */
15087                mips32_op = OPC_BGTZC;
15088            } else if (rs != 0 && rt != 0 && rs == rt) {
15089                /* BLTZC */
15090                mips32_op = OPC_BLTZC;
15091            } else {
15092                /* BLTC */
15093                mips32_op = OPC_BLTC;
15094            }
15095            gen_compute_compact_branch(ctx, mips32_op, rs, rt, imm << 1);
15096        } else {
15097            /* J32 */
15098            gen_compute_branch(ctx, OPC_J, 4, rt, rs,
15099                               (int32_t)(ctx->opcode & 0x3FFFFFF) << 1, 4);
15100        }
15101        break;
15102    case JAL32: /* BLEZC, BGEZC, BGEC */
15103        if (ctx->insn_flags & ISA_MIPS32R6) {
15104            if (rs == 0 && rt != 0) {
15105                /* BLEZC */
15106                mips32_op = OPC_BLEZC;
15107            } else if (rs != 0 && rt != 0 && rs == rt) {
15108                /* BGEZC */
15109                mips32_op = OPC_BGEZC;
15110            } else {
15111                /* BGEC */
15112                mips32_op = OPC_BGEC;
15113            }
15114            gen_compute_compact_branch(ctx, mips32_op, rs, rt, imm << 1);
15115        } else {
15116            /* JAL32 */
15117            gen_compute_branch(ctx, OPC_JAL, 4, rt, rs,
15118                               (int32_t)(ctx->opcode & 0x3FFFFFF) << 1, 4);
15119            ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
15120        }
15121        break;
15122        /* Floating point (COP1) */
15123    case LWC132:
15124        mips32_op = OPC_LWC1;
15125        goto do_cop1;
15126    case LDC132:
15127        mips32_op = OPC_LDC1;
15128        goto do_cop1;
15129    case SWC132:
15130        mips32_op = OPC_SWC1;
15131        goto do_cop1;
15132    case SDC132:
15133        mips32_op = OPC_SDC1;
15134    do_cop1:
15135        gen_cop1_ldst(ctx, mips32_op, rt, rs, imm);
15136        break;
15137    case ADDIUPC: /* PCREL: ADDIUPC, AUIPC, ALUIPC, LWPC */
15138        if (ctx->insn_flags & ISA_MIPS32R6) {
15139            /* PCREL: ADDIUPC, AUIPC, ALUIPC, LWPC */
15140            switch ((ctx->opcode >> 16) & 0x1f) {
15141            case ADDIUPC_00 ... ADDIUPC_07:
15142                gen_pcrel(ctx, OPC_ADDIUPC, ctx->pc & ~0x3, rt);
15143                break;
15144            case AUIPC:
15145                gen_pcrel(ctx, OPC_AUIPC, ctx->pc, rt);
15146                break;
15147            case ALUIPC:
15148                gen_pcrel(ctx, OPC_ALUIPC, ctx->pc, rt);
15149                break;
15150            case LWPC_08 ... LWPC_0F:
15151                gen_pcrel(ctx, R6_OPC_LWPC, ctx->pc & ~0x3, rt);
15152                break;
15153            default:
15154                generate_exception(ctx, EXCP_RI);
15155                break;
15156            }
15157        } else {
15158            /* ADDIUPC */
15159            int reg = mmreg(ZIMM(ctx->opcode, 23, 3));
15160            int offset = SIMM(ctx->opcode, 0, 23) << 2;
15161
15162            gen_addiupc(ctx, reg, offset, 0, 0);
15163        }
15164        break;
15165    case BNVC: /* BNEC, BNEZALC */
15166        check_insn(ctx, ISA_MIPS32R6);
15167        if (rs >= rt) {
15168            /* BNVC */
15169            mips32_op = OPC_BNVC;
15170        } else if (rs < rt && rs == 0) {
15171            /* BNEZALC */
15172            mips32_op = OPC_BNEZALC;
15173        } else {
15174            /* BNEC */
15175            mips32_op = OPC_BNEC;
15176        }
15177        gen_compute_compact_branch(ctx, mips32_op, rs, rt, imm << 1);
15178        break;
15179    case R6_BNEZC: /* JIALC */
15180        check_insn(ctx, ISA_MIPS32R6);
15181        if (rt != 0) {
15182            /* BNEZC */
15183            gen_compute_compact_branch(ctx, OPC_BNEZC, rt, 0,
15184                                       sextract32(ctx->opcode << 1, 0, 22));
15185        } else {
15186            /* JIALC */
15187            gen_compute_compact_branch(ctx, OPC_JIALC, 0, rs, imm);
15188        }
15189        break;
15190    case R6_BEQZC: /* JIC */
15191        check_insn(ctx, ISA_MIPS32R6);
15192        if (rt != 0) {
15193            /* BEQZC */
15194            gen_compute_compact_branch(ctx, OPC_BEQZC, rt, 0,
15195                                       sextract32(ctx->opcode << 1, 0, 22));
15196        } else {
15197            /* JIC */
15198            gen_compute_compact_branch(ctx, OPC_JIC, 0, rs, imm);
15199        }
15200        break;
15201    case BLEZALC: /* BGEZALC, BGEUC */
15202        check_insn(ctx, ISA_MIPS32R6);
15203        if (rs == 0 && rt != 0) {
15204            /* BLEZALC */
15205            mips32_op = OPC_BLEZALC;
15206        } else if (rs != 0 && rt != 0 && rs == rt) {
15207            /* BGEZALC */
15208            mips32_op = OPC_BGEZALC;
15209        } else {
15210            /* BGEUC */
15211            mips32_op = OPC_BGEUC;
15212        }
15213        gen_compute_compact_branch(ctx, mips32_op, rs, rt, imm << 1);
15214        break;
15215    case BGTZALC: /* BLTZALC, BLTUC */
15216        check_insn(ctx, ISA_MIPS32R6);
15217        if (rs == 0 && rt != 0) {
15218            /* BGTZALC */
15219            mips32_op = OPC_BGTZALC;
15220        } else if (rs != 0 && rt != 0 && rs == rt) {
15221            /* BLTZALC */
15222            mips32_op = OPC_BLTZALC;
15223        } else {
15224            /* BLTUC */
15225            mips32_op = OPC_BLTUC;
15226        }
15227        gen_compute_compact_branch(ctx, mips32_op, rs, rt, imm << 1);
15228        break;
15229        /* Loads and stores */
15230    case LB32:
15231        mips32_op = OPC_LB;
15232        goto do_ld;
15233    case LBU32:
15234        mips32_op = OPC_LBU;
15235        goto do_ld;
15236    case LH32:
15237        mips32_op = OPC_LH;
15238        goto do_ld;
15239    case LHU32:
15240        mips32_op = OPC_LHU;
15241        goto do_ld;
15242    case LW32:
15243        mips32_op = OPC_LW;
15244        goto do_ld;
15245#ifdef TARGET_MIPS64
15246    case LD32:
15247        check_insn(ctx, ISA_MIPS3);
15248        check_mips_64(ctx);
15249        mips32_op = OPC_LD;
15250        goto do_ld;
15251    case SD32:
15252        check_insn(ctx, ISA_MIPS3);
15253        check_mips_64(ctx);
15254        mips32_op = OPC_SD;
15255        goto do_st;
15256#endif
15257    case SB32:
15258        mips32_op = OPC_SB;
15259        goto do_st;
15260    case SH32:
15261        mips32_op = OPC_SH;
15262        goto do_st;
15263    case SW32:
15264        mips32_op = OPC_SW;
15265        goto do_st;
15266    do_ld:
15267        gen_ld(ctx, mips32_op, rt, rs, imm);
15268        break;
15269    do_st:
15270        gen_st(ctx, mips32_op, rt, rs, imm);
15271        break;
15272    default:
15273        generate_exception_end(ctx, EXCP_RI);
15274        break;
15275    }
15276}
15277
15278static int decode_micromips_opc (CPUMIPSState *env, DisasContext *ctx)
15279{
15280    uint32_t op;
15281
15282    /* make sure instructions are on a halfword boundary */
15283    if (ctx->pc & 0x1) {
15284        env->CP0_BadVAddr = ctx->pc;
15285        generate_exception_end(ctx, EXCP_AdEL);
15286        return 2;
15287    }
15288
15289    op = (ctx->opcode >> 10) & 0x3f;
15290    /* Enforce properly-sized instructions in a delay slot */
15291    if (ctx->hflags & MIPS_HFLAG_BDS_STRICT) {
15292        switch (op & 0x7) { /* MSB-3..MSB-5 */
15293        case 0:
15294        /* POOL32A, POOL32B, POOL32I, POOL32C */
15295        case 4:
15296        /* ADDI32, ADDIU32, ORI32, XORI32, SLTI32, SLTIU32, ANDI32, JALX32 */
15297        case 5:
15298        /* LBU32, LHU32, POOL32F, JALS32, BEQ32, BNE32, J32, JAL32 */
15299        case 6:
15300        /* SB32, SH32, ADDIUPC, SWC132, SDC132, SW32 */
15301        case 7:
15302        /* LB32, LH32, LWC132, LDC132, LW32 */
15303            if (ctx->hflags & MIPS_HFLAG_BDS16) {
15304                generate_exception_end(ctx, EXCP_RI);
15305                return 2;
15306            }
15307            break;
15308        case 1:
15309        /* POOL16A, POOL16B, POOL16C, LWGP16, POOL16F */
15310        case 2:
15311        /* LBU16, LHU16, LWSP16, LW16, SB16, SH16, SWSP16, SW16 */
15312        case 3:
15313        /* MOVE16, ANDI16, POOL16D, POOL16E, BEQZ16, BNEZ16, B16, LI16 */
15314            if (ctx->hflags & MIPS_HFLAG_BDS32) {
15315                generate_exception_end(ctx, EXCP_RI);
15316                return 2;
15317            }
15318            break;
15319        }
15320    }
15321
15322    switch (op) {
15323    case POOL16A:
15324        {
15325            int rd = mmreg(uMIPS_RD(ctx->opcode));
15326            int rs1 = mmreg(uMIPS_RS1(ctx->opcode));
15327            int rs2 = mmreg(uMIPS_RS2(ctx->opcode));
15328            uint32_t opc = 0;
15329
15330            switch (ctx->opcode & 0x1) {
15331            case ADDU16:
15332                opc = OPC_ADDU;
15333                break;
15334            case SUBU16:
15335                opc = OPC_SUBU;
15336                break;
15337            }
15338            if (ctx->insn_flags & ISA_MIPS32R6) {
15339                /* In the Release 6 the register number location in
15340                 * the instruction encoding has changed.
15341                 */
15342                gen_arith(ctx, opc, rs1, rd, rs2);
15343            } else {
15344                gen_arith(ctx, opc, rd, rs1, rs2);
15345            }
15346        }
15347        break;
15348    case POOL16B:
15349        {
15350            int rd = mmreg(uMIPS_RD(ctx->opcode));
15351            int rs = mmreg(uMIPS_RS(ctx->opcode));
15352            int amount = (ctx->opcode >> 1) & 0x7;
15353            uint32_t opc = 0;
15354            amount = amount == 0 ? 8 : amount;
15355
15356            switch (ctx->opcode & 0x1) {
15357            case SLL16:
15358                opc = OPC_SLL;
15359                break;
15360            case SRL16:
15361                opc = OPC_SRL;
15362                break;
15363            }
15364
15365            gen_shift_imm(ctx, opc, rd, rs, amount);
15366        }
15367        break;
15368    case POOL16C:
15369        if (ctx->insn_flags & ISA_MIPS32R6) {
15370            gen_pool16c_r6_insn(ctx);
15371        } else {
15372            gen_pool16c_insn(ctx);
15373        }
15374        break;
15375    case LWGP16:
15376        {
15377            int rd = mmreg(uMIPS_RD(ctx->opcode));
15378            int rb = 28;            /* GP */
15379            int16_t offset = SIMM(ctx->opcode, 0, 7) << 2;
15380
15381            gen_ld(ctx, OPC_LW, rd, rb, offset);
15382        }
15383        break;
15384    case POOL16F:
15385        check_insn_opc_removed(ctx, ISA_MIPS32R6);
15386        if (ctx->opcode & 1) {
15387            generate_exception_end(ctx, EXCP_RI);
15388        } else {
15389            /* MOVEP */
15390            int enc_dest = uMIPS_RD(ctx->opcode);
15391            int enc_rt = uMIPS_RS2(ctx->opcode);
15392            int enc_rs = uMIPS_RS1(ctx->opcode);
15393            gen_movep(ctx, enc_dest, enc_rt, enc_rs);
15394        }
15395        break;
15396    case LBU16:
15397        {
15398            int rd = mmreg(uMIPS_RD(ctx->opcode));
15399            int rb = mmreg(uMIPS_RS(ctx->opcode));
15400            int16_t offset = ZIMM(ctx->opcode, 0, 4);
15401            offset = (offset == 0xf ? -1 : offset);
15402
15403            gen_ld(ctx, OPC_LBU, rd, rb, offset);
15404        }
15405        break;
15406    case LHU16:
15407        {
15408            int rd = mmreg(uMIPS_RD(ctx->opcode));
15409            int rb = mmreg(uMIPS_RS(ctx->opcode));
15410            int16_t offset = ZIMM(ctx->opcode, 0, 4) << 1;
15411
15412            gen_ld(ctx, OPC_LHU, rd, rb, offset);
15413        }
15414        break;
15415    case LWSP16:
15416        {
15417            int rd = (ctx->opcode >> 5) & 0x1f;
15418            int rb = 29;            /* SP */
15419            int16_t offset = ZIMM(ctx->opcode, 0, 5) << 2;
15420
15421            gen_ld(ctx, OPC_LW, rd, rb, offset);
15422        }
15423        break;
15424    case LW16:
15425        {
15426            int rd = mmreg(uMIPS_RD(ctx->opcode));
15427            int rb = mmreg(uMIPS_RS(ctx->opcode));
15428            int16_t offset = ZIMM(ctx->opcode, 0, 4) << 2;
15429
15430            gen_ld(ctx, OPC_LW, rd, rb, offset);
15431        }
15432        break;
15433    case SB16:
15434        {
15435            int rd = mmreg2(uMIPS_RD(ctx->opcode));
15436            int rb = mmreg(uMIPS_RS(ctx->opcode));
15437            int16_t offset = ZIMM(ctx->opcode, 0, 4);
15438
15439            gen_st(ctx, OPC_SB, rd, rb, offset);
15440        }
15441        break;
15442    case SH16:
15443        {
15444            int rd = mmreg2(uMIPS_RD(ctx->opcode));
15445            int rb = mmreg(uMIPS_RS(ctx->opcode));
15446            int16_t offset = ZIMM(ctx->opcode, 0, 4) << 1;
15447
15448            gen_st(ctx, OPC_SH, rd, rb, offset);
15449        }
15450        break;
15451    case SWSP16:
15452        {
15453            int rd = (ctx->opcode >> 5) & 0x1f;
15454            int rb = 29;            /* SP */
15455            int16_t offset = ZIMM(ctx->opcode, 0, 5) << 2;
15456
15457            gen_st(ctx, OPC_SW, rd, rb, offset);
15458        }
15459        break;
15460    case SW16:
15461        {
15462            int rd = mmreg2(uMIPS_RD(ctx->opcode));
15463            int rb = mmreg(uMIPS_RS(ctx->opcode));
15464            int16_t offset = ZIMM(ctx->opcode, 0, 4) << 2;
15465
15466            gen_st(ctx, OPC_SW, rd, rb, offset);
15467        }
15468        break;
15469    case MOVE16:
15470        {
15471            int rd = uMIPS_RD5(ctx->opcode);
15472            int rs = uMIPS_RS5(ctx->opcode);
15473
15474            gen_arith(ctx, OPC_ADDU, rd, rs, 0);
15475        }
15476        break;
15477    case ANDI16:
15478        gen_andi16(ctx);
15479        break;
15480    case POOL16D:
15481        switch (ctx->opcode & 0x1) {
15482        case ADDIUS5:
15483            gen_addius5(ctx);
15484            break;
15485        case ADDIUSP:
15486            gen_addiusp(ctx);
15487            break;
15488        }
15489        break;
15490    case POOL16E:
15491        switch (ctx->opcode & 0x1) {
15492        case ADDIUR2:
15493            gen_addiur2(ctx);
15494            break;
15495        case ADDIUR1SP:
15496            gen_addiur1sp(ctx);
15497            break;
15498        }
15499        break;
15500    case B16: /* BC16 */
15501        gen_compute_branch(ctx, OPC_BEQ, 2, 0, 0,
15502                           sextract32(ctx->opcode, 0, 10) << 1,
15503                           (ctx->insn_flags & ISA_MIPS32R6) ? 0 : 4);
15504        break;
15505    case BNEZ16: /* BNEZC16 */
15506    case BEQZ16: /* BEQZC16 */
15507        gen_compute_branch(ctx, op == BNEZ16 ? OPC_BNE : OPC_BEQ, 2,
15508                           mmreg(uMIPS_RD(ctx->opcode)),
15509                           0, sextract32(ctx->opcode, 0, 7) << 1,
15510                           (ctx->insn_flags & ISA_MIPS32R6) ? 0 : 4);
15511
15512        break;
15513    case LI16:
15514        {
15515            int reg = mmreg(uMIPS_RD(ctx->opcode));
15516            int imm = ZIMM(ctx->opcode, 0, 7);
15517
15518            imm = (imm == 0x7f ? -1 : imm);
15519            tcg_gen_movi_tl(cpu_gpr[reg], imm);
15520        }
15521        break;
15522    case RES_29:
15523    case RES_31:
15524    case RES_39:
15525        generate_exception_end(ctx, EXCP_RI);
15526        break;
15527    default:
15528        decode_micromips32_opc(env, ctx);
15529        return 4;
15530    }
15531
15532    return 2;
15533}
15534
15535/* SmartMIPS extension to MIPS32 */
15536
15537#if defined(TARGET_MIPS64)
15538
15539/* MDMX extension to MIPS64 */
15540
15541#endif
15542
15543/* MIPSDSP functions. */
15544static void gen_mipsdsp_ld(DisasContext *ctx, uint32_t opc,
15545                           int rd, int base, int offset)
15546{
15547    TCGv t0;
15548
15549    check_dsp(ctx);
15550    t0 = tcg_temp_new();
15551
15552    if (base == 0) {
15553        gen_load_gpr(t0, offset);
15554    } else if (offset == 0) {
15555        gen_load_gpr(t0, base);
15556    } else {
15557        gen_op_addr_add(ctx, t0, cpu_gpr[base], cpu_gpr[offset]);
15558    }
15559
15560    switch (opc) {
15561    case OPC_LBUX:
15562        tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_UB);
15563        gen_store_gpr(t0, rd);
15564        break;
15565    case OPC_LHX:
15566        tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TESW);
15567        gen_store_gpr(t0, rd);
15568        break;
15569    case OPC_LWX:
15570        tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TESL);
15571        gen_store_gpr(t0, rd);
15572        break;
15573#if defined(TARGET_MIPS64)
15574    case OPC_LDX:
15575        tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEQ);
15576        gen_store_gpr(t0, rd);
15577        break;
15578#endif
15579    }
15580    tcg_temp_free(t0);
15581}
15582
15583static void gen_mipsdsp_arith(DisasContext *ctx, uint32_t op1, uint32_t op2,
15584                              int ret, int v1, int v2)
15585{
15586    TCGv v1_t;
15587    TCGv v2_t;
15588
15589    if (ret == 0) {
15590        /* Treat as NOP. */
15591        return;
15592    }
15593
15594    v1_t = tcg_temp_new();
15595    v2_t = tcg_temp_new();
15596
15597    gen_load_gpr(v1_t, v1);
15598    gen_load_gpr(v2_t, v2);
15599
15600    switch (op1) {
15601    /* OPC_MULT_G_2E is equal OPC_ADDUH_QB_DSP */
15602    case OPC_MULT_G_2E:
15603        check_dspr2(ctx);
15604        switch (op2) {
15605        case OPC_ADDUH_QB:
15606            gen_helper_adduh_qb(cpu_gpr[ret], v1_t, v2_t);
15607            break;
15608        case OPC_ADDUH_R_QB:
15609            gen_helper_adduh_r_qb(cpu_gpr[ret], v1_t, v2_t);
15610            break;
15611        case OPC_ADDQH_PH:
15612            gen_helper_addqh_ph(cpu_gpr[ret], v1_t, v2_t);
15613            break;
15614        case OPC_ADDQH_R_PH:
15615            gen_helper_addqh_r_ph(cpu_gpr[ret], v1_t, v2_t);
15616            break;
15617        case OPC_ADDQH_W:
15618            gen_helper_addqh_w(cpu_gpr[ret], v1_t, v2_t);
15619            break;
15620        case OPC_ADDQH_R_W:
15621            gen_helper_addqh_r_w(cpu_gpr[ret], v1_t, v2_t);
15622            break;
15623        case OPC_SUBUH_QB:
15624            gen_helper_subuh_qb(cpu_gpr[ret], v1_t, v2_t);
15625            break;
15626        case OPC_SUBUH_R_QB:
15627            gen_helper_subuh_r_qb(cpu_gpr[ret], v1_t, v2_t);
15628            break;
15629        case OPC_SUBQH_PH:
15630            gen_helper_subqh_ph(cpu_gpr[ret], v1_t, v2_t);
15631            break;
15632        case OPC_SUBQH_R_PH:
15633            gen_helper_subqh_r_ph(cpu_gpr[ret], v1_t, v2_t);
15634            break;
15635        case OPC_SUBQH_W:
15636            gen_helper_subqh_w(cpu_gpr[ret], v1_t, v2_t);
15637            break;
15638        case OPC_SUBQH_R_W:
15639            gen_helper_subqh_r_w(cpu_gpr[ret], v1_t, v2_t);
15640            break;
15641        }
15642        break;
15643    case OPC_ABSQ_S_PH_DSP:
15644        switch (op2) {
15645        case OPC_ABSQ_S_QB:
15646            check_dspr2(ctx);
15647            gen_helper_absq_s_qb(cpu_gpr[ret], v2_t, cpu_env);
15648            break;
15649        case OPC_ABSQ_S_PH:
15650            check_dsp(ctx);
15651            gen_helper_absq_s_ph(cpu_gpr[ret], v2_t, cpu_env);
15652            break;
15653        case OPC_ABSQ_S_W:
15654            check_dsp(ctx);
15655            gen_helper_absq_s_w(cpu_gpr[ret], v2_t, cpu_env);
15656            break;
15657        case OPC_PRECEQ_W_PHL:
15658            check_dsp(ctx);
15659            tcg_gen_andi_tl(cpu_gpr[ret], v2_t, 0xFFFF0000);
15660            tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]);
15661            break;
15662        case OPC_PRECEQ_W_PHR:
15663            check_dsp(ctx);
15664            tcg_gen_andi_tl(cpu_gpr[ret], v2_t, 0x0000FFFF);
15665            tcg_gen_shli_tl(cpu_gpr[ret], cpu_gpr[ret], 16);
15666            tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]);
15667            break;
15668        case OPC_PRECEQU_PH_QBL:
15669            check_dsp(ctx);
15670            gen_helper_precequ_ph_qbl(cpu_gpr[ret], v2_t);
15671            break;
15672        case OPC_PRECEQU_PH_QBR:
15673            check_dsp(ctx);
15674            gen_helper_precequ_ph_qbr(cpu_gpr[ret], v2_t);
15675            break;
15676        case OPC_PRECEQU_PH_QBLA:
15677            check_dsp(ctx);
15678            gen_helper_precequ_ph_qbla(cpu_gpr[ret], v2_t);
15679            break;
15680        case OPC_PRECEQU_PH_QBRA:
15681            check_dsp(ctx);
15682            gen_helper_precequ_ph_qbra(cpu_gpr[ret], v2_t);
15683            break;
15684        case OPC_PRECEU_PH_QBL:
15685            check_dsp(ctx);
15686            gen_helper_preceu_ph_qbl(cpu_gpr[ret], v2_t);
15687            break;
15688        case OPC_PRECEU_PH_QBR:
15689            check_dsp(ctx);
15690            gen_helper_preceu_ph_qbr(cpu_gpr[ret], v2_t);
15691            break;
15692        case OPC_PRECEU_PH_QBLA:
15693            check_dsp(ctx);
15694            gen_helper_preceu_ph_qbla(cpu_gpr[ret], v2_t);
15695            break;
15696        case OPC_PRECEU_PH_QBRA:
15697            check_dsp(ctx);
15698            gen_helper_preceu_ph_qbra(cpu_gpr[ret], v2_t);
15699            break;
15700        }
15701        break;
15702    case OPC_ADDU_QB_DSP:
15703        switch (op2) {
15704        case OPC_ADDQ_PH:
15705            check_dsp(ctx);
15706            gen_helper_addq_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15707            break;
15708        case OPC_ADDQ_S_PH:
15709            check_dsp(ctx);
15710            gen_helper_addq_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15711            break;
15712        case OPC_ADDQ_S_W:
15713            check_dsp(ctx);
15714            gen_helper_addq_s_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15715            break;
15716        case OPC_ADDU_QB:
15717            check_dsp(ctx);
15718            gen_helper_addu_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15719            break;
15720        case OPC_ADDU_S_QB:
15721            check_dsp(ctx);
15722            gen_helper_addu_s_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15723            break;
15724        case OPC_ADDU_PH:
15725            check_dspr2(ctx);
15726            gen_helper_addu_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15727            break;
15728        case OPC_ADDU_S_PH:
15729            check_dspr2(ctx);
15730            gen_helper_addu_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15731            break;
15732        case OPC_SUBQ_PH:
15733            check_dsp(ctx);
15734            gen_helper_subq_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15735            break;
15736        case OPC_SUBQ_S_PH:
15737            check_dsp(ctx);
15738            gen_helper_subq_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15739            break;
15740        case OPC_SUBQ_S_W:
15741            check_dsp(ctx);
15742            gen_helper_subq_s_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15743            break;
15744        case OPC_SUBU_QB:
15745            check_dsp(ctx);
15746            gen_helper_subu_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15747            break;
15748        case OPC_SUBU_S_QB:
15749            check_dsp(ctx);
15750            gen_helper_subu_s_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15751            break;
15752        case OPC_SUBU_PH:
15753            check_dspr2(ctx);
15754            gen_helper_subu_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15755            break;
15756        case OPC_SUBU_S_PH:
15757            check_dspr2(ctx);
15758            gen_helper_subu_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15759            break;
15760        case OPC_ADDSC:
15761            check_dsp(ctx);
15762            gen_helper_addsc(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15763            break;
15764        case OPC_ADDWC:
15765            check_dsp(ctx);
15766            gen_helper_addwc(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15767            break;
15768        case OPC_MODSUB:
15769            check_dsp(ctx);
15770            gen_helper_modsub(cpu_gpr[ret], v1_t, v2_t);
15771            break;
15772        case OPC_RADDU_W_QB:
15773            check_dsp(ctx);
15774            gen_helper_raddu_w_qb(cpu_gpr[ret], v1_t);
15775            break;
15776        }
15777        break;
15778    case OPC_CMPU_EQ_QB_DSP:
15779        switch (op2) {
15780        case OPC_PRECR_QB_PH:
15781            check_dspr2(ctx);
15782            gen_helper_precr_qb_ph(cpu_gpr[ret], v1_t, v2_t);
15783            break;
15784        case OPC_PRECRQ_QB_PH:
15785            check_dsp(ctx);
15786            gen_helper_precrq_qb_ph(cpu_gpr[ret], v1_t, v2_t);
15787            break;
15788        case OPC_PRECR_SRA_PH_W:
15789            check_dspr2(ctx);
15790            {
15791                TCGv_i32 sa_t = tcg_const_i32(v2);
15792                gen_helper_precr_sra_ph_w(cpu_gpr[ret], sa_t, v1_t,
15793                                          cpu_gpr[ret]);
15794                tcg_temp_free_i32(sa_t);
15795                break;
15796            }
15797        case OPC_PRECR_SRA_R_PH_W:
15798            check_dspr2(ctx);
15799            {
15800                TCGv_i32 sa_t = tcg_const_i32(v2);
15801                gen_helper_precr_sra_r_ph_w(cpu_gpr[ret], sa_t, v1_t,
15802                                            cpu_gpr[ret]);
15803                tcg_temp_free_i32(sa_t);
15804                break;
15805            }
15806        case OPC_PRECRQ_PH_W:
15807            check_dsp(ctx);
15808            gen_helper_precrq_ph_w(cpu_gpr[ret], v1_t, v2_t);
15809            break;
15810        case OPC_PRECRQ_RS_PH_W:
15811            check_dsp(ctx);
15812            gen_helper_precrq_rs_ph_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15813            break;
15814        case OPC_PRECRQU_S_QB_PH:
15815            check_dsp(ctx);
15816            gen_helper_precrqu_s_qb_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15817            break;
15818        }
15819        break;
15820#ifdef TARGET_MIPS64
15821    case OPC_ABSQ_S_QH_DSP:
15822        switch (op2) {
15823        case OPC_PRECEQ_L_PWL:
15824            check_dsp(ctx);
15825            tcg_gen_andi_tl(cpu_gpr[ret], v2_t, 0xFFFFFFFF00000000ull);
15826            break;
15827        case OPC_PRECEQ_L_PWR:
15828            check_dsp(ctx);
15829            tcg_gen_shli_tl(cpu_gpr[ret], v2_t, 32);
15830            break;
15831        case OPC_PRECEQ_PW_QHL:
15832            check_dsp(ctx);
15833            gen_helper_preceq_pw_qhl(cpu_gpr[ret], v2_t);
15834            break;
15835        case OPC_PRECEQ_PW_QHR:
15836            check_dsp(ctx);
15837            gen_helper_preceq_pw_qhr(cpu_gpr[ret], v2_t);
15838            break;
15839        case OPC_PRECEQ_PW_QHLA:
15840            check_dsp(ctx);
15841            gen_helper_preceq_pw_qhla(cpu_gpr[ret], v2_t);
15842            break;
15843        case OPC_PRECEQ_PW_QHRA:
15844            check_dsp(ctx);
15845            gen_helper_preceq_pw_qhra(cpu_gpr[ret], v2_t);
15846            break;
15847        case OPC_PRECEQU_QH_OBL:
15848            check_dsp(ctx);
15849            gen_helper_precequ_qh_obl(cpu_gpr[ret], v2_t);
15850            break;
15851        case OPC_PRECEQU_QH_OBR:
15852            check_dsp(ctx);
15853            gen_helper_precequ_qh_obr(cpu_gpr[ret], v2_t);
15854            break;
15855        case OPC_PRECEQU_QH_OBLA:
15856            check_dsp(ctx);
15857            gen_helper_precequ_qh_obla(cpu_gpr[ret], v2_t);
15858            break;
15859        case OPC_PRECEQU_QH_OBRA:
15860            check_dsp(ctx);
15861            gen_helper_precequ_qh_obra(cpu_gpr[ret], v2_t);
15862            break;
15863        case OPC_PRECEU_QH_OBL:
15864            check_dsp(ctx);
15865            gen_helper_preceu_qh_obl(cpu_gpr[ret], v2_t);
15866            break;
15867        case OPC_PRECEU_QH_OBR:
15868            check_dsp(ctx);
15869            gen_helper_preceu_qh_obr(cpu_gpr[ret], v2_t);
15870            break;
15871        case OPC_PRECEU_QH_OBLA:
15872            check_dsp(ctx);
15873            gen_helper_preceu_qh_obla(cpu_gpr[ret], v2_t);
15874            break;
15875        case OPC_PRECEU_QH_OBRA:
15876            check_dsp(ctx);
15877            gen_helper_preceu_qh_obra(cpu_gpr[ret], v2_t);
15878            break;
15879        case OPC_ABSQ_S_OB:
15880            check_dspr2(ctx);
15881            gen_helper_absq_s_ob(cpu_gpr[ret], v2_t, cpu_env);
15882            break;
15883        case OPC_ABSQ_S_PW:
15884            check_dsp(ctx);
15885            gen_helper_absq_s_pw(cpu_gpr[ret], v2_t, cpu_env);
15886            break;
15887        case OPC_ABSQ_S_QH:
15888            check_dsp(ctx);
15889            gen_helper_absq_s_qh(cpu_gpr[ret], v2_t, cpu_env);
15890            break;
15891        }
15892        break;
15893    case OPC_ADDU_OB_DSP:
15894        switch (op2) {
15895        case OPC_RADDU_L_OB:
15896            check_dsp(ctx);
15897            gen_helper_raddu_l_ob(cpu_gpr[ret], v1_t);
15898            break;
15899        case OPC_SUBQ_PW:
15900            check_dsp(ctx);
15901            gen_helper_subq_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15902            break;
15903        case OPC_SUBQ_S_PW:
15904            check_dsp(ctx);
15905            gen_helper_subq_s_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15906            break;
15907        case OPC_SUBQ_QH:
15908            check_dsp(ctx);
15909            gen_helper_subq_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15910            break;
15911        case OPC_SUBQ_S_QH:
15912            check_dsp(ctx);
15913            gen_helper_subq_s_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15914            break;
15915        case OPC_SUBU_OB:
15916            check_dsp(ctx);
15917            gen_helper_subu_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15918            break;
15919        case OPC_SUBU_S_OB:
15920            check_dsp(ctx);
15921            gen_helper_subu_s_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15922            break;
15923        case OPC_SUBU_QH:
15924            check_dspr2(ctx);
15925            gen_helper_subu_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15926            break;
15927        case OPC_SUBU_S_QH:
15928            check_dspr2(ctx);
15929            gen_helper_subu_s_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15930            break;
15931        case OPC_SUBUH_OB:
15932            check_dspr2(ctx);
15933            gen_helper_subuh_ob(cpu_gpr[ret], v1_t, v2_t);
15934            break;
15935        case OPC_SUBUH_R_OB:
15936            check_dspr2(ctx);
15937            gen_helper_subuh_r_ob(cpu_gpr[ret], v1_t, v2_t);
15938            break;
15939        case OPC_ADDQ_PW:
15940            check_dsp(ctx);
15941            gen_helper_addq_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15942            break;
15943        case OPC_ADDQ_S_PW:
15944            check_dsp(ctx);
15945            gen_helper_addq_s_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15946            break;
15947        case OPC_ADDQ_QH:
15948            check_dsp(ctx);
15949            gen_helper_addq_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15950            break;
15951        case OPC_ADDQ_S_QH:
15952            check_dsp(ctx);
15953            gen_helper_addq_s_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15954            break;
15955        case OPC_ADDU_OB:
15956            check_dsp(ctx);
15957            gen_helper_addu_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15958            break;
15959        case OPC_ADDU_S_OB:
15960            check_dsp(ctx);
15961            gen_helper_addu_s_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15962            break;
15963        case OPC_ADDU_QH:
15964            check_dspr2(ctx);
15965            gen_helper_addu_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15966            break;
15967        case OPC_ADDU_S_QH:
15968            check_dspr2(ctx);
15969            gen_helper_addu_s_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15970            break;
15971        case OPC_ADDUH_OB:
15972            check_dspr2(ctx);
15973            gen_helper_adduh_ob(cpu_gpr[ret], v1_t, v2_t);
15974            break;
15975        case OPC_ADDUH_R_OB:
15976            check_dspr2(ctx);
15977            gen_helper_adduh_r_ob(cpu_gpr[ret], v1_t, v2_t);
15978            break;
15979        }
15980        break;
15981    case OPC_CMPU_EQ_OB_DSP:
15982        switch (op2) {
15983        case OPC_PRECR_OB_QH:
15984            check_dspr2(ctx);
15985            gen_helper_precr_ob_qh(cpu_gpr[ret], v1_t, v2_t);
15986            break;
15987        case OPC_PRECR_SRA_QH_PW:
15988            check_dspr2(ctx);
15989            {
15990                TCGv_i32 ret_t = tcg_const_i32(ret);
15991                gen_helper_precr_sra_qh_pw(v2_t, v1_t, v2_t, ret_t);
15992                tcg_temp_free_i32(ret_t);
15993                break;
15994            }
15995        case OPC_PRECR_SRA_R_QH_PW:
15996            check_dspr2(ctx);
15997            {
15998                TCGv_i32 sa_v = tcg_const_i32(ret);
15999                gen_helper_precr_sra_r_qh_pw(v2_t, v1_t, v2_t, sa_v);
16000                tcg_temp_free_i32(sa_v);
16001                break;
16002            }
16003        case OPC_PRECRQ_OB_QH:
16004            check_dsp(ctx);
16005            gen_helper_precrq_ob_qh(cpu_gpr[ret], v1_t, v2_t);
16006            break;
16007        case OPC_PRECRQ_PW_L:
16008            check_dsp(ctx);
16009            gen_helper_precrq_pw_l(cpu_gpr[ret], v1_t, v2_t);
16010            break;
16011        case OPC_PRECRQ_QH_PW:
16012            check_dsp(ctx);
16013            gen_helper_precrq_qh_pw(cpu_gpr[ret], v1_t, v2_t);
16014            break;
16015        case OPC_PRECRQ_RS_QH_PW:
16016            check_dsp(ctx);
16017            gen_helper_precrq_rs_qh_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
16018            break;
16019        case OPC_PRECRQU_S_OB_QH:
16020            check_dsp(ctx);
16021            gen_helper_precrqu_s_ob_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
16022            break;
16023        }
16024        break;
16025#endif
16026    }
16027
16028    tcg_temp_free(v1_t);
16029    tcg_temp_free(v2_t);
16030}
16031
16032static void gen_mipsdsp_shift(DisasContext *ctx, uint32_t opc,
16033                              int ret, int v1, int v2)
16034{
16035    uint32_t op2;
16036    TCGv t0;
16037    TCGv v1_t;
16038    TCGv v2_t;
16039
16040    if (ret == 0) {
16041        /* Treat as NOP. */
16042        return;
16043    }
16044
16045    t0 = tcg_temp_new();
16046    v1_t = tcg_temp_new();
16047    v2_t = tcg_temp_new();
16048
16049    tcg_gen_movi_tl(t0, v1);
16050    gen_load_gpr(v1_t, v1);
16051    gen_load_gpr(v2_t, v2);
16052
16053    switch (opc) {
16054    case OPC_SHLL_QB_DSP:
16055        {
16056            op2 = MASK_SHLL_QB(ctx->opcode);
16057            switch (op2) {
16058            case OPC_SHLL_QB:
16059                check_dsp(ctx);
16060                gen_helper_shll_qb(cpu_gpr[ret], t0, v2_t, cpu_env);
16061                break;
16062            case OPC_SHLLV_QB:
16063                check_dsp(ctx);
16064                gen_helper_shll_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
16065                break;
16066            case OPC_SHLL_PH:
16067                check_dsp(ctx);
16068                gen_helper_shll_ph(cpu_gpr[ret], t0, v2_t, cpu_env);
16069                break;
16070            case OPC_SHLLV_PH:
16071                check_dsp(ctx);
16072                gen_helper_shll_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
16073                break;
16074            case OPC_SHLL_S_PH:
16075                check_dsp(ctx);
16076                gen_helper_shll_s_ph(cpu_gpr[ret], t0, v2_t, cpu_env);
16077                break;
16078            case OPC_SHLLV_S_PH:
16079                check_dsp(ctx);
16080                gen_helper_shll_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
16081                break;
16082            case OPC_SHLL_S_W:
16083                check_dsp(ctx);
16084                gen_helper_shll_s_w(cpu_gpr[ret], t0, v2_t, cpu_env);
16085                break;
16086            case OPC_SHLLV_S_W:
16087                check_dsp(ctx);
16088                gen_helper_shll_s_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
16089                break;
16090            case OPC_SHRL_QB:
16091                check_dsp(ctx);
16092                gen_helper_shrl_qb(cpu_gpr[ret], t0, v2_t);
16093                break;
16094            case OPC_SHRLV_QB:
16095                check_dsp(ctx);
16096                gen_helper_shrl_qb(cpu_gpr[ret], v1_t, v2_t);
16097                break;
16098            case OPC_SHRL_PH:
16099                check_dspr2(ctx);
16100                gen_helper_shrl_ph(cpu_gpr[ret], t0, v2_t);
16101                break;
16102            case OPC_SHRLV_PH:
16103                check_dspr2(ctx);
16104                gen_helper_shrl_ph(cpu_gpr[ret], v1_t, v2_t);
16105                break;
16106            case OPC_SHRA_QB:
16107                check_dspr2(ctx);
16108                gen_helper_shra_qb(cpu_gpr[ret], t0, v2_t);
16109                break;
16110            case OPC_SHRA_R_QB:
16111                check_dspr2(ctx);
16112                gen_helper_shra_r_qb(cpu_gpr[ret], t0, v2_t);
16113                break;
16114            case OPC_SHRAV_QB:
16115                check_dspr2(ctx);
16116                gen_helper_shra_qb(cpu_gpr[ret], v1_t, v2_t);
16117                break;
16118            case OPC_SHRAV_R_QB:
16119                check_dspr2(ctx);
16120                gen_helper_shra_r_qb(cpu_gpr[ret], v1_t, v2_t);
16121                break;
16122            case OPC_SHRA_PH:
16123                check_dsp(ctx);
16124                gen_helper_shra_ph(cpu_gpr[ret], t0, v2_t);
16125                break;
16126            case OPC_SHRA_R_PH:
16127                check_dsp(ctx);
16128                gen_helper_shra_r_ph(cpu_gpr[ret], t0, v2_t);
16129                break;
16130            case OPC_SHRAV_PH:
16131                check_dsp(ctx);
16132                gen_helper_shra_ph(cpu_gpr[ret], v1_t, v2_t);
16133                break;
16134            case OPC_SHRAV_R_PH:
16135                check_dsp(ctx);
16136                gen_helper_shra_r_ph(cpu_gpr[ret], v1_t, v2_t);
16137                break;
16138            case OPC_SHRA_R_W:
16139                check_dsp(ctx);
16140                gen_helper_shra_r_w(cpu_gpr[ret], t0, v2_t);
16141                break;
16142            case OPC_SHRAV_R_W:
16143                check_dsp(ctx);
16144                gen_helper_shra_r_w(cpu_gpr[ret], v1_t, v2_t);
16145                break;
16146            default:            /* Invalid */
16147                MIPS_INVAL("MASK SHLL.QB");
16148                generate_exception_end(ctx, EXCP_RI);
16149                break;
16150            }
16151            break;
16152        }
16153#ifdef TARGET_MIPS64
16154    case OPC_SHLL_OB_DSP:
16155        op2 = MASK_SHLL_OB(ctx->opcode);
16156        switch (op2) {
16157        case OPC_SHLL_PW:
16158            check_dsp(ctx);
16159            gen_helper_shll_pw(cpu_gpr[ret], v2_t, t0, cpu_env);
16160            break;
16161        case OPC_SHLLV_PW:
16162            check_dsp(ctx);
16163            gen_helper_shll_pw(cpu_gpr[ret], v2_t, v1_t, cpu_env);
16164            break;
16165        case OPC_SHLL_S_PW:
16166            check_dsp(ctx);
16167            gen_helper_shll_s_pw(cpu_gpr[ret], v2_t, t0, cpu_env);
16168            break;
16169        case OPC_SHLLV_S_PW:
16170            check_dsp(ctx);
16171            gen_helper_shll_s_pw(cpu_gpr[ret], v2_t, v1_t, cpu_env);
16172            break;
16173        case OPC_SHLL_OB:
16174            check_dsp(ctx);
16175            gen_helper_shll_ob(cpu_gpr[ret], v2_t, t0, cpu_env);
16176            break;
16177        case OPC_SHLLV_OB:
16178            check_dsp(ctx);
16179            gen_helper_shll_ob(cpu_gpr[ret], v2_t, v1_t, cpu_env);
16180            break;
16181        case OPC_SHLL_QH:
16182            check_dsp(ctx);
16183            gen_helper_shll_qh(cpu_gpr[ret], v2_t, t0, cpu_env);
16184            break;
16185        case OPC_SHLLV_QH:
16186            check_dsp(ctx);
16187            gen_helper_shll_qh(cpu_gpr[ret], v2_t, v1_t, cpu_env);
16188            break;
16189        case OPC_SHLL_S_QH:
16190            check_dsp(ctx);
16191            gen_helper_shll_s_qh(cpu_gpr[ret], v2_t, t0, cpu_env);
16192            break;
16193        case OPC_SHLLV_S_QH:
16194            check_dsp(ctx);
16195            gen_helper_shll_s_qh(cpu_gpr[ret], v2_t, v1_t, cpu_env);
16196            break;
16197        case OPC_SHRA_OB:
16198            check_dspr2(ctx);
16199            gen_helper_shra_ob(cpu_gpr[ret], v2_t, t0);
16200            break;
16201        case OPC_SHRAV_OB:
16202            check_dspr2(ctx);
16203            gen_helper_shra_ob(cpu_gpr[ret], v2_t, v1_t);
16204            break;
16205        case OPC_SHRA_R_OB:
16206            check_dspr2(ctx);
16207            gen_helper_shra_r_ob(cpu_gpr[ret], v2_t, t0);
16208            break;
16209        case OPC_SHRAV_R_OB:
16210            check_dspr2(ctx);
16211            gen_helper_shra_r_ob(cpu_gpr[ret], v2_t, v1_t);
16212            break;
16213        case OPC_SHRA_PW:
16214            check_dsp(ctx);
16215            gen_helper_shra_pw(cpu_gpr[ret], v2_t, t0);
16216            break;
16217        case OPC_SHRAV_PW:
16218            check_dsp(ctx);
16219            gen_helper_shra_pw(cpu_gpr[ret], v2_t, v1_t);
16220            break;
16221        case OPC_SHRA_R_PW:
16222            check_dsp(ctx);
16223            gen_helper_shra_r_pw(cpu_gpr[ret], v2_t, t0);
16224            break;
16225        case OPC_SHRAV_R_PW:
16226            check_dsp(ctx);
16227            gen_helper_shra_r_pw(cpu_gpr[ret], v2_t, v1_t);
16228            break;
16229        case OPC_SHRA_QH:
16230            check_dsp(ctx);
16231            gen_helper_shra_qh(cpu_gpr[ret], v2_t, t0);
16232            break;
16233        case OPC_SHRAV_QH:
16234            check_dsp(ctx);
16235            gen_helper_shra_qh(cpu_gpr[ret], v2_t, v1_t);
16236            break;
16237        case OPC_SHRA_R_QH:
16238            check_dsp(ctx);
16239            gen_helper_shra_r_qh(cpu_gpr[ret], v2_t, t0);
16240            break;
16241        case OPC_SHRAV_R_QH:
16242            check_dsp(ctx);
16243            gen_helper_shra_r_qh(cpu_gpr[ret], v2_t, v1_t);
16244            break;
16245        case OPC_SHRL_OB:
16246            check_dsp(ctx);
16247            gen_helper_shrl_ob(cpu_gpr[ret], v2_t, t0);
16248            break;
16249        case OPC_SHRLV_OB:
16250            check_dsp(ctx);
16251            gen_helper_shrl_ob(cpu_gpr[ret], v2_t, v1_t);
16252            break;
16253        case OPC_SHRL_QH:
16254            check_dspr2(ctx);
16255            gen_helper_shrl_qh(cpu_gpr[ret], v2_t, t0);
16256            break;
16257        case OPC_SHRLV_QH:
16258            check_dspr2(ctx);
16259            gen_helper_shrl_qh(cpu_gpr[ret], v2_t, v1_t);
16260            break;
16261        default:            /* Invalid */
16262            MIPS_INVAL("MASK SHLL.OB");
16263            generate_exception_end(ctx, EXCP_RI);
16264            break;
16265        }
16266        break;
16267#endif
16268    }
16269
16270    tcg_temp_free(t0);
16271    tcg_temp_free(v1_t);
16272    tcg_temp_free(v2_t);
16273}
16274
16275static void gen_mipsdsp_multiply(DisasContext *ctx, uint32_t op1, uint32_t op2,
16276                                 int ret, int v1, int v2, int check_ret)
16277{
16278    TCGv_i32 t0;
16279    TCGv v1_t;
16280    TCGv v2_t;
16281
16282    if ((ret == 0) && (check_ret == 1)) {
16283        /* Treat as NOP. */
16284        return;
16285    }
16286
16287    t0 = tcg_temp_new_i32();
16288    v1_t = tcg_temp_new();
16289    v2_t = tcg_temp_new();
16290
16291    tcg_gen_movi_i32(t0, ret);
16292    gen_load_gpr(v1_t, v1);
16293    gen_load_gpr(v2_t, v2);
16294
16295    switch (op1) {
16296    /* OPC_MULT_G_2E, OPC_ADDUH_QB_DSP, OPC_MUL_PH_DSP have
16297     * the same mask and op1. */
16298    case OPC_MULT_G_2E:
16299        check_dspr2(ctx);
16300        switch (op2) {
16301        case  OPC_MUL_PH:
16302            gen_helper_mul_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
16303            break;
16304        case  OPC_MUL_S_PH:
16305            gen_helper_mul_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
16306            break;
16307        case OPC_MULQ_S_W:
16308            gen_helper_mulq_s_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
16309            break;
16310        case OPC_MULQ_RS_W:
16311            gen_helper_mulq_rs_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
16312            break;
16313        }
16314        break;
16315    case OPC_DPA_W_PH_DSP:
16316        switch (op2) {
16317        case OPC_DPAU_H_QBL:
16318            check_dsp(ctx);
16319            gen_helper_dpau_h_qbl(t0, v1_t, v2_t, cpu_env);
16320            break;
16321        case OPC_DPAU_H_QBR:
16322            check_dsp(ctx);
16323            gen_helper_dpau_h_qbr(t0, v1_t, v2_t, cpu_env);
16324            break;
16325        case OPC_DPSU_H_QBL:
16326            check_dsp(ctx);
16327            gen_helper_dpsu_h_qbl(t0, v1_t, v2_t, cpu_env);
16328            break;
16329        case OPC_DPSU_H_QBR:
16330            check_dsp(ctx);
16331            gen_helper_dpsu_h_qbr(t0, v1_t, v2_t, cpu_env);
16332            break;
16333        case OPC_DPA_W_PH:
16334            check_dspr2(ctx);
16335            gen_helper_dpa_w_ph(t0, v1_t, v2_t, cpu_env);
16336            break;
16337        case OPC_DPAX_W_PH:
16338            check_dspr2(ctx);
16339            gen_helper_dpax_w_ph(t0, v1_t, v2_t, cpu_env);
16340            break;
16341        case OPC_DPAQ_S_W_PH:
16342            check_dsp(ctx);
16343            gen_helper_dpaq_s_w_ph(t0, v1_t, v2_t, cpu_env);
16344            break;
16345        case OPC_DPAQX_S_W_PH:
16346            check_dspr2(ctx);
16347            gen_helper_dpaqx_s_w_ph(t0, v1_t, v2_t, cpu_env);
16348            break;
16349        case OPC_DPAQX_SA_W_PH:
16350            check_dspr2(ctx);
16351            gen_helper_dpaqx_sa_w_ph(t0, v1_t, v2_t, cpu_env);
16352            break;
16353        case OPC_DPS_W_PH:
16354            check_dspr2(ctx);
16355            gen_helper_dps_w_ph(t0, v1_t, v2_t, cpu_env);
16356            break;
16357        case OPC_DPSX_W_PH:
16358            check_dspr2(ctx);
16359            gen_helper_dpsx_w_ph(t0, v1_t, v2_t, cpu_env);
16360            break;
16361        case OPC_DPSQ_S_W_PH:
16362            check_dsp(ctx);
16363            gen_helper_dpsq_s_w_ph(t0, v1_t, v2_t, cpu_env);
16364            break;
16365        case OPC_DPSQX_S_W_PH:
16366            check_dspr2(ctx);
16367            gen_helper_dpsqx_s_w_ph(t0, v1_t, v2_t, cpu_env);
16368            break;
16369        case OPC_DPSQX_SA_W_PH:
16370            check_dspr2(ctx);
16371            gen_helper_dpsqx_sa_w_ph(t0, v1_t, v2_t, cpu_env);
16372            break;
16373        case OPC_MULSAQ_S_W_PH:
16374            check_dsp(ctx);
16375            gen_helper_mulsaq_s_w_ph(t0, v1_t, v2_t, cpu_env);
16376            break;
16377        case OPC_DPAQ_SA_L_W:
16378            check_dsp(ctx);
16379            gen_helper_dpaq_sa_l_w(t0, v1_t, v2_t, cpu_env);
16380            break;
16381        case OPC_DPSQ_SA_L_W:
16382            check_dsp(ctx);
16383            gen_helper_dpsq_sa_l_w(t0, v1_t, v2_t, cpu_env);
16384            break;
16385        case OPC_MAQ_S_W_PHL:
16386            check_dsp(ctx);
16387            gen_helper_maq_s_w_phl(t0, v1_t, v2_t, cpu_env);
16388            break;
16389        case OPC_MAQ_S_W_PHR:
16390            check_dsp(ctx);
16391            gen_helper_maq_s_w_phr(t0, v1_t, v2_t, cpu_env);
16392            break;
16393        case OPC_MAQ_SA_W_PHL:
16394            check_dsp(ctx);
16395            gen_helper_maq_sa_w_phl(t0, v1_t, v2_t, cpu_env);
16396            break;
16397        case OPC_MAQ_SA_W_PHR:
16398            check_dsp(ctx);
16399            gen_helper_maq_sa_w_phr(t0, v1_t, v2_t, cpu_env);
16400            break;
16401        case OPC_MULSA_W_PH:
16402            check_dspr2(ctx);
16403            gen_helper_mulsa_w_ph(t0, v1_t, v2_t, cpu_env);
16404            break;
16405        }
16406        break;
16407#ifdef TARGET_MIPS64
16408    case OPC_DPAQ_W_QH_DSP:
16409        {
16410            int ac = ret & 0x03;
16411            tcg_gen_movi_i32(t0, ac);
16412
16413            switch (op2) {
16414            case OPC_DMADD:
16415                check_dsp(ctx);
16416                gen_helper_dmadd(v1_t, v2_t, t0, cpu_env);
16417                break;
16418            case OPC_DMADDU:
16419                check_dsp(ctx);
16420                gen_helper_dmaddu(v1_t, v2_t, t0, cpu_env);
16421                break;
16422            case OPC_DMSUB:
16423                check_dsp(ctx);
16424                gen_helper_dmsub(v1_t, v2_t, t0, cpu_env);
16425                break;
16426            case OPC_DMSUBU:
16427                check_dsp(ctx);
16428                gen_helper_dmsubu(v1_t, v2_t, t0, cpu_env);
16429                break;
16430            case OPC_DPA_W_QH:
16431                check_dspr2(ctx);
16432                gen_helper_dpa_w_qh(v1_t, v2_t, t0, cpu_env);
16433                break;
16434            case OPC_DPAQ_S_W_QH:
16435                check_dsp(ctx);
16436                gen_helper_dpaq_s_w_qh(v1_t, v2_t, t0, cpu_env);
16437                break;
16438            case OPC_DPAQ_SA_L_PW:
16439                check_dsp(ctx);
16440                gen_helper_dpaq_sa_l_pw(v1_t, v2_t, t0, cpu_env);
16441                break;
16442            case OPC_DPAU_H_OBL:
16443                check_dsp(ctx);
16444                gen_helper_dpau_h_obl(v1_t, v2_t, t0, cpu_env);
16445                break;
16446            case OPC_DPAU_H_OBR:
16447                check_dsp(ctx);
16448                gen_helper_dpau_h_obr(v1_t, v2_t, t0, cpu_env);
16449                break;
16450            case OPC_DPS_W_QH:
16451                check_dspr2(ctx);
16452                gen_helper_dps_w_qh(v1_t, v2_t, t0, cpu_env);
16453                break;
16454            case OPC_DPSQ_S_W_QH:
16455                check_dsp(ctx);
16456                gen_helper_dpsq_s_w_qh(v1_t, v2_t, t0, cpu_env);
16457                break;
16458            case OPC_DPSQ_SA_L_PW:
16459                check_dsp(ctx);
16460                gen_helper_dpsq_sa_l_pw(v1_t, v2_t, t0, cpu_env);
16461                break;
16462            case OPC_DPSU_H_OBL:
16463                check_dsp(ctx);
16464                gen_helper_dpsu_h_obl(v1_t, v2_t, t0, cpu_env);
16465                break;
16466            case OPC_DPSU_H_OBR:
16467                check_dsp(ctx);
16468                gen_helper_dpsu_h_obr(v1_t, v2_t, t0, cpu_env);
16469                break;
16470            case OPC_MAQ_S_L_PWL:
16471                check_dsp(ctx);
16472                gen_helper_maq_s_l_pwl(v1_t, v2_t, t0, cpu_env);
16473                break;
16474            case OPC_MAQ_S_L_PWR:
16475                check_dsp(ctx);
16476                gen_helper_maq_s_l_pwr(v1_t, v2_t, t0, cpu_env);
16477                break;
16478            case OPC_MAQ_S_W_QHLL:
16479                check_dsp(ctx);
16480                gen_helper_maq_s_w_qhll(v1_t, v2_t, t0, cpu_env);
16481                break;
16482            case OPC_MAQ_SA_W_QHLL:
16483                check_dsp(ctx);
16484                gen_helper_maq_sa_w_qhll(v1_t, v2_t, t0, cpu_env);
16485                break;
16486            case OPC_MAQ_S_W_QHLR:
16487                check_dsp(ctx);
16488                gen_helper_maq_s_w_qhlr(v1_t, v2_t, t0, cpu_env);
16489                break;
16490            case OPC_MAQ_SA_W_QHLR:
16491                check_dsp(ctx);
16492                gen_helper_maq_sa_w_qhlr(v1_t, v2_t, t0, cpu_env);
16493                break;
16494            case OPC_MAQ_S_W_QHRL:
16495                check_dsp(ctx);
16496                gen_helper_maq_s_w_qhrl(v1_t, v2_t, t0, cpu_env);
16497                break;
16498            case OPC_MAQ_SA_W_QHRL:
16499                check_dsp(ctx);
16500                gen_helper_maq_sa_w_qhrl(v1_t, v2_t, t0, cpu_env);
16501                break;
16502            case OPC_MAQ_S_W_QHRR:
16503                check_dsp(ctx);
16504                gen_helper_maq_s_w_qhrr(v1_t, v2_t, t0, cpu_env);
16505                break;
16506            case OPC_MAQ_SA_W_QHRR:
16507                check_dsp(ctx);
16508                gen_helper_maq_sa_w_qhrr(v1_t, v2_t, t0, cpu_env);
16509                break;
16510            case OPC_MULSAQ_S_L_PW:
16511                check_dsp(ctx);
16512                gen_helper_mulsaq_s_l_pw(v1_t, v2_t, t0, cpu_env);
16513                break;
16514            case OPC_MULSAQ_S_W_QH:
16515                check_dsp(ctx);
16516                gen_helper_mulsaq_s_w_qh(v1_t, v2_t, t0, cpu_env);
16517                break;
16518            }
16519        }
16520        break;
16521#endif
16522    case OPC_ADDU_QB_DSP:
16523        switch (op2) {
16524        case OPC_MULEU_S_PH_QBL:
16525            check_dsp(ctx);
16526            gen_helper_muleu_s_ph_qbl(cpu_gpr[ret], v1_t, v2_t, cpu_env);
16527            break;
16528        case OPC_MULEU_S_PH_QBR:
16529            check_dsp(ctx);
16530            gen_helper_muleu_s_ph_qbr(cpu_gpr[ret], v1_t, v2_t, cpu_env);
16531            break;
16532        case OPC_MULQ_RS_PH:
16533            check_dsp(ctx);
16534            gen_helper_mulq_rs_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
16535            break;
16536        case OPC_MULEQ_S_W_PHL:
16537            check_dsp(ctx);
16538            gen_helper_muleq_s_w_phl(cpu_gpr[ret], v1_t, v2_t, cpu_env);
16539            break;
16540        case OPC_MULEQ_S_W_PHR:
16541            check_dsp(ctx);
16542            gen_helper_muleq_s_w_phr(cpu_gpr[ret], v1_t, v2_t, cpu_env);
16543            break;
16544        case OPC_MULQ_S_PH:
16545            check_dspr2(ctx);
16546            gen_helper_mulq_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
16547            break;
16548        }
16549        break;
16550#ifdef TARGET_MIPS64
16551    case OPC_ADDU_OB_DSP:
16552        switch (op2) {
16553        case OPC_MULEQ_S_PW_QHL:
16554            check_dsp(ctx);
16555            gen_helper_muleq_s_pw_qhl(cpu_gpr[ret], v1_t, v2_t, cpu_env);
16556            break;
16557        case OPC_MULEQ_S_PW_QHR:
16558            check_dsp(ctx);
16559            gen_helper_muleq_s_pw_qhr(cpu_gpr[ret], v1_t, v2_t, cpu_env);
16560            break;
16561        case OPC_MULEU_S_QH_OBL:
16562            check_dsp(ctx);
16563            gen_helper_muleu_s_qh_obl(cpu_gpr[ret], v1_t, v2_t, cpu_env);
16564            break;
16565        case OPC_MULEU_S_QH_OBR:
16566            check_dsp(ctx);
16567            gen_helper_muleu_s_qh_obr(cpu_gpr[ret], v1_t, v2_t, cpu_env);
16568            break;
16569        case OPC_MULQ_RS_QH:
16570            check_dsp(ctx);
16571            gen_helper_mulq_rs_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
16572            break;
16573        }
16574        break;
16575#endif
16576    }
16577
16578    tcg_temp_free_i32(t0);
16579    tcg_temp_free(v1_t);
16580    tcg_temp_free(v2_t);
16581}
16582
16583static void gen_mipsdsp_bitinsn(DisasContext *ctx, uint32_t op1, uint32_t op2,
16584                                int ret, int val)
16585{
16586    int16_t imm;
16587    TCGv t0;
16588    TCGv val_t;
16589
16590    if (ret == 0) {
16591        /* Treat as NOP. */
16592        return;
16593    }
16594
16595    t0 = tcg_temp_new();
16596    val_t = tcg_temp_new();
16597    gen_load_gpr(val_t, val);
16598
16599    switch (op1) {
16600    case OPC_ABSQ_S_PH_DSP:
16601        switch (op2) {
16602        case OPC_BITREV:
16603            check_dsp(ctx);
16604            gen_helper_bitrev(cpu_gpr[ret], val_t);
16605            break;
16606        case OPC_REPL_QB:
16607            check_dsp(ctx);
16608            {
16609                target_long result;
16610                imm = (ctx->opcode >> 16) & 0xFF;
16611                result = (uint32_t)imm << 24 |
16612                         (uint32_t)imm << 16 |
16613                         (uint32_t)imm << 8  |
16614                         (uint32_t)imm;
16615                result = (int32_t)result;
16616                tcg_gen_movi_tl(cpu_gpr[ret], result);
16617            }
16618            break;
16619        case OPC_REPLV_QB:
16620            check_dsp(ctx);
16621            tcg_gen_ext8u_tl(cpu_gpr[ret], val_t);
16622            tcg_gen_shli_tl(t0, cpu_gpr[ret], 8);
16623            tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
16624            tcg_gen_shli_tl(t0, cpu_gpr[ret], 16);
16625            tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
16626            tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]);
16627            break;
16628        case OPC_REPL_PH:
16629            check_dsp(ctx);
16630            {
16631                imm = (ctx->opcode >> 16) & 0x03FF;
16632                imm = (int16_t)(imm << 6) >> 6;
16633                tcg_gen_movi_tl(cpu_gpr[ret], \
16634                                (target_long)((int32_t)imm << 16 | \
16635                                (uint16_t)imm));
16636            }
16637            break;
16638        case OPC_REPLV_PH:
16639            check_dsp(ctx);
16640            tcg_gen_ext16u_tl(cpu_gpr[ret], val_t);
16641            tcg_gen_shli_tl(t0, cpu_gpr[ret], 16);
16642            tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
16643            tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]);
16644            break;
16645        }
16646        break;
16647#ifdef TARGET_MIPS64
16648    case OPC_ABSQ_S_QH_DSP:
16649        switch (op2) {
16650        case OPC_REPL_OB:
16651            check_dsp(ctx);
16652            {
16653                target_long temp;
16654
16655                imm = (ctx->opcode >> 16) & 0xFF;
16656                temp = ((uint64_t)imm << 8) | (uint64_t)imm;
16657                temp = (temp << 16) | temp;
16658                temp = (temp << 32) | temp;
16659                tcg_gen_movi_tl(cpu_gpr[ret], temp);
16660                break;
16661            }
16662        case OPC_REPL_PW:
16663            check_dsp(ctx);
16664            {
16665                target_long temp;
16666
16667                imm = (ctx->opcode >> 16) & 0x03FF;
16668                imm = (int16_t)(imm << 6) >> 6;
16669                temp = ((target_long)imm << 32) \
16670                       | ((target_long)imm & 0xFFFFFFFF);
16671                tcg_gen_movi_tl(cpu_gpr[ret], temp);
16672                break;
16673            }
16674        case OPC_REPL_QH:
16675            check_dsp(ctx);
16676            {
16677                target_long temp;
16678
16679                imm = (ctx->opcode >> 16) & 0x03FF;
16680                imm = (int16_t)(imm << 6) >> 6;
16681
16682                temp = ((uint64_t)(uint16_t)imm << 48) |
16683                       ((uint64_t)(uint16_t)imm << 32) |
16684                       ((uint64_t)(uint16_t)imm << 16) |
16685                       (uint64_t)(uint16_t)imm;
16686                tcg_gen_movi_tl(cpu_gpr[ret], temp);
16687                break;
16688            }
16689        case OPC_REPLV_OB:
16690            check_dsp(ctx);
16691            tcg_gen_ext8u_tl(cpu_gpr[ret], val_t);
16692            tcg_gen_shli_tl(t0, cpu_gpr[ret], 8);
16693            tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
16694            tcg_gen_shli_tl(t0, cpu_gpr[ret], 16);
16695            tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
16696            tcg_gen_shli_tl(t0, cpu_gpr[ret], 32);
16697            tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
16698            break;
16699        case OPC_REPLV_PW:
16700            check_dsp(ctx);
16701            tcg_gen_ext32u_i64(cpu_gpr[ret], val_t);
16702            tcg_gen_shli_tl(t0, cpu_gpr[ret], 32);
16703            tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
16704            break;
16705        case OPC_REPLV_QH:
16706            check_dsp(ctx);
16707            tcg_gen_ext16u_tl(cpu_gpr[ret], val_t);
16708            tcg_gen_shli_tl(t0, cpu_gpr[ret], 16);
16709            tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
16710            tcg_gen_shli_tl(t0, cpu_gpr[ret], 32);
16711            tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
16712            break;
16713        }
16714        break;
16715#endif
16716    }
16717    tcg_temp_free(t0);
16718    tcg_temp_free(val_t);
16719}
16720
16721static void gen_mipsdsp_add_cmp_pick(DisasContext *ctx,
16722                                     uint32_t op1, uint32_t op2,
16723                                     int ret, int v1, int v2, int check_ret)
16724{
16725    TCGv t1;
16726    TCGv v1_t;
16727    TCGv v2_t;
16728
16729    if ((ret == 0) && (check_ret == 1)) {
16730        /* Treat as NOP. */
16731        return;
16732    }
16733
16734    t1 = tcg_temp_new();
16735    v1_t = tcg_temp_new();
16736    v2_t = tcg_temp_new();
16737
16738    gen_load_gpr(v1_t, v1);
16739    gen_load_gpr(v2_t, v2);
16740
16741    switch (op1) {
16742    case OPC_CMPU_EQ_QB_DSP:
16743        switch (op2) {
16744        case OPC_CMPU_EQ_QB:
16745            check_dsp(ctx);
16746            gen_helper_cmpu_eq_qb(v1_t, v2_t, cpu_env);
16747            break;
16748        case OPC_CMPU_LT_QB:
16749            check_dsp(ctx);
16750            gen_helper_cmpu_lt_qb(v1_t, v2_t, cpu_env);
16751            break;
16752        case OPC_CMPU_LE_QB:
16753            check_dsp(ctx);
16754            gen_helper_cmpu_le_qb(v1_t, v2_t, cpu_env);
16755            break;
16756        case OPC_CMPGU_EQ_QB:
16757            check_dsp(ctx);
16758            gen_helper_cmpgu_eq_qb(cpu_gpr[ret], v1_t, v2_t);
16759            break;
16760        case OPC_CMPGU_LT_QB:
16761            check_dsp(ctx);
16762            gen_helper_cmpgu_lt_qb(cpu_gpr[ret], v1_t, v2_t);
16763            break;
16764        case OPC_CMPGU_LE_QB:
16765            check_dsp(ctx);
16766            gen_helper_cmpgu_le_qb(cpu_gpr[ret], v1_t, v2_t);
16767            break;
16768        case OPC_CMPGDU_EQ_QB:
16769            check_dspr2(ctx);
16770            gen_helper_cmpgu_eq_qb(t1, v1_t, v2_t);
16771            tcg_gen_mov_tl(cpu_gpr[ret], t1);
16772            tcg_gen_andi_tl(cpu_dspctrl, cpu_dspctrl, 0xF0FFFFFF);
16773            tcg_gen_shli_tl(t1, t1, 24);
16774            tcg_gen_or_tl(cpu_dspctrl, cpu_dspctrl, t1);
16775            break;
16776        case OPC_CMPGDU_LT_QB:
16777            check_dspr2(ctx);
16778            gen_helper_cmpgu_lt_qb(t1, v1_t, v2_t);
16779            tcg_gen_mov_tl(cpu_gpr[ret], t1);
16780            tcg_gen_andi_tl(cpu_dspctrl, cpu_dspctrl, 0xF0FFFFFF);
16781            tcg_gen_shli_tl(t1, t1, 24);
16782            tcg_gen_or_tl(cpu_dspctrl, cpu_dspctrl, t1);
16783            break;
16784        case OPC_CMPGDU_LE_QB:
16785            check_dspr2(ctx);
16786            gen_helper_cmpgu_le_qb(t1, v1_t, v2_t);
16787            tcg_gen_mov_tl(cpu_gpr[ret], t1);
16788            tcg_gen_andi_tl(cpu_dspctrl, cpu_dspctrl, 0xF0FFFFFF);
16789            tcg_gen_shli_tl(t1, t1, 24);
16790            tcg_gen_or_tl(cpu_dspctrl, cpu_dspctrl, t1);
16791            break;
16792        case OPC_CMP_EQ_PH:
16793            check_dsp(ctx);
16794            gen_helper_cmp_eq_ph(v1_t, v2_t, cpu_env);
16795            break;
16796        case OPC_CMP_LT_PH:
16797            check_dsp(ctx);
16798            gen_helper_cmp_lt_ph(v1_t, v2_t, cpu_env);
16799            break;
16800        case OPC_CMP_LE_PH:
16801            check_dsp(ctx);
16802            gen_helper_cmp_le_ph(v1_t, v2_t, cpu_env);
16803            break;
16804        case OPC_PICK_QB:
16805            check_dsp(ctx);
16806            gen_helper_pick_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
16807            break;
16808        case OPC_PICK_PH:
16809            check_dsp(ctx);
16810            gen_helper_pick_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
16811            break;
16812        case OPC_PACKRL_PH:
16813            check_dsp(ctx);
16814            gen_helper_packrl_ph(cpu_gpr[ret], v1_t, v2_t);
16815            break;
16816        }
16817        break;
16818#ifdef TARGET_MIPS64
16819    case OPC_CMPU_EQ_OB_DSP:
16820        switch (op2) {
16821        case OPC_CMP_EQ_PW:
16822            check_dsp(ctx);
16823            gen_helper_cmp_eq_pw(v1_t, v2_t, cpu_env);
16824            break;
16825        case OPC_CMP_LT_PW:
16826            check_dsp(ctx);
16827            gen_helper_cmp_lt_pw(v1_t, v2_t, cpu_env);
16828            break;
16829        case OPC_CMP_LE_PW:
16830            check_dsp(ctx);
16831            gen_helper_cmp_le_pw(v1_t, v2_t, cpu_env);
16832            break;
16833        case OPC_CMP_EQ_QH:
16834            check_dsp(ctx);
16835            gen_helper_cmp_eq_qh(v1_t, v2_t, cpu_env);
16836            break;
16837        case OPC_CMP_LT_QH:
16838            check_dsp(ctx);
16839            gen_helper_cmp_lt_qh(v1_t, v2_t, cpu_env);
16840            break;
16841        case OPC_CMP_LE_QH:
16842            check_dsp(ctx);
16843            gen_helper_cmp_le_qh(v1_t, v2_t, cpu_env);
16844            break;
16845        case OPC_CMPGDU_EQ_OB:
16846            check_dspr2(ctx);
16847            gen_helper_cmpgdu_eq_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
16848            break;
16849        case OPC_CMPGDU_LT_OB:
16850            check_dspr2(ctx);
16851            gen_helper_cmpgdu_lt_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
16852            break;
16853        case OPC_CMPGDU_LE_OB:
16854            check_dspr2(ctx);
16855            gen_helper_cmpgdu_le_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
16856            break;
16857        case OPC_CMPGU_EQ_OB:
16858            check_dsp(ctx);
16859            gen_helper_cmpgu_eq_ob(cpu_gpr[ret], v1_t, v2_t);
16860            break;
16861        case OPC_CMPGU_LT_OB:
16862            check_dsp(ctx);
16863            gen_helper_cmpgu_lt_ob(cpu_gpr[ret], v1_t, v2_t);
16864            break;
16865        case OPC_CMPGU_LE_OB:
16866            check_dsp(ctx);
16867            gen_helper_cmpgu_le_ob(cpu_gpr[ret], v1_t, v2_t);
16868            break;
16869        case OPC_CMPU_EQ_OB:
16870            check_dsp(ctx);
16871            gen_helper_cmpu_eq_ob(v1_t, v2_t, cpu_env);
16872            break;
16873        case OPC_CMPU_LT_OB:
16874            check_dsp(ctx);
16875            gen_helper_cmpu_lt_ob(v1_t, v2_t, cpu_env);
16876            break;
16877        case OPC_CMPU_LE_OB:
16878            check_dsp(ctx);
16879            gen_helper_cmpu_le_ob(v1_t, v2_t, cpu_env);
16880            break;
16881        case OPC_PACKRL_PW:
16882            check_dsp(ctx);
16883            gen_helper_packrl_pw(cpu_gpr[ret], v1_t, v2_t);
16884            break;
16885        case OPC_PICK_OB:
16886            check_dsp(ctx);
16887            gen_helper_pick_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
16888            break;
16889        case OPC_PICK_PW:
16890            check_dsp(ctx);
16891            gen_helper_pick_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
16892            break;
16893        case OPC_PICK_QH:
16894            check_dsp(ctx);
16895            gen_helper_pick_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
16896            break;
16897        }
16898        break;
16899#endif
16900    }
16901
16902    tcg_temp_free(t1);
16903    tcg_temp_free(v1_t);
16904    tcg_temp_free(v2_t);
16905}
16906
16907static void gen_mipsdsp_append(CPUMIPSState *env, DisasContext *ctx,
16908                               uint32_t op1, int rt, int rs, int sa)
16909{
16910    TCGv t0;
16911
16912    check_dspr2(ctx);
16913
16914    if (rt == 0) {
16915        /* Treat as NOP. */
16916        return;
16917    }
16918
16919    t0 = tcg_temp_new();
16920    gen_load_gpr(t0, rs);
16921
16922    switch (op1) {
16923    case OPC_APPEND_DSP:
16924        switch (MASK_APPEND(ctx->opcode)) {
16925        case OPC_APPEND:
16926            if (sa != 0) {
16927                tcg_gen_deposit_tl(cpu_gpr[rt], t0, cpu_gpr[rt], sa, 32 - sa);
16928            }
16929            tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
16930            break;
16931        case OPC_PREPEND:
16932            if (sa != 0) {
16933                tcg_gen_ext32u_tl(cpu_gpr[rt], cpu_gpr[rt]);
16934                tcg_gen_shri_tl(cpu_gpr[rt], cpu_gpr[rt], sa);
16935                tcg_gen_shli_tl(t0, t0, 32 - sa);
16936                tcg_gen_or_tl(cpu_gpr[rt], cpu_gpr[rt], t0);
16937            }
16938            tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
16939            break;
16940        case OPC_BALIGN:
16941            sa &= 3;
16942            if (sa != 0 && sa != 2) {
16943                tcg_gen_shli_tl(cpu_gpr[rt], cpu_gpr[rt], 8 * sa);
16944                tcg_gen_ext32u_tl(t0, t0);
16945                tcg_gen_shri_tl(t0, t0, 8 * (4 - sa));
16946                tcg_gen_or_tl(cpu_gpr[rt], cpu_gpr[rt], t0);
16947            }
16948            tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
16949            break;
16950        default:            /* Invalid */
16951            MIPS_INVAL("MASK APPEND");
16952            generate_exception_end(ctx, EXCP_RI);
16953            break;
16954        }
16955        break;
16956#ifdef TARGET_MIPS64
16957    case OPC_DAPPEND_DSP:
16958        switch (MASK_DAPPEND(ctx->opcode)) {
16959        case OPC_DAPPEND:
16960            if (sa != 0) {
16961                tcg_gen_deposit_tl(cpu_gpr[rt], t0, cpu_gpr[rt], sa, 64 - sa);
16962            }
16963            break;
16964        case OPC_PREPENDD:
16965            tcg_gen_shri_tl(cpu_gpr[rt], cpu_gpr[rt], 0x20 | sa);
16966            tcg_gen_shli_tl(t0, t0, 64 - (0x20 | sa));
16967            tcg_gen_or_tl(cpu_gpr[rt], t0, t0);
16968            break;
16969        case OPC_PREPENDW:
16970            if (sa != 0) {
16971                tcg_gen_shri_tl(cpu_gpr[rt], cpu_gpr[rt], sa);
16972                tcg_gen_shli_tl(t0, t0, 64 - sa);
16973                tcg_gen_or_tl(cpu_gpr[rt], cpu_gpr[rt], t0);
16974            }
16975            break;
16976        case OPC_DBALIGN:
16977            sa &= 7;
16978            if (sa != 0 && sa != 2 && sa != 4) {
16979                tcg_gen_shli_tl(cpu_gpr[rt], cpu_gpr[rt], 8 * sa);
16980                tcg_gen_shri_tl(t0, t0, 8 * (8 - sa));
16981                tcg_gen_or_tl(cpu_gpr[rt], cpu_gpr[rt], t0);
16982            }
16983            break;
16984        default:            /* Invalid */
16985            MIPS_INVAL("MASK DAPPEND");
16986            generate_exception_end(ctx, EXCP_RI);
16987            break;
16988        }
16989        break;
16990#endif
16991    }
16992    tcg_temp_free(t0);
16993}
16994
16995static void gen_mipsdsp_accinsn(DisasContext *ctx, uint32_t op1, uint32_t op2,
16996                                int ret, int v1, int v2, int check_ret)
16997
16998{
16999    TCGv t0;
17000    TCGv t1;
17001    TCGv v1_t;
17002    TCGv v2_t;
17003    int16_t imm;
17004
17005    if ((ret == 0) && (check_ret == 1)) {
17006        /* Treat as NOP. */
17007        return;
17008    }
17009
17010    t0 = tcg_temp_new();
17011    t1 = tcg_temp_new();
17012    v1_t = tcg_temp_new();
17013    v2_t = tcg_temp_new();
17014
17015    gen_load_gpr(v1_t, v1);
17016    gen_load_gpr(v2_t, v2);
17017
17018    switch (op1) {
17019    case OPC_EXTR_W_DSP:
17020        check_dsp(ctx);
17021        switch (op2) {
17022        case OPC_EXTR_W:
17023            tcg_gen_movi_tl(t0, v2);
17024            tcg_gen_movi_tl(t1, v1);
17025            gen_helper_extr_w(cpu_gpr[ret], t0, t1, cpu_env);
17026            break;
17027        case OPC_EXTR_R_W:
17028            tcg_gen_movi_tl(t0, v2);
17029            tcg_gen_movi_tl(t1, v1);
17030            gen_helper_extr_r_w(cpu_gpr[ret], t0, t1, cpu_env);
17031            break;
17032        case OPC_EXTR_RS_W:
17033            tcg_gen_movi_tl(t0, v2);
17034            tcg_gen_movi_tl(t1, v1);
17035            gen_helper_extr_rs_w(cpu_gpr[ret], t0, t1, cpu_env);
17036            break;
17037        case OPC_EXTR_S_H:
17038            tcg_gen_movi_tl(t0, v2);
17039            tcg_gen_movi_tl(t1, v1);
17040            gen_helper_extr_s_h(cpu_gpr[ret], t0, t1, cpu_env);
17041            break;
17042        case OPC_EXTRV_S_H:
17043            tcg_gen_movi_tl(t0, v2);
17044            gen_helper_extr_s_h(cpu_gpr[ret], t0, v1_t, cpu_env);
17045            break;
17046        case OPC_EXTRV_W:
17047            tcg_gen_movi_tl(t0, v2);
17048            gen_helper_extr_w(cpu_gpr[ret], t0, v1_t, cpu_env);
17049            break;
17050        case OPC_EXTRV_R_W:
17051            tcg_gen_movi_tl(t0, v2);
17052            gen_helper_extr_r_w(cpu_gpr[ret], t0, v1_t, cpu_env);
17053            break;
17054        case OPC_EXTRV_RS_W:
17055            tcg_gen_movi_tl(t0, v2);
17056            gen_helper_extr_rs_w(cpu_gpr[ret], t0, v1_t, cpu_env);
17057            break;
17058        case OPC_EXTP:
17059            tcg_gen_movi_tl(t0, v2);
17060            tcg_gen_movi_tl(t1, v1);
17061            gen_helper_extp(cpu_gpr[ret], t0, t1, cpu_env);
17062            break;
17063        case OPC_EXTPV:
17064            tcg_gen_movi_tl(t0, v2);
17065            gen_helper_extp(cpu_gpr[ret], t0, v1_t, cpu_env);
17066            break;
17067        case OPC_EXTPDP:
17068            tcg_gen_movi_tl(t0, v2);
17069            tcg_gen_movi_tl(t1, v1);
17070            gen_helper_extpdp(cpu_gpr[ret], t0, t1, cpu_env);
17071            break;
17072        case OPC_EXTPDPV:
17073            tcg_gen_movi_tl(t0, v2);
17074            gen_helper_extpdp(cpu_gpr[ret], t0, v1_t, cpu_env);
17075            break;
17076        case OPC_SHILO:
17077            imm = (ctx->opcode >> 20) & 0x3F;
17078            tcg_gen_movi_tl(t0, ret);
17079            tcg_gen_movi_tl(t1, imm);
17080            gen_helper_shilo(t0, t1, cpu_env);
17081            break;
17082        case OPC_SHILOV:
17083            tcg_gen_movi_tl(t0, ret);
17084            gen_helper_shilo(t0, v1_t, cpu_env);
17085            break;
17086        case OPC_MTHLIP:
17087            tcg_gen_movi_tl(t0, ret);
17088            gen_helper_mthlip(t0, v1_t, cpu_env);
17089            break;
17090        case OPC_WRDSP:
17091            imm = (ctx->opcode >> 11) & 0x3FF;
17092            tcg_gen_movi_tl(t0, imm);
17093            gen_helper_wrdsp(v1_t, t0, cpu_env);
17094            break;
17095        case OPC_RDDSP:
17096            imm = (ctx->opcode >> 16) & 0x03FF;
17097            tcg_gen_movi_tl(t0, imm);
17098            gen_helper_rddsp(cpu_gpr[ret], t0, cpu_env);
17099            break;
17100        }
17101        break;
17102#ifdef TARGET_MIPS64
17103    case OPC_DEXTR_W_DSP:
17104        check_dsp(ctx);
17105        switch (op2) {
17106        case OPC_DMTHLIP:
17107            tcg_gen_movi_tl(t0, ret);
17108            gen_helper_dmthlip(v1_t, t0, cpu_env);
17109            break;
17110        case OPC_DSHILO:
17111            {
17112                int shift = (ctx->opcode >> 19) & 0x7F;
17113                int ac = (ctx->opcode >> 11) & 0x03;
17114                tcg_gen_movi_tl(t0, shift);
17115                tcg_gen_movi_tl(t1, ac);
17116                gen_helper_dshilo(t0, t1, cpu_env);
17117                break;
17118            }
17119        case OPC_DSHILOV:
17120            {
17121                int ac = (ctx->opcode >> 11) & 0x03;
17122                tcg_gen_movi_tl(t0, ac);
17123                gen_helper_dshilo(v1_t, t0, cpu_env);
17124                break;
17125            }
17126        case OPC_DEXTP:
17127            tcg_gen_movi_tl(t0, v2);
17128            tcg_gen_movi_tl(t1, v1);
17129
17130            gen_helper_dextp(cpu_gpr[ret], t0, t1, cpu_env);
17131            break;
17132        case OPC_DEXTPV:
17133            tcg_gen_movi_tl(t0, v2);
17134            gen_helper_dextp(cpu_gpr[ret], t0, v1_t, cpu_env);
17135            break;
17136        case OPC_DEXTPDP:
17137            tcg_gen_movi_tl(t0, v2);
17138            tcg_gen_movi_tl(t1, v1);
17139            gen_helper_dextpdp(cpu_gpr[ret], t0, t1, cpu_env);
17140            break;
17141        case OPC_DEXTPDPV:
17142            tcg_gen_movi_tl(t0, v2);
17143            gen_helper_dextpdp(cpu_gpr[ret], t0, v1_t, cpu_env);
17144            break;
17145        case OPC_DEXTR_L:
17146            tcg_gen_movi_tl(t0, v2);
17147            tcg_gen_movi_tl(t1, v1);
17148            gen_helper_dextr_l(cpu_gpr[ret], t0, t1, cpu_env);
17149            break;
17150        case OPC_DEXTR_R_L:
17151            tcg_gen_movi_tl(t0, v2);
17152            tcg_gen_movi_tl(t1, v1);
17153            gen_helper_dextr_r_l(cpu_gpr[ret], t0, t1, cpu_env);
17154            break;
17155        case OPC_DEXTR_RS_L:
17156            tcg_gen_movi_tl(t0, v2);
17157            tcg_gen_movi_tl(t1, v1);
17158            gen_helper_dextr_rs_l(cpu_gpr[ret], t0, t1, cpu_env);
17159            break;
17160        case OPC_DEXTR_W:
17161            tcg_gen_movi_tl(t0, v2);
17162            tcg_gen_movi_tl(t1, v1);
17163            gen_helper_dextr_w(cpu_gpr[ret], t0, t1, cpu_env);
17164            break;
17165        case OPC_DEXTR_R_W:
17166            tcg_gen_movi_tl(t0, v2);
17167            tcg_gen_movi_tl(t1, v1);
17168            gen_helper_dextr_r_w(cpu_gpr[ret], t0, t1, cpu_env);
17169            break;
17170        case OPC_DEXTR_RS_W:
17171            tcg_gen_movi_tl(t0, v2);
17172            tcg_gen_movi_tl(t1, v1);
17173            gen_helper_dextr_rs_w(cpu_gpr[ret], t0, t1, cpu_env);
17174            break;
17175        case OPC_DEXTR_S_H:
17176            tcg_gen_movi_tl(t0, v2);
17177            tcg_gen_movi_tl(t1, v1);
17178            gen_helper_dextr_s_h(cpu_gpr[ret], t0, t1, cpu_env);
17179            break;
17180        case OPC_DEXTRV_S_H:
17181            tcg_gen_movi_tl(t0, v2);
17182            tcg_gen_movi_tl(t1, v1);
17183            gen_helper_dextr_s_h(cpu_gpr[ret], t0, t1, cpu_env);
17184            break;
17185        case OPC_DEXTRV_L:
17186            tcg_gen_movi_tl(t0, v2);
17187            gen_helper_dextr_l(cpu_gpr[ret], t0, v1_t, cpu_env);
17188            break;
17189        case OPC_DEXTRV_R_L:
17190            tcg_gen_movi_tl(t0, v2);
17191            gen_helper_dextr_r_l(cpu_gpr[ret], t0, v1_t, cpu_env);
17192            break;
17193        case OPC_DEXTRV_RS_L:
17194            tcg_gen_movi_tl(t0, v2);
17195            gen_helper_dextr_rs_l(cpu_gpr[ret], t0, v1_t, cpu_env);
17196            break;
17197        case OPC_DEXTRV_W:
17198            tcg_gen_movi_tl(t0, v2);
17199            gen_helper_dextr_w(cpu_gpr[ret], t0, v1_t, cpu_env);
17200            break;
17201        case OPC_DEXTRV_R_W:
17202            tcg_gen_movi_tl(t0, v2);
17203            gen_helper_dextr_r_w(cpu_gpr[ret], t0, v1_t, cpu_env);
17204            break;
17205        case OPC_DEXTRV_RS_W:
17206            tcg_gen_movi_tl(t0, v2);
17207            gen_helper_dextr_rs_w(cpu_gpr[ret], t0, v1_t, cpu_env);
17208            break;
17209        }
17210        break;
17211#endif
17212    }
17213
17214    tcg_temp_free(t0);
17215    tcg_temp_free(t1);
17216    tcg_temp_free(v1_t);
17217    tcg_temp_free(v2_t);
17218}
17219
17220/* End MIPSDSP functions. */
17221
17222static void decode_opc_special_r6(CPUMIPSState *env, DisasContext *ctx)
17223{
17224    int rs, rt, rd, sa;
17225    uint32_t op1, op2;
17226
17227    rs = (ctx->opcode >> 21) & 0x1f;
17228    rt = (ctx->opcode >> 16) & 0x1f;
17229    rd = (ctx->opcode >> 11) & 0x1f;
17230    sa = (ctx->opcode >> 6) & 0x1f;
17231
17232    op1 = MASK_SPECIAL(ctx->opcode);
17233    switch (op1) {
17234    case OPC_LSA:
17235        gen_lsa(ctx, op1, rd, rs, rt, extract32(ctx->opcode, 6, 2));
17236        break;
17237    case OPC_MULT ... OPC_DIVU:
17238        op2 = MASK_R6_MULDIV(ctx->opcode);
17239        switch (op2) {
17240        case R6_OPC_MUL:
17241        case R6_OPC_MUH:
17242        case R6_OPC_MULU:
17243        case R6_OPC_MUHU:
17244        case R6_OPC_DIV:
17245        case R6_OPC_MOD:
17246        case R6_OPC_DIVU:
17247        case R6_OPC_MODU:
17248            gen_r6_muldiv(ctx, op2, rd, rs, rt);
17249            break;
17250        default:
17251            MIPS_INVAL("special_r6 muldiv");
17252            generate_exception_end(ctx, EXCP_RI);
17253            break;
17254        }
17255        break;
17256    case OPC_SELEQZ:
17257    case OPC_SELNEZ:
17258        gen_cond_move(ctx, op1, rd, rs, rt);
17259        break;
17260    case R6_OPC_CLO:
17261    case R6_OPC_CLZ:
17262        if (rt == 0 && sa == 1) {
17263            /* Major opcode and function field is shared with preR6 MFHI/MTHI.
17264               We need additionally to check other fields */
17265            gen_cl(ctx, op1, rd, rs);
17266        } else {
17267            generate_exception_end(ctx, EXCP_RI);
17268        }
17269        break;
17270    case R6_OPC_SDBBP:
17271        if (is_uhi(extract32(ctx->opcode, 6, 20))) {
17272            gen_helper_do_semihosting(cpu_env);
17273        } else {
17274            if (ctx->hflags & MIPS_HFLAG_SBRI) {
17275                generate_exception_end(ctx, EXCP_RI);
17276            } else {
17277                generate_exception_end(ctx, EXCP_DBp);
17278            }
17279        }
17280        break;
17281#if defined(TARGET_MIPS64)
17282    case OPC_DLSA:
17283        check_mips_64(ctx);
17284        gen_lsa(ctx, op1, rd, rs, rt, extract32(ctx->opcode, 6, 2));
17285        break;
17286    case R6_OPC_DCLO:
17287    case R6_OPC_DCLZ:
17288        if (rt == 0 && sa == 1) {
17289            /* Major opcode and function field is shared with preR6 MFHI/MTHI.
17290               We need additionally to check other fields */
17291            check_mips_64(ctx);
17292            gen_cl(ctx, op1, rd, rs);
17293        } else {
17294            generate_exception_end(ctx, EXCP_RI);
17295        }
17296        break;
17297    case OPC_DMULT ... OPC_DDIVU:
17298        op2 = MASK_R6_MULDIV(ctx->opcode);
17299        switch (op2) {
17300        case R6_OPC_DMUL:
17301        case R6_OPC_DMUH:
17302        case R6_OPC_DMULU:
17303        case R6_OPC_DMUHU:
17304        case R6_OPC_DDIV:
17305        case R6_OPC_DMOD:
17306        case R6_OPC_DDIVU:
17307        case R6_OPC_DMODU:
17308            check_mips_64(ctx);
17309            gen_r6_muldiv(ctx, op2, rd, rs, rt);
17310            break;
17311        default:
17312            MIPS_INVAL("special_r6 muldiv");
17313            generate_exception_end(ctx, EXCP_RI);
17314            break;
17315        }
17316        break;
17317#endif
17318    default:            /* Invalid */
17319        MIPS_INVAL("special_r6");
17320        generate_exception_end(ctx, EXCP_RI);
17321        break;
17322    }
17323}
17324
17325static void decode_opc_special_legacy(CPUMIPSState *env, DisasContext *ctx)
17326{
17327    int rs, rt, rd, sa;
17328    uint32_t op1;
17329
17330    rs = (ctx->opcode >> 21) & 0x1f;
17331    rt = (ctx->opcode >> 16) & 0x1f;
17332    rd = (ctx->opcode >> 11) & 0x1f;
17333    sa = (ctx->opcode >> 6) & 0x1f;
17334
17335    op1 = MASK_SPECIAL(ctx->opcode);
17336    switch (op1) {
17337    case OPC_MOVN:         /* Conditional move */
17338    case OPC_MOVZ:
17339        check_insn(ctx, ISA_MIPS4 | ISA_MIPS32 |
17340                   INSN_LOONGSON2E | INSN_LOONGSON2F);
17341        gen_cond_move(ctx, op1, rd, rs, rt);
17342        break;
17343    case OPC_MFHI:          /* Move from HI/LO */
17344    case OPC_MFLO:
17345        gen_HILO(ctx, op1, rs & 3, rd);
17346        break;
17347    case OPC_MTHI:
17348    case OPC_MTLO:          /* Move to HI/LO */
17349        gen_HILO(ctx, op1, rd & 3, rs);
17350        break;
17351    case OPC_MOVCI:
17352        check_insn(ctx, ISA_MIPS4 | ISA_MIPS32);
17353        if (env->CP0_Config1 & (1 << CP0C1_FP)) {
17354            check_cp1_enabled(ctx);
17355            gen_movci(ctx, rd, rs, (ctx->opcode >> 18) & 0x7,
17356                      (ctx->opcode >> 16) & 1);
17357        } else {
17358            generate_exception_err(ctx, EXCP_CpU, 1);
17359        }
17360        break;
17361    case OPC_MULT:
17362    case OPC_MULTU:
17363        if (sa) {
17364            check_insn(ctx, INSN_VR54XX);
17365            op1 = MASK_MUL_VR54XX(ctx->opcode);
17366            gen_mul_vr54xx(ctx, op1, rd, rs, rt);
17367        } else {
17368            gen_muldiv(ctx, op1, rd & 3, rs, rt);
17369        }
17370        break;
17371    case OPC_DIV:
17372    case OPC_DIVU:
17373        gen_muldiv(ctx, op1, 0, rs, rt);
17374        break;
17375#if defined(TARGET_MIPS64)
17376    case OPC_DMULT ... OPC_DDIVU:
17377        check_insn(ctx, ISA_MIPS3);
17378        check_mips_64(ctx);
17379        gen_muldiv(ctx, op1, 0, rs, rt);
17380        break;
17381#endif
17382    case OPC_JR:
17383        gen_compute_branch(ctx, op1, 4, rs, rd, sa, 4);
17384        break;
17385    case OPC_SPIM:
17386#ifdef MIPS_STRICT_STANDARD
17387        MIPS_INVAL("SPIM");
17388        generate_exception_end(ctx, EXCP_RI);
17389#else
17390        /* Implemented as RI exception for now. */
17391        MIPS_INVAL("spim (unofficial)");
17392        generate_exception_end(ctx, EXCP_RI);
17393#endif
17394        break;
17395    default:            /* Invalid */
17396        MIPS_INVAL("special_legacy");
17397        generate_exception_end(ctx, EXCP_RI);
17398        break;
17399    }
17400}
17401
17402static void decode_opc_special(CPUMIPSState *env, DisasContext *ctx)
17403{
17404    int rs, rt, rd, sa;
17405    uint32_t op1;
17406
17407    rs = (ctx->opcode >> 21) & 0x1f;
17408    rt = (ctx->opcode >> 16) & 0x1f;
17409    rd = (ctx->opcode >> 11) & 0x1f;
17410    sa = (ctx->opcode >> 6) & 0x1f;
17411
17412    op1 = MASK_SPECIAL(ctx->opcode);
17413    switch (op1) {
17414    case OPC_SLL:          /* Shift with immediate */
17415        if (sa == 5 && rd == 0 &&
17416            rs == 0 && rt == 0) { /* PAUSE */
17417            if ((ctx->insn_flags & ISA_MIPS32R6) &&
17418                (ctx->hflags & MIPS_HFLAG_BMASK)) {
17419                generate_exception_end(ctx, EXCP_RI);
17420                break;
17421            }
17422        }
17423        /* Fallthrough */
17424    case OPC_SRA:
17425        gen_shift_imm(ctx, op1, rd, rt, sa);
17426        break;
17427    case OPC_SRL:
17428        switch ((ctx->opcode >> 21) & 0x1f) {
17429        case 1:
17430            /* rotr is decoded as srl on non-R2 CPUs */
17431            if (ctx->insn_flags & ISA_MIPS32R2) {
17432                op1 = OPC_ROTR;
17433            }
17434            /* Fallthrough */
17435        case 0:
17436            gen_shift_imm(ctx, op1, rd, rt, sa);
17437            break;
17438        default:
17439            generate_exception_end(ctx, EXCP_RI);
17440            break;
17441        }
17442        break;
17443    case OPC_ADD ... OPC_SUBU:
17444        gen_arith(ctx, op1, rd, rs, rt);
17445        break;
17446    case OPC_SLLV:         /* Shifts */
17447    case OPC_SRAV:
17448        gen_shift(ctx, op1, rd, rs, rt);
17449        break;
17450    case OPC_SRLV:
17451        switch ((ctx->opcode >> 6) & 0x1f) {
17452        case 1:
17453            /* rotrv is decoded as srlv on non-R2 CPUs */
17454            if (ctx->insn_flags & ISA_MIPS32R2) {
17455                op1 = OPC_ROTRV;
17456            }
17457            /* Fallthrough */
17458        case 0:
17459            gen_shift(ctx, op1, rd, rs, rt);
17460            break;
17461        default:
17462            generate_exception_end(ctx, EXCP_RI);
17463            break;
17464        }
17465        break;
17466    case OPC_SLT:          /* Set on less than */
17467    case OPC_SLTU:
17468        gen_slt(ctx, op1, rd, rs, rt);
17469        break;
17470    case OPC_AND:          /* Logic*/
17471    case OPC_OR:
17472    case OPC_NOR:
17473    case OPC_XOR:
17474        gen_logic(ctx, op1, rd, rs, rt);
17475        break;
17476    case OPC_JALR:
17477        gen_compute_branch(ctx, op1, 4, rs, rd, sa, 4);
17478        break;
17479    case OPC_TGE ... OPC_TEQ: /* Traps */
17480    case OPC_TNE:
17481        check_insn(ctx, ISA_MIPS2);
17482        gen_trap(ctx, op1, rs, rt, -1);
17483        break;
17484    case OPC_LSA: /* OPC_PMON */
17485        if ((ctx->insn_flags & ISA_MIPS32R6) ||
17486            (env->CP0_Config3 & (1 << CP0C3_MSAP))) {
17487            decode_opc_special_r6(env, ctx);
17488        } else {
17489            /* Pmon entry point, also R4010 selsl */
17490#ifdef MIPS_STRICT_STANDARD
17491            MIPS_INVAL("PMON / selsl");
17492            generate_exception_end(ctx, EXCP_RI);
17493#else
17494            gen_helper_0e0i(pmon, sa);
17495#endif
17496        }
17497        break;
17498    case OPC_SYSCALL:
17499        generate_exception_end(ctx, EXCP_SYSCALL);
17500        break;
17501    case OPC_BREAK:
17502        generate_exception_end(ctx, EXCP_BREAK);
17503        break;
17504    case OPC_SYNC:
17505        check_insn(ctx, ISA_MIPS2);
17506        gen_sync(extract32(ctx->opcode, 6, 5));
17507        break;
17508
17509#if defined(TARGET_MIPS64)
17510        /* MIPS64 specific opcodes */
17511    case OPC_DSLL:
17512    case OPC_DSRA:
17513    case OPC_DSLL32:
17514    case OPC_DSRA32:
17515        check_insn(ctx, ISA_MIPS3);
17516        check_mips_64(ctx);
17517        gen_shift_imm(ctx, op1, rd, rt, sa);
17518        break;
17519    case OPC_DSRL:
17520        switch ((ctx->opcode >> 21) & 0x1f) {
17521        case 1:
17522            /* drotr is decoded as dsrl on non-R2 CPUs */
17523            if (ctx->insn_flags & ISA_MIPS32R2) {
17524                op1 = OPC_DROTR;
17525            }
17526            /* Fallthrough */
17527        case 0:
17528            check_insn(ctx, ISA_MIPS3);
17529            check_mips_64(ctx);
17530            gen_shift_imm(ctx, op1, rd, rt, sa);
17531            break;
17532        default:
17533            generate_exception_end(ctx, EXCP_RI);
17534            break;
17535        }
17536        break;
17537    case OPC_DSRL32:
17538        switch ((ctx->opcode >> 21) & 0x1f) {
17539        case 1:
17540            /* drotr32 is decoded as dsrl32 on non-R2 CPUs */
17541            if (ctx->insn_flags & ISA_MIPS32R2) {
17542                op1 = OPC_DROTR32;
17543            }
17544            /* Fallthrough */
17545        case 0:
17546            check_insn(ctx, ISA_MIPS3);
17547            check_mips_64(ctx);
17548            gen_shift_imm(ctx, op1, rd, rt, sa);
17549            break;
17550        default:
17551            generate_exception_end(ctx, EXCP_RI);
17552            break;
17553        }
17554        break;
17555    case OPC_DADD ... OPC_DSUBU:
17556        check_insn(ctx, ISA_MIPS3);
17557        check_mips_64(ctx);
17558        gen_arith(ctx, op1, rd, rs, rt);
17559        break;
17560    case OPC_DSLLV:
17561    case OPC_DSRAV:
17562        check_insn(ctx, ISA_MIPS3);
17563        check_mips_64(ctx);
17564        gen_shift(ctx, op1, rd, rs, rt);
17565        break;
17566    case OPC_DSRLV:
17567        switch ((ctx->opcode >> 6) & 0x1f) {
17568        case 1:
17569            /* drotrv is decoded as dsrlv on non-R2 CPUs */
17570            if (ctx->insn_flags & ISA_MIPS32R2) {
17571                op1 = OPC_DROTRV;
17572            }
17573            /* Fallthrough */
17574        case 0:
17575            check_insn(ctx, ISA_MIPS3);
17576            check_mips_64(ctx);
17577            gen_shift(ctx, op1, rd, rs, rt);
17578            break;
17579        default:
17580            generate_exception_end(ctx, EXCP_RI);
17581            break;
17582        }
17583        break;
17584    case OPC_DLSA:
17585        if ((ctx->insn_flags & ISA_MIPS32R6) ||
17586            (env->CP0_Config3 & (1 << CP0C3_MSAP))) {
17587            decode_opc_special_r6(env, ctx);
17588        }
17589        break;
17590#endif
17591    default:
17592        if (ctx->insn_flags & ISA_MIPS32R6) {
17593            decode_opc_special_r6(env, ctx);
17594        } else {
17595            decode_opc_special_legacy(env, ctx);
17596        }
17597    }
17598}
17599
17600static void decode_opc_special2_legacy(CPUMIPSState *env, DisasContext *ctx)
17601{
17602    int rs, rt, rd;
17603    uint32_t op1;
17604
17605    check_insn_opc_removed(ctx, ISA_MIPS32R6);
17606
17607    rs = (ctx->opcode >> 21) & 0x1f;
17608    rt = (ctx->opcode >> 16) & 0x1f;
17609    rd = (ctx->opcode >> 11) & 0x1f;
17610
17611    op1 = MASK_SPECIAL2(ctx->opcode);
17612    switch (op1) {
17613    case OPC_MADD ... OPC_MADDU: /* Multiply and add/sub */
17614    case OPC_MSUB ... OPC_MSUBU:
17615        check_insn(ctx, ISA_MIPS32);
17616        gen_muldiv(ctx, op1, rd & 3, rs, rt);
17617        break;
17618    case OPC_MUL:
17619        gen_arith(ctx, op1, rd, rs, rt);
17620        break;
17621    case OPC_DIV_G_2F:
17622    case OPC_DIVU_G_2F:
17623    case OPC_MULT_G_2F:
17624    case OPC_MULTU_G_2F:
17625    case OPC_MOD_G_2F:
17626    case OPC_MODU_G_2F:
17627        check_insn(ctx, INSN_LOONGSON2F);
17628        gen_loongson_integer(ctx, op1, rd, rs, rt);
17629        break;
17630    case OPC_CLO:
17631    case OPC_CLZ:
17632        check_insn(ctx, ISA_MIPS32);
17633        gen_cl(ctx, op1, rd, rs);
17634        break;
17635    case OPC_SDBBP:
17636        if (is_uhi(extract32(ctx->opcode, 6, 20))) {
17637            gen_helper_do_semihosting(cpu_env);
17638        } else {
17639            /* XXX: not clear which exception should be raised
17640             *      when in debug mode...
17641             */
17642            check_insn(ctx, ISA_MIPS32);
17643            generate_exception_end(ctx, EXCP_DBp);
17644        }
17645        break;
17646#if defined(TARGET_MIPS64)
17647    case OPC_DCLO:
17648    case OPC_DCLZ:
17649        check_insn(ctx, ISA_MIPS64);
17650        check_mips_64(ctx);
17651        gen_cl(ctx, op1, rd, rs);
17652        break;
17653    case OPC_DMULT_G_2F:
17654    case OPC_DMULTU_G_2F:
17655    case OPC_DDIV_G_2F:
17656    case OPC_DDIVU_G_2F:
17657    case OPC_DMOD_G_2F:
17658    case OPC_DMODU_G_2F:
17659        check_insn(ctx, INSN_LOONGSON2F);
17660        gen_loongson_integer(ctx, op1, rd, rs, rt);
17661        break;
17662#endif
17663    default:            /* Invalid */
17664        MIPS_INVAL("special2_legacy");
17665        generate_exception_end(ctx, EXCP_RI);
17666        break;
17667    }
17668}
17669
17670static void decode_opc_special3_r6(CPUMIPSState *env, DisasContext *ctx)
17671{
17672    int rs, rt, rd, sa;
17673    uint32_t op1, op2;
17674    int16_t imm;
17675
17676    rs = (ctx->opcode >> 21) & 0x1f;
17677    rt = (ctx->opcode >> 16) & 0x1f;
17678    rd = (ctx->opcode >> 11) & 0x1f;
17679    sa = (ctx->opcode >> 6) & 0x1f;
17680    imm = (int16_t)ctx->opcode >> 7;
17681
17682    op1 = MASK_SPECIAL3(ctx->opcode);
17683    switch (op1) {
17684    case R6_OPC_PREF:
17685        if (rt >= 24) {
17686            /* hint codes 24-31 are reserved and signal RI */
17687            generate_exception_end(ctx, EXCP_RI);
17688        }
17689        /* Treat as NOP. */
17690        break;
17691    case R6_OPC_CACHE:
17692        check_cp0_enabled(ctx);
17693        if (ctx->hflags & MIPS_HFLAG_ITC_CACHE) {
17694            gen_cache_operation(ctx, rt, rs, imm);
17695        }
17696        break;
17697    case R6_OPC_SC:
17698        gen_st_cond(ctx, op1, rt, rs, imm);
17699        break;
17700    case R6_OPC_LL:
17701        gen_ld(ctx, op1, rt, rs, imm);
17702        break;
17703    case OPC_BSHFL:
17704        {
17705            if (rd == 0) {
17706                /* Treat as NOP. */
17707                break;
17708            }
17709            op2 = MASK_BSHFL(ctx->opcode);
17710            switch (op2) {
17711            case OPC_ALIGN ... OPC_ALIGN_END:
17712                gen_align(ctx, OPC_ALIGN, rd, rs, rt, sa & 3);
17713                break;
17714            case OPC_BITSWAP:
17715                gen_bitswap(ctx, op2, rd, rt);
17716                break;
17717            }
17718        }
17719        break;
17720#if defined(TARGET_MIPS64)
17721    case R6_OPC_SCD:
17722        gen_st_cond(ctx, op1, rt, rs, imm);
17723        break;
17724    case R6_OPC_LLD:
17725        gen_ld(ctx, op1, rt, rs, imm);
17726        break;
17727    case OPC_DBSHFL:
17728        check_mips_64(ctx);
17729        {
17730            if (rd == 0) {
17731                /* Treat as NOP. */
17732                break;
17733            }
17734            op2 = MASK_DBSHFL(ctx->opcode);
17735            switch (op2) {
17736            case OPC_DALIGN ... OPC_DALIGN_END:
17737                gen_align(ctx, OPC_DALIGN, rd, rs, rt, sa & 7);
17738                break;
17739            case OPC_DBITSWAP:
17740                gen_bitswap(ctx, op2, rd, rt);
17741                break;
17742            }
17743
17744        }
17745        break;
17746#endif
17747    default:            /* Invalid */
17748        MIPS_INVAL("special3_r6");
17749        generate_exception_end(ctx, EXCP_RI);
17750        break;
17751    }
17752}
17753
17754static void decode_opc_special3_legacy(CPUMIPSState *env, DisasContext *ctx)
17755{
17756    int rs, rt, rd;
17757    uint32_t op1, op2;
17758
17759    rs = (ctx->opcode >> 21) & 0x1f;
17760    rt = (ctx->opcode >> 16) & 0x1f;
17761    rd = (ctx->opcode >> 11) & 0x1f;
17762
17763    op1 = MASK_SPECIAL3(ctx->opcode);
17764    switch (op1) {
17765    case OPC_DIV_G_2E ... OPC_DIVU_G_2E:
17766    case OPC_MOD_G_2E ... OPC_MODU_G_2E:
17767    case OPC_MULT_G_2E ... OPC_MULTU_G_2E:
17768        /* OPC_MULT_G_2E, OPC_ADDUH_QB_DSP, OPC_MUL_PH_DSP have
17769         * the same mask and op1. */
17770        if ((ctx->insn_flags & ASE_DSPR2) && (op1 == OPC_MULT_G_2E)) {
17771            op2 = MASK_ADDUH_QB(ctx->opcode);
17772            switch (op2) {
17773            case OPC_ADDUH_QB:
17774            case OPC_ADDUH_R_QB:
17775            case OPC_ADDQH_PH:
17776            case OPC_ADDQH_R_PH:
17777            case OPC_ADDQH_W:
17778            case OPC_ADDQH_R_W:
17779            case OPC_SUBUH_QB:
17780            case OPC_SUBUH_R_QB:
17781            case OPC_SUBQH_PH:
17782            case OPC_SUBQH_R_PH:
17783            case OPC_SUBQH_W:
17784            case OPC_SUBQH_R_W:
17785                gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
17786                break;
17787            case OPC_MUL_PH:
17788            case OPC_MUL_S_PH:
17789            case OPC_MULQ_S_W:
17790            case OPC_MULQ_RS_W:
17791                gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 1);
17792                break;
17793            default:
17794                MIPS_INVAL("MASK ADDUH.QB");
17795                generate_exception_end(ctx, EXCP_RI);
17796                break;
17797            }
17798        } else if (ctx->insn_flags & INSN_LOONGSON2E) {
17799            gen_loongson_integer(ctx, op1, rd, rs, rt);
17800        } else {
17801            generate_exception_end(ctx, EXCP_RI);
17802        }
17803        break;
17804    case OPC_LX_DSP:
17805        op2 = MASK_LX(ctx->opcode);
17806        switch (op2) {
17807#if defined(TARGET_MIPS64)
17808        case OPC_LDX:
17809#endif
17810        case OPC_LBUX:
17811        case OPC_LHX:
17812        case OPC_LWX:
17813            gen_mipsdsp_ld(ctx, op2, rd, rs, rt);
17814            break;
17815        default:            /* Invalid */
17816            MIPS_INVAL("MASK LX");
17817            generate_exception_end(ctx, EXCP_RI);
17818            break;
17819        }
17820        break;
17821    case OPC_ABSQ_S_PH_DSP:
17822        op2 = MASK_ABSQ_S_PH(ctx->opcode);
17823        switch (op2) {
17824        case OPC_ABSQ_S_QB:
17825        case OPC_ABSQ_S_PH:
17826        case OPC_ABSQ_S_W:
17827        case OPC_PRECEQ_W_PHL:
17828        case OPC_PRECEQ_W_PHR:
17829        case OPC_PRECEQU_PH_QBL:
17830        case OPC_PRECEQU_PH_QBR:
17831        case OPC_PRECEQU_PH_QBLA:
17832        case OPC_PRECEQU_PH_QBRA:
17833        case OPC_PRECEU_PH_QBL:
17834        case OPC_PRECEU_PH_QBR:
17835        case OPC_PRECEU_PH_QBLA:
17836        case OPC_PRECEU_PH_QBRA:
17837            gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
17838            break;
17839        case OPC_BITREV:
17840        case OPC_REPL_QB:
17841        case OPC_REPLV_QB:
17842        case OPC_REPL_PH:
17843        case OPC_REPLV_PH:
17844            gen_mipsdsp_bitinsn(ctx, op1, op2, rd, rt);
17845            break;
17846        default:
17847            MIPS_INVAL("MASK ABSQ_S.PH");
17848            generate_exception_end(ctx, EXCP_RI);
17849            break;
17850        }
17851        break;
17852    case OPC_ADDU_QB_DSP:
17853        op2 = MASK_ADDU_QB(ctx->opcode);
17854        switch (op2) {
17855        case OPC_ADDQ_PH:
17856        case OPC_ADDQ_S_PH:
17857        case OPC_ADDQ_S_W:
17858        case OPC_ADDU_QB:
17859        case OPC_ADDU_S_QB:
17860        case OPC_ADDU_PH:
17861        case OPC_ADDU_S_PH:
17862        case OPC_SUBQ_PH:
17863        case OPC_SUBQ_S_PH:
17864        case OPC_SUBQ_S_W:
17865        case OPC_SUBU_QB:
17866        case OPC_SUBU_S_QB:
17867        case OPC_SUBU_PH:
17868        case OPC_SUBU_S_PH:
17869        case OPC_ADDSC:
17870        case OPC_ADDWC:
17871        case OPC_MODSUB:
17872        case OPC_RADDU_W_QB:
17873            gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
17874            break;
17875        case OPC_MULEU_S_PH_QBL:
17876        case OPC_MULEU_S_PH_QBR:
17877        case OPC_MULQ_RS_PH:
17878        case OPC_MULEQ_S_W_PHL:
17879        case OPC_MULEQ_S_W_PHR:
17880        case OPC_MULQ_S_PH:
17881            gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 1);
17882            break;
17883        default:            /* Invalid */
17884            MIPS_INVAL("MASK ADDU.QB");
17885            generate_exception_end(ctx, EXCP_RI);
17886            break;
17887
17888        }
17889        break;
17890    case OPC_CMPU_EQ_QB_DSP:
17891        op2 = MASK_CMPU_EQ_QB(ctx->opcode);
17892        switch (op2) {
17893        case OPC_PRECR_SRA_PH_W:
17894        case OPC_PRECR_SRA_R_PH_W:
17895            gen_mipsdsp_arith(ctx, op1, op2, rt, rs, rd);
17896            break;
17897        case OPC_PRECR_QB_PH:
17898        case OPC_PRECRQ_QB_PH:
17899        case OPC_PRECRQ_PH_W:
17900        case OPC_PRECRQ_RS_PH_W:
17901        case OPC_PRECRQU_S_QB_PH:
17902            gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
17903            break;
17904        case OPC_CMPU_EQ_QB:
17905        case OPC_CMPU_LT_QB:
17906        case OPC_CMPU_LE_QB:
17907        case OPC_CMP_EQ_PH:
17908        case OPC_CMP_LT_PH:
17909        case OPC_CMP_LE_PH:
17910            gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 0);
17911            break;
17912        case OPC_CMPGU_EQ_QB:
17913        case OPC_CMPGU_LT_QB:
17914        case OPC_CMPGU_LE_QB:
17915        case OPC_CMPGDU_EQ_QB:
17916        case OPC_CMPGDU_LT_QB:
17917        case OPC_CMPGDU_LE_QB:
17918        case OPC_PICK_QB:
17919        case OPC_PICK_PH:
17920        case OPC_PACKRL_PH:
17921            gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 1);
17922            break;
17923        default:            /* Invalid */
17924            MIPS_INVAL("MASK CMPU.EQ.QB");
17925            generate_exception_end(ctx, EXCP_RI);
17926            break;
17927        }
17928        break;
17929    case OPC_SHLL_QB_DSP:
17930        gen_mipsdsp_shift(ctx, op1, rd, rs, rt);
17931        break;
17932    case OPC_DPA_W_PH_DSP:
17933        op2 = MASK_DPA_W_PH(ctx->opcode);
17934        switch (op2) {
17935        case OPC_DPAU_H_QBL:
17936        case OPC_DPAU_H_QBR:
17937        case OPC_DPSU_H_QBL:
17938        case OPC_DPSU_H_QBR:
17939        case OPC_DPA_W_PH:
17940        case OPC_DPAX_W_PH:
17941        case OPC_DPAQ_S_W_PH:
17942        case OPC_DPAQX_S_W_PH:
17943        case OPC_DPAQX_SA_W_PH:
17944        case OPC_DPS_W_PH:
17945        case OPC_DPSX_W_PH:
17946        case OPC_DPSQ_S_W_PH:
17947        case OPC_DPSQX_S_W_PH:
17948        case OPC_DPSQX_SA_W_PH:
17949        case OPC_MULSAQ_S_W_PH:
17950        case OPC_DPAQ_SA_L_W:
17951        case OPC_DPSQ_SA_L_W:
17952        case OPC_MAQ_S_W_PHL:
17953        case OPC_MAQ_S_W_PHR:
17954        case OPC_MAQ_SA_W_PHL:
17955        case OPC_MAQ_SA_W_PHR:
17956        case OPC_MULSA_W_PH:
17957            gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 0);
17958            break;
17959        default:            /* Invalid */
17960            MIPS_INVAL("MASK DPAW.PH");
17961            generate_exception_end(ctx, EXCP_RI);
17962            break;
17963        }
17964        break;
17965    case OPC_INSV_DSP:
17966        op2 = MASK_INSV(ctx->opcode);
17967        switch (op2) {
17968        case OPC_INSV:
17969            check_dsp(ctx);
17970            {
17971                TCGv t0, t1;
17972
17973                if (rt == 0) {
17974                    break;
17975                }
17976
17977                t0 = tcg_temp_new();
17978                t1 = tcg_temp_new();
17979
17980                gen_load_gpr(t0, rt);
17981                gen_load_gpr(t1, rs);
17982
17983                gen_helper_insv(cpu_gpr[rt], cpu_env, t1, t0);
17984
17985                tcg_temp_free(t0);
17986                tcg_temp_free(t1);
17987                break;
17988            }
17989        default:            /* Invalid */
17990            MIPS_INVAL("MASK INSV");
17991            generate_exception_end(ctx, EXCP_RI);
17992            break;
17993        }
17994        break;
17995    case OPC_APPEND_DSP:
17996        gen_mipsdsp_append(env, ctx, op1, rt, rs, rd);
17997        break;
17998    case OPC_EXTR_W_DSP:
17999        op2 = MASK_EXTR_W(ctx->opcode);
18000        switch (op2) {
18001        case OPC_EXTR_W:
18002        case OPC_EXTR_R_W:
18003        case OPC_EXTR_RS_W:
18004        case OPC_EXTR_S_H:
18005        case OPC_EXTRV_S_H:
18006        case OPC_EXTRV_W:
18007        case OPC_EXTRV_R_W:
18008        case OPC_EXTRV_RS_W:
18009        case OPC_EXTP:
18010        case OPC_EXTPV:
18011        case OPC_EXTPDP:
18012        case OPC_EXTPDPV:
18013            gen_mipsdsp_accinsn(ctx, op1, op2, rt, rs, rd, 1);
18014            break;
18015        case OPC_RDDSP:
18016            gen_mipsdsp_accinsn(ctx, op1, op2, rd, rs, rt, 1);
18017            break;
18018        case OPC_SHILO:
18019        case OPC_SHILOV:
18020        case OPC_MTHLIP:
18021        case OPC_WRDSP:
18022            gen_mipsdsp_accinsn(ctx, op1, op2, rd, rs, rt, 0);
18023            break;
18024        default:            /* Invalid */
18025            MIPS_INVAL("MASK EXTR.W");
18026            generate_exception_end(ctx, EXCP_RI);
18027            break;
18028        }
18029        break;
18030#if defined(TARGET_MIPS64)
18031    case OPC_DDIV_G_2E ... OPC_DDIVU_G_2E:
18032    case OPC_DMULT_G_2E ... OPC_DMULTU_G_2E:
18033    case OPC_DMOD_G_2E ... OPC_DMODU_G_2E:
18034        check_insn(ctx, INSN_LOONGSON2E);
18035        gen_loongson_integer(ctx, op1, rd, rs, rt);
18036        break;
18037    case OPC_ABSQ_S_QH_DSP:
18038        op2 = MASK_ABSQ_S_QH(ctx->opcode);
18039        switch (op2) {
18040        case OPC_PRECEQ_L_PWL:
18041        case OPC_PRECEQ_L_PWR:
18042        case OPC_PRECEQ_PW_QHL:
18043        case OPC_PRECEQ_PW_QHR:
18044        case OPC_PRECEQ_PW_QHLA:
18045        case OPC_PRECEQ_PW_QHRA:
18046        case OPC_PRECEQU_QH_OBL:
18047        case OPC_PRECEQU_QH_OBR:
18048        case OPC_PRECEQU_QH_OBLA:
18049        case OPC_PRECEQU_QH_OBRA:
18050        case OPC_PRECEU_QH_OBL:
18051        case OPC_PRECEU_QH_OBR:
18052        case OPC_PRECEU_QH_OBLA:
18053        case OPC_PRECEU_QH_OBRA:
18054        case OPC_ABSQ_S_OB:
18055        case OPC_ABSQ_S_PW:
18056        case OPC_ABSQ_S_QH:
18057            gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
18058            break;
18059        case OPC_REPL_OB:
18060        case OPC_REPL_PW:
18061        case OPC_REPL_QH:
18062        case OPC_REPLV_OB:
18063        case OPC_REPLV_PW:
18064        case OPC_REPLV_QH:
18065            gen_mipsdsp_bitinsn(ctx, op1, op2, rd, rt);
18066            break;
18067        default:            /* Invalid */
18068            MIPS_INVAL("MASK ABSQ_S.QH");
18069            generate_exception_end(ctx, EXCP_RI);
18070            break;
18071        }
18072        break;
18073    case OPC_ADDU_OB_DSP:
18074        op2 = MASK_ADDU_OB(ctx->opcode);
18075        switch (op2) {
18076        case OPC_RADDU_L_OB:
18077        case OPC_SUBQ_PW:
18078        case OPC_SUBQ_S_PW:
18079        case OPC_SUBQ_QH:
18080        case OPC_SUBQ_S_QH:
18081        case OPC_SUBU_OB:
18082        case OPC_SUBU_S_OB:
18083        case OPC_SUBU_QH:
18084        case OPC_SUBU_S_QH:
18085        case OPC_SUBUH_OB:
18086        case OPC_SUBUH_R_OB:
18087        case OPC_ADDQ_PW:
18088        case OPC_ADDQ_S_PW:
18089        case OPC_ADDQ_QH:
18090        case OPC_ADDQ_S_QH:
18091        case OPC_ADDU_OB:
18092        case OPC_ADDU_S_OB:
18093        case OPC_ADDU_QH:
18094        case OPC_ADDU_S_QH:
18095        case OPC_ADDUH_OB:
18096        case OPC_ADDUH_R_OB:
18097            gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
18098            break;
18099        case OPC_MULEQ_S_PW_QHL:
18100        case OPC_MULEQ_S_PW_QHR:
18101        case OPC_MULEU_S_QH_OBL:
18102        case OPC_MULEU_S_QH_OBR:
18103        case OPC_MULQ_RS_QH:
18104            gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 1);
18105            break;
18106        default:            /* Invalid */
18107            MIPS_INVAL("MASK ADDU.OB");
18108            generate_exception_end(ctx, EXCP_RI);
18109            break;
18110        }
18111        break;
18112    case OPC_CMPU_EQ_OB_DSP:
18113        op2 = MASK_CMPU_EQ_OB(ctx->opcode);
18114        switch (op2) {
18115        case OPC_PRECR_SRA_QH_PW:
18116        case OPC_PRECR_SRA_R_QH_PW:
18117            /* Return value is rt. */
18118            gen_mipsdsp_arith(ctx, op1, op2, rt, rs, rd);
18119            break;
18120        case OPC_PRECR_OB_QH:
18121        case OPC_PRECRQ_OB_QH:
18122        case OPC_PRECRQ_PW_L:
18123        case OPC_PRECRQ_QH_PW:
18124        case OPC_PRECRQ_RS_QH_PW:
18125        case OPC_PRECRQU_S_OB_QH:
18126            gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
18127            break;
18128        case OPC_CMPU_EQ_OB:
18129        case OPC_CMPU_LT_OB:
18130        case OPC_CMPU_LE_OB:
18131        case OPC_CMP_EQ_QH:
18132        case OPC_CMP_LT_QH:
18133        case OPC_CMP_LE_QH:
18134        case OPC_CMP_EQ_PW:
18135        case OPC_CMP_LT_PW:
18136        case OPC_CMP_LE_PW:
18137            gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 0);
18138            break;
18139        case OPC_CMPGDU_EQ_OB:
18140        case OPC_CMPGDU_LT_OB:
18141        case OPC_CMPGDU_LE_OB:
18142        case OPC_CMPGU_EQ_OB:
18143        case OPC_CMPGU_LT_OB:
18144        case OPC_CMPGU_LE_OB:
18145        case OPC_PACKRL_PW:
18146        case OPC_PICK_OB:
18147        case OPC_PICK_PW:
18148        case OPC_PICK_QH:
18149            gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 1);
18150            break;
18151        default:            /* Invalid */
18152            MIPS_INVAL("MASK CMPU_EQ.OB");
18153            generate_exception_end(ctx, EXCP_RI);
18154            break;
18155        }
18156        break;
18157    case OPC_DAPPEND_DSP:
18158        gen_mipsdsp_append(env, ctx, op1, rt, rs, rd);
18159        break;
18160    case OPC_DEXTR_W_DSP:
18161        op2 = MASK_DEXTR_W(ctx->opcode);
18162        switch (op2) {
18163        case OPC_DEXTP:
18164        case OPC_DEXTPDP:
18165        case OPC_DEXTPDPV:
18166        case OPC_DEXTPV:
18167        case OPC_DEXTR_L:
18168        case OPC_DEXTR_R_L:
18169        case OPC_DEXTR_RS_L:
18170        case OPC_DEXTR_W:
18171        case OPC_DEXTR_R_W:
18172        case OPC_DEXTR_RS_W:
18173        case OPC_DEXTR_S_H:
18174        case OPC_DEXTRV_L:
18175        case OPC_DEXTRV_R_L:
18176        case OPC_DEXTRV_RS_L:
18177        case OPC_DEXTRV_S_H:
18178        case OPC_DEXTRV_W:
18179        case OPC_DEXTRV_R_W:
18180        case OPC_DEXTRV_RS_W:
18181            gen_mipsdsp_accinsn(ctx, op1, op2, rt, rs, rd, 1);
18182            break;
18183        case OPC_DMTHLIP:
18184        case OPC_DSHILO:
18185        case OPC_DSHILOV:
18186            gen_mipsdsp_accinsn(ctx, op1, op2, rd, rs, rt, 0);
18187            break;
18188        default:            /* Invalid */
18189            MIPS_INVAL("MASK EXTR.W");
18190            generate_exception_end(ctx, EXCP_RI);
18191            break;
18192        }
18193        break;
18194    case OPC_DPAQ_W_QH_DSP:
18195        op2 = MASK_DPAQ_W_QH(ctx->opcode);
18196        switch (op2) {
18197        case OPC_DPAU_H_OBL:
18198        case OPC_DPAU_H_OBR:
18199        case OPC_DPSU_H_OBL:
18200        case OPC_DPSU_H_OBR:
18201        case OPC_DPA_W_QH:
18202        case OPC_DPAQ_S_W_QH:
18203        case OPC_DPS_W_QH:
18204        case OPC_DPSQ_S_W_QH:
18205        case OPC_MULSAQ_S_W_QH:
18206        case OPC_DPAQ_SA_L_PW:
18207        case OPC_DPSQ_SA_L_PW:
18208        case OPC_MULSAQ_S_L_PW:
18209            gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 0);
18210            break;
18211        case OPC_MAQ_S_W_QHLL:
18212        case OPC_MAQ_S_W_QHLR:
18213        case OPC_MAQ_S_W_QHRL:
18214        case OPC_MAQ_S_W_QHRR:
18215        case OPC_MAQ_SA_W_QHLL:
18216        case OPC_MAQ_SA_W_QHLR:
18217        case OPC_MAQ_SA_W_QHRL:
18218        case OPC_MAQ_SA_W_QHRR:
18219        case OPC_MAQ_S_L_PWL:
18220        case OPC_MAQ_S_L_PWR:
18221        case OPC_DMADD:
18222        case OPC_DMADDU:
18223        case OPC_DMSUB:
18224        case OPC_DMSUBU:
18225            gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 0);
18226            break;
18227        default:            /* Invalid */
18228            MIPS_INVAL("MASK DPAQ.W.QH");
18229            generate_exception_end(ctx, EXCP_RI);
18230            break;
18231        }
18232        break;
18233    case OPC_DINSV_DSP:
18234        op2 = MASK_INSV(ctx->opcode);
18235        switch (op2) {
18236        case OPC_DINSV:
18237        {
18238            TCGv t0, t1;
18239
18240            if (rt == 0) {
18241                break;
18242            }
18243            check_dsp(ctx);
18244
18245            t0 = tcg_temp_new();
18246            t1 = tcg_temp_new();
18247
18248            gen_load_gpr(t0, rt);
18249            gen_load_gpr(t1, rs);
18250
18251            gen_helper_dinsv(cpu_gpr[rt], cpu_env, t1, t0);
18252
18253            tcg_temp_free(t0);
18254            tcg_temp_free(t1);
18255            break;
18256        }
18257        default:            /* Invalid */
18258            MIPS_INVAL("MASK DINSV");
18259            generate_exception_end(ctx, EXCP_RI);
18260            break;
18261        }
18262        break;
18263    case OPC_SHLL_OB_DSP:
18264        gen_mipsdsp_shift(ctx, op1, rd, rs, rt);
18265        break;
18266#endif
18267    default:            /* Invalid */
18268        MIPS_INVAL("special3_legacy");
18269        generate_exception_end(ctx, EXCP_RI);
18270        break;
18271    }
18272}
18273
18274static void decode_opc_special3(CPUMIPSState *env, DisasContext *ctx)
18275{
18276    int rs, rt, rd, sa;
18277    uint32_t op1, op2;
18278    int16_t imm;
18279
18280    rs = (ctx->opcode >> 21) & 0x1f;
18281    rt = (ctx->opcode >> 16) & 0x1f;
18282    rd = (ctx->opcode >> 11) & 0x1f;
18283    sa = (ctx->opcode >> 6) & 0x1f;
18284    imm = sextract32(ctx->opcode, 7, 9);
18285
18286    op1 = MASK_SPECIAL3(ctx->opcode);
18287
18288    /*
18289     * EVA loads and stores overlap Loongson 2E instructions decoded by
18290     * decode_opc_special3_legacy(), so be careful to allow their decoding when
18291     * EVA is absent.
18292     */
18293    if (ctx->eva) {
18294        switch (op1) {
18295        case OPC_LWLE ... OPC_LWRE:
18296            check_insn_opc_removed(ctx, ISA_MIPS32R6);
18297            /* fall through */
18298        case OPC_LBUE ... OPC_LHUE:
18299        case OPC_LBE ... OPC_LWE:
18300            check_cp0_enabled(ctx);
18301            gen_ld(ctx, op1, rt, rs, imm);
18302            return;
18303        case OPC_SWLE ... OPC_SWRE:
18304            check_insn_opc_removed(ctx, ISA_MIPS32R6);
18305            /* fall through */
18306        case OPC_SBE ... OPC_SHE:
18307        case OPC_SWE:
18308            check_cp0_enabled(ctx);
18309            gen_st(ctx, op1, rt, rs, imm);
18310            return;
18311        case OPC_SCE:
18312            check_cp0_enabled(ctx);
18313            gen_st_cond(ctx, op1, rt, rs, imm);
18314            return;
18315        case OPC_CACHEE:
18316            check_cp0_enabled(ctx);
18317            if (ctx->hflags & MIPS_HFLAG_ITC_CACHE) {
18318                gen_cache_operation(ctx, rt, rs, imm);
18319            }
18320            /* Treat as NOP. */
18321            return;
18322        case OPC_PREFE:
18323            check_cp0_enabled(ctx);
18324            /* Treat as NOP. */
18325            return;
18326        }
18327    }
18328
18329    switch (op1) {
18330    case OPC_EXT:
18331    case OPC_INS:
18332        check_insn(ctx, ISA_MIPS32R2);
18333        gen_bitops(ctx, op1, rt, rs, sa, rd);
18334        break;
18335    case OPC_BSHFL:
18336        op2 = MASK_BSHFL(ctx->opcode);
18337        switch (op2) {
18338        case OPC_ALIGN ... OPC_ALIGN_END:
18339        case OPC_BITSWAP:
18340            check_insn(ctx, ISA_MIPS32R6);
18341            decode_opc_special3_r6(env, ctx);
18342            break;
18343        default:
18344            check_insn(ctx, ISA_MIPS32R2);
18345            gen_bshfl(ctx, op2, rt, rd);
18346            break;
18347        }
18348        break;
18349#if defined(TARGET_MIPS64)
18350    case OPC_DEXTM ... OPC_DEXT:
18351    case OPC_DINSM ... OPC_DINS:
18352        check_insn(ctx, ISA_MIPS64R2);
18353        check_mips_64(ctx);
18354        gen_bitops(ctx, op1, rt, rs, sa, rd);
18355        break;
18356    case OPC_DBSHFL:
18357        op2 = MASK_DBSHFL(ctx->opcode);
18358        switch (op2) {
18359        case OPC_DALIGN ... OPC_DALIGN_END:
18360        case OPC_DBITSWAP:
18361            check_insn(ctx, ISA_MIPS32R6);
18362            decode_opc_special3_r6(env, ctx);
18363            break;
18364        default:
18365            check_insn(ctx, ISA_MIPS64R2);
18366            check_mips_64(ctx);
18367            op2 = MASK_DBSHFL(ctx->opcode);
18368            gen_bshfl(ctx, op2, rt, rd);
18369            break;
18370        }
18371        break;
18372#endif
18373    case OPC_RDHWR:
18374        gen_rdhwr(ctx, rt, rd, extract32(ctx->opcode, 6, 3));
18375        break;
18376    case OPC_FORK:
18377        check_insn(ctx, ASE_MT);
18378        {
18379            TCGv t0 = tcg_temp_new();
18380            TCGv t1 = tcg_temp_new();
18381
18382            gen_load_gpr(t0, rt);
18383            gen_load_gpr(t1, rs);
18384            gen_helper_fork(t0, t1);
18385            tcg_temp_free(t0);
18386            tcg_temp_free(t1);
18387        }
18388        break;
18389    case OPC_YIELD:
18390        check_insn(ctx, ASE_MT);
18391        {
18392            TCGv t0 = tcg_temp_new();
18393
18394            gen_load_gpr(t0, rs);
18395            gen_helper_yield(t0, cpu_env, t0);
18396            gen_store_gpr(t0, rd);
18397            tcg_temp_free(t0);
18398        }
18399        break;
18400    default:
18401        if (ctx->insn_flags & ISA_MIPS32R6) {
18402            decode_opc_special3_r6(env, ctx);
18403        } else {
18404            decode_opc_special3_legacy(env, ctx);
18405        }
18406    }
18407}
18408
18409/* MIPS SIMD Architecture (MSA)  */
18410static inline int check_msa_access(DisasContext *ctx)
18411{
18412    if (unlikely((ctx->hflags & MIPS_HFLAG_FPU) &&
18413                 !(ctx->hflags & MIPS_HFLAG_F64))) {
18414        generate_exception_end(ctx, EXCP_RI);
18415        return 0;
18416    }
18417
18418    if (unlikely(!(ctx->hflags & MIPS_HFLAG_MSA))) {
18419        if (ctx->insn_flags & ASE_MSA) {
18420            generate_exception_end(ctx, EXCP_MSADIS);
18421            return 0;
18422        } else {
18423            generate_exception_end(ctx, EXCP_RI);
18424            return 0;
18425        }
18426    }
18427    return 1;
18428}
18429
18430static void gen_check_zero_element(TCGv tresult, uint8_t df, uint8_t wt)
18431{
18432    /* generates tcg ops to check if any element is 0 */
18433    /* Note this function only works with MSA_WRLEN = 128 */
18434    uint64_t eval_zero_or_big = 0;
18435    uint64_t eval_big = 0;
18436    TCGv_i64 t0 = tcg_temp_new_i64();
18437    TCGv_i64 t1 = tcg_temp_new_i64();
18438    switch (df) {
18439    case DF_BYTE:
18440        eval_zero_or_big = 0x0101010101010101ULL;
18441        eval_big = 0x8080808080808080ULL;
18442        break;
18443    case DF_HALF:
18444        eval_zero_or_big = 0x0001000100010001ULL;
18445        eval_big = 0x8000800080008000ULL;
18446        break;
18447    case DF_WORD:
18448        eval_zero_or_big = 0x0000000100000001ULL;
18449        eval_big = 0x8000000080000000ULL;
18450        break;
18451    case DF_DOUBLE:
18452        eval_zero_or_big = 0x0000000000000001ULL;
18453        eval_big = 0x8000000000000000ULL;
18454        break;
18455    }
18456    tcg_gen_subi_i64(t0, msa_wr_d[wt<<1], eval_zero_or_big);
18457    tcg_gen_andc_i64(t0, t0, msa_wr_d[wt<<1]);
18458    tcg_gen_andi_i64(t0, t0, eval_big);
18459    tcg_gen_subi_i64(t1, msa_wr_d[(wt<<1)+1], eval_zero_or_big);
18460    tcg_gen_andc_i64(t1, t1, msa_wr_d[(wt<<1)+1]);
18461    tcg_gen_andi_i64(t1, t1, eval_big);
18462    tcg_gen_or_i64(t0, t0, t1);
18463    /* if all bits are zero then all elements are not zero */
18464    /* if some bit is non-zero then some element is zero */
18465    tcg_gen_setcondi_i64(TCG_COND_NE, t0, t0, 0);
18466    tcg_gen_trunc_i64_tl(tresult, t0);
18467    tcg_temp_free_i64(t0);
18468    tcg_temp_free_i64(t1);
18469}
18470
18471static void gen_msa_branch(CPUMIPSState *env, DisasContext *ctx, uint32_t op1)
18472{
18473    uint8_t df = (ctx->opcode >> 21) & 0x3;
18474    uint8_t wt = (ctx->opcode >> 16) & 0x1f;
18475    int64_t s16 = (int16_t)ctx->opcode;
18476
18477    check_msa_access(ctx);
18478
18479    if (ctx->hflags & MIPS_HFLAG_BMASK) {
18480        generate_exception_end(ctx, EXCP_RI);
18481        return;
18482    }
18483    switch (op1) {
18484    case OPC_BZ_V:
18485    case OPC_BNZ_V:
18486        {
18487            TCGv_i64 t0 = tcg_temp_new_i64();
18488            tcg_gen_or_i64(t0, msa_wr_d[wt<<1], msa_wr_d[(wt<<1)+1]);
18489            tcg_gen_setcondi_i64((op1 == OPC_BZ_V) ?
18490                    TCG_COND_EQ : TCG_COND_NE, t0, t0, 0);
18491            tcg_gen_trunc_i64_tl(bcond, t0);
18492            tcg_temp_free_i64(t0);
18493        }
18494        break;
18495    case OPC_BZ_B:
18496    case OPC_BZ_H:
18497    case OPC_BZ_W:
18498    case OPC_BZ_D:
18499        gen_check_zero_element(bcond, df, wt);
18500        break;
18501    case OPC_BNZ_B:
18502    case OPC_BNZ_H:
18503    case OPC_BNZ_W:
18504    case OPC_BNZ_D:
18505        gen_check_zero_element(bcond, df, wt);
18506        tcg_gen_setcondi_tl(TCG_COND_EQ, bcond, bcond, 0);
18507        break;
18508    }
18509
18510    ctx->btarget = ctx->pc + (s16 << 2) + 4;
18511
18512    ctx->hflags |= MIPS_HFLAG_BC;
18513    ctx->hflags |= MIPS_HFLAG_BDS32;
18514}
18515
18516static void gen_msa_i8(CPUMIPSState *env, DisasContext *ctx)
18517{
18518#define MASK_MSA_I8(op)    (MASK_MSA_MINOR(op) | (op & (0x03 << 24)))
18519    uint8_t i8 = (ctx->opcode >> 16) & 0xff;
18520    uint8_t ws = (ctx->opcode >> 11) & 0x1f;
18521    uint8_t wd = (ctx->opcode >> 6) & 0x1f;
18522
18523    TCGv_i32 twd = tcg_const_i32(wd);
18524    TCGv_i32 tws = tcg_const_i32(ws);
18525    TCGv_i32 ti8 = tcg_const_i32(i8);
18526
18527    switch (MASK_MSA_I8(ctx->opcode)) {
18528    case OPC_ANDI_B:
18529        gen_helper_msa_andi_b(cpu_env, twd, tws, ti8);
18530        break;
18531    case OPC_ORI_B:
18532        gen_helper_msa_ori_b(cpu_env, twd, tws, ti8);
18533        break;
18534    case OPC_NORI_B:
18535        gen_helper_msa_nori_b(cpu_env, twd, tws, ti8);
18536        break;
18537    case OPC_XORI_B:
18538        gen_helper_msa_xori_b(cpu_env, twd, tws, ti8);
18539        break;
18540    case OPC_BMNZI_B:
18541        gen_helper_msa_bmnzi_b(cpu_env, twd, tws, ti8);
18542        break;
18543    case OPC_BMZI_B:
18544        gen_helper_msa_bmzi_b(cpu_env, twd, tws, ti8);
18545        break;
18546    case OPC_BSELI_B:
18547        gen_helper_msa_bseli_b(cpu_env, twd, tws, ti8);
18548        break;
18549    case OPC_SHF_B:
18550    case OPC_SHF_H:
18551    case OPC_SHF_W:
18552        {
18553            uint8_t df = (ctx->opcode >> 24) & 0x3;
18554            if (df == DF_DOUBLE) {
18555                generate_exception_end(ctx, EXCP_RI);
18556            } else {
18557                TCGv_i32 tdf = tcg_const_i32(df);
18558                gen_helper_msa_shf_df(cpu_env, tdf, twd, tws, ti8);
18559                tcg_temp_free_i32(tdf);
18560            }
18561        }
18562        break;
18563    default:
18564        MIPS_INVAL("MSA instruction");
18565        generate_exception_end(ctx, EXCP_RI);
18566        break;
18567    }
18568
18569    tcg_temp_free_i32(twd);
18570    tcg_temp_free_i32(tws);
18571    tcg_temp_free_i32(ti8);
18572}
18573
18574static void gen_msa_i5(CPUMIPSState *env, DisasContext *ctx)
18575{
18576#define MASK_MSA_I5(op)    (MASK_MSA_MINOR(op) | (op & (0x7 << 23)))
18577    uint8_t df = (ctx->opcode >> 21) & 0x3;
18578    int8_t s5 = (int8_t) sextract32(ctx->opcode, 16, 5);
18579    uint8_t u5 = (ctx->opcode >> 16) & 0x1f;
18580    uint8_t ws = (ctx->opcode >> 11) & 0x1f;
18581    uint8_t wd = (ctx->opcode >> 6) & 0x1f;
18582
18583    TCGv_i32 tdf = tcg_const_i32(df);
18584    TCGv_i32 twd = tcg_const_i32(wd);
18585    TCGv_i32 tws = tcg_const_i32(ws);
18586    TCGv_i32 timm = tcg_temp_new_i32();
18587    tcg_gen_movi_i32(timm, u5);
18588
18589    switch (MASK_MSA_I5(ctx->opcode)) {
18590    case OPC_ADDVI_df:
18591        gen_helper_msa_addvi_df(cpu_env, tdf, twd, tws, timm);
18592        break;
18593    case OPC_SUBVI_df:
18594        gen_helper_msa_subvi_df(cpu_env, tdf, twd, tws, timm);
18595        break;
18596    case OPC_MAXI_S_df:
18597        tcg_gen_movi_i32(timm, s5);
18598        gen_helper_msa_maxi_s_df(cpu_env, tdf, twd, tws, timm);
18599        break;
18600    case OPC_MAXI_U_df:
18601        gen_helper_msa_maxi_u_df(cpu_env, tdf, twd, tws, timm);
18602        break;
18603    case OPC_MINI_S_df:
18604        tcg_gen_movi_i32(timm, s5);
18605        gen_helper_msa_mini_s_df(cpu_env, tdf, twd, tws, timm);
18606        break;
18607    case OPC_MINI_U_df:
18608        gen_helper_msa_mini_u_df(cpu_env, tdf, twd, tws, timm);
18609        break;
18610    case OPC_CEQI_df:
18611        tcg_gen_movi_i32(timm, s5);
18612        gen_helper_msa_ceqi_df(cpu_env, tdf, twd, tws, timm);
18613        break;
18614    case OPC_CLTI_S_df:
18615        tcg_gen_movi_i32(timm, s5);
18616        gen_helper_msa_clti_s_df(cpu_env, tdf, twd, tws, timm);
18617        break;
18618    case OPC_CLTI_U_df:
18619        gen_helper_msa_clti_u_df(cpu_env, tdf, twd, tws, timm);
18620        break;
18621    case OPC_CLEI_S_df:
18622        tcg_gen_movi_i32(timm, s5);
18623        gen_helper_msa_clei_s_df(cpu_env, tdf, twd, tws, timm);
18624        break;
18625    case OPC_CLEI_U_df:
18626        gen_helper_msa_clei_u_df(cpu_env, tdf, twd, tws, timm);
18627        break;
18628    case OPC_LDI_df:
18629        {
18630            int32_t s10 = sextract32(ctx->opcode, 11, 10);
18631            tcg_gen_movi_i32(timm, s10);
18632            gen_helper_msa_ldi_df(cpu_env, tdf, twd, timm);
18633        }
18634        break;
18635    default:
18636        MIPS_INVAL("MSA instruction");
18637        generate_exception_end(ctx, EXCP_RI);
18638        break;
18639    }
18640
18641    tcg_temp_free_i32(tdf);
18642    tcg_temp_free_i32(twd);
18643    tcg_temp_free_i32(tws);
18644    tcg_temp_free_i32(timm);
18645}
18646
18647static void gen_msa_bit(CPUMIPSState *env, DisasContext *ctx)
18648{
18649#define MASK_MSA_BIT(op)    (MASK_MSA_MINOR(op) | (op & (0x7 << 23)))
18650    uint8_t dfm = (ctx->opcode >> 16) & 0x7f;
18651    uint32_t df = 0, m = 0;
18652    uint8_t ws = (ctx->opcode >> 11) & 0x1f;
18653    uint8_t wd = (ctx->opcode >> 6) & 0x1f;
18654
18655    TCGv_i32 tdf;
18656    TCGv_i32 tm;
18657    TCGv_i32 twd;
18658    TCGv_i32 tws;
18659
18660    if ((dfm & 0x40) == 0x00) {
18661        m = dfm & 0x3f;
18662        df = DF_DOUBLE;
18663    } else if ((dfm & 0x60) == 0x40) {
18664        m = dfm & 0x1f;
18665        df = DF_WORD;
18666    } else if ((dfm & 0x70) == 0x60) {
18667        m = dfm & 0x0f;
18668        df = DF_HALF;
18669    } else if ((dfm & 0x78) == 0x70) {
18670        m = dfm & 0x7;
18671        df = DF_BYTE;
18672    } else {
18673        generate_exception_end(ctx, EXCP_RI);
18674        return;
18675    }
18676
18677    tdf = tcg_const_i32(df);
18678    tm  = tcg_const_i32(m);
18679    twd = tcg_const_i32(wd);
18680    tws = tcg_const_i32(ws);
18681
18682    switch (MASK_MSA_BIT(ctx->opcode)) {
18683    case OPC_SLLI_df:
18684        gen_helper_msa_slli_df(cpu_env, tdf, twd, tws, tm);
18685        break;
18686    case OPC_SRAI_df:
18687        gen_helper_msa_srai_df(cpu_env, tdf, twd, tws, tm);
18688        break;
18689    case OPC_SRLI_df:
18690        gen_helper_msa_srli_df(cpu_env, tdf, twd, tws, tm);
18691        break;
18692    case OPC_BCLRI_df:
18693        gen_helper_msa_bclri_df(cpu_env, tdf, twd, tws, tm);
18694        break;
18695    case OPC_BSETI_df:
18696        gen_helper_msa_bseti_df(cpu_env, tdf, twd, tws, tm);
18697        break;
18698    case OPC_BNEGI_df:
18699        gen_helper_msa_bnegi_df(cpu_env, tdf, twd, tws, tm);
18700        break;
18701    case OPC_BINSLI_df:
18702        gen_helper_msa_binsli_df(cpu_env, tdf, twd, tws, tm);
18703        break;
18704    case OPC_BINSRI_df:
18705        gen_helper_msa_binsri_df(cpu_env, tdf, twd, tws, tm);
18706        break;
18707    case OPC_SAT_S_df:
18708        gen_helper_msa_sat_s_df(cpu_env, tdf, twd, tws, tm);
18709        break;
18710    case OPC_SAT_U_df:
18711        gen_helper_msa_sat_u_df(cpu_env, tdf, twd, tws, tm);
18712        break;
18713    case OPC_SRARI_df:
18714        gen_helper_msa_srari_df(cpu_env, tdf, twd, tws, tm);
18715        break;
18716    case OPC_SRLRI_df:
18717        gen_helper_msa_srlri_df(cpu_env, tdf, twd, tws, tm);
18718        break;
18719    default:
18720        MIPS_INVAL("MSA instruction");
18721        generate_exception_end(ctx, EXCP_RI);
18722        break;
18723    }
18724
18725    tcg_temp_free_i32(tdf);
18726    tcg_temp_free_i32(tm);
18727    tcg_temp_free_i32(twd);
18728    tcg_temp_free_i32(tws);
18729}
18730
18731static void gen_msa_3r(CPUMIPSState *env, DisasContext *ctx)
18732{
18733#define MASK_MSA_3R(op)    (MASK_MSA_MINOR(op) | (op & (0x7 << 23)))
18734    uint8_t df = (ctx->opcode >> 21) & 0x3;
18735    uint8_t wt = (ctx->opcode >> 16) & 0x1f;
18736    uint8_t ws = (ctx->opcode >> 11) & 0x1f;
18737    uint8_t wd = (ctx->opcode >> 6) & 0x1f;
18738
18739    TCGv_i32 tdf = tcg_const_i32(df);
18740    TCGv_i32 twd = tcg_const_i32(wd);
18741    TCGv_i32 tws = tcg_const_i32(ws);
18742    TCGv_i32 twt = tcg_const_i32(wt);
18743
18744    switch (MASK_MSA_3R(ctx->opcode)) {
18745    case OPC_SLL_df:
18746        gen_helper_msa_sll_df(cpu_env, tdf, twd, tws, twt);
18747        break;
18748    case OPC_ADDV_df:
18749        gen_helper_msa_addv_df(cpu_env, tdf, twd, tws, twt);
18750        break;
18751    case OPC_CEQ_df:
18752        gen_helper_msa_ceq_df(cpu_env, tdf, twd, tws, twt);
18753        break;
18754    case OPC_ADD_A_df:
18755        gen_helper_msa_add_a_df(cpu_env, tdf, twd, tws, twt);
18756        break;
18757    case OPC_SUBS_S_df:
18758        gen_helper_msa_subs_s_df(cpu_env, tdf, twd, tws, twt);
18759        break;
18760    case OPC_MULV_df:
18761        gen_helper_msa_mulv_df(cpu_env, tdf, twd, tws, twt);
18762        break;
18763    case OPC_SLD_df:
18764        gen_helper_msa_sld_df(cpu_env, tdf, twd, tws, twt);
18765        break;
18766    case OPC_VSHF_df:
18767        gen_helper_msa_vshf_df(cpu_env, tdf, twd, tws, twt);
18768        break;
18769    case OPC_SRA_df:
18770        gen_helper_msa_sra_df(cpu_env, tdf, twd, tws, twt);
18771        break;
18772    case OPC_SUBV_df:
18773        gen_helper_msa_subv_df(cpu_env, tdf, twd, tws, twt);
18774        break;
18775    case OPC_ADDS_A_df:
18776        gen_helper_msa_adds_a_df(cpu_env, tdf, twd, tws, twt);
18777        break;
18778    case OPC_SUBS_U_df:
18779        gen_helper_msa_subs_u_df(cpu_env, tdf, twd, tws, twt);
18780        break;
18781    case OPC_MADDV_df:
18782        gen_helper_msa_maddv_df(cpu_env, tdf, twd, tws, twt);
18783        break;
18784    case OPC_SPLAT_df:
18785        gen_helper_msa_splat_df(cpu_env, tdf, twd, tws, twt);
18786        break;
18787    case OPC_SRAR_df:
18788        gen_helper_msa_srar_df(cpu_env, tdf, twd, tws, twt);
18789        break;
18790    case OPC_SRL_df:
18791        gen_helper_msa_srl_df(cpu_env, tdf, twd, tws, twt);
18792        break;
18793    case OPC_MAX_S_df:
18794        gen_helper_msa_max_s_df(cpu_env, tdf, twd, tws, twt);
18795        break;
18796    case OPC_CLT_S_df:
18797        gen_helper_msa_clt_s_df(cpu_env, tdf, twd, tws, twt);
18798        break;
18799    case OPC_ADDS_S_df:
18800        gen_helper_msa_adds_s_df(cpu_env, tdf, twd, tws, twt);
18801        break;
18802    case OPC_SUBSUS_U_df:
18803        gen_helper_msa_subsus_u_df(cpu_env, tdf, twd, tws, twt);
18804        break;
18805    case OPC_MSUBV_df:
18806        gen_helper_msa_msubv_df(cpu_env, tdf, twd, tws, twt);
18807        break;
18808    case OPC_PCKEV_df:
18809        gen_helper_msa_pckev_df(cpu_env, tdf, twd, tws, twt);
18810        break;
18811    case OPC_SRLR_df:
18812        gen_helper_msa_srlr_df(cpu_env, tdf, twd, tws, twt);
18813        break;
18814    case OPC_BCLR_df:
18815        gen_helper_msa_bclr_df(cpu_env, tdf, twd, tws, twt);
18816        break;
18817    case OPC_MAX_U_df:
18818        gen_helper_msa_max_u_df(cpu_env, tdf, twd, tws, twt);
18819        break;
18820    case OPC_CLT_U_df:
18821        gen_helper_msa_clt_u_df(cpu_env, tdf, twd, tws, twt);
18822        break;
18823    case OPC_ADDS_U_df:
18824        gen_helper_msa_adds_u_df(cpu_env, tdf, twd, tws, twt);
18825        break;
18826    case OPC_SUBSUU_S_df:
18827        gen_helper_msa_subsuu_s_df(cpu_env, tdf, twd, tws, twt);
18828        break;
18829    case OPC_PCKOD_df:
18830        gen_helper_msa_pckod_df(cpu_env, tdf, twd, tws, twt);
18831        break;
18832    case OPC_BSET_df:
18833        gen_helper_msa_bset_df(cpu_env, tdf, twd, tws, twt);
18834        break;
18835    case OPC_MIN_S_df:
18836        gen_helper_msa_min_s_df(cpu_env, tdf, twd, tws, twt);
18837        break;
18838    case OPC_CLE_S_df:
18839        gen_helper_msa_cle_s_df(cpu_env, tdf, twd, tws, twt);
18840        break;
18841    case OPC_AVE_S_df:
18842        gen_helper_msa_ave_s_df(cpu_env, tdf, twd, tws, twt);
18843        break;
18844    case OPC_ASUB_S_df:
18845        gen_helper_msa_asub_s_df(cpu_env, tdf, twd, tws, twt);
18846        break;
18847    case OPC_DIV_S_df:
18848        gen_helper_msa_div_s_df(cpu_env, tdf, twd, tws, twt);
18849        break;
18850    case OPC_ILVL_df:
18851        gen_helper_msa_ilvl_df(cpu_env, tdf, twd, tws, twt);
18852        break;
18853    case OPC_BNEG_df:
18854        gen_helper_msa_bneg_df(cpu_env, tdf, twd, tws, twt);
18855        break;
18856    case OPC_MIN_U_df:
18857        gen_helper_msa_min_u_df(cpu_env, tdf, twd, tws, twt);
18858        break;
18859    case OPC_CLE_U_df:
18860        gen_helper_msa_cle_u_df(cpu_env, tdf, twd, tws, twt);
18861        break;
18862    case OPC_AVE_U_df:
18863        gen_helper_msa_ave_u_df(cpu_env, tdf, twd, tws, twt);
18864        break;
18865    case OPC_ASUB_U_df:
18866        gen_helper_msa_asub_u_df(cpu_env, tdf, twd, tws, twt);
18867        break;
18868    case OPC_DIV_U_df:
18869        gen_helper_msa_div_u_df(cpu_env, tdf, twd, tws, twt);
18870        break;
18871    case OPC_ILVR_df:
18872        gen_helper_msa_ilvr_df(cpu_env, tdf, twd, tws, twt);
18873        break;
18874    case OPC_BINSL_df:
18875        gen_helper_msa_binsl_df(cpu_env, tdf, twd, tws, twt);
18876        break;
18877    case OPC_MAX_A_df:
18878        gen_helper_msa_max_a_df(cpu_env, tdf, twd, tws, twt);
18879        break;
18880    case OPC_AVER_S_df:
18881        gen_helper_msa_aver_s_df(cpu_env, tdf, twd, tws, twt);
18882        break;
18883    case OPC_MOD_S_df:
18884        gen_helper_msa_mod_s_df(cpu_env, tdf, twd, tws, twt);
18885        break;
18886    case OPC_ILVEV_df:
18887        gen_helper_msa_ilvev_df(cpu_env, tdf, twd, tws, twt);
18888        break;
18889    case OPC_BINSR_df:
18890        gen_helper_msa_binsr_df(cpu_env, tdf, twd, tws, twt);
18891        break;
18892    case OPC_MIN_A_df:
18893        gen_helper_msa_min_a_df(cpu_env, tdf, twd, tws, twt);
18894        break;
18895    case OPC_AVER_U_df:
18896        gen_helper_msa_aver_u_df(cpu_env, tdf, twd, tws, twt);
18897        break;
18898    case OPC_MOD_U_df:
18899        gen_helper_msa_mod_u_df(cpu_env, tdf, twd, tws, twt);
18900        break;
18901    case OPC_ILVOD_df:
18902        gen_helper_msa_ilvod_df(cpu_env, tdf, twd, tws, twt);
18903        break;
18904
18905    case OPC_DOTP_S_df:
18906    case OPC_DOTP_U_df:
18907    case OPC_DPADD_S_df:
18908    case OPC_DPADD_U_df:
18909    case OPC_DPSUB_S_df:
18910    case OPC_HADD_S_df:
18911    case OPC_DPSUB_U_df:
18912    case OPC_HADD_U_df:
18913    case OPC_HSUB_S_df:
18914    case OPC_HSUB_U_df:
18915        if (df == DF_BYTE) {
18916            generate_exception_end(ctx, EXCP_RI);
18917            break;
18918        }
18919        switch (MASK_MSA_3R(ctx->opcode)) {
18920        case OPC_DOTP_S_df:
18921            gen_helper_msa_dotp_s_df(cpu_env, tdf, twd, tws, twt);
18922            break;
18923        case OPC_DOTP_U_df:
18924            gen_helper_msa_dotp_u_df(cpu_env, tdf, twd, tws, twt);
18925            break;
18926        case OPC_DPADD_S_df:
18927            gen_helper_msa_dpadd_s_df(cpu_env, tdf, twd, tws, twt);
18928            break;
18929        case OPC_DPADD_U_df:
18930            gen_helper_msa_dpadd_u_df(cpu_env, tdf, twd, tws, twt);
18931            break;
18932        case OPC_DPSUB_S_df:
18933            gen_helper_msa_dpsub_s_df(cpu_env, tdf, twd, tws, twt);
18934            break;
18935        case OPC_HADD_S_df:
18936            gen_helper_msa_hadd_s_df(cpu_env, tdf, twd, tws, twt);
18937            break;
18938        case OPC_DPSUB_U_df:
18939            gen_helper_msa_dpsub_u_df(cpu_env, tdf, twd, tws, twt);
18940            break;
18941        case OPC_HADD_U_df:
18942            gen_helper_msa_hadd_u_df(cpu_env, tdf, twd, tws, twt);
18943            break;
18944        case OPC_HSUB_S_df:
18945            gen_helper_msa_hsub_s_df(cpu_env, tdf, twd, tws, twt);
18946            break;
18947        case OPC_HSUB_U_df:
18948            gen_helper_msa_hsub_u_df(cpu_env, tdf, twd, tws, twt);
18949            break;
18950        }
18951        break;
18952    default:
18953        MIPS_INVAL("MSA instruction");
18954        generate_exception_end(ctx, EXCP_RI);
18955        break;
18956    }
18957    tcg_temp_free_i32(twd);
18958    tcg_temp_free_i32(tws);
18959    tcg_temp_free_i32(twt);
18960    tcg_temp_free_i32(tdf);
18961}
18962
18963static void gen_msa_elm_3e(CPUMIPSState *env, DisasContext *ctx)
18964{
18965#define MASK_MSA_ELM_DF3E(op)   (MASK_MSA_MINOR(op) | (op & (0x3FF << 16)))
18966    uint8_t source = (ctx->opcode >> 11) & 0x1f;
18967    uint8_t dest = (ctx->opcode >> 6) & 0x1f;
18968    TCGv telm = tcg_temp_new();
18969    TCGv_i32 tsr = tcg_const_i32(source);
18970    TCGv_i32 tdt = tcg_const_i32(dest);
18971
18972    switch (MASK_MSA_ELM_DF3E(ctx->opcode)) {
18973    case OPC_CTCMSA:
18974        gen_load_gpr(telm, source);
18975        gen_helper_msa_ctcmsa(cpu_env, telm, tdt);
18976        break;
18977    case OPC_CFCMSA:
18978        gen_helper_msa_cfcmsa(telm, cpu_env, tsr);
18979        gen_store_gpr(telm, dest);
18980        break;
18981    case OPC_MOVE_V:
18982        gen_helper_msa_move_v(cpu_env, tdt, tsr);
18983        break;
18984    default:
18985        MIPS_INVAL("MSA instruction");
18986        generate_exception_end(ctx, EXCP_RI);
18987        break;
18988    }
18989
18990    tcg_temp_free(telm);
18991    tcg_temp_free_i32(tdt);
18992    tcg_temp_free_i32(tsr);
18993}
18994
18995static void gen_msa_elm_df(CPUMIPSState *env, DisasContext *ctx, uint32_t df,
18996        uint32_t n)
18997{
18998#define MASK_MSA_ELM(op)    (MASK_MSA_MINOR(op) | (op & (0xf << 22)))
18999    uint8_t ws = (ctx->opcode >> 11) & 0x1f;
19000    uint8_t wd = (ctx->opcode >> 6) & 0x1f;
19001
19002    TCGv_i32 tws = tcg_const_i32(ws);
19003    TCGv_i32 twd = tcg_const_i32(wd);
19004    TCGv_i32 tn  = tcg_const_i32(n);
19005    TCGv_i32 tdf = tcg_const_i32(df);
19006
19007    switch (MASK_MSA_ELM(ctx->opcode)) {
19008    case OPC_SLDI_df:
19009        gen_helper_msa_sldi_df(cpu_env, tdf, twd, tws, tn);
19010        break;
19011    case OPC_SPLATI_df:
19012        gen_helper_msa_splati_df(cpu_env, tdf, twd, tws, tn);
19013        break;
19014    case OPC_INSVE_df:
19015        gen_helper_msa_insve_df(cpu_env, tdf, twd, tws, tn);
19016        break;
19017    case OPC_COPY_S_df:
19018    case OPC_COPY_U_df:
19019    case OPC_INSERT_df:
19020#if !defined(TARGET_MIPS64)
19021        /* Double format valid only for MIPS64 */
19022        if (df == DF_DOUBLE) {
19023            generate_exception_end(ctx, EXCP_RI);
19024            break;
19025        }
19026#endif
19027        switch (MASK_MSA_ELM(ctx->opcode)) {
19028        case OPC_COPY_S_df:
19029            if (likely(wd != 0)) {
19030                gen_helper_msa_copy_s_df(cpu_env, tdf, twd, tws, tn);
19031            }
19032            break;
19033        case OPC_COPY_U_df:
19034            if (likely(wd != 0)) {
19035                gen_helper_msa_copy_u_df(cpu_env, tdf, twd, tws, tn);
19036            }
19037            break;
19038        case OPC_INSERT_df:
19039            gen_helper_msa_insert_df(cpu_env, tdf, twd, tws, tn);
19040            break;
19041        }
19042        break;
19043    default:
19044        MIPS_INVAL("MSA instruction");
19045        generate_exception_end(ctx, EXCP_RI);
19046    }
19047    tcg_temp_free_i32(twd);
19048    tcg_temp_free_i32(tws);
19049    tcg_temp_free_i32(tn);
19050    tcg_temp_free_i32(tdf);
19051}
19052
19053static void gen_msa_elm(CPUMIPSState *env, DisasContext *ctx)
19054{
19055    uint8_t dfn = (ctx->opcode >> 16) & 0x3f;
19056    uint32_t df = 0, n = 0;
19057
19058    if ((dfn & 0x30) == 0x00) {
19059        n = dfn & 0x0f;
19060        df = DF_BYTE;
19061    } else if ((dfn & 0x38) == 0x20) {
19062        n = dfn & 0x07;
19063        df = DF_HALF;
19064    } else if ((dfn & 0x3c) == 0x30) {
19065        n = dfn & 0x03;
19066        df = DF_WORD;
19067    } else if ((dfn & 0x3e) == 0x38) {
19068        n = dfn & 0x01;
19069        df = DF_DOUBLE;
19070    } else if (dfn == 0x3E) {
19071        /* CTCMSA, CFCMSA, MOVE.V */
19072        gen_msa_elm_3e(env, ctx);
19073        return;
19074    } else {
19075        generate_exception_end(ctx, EXCP_RI);
19076        return;
19077    }
19078
19079    gen_msa_elm_df(env, ctx, df, n);
19080}
19081
19082static void gen_msa_3rf(CPUMIPSState *env, DisasContext *ctx)
19083{
19084#define MASK_MSA_3RF(op)    (MASK_MSA_MINOR(op) | (op & (0xf << 22)))
19085    uint8_t df = (ctx->opcode >> 21) & 0x1;
19086    uint8_t wt = (ctx->opcode >> 16) & 0x1f;
19087    uint8_t ws = (ctx->opcode >> 11) & 0x1f;
19088    uint8_t wd = (ctx->opcode >> 6) & 0x1f;
19089
19090    TCGv_i32 twd = tcg_const_i32(wd);
19091    TCGv_i32 tws = tcg_const_i32(ws);
19092    TCGv_i32 twt = tcg_const_i32(wt);
19093    TCGv_i32 tdf = tcg_temp_new_i32();
19094
19095    /* adjust df value for floating-point instruction */
19096    tcg_gen_movi_i32(tdf, df + 2);
19097
19098    switch (MASK_MSA_3RF(ctx->opcode)) {
19099    case OPC_FCAF_df:
19100        gen_helper_msa_fcaf_df(cpu_env, tdf, twd, tws, twt);
19101        break;
19102    case OPC_FADD_df:
19103        gen_helper_msa_fadd_df(cpu_env, tdf, twd, tws, twt);
19104        break;
19105    case OPC_FCUN_df:
19106        gen_helper_msa_fcun_df(cpu_env, tdf, twd, tws, twt);
19107        break;
19108    case OPC_FSUB_df:
19109        gen_helper_msa_fsub_df(cpu_env, tdf, twd, tws, twt);
19110        break;
19111    case OPC_FCOR_df:
19112        gen_helper_msa_fcor_df(cpu_env, tdf, twd, tws, twt);
19113        break;
19114    case OPC_FCEQ_df:
19115        gen_helper_msa_fceq_df(cpu_env, tdf, twd, tws, twt);
19116        break;
19117    case OPC_FMUL_df:
19118        gen_helper_msa_fmul_df(cpu_env, tdf, twd, tws, twt);
19119        break;
19120    case OPC_FCUNE_df:
19121        gen_helper_msa_fcune_df(cpu_env, tdf, twd, tws, twt);
19122        break;
19123    case OPC_FCUEQ_df:
19124        gen_helper_msa_fcueq_df(cpu_env, tdf, twd, tws, twt);
19125        break;
19126    case OPC_FDIV_df:
19127        gen_helper_msa_fdiv_df(cpu_env, tdf, twd, tws, twt);
19128        break;
19129    case OPC_FCNE_df:
19130        gen_helper_msa_fcne_df(cpu_env, tdf, twd, tws, twt);
19131        break;
19132    case OPC_FCLT_df:
19133        gen_helper_msa_fclt_df(cpu_env, tdf, twd, tws, twt);
19134        break;
19135    case OPC_FMADD_df:
19136        gen_helper_msa_fmadd_df(cpu_env, tdf, twd, tws, twt);
19137        break;
19138    case OPC_MUL_Q_df:
19139        tcg_gen_movi_i32(tdf, df + 1);
19140        gen_helper_msa_mul_q_df(cpu_env, tdf, twd, tws, twt);
19141        break;
19142    case OPC_FCULT_df:
19143        gen_helper_msa_fcult_df(cpu_env, tdf, twd, tws, twt);
19144        break;
19145    case OPC_FMSUB_df:
19146        gen_helper_msa_fmsub_df(cpu_env, tdf, twd, tws, twt);
19147        break;
19148    case OPC_MADD_Q_df:
19149        tcg_gen_movi_i32(tdf, df + 1);
19150        gen_helper_msa_madd_q_df(cpu_env, tdf, twd, tws, twt);
19151        break;
19152    case OPC_FCLE_df:
19153        gen_helper_msa_fcle_df(cpu_env, tdf, twd, tws, twt);
19154        break;
19155    case OPC_MSUB_Q_df:
19156        tcg_gen_movi_i32(tdf, df + 1);
19157        gen_helper_msa_msub_q_df(cpu_env, tdf, twd, tws, twt);
19158        break;
19159    case OPC_FCULE_df:
19160        gen_helper_msa_fcule_df(cpu_env, tdf, twd, tws, twt);
19161        break;
19162    case OPC_FEXP2_df:
19163        gen_helper_msa_fexp2_df(cpu_env, tdf, twd, tws, twt);
19164        break;
19165    case OPC_FSAF_df:
19166        gen_helper_msa_fsaf_df(cpu_env, tdf, twd, tws, twt);
19167        break;
19168    case OPC_FEXDO_df:
19169        gen_helper_msa_fexdo_df(cpu_env, tdf, twd, tws, twt);
19170        break;
19171    case OPC_FSUN_df:
19172        gen_helper_msa_fsun_df(cpu_env, tdf, twd, tws, twt);
19173        break;
19174    case OPC_FSOR_df:
19175        gen_helper_msa_fsor_df(cpu_env, tdf, twd, tws, twt);
19176        break;
19177    case OPC_FSEQ_df:
19178        gen_helper_msa_fseq_df(cpu_env, tdf, twd, tws, twt);
19179        break;
19180    case OPC_FTQ_df:
19181        gen_helper_msa_ftq_df(cpu_env, tdf, twd, tws, twt);
19182        break;
19183    case OPC_FSUNE_df:
19184        gen_helper_msa_fsune_df(cpu_env, tdf, twd, tws, twt);
19185        break;
19186    case OPC_FSUEQ_df:
19187        gen_helper_msa_fsueq_df(cpu_env, tdf, twd, tws, twt);
19188        break;
19189    case OPC_FSNE_df:
19190        gen_helper_msa_fsne_df(cpu_env, tdf, twd, tws, twt);
19191        break;
19192    case OPC_FSLT_df:
19193        gen_helper_msa_fslt_df(cpu_env, tdf, twd, tws, twt);
19194        break;
19195    case OPC_FMIN_df:
19196        gen_helper_msa_fmin_df(cpu_env, tdf, twd, tws, twt);
19197        break;
19198    case OPC_MULR_Q_df:
19199        tcg_gen_movi_i32(tdf, df + 1);
19200        gen_helper_msa_mulr_q_df(cpu_env, tdf, twd, tws, twt);
19201        break;
19202    case OPC_FSULT_df:
19203        gen_helper_msa_fsult_df(cpu_env, tdf, twd, tws, twt);
19204        break;
19205    case OPC_FMIN_A_df:
19206        gen_helper_msa_fmin_a_df(cpu_env, tdf, twd, tws, twt);
19207        break;
19208    case OPC_MADDR_Q_df:
19209        tcg_gen_movi_i32(tdf, df + 1);
19210        gen_helper_msa_maddr_q_df(cpu_env, tdf, twd, tws, twt);
19211        break;
19212    case OPC_FSLE_df:
19213        gen_helper_msa_fsle_df(cpu_env, tdf, twd, tws, twt);
19214        break;
19215    case OPC_FMAX_df:
19216        gen_helper_msa_fmax_df(cpu_env, tdf, twd, tws, twt);
19217        break;
19218    case OPC_MSUBR_Q_df:
19219        tcg_gen_movi_i32(tdf, df + 1);
19220        gen_helper_msa_msubr_q_df(cpu_env, tdf, twd, tws, twt);
19221        break;
19222    case OPC_FSULE_df:
19223        gen_helper_msa_fsule_df(cpu_env, tdf, twd, tws, twt);
19224        break;
19225    case OPC_FMAX_A_df:
19226        gen_helper_msa_fmax_a_df(cpu_env, tdf, twd, tws, twt);
19227        break;
19228    default:
19229        MIPS_INVAL("MSA instruction");
19230        generate_exception_end(ctx, EXCP_RI);
19231        break;
19232    }
19233
19234    tcg_temp_free_i32(twd);
19235    tcg_temp_free_i32(tws);
19236    tcg_temp_free_i32(twt);
19237    tcg_temp_free_i32(tdf);
19238}
19239
19240static void gen_msa_2r(CPUMIPSState *env, DisasContext *ctx)
19241{
19242#define MASK_MSA_2R(op)     (MASK_MSA_MINOR(op) | (op & (0x1f << 21)) | \
19243                            (op & (0x7 << 18)))
19244    uint8_t wt = (ctx->opcode >> 16) & 0x1f;
19245    uint8_t ws = (ctx->opcode >> 11) & 0x1f;
19246    uint8_t wd = (ctx->opcode >> 6) & 0x1f;
19247    uint8_t df = (ctx->opcode >> 16) & 0x3;
19248    TCGv_i32 twd = tcg_const_i32(wd);
19249    TCGv_i32 tws = tcg_const_i32(ws);
19250    TCGv_i32 twt = tcg_const_i32(wt);
19251    TCGv_i32 tdf = tcg_const_i32(df);
19252
19253    switch (MASK_MSA_2R(ctx->opcode)) {
19254    case OPC_FILL_df:
19255#if !defined(TARGET_MIPS64)
19256        /* Double format valid only for MIPS64 */
19257        if (df == DF_DOUBLE) {
19258            generate_exception_end(ctx, EXCP_RI);
19259            break;
19260        }
19261#endif
19262        gen_helper_msa_fill_df(cpu_env, tdf, twd, tws); /* trs */
19263        break;
19264    case OPC_PCNT_df:
19265        gen_helper_msa_pcnt_df(cpu_env, tdf, twd, tws);
19266        break;
19267    case OPC_NLOC_df:
19268        gen_helper_msa_nloc_df(cpu_env, tdf, twd, tws);
19269        break;
19270    case OPC_NLZC_df:
19271        gen_helper_msa_nlzc_df(cpu_env, tdf, twd, tws);
19272        break;
19273    default:
19274        MIPS_INVAL("MSA instruction");
19275        generate_exception_end(ctx, EXCP_RI);
19276        break;
19277    }
19278
19279    tcg_temp_free_i32(twd);
19280    tcg_temp_free_i32(tws);
19281    tcg_temp_free_i32(twt);
19282    tcg_temp_free_i32(tdf);
19283}
19284
19285static void gen_msa_2rf(CPUMIPSState *env, DisasContext *ctx)
19286{
19287#define MASK_MSA_2RF(op)    (MASK_MSA_MINOR(op) | (op & (0x1f << 21)) | \
19288                            (op & (0xf << 17)))
19289    uint8_t wt = (ctx->opcode >> 16) & 0x1f;
19290    uint8_t ws = (ctx->opcode >> 11) & 0x1f;
19291    uint8_t wd = (ctx->opcode >> 6) & 0x1f;
19292    uint8_t df = (ctx->opcode >> 16) & 0x1;
19293    TCGv_i32 twd = tcg_const_i32(wd);
19294    TCGv_i32 tws = tcg_const_i32(ws);
19295    TCGv_i32 twt = tcg_const_i32(wt);
19296    /* adjust df value for floating-point instruction */
19297    TCGv_i32 tdf = tcg_const_i32(df + 2);
19298
19299    switch (MASK_MSA_2RF(ctx->opcode)) {
19300    case OPC_FCLASS_df:
19301        gen_helper_msa_fclass_df(cpu_env, tdf, twd, tws);
19302        break;
19303    case OPC_FTRUNC_S_df:
19304        gen_helper_msa_ftrunc_s_df(cpu_env, tdf, twd, tws);
19305        break;
19306    case OPC_FTRUNC_U_df:
19307        gen_helper_msa_ftrunc_u_df(cpu_env, tdf, twd, tws);
19308        break;
19309    case OPC_FSQRT_df:
19310        gen_helper_msa_fsqrt_df(cpu_env, tdf, twd, tws);
19311        break;
19312    case OPC_FRSQRT_df:
19313        gen_helper_msa_frsqrt_df(cpu_env, tdf, twd, tws);
19314        break;
19315    case OPC_FRCP_df:
19316        gen_helper_msa_frcp_df(cpu_env, tdf, twd, tws);
19317        break;
19318    case OPC_FRINT_df:
19319        gen_helper_msa_frint_df(cpu_env, tdf, twd, tws);
19320        break;
19321    case OPC_FLOG2_df:
19322        gen_helper_msa_flog2_df(cpu_env, tdf, twd, tws);
19323        break;
19324    case OPC_FEXUPL_df:
19325        gen_helper_msa_fexupl_df(cpu_env, tdf, twd, tws);
19326        break;
19327    case OPC_FEXUPR_df:
19328        gen_helper_msa_fexupr_df(cpu_env, tdf, twd, tws);
19329        break;
19330    case OPC_FFQL_df:
19331        gen_helper_msa_ffql_df(cpu_env, tdf, twd, tws);
19332        break;
19333    case OPC_FFQR_df:
19334        gen_helper_msa_ffqr_df(cpu_env, tdf, twd, tws);
19335        break;
19336    case OPC_FTINT_S_df:
19337        gen_helper_msa_ftint_s_df(cpu_env, tdf, twd, tws);
19338        break;
19339    case OPC_FTINT_U_df:
19340        gen_helper_msa_ftint_u_df(cpu_env, tdf, twd, tws);
19341        break;
19342    case OPC_FFINT_S_df:
19343        gen_helper_msa_ffint_s_df(cpu_env, tdf, twd, tws);
19344        break;
19345    case OPC_FFINT_U_df:
19346        gen_helper_msa_ffint_u_df(cpu_env, tdf, twd, tws);
19347        break;
19348    }
19349
19350    tcg_temp_free_i32(twd);
19351    tcg_temp_free_i32(tws);
19352    tcg_temp_free_i32(twt);
19353    tcg_temp_free_i32(tdf);
19354}
19355
19356static void gen_msa_vec_v(CPUMIPSState *env, DisasContext *ctx)
19357{
19358#define MASK_MSA_VEC(op)    (MASK_MSA_MINOR(op) | (op & (0x1f << 21)))
19359    uint8_t wt = (ctx->opcode >> 16) & 0x1f;
19360    uint8_t ws = (ctx->opcode >> 11) & 0x1f;
19361    uint8_t wd = (ctx->opcode >> 6) & 0x1f;
19362    TCGv_i32 twd = tcg_const_i32(wd);
19363    TCGv_i32 tws = tcg_const_i32(ws);
19364    TCGv_i32 twt = tcg_const_i32(wt);
19365
19366    switch (MASK_MSA_VEC(ctx->opcode)) {
19367    case OPC_AND_V:
19368        gen_helper_msa_and_v(cpu_env, twd, tws, twt);
19369        break;
19370    case OPC_OR_V:
19371        gen_helper_msa_or_v(cpu_env, twd, tws, twt);
19372        break;
19373    case OPC_NOR_V:
19374        gen_helper_msa_nor_v(cpu_env, twd, tws, twt);
19375        break;
19376    case OPC_XOR_V:
19377        gen_helper_msa_xor_v(cpu_env, twd, tws, twt);
19378        break;
19379    case OPC_BMNZ_V:
19380        gen_helper_msa_bmnz_v(cpu_env, twd, tws, twt);
19381        break;
19382    case OPC_BMZ_V:
19383        gen_helper_msa_bmz_v(cpu_env, twd, tws, twt);
19384        break;
19385    case OPC_BSEL_V:
19386        gen_helper_msa_bsel_v(cpu_env, twd, tws, twt);
19387        break;
19388    default:
19389        MIPS_INVAL("MSA instruction");
19390        generate_exception_end(ctx, EXCP_RI);
19391        break;
19392    }
19393
19394    tcg_temp_free_i32(twd);
19395    tcg_temp_free_i32(tws);
19396    tcg_temp_free_i32(twt);
19397}
19398
19399static void gen_msa_vec(CPUMIPSState *env, DisasContext *ctx)
19400{
19401    switch (MASK_MSA_VEC(ctx->opcode)) {
19402    case OPC_AND_V:
19403    case OPC_OR_V:
19404    case OPC_NOR_V:
19405    case OPC_XOR_V:
19406    case OPC_BMNZ_V:
19407    case OPC_BMZ_V:
19408    case OPC_BSEL_V:
19409        gen_msa_vec_v(env, ctx);
19410        break;
19411    case OPC_MSA_2R:
19412        gen_msa_2r(env, ctx);
19413        break;
19414    case OPC_MSA_2RF:
19415        gen_msa_2rf(env, ctx);
19416        break;
19417    default:
19418        MIPS_INVAL("MSA instruction");
19419        generate_exception_end(ctx, EXCP_RI);
19420        break;
19421    }
19422}
19423
19424static void gen_msa(CPUMIPSState *env, DisasContext *ctx)
19425{
19426    uint32_t opcode = ctx->opcode;
19427    check_insn(ctx, ASE_MSA);
19428    check_msa_access(ctx);
19429
19430    switch (MASK_MSA_MINOR(opcode)) {
19431    case OPC_MSA_I8_00:
19432    case OPC_MSA_I8_01:
19433    case OPC_MSA_I8_02:
19434        gen_msa_i8(env, ctx);
19435        break;
19436    case OPC_MSA_I5_06:
19437    case OPC_MSA_I5_07:
19438        gen_msa_i5(env, ctx);
19439        break;
19440    case OPC_MSA_BIT_09:
19441    case OPC_MSA_BIT_0A:
19442        gen_msa_bit(env, ctx);
19443        break;
19444    case OPC_MSA_3R_0D:
19445    case OPC_MSA_3R_0E:
19446    case OPC_MSA_3R_0F:
19447    case OPC_MSA_3R_10:
19448    case OPC_MSA_3R_11:
19449    case OPC_MSA_3R_12:
19450    case OPC_MSA_3R_13:
19451    case OPC_MSA_3R_14:
19452    case OPC_MSA_3R_15:
19453        gen_msa_3r(env, ctx);
19454        break;
19455    case OPC_MSA_ELM:
19456        gen_msa_elm(env, ctx);
19457        break;
19458    case OPC_MSA_3RF_1A:
19459    case OPC_MSA_3RF_1B:
19460    case OPC_MSA_3RF_1C:
19461        gen_msa_3rf(env, ctx);
19462        break;
19463    case OPC_MSA_VEC:
19464        gen_msa_vec(env, ctx);
19465        break;
19466    case OPC_LD_B:
19467    case OPC_LD_H:
19468    case OPC_LD_W:
19469    case OPC_LD_D:
19470    case OPC_ST_B:
19471    case OPC_ST_H:
19472    case OPC_ST_W:
19473    case OPC_ST_D:
19474        {
19475            int32_t s10 = sextract32(ctx->opcode, 16, 10);
19476            uint8_t rs = (ctx->opcode >> 11) & 0x1f;
19477            uint8_t wd = (ctx->opcode >> 6) & 0x1f;
19478            uint8_t df = (ctx->opcode >> 0) & 0x3;
19479
19480            TCGv_i32 twd = tcg_const_i32(wd);
19481            TCGv taddr = tcg_temp_new();
19482            gen_base_offset_addr(ctx, taddr, rs, s10 << df);
19483
19484            switch (MASK_MSA_MINOR(opcode)) {
19485            case OPC_LD_B:
19486                gen_helper_msa_ld_b(cpu_env, twd, taddr);
19487                break;
19488            case OPC_LD_H:
19489                gen_helper_msa_ld_h(cpu_env, twd, taddr);
19490                break;
19491            case OPC_LD_W:
19492                gen_helper_msa_ld_w(cpu_env, twd, taddr);
19493                break;
19494            case OPC_LD_D:
19495                gen_helper_msa_ld_d(cpu_env, twd, taddr);
19496                break;
19497            case OPC_ST_B:
19498                gen_helper_msa_st_b(cpu_env, twd, taddr);
19499                break;
19500            case OPC_ST_H:
19501                gen_helper_msa_st_h(cpu_env, twd, taddr);
19502                break;
19503            case OPC_ST_W:
19504                gen_helper_msa_st_w(cpu_env, twd, taddr);
19505                break;
19506            case OPC_ST_D:
19507                gen_helper_msa_st_d(cpu_env, twd, taddr);
19508                break;
19509            }
19510
19511            tcg_temp_free_i32(twd);
19512            tcg_temp_free(taddr);
19513        }
19514        break;
19515    default:
19516        MIPS_INVAL("MSA instruction");
19517        generate_exception_end(ctx, EXCP_RI);
19518        break;
19519    }
19520
19521}
19522
19523static void decode_opc(CPUMIPSState *env, DisasContext *ctx)
19524{
19525    int32_t offset;
19526    int rs, rt, rd, sa;
19527    uint32_t op, op1;
19528    int16_t imm;
19529
19530    /* make sure instructions are on a word boundary */
19531    if (ctx->pc & 0x3) {
19532        env->CP0_BadVAddr = ctx->pc;
19533        generate_exception_err(ctx, EXCP_AdEL, EXCP_INST_NOTAVAIL);
19534        return;
19535    }
19536
19537    /* Handle blikely not taken case */
19538    if ((ctx->hflags & MIPS_HFLAG_BMASK_BASE) == MIPS_HFLAG_BL) {
19539        TCGLabel *l1 = gen_new_label();
19540
19541        tcg_gen_brcondi_tl(TCG_COND_NE, bcond, 0, l1);
19542        tcg_gen_movi_i32(hflags, ctx->hflags & ~MIPS_HFLAG_BMASK);
19543        gen_goto_tb(ctx, 1, ctx->pc + 4);
19544        gen_set_label(l1);
19545    }
19546
19547    op = MASK_OP_MAJOR(ctx->opcode);
19548    rs = (ctx->opcode >> 21) & 0x1f;
19549    rt = (ctx->opcode >> 16) & 0x1f;
19550    rd = (ctx->opcode >> 11) & 0x1f;
19551    sa = (ctx->opcode >> 6) & 0x1f;
19552    imm = (int16_t)ctx->opcode;
19553    switch (op) {
19554    case OPC_SPECIAL:
19555        decode_opc_special(env, ctx);
19556        break;
19557    case OPC_SPECIAL2:
19558        decode_opc_special2_legacy(env, ctx);
19559        break;
19560    case OPC_SPECIAL3:
19561        decode_opc_special3(env, ctx);
19562        break;
19563    case OPC_REGIMM:
19564        op1 = MASK_REGIMM(ctx->opcode);
19565        switch (op1) {
19566        case OPC_BLTZL: /* REGIMM branches */
19567        case OPC_BGEZL:
19568        case OPC_BLTZALL:
19569        case OPC_BGEZALL:
19570            check_insn(ctx, ISA_MIPS2);
19571            check_insn_opc_removed(ctx, ISA_MIPS32R6);
19572            /* Fallthrough */
19573        case OPC_BLTZ:
19574        case OPC_BGEZ:
19575            gen_compute_branch(ctx, op1, 4, rs, -1, imm << 2, 4);
19576            break;
19577        case OPC_BLTZAL:
19578        case OPC_BGEZAL:
19579            if (ctx->insn_flags & ISA_MIPS32R6) {
19580                if (rs == 0) {
19581                    /* OPC_NAL, OPC_BAL */
19582                    gen_compute_branch(ctx, op1, 4, 0, -1, imm << 2, 4);
19583                } else {
19584                    generate_exception_end(ctx, EXCP_RI);
19585                }
19586            } else {
19587                gen_compute_branch(ctx, op1, 4, rs, -1, imm << 2, 4);
19588            }
19589            break;
19590        case OPC_TGEI ... OPC_TEQI: /* REGIMM traps */
19591        case OPC_TNEI:
19592            check_insn(ctx, ISA_MIPS2);
19593            check_insn_opc_removed(ctx, ISA_MIPS32R6);
19594            gen_trap(ctx, op1, rs, -1, imm);
19595            break;
19596        case OPC_SIGRIE:
19597            check_insn(ctx, ISA_MIPS32R6);
19598            generate_exception_end(ctx, EXCP_RI);
19599            break;
19600        case OPC_SYNCI:
19601            check_insn(ctx, ISA_MIPS32R2);
19602            /* Break the TB to be able to sync copied instructions
19603               immediately */
19604            ctx->bstate = BS_STOP;
19605            break;
19606        case OPC_BPOSGE32:    /* MIPS DSP branch */
19607#if defined(TARGET_MIPS64)
19608        case OPC_BPOSGE64:
19609#endif
19610            check_dsp(ctx);
19611            gen_compute_branch(ctx, op1, 4, -1, -2, (int32_t)imm << 2, 4);
19612            break;
19613#if defined(TARGET_MIPS64)
19614        case OPC_DAHI:
19615            check_insn(ctx, ISA_MIPS32R6);
19616            check_mips_64(ctx);
19617            if (rs != 0) {
19618                tcg_gen_addi_tl(cpu_gpr[rs], cpu_gpr[rs], (int64_t)imm << 32);
19619            }
19620            break;
19621        case OPC_DATI:
19622            check_insn(ctx, ISA_MIPS32R6);
19623            check_mips_64(ctx);
19624            if (rs != 0) {
19625                tcg_gen_addi_tl(cpu_gpr[rs], cpu_gpr[rs], (int64_t)imm << 48);
19626            }
19627            break;
19628#endif
19629        default:            /* Invalid */
19630            MIPS_INVAL("regimm");
19631            generate_exception_end(ctx, EXCP_RI);
19632            break;
19633        }
19634        break;
19635    case OPC_CP0:
19636        check_cp0_enabled(ctx);
19637        op1 = MASK_CP0(ctx->opcode);
19638        switch (op1) {
19639        case OPC_MFC0:
19640        case OPC_MTC0:
19641        case OPC_MFTR:
19642        case OPC_MTTR:
19643        case OPC_MFHC0:
19644        case OPC_MTHC0:
19645#if defined(TARGET_MIPS64)
19646        case OPC_DMFC0:
19647        case OPC_DMTC0:
19648#endif
19649#ifndef CONFIG_USER_ONLY
19650            gen_cp0(env, ctx, op1, rt, rd);
19651#endif /* !CONFIG_USER_ONLY */
19652            break;
19653        case OPC_C0_FIRST ... OPC_C0_LAST:
19654#ifndef CONFIG_USER_ONLY
19655            gen_cp0(env, ctx, MASK_C0(ctx->opcode), rt, rd);
19656#endif /* !CONFIG_USER_ONLY */
19657            break;
19658        case OPC_MFMC0:
19659#ifndef CONFIG_USER_ONLY
19660            {
19661                uint32_t op2;
19662                TCGv t0 = tcg_temp_new();
19663
19664                op2 = MASK_MFMC0(ctx->opcode);
19665                switch (op2) {
19666                case OPC_DMT:
19667                    check_insn(ctx, ASE_MT);
19668                    gen_helper_dmt(t0);
19669                    gen_store_gpr(t0, rt);
19670                    break;
19671                case OPC_EMT:
19672                    check_insn(ctx, ASE_MT);
19673                    gen_helper_emt(t0);
19674                    gen_store_gpr(t0, rt);
19675                    break;
19676                case OPC_DVPE:
19677                    check_insn(ctx, ASE_MT);
19678                    gen_helper_dvpe(t0, cpu_env);
19679                    gen_store_gpr(t0, rt);
19680                    break;
19681                case OPC_EVPE:
19682                    check_insn(ctx, ASE_MT);
19683                    gen_helper_evpe(t0, cpu_env);
19684                    gen_store_gpr(t0, rt);
19685                    break;
19686                case OPC_DVP:
19687                    check_insn(ctx, ISA_MIPS32R6);
19688                    if (ctx->vp) {
19689                        gen_helper_dvp(t0, cpu_env);
19690                        gen_store_gpr(t0, rt);
19691                    }
19692                    break;
19693                case OPC_EVP:
19694                    check_insn(ctx, ISA_MIPS32R6);
19695                    if (ctx->vp) {
19696                        gen_helper_evp(t0, cpu_env);
19697                        gen_store_gpr(t0, rt);
19698                    }
19699                    break;
19700                case OPC_DI:
19701                    check_insn(ctx, ISA_MIPS32R2);
19702                    save_cpu_state(ctx, 1);
19703                    gen_helper_di(t0, cpu_env);
19704                    gen_store_gpr(t0, rt);
19705                    /* Stop translation as we may have switched
19706                       the execution mode.  */
19707                    ctx->bstate = BS_STOP;
19708                    break;
19709                case OPC_EI:
19710                    check_insn(ctx, ISA_MIPS32R2);
19711                    save_cpu_state(ctx, 1);
19712                    gen_helper_ei(t0, cpu_env);
19713                    gen_store_gpr(t0, rt);
19714                    /* BS_STOP isn't sufficient, we need to ensure we break out
19715                       of translated code to check for pending interrupts.  */
19716                    gen_save_pc(ctx->pc + 4);
19717                    ctx->bstate = BS_EXCP;
19718                    break;
19719                default:            /* Invalid */
19720                    MIPS_INVAL("mfmc0");
19721                    generate_exception_end(ctx, EXCP_RI);
19722                    break;
19723                }
19724                tcg_temp_free(t0);
19725            }
19726#endif /* !CONFIG_USER_ONLY */
19727            break;
19728        case OPC_RDPGPR:
19729            check_insn(ctx, ISA_MIPS32R2);
19730            gen_load_srsgpr(rt, rd);
19731            break;
19732        case OPC_WRPGPR:
19733            check_insn(ctx, ISA_MIPS32R2);
19734            gen_store_srsgpr(rt, rd);
19735            break;
19736        default:
19737            MIPS_INVAL("cp0");
19738            generate_exception_end(ctx, EXCP_RI);
19739            break;
19740        }
19741        break;
19742    case OPC_BOVC: /* OPC_BEQZALC, OPC_BEQC, OPC_ADDI */
19743        if (ctx->insn_flags & ISA_MIPS32R6) {
19744            /* OPC_BOVC, OPC_BEQZALC, OPC_BEQC */
19745            gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
19746        } else {
19747            /* OPC_ADDI */
19748            /* Arithmetic with immediate opcode */
19749            gen_arith_imm(ctx, op, rt, rs, imm);
19750        }
19751        break;
19752    case OPC_ADDIU:
19753         gen_arith_imm(ctx, op, rt, rs, imm);
19754         break;
19755    case OPC_SLTI: /* Set on less than with immediate opcode */
19756    case OPC_SLTIU:
19757         gen_slt_imm(ctx, op, rt, rs, imm);
19758         break;
19759    case OPC_ANDI: /* Arithmetic with immediate opcode */
19760    case OPC_LUI: /* OPC_AUI */
19761    case OPC_ORI:
19762    case OPC_XORI:
19763         gen_logic_imm(ctx, op, rt, rs, imm);
19764         break;
19765    case OPC_J ... OPC_JAL: /* Jump */
19766         offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 2;
19767         gen_compute_branch(ctx, op, 4, rs, rt, offset, 4);
19768         break;
19769    /* Branch */
19770    case OPC_BLEZC: /* OPC_BGEZC, OPC_BGEC, OPC_BLEZL */
19771        if (ctx->insn_flags & ISA_MIPS32R6) {
19772            if (rt == 0) {
19773                generate_exception_end(ctx, EXCP_RI);
19774                break;
19775            }
19776            /* OPC_BLEZC, OPC_BGEZC, OPC_BGEC */
19777            gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
19778        } else {
19779            /* OPC_BLEZL */
19780            gen_compute_branch(ctx, op, 4, rs, rt, imm << 2, 4);
19781        }
19782        break;
19783    case OPC_BGTZC: /* OPC_BLTZC, OPC_BLTC, OPC_BGTZL */
19784        if (ctx->insn_flags & ISA_MIPS32R6) {
19785            if (rt == 0) {
19786                generate_exception_end(ctx, EXCP_RI);
19787                break;
19788            }
19789            /* OPC_BGTZC, OPC_BLTZC, OPC_BLTC */
19790            gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
19791        } else {
19792            /* OPC_BGTZL */
19793            gen_compute_branch(ctx, op, 4, rs, rt, imm << 2, 4);
19794        }
19795        break;
19796    case OPC_BLEZALC: /* OPC_BGEZALC, OPC_BGEUC, OPC_BLEZ */
19797        if (rt == 0) {
19798            /* OPC_BLEZ */
19799            gen_compute_branch(ctx, op, 4, rs, rt, imm << 2, 4);
19800        } else {
19801            check_insn(ctx, ISA_MIPS32R6);
19802            /* OPC_BLEZALC, OPC_BGEZALC, OPC_BGEUC */
19803            gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
19804        }
19805        break;
19806    case OPC_BGTZALC: /* OPC_BLTZALC, OPC_BLTUC, OPC_BGTZ */
19807        if (rt == 0) {
19808            /* OPC_BGTZ */
19809            gen_compute_branch(ctx, op, 4, rs, rt, imm << 2, 4);
19810        } else {
19811            check_insn(ctx, ISA_MIPS32R6);
19812            /* OPC_BGTZALC, OPC_BLTZALC, OPC_BLTUC */
19813            gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
19814        }
19815        break;
19816    case OPC_BEQL:
19817    case OPC_BNEL:
19818        check_insn(ctx, ISA_MIPS2);
19819         check_insn_opc_removed(ctx, ISA_MIPS32R6);
19820        /* Fallthrough */
19821    case OPC_BEQ:
19822    case OPC_BNE:
19823         gen_compute_branch(ctx, op, 4, rs, rt, imm << 2, 4);
19824         break;
19825    case OPC_LL: /* Load and stores */
19826        check_insn(ctx, ISA_MIPS2);
19827        /* Fallthrough */
19828    case OPC_LWL:
19829    case OPC_LWR:
19830        check_insn_opc_removed(ctx, ISA_MIPS32R6);
19831         /* Fallthrough */
19832    case OPC_LB ... OPC_LH:
19833    case OPC_LW ... OPC_LHU:
19834         gen_ld(ctx, op, rt, rs, imm);
19835         break;
19836    case OPC_SWL:
19837    case OPC_SWR:
19838        check_insn_opc_removed(ctx, ISA_MIPS32R6);
19839        /* fall through */
19840    case OPC_SB ... OPC_SH:
19841    case OPC_SW:
19842         gen_st(ctx, op, rt, rs, imm);
19843         break;
19844    case OPC_SC:
19845        check_insn(ctx, ISA_MIPS2);
19846         check_insn_opc_removed(ctx, ISA_MIPS32R6);
19847         gen_st_cond(ctx, op, rt, rs, imm);
19848         break;
19849    case OPC_CACHE:
19850        check_insn_opc_removed(ctx, ISA_MIPS32R6);
19851        check_cp0_enabled(ctx);
19852        check_insn(ctx, ISA_MIPS3 | ISA_MIPS32);
19853        if (ctx->hflags & MIPS_HFLAG_ITC_CACHE) {
19854            gen_cache_operation(ctx, rt, rs, imm);
19855        }
19856        /* Treat as NOP. */
19857        break;
19858    case OPC_PREF:
19859        check_insn_opc_removed(ctx, ISA_MIPS32R6);
19860        check_insn(ctx, ISA_MIPS4 | ISA_MIPS32);
19861        /* Treat as NOP. */
19862        break;
19863
19864    /* Floating point (COP1). */
19865    case OPC_LWC1:
19866    case OPC_LDC1:
19867    case OPC_SWC1:
19868    case OPC_SDC1:
19869        gen_cop1_ldst(ctx, op, rt, rs, imm);
19870        break;
19871
19872    case OPC_CP1:
19873        op1 = MASK_CP1(ctx->opcode);
19874
19875        switch (op1) {
19876        case OPC_MFHC1:
19877        case OPC_MTHC1:
19878            check_cp1_enabled(ctx);
19879            check_insn(ctx, ISA_MIPS32R2);
19880        case OPC_MFC1:
19881        case OPC_CFC1:
19882        case OPC_MTC1:
19883        case OPC_CTC1:
19884            check_cp1_enabled(ctx);
19885            gen_cp1(ctx, op1, rt, rd);
19886            break;
19887#if defined(TARGET_MIPS64)
19888        case OPC_DMFC1:
19889        case OPC_DMTC1:
19890            check_cp1_enabled(ctx);
19891            check_insn(ctx, ISA_MIPS3);
19892            check_mips_64(ctx);
19893            gen_cp1(ctx, op1, rt, rd);
19894            break;
19895#endif
19896        case OPC_BC1EQZ: /* OPC_BC1ANY2 */
19897            check_cp1_enabled(ctx);
19898            if (ctx->insn_flags & ISA_MIPS32R6) {
19899                /* OPC_BC1EQZ */
19900                gen_compute_branch1_r6(ctx, MASK_CP1(ctx->opcode),
19901                                       rt, imm << 2, 4);
19902            } else {
19903                /* OPC_BC1ANY2 */
19904                check_cop1x(ctx);
19905                check_insn(ctx, ASE_MIPS3D);
19906                gen_compute_branch1(ctx, MASK_BC1(ctx->opcode),
19907                                    (rt >> 2) & 0x7, imm << 2);
19908            }
19909            break;
19910        case OPC_BC1NEZ:
19911            check_cp1_enabled(ctx);
19912            check_insn(ctx, ISA_MIPS32R6);
19913            gen_compute_branch1_r6(ctx, MASK_CP1(ctx->opcode),
19914                                   rt, imm << 2, 4);
19915            break;
19916        case OPC_BC1ANY4:
19917            check_cp1_enabled(ctx);
19918            check_insn_opc_removed(ctx, ISA_MIPS32R6);
19919            check_cop1x(ctx);
19920            check_insn(ctx, ASE_MIPS3D);
19921            /* fall through */
19922        case OPC_BC1:
19923            check_cp1_enabled(ctx);
19924            check_insn_opc_removed(ctx, ISA_MIPS32R6);
19925            gen_compute_branch1(ctx, MASK_BC1(ctx->opcode),
19926                                (rt >> 2) & 0x7, imm << 2);
19927            break;
19928        case OPC_PS_FMT:
19929            check_ps(ctx);
19930            /* fall through */
19931        case OPC_S_FMT:
19932        case OPC_D_FMT:
19933            check_cp1_enabled(ctx);
19934            gen_farith(ctx, ctx->opcode & FOP(0x3f, 0x1f), rt, rd, sa,
19935                       (imm >> 8) & 0x7);
19936            break;
19937        case OPC_W_FMT:
19938        case OPC_L_FMT:
19939        {
19940            int r6_op = ctx->opcode & FOP(0x3f, 0x1f);
19941            check_cp1_enabled(ctx);
19942            if (ctx->insn_flags & ISA_MIPS32R6) {
19943                switch (r6_op) {
19944                case R6_OPC_CMP_AF_S:
19945                case R6_OPC_CMP_UN_S:
19946                case R6_OPC_CMP_EQ_S:
19947                case R6_OPC_CMP_UEQ_S:
19948                case R6_OPC_CMP_LT_S:
19949                case R6_OPC_CMP_ULT_S:
19950                case R6_OPC_CMP_LE_S:
19951                case R6_OPC_CMP_ULE_S:
19952                case R6_OPC_CMP_SAF_S:
19953                case R6_OPC_CMP_SUN_S:
19954                case R6_OPC_CMP_SEQ_S:
19955                case R6_OPC_CMP_SEUQ_S:
19956                case R6_OPC_CMP_SLT_S:
19957                case R6_OPC_CMP_SULT_S:
19958                case R6_OPC_CMP_SLE_S:
19959                case R6_OPC_CMP_SULE_S:
19960                case R6_OPC_CMP_OR_S:
19961                case R6_OPC_CMP_UNE_S:
19962                case R6_OPC_CMP_NE_S:
19963                case R6_OPC_CMP_SOR_S:
19964                case R6_OPC_CMP_SUNE_S:
19965                case R6_OPC_CMP_SNE_S:
19966                    gen_r6_cmp_s(ctx, ctx->opcode & 0x1f, rt, rd, sa);
19967                    break;
19968                case R6_OPC_CMP_AF_D:
19969                case R6_OPC_CMP_UN_D:
19970                case R6_OPC_CMP_EQ_D:
19971                case R6_OPC_CMP_UEQ_D:
19972                case R6_OPC_CMP_LT_D:
19973                case R6_OPC_CMP_ULT_D:
19974                case R6_OPC_CMP_LE_D:
19975                case R6_OPC_CMP_ULE_D:
19976                case R6_OPC_CMP_SAF_D:
19977                case R6_OPC_CMP_SUN_D:
19978                case R6_OPC_CMP_SEQ_D:
19979                case R6_OPC_CMP_SEUQ_D:
19980                case R6_OPC_CMP_SLT_D:
19981                case R6_OPC_CMP_SULT_D:
19982                case R6_OPC_CMP_SLE_D:
19983                case R6_OPC_CMP_SULE_D:
19984                case R6_OPC_CMP_OR_D:
19985                case R6_OPC_CMP_UNE_D:
19986                case R6_OPC_CMP_NE_D:
19987                case R6_OPC_CMP_SOR_D:
19988                case R6_OPC_CMP_SUNE_D:
19989                case R6_OPC_CMP_SNE_D:
19990                    gen_r6_cmp_d(ctx, ctx->opcode & 0x1f, rt, rd, sa);
19991                    break;
19992                default:
19993                    gen_farith(ctx, ctx->opcode & FOP(0x3f, 0x1f),
19994                               rt, rd, sa, (imm >> 8) & 0x7);
19995
19996                    break;
19997                }
19998            } else {
19999                gen_farith(ctx, ctx->opcode & FOP(0x3f, 0x1f), rt, rd, sa,
20000                           (imm >> 8) & 0x7);
20001            }
20002            break;
20003        }
20004        case OPC_BZ_V:
20005        case OPC_BNZ_V:
20006        case OPC_BZ_B:
20007        case OPC_BZ_H:
20008        case OPC_BZ_W:
20009        case OPC_BZ_D:
20010        case OPC_BNZ_B:
20011        case OPC_BNZ_H:
20012        case OPC_BNZ_W:
20013        case OPC_BNZ_D:
20014            check_insn(ctx, ASE_MSA);
20015            gen_msa_branch(env, ctx, op1);
20016            break;
20017        default:
20018            MIPS_INVAL("cp1");
20019            generate_exception_end(ctx, EXCP_RI);
20020            break;
20021        }
20022        break;
20023
20024    /* Compact branches [R6] and COP2 [non-R6] */
20025    case OPC_BC: /* OPC_LWC2 */
20026    case OPC_BALC: /* OPC_SWC2 */
20027        if (ctx->insn_flags & ISA_MIPS32R6) {
20028            /* OPC_BC, OPC_BALC */
20029            gen_compute_compact_branch(ctx, op, 0, 0,
20030                                       sextract32(ctx->opcode << 2, 0, 28));
20031        } else {
20032            /* OPC_LWC2, OPC_SWC2 */
20033            /* COP2: Not implemented. */
20034            generate_exception_err(ctx, EXCP_CpU, 2);
20035        }
20036        break;
20037    case OPC_BEQZC: /* OPC_JIC, OPC_LDC2 */
20038    case OPC_BNEZC: /* OPC_JIALC, OPC_SDC2 */
20039        if (ctx->insn_flags & ISA_MIPS32R6) {
20040            if (rs != 0) {
20041                /* OPC_BEQZC, OPC_BNEZC */
20042                gen_compute_compact_branch(ctx, op, rs, 0,
20043                                           sextract32(ctx->opcode << 2, 0, 23));
20044            } else {
20045                /* OPC_JIC, OPC_JIALC */
20046                gen_compute_compact_branch(ctx, op, 0, rt, imm);
20047            }
20048        } else {
20049            /* OPC_LWC2, OPC_SWC2 */
20050            /* COP2: Not implemented. */
20051            generate_exception_err(ctx, EXCP_CpU, 2);
20052        }
20053        break;
20054    case OPC_CP2:
20055        check_insn(ctx, INSN_LOONGSON2F);
20056        /* Note that these instructions use different fields.  */
20057        gen_loongson_multimedia(ctx, sa, rd, rt);
20058        break;
20059
20060    case OPC_CP3:
20061        check_insn_opc_removed(ctx, ISA_MIPS32R6);
20062        if (ctx->CP0_Config1 & (1 << CP0C1_FP)) {
20063            check_cp1_enabled(ctx);
20064            op1 = MASK_CP3(ctx->opcode);
20065            switch (op1) {
20066            case OPC_LUXC1:
20067            case OPC_SUXC1:
20068                check_insn(ctx, ISA_MIPS5 | ISA_MIPS32R2);
20069                /* Fallthrough */
20070            case OPC_LWXC1:
20071            case OPC_LDXC1:
20072            case OPC_SWXC1:
20073            case OPC_SDXC1:
20074                check_insn(ctx, ISA_MIPS4 | ISA_MIPS32R2);
20075                gen_flt3_ldst(ctx, op1, sa, rd, rs, rt);
20076                break;
20077            case OPC_PREFX:
20078                check_insn(ctx, ISA_MIPS4 | ISA_MIPS32R2);
20079                /* Treat as NOP. */
20080                break;
20081            case OPC_ALNV_PS:
20082                check_insn(ctx, ISA_MIPS5 | ISA_MIPS32R2);
20083                /* Fallthrough */
20084            case OPC_MADD_S:
20085            case OPC_MADD_D:
20086            case OPC_MADD_PS:
20087            case OPC_MSUB_S:
20088            case OPC_MSUB_D:
20089            case OPC_MSUB_PS:
20090            case OPC_NMADD_S:
20091            case OPC_NMADD_D:
20092            case OPC_NMADD_PS:
20093            case OPC_NMSUB_S:
20094            case OPC_NMSUB_D:
20095            case OPC_NMSUB_PS:
20096                check_insn(ctx, ISA_MIPS4 | ISA_MIPS32R2);
20097                gen_flt3_arith(ctx, op1, sa, rs, rd, rt);
20098                break;
20099            default:
20100                MIPS_INVAL("cp3");
20101                generate_exception_end(ctx, EXCP_RI);
20102                break;
20103            }
20104        } else {
20105            generate_exception_err(ctx, EXCP_CpU, 1);
20106        }
20107        break;
20108
20109#if defined(TARGET_MIPS64)
20110    /* MIPS64 opcodes */
20111    case OPC_LDL ... OPC_LDR:
20112    case OPC_LLD:
20113        check_insn_opc_removed(ctx, ISA_MIPS32R6);
20114        /* fall through */
20115    case OPC_LWU:
20116    case OPC_LD:
20117        check_insn(ctx, ISA_MIPS3);
20118        check_mips_64(ctx);
20119        gen_ld(ctx, op, rt, rs, imm);
20120        break;
20121    case OPC_SDL ... OPC_SDR:
20122        check_insn_opc_removed(ctx, ISA_MIPS32R6);
20123        /* fall through */
20124    case OPC_SD:
20125        check_insn(ctx, ISA_MIPS3);
20126        check_mips_64(ctx);
20127        gen_st(ctx, op, rt, rs, imm);
20128        break;
20129    case OPC_SCD:
20130        check_insn_opc_removed(ctx, ISA_MIPS32R6);
20131        check_insn(ctx, ISA_MIPS3);
20132        check_mips_64(ctx);
20133        gen_st_cond(ctx, op, rt, rs, imm);
20134        break;
20135    case OPC_BNVC: /* OPC_BNEZALC, OPC_BNEC, OPC_DADDI */
20136        if (ctx->insn_flags & ISA_MIPS32R6) {
20137            /* OPC_BNVC, OPC_BNEZALC, OPC_BNEC */
20138            gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
20139        } else {
20140            /* OPC_DADDI */
20141            check_insn(ctx, ISA_MIPS3);
20142            check_mips_64(ctx);
20143            gen_arith_imm(ctx, op, rt, rs, imm);
20144        }
20145        break;
20146    case OPC_DADDIU:
20147        check_insn(ctx, ISA_MIPS3);
20148        check_mips_64(ctx);
20149        gen_arith_imm(ctx, op, rt, rs, imm);
20150        break;
20151#else
20152    case OPC_BNVC: /* OPC_BNEZALC, OPC_BNEC */
20153        if (ctx->insn_flags & ISA_MIPS32R6) {
20154            gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
20155        } else {
20156            MIPS_INVAL("major opcode");
20157            generate_exception_end(ctx, EXCP_RI);
20158        }
20159        break;
20160#endif
20161    case OPC_DAUI: /* OPC_JALX */
20162        if (ctx->insn_flags & ISA_MIPS32R6) {
20163#if defined(TARGET_MIPS64)
20164            /* OPC_DAUI */
20165            check_mips_64(ctx);
20166            if (rs == 0) {
20167                generate_exception(ctx, EXCP_RI);
20168            } else if (rt != 0) {
20169                TCGv t0 = tcg_temp_new();
20170                gen_load_gpr(t0, rs);
20171                tcg_gen_addi_tl(cpu_gpr[rt], t0, imm << 16);
20172                tcg_temp_free(t0);
20173            }
20174#else
20175            generate_exception_end(ctx, EXCP_RI);
20176            MIPS_INVAL("major opcode");
20177#endif
20178        } else {
20179            /* OPC_JALX */
20180            check_insn(ctx, ASE_MIPS16 | ASE_MICROMIPS);
20181            offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 2;
20182            gen_compute_branch(ctx, op, 4, rs, rt, offset, 4);
20183        }
20184        break;
20185    case OPC_MSA: /* OPC_MDMX */
20186        /* MDMX: Not implemented. */
20187        gen_msa(env, ctx);
20188        break;
20189    case OPC_PCREL:
20190        check_insn(ctx, ISA_MIPS32R6);
20191        gen_pcrel(ctx, ctx->opcode, ctx->pc, rs);
20192        break;
20193    default:            /* Invalid */
20194        MIPS_INVAL("major opcode");
20195        generate_exception_end(ctx, EXCP_RI);
20196        break;
20197    }
20198}
20199
20200void gen_intermediate_code(CPUState *cs, struct TranslationBlock *tb)
20201{
20202    CPUMIPSState *env = cs->env_ptr;
20203    DisasContext ctx;
20204    target_ulong pc_start;
20205    target_ulong next_page_start;
20206    int num_insns;
20207    int max_insns;
20208    int insn_bytes;
20209    int is_slot;
20210
20211    pc_start = tb->pc;
20212    next_page_start = (pc_start & TARGET_PAGE_MASK) + TARGET_PAGE_SIZE;
20213    ctx.pc = pc_start;
20214    ctx.saved_pc = -1;
20215    ctx.singlestep_enabled = cs->singlestep_enabled;
20216    ctx.insn_flags = env->insn_flags;
20217    ctx.CP0_Config1 = env->CP0_Config1;
20218    ctx.tb = tb;
20219    ctx.bstate = BS_NONE;
20220    ctx.btarget = 0;
20221    ctx.kscrexist = (env->CP0_Config4 >> CP0C4_KScrExist) & 0xff;
20222    ctx.rxi = (env->CP0_Config3 >> CP0C3_RXI) & 1;
20223    ctx.ie = (env->CP0_Config4 >> CP0C4_IE) & 3;
20224    ctx.bi = (env->CP0_Config3 >> CP0C3_BI) & 1;
20225    ctx.bp = (env->CP0_Config3 >> CP0C3_BP) & 1;
20226    ctx.PAMask = env->PAMask;
20227    ctx.mvh = (env->CP0_Config5 >> CP0C5_MVH) & 1;
20228    ctx.eva = (env->CP0_Config5 >> CP0C5_EVA) & 1;
20229    ctx.sc = (env->CP0_Config3 >> CP0C3_SC) & 1;
20230    ctx.CP0_LLAddr_shift = env->CP0_LLAddr_shift;
20231    ctx.cmgcr = (env->CP0_Config3 >> CP0C3_CMGCR) & 1;
20232    /* Restore delay slot state from the tb context.  */
20233    ctx.hflags = (uint32_t)tb->flags; /* FIXME: maybe use 64 bits here? */
20234    ctx.ulri = (env->CP0_Config3 >> CP0C3_ULRI) & 1;
20235    ctx.ps = ((env->active_fpu.fcr0 >> FCR0_PS) & 1) ||
20236             (env->insn_flags & (INSN_LOONGSON2E | INSN_LOONGSON2F));
20237    ctx.vp = (env->CP0_Config5 >> CP0C5_VP) & 1;
20238    ctx.mrp = (env->CP0_Config5 >> CP0C5_MRP) & 1;
20239    ctx.nan2008 = (env->active_fpu.fcr31 >> FCR31_NAN2008) & 1;
20240    ctx.abs2008 = (env->active_fpu.fcr31 >> FCR31_ABS2008) & 1;
20241    restore_cpu_state(env, &ctx);
20242#ifdef CONFIG_USER_ONLY
20243        ctx.mem_idx = MIPS_HFLAG_UM;
20244#else
20245        ctx.mem_idx = hflags_mmu_index(ctx.hflags);
20246#endif
20247    ctx.default_tcg_memop_mask = (ctx.insn_flags & ISA_MIPS32R6) ?
20248                                 MO_UNALN : MO_ALIGN;
20249    num_insns = 0;
20250    max_insns = tb_cflags(tb) & CF_COUNT_MASK;
20251    if (max_insns == 0) {
20252        max_insns = CF_COUNT_MASK;
20253    }
20254    if (max_insns > TCG_MAX_INSNS) {
20255        max_insns = TCG_MAX_INSNS;
20256    }
20257
20258    LOG_DISAS("\ntb %p idx %d hflags %04x\n", tb, ctx.mem_idx, ctx.hflags);
20259    gen_tb_start(tb);
20260    while (ctx.bstate == BS_NONE) {
20261        tcg_gen_insn_start(ctx.pc, ctx.hflags & MIPS_HFLAG_BMASK, ctx.btarget);
20262        num_insns++;
20263
20264        if (unlikely(cpu_breakpoint_test(cs, ctx.pc, BP_ANY))) {
20265            save_cpu_state(&ctx, 1);
20266            ctx.bstate = BS_BRANCH;
20267            gen_helper_raise_exception_debug(cpu_env);
20268            /* The address covered by the breakpoint must be included in
20269               [tb->pc, tb->pc + tb->size) in order to for it to be
20270               properly cleared -- thus we increment the PC here so that
20271               the logic setting tb->size below does the right thing.  */
20272            ctx.pc += 4;
20273            goto done_generating;
20274        }
20275
20276        if (num_insns == max_insns && (tb_cflags(tb) & CF_LAST_IO)) {
20277            gen_io_start();
20278        }
20279
20280        is_slot = ctx.hflags & MIPS_HFLAG_BMASK;
20281        if (!(ctx.hflags & MIPS_HFLAG_M16)) {
20282            ctx.opcode = cpu_ldl_code(env, ctx.pc);
20283            insn_bytes = 4;
20284            decode_opc(env, &ctx);
20285        } else if (ctx.insn_flags & ASE_MICROMIPS) {
20286            ctx.opcode = cpu_lduw_code(env, ctx.pc);
20287            insn_bytes = decode_micromips_opc(env, &ctx);
20288        } else if (ctx.insn_flags & ASE_MIPS16) {
20289            ctx.opcode = cpu_lduw_code(env, ctx.pc);
20290            insn_bytes = decode_mips16_opc(env, &ctx);
20291        } else {
20292            generate_exception_end(&ctx, EXCP_RI);
20293            break;
20294        }
20295
20296        if (ctx.hflags & MIPS_HFLAG_BMASK) {
20297            if (!(ctx.hflags & (MIPS_HFLAG_BDS16 | MIPS_HFLAG_BDS32 |
20298                                MIPS_HFLAG_FBNSLOT))) {
20299                /* force to generate branch as there is neither delay nor
20300                   forbidden slot */
20301                is_slot = 1;
20302            }
20303            if ((ctx.hflags & MIPS_HFLAG_M16) &&
20304                (ctx.hflags & MIPS_HFLAG_FBNSLOT)) {
20305                /* Force to generate branch as microMIPS R6 doesn't restrict
20306                   branches in the forbidden slot. */
20307                is_slot = 1;
20308            }
20309        }
20310        if (is_slot) {
20311            gen_branch(&ctx, insn_bytes);
20312        }
20313        ctx.pc += insn_bytes;
20314
20315        /* Execute a branch and its delay slot as a single instruction.
20316           This is what GDB expects and is consistent with what the
20317           hardware does (e.g. if a delay slot instruction faults, the
20318           reported PC is the PC of the branch).  */
20319        if (cs->singlestep_enabled && (ctx.hflags & MIPS_HFLAG_BMASK) == 0) {
20320            break;
20321        }
20322
20323        if (ctx.pc >= next_page_start) {
20324            break;
20325        }
20326
20327        if (tcg_op_buf_full()) {
20328            break;
20329        }
20330
20331        if (num_insns >= max_insns)
20332            break;
20333
20334        if (singlestep)
20335            break;
20336    }
20337    if (tb_cflags(tb) & CF_LAST_IO) {
20338        gen_io_end();
20339    }
20340    if (cs->singlestep_enabled && ctx.bstate != BS_BRANCH) {
20341        save_cpu_state(&ctx, ctx.bstate != BS_EXCP);
20342        gen_helper_raise_exception_debug(cpu_env);
20343    } else {
20344        switch (ctx.bstate) {
20345        case BS_STOP:
20346            gen_goto_tb(&ctx, 0, ctx.pc);
20347            break;
20348        case BS_NONE:
20349            save_cpu_state(&ctx, 0);
20350            gen_goto_tb(&ctx, 0, ctx.pc);
20351            break;
20352        case BS_EXCP:
20353            tcg_gen_exit_tb(0);
20354            break;
20355        case BS_BRANCH:
20356        default:
20357            break;
20358        }
20359    }
20360done_generating:
20361    gen_tb_end(tb, num_insns);
20362
20363    tb->size = ctx.pc - pc_start;
20364    tb->icount = num_insns;
20365
20366#ifdef DEBUG_DISAS
20367    LOG_DISAS("\n");
20368    if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM)
20369        && qemu_log_in_addr_range(pc_start)) {
20370        qemu_log_lock();
20371        qemu_log("IN: %s\n", lookup_symbol(pc_start));
20372        log_target_disas(cs, pc_start, ctx.pc - pc_start);
20373        qemu_log("\n");
20374        qemu_log_unlock();
20375    }
20376#endif
20377}
20378
20379static void fpu_dump_state(CPUMIPSState *env, FILE *f, fprintf_function fpu_fprintf,
20380                           int flags)
20381{
20382    int i;
20383    int is_fpu64 = !!(env->hflags & MIPS_HFLAG_F64);
20384
20385#define printfpr(fp)                                                    \
20386    do {                                                                \
20387        if (is_fpu64)                                                   \
20388            fpu_fprintf(f, "w:%08x d:%016" PRIx64                       \
20389                        " fd:%13g fs:%13g psu: %13g\n",                 \
20390                        (fp)->w[FP_ENDIAN_IDX], (fp)->d,                \
20391                        (double)(fp)->fd,                               \
20392                        (double)(fp)->fs[FP_ENDIAN_IDX],                \
20393                        (double)(fp)->fs[!FP_ENDIAN_IDX]);              \
20394        else {                                                          \
20395            fpr_t tmp;                                                  \
20396            tmp.w[FP_ENDIAN_IDX] = (fp)->w[FP_ENDIAN_IDX];              \
20397            tmp.w[!FP_ENDIAN_IDX] = ((fp) + 1)->w[FP_ENDIAN_IDX];       \
20398            fpu_fprintf(f, "w:%08x d:%016" PRIx64                       \
20399                        " fd:%13g fs:%13g psu:%13g\n",                  \
20400                        tmp.w[FP_ENDIAN_IDX], tmp.d,                    \
20401                        (double)tmp.fd,                                 \
20402                        (double)tmp.fs[FP_ENDIAN_IDX],                  \
20403                        (double)tmp.fs[!FP_ENDIAN_IDX]);                \
20404        }                                                               \
20405    } while(0)
20406
20407
20408    fpu_fprintf(f, "CP1 FCR0 0x%08x  FCR31 0x%08x  SR.FR %d  fp_status 0x%02x\n",
20409                env->active_fpu.fcr0, env->active_fpu.fcr31, is_fpu64,
20410                get_float_exception_flags(&env->active_fpu.fp_status));
20411    for (i = 0; i < 32; (is_fpu64) ? i++ : (i += 2)) {
20412        fpu_fprintf(f, "%3s: ", fregnames[i]);
20413        printfpr(&env->active_fpu.fpr[i]);
20414    }
20415
20416#undef printfpr
20417}
20418
20419void mips_cpu_dump_state(CPUState *cs, FILE *f, fprintf_function cpu_fprintf,
20420                         int flags)
20421{
20422    MIPSCPU *cpu = MIPS_CPU(cs);
20423    CPUMIPSState *env = &cpu->env;
20424    int i;
20425
20426    cpu_fprintf(f, "pc=0x" TARGET_FMT_lx " HI=0x" TARGET_FMT_lx
20427                " LO=0x" TARGET_FMT_lx " ds %04x "
20428                TARGET_FMT_lx " " TARGET_FMT_ld "\n",
20429                env->active_tc.PC, env->active_tc.HI[0], env->active_tc.LO[0],
20430                env->hflags, env->btarget, env->bcond);
20431    for (i = 0; i < 32; i++) {
20432        if ((i & 3) == 0)
20433            cpu_fprintf(f, "GPR%02d:", i);
20434        cpu_fprintf(f, " %s " TARGET_FMT_lx, regnames[i], env->active_tc.gpr[i]);
20435        if ((i & 3) == 3)
20436            cpu_fprintf(f, "\n");
20437    }
20438
20439    cpu_fprintf(f, "CP0 Status  0x%08x Cause   0x%08x EPC    0x" TARGET_FMT_lx "\n",
20440                env->CP0_Status, env->CP0_Cause, env->CP0_EPC);
20441    cpu_fprintf(f, "    Config0 0x%08x Config1 0x%08x LLAddr 0x%016"
20442                PRIx64 "\n",
20443                env->CP0_Config0, env->CP0_Config1, env->lladdr);
20444    cpu_fprintf(f, "    Config2 0x%08x Config3 0x%08x\n",
20445                env->CP0_Config2, env->CP0_Config3);
20446    cpu_fprintf(f, "    Config4 0x%08x Config5 0x%08x\n",
20447                env->CP0_Config4, env->CP0_Config5);
20448    if (env->hflags & MIPS_HFLAG_FPU)
20449        fpu_dump_state(env, f, cpu_fprintf, flags);
20450}
20451
20452void mips_tcg_init(void)
20453{
20454    int i;
20455
20456    cpu_gpr[0] = NULL;
20457    for (i = 1; i < 32; i++)
20458        cpu_gpr[i] = tcg_global_mem_new(cpu_env,
20459                                        offsetof(CPUMIPSState, active_tc.gpr[i]),
20460                                        regnames[i]);
20461
20462    for (i = 0; i < 32; i++) {
20463        int off = offsetof(CPUMIPSState, active_fpu.fpr[i].wr.d[0]);
20464        msa_wr_d[i * 2] =
20465                tcg_global_mem_new_i64(cpu_env, off, msaregnames[i * 2]);
20466        /* The scalar floating-point unit (FPU) registers are mapped on
20467         * the MSA vector registers. */
20468        fpu_f64[i] = msa_wr_d[i * 2];
20469        off = offsetof(CPUMIPSState, active_fpu.fpr[i].wr.d[1]);
20470        msa_wr_d[i * 2 + 1] =
20471                tcg_global_mem_new_i64(cpu_env, off, msaregnames[i * 2 + 1]);
20472    }
20473
20474    cpu_PC = tcg_global_mem_new(cpu_env,
20475                                offsetof(CPUMIPSState, active_tc.PC), "PC");
20476    for (i = 0; i < MIPS_DSP_ACC; i++) {
20477        cpu_HI[i] = tcg_global_mem_new(cpu_env,
20478                                       offsetof(CPUMIPSState, active_tc.HI[i]),
20479                                       regnames_HI[i]);
20480        cpu_LO[i] = tcg_global_mem_new(cpu_env,
20481                                       offsetof(CPUMIPSState, active_tc.LO[i]),
20482                                       regnames_LO[i]);
20483    }
20484    cpu_dspctrl = tcg_global_mem_new(cpu_env,
20485                                     offsetof(CPUMIPSState, active_tc.DSPControl),
20486                                     "DSPControl");
20487    bcond = tcg_global_mem_new(cpu_env,
20488                               offsetof(CPUMIPSState, bcond), "bcond");
20489    btarget = tcg_global_mem_new(cpu_env,
20490                                 offsetof(CPUMIPSState, btarget), "btarget");
20491    hflags = tcg_global_mem_new_i32(cpu_env,
20492                                    offsetof(CPUMIPSState, hflags), "hflags");
20493
20494    fpu_fcr0 = tcg_global_mem_new_i32(cpu_env,
20495                                      offsetof(CPUMIPSState, active_fpu.fcr0),
20496                                      "fcr0");
20497    fpu_fcr31 = tcg_global_mem_new_i32(cpu_env,
20498                                       offsetof(CPUMIPSState, active_fpu.fcr31),
20499                                       "fcr31");
20500}
20501
20502#include "translate_init.c"
20503
20504void cpu_mips_realize_env(CPUMIPSState *env)
20505{
20506    env->exception_base = (int32_t)0xBFC00000;
20507
20508#ifndef CONFIG_USER_ONLY
20509    mmu_init(env, env->cpu_model);
20510#endif
20511    fpu_init(env, env->cpu_model);
20512    mvp_init(env, env->cpu_model);
20513}
20514
20515bool cpu_supports_cps_smp(const char *cpu_type)
20516{
20517    const MIPSCPUClass *mcc = MIPS_CPU_CLASS(object_class_by_name(cpu_type));
20518    return (mcc->cpu_def->CP0_Config3 & (1 << CP0C3_CMGCR)) != 0;
20519}
20520
20521bool cpu_supports_isa(const char *cpu_type, unsigned int isa)
20522{
20523    const MIPSCPUClass *mcc = MIPS_CPU_CLASS(object_class_by_name(cpu_type));
20524    return (mcc->cpu_def->insn_flags & isa) != 0;
20525}
20526
20527void cpu_set_exception_base(int vp_index, target_ulong address)
20528{
20529    MIPSCPU *vp = MIPS_CPU(qemu_get_cpu(vp_index));
20530    vp->env.exception_base = address;
20531}
20532
20533void cpu_state_reset(CPUMIPSState *env)
20534{
20535    MIPSCPU *cpu = mips_env_get_cpu(env);
20536    CPUState *cs = CPU(cpu);
20537
20538    /* Reset registers to their default values */
20539    env->CP0_PRid = env->cpu_model->CP0_PRid;
20540    env->CP0_Config0 = env->cpu_model->CP0_Config0;
20541#ifdef TARGET_WORDS_BIGENDIAN
20542    env->CP0_Config0 |= (1 << CP0C0_BE);
20543#endif
20544    env->CP0_Config1 = env->cpu_model->CP0_Config1;
20545    env->CP0_Config2 = env->cpu_model->CP0_Config2;
20546    env->CP0_Config3 = env->cpu_model->CP0_Config3;
20547    env->CP0_Config4 = env->cpu_model->CP0_Config4;
20548    env->CP0_Config4_rw_bitmask = env->cpu_model->CP0_Config4_rw_bitmask;
20549    env->CP0_Config5 = env->cpu_model->CP0_Config5;
20550    env->CP0_Config5_rw_bitmask = env->cpu_model->CP0_Config5_rw_bitmask;
20551    env->CP0_Config6 = env->cpu_model->CP0_Config6;
20552    env->CP0_Config7 = env->cpu_model->CP0_Config7;
20553    env->CP0_LLAddr_rw_bitmask = env->cpu_model->CP0_LLAddr_rw_bitmask
20554                                 << env->cpu_model->CP0_LLAddr_shift;
20555    env->CP0_LLAddr_shift = env->cpu_model->CP0_LLAddr_shift;
20556    env->SYNCI_Step = env->cpu_model->SYNCI_Step;
20557    env->CCRes = env->cpu_model->CCRes;
20558    env->CP0_Status_rw_bitmask = env->cpu_model->CP0_Status_rw_bitmask;
20559    env->CP0_TCStatus_rw_bitmask = env->cpu_model->CP0_TCStatus_rw_bitmask;
20560    env->CP0_SRSCtl = env->cpu_model->CP0_SRSCtl;
20561    env->current_tc = 0;
20562    env->SEGBITS = env->cpu_model->SEGBITS;
20563    env->SEGMask = (target_ulong)((1ULL << env->cpu_model->SEGBITS) - 1);
20564#if defined(TARGET_MIPS64)
20565    if (env->cpu_model->insn_flags & ISA_MIPS3) {
20566        env->SEGMask |= 3ULL << 62;
20567    }
20568#endif
20569    env->PABITS = env->cpu_model->PABITS;
20570    env->CP0_SRSConf0_rw_bitmask = env->cpu_model->CP0_SRSConf0_rw_bitmask;
20571    env->CP0_SRSConf0 = env->cpu_model->CP0_SRSConf0;
20572    env->CP0_SRSConf1_rw_bitmask = env->cpu_model->CP0_SRSConf1_rw_bitmask;
20573    env->CP0_SRSConf1 = env->cpu_model->CP0_SRSConf1;
20574    env->CP0_SRSConf2_rw_bitmask = env->cpu_model->CP0_SRSConf2_rw_bitmask;
20575    env->CP0_SRSConf2 = env->cpu_model->CP0_SRSConf2;
20576    env->CP0_SRSConf3_rw_bitmask = env->cpu_model->CP0_SRSConf3_rw_bitmask;
20577    env->CP0_SRSConf3 = env->cpu_model->CP0_SRSConf3;
20578    env->CP0_SRSConf4_rw_bitmask = env->cpu_model->CP0_SRSConf4_rw_bitmask;
20579    env->CP0_SRSConf4 = env->cpu_model->CP0_SRSConf4;
20580    env->CP0_PageGrain_rw_bitmask = env->cpu_model->CP0_PageGrain_rw_bitmask;
20581    env->CP0_PageGrain = env->cpu_model->CP0_PageGrain;
20582    env->CP0_EBaseWG_rw_bitmask = env->cpu_model->CP0_EBaseWG_rw_bitmask;
20583    env->active_fpu.fcr0 = env->cpu_model->CP1_fcr0;
20584    env->active_fpu.fcr31_rw_bitmask = env->cpu_model->CP1_fcr31_rw_bitmask;
20585    env->active_fpu.fcr31 = env->cpu_model->CP1_fcr31;
20586    env->msair = env->cpu_model->MSAIR;
20587    env->insn_flags = env->cpu_model->insn_flags;
20588
20589#if defined(CONFIG_USER_ONLY)
20590    env->CP0_Status = (MIPS_HFLAG_UM << CP0St_KSU);
20591# ifdef TARGET_MIPS64
20592    /* Enable 64-bit register mode.  */
20593    env->CP0_Status |= (1 << CP0St_PX);
20594# endif
20595# ifdef TARGET_ABI_MIPSN64
20596    /* Enable 64-bit address mode.  */
20597    env->CP0_Status |= (1 << CP0St_UX);
20598# endif
20599    /* Enable access to the CPUNum, SYNCI_Step, CC, and CCRes RDHWR
20600       hardware registers.  */
20601    env->CP0_HWREna |= 0x0000000F;
20602    if (env->CP0_Config1 & (1 << CP0C1_FP)) {
20603        env->CP0_Status |= (1 << CP0St_CU1);
20604    }
20605    if (env->CP0_Config3 & (1 << CP0C3_DSPP)) {
20606        env->CP0_Status |= (1 << CP0St_MX);
20607    }
20608# if defined(TARGET_MIPS64)
20609    /* For MIPS64, init FR bit to 1 if FPU unit is there and bit is writable. */
20610    if ((env->CP0_Config1 & (1 << CP0C1_FP)) &&
20611        (env->CP0_Status_rw_bitmask & (1 << CP0St_FR))) {
20612        env->CP0_Status |= (1 << CP0St_FR);
20613    }
20614# endif
20615#else
20616    if (env->hflags & MIPS_HFLAG_BMASK) {
20617        /* If the exception was raised from a delay slot,
20618           come back to the jump.  */
20619        env->CP0_ErrorEPC = (env->active_tc.PC
20620                             - (env->hflags & MIPS_HFLAG_B16 ? 2 : 4));
20621    } else {
20622        env->CP0_ErrorEPC = env->active_tc.PC;
20623    }
20624    env->active_tc.PC = env->exception_base;
20625    env->CP0_Random = env->tlb->nb_tlb - 1;
20626    env->tlb->tlb_in_use = env->tlb->nb_tlb;
20627    env->CP0_Wired = 0;
20628    env->CP0_GlobalNumber = (cs->cpu_index & 0xFF) << CP0GN_VPId;
20629    env->CP0_EBase = (cs->cpu_index & 0x3FF);
20630    if (mips_um_ksegs_enabled()) {
20631        env->CP0_EBase |= 0x40000000;
20632    } else {
20633        env->CP0_EBase |= (int32_t)0x80000000;
20634    }
20635    if (env->CP0_Config3 & (1 << CP0C3_CMGCR)) {
20636        env->CP0_CMGCRBase = 0x1fbf8000 >> 4;
20637    }
20638    env->CP0_EntryHi_ASID_mask = (env->CP0_Config4 & (1 << CP0C4_AE)) ?
20639                                 0x3ff : 0xff;
20640    env->CP0_Status = (1 << CP0St_BEV) | (1 << CP0St_ERL);
20641    /* vectored interrupts not implemented, timer on int 7,
20642       no performance counters. */
20643    env->CP0_IntCtl = 0xe0000000;
20644    {
20645        int i;
20646
20647        for (i = 0; i < 7; i++) {
20648            env->CP0_WatchLo[i] = 0;
20649            env->CP0_WatchHi[i] = 0x80000000;
20650        }
20651        env->CP0_WatchLo[7] = 0;
20652        env->CP0_WatchHi[7] = 0;
20653    }
20654    /* Count register increments in debug mode, EJTAG version 1 */
20655    env->CP0_Debug = (1 << CP0DB_CNT) | (0x1 << CP0DB_VER);
20656
20657    cpu_mips_store_count(env, 1);
20658
20659    if (env->CP0_Config3 & (1 << CP0C3_MT)) {
20660        int i;
20661
20662        /* Only TC0 on VPE 0 starts as active.  */
20663        for (i = 0; i < ARRAY_SIZE(env->tcs); i++) {
20664            env->tcs[i].CP0_TCBind = cs->cpu_index << CP0TCBd_CurVPE;
20665            env->tcs[i].CP0_TCHalt = 1;
20666        }
20667        env->active_tc.CP0_TCHalt = 1;
20668        cs->halted = 1;
20669
20670        if (cs->cpu_index == 0) {
20671            /* VPE0 starts up enabled.  */
20672            env->mvp->CP0_MVPControl |= (1 << CP0MVPCo_EVP);
20673            env->CP0_VPEConf0 |= (1 << CP0VPEC0_MVP) | (1 << CP0VPEC0_VPA);
20674
20675            /* TC0 starts up unhalted.  */
20676            cs->halted = 0;
20677            env->active_tc.CP0_TCHalt = 0;
20678            env->tcs[0].CP0_TCHalt = 0;
20679            /* With thread 0 active.  */
20680            env->active_tc.CP0_TCStatus = (1 << CP0TCSt_A);
20681            env->tcs[0].CP0_TCStatus = (1 << CP0TCSt_A);
20682        }
20683    }
20684
20685    /*
20686     * Configure default legacy segmentation control. We use this regardless of
20687     * whether segmentation control is presented to the guest.
20688     */
20689    /* KSeg3 (seg0 0xE0000000..0xFFFFFFFF) */
20690    env->CP0_SegCtl0 =   (CP0SC_AM_MK << CP0SC_AM);
20691    /* KSeg2 (seg1 0xC0000000..0xDFFFFFFF) */
20692    env->CP0_SegCtl0 |= ((CP0SC_AM_MSK << CP0SC_AM)) << 16;
20693    /* KSeg1 (seg2 0xA0000000..0x9FFFFFFF) */
20694    env->CP0_SegCtl1 =   (0 << CP0SC_PA) | (CP0SC_AM_UK << CP0SC_AM) |
20695                         (2 << CP0SC_C);
20696    /* KSeg0 (seg3 0x80000000..0x9FFFFFFF) */
20697    env->CP0_SegCtl1 |= ((0 << CP0SC_PA) | (CP0SC_AM_UK << CP0SC_AM) |
20698                         (3 << CP0SC_C)) << 16;
20699    /* USeg (seg4 0x40000000..0x7FFFFFFF) */
20700    env->CP0_SegCtl2 =   (2 << CP0SC_PA) | (CP0SC_AM_MUSK << CP0SC_AM) |
20701                         (1 << CP0SC_EU) | (2 << CP0SC_C);
20702    /* USeg (seg5 0x00000000..0x3FFFFFFF) */
20703    env->CP0_SegCtl2 |= ((0 << CP0SC_PA) | (CP0SC_AM_MUSK << CP0SC_AM) |
20704                         (1 << CP0SC_EU) | (2 << CP0SC_C)) << 16;
20705    /* XKPhys (note, SegCtl2.XR = 0, so XAM won't be used) */
20706    env->CP0_SegCtl1 |= (CP0SC_AM_UK << CP0SC1_XAM);
20707#endif
20708    if ((env->insn_flags & ISA_MIPS32R6) &&
20709        (env->active_fpu.fcr0 & (1 << FCR0_F64))) {
20710        /* Status.FR = 0 mode in 64-bit FPU not allowed in R6 */
20711        env->CP0_Status |= (1 << CP0St_FR);
20712    }
20713
20714    /* MSA */
20715    if (env->CP0_Config3 & (1 << CP0C3_MSAP)) {
20716        msa_reset(env);
20717    }
20718
20719    compute_hflags(env);
20720    restore_fp_status(env);
20721    restore_pamask(env);
20722    cs->exception_index = EXCP_NONE;
20723
20724    if (semihosting_get_argc()) {
20725        /* UHI interface can be used to obtain argc and argv */
20726        env->active_tc.gpr[4] = -1;
20727    }
20728}
20729
20730void restore_state_to_opc(CPUMIPSState *env, TranslationBlock *tb,
20731                          target_ulong *data)
20732{
20733    env->active_tc.PC = data[0];
20734    env->hflags &= ~MIPS_HFLAG_BMASK;
20735    env->hflags |= data[1];
20736    switch (env->hflags & MIPS_HFLAG_BMASK_BASE) {
20737    case MIPS_HFLAG_BR:
20738        break;
20739    case MIPS_HFLAG_BC:
20740    case MIPS_HFLAG_BL:
20741    case MIPS_HFLAG_B:
20742        env->btarget = data[2];
20743        break;
20744    }
20745}
20746