qemu/target/mips/translate.c
<<
>>
Prefs
   1/*
   2 *  MIPS emulation for QEMU - main translation routines
   3 *
   4 *  Copyright (c) 2004-2005 Jocelyn Mayer
   5 *  Copyright (c) 2006 Marius Groeger (FPU operations)
   6 *  Copyright (c) 2006 Thiemo Seufer (MIPS32R2 support)
   7 *  Copyright (c) 2009 CodeSourcery (MIPS16 and microMIPS support)
   8 *  Copyright (c) 2012 Jia Liu & Dongxue Zhang (MIPS ASE DSP support)
   9 *
  10 * This library is free software; you can redistribute it and/or
  11 * modify it under the terms of the GNU Lesser General Public
  12 * License as published by the Free Software Foundation; either
  13 * version 2 of the License, or (at your option) any later version.
  14 *
  15 * This library is distributed in the hope that it will be useful,
  16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
  17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  18 * Lesser General Public License for more details.
  19 *
  20 * You should have received a copy of the GNU Lesser General Public
  21 * License along with this library; if not, see <http://www.gnu.org/licenses/>.
  22 */
  23
  24#include "qemu/osdep.h"
  25#include "cpu.h"
  26#include "internal.h"
  27#include "disas/disas.h"
  28#include "exec/exec-all.h"
  29#include "tcg-op.h"
  30#include "exec/cpu_ldst.h"
  31#include "hw/mips/cpudevs.h"
  32
  33#include "exec/helper-proto.h"
  34#include "exec/helper-gen.h"
  35#include "exec/semihost.h"
  36
  37#include "target/mips/trace.h"
  38#include "trace-tcg.h"
  39#include "exec/translator.h"
  40#include "exec/log.h"
  41
  42#define MIPS_DEBUG_DISAS 0
  43
  44/* MIPS major opcodes */
  45#define MASK_OP_MAJOR(op)  (op & (0x3F << 26))
  46
  47enum {
  48    /* indirect opcode tables */
  49    OPC_SPECIAL  = (0x00 << 26),
  50    OPC_REGIMM   = (0x01 << 26),
  51    OPC_CP0      = (0x10 << 26),
  52    OPC_CP1      = (0x11 << 26),
  53    OPC_CP2      = (0x12 << 26),
  54    OPC_CP3      = (0x13 << 26),
  55    OPC_SPECIAL2 = (0x1C << 26),
  56    OPC_SPECIAL3 = (0x1F << 26),
  57    /* arithmetic with immediate */
  58    OPC_ADDI     = (0x08 << 26),
  59    OPC_ADDIU    = (0x09 << 26),
  60    OPC_SLTI     = (0x0A << 26),
  61    OPC_SLTIU    = (0x0B << 26),
  62    /* logic with immediate */
  63    OPC_ANDI     = (0x0C << 26),
  64    OPC_ORI      = (0x0D << 26),
  65    OPC_XORI     = (0x0E << 26),
  66    OPC_LUI      = (0x0F << 26),
  67    /* arithmetic with immediate */
  68    OPC_DADDI    = (0x18 << 26),
  69    OPC_DADDIU   = (0x19 << 26),
  70    /* Jump and branches */
  71    OPC_J        = (0x02 << 26),
  72    OPC_JAL      = (0x03 << 26),
  73    OPC_BEQ      = (0x04 << 26),  /* Unconditional if rs = rt = 0 (B) */
  74    OPC_BEQL     = (0x14 << 26),
  75    OPC_BNE      = (0x05 << 26),
  76    OPC_BNEL     = (0x15 << 26),
  77    OPC_BLEZ     = (0x06 << 26),
  78    OPC_BLEZL    = (0x16 << 26),
  79    OPC_BGTZ     = (0x07 << 26),
  80    OPC_BGTZL    = (0x17 << 26),
  81    OPC_JALX     = (0x1D << 26),
  82    OPC_DAUI     = (0x1D << 26),
  83    /* Load and stores */
  84    OPC_LDL      = (0x1A << 26),
  85    OPC_LDR      = (0x1B << 26),
  86    OPC_LB       = (0x20 << 26),
  87    OPC_LH       = (0x21 << 26),
  88    OPC_LWL      = (0x22 << 26),
  89    OPC_LW       = (0x23 << 26),
  90    OPC_LWPC     = OPC_LW | 0x5,
  91    OPC_LBU      = (0x24 << 26),
  92    OPC_LHU      = (0x25 << 26),
  93    OPC_LWR      = (0x26 << 26),
  94    OPC_LWU      = (0x27 << 26),
  95    OPC_SB       = (0x28 << 26),
  96    OPC_SH       = (0x29 << 26),
  97    OPC_SWL      = (0x2A << 26),
  98    OPC_SW       = (0x2B << 26),
  99    OPC_SDL      = (0x2C << 26),
 100    OPC_SDR      = (0x2D << 26),
 101    OPC_SWR      = (0x2E << 26),
 102    OPC_LL       = (0x30 << 26),
 103    OPC_LLD      = (0x34 << 26),
 104    OPC_LD       = (0x37 << 26),
 105    OPC_LDPC     = OPC_LD | 0x5,
 106    OPC_SC       = (0x38 << 26),
 107    OPC_SCD      = (0x3C << 26),
 108    OPC_SD       = (0x3F << 26),
 109    /* Floating point load/store */
 110    OPC_LWC1     = (0x31 << 26),
 111    OPC_LWC2     = (0x32 << 26),
 112    OPC_LDC1     = (0x35 << 26),
 113    OPC_LDC2     = (0x36 << 26),
 114    OPC_SWC1     = (0x39 << 26),
 115    OPC_SWC2     = (0x3A << 26),
 116    OPC_SDC1     = (0x3D << 26),
 117    OPC_SDC2     = (0x3E << 26),
 118    /* Compact Branches */
 119    OPC_BLEZALC  = (0x06 << 26),
 120    OPC_BGEZALC  = (0x06 << 26),
 121    OPC_BGEUC    = (0x06 << 26),
 122    OPC_BGTZALC  = (0x07 << 26),
 123    OPC_BLTZALC  = (0x07 << 26),
 124    OPC_BLTUC    = (0x07 << 26),
 125    OPC_BOVC     = (0x08 << 26),
 126    OPC_BEQZALC  = (0x08 << 26),
 127    OPC_BEQC     = (0x08 << 26),
 128    OPC_BLEZC    = (0x16 << 26),
 129    OPC_BGEZC    = (0x16 << 26),
 130    OPC_BGEC     = (0x16 << 26),
 131    OPC_BGTZC    = (0x17 << 26),
 132    OPC_BLTZC    = (0x17 << 26),
 133    OPC_BLTC     = (0x17 << 26),
 134    OPC_BNVC     = (0x18 << 26),
 135    OPC_BNEZALC  = (0x18 << 26),
 136    OPC_BNEC     = (0x18 << 26),
 137    OPC_BC       = (0x32 << 26),
 138    OPC_BEQZC    = (0x36 << 26),
 139    OPC_JIC      = (0x36 << 26),
 140    OPC_BALC     = (0x3A << 26),
 141    OPC_BNEZC    = (0x3E << 26),
 142    OPC_JIALC    = (0x3E << 26),
 143    /* MDMX ASE specific */
 144    OPC_MDMX     = (0x1E << 26),
 145    /* MSA ASE, same as MDMX */
 146    OPC_MSA      = OPC_MDMX,
 147    /* Cache and prefetch */
 148    OPC_CACHE    = (0x2F << 26),
 149    OPC_PREF     = (0x33 << 26),
 150    /* PC-relative address computation / loads */
 151    OPC_PCREL    = (0x3B << 26),
 152};
 153
 154/* PC-relative address computation / loads  */
 155#define MASK_OPC_PCREL_TOP2BITS(op)  (MASK_OP_MAJOR(op) | (op & (3 << 19)))
 156#define MASK_OPC_PCREL_TOP5BITS(op)  (MASK_OP_MAJOR(op) | (op & (0x1f << 16)))
 157enum {
 158    /* Instructions determined by bits 19 and 20 */
 159    OPC_ADDIUPC = OPC_PCREL | (0 << 19),
 160    R6_OPC_LWPC = OPC_PCREL | (1 << 19),
 161    OPC_LWUPC   = OPC_PCREL | (2 << 19),
 162
 163    /* Instructions determined by bits 16 ... 20 */
 164    OPC_AUIPC   = OPC_PCREL | (0x1e << 16),
 165    OPC_ALUIPC  = OPC_PCREL | (0x1f << 16),
 166
 167    /* Other */
 168    R6_OPC_LDPC = OPC_PCREL | (6 << 18),
 169};
 170
 171/* MIPS special opcodes */
 172#define MASK_SPECIAL(op)   MASK_OP_MAJOR(op) | (op & 0x3F)
 173
 174enum {
 175    /* Shifts */
 176    OPC_SLL      = 0x00 | OPC_SPECIAL,
 177    /* NOP is SLL r0, r0, 0   */
 178    /* SSNOP is SLL r0, r0, 1 */
 179    /* EHB is SLL r0, r0, 3 */
 180    OPC_SRL      = 0x02 | OPC_SPECIAL, /* also ROTR */
 181    OPC_ROTR     = OPC_SRL | (1 << 21),
 182    OPC_SRA      = 0x03 | OPC_SPECIAL,
 183    OPC_SLLV     = 0x04 | OPC_SPECIAL,
 184    OPC_SRLV     = 0x06 | OPC_SPECIAL, /* also ROTRV */
 185    OPC_ROTRV    = OPC_SRLV | (1 << 6),
 186    OPC_SRAV     = 0x07 | OPC_SPECIAL,
 187    OPC_DSLLV    = 0x14 | OPC_SPECIAL,
 188    OPC_DSRLV    = 0x16 | OPC_SPECIAL, /* also DROTRV */
 189    OPC_DROTRV   = OPC_DSRLV | (1 << 6),
 190    OPC_DSRAV    = 0x17 | OPC_SPECIAL,
 191    OPC_DSLL     = 0x38 | OPC_SPECIAL,
 192    OPC_DSRL     = 0x3A | OPC_SPECIAL, /* also DROTR */
 193    OPC_DROTR    = OPC_DSRL | (1 << 21),
 194    OPC_DSRA     = 0x3B | OPC_SPECIAL,
 195    OPC_DSLL32   = 0x3C | OPC_SPECIAL,
 196    OPC_DSRL32   = 0x3E | OPC_SPECIAL, /* also DROTR32 */
 197    OPC_DROTR32  = OPC_DSRL32 | (1 << 21),
 198    OPC_DSRA32   = 0x3F | OPC_SPECIAL,
 199    /* Multiplication / division */
 200    OPC_MULT     = 0x18 | OPC_SPECIAL,
 201    OPC_MULTU    = 0x19 | OPC_SPECIAL,
 202    OPC_DIV      = 0x1A | OPC_SPECIAL,
 203    OPC_DIVU     = 0x1B | OPC_SPECIAL,
 204    OPC_DMULT    = 0x1C | OPC_SPECIAL,
 205    OPC_DMULTU   = 0x1D | OPC_SPECIAL,
 206    OPC_DDIV     = 0x1E | OPC_SPECIAL,
 207    OPC_DDIVU    = 0x1F | OPC_SPECIAL,
 208
 209    /* 2 registers arithmetic / logic */
 210    OPC_ADD      = 0x20 | OPC_SPECIAL,
 211    OPC_ADDU     = 0x21 | OPC_SPECIAL,
 212    OPC_SUB      = 0x22 | OPC_SPECIAL,
 213    OPC_SUBU     = 0x23 | OPC_SPECIAL,
 214    OPC_AND      = 0x24 | OPC_SPECIAL,
 215    OPC_OR       = 0x25 | OPC_SPECIAL,
 216    OPC_XOR      = 0x26 | OPC_SPECIAL,
 217    OPC_NOR      = 0x27 | OPC_SPECIAL,
 218    OPC_SLT      = 0x2A | OPC_SPECIAL,
 219    OPC_SLTU     = 0x2B | OPC_SPECIAL,
 220    OPC_DADD     = 0x2C | OPC_SPECIAL,
 221    OPC_DADDU    = 0x2D | OPC_SPECIAL,
 222    OPC_DSUB     = 0x2E | OPC_SPECIAL,
 223    OPC_DSUBU    = 0x2F | OPC_SPECIAL,
 224    /* Jumps */
 225    OPC_JR       = 0x08 | OPC_SPECIAL, /* Also JR.HB */
 226    OPC_JALR     = 0x09 | OPC_SPECIAL, /* Also JALR.HB */
 227    /* Traps */
 228    OPC_TGE      = 0x30 | OPC_SPECIAL,
 229    OPC_TGEU     = 0x31 | OPC_SPECIAL,
 230    OPC_TLT      = 0x32 | OPC_SPECIAL,
 231    OPC_TLTU     = 0x33 | OPC_SPECIAL,
 232    OPC_TEQ      = 0x34 | OPC_SPECIAL,
 233    OPC_TNE      = 0x36 | OPC_SPECIAL,
 234    /* HI / LO registers load & stores */
 235    OPC_MFHI     = 0x10 | OPC_SPECIAL,
 236    OPC_MTHI     = 0x11 | OPC_SPECIAL,
 237    OPC_MFLO     = 0x12 | OPC_SPECIAL,
 238    OPC_MTLO     = 0x13 | OPC_SPECIAL,
 239    /* Conditional moves */
 240    OPC_MOVZ     = 0x0A | OPC_SPECIAL,
 241    OPC_MOVN     = 0x0B | OPC_SPECIAL,
 242
 243    OPC_SELEQZ   = 0x35 | OPC_SPECIAL,
 244    OPC_SELNEZ   = 0x37 | OPC_SPECIAL,
 245
 246    OPC_MOVCI    = 0x01 | OPC_SPECIAL,
 247
 248    /* Special */
 249    OPC_PMON     = 0x05 | OPC_SPECIAL, /* unofficial */
 250    OPC_SYSCALL  = 0x0C | OPC_SPECIAL,
 251    OPC_BREAK    = 0x0D | OPC_SPECIAL,
 252    OPC_SPIM     = 0x0E | OPC_SPECIAL, /* unofficial */
 253    OPC_SYNC     = 0x0F | OPC_SPECIAL,
 254
 255    OPC_SPECIAL28_RESERVED = 0x28 | OPC_SPECIAL,
 256    OPC_SPECIAL29_RESERVED = 0x29 | OPC_SPECIAL,
 257    OPC_SPECIAL39_RESERVED = 0x39 | OPC_SPECIAL,
 258    OPC_SPECIAL3D_RESERVED = 0x3D | OPC_SPECIAL,
 259};
 260
 261/* R6 Multiply and Divide instructions have the same Opcode
 262   and function field as legacy OPC_MULT[U]/OPC_DIV[U] */
 263#define MASK_R6_MULDIV(op)   (MASK_SPECIAL(op) | (op & (0x7ff)))
 264
 265enum {
 266    R6_OPC_MUL   = OPC_MULT  | (2 << 6),
 267    R6_OPC_MUH   = OPC_MULT  | (3 << 6),
 268    R6_OPC_MULU  = OPC_MULTU | (2 << 6),
 269    R6_OPC_MUHU  = OPC_MULTU | (3 << 6),
 270    R6_OPC_DIV   = OPC_DIV   | (2 << 6),
 271    R6_OPC_MOD   = OPC_DIV   | (3 << 6),
 272    R6_OPC_DIVU  = OPC_DIVU  | (2 << 6),
 273    R6_OPC_MODU  = OPC_DIVU  | (3 << 6),
 274
 275    R6_OPC_DMUL   = OPC_DMULT  | (2 << 6),
 276    R6_OPC_DMUH   = OPC_DMULT  | (3 << 6),
 277    R6_OPC_DMULU  = OPC_DMULTU | (2 << 6),
 278    R6_OPC_DMUHU  = OPC_DMULTU | (3 << 6),
 279    R6_OPC_DDIV   = OPC_DDIV   | (2 << 6),
 280    R6_OPC_DMOD   = OPC_DDIV   | (3 << 6),
 281    R6_OPC_DDIVU  = OPC_DDIVU  | (2 << 6),
 282    R6_OPC_DMODU  = OPC_DDIVU  | (3 << 6),
 283
 284    R6_OPC_CLZ      = 0x10 | OPC_SPECIAL,
 285    R6_OPC_CLO      = 0x11 | OPC_SPECIAL,
 286    R6_OPC_DCLZ     = 0x12 | OPC_SPECIAL,
 287    R6_OPC_DCLO     = 0x13 | OPC_SPECIAL,
 288    R6_OPC_SDBBP    = 0x0e | OPC_SPECIAL,
 289
 290    OPC_LSA  = 0x05 | OPC_SPECIAL,
 291    OPC_DLSA = 0x15 | OPC_SPECIAL,
 292};
 293
 294/* Multiplication variants of the vr54xx. */
 295#define MASK_MUL_VR54XX(op)   MASK_SPECIAL(op) | (op & (0x1F << 6))
 296
 297enum {
 298    OPC_VR54XX_MULS    = (0x03 << 6) | OPC_MULT,
 299    OPC_VR54XX_MULSU   = (0x03 << 6) | OPC_MULTU,
 300    OPC_VR54XX_MACC    = (0x05 << 6) | OPC_MULT,
 301    OPC_VR54XX_MACCU   = (0x05 << 6) | OPC_MULTU,
 302    OPC_VR54XX_MSAC    = (0x07 << 6) | OPC_MULT,
 303    OPC_VR54XX_MSACU   = (0x07 << 6) | OPC_MULTU,
 304    OPC_VR54XX_MULHI   = (0x09 << 6) | OPC_MULT,
 305    OPC_VR54XX_MULHIU  = (0x09 << 6) | OPC_MULTU,
 306    OPC_VR54XX_MULSHI  = (0x0B << 6) | OPC_MULT,
 307    OPC_VR54XX_MULSHIU = (0x0B << 6) | OPC_MULTU,
 308    OPC_VR54XX_MACCHI  = (0x0D << 6) | OPC_MULT,
 309    OPC_VR54XX_MACCHIU = (0x0D << 6) | OPC_MULTU,
 310    OPC_VR54XX_MSACHI  = (0x0F << 6) | OPC_MULT,
 311    OPC_VR54XX_MSACHIU = (0x0F << 6) | OPC_MULTU,
 312};
 313
 314/* REGIMM (rt field) opcodes */
 315#define MASK_REGIMM(op)    MASK_OP_MAJOR(op) | (op & (0x1F << 16))
 316
 317enum {
 318    OPC_BLTZ     = (0x00 << 16) | OPC_REGIMM,
 319    OPC_BLTZL    = (0x02 << 16) | OPC_REGIMM,
 320    OPC_BGEZ     = (0x01 << 16) | OPC_REGIMM,
 321    OPC_BGEZL    = (0x03 << 16) | OPC_REGIMM,
 322    OPC_BLTZAL   = (0x10 << 16) | OPC_REGIMM,
 323    OPC_BLTZALL  = (0x12 << 16) | OPC_REGIMM,
 324    OPC_BGEZAL   = (0x11 << 16) | OPC_REGIMM,
 325    OPC_BGEZALL  = (0x13 << 16) | OPC_REGIMM,
 326    OPC_TGEI     = (0x08 << 16) | OPC_REGIMM,
 327    OPC_TGEIU    = (0x09 << 16) | OPC_REGIMM,
 328    OPC_TLTI     = (0x0A << 16) | OPC_REGIMM,
 329    OPC_TLTIU    = (0x0B << 16) | OPC_REGIMM,
 330    OPC_TEQI     = (0x0C << 16) | OPC_REGIMM,
 331    OPC_TNEI     = (0x0E << 16) | OPC_REGIMM,
 332    OPC_SIGRIE   = (0x17 << 16) | OPC_REGIMM,
 333    OPC_SYNCI    = (0x1F << 16) | OPC_REGIMM,
 334
 335    OPC_DAHI     = (0x06 << 16) | OPC_REGIMM,
 336    OPC_DATI     = (0x1e << 16) | OPC_REGIMM,
 337};
 338
 339/* Special2 opcodes */
 340#define MASK_SPECIAL2(op)  MASK_OP_MAJOR(op) | (op & 0x3F)
 341
 342enum {
 343    /* Multiply & xxx operations */
 344    OPC_MADD     = 0x00 | OPC_SPECIAL2,
 345    OPC_MADDU    = 0x01 | OPC_SPECIAL2,
 346    OPC_MUL      = 0x02 | OPC_SPECIAL2,
 347    OPC_MSUB     = 0x04 | OPC_SPECIAL2,
 348    OPC_MSUBU    = 0x05 | OPC_SPECIAL2,
 349    /* Loongson 2F */
 350    OPC_MULT_G_2F   = 0x10 | OPC_SPECIAL2,
 351    OPC_DMULT_G_2F  = 0x11 | OPC_SPECIAL2,
 352    OPC_MULTU_G_2F  = 0x12 | OPC_SPECIAL2,
 353    OPC_DMULTU_G_2F = 0x13 | OPC_SPECIAL2,
 354    OPC_DIV_G_2F    = 0x14 | OPC_SPECIAL2,
 355    OPC_DDIV_G_2F   = 0x15 | OPC_SPECIAL2,
 356    OPC_DIVU_G_2F   = 0x16 | OPC_SPECIAL2,
 357    OPC_DDIVU_G_2F  = 0x17 | OPC_SPECIAL2,
 358    OPC_MOD_G_2F    = 0x1c | OPC_SPECIAL2,
 359    OPC_DMOD_G_2F   = 0x1d | OPC_SPECIAL2,
 360    OPC_MODU_G_2F   = 0x1e | OPC_SPECIAL2,
 361    OPC_DMODU_G_2F  = 0x1f | OPC_SPECIAL2,
 362    /* Misc */
 363    OPC_CLZ      = 0x20 | OPC_SPECIAL2,
 364    OPC_CLO      = 0x21 | OPC_SPECIAL2,
 365    OPC_DCLZ     = 0x24 | OPC_SPECIAL2,
 366    OPC_DCLO     = 0x25 | OPC_SPECIAL2,
 367    /* Special */
 368    OPC_SDBBP    = 0x3F | OPC_SPECIAL2,
 369};
 370
 371/* Special3 opcodes */
 372#define MASK_SPECIAL3(op)  MASK_OP_MAJOR(op) | (op & 0x3F)
 373
 374enum {
 375    OPC_EXT      = 0x00 | OPC_SPECIAL3,
 376    OPC_DEXTM    = 0x01 | OPC_SPECIAL3,
 377    OPC_DEXTU    = 0x02 | OPC_SPECIAL3,
 378    OPC_DEXT     = 0x03 | OPC_SPECIAL3,
 379    OPC_INS      = 0x04 | OPC_SPECIAL3,
 380    OPC_DINSM    = 0x05 | OPC_SPECIAL3,
 381    OPC_DINSU    = 0x06 | OPC_SPECIAL3,
 382    OPC_DINS     = 0x07 | OPC_SPECIAL3,
 383    OPC_FORK     = 0x08 | OPC_SPECIAL3,
 384    OPC_YIELD    = 0x09 | OPC_SPECIAL3,
 385    OPC_BSHFL    = 0x20 | OPC_SPECIAL3,
 386    OPC_DBSHFL   = 0x24 | OPC_SPECIAL3,
 387    OPC_RDHWR    = 0x3B | OPC_SPECIAL3,
 388
 389    /* Loongson 2E */
 390    OPC_MULT_G_2E   = 0x18 | OPC_SPECIAL3,
 391    OPC_MULTU_G_2E  = 0x19 | OPC_SPECIAL3,
 392    OPC_DIV_G_2E    = 0x1A | OPC_SPECIAL3,
 393    OPC_DIVU_G_2E   = 0x1B | OPC_SPECIAL3,
 394    OPC_DMULT_G_2E  = 0x1C | OPC_SPECIAL3,
 395    OPC_DMULTU_G_2E = 0x1D | OPC_SPECIAL3,
 396    OPC_DDIV_G_2E   = 0x1E | OPC_SPECIAL3,
 397    OPC_DDIVU_G_2E  = 0x1F | OPC_SPECIAL3,
 398    OPC_MOD_G_2E    = 0x22 | OPC_SPECIAL3,
 399    OPC_MODU_G_2E   = 0x23 | OPC_SPECIAL3,
 400    OPC_DMOD_G_2E   = 0x26 | OPC_SPECIAL3,
 401    OPC_DMODU_G_2E  = 0x27 | OPC_SPECIAL3,
 402
 403    /* MIPS DSP Load */
 404    OPC_LX_DSP         = 0x0A | OPC_SPECIAL3,
 405    /* MIPS DSP Arithmetic */
 406    OPC_ADDU_QB_DSP    = 0x10 | OPC_SPECIAL3,
 407    OPC_ADDU_OB_DSP    = 0x14 | OPC_SPECIAL3,
 408    OPC_ABSQ_S_PH_DSP  = 0x12 | OPC_SPECIAL3,
 409    OPC_ABSQ_S_QH_DSP  = 0x16 | OPC_SPECIAL3,
 410    /* OPC_ADDUH_QB_DSP is same as OPC_MULT_G_2E.  */
 411    /* OPC_ADDUH_QB_DSP   = 0x18 | OPC_SPECIAL3,  */
 412    OPC_CMPU_EQ_QB_DSP = 0x11 | OPC_SPECIAL3,
 413    OPC_CMPU_EQ_OB_DSP = 0x15 | OPC_SPECIAL3,
 414    /* MIPS DSP GPR-Based Shift Sub-class */
 415    OPC_SHLL_QB_DSP    = 0x13 | OPC_SPECIAL3,
 416    OPC_SHLL_OB_DSP    = 0x17 | OPC_SPECIAL3,
 417    /* MIPS DSP Multiply Sub-class insns */
 418    /* OPC_MUL_PH_DSP is same as OPC_ADDUH_QB_DSP.  */
 419    /* OPC_MUL_PH_DSP     = 0x18 | OPC_SPECIAL3,  */
 420    OPC_DPA_W_PH_DSP   = 0x30 | OPC_SPECIAL3,
 421    OPC_DPAQ_W_QH_DSP  = 0x34 | OPC_SPECIAL3,
 422    /* DSP Bit/Manipulation Sub-class */
 423    OPC_INSV_DSP       = 0x0C | OPC_SPECIAL3,
 424    OPC_DINSV_DSP      = 0x0D | OPC_SPECIAL3,
 425    /* MIPS DSP Append Sub-class */
 426    OPC_APPEND_DSP     = 0x31 | OPC_SPECIAL3,
 427    OPC_DAPPEND_DSP    = 0x35 | OPC_SPECIAL3,
 428    /* MIPS DSP Accumulator and DSPControl Access Sub-class */
 429    OPC_EXTR_W_DSP     = 0x38 | OPC_SPECIAL3,
 430    OPC_DEXTR_W_DSP    = 0x3C | OPC_SPECIAL3,
 431
 432    /* EVA */
 433    OPC_LWLE           = 0x19 | OPC_SPECIAL3,
 434    OPC_LWRE           = 0x1A | OPC_SPECIAL3,
 435    OPC_CACHEE         = 0x1B | OPC_SPECIAL3,
 436    OPC_SBE            = 0x1C | OPC_SPECIAL3,
 437    OPC_SHE            = 0x1D | OPC_SPECIAL3,
 438    OPC_SCE            = 0x1E | OPC_SPECIAL3,
 439    OPC_SWE            = 0x1F | OPC_SPECIAL3,
 440    OPC_SWLE           = 0x21 | OPC_SPECIAL3,
 441    OPC_SWRE           = 0x22 | OPC_SPECIAL3,
 442    OPC_PREFE          = 0x23 | OPC_SPECIAL3,
 443    OPC_LBUE           = 0x28 | OPC_SPECIAL3,
 444    OPC_LHUE           = 0x29 | OPC_SPECIAL3,
 445    OPC_LBE            = 0x2C | OPC_SPECIAL3,
 446    OPC_LHE            = 0x2D | OPC_SPECIAL3,
 447    OPC_LLE            = 0x2E | OPC_SPECIAL3,
 448    OPC_LWE            = 0x2F | OPC_SPECIAL3,
 449
 450    /* R6 */
 451    R6_OPC_PREF        = 0x35 | OPC_SPECIAL3,
 452    R6_OPC_CACHE       = 0x25 | OPC_SPECIAL3,
 453    R6_OPC_LL          = 0x36 | OPC_SPECIAL3,
 454    R6_OPC_SC          = 0x26 | OPC_SPECIAL3,
 455    R6_OPC_LLD         = 0x37 | OPC_SPECIAL3,
 456    R6_OPC_SCD         = 0x27 | OPC_SPECIAL3,
 457};
 458
 459/* BSHFL opcodes */
 460#define MASK_BSHFL(op)     MASK_SPECIAL3(op) | (op & (0x1F << 6))
 461
 462enum {
 463    OPC_WSBH      = (0x02 << 6) | OPC_BSHFL,
 464    OPC_SEB       = (0x10 << 6) | OPC_BSHFL,
 465    OPC_SEH       = (0x18 << 6) | OPC_BSHFL,
 466    OPC_ALIGN     = (0x08 << 6) | OPC_BSHFL, /* 010.bp (010.00 to 010.11) */
 467    OPC_ALIGN_1   = (0x09 << 6) | OPC_BSHFL,
 468    OPC_ALIGN_2   = (0x0A << 6) | OPC_BSHFL,
 469    OPC_ALIGN_3   = (0x0B << 6) | OPC_BSHFL,
 470    OPC_BITSWAP   = (0x00 << 6) | OPC_BSHFL  /* 00000 */
 471};
 472
 473/* DBSHFL opcodes */
 474#define MASK_DBSHFL(op)    MASK_SPECIAL3(op) | (op & (0x1F << 6))
 475
 476enum {
 477    OPC_DSBH       = (0x02 << 6) | OPC_DBSHFL,
 478    OPC_DSHD       = (0x05 << 6) | OPC_DBSHFL,
 479    OPC_DALIGN     = (0x08 << 6) | OPC_DBSHFL, /* 01.bp (01.000 to 01.111) */
 480    OPC_DALIGN_1   = (0x09 << 6) | OPC_DBSHFL,
 481    OPC_DALIGN_2   = (0x0A << 6) | OPC_DBSHFL,
 482    OPC_DALIGN_3   = (0x0B << 6) | OPC_DBSHFL,
 483    OPC_DALIGN_4   = (0x0C << 6) | OPC_DBSHFL,
 484    OPC_DALIGN_5   = (0x0D << 6) | OPC_DBSHFL,
 485    OPC_DALIGN_6   = (0x0E << 6) | OPC_DBSHFL,
 486    OPC_DALIGN_7   = (0x0F << 6) | OPC_DBSHFL,
 487    OPC_DBITSWAP   = (0x00 << 6) | OPC_DBSHFL, /* 00000 */
 488};
 489
 490/* MIPS DSP REGIMM opcodes */
 491enum {
 492    OPC_BPOSGE32 = (0x1C << 16) | OPC_REGIMM,
 493    OPC_BPOSGE64 = (0x1D << 16) | OPC_REGIMM,
 494};
 495
 496#define MASK_LX(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
 497/* MIPS DSP Load */
 498enum {
 499    OPC_LBUX = (0x06 << 6) | OPC_LX_DSP,
 500    OPC_LHX  = (0x04 << 6) | OPC_LX_DSP,
 501    OPC_LWX  = (0x00 << 6) | OPC_LX_DSP,
 502    OPC_LDX = (0x08 << 6) | OPC_LX_DSP,
 503};
 504
 505#define MASK_ADDU_QB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
 506enum {
 507    /* MIPS DSP Arithmetic Sub-class */
 508    OPC_ADDQ_PH        = (0x0A << 6) | OPC_ADDU_QB_DSP,
 509    OPC_ADDQ_S_PH      = (0x0E << 6) | OPC_ADDU_QB_DSP,
 510    OPC_ADDQ_S_W       = (0x16 << 6) | OPC_ADDU_QB_DSP,
 511    OPC_ADDU_QB        = (0x00 << 6) | OPC_ADDU_QB_DSP,
 512    OPC_ADDU_S_QB      = (0x04 << 6) | OPC_ADDU_QB_DSP,
 513    OPC_ADDU_PH        = (0x08 << 6) | OPC_ADDU_QB_DSP,
 514    OPC_ADDU_S_PH      = (0x0C << 6) | OPC_ADDU_QB_DSP,
 515    OPC_SUBQ_PH        = (0x0B << 6) | OPC_ADDU_QB_DSP,
 516    OPC_SUBQ_S_PH      = (0x0F << 6) | OPC_ADDU_QB_DSP,
 517    OPC_SUBQ_S_W       = (0x17 << 6) | OPC_ADDU_QB_DSP,
 518    OPC_SUBU_QB        = (0x01 << 6) | OPC_ADDU_QB_DSP,
 519    OPC_SUBU_S_QB      = (0x05 << 6) | OPC_ADDU_QB_DSP,
 520    OPC_SUBU_PH        = (0x09 << 6) | OPC_ADDU_QB_DSP,
 521    OPC_SUBU_S_PH      = (0x0D << 6) | OPC_ADDU_QB_DSP,
 522    OPC_ADDSC          = (0x10 << 6) | OPC_ADDU_QB_DSP,
 523    OPC_ADDWC          = (0x11 << 6) | OPC_ADDU_QB_DSP,
 524    OPC_MODSUB         = (0x12 << 6) | OPC_ADDU_QB_DSP,
 525    OPC_RADDU_W_QB     = (0x14 << 6) | OPC_ADDU_QB_DSP,
 526    /* MIPS DSP Multiply Sub-class insns */
 527    OPC_MULEU_S_PH_QBL = (0x06 << 6) | OPC_ADDU_QB_DSP,
 528    OPC_MULEU_S_PH_QBR = (0x07 << 6) | OPC_ADDU_QB_DSP,
 529    OPC_MULQ_RS_PH     = (0x1F << 6) | OPC_ADDU_QB_DSP,
 530    OPC_MULEQ_S_W_PHL  = (0x1C << 6) | OPC_ADDU_QB_DSP,
 531    OPC_MULEQ_S_W_PHR  = (0x1D << 6) | OPC_ADDU_QB_DSP,
 532    OPC_MULQ_S_PH      = (0x1E << 6) | OPC_ADDU_QB_DSP,
 533};
 534
 535#define OPC_ADDUH_QB_DSP OPC_MULT_G_2E
 536#define MASK_ADDUH_QB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
 537enum {
 538    /* MIPS DSP Arithmetic Sub-class */
 539    OPC_ADDUH_QB   = (0x00 << 6) | OPC_ADDUH_QB_DSP,
 540    OPC_ADDUH_R_QB = (0x02 << 6) | OPC_ADDUH_QB_DSP,
 541    OPC_ADDQH_PH   = (0x08 << 6) | OPC_ADDUH_QB_DSP,
 542    OPC_ADDQH_R_PH = (0x0A << 6) | OPC_ADDUH_QB_DSP,
 543    OPC_ADDQH_W    = (0x10 << 6) | OPC_ADDUH_QB_DSP,
 544    OPC_ADDQH_R_W  = (0x12 << 6) | OPC_ADDUH_QB_DSP,
 545    OPC_SUBUH_QB   = (0x01 << 6) | OPC_ADDUH_QB_DSP,
 546    OPC_SUBUH_R_QB = (0x03 << 6) | OPC_ADDUH_QB_DSP,
 547    OPC_SUBQH_PH   = (0x09 << 6) | OPC_ADDUH_QB_DSP,
 548    OPC_SUBQH_R_PH = (0x0B << 6) | OPC_ADDUH_QB_DSP,
 549    OPC_SUBQH_W    = (0x11 << 6) | OPC_ADDUH_QB_DSP,
 550    OPC_SUBQH_R_W  = (0x13 << 6) | OPC_ADDUH_QB_DSP,
 551    /* MIPS DSP Multiply Sub-class insns */
 552    OPC_MUL_PH     = (0x0C << 6) | OPC_ADDUH_QB_DSP,
 553    OPC_MUL_S_PH   = (0x0E << 6) | OPC_ADDUH_QB_DSP,
 554    OPC_MULQ_S_W   = (0x16 << 6) | OPC_ADDUH_QB_DSP,
 555    OPC_MULQ_RS_W  = (0x17 << 6) | OPC_ADDUH_QB_DSP,
 556};
 557
 558#define MASK_ABSQ_S_PH(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
 559enum {
 560    /* MIPS DSP Arithmetic Sub-class */
 561    OPC_ABSQ_S_QB       = (0x01 << 6) | OPC_ABSQ_S_PH_DSP,
 562    OPC_ABSQ_S_PH       = (0x09 << 6) | OPC_ABSQ_S_PH_DSP,
 563    OPC_ABSQ_S_W        = (0x11 << 6) | OPC_ABSQ_S_PH_DSP,
 564    OPC_PRECEQ_W_PHL    = (0x0C << 6) | OPC_ABSQ_S_PH_DSP,
 565    OPC_PRECEQ_W_PHR    = (0x0D << 6) | OPC_ABSQ_S_PH_DSP,
 566    OPC_PRECEQU_PH_QBL  = (0x04 << 6) | OPC_ABSQ_S_PH_DSP,
 567    OPC_PRECEQU_PH_QBR  = (0x05 << 6) | OPC_ABSQ_S_PH_DSP,
 568    OPC_PRECEQU_PH_QBLA = (0x06 << 6) | OPC_ABSQ_S_PH_DSP,
 569    OPC_PRECEQU_PH_QBRA = (0x07 << 6) | OPC_ABSQ_S_PH_DSP,
 570    OPC_PRECEU_PH_QBL   = (0x1C << 6) | OPC_ABSQ_S_PH_DSP,
 571    OPC_PRECEU_PH_QBR   = (0x1D << 6) | OPC_ABSQ_S_PH_DSP,
 572    OPC_PRECEU_PH_QBLA  = (0x1E << 6) | OPC_ABSQ_S_PH_DSP,
 573    OPC_PRECEU_PH_QBRA  = (0x1F << 6) | OPC_ABSQ_S_PH_DSP,
 574    /* DSP Bit/Manipulation Sub-class */
 575    OPC_BITREV          = (0x1B << 6) | OPC_ABSQ_S_PH_DSP,
 576    OPC_REPL_QB         = (0x02 << 6) | OPC_ABSQ_S_PH_DSP,
 577    OPC_REPLV_QB        = (0x03 << 6) | OPC_ABSQ_S_PH_DSP,
 578    OPC_REPL_PH         = (0x0A << 6) | OPC_ABSQ_S_PH_DSP,
 579    OPC_REPLV_PH        = (0x0B << 6) | OPC_ABSQ_S_PH_DSP,
 580};
 581
 582#define MASK_CMPU_EQ_QB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
 583enum {
 584    /* MIPS DSP Arithmetic Sub-class */
 585    OPC_PRECR_QB_PH      = (0x0D << 6) | OPC_CMPU_EQ_QB_DSP,
 586    OPC_PRECRQ_QB_PH     = (0x0C << 6) | OPC_CMPU_EQ_QB_DSP,
 587    OPC_PRECR_SRA_PH_W   = (0x1E << 6) | OPC_CMPU_EQ_QB_DSP,
 588    OPC_PRECR_SRA_R_PH_W = (0x1F << 6) | OPC_CMPU_EQ_QB_DSP,
 589    OPC_PRECRQ_PH_W      = (0x14 << 6) | OPC_CMPU_EQ_QB_DSP,
 590    OPC_PRECRQ_RS_PH_W   = (0x15 << 6) | OPC_CMPU_EQ_QB_DSP,
 591    OPC_PRECRQU_S_QB_PH  = (0x0F << 6) | OPC_CMPU_EQ_QB_DSP,
 592    /* DSP Compare-Pick Sub-class */
 593    OPC_CMPU_EQ_QB       = (0x00 << 6) | OPC_CMPU_EQ_QB_DSP,
 594    OPC_CMPU_LT_QB       = (0x01 << 6) | OPC_CMPU_EQ_QB_DSP,
 595    OPC_CMPU_LE_QB       = (0x02 << 6) | OPC_CMPU_EQ_QB_DSP,
 596    OPC_CMPGU_EQ_QB      = (0x04 << 6) | OPC_CMPU_EQ_QB_DSP,
 597    OPC_CMPGU_LT_QB      = (0x05 << 6) | OPC_CMPU_EQ_QB_DSP,
 598    OPC_CMPGU_LE_QB      = (0x06 << 6) | OPC_CMPU_EQ_QB_DSP,
 599    OPC_CMPGDU_EQ_QB     = (0x18 << 6) | OPC_CMPU_EQ_QB_DSP,
 600    OPC_CMPGDU_LT_QB     = (0x19 << 6) | OPC_CMPU_EQ_QB_DSP,
 601    OPC_CMPGDU_LE_QB     = (0x1A << 6) | OPC_CMPU_EQ_QB_DSP,
 602    OPC_CMP_EQ_PH        = (0x08 << 6) | OPC_CMPU_EQ_QB_DSP,
 603    OPC_CMP_LT_PH        = (0x09 << 6) | OPC_CMPU_EQ_QB_DSP,
 604    OPC_CMP_LE_PH        = (0x0A << 6) | OPC_CMPU_EQ_QB_DSP,
 605    OPC_PICK_QB          = (0x03 << 6) | OPC_CMPU_EQ_QB_DSP,
 606    OPC_PICK_PH          = (0x0B << 6) | OPC_CMPU_EQ_QB_DSP,
 607    OPC_PACKRL_PH        = (0x0E << 6) | OPC_CMPU_EQ_QB_DSP,
 608};
 609
 610#define MASK_SHLL_QB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
 611enum {
 612    /* MIPS DSP GPR-Based Shift Sub-class */
 613    OPC_SHLL_QB    = (0x00 << 6) | OPC_SHLL_QB_DSP,
 614    OPC_SHLLV_QB   = (0x02 << 6) | OPC_SHLL_QB_DSP,
 615    OPC_SHLL_PH    = (0x08 << 6) | OPC_SHLL_QB_DSP,
 616    OPC_SHLLV_PH   = (0x0A << 6) | OPC_SHLL_QB_DSP,
 617    OPC_SHLL_S_PH  = (0x0C << 6) | OPC_SHLL_QB_DSP,
 618    OPC_SHLLV_S_PH = (0x0E << 6) | OPC_SHLL_QB_DSP,
 619    OPC_SHLL_S_W   = (0x14 << 6) | OPC_SHLL_QB_DSP,
 620    OPC_SHLLV_S_W  = (0x16 << 6) | OPC_SHLL_QB_DSP,
 621    OPC_SHRL_QB    = (0x01 << 6) | OPC_SHLL_QB_DSP,
 622    OPC_SHRLV_QB   = (0x03 << 6) | OPC_SHLL_QB_DSP,
 623    OPC_SHRL_PH    = (0x19 << 6) | OPC_SHLL_QB_DSP,
 624    OPC_SHRLV_PH   = (0x1B << 6) | OPC_SHLL_QB_DSP,
 625    OPC_SHRA_QB    = (0x04 << 6) | OPC_SHLL_QB_DSP,
 626    OPC_SHRA_R_QB  = (0x05 << 6) | OPC_SHLL_QB_DSP,
 627    OPC_SHRAV_QB   = (0x06 << 6) | OPC_SHLL_QB_DSP,
 628    OPC_SHRAV_R_QB = (0x07 << 6) | OPC_SHLL_QB_DSP,
 629    OPC_SHRA_PH    = (0x09 << 6) | OPC_SHLL_QB_DSP,
 630    OPC_SHRAV_PH   = (0x0B << 6) | OPC_SHLL_QB_DSP,
 631    OPC_SHRA_R_PH  = (0x0D << 6) | OPC_SHLL_QB_DSP,
 632    OPC_SHRAV_R_PH = (0x0F << 6) | OPC_SHLL_QB_DSP,
 633    OPC_SHRA_R_W   = (0x15 << 6) | OPC_SHLL_QB_DSP,
 634    OPC_SHRAV_R_W  = (0x17 << 6) | OPC_SHLL_QB_DSP,
 635};
 636
 637#define MASK_DPA_W_PH(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
 638enum {
 639    /* MIPS DSP Multiply Sub-class insns */
 640    OPC_DPAU_H_QBL    = (0x03 << 6) | OPC_DPA_W_PH_DSP,
 641    OPC_DPAU_H_QBR    = (0x07 << 6) | OPC_DPA_W_PH_DSP,
 642    OPC_DPSU_H_QBL    = (0x0B << 6) | OPC_DPA_W_PH_DSP,
 643    OPC_DPSU_H_QBR    = (0x0F << 6) | OPC_DPA_W_PH_DSP,
 644    OPC_DPA_W_PH      = (0x00 << 6) | OPC_DPA_W_PH_DSP,
 645    OPC_DPAX_W_PH     = (0x08 << 6) | OPC_DPA_W_PH_DSP,
 646    OPC_DPAQ_S_W_PH   = (0x04 << 6) | OPC_DPA_W_PH_DSP,
 647    OPC_DPAQX_S_W_PH  = (0x18 << 6) | OPC_DPA_W_PH_DSP,
 648    OPC_DPAQX_SA_W_PH = (0x1A << 6) | OPC_DPA_W_PH_DSP,
 649    OPC_DPS_W_PH      = (0x01 << 6) | OPC_DPA_W_PH_DSP,
 650    OPC_DPSX_W_PH     = (0x09 << 6) | OPC_DPA_W_PH_DSP,
 651    OPC_DPSQ_S_W_PH   = (0x05 << 6) | OPC_DPA_W_PH_DSP,
 652    OPC_DPSQX_S_W_PH  = (0x19 << 6) | OPC_DPA_W_PH_DSP,
 653    OPC_DPSQX_SA_W_PH = (0x1B << 6) | OPC_DPA_W_PH_DSP,
 654    OPC_MULSAQ_S_W_PH = (0x06 << 6) | OPC_DPA_W_PH_DSP,
 655    OPC_DPAQ_SA_L_W   = (0x0C << 6) | OPC_DPA_W_PH_DSP,
 656    OPC_DPSQ_SA_L_W   = (0x0D << 6) | OPC_DPA_W_PH_DSP,
 657    OPC_MAQ_S_W_PHL   = (0x14 << 6) | OPC_DPA_W_PH_DSP,
 658    OPC_MAQ_S_W_PHR   = (0x16 << 6) | OPC_DPA_W_PH_DSP,
 659    OPC_MAQ_SA_W_PHL  = (0x10 << 6) | OPC_DPA_W_PH_DSP,
 660    OPC_MAQ_SA_W_PHR  = (0x12 << 6) | OPC_DPA_W_PH_DSP,
 661    OPC_MULSA_W_PH    = (0x02 << 6) | OPC_DPA_W_PH_DSP,
 662};
 663
 664#define MASK_INSV(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
 665enum {
 666    /* DSP Bit/Manipulation Sub-class */
 667    OPC_INSV = (0x00 << 6) | OPC_INSV_DSP,
 668};
 669
 670#define MASK_APPEND(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
 671enum {
 672    /* MIPS DSP Append Sub-class */
 673    OPC_APPEND  = (0x00 << 6) | OPC_APPEND_DSP,
 674    OPC_PREPEND = (0x01 << 6) | OPC_APPEND_DSP,
 675    OPC_BALIGN  = (0x10 << 6) | OPC_APPEND_DSP,
 676};
 677
 678#define MASK_EXTR_W(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
 679enum {
 680    /* MIPS DSP Accumulator and DSPControl Access Sub-class */
 681    OPC_EXTR_W     = (0x00 << 6) | OPC_EXTR_W_DSP,
 682    OPC_EXTR_R_W   = (0x04 << 6) | OPC_EXTR_W_DSP,
 683    OPC_EXTR_RS_W  = (0x06 << 6) | OPC_EXTR_W_DSP,
 684    OPC_EXTR_S_H   = (0x0E << 6) | OPC_EXTR_W_DSP,
 685    OPC_EXTRV_S_H  = (0x0F << 6) | OPC_EXTR_W_DSP,
 686    OPC_EXTRV_W    = (0x01 << 6) | OPC_EXTR_W_DSP,
 687    OPC_EXTRV_R_W  = (0x05 << 6) | OPC_EXTR_W_DSP,
 688    OPC_EXTRV_RS_W = (0x07 << 6) | OPC_EXTR_W_DSP,
 689    OPC_EXTP       = (0x02 << 6) | OPC_EXTR_W_DSP,
 690    OPC_EXTPV      = (0x03 << 6) | OPC_EXTR_W_DSP,
 691    OPC_EXTPDP     = (0x0A << 6) | OPC_EXTR_W_DSP,
 692    OPC_EXTPDPV    = (0x0B << 6) | OPC_EXTR_W_DSP,
 693    OPC_SHILO      = (0x1A << 6) | OPC_EXTR_W_DSP,
 694    OPC_SHILOV     = (0x1B << 6) | OPC_EXTR_W_DSP,
 695    OPC_MTHLIP     = (0x1F << 6) | OPC_EXTR_W_DSP,
 696    OPC_WRDSP      = (0x13 << 6) | OPC_EXTR_W_DSP,
 697    OPC_RDDSP      = (0x12 << 6) | OPC_EXTR_W_DSP,
 698};
 699
 700#define MASK_ABSQ_S_QH(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
 701enum {
 702    /* MIPS DSP Arithmetic Sub-class */
 703    OPC_PRECEQ_L_PWL    = (0x14 << 6) | OPC_ABSQ_S_QH_DSP,
 704    OPC_PRECEQ_L_PWR    = (0x15 << 6) | OPC_ABSQ_S_QH_DSP,
 705    OPC_PRECEQ_PW_QHL   = (0x0C << 6) | OPC_ABSQ_S_QH_DSP,
 706    OPC_PRECEQ_PW_QHR   = (0x0D << 6) | OPC_ABSQ_S_QH_DSP,
 707    OPC_PRECEQ_PW_QHLA  = (0x0E << 6) | OPC_ABSQ_S_QH_DSP,
 708    OPC_PRECEQ_PW_QHRA  = (0x0F << 6) | OPC_ABSQ_S_QH_DSP,
 709    OPC_PRECEQU_QH_OBL  = (0x04 << 6) | OPC_ABSQ_S_QH_DSP,
 710    OPC_PRECEQU_QH_OBR  = (0x05 << 6) | OPC_ABSQ_S_QH_DSP,
 711    OPC_PRECEQU_QH_OBLA = (0x06 << 6) | OPC_ABSQ_S_QH_DSP,
 712    OPC_PRECEQU_QH_OBRA = (0x07 << 6) | OPC_ABSQ_S_QH_DSP,
 713    OPC_PRECEU_QH_OBL   = (0x1C << 6) | OPC_ABSQ_S_QH_DSP,
 714    OPC_PRECEU_QH_OBR   = (0x1D << 6) | OPC_ABSQ_S_QH_DSP,
 715    OPC_PRECEU_QH_OBLA  = (0x1E << 6) | OPC_ABSQ_S_QH_DSP,
 716    OPC_PRECEU_QH_OBRA  = (0x1F << 6) | OPC_ABSQ_S_QH_DSP,
 717    OPC_ABSQ_S_OB       = (0x01 << 6) | OPC_ABSQ_S_QH_DSP,
 718    OPC_ABSQ_S_PW       = (0x11 << 6) | OPC_ABSQ_S_QH_DSP,
 719    OPC_ABSQ_S_QH       = (0x09 << 6) | OPC_ABSQ_S_QH_DSP,
 720    /* DSP Bit/Manipulation Sub-class */
 721    OPC_REPL_OB         = (0x02 << 6) | OPC_ABSQ_S_QH_DSP,
 722    OPC_REPL_PW         = (0x12 << 6) | OPC_ABSQ_S_QH_DSP,
 723    OPC_REPL_QH         = (0x0A << 6) | OPC_ABSQ_S_QH_DSP,
 724    OPC_REPLV_OB        = (0x03 << 6) | OPC_ABSQ_S_QH_DSP,
 725    OPC_REPLV_PW        = (0x13 << 6) | OPC_ABSQ_S_QH_DSP,
 726    OPC_REPLV_QH        = (0x0B << 6) | OPC_ABSQ_S_QH_DSP,
 727};
 728
 729#define MASK_ADDU_OB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
 730enum {
 731    /* MIPS DSP Multiply Sub-class insns */
 732    OPC_MULEQ_S_PW_QHL = (0x1C << 6) | OPC_ADDU_OB_DSP,
 733    OPC_MULEQ_S_PW_QHR = (0x1D << 6) | OPC_ADDU_OB_DSP,
 734    OPC_MULEU_S_QH_OBL = (0x06 << 6) | OPC_ADDU_OB_DSP,
 735    OPC_MULEU_S_QH_OBR = (0x07 << 6) | OPC_ADDU_OB_DSP,
 736    OPC_MULQ_RS_QH     = (0x1F << 6) | OPC_ADDU_OB_DSP,
 737    /* MIPS DSP Arithmetic Sub-class */
 738    OPC_RADDU_L_OB     = (0x14 << 6) | OPC_ADDU_OB_DSP,
 739    OPC_SUBQ_PW        = (0x13 << 6) | OPC_ADDU_OB_DSP,
 740    OPC_SUBQ_S_PW      = (0x17 << 6) | OPC_ADDU_OB_DSP,
 741    OPC_SUBQ_QH        = (0x0B << 6) | OPC_ADDU_OB_DSP,
 742    OPC_SUBQ_S_QH      = (0x0F << 6) | OPC_ADDU_OB_DSP,
 743    OPC_SUBU_OB        = (0x01 << 6) | OPC_ADDU_OB_DSP,
 744    OPC_SUBU_S_OB      = (0x05 << 6) | OPC_ADDU_OB_DSP,
 745    OPC_SUBU_QH        = (0x09 << 6) | OPC_ADDU_OB_DSP,
 746    OPC_SUBU_S_QH      = (0x0D << 6) | OPC_ADDU_OB_DSP,
 747    OPC_SUBUH_OB       = (0x19 << 6) | OPC_ADDU_OB_DSP,
 748    OPC_SUBUH_R_OB     = (0x1B << 6) | OPC_ADDU_OB_DSP,
 749    OPC_ADDQ_PW        = (0x12 << 6) | OPC_ADDU_OB_DSP,
 750    OPC_ADDQ_S_PW      = (0x16 << 6) | OPC_ADDU_OB_DSP,
 751    OPC_ADDQ_QH        = (0x0A << 6) | OPC_ADDU_OB_DSP,
 752    OPC_ADDQ_S_QH      = (0x0E << 6) | OPC_ADDU_OB_DSP,
 753    OPC_ADDU_OB        = (0x00 << 6) | OPC_ADDU_OB_DSP,
 754    OPC_ADDU_S_OB      = (0x04 << 6) | OPC_ADDU_OB_DSP,
 755    OPC_ADDU_QH        = (0x08 << 6) | OPC_ADDU_OB_DSP,
 756    OPC_ADDU_S_QH      = (0x0C << 6) | OPC_ADDU_OB_DSP,
 757    OPC_ADDUH_OB       = (0x18 << 6) | OPC_ADDU_OB_DSP,
 758    OPC_ADDUH_R_OB     = (0x1A << 6) | OPC_ADDU_OB_DSP,
 759};
 760
 761#define MASK_CMPU_EQ_OB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
 762enum {
 763    /* DSP Compare-Pick Sub-class */
 764    OPC_CMP_EQ_PW         = (0x10 << 6) | OPC_CMPU_EQ_OB_DSP,
 765    OPC_CMP_LT_PW         = (0x11 << 6) | OPC_CMPU_EQ_OB_DSP,
 766    OPC_CMP_LE_PW         = (0x12 << 6) | OPC_CMPU_EQ_OB_DSP,
 767    OPC_CMP_EQ_QH         = (0x08 << 6) | OPC_CMPU_EQ_OB_DSP,
 768    OPC_CMP_LT_QH         = (0x09 << 6) | OPC_CMPU_EQ_OB_DSP,
 769    OPC_CMP_LE_QH         = (0x0A << 6) | OPC_CMPU_EQ_OB_DSP,
 770    OPC_CMPGDU_EQ_OB      = (0x18 << 6) | OPC_CMPU_EQ_OB_DSP,
 771    OPC_CMPGDU_LT_OB      = (0x19 << 6) | OPC_CMPU_EQ_OB_DSP,
 772    OPC_CMPGDU_LE_OB      = (0x1A << 6) | OPC_CMPU_EQ_OB_DSP,
 773    OPC_CMPGU_EQ_OB       = (0x04 << 6) | OPC_CMPU_EQ_OB_DSP,
 774    OPC_CMPGU_LT_OB       = (0x05 << 6) | OPC_CMPU_EQ_OB_DSP,
 775    OPC_CMPGU_LE_OB       = (0x06 << 6) | OPC_CMPU_EQ_OB_DSP,
 776    OPC_CMPU_EQ_OB        = (0x00 << 6) | OPC_CMPU_EQ_OB_DSP,
 777    OPC_CMPU_LT_OB        = (0x01 << 6) | OPC_CMPU_EQ_OB_DSP,
 778    OPC_CMPU_LE_OB        = (0x02 << 6) | OPC_CMPU_EQ_OB_DSP,
 779    OPC_PACKRL_PW         = (0x0E << 6) | OPC_CMPU_EQ_OB_DSP,
 780    OPC_PICK_OB           = (0x03 << 6) | OPC_CMPU_EQ_OB_DSP,
 781    OPC_PICK_PW           = (0x13 << 6) | OPC_CMPU_EQ_OB_DSP,
 782    OPC_PICK_QH           = (0x0B << 6) | OPC_CMPU_EQ_OB_DSP,
 783    /* MIPS DSP Arithmetic Sub-class */
 784    OPC_PRECR_OB_QH       = (0x0D << 6) | OPC_CMPU_EQ_OB_DSP,
 785    OPC_PRECR_SRA_QH_PW   = (0x1E << 6) | OPC_CMPU_EQ_OB_DSP,
 786    OPC_PRECR_SRA_R_QH_PW = (0x1F << 6) | OPC_CMPU_EQ_OB_DSP,
 787    OPC_PRECRQ_OB_QH      = (0x0C << 6) | OPC_CMPU_EQ_OB_DSP,
 788    OPC_PRECRQ_PW_L       = (0x1C << 6) | OPC_CMPU_EQ_OB_DSP,
 789    OPC_PRECRQ_QH_PW      = (0x14 << 6) | OPC_CMPU_EQ_OB_DSP,
 790    OPC_PRECRQ_RS_QH_PW   = (0x15 << 6) | OPC_CMPU_EQ_OB_DSP,
 791    OPC_PRECRQU_S_OB_QH   = (0x0F << 6) | OPC_CMPU_EQ_OB_DSP,
 792};
 793
 794#define MASK_DAPPEND(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
 795enum {
 796    /* DSP Append Sub-class */
 797    OPC_DAPPEND  = (0x00 << 6) | OPC_DAPPEND_DSP,
 798    OPC_PREPENDD = (0x03 << 6) | OPC_DAPPEND_DSP,
 799    OPC_PREPENDW = (0x01 << 6) | OPC_DAPPEND_DSP,
 800    OPC_DBALIGN  = (0x10 << 6) | OPC_DAPPEND_DSP,
 801};
 802
 803#define MASK_DEXTR_W(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
 804enum {
 805    /* MIPS DSP Accumulator and DSPControl Access Sub-class */
 806    OPC_DMTHLIP     = (0x1F << 6) | OPC_DEXTR_W_DSP,
 807    OPC_DSHILO      = (0x1A << 6) | OPC_DEXTR_W_DSP,
 808    OPC_DEXTP       = (0x02 << 6) | OPC_DEXTR_W_DSP,
 809    OPC_DEXTPDP     = (0x0A << 6) | OPC_DEXTR_W_DSP,
 810    OPC_DEXTPDPV    = (0x0B << 6) | OPC_DEXTR_W_DSP,
 811    OPC_DEXTPV      = (0x03 << 6) | OPC_DEXTR_W_DSP,
 812    OPC_DEXTR_L     = (0x10 << 6) | OPC_DEXTR_W_DSP,
 813    OPC_DEXTR_R_L   = (0x14 << 6) | OPC_DEXTR_W_DSP,
 814    OPC_DEXTR_RS_L  = (0x16 << 6) | OPC_DEXTR_W_DSP,
 815    OPC_DEXTR_W     = (0x00 << 6) | OPC_DEXTR_W_DSP,
 816    OPC_DEXTR_R_W   = (0x04 << 6) | OPC_DEXTR_W_DSP,
 817    OPC_DEXTR_RS_W  = (0x06 << 6) | OPC_DEXTR_W_DSP,
 818    OPC_DEXTR_S_H   = (0x0E << 6) | OPC_DEXTR_W_DSP,
 819    OPC_DEXTRV_L    = (0x11 << 6) | OPC_DEXTR_W_DSP,
 820    OPC_DEXTRV_R_L  = (0x15 << 6) | OPC_DEXTR_W_DSP,
 821    OPC_DEXTRV_RS_L = (0x17 << 6) | OPC_DEXTR_W_DSP,
 822    OPC_DEXTRV_S_H  = (0x0F << 6) | OPC_DEXTR_W_DSP,
 823    OPC_DEXTRV_W    = (0x01 << 6) | OPC_DEXTR_W_DSP,
 824    OPC_DEXTRV_R_W  = (0x05 << 6) | OPC_DEXTR_W_DSP,
 825    OPC_DEXTRV_RS_W = (0x07 << 6) | OPC_DEXTR_W_DSP,
 826    OPC_DSHILOV     = (0x1B << 6) | OPC_DEXTR_W_DSP,
 827};
 828
 829#define MASK_DINSV(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
 830enum {
 831    /* DSP Bit/Manipulation Sub-class */
 832    OPC_DINSV = (0x00 << 6) | OPC_DINSV_DSP,
 833};
 834
 835#define MASK_DPAQ_W_QH(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
 836enum {
 837    /* MIPS DSP Multiply Sub-class insns */
 838    OPC_DMADD         = (0x19 << 6) | OPC_DPAQ_W_QH_DSP,
 839    OPC_DMADDU        = (0x1D << 6) | OPC_DPAQ_W_QH_DSP,
 840    OPC_DMSUB         = (0x1B << 6) | OPC_DPAQ_W_QH_DSP,
 841    OPC_DMSUBU        = (0x1F << 6) | OPC_DPAQ_W_QH_DSP,
 842    OPC_DPA_W_QH      = (0x00 << 6) | OPC_DPAQ_W_QH_DSP,
 843    OPC_DPAQ_S_W_QH   = (0x04 << 6) | OPC_DPAQ_W_QH_DSP,
 844    OPC_DPAQ_SA_L_PW  = (0x0C << 6) | OPC_DPAQ_W_QH_DSP,
 845    OPC_DPAU_H_OBL    = (0x03 << 6) | OPC_DPAQ_W_QH_DSP,
 846    OPC_DPAU_H_OBR    = (0x07 << 6) | OPC_DPAQ_W_QH_DSP,
 847    OPC_DPS_W_QH      = (0x01 << 6) | OPC_DPAQ_W_QH_DSP,
 848    OPC_DPSQ_S_W_QH   = (0x05 << 6) | OPC_DPAQ_W_QH_DSP,
 849    OPC_DPSQ_SA_L_PW  = (0x0D << 6) | OPC_DPAQ_W_QH_DSP,
 850    OPC_DPSU_H_OBL    = (0x0B << 6) | OPC_DPAQ_W_QH_DSP,
 851    OPC_DPSU_H_OBR    = (0x0F << 6) | OPC_DPAQ_W_QH_DSP,
 852    OPC_MAQ_S_L_PWL   = (0x1C << 6) | OPC_DPAQ_W_QH_DSP,
 853    OPC_MAQ_S_L_PWR   = (0x1E << 6) | OPC_DPAQ_W_QH_DSP,
 854    OPC_MAQ_S_W_QHLL  = (0x14 << 6) | OPC_DPAQ_W_QH_DSP,
 855    OPC_MAQ_SA_W_QHLL = (0x10 << 6) | OPC_DPAQ_W_QH_DSP,
 856    OPC_MAQ_S_W_QHLR  = (0x15 << 6) | OPC_DPAQ_W_QH_DSP,
 857    OPC_MAQ_SA_W_QHLR = (0x11 << 6) | OPC_DPAQ_W_QH_DSP,
 858    OPC_MAQ_S_W_QHRL  = (0x16 << 6) | OPC_DPAQ_W_QH_DSP,
 859    OPC_MAQ_SA_W_QHRL = (0x12 << 6) | OPC_DPAQ_W_QH_DSP,
 860    OPC_MAQ_S_W_QHRR  = (0x17 << 6) | OPC_DPAQ_W_QH_DSP,
 861    OPC_MAQ_SA_W_QHRR = (0x13 << 6) | OPC_DPAQ_W_QH_DSP,
 862    OPC_MULSAQ_S_L_PW = (0x0E << 6) | OPC_DPAQ_W_QH_DSP,
 863    OPC_MULSAQ_S_W_QH = (0x06 << 6) | OPC_DPAQ_W_QH_DSP,
 864};
 865
 866#define MASK_SHLL_OB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
 867enum {
 868    /* MIPS DSP GPR-Based Shift Sub-class */
 869    OPC_SHLL_PW    = (0x10 << 6) | OPC_SHLL_OB_DSP,
 870    OPC_SHLL_S_PW  = (0x14 << 6) | OPC_SHLL_OB_DSP,
 871    OPC_SHLLV_OB   = (0x02 << 6) | OPC_SHLL_OB_DSP,
 872    OPC_SHLLV_PW   = (0x12 << 6) | OPC_SHLL_OB_DSP,
 873    OPC_SHLLV_S_PW = (0x16 << 6) | OPC_SHLL_OB_DSP,
 874    OPC_SHLLV_QH   = (0x0A << 6) | OPC_SHLL_OB_DSP,
 875    OPC_SHLLV_S_QH = (0x0E << 6) | OPC_SHLL_OB_DSP,
 876    OPC_SHRA_PW    = (0x11 << 6) | OPC_SHLL_OB_DSP,
 877    OPC_SHRA_R_PW  = (0x15 << 6) | OPC_SHLL_OB_DSP,
 878    OPC_SHRAV_OB   = (0x06 << 6) | OPC_SHLL_OB_DSP,
 879    OPC_SHRAV_R_OB = (0x07 << 6) | OPC_SHLL_OB_DSP,
 880    OPC_SHRAV_PW   = (0x13 << 6) | OPC_SHLL_OB_DSP,
 881    OPC_SHRAV_R_PW = (0x17 << 6) | OPC_SHLL_OB_DSP,
 882    OPC_SHRAV_QH   = (0x0B << 6) | OPC_SHLL_OB_DSP,
 883    OPC_SHRAV_R_QH = (0x0F << 6) | OPC_SHLL_OB_DSP,
 884    OPC_SHRLV_OB   = (0x03 << 6) | OPC_SHLL_OB_DSP,
 885    OPC_SHRLV_QH   = (0x1B << 6) | OPC_SHLL_OB_DSP,
 886    OPC_SHLL_OB    = (0x00 << 6) | OPC_SHLL_OB_DSP,
 887    OPC_SHLL_QH    = (0x08 << 6) | OPC_SHLL_OB_DSP,
 888    OPC_SHLL_S_QH  = (0x0C << 6) | OPC_SHLL_OB_DSP,
 889    OPC_SHRA_OB    = (0x04 << 6) | OPC_SHLL_OB_DSP,
 890    OPC_SHRA_R_OB  = (0x05 << 6) | OPC_SHLL_OB_DSP,
 891    OPC_SHRA_QH    = (0x09 << 6) | OPC_SHLL_OB_DSP,
 892    OPC_SHRA_R_QH  = (0x0D << 6) | OPC_SHLL_OB_DSP,
 893    OPC_SHRL_OB    = (0x01 << 6) | OPC_SHLL_OB_DSP,
 894    OPC_SHRL_QH    = (0x19 << 6) | OPC_SHLL_OB_DSP,
 895};
 896
 897/* Coprocessor 0 (rs field) */
 898#define MASK_CP0(op)       MASK_OP_MAJOR(op) | (op & (0x1F << 21))
 899
 900enum {
 901    OPC_MFC0     = (0x00 << 21) | OPC_CP0,
 902    OPC_DMFC0    = (0x01 << 21) | OPC_CP0,
 903    OPC_MFHC0    = (0x02 << 21) | OPC_CP0,
 904    OPC_MTC0     = (0x04 << 21) | OPC_CP0,
 905    OPC_DMTC0    = (0x05 << 21) | OPC_CP0,
 906    OPC_MTHC0    = (0x06 << 21) | OPC_CP0,
 907    OPC_MFTR     = (0x08 << 21) | OPC_CP0,
 908    OPC_RDPGPR   = (0x0A << 21) | OPC_CP0,
 909    OPC_MFMC0    = (0x0B << 21) | OPC_CP0,
 910    OPC_MTTR     = (0x0C << 21) | OPC_CP0,
 911    OPC_WRPGPR   = (0x0E << 21) | OPC_CP0,
 912    OPC_C0       = (0x10 << 21) | OPC_CP0,
 913    OPC_C0_1     = (0x11 << 21) | OPC_CP0,
 914    OPC_C0_2     = (0x12 << 21) | OPC_CP0,
 915    OPC_C0_3     = (0x13 << 21) | OPC_CP0,
 916    OPC_C0_4     = (0x14 << 21) | OPC_CP0,
 917    OPC_C0_5     = (0x15 << 21) | OPC_CP0,
 918    OPC_C0_6     = (0x16 << 21) | OPC_CP0,
 919    OPC_C0_7     = (0x17 << 21) | OPC_CP0,
 920    OPC_C0_8     = (0x18 << 21) | OPC_CP0,
 921    OPC_C0_9     = (0x19 << 21) | OPC_CP0,
 922    OPC_C0_A     = (0x1A << 21) | OPC_CP0,
 923    OPC_C0_B     = (0x1B << 21) | OPC_CP0,
 924    OPC_C0_C     = (0x1C << 21) | OPC_CP0,
 925    OPC_C0_D     = (0x1D << 21) | OPC_CP0,
 926    OPC_C0_E     = (0x1E << 21) | OPC_CP0,
 927    OPC_C0_F     = (0x1F << 21) | OPC_CP0,
 928};
 929
 930/* MFMC0 opcodes */
 931#define MASK_MFMC0(op)     MASK_CP0(op) | (op & 0xFFFF)
 932
 933enum {
 934    OPC_DMT      = 0x01 | (0 << 5) | (0x0F << 6) | (0x01 << 11) | OPC_MFMC0,
 935    OPC_EMT      = 0x01 | (1 << 5) | (0x0F << 6) | (0x01 << 11) | OPC_MFMC0,
 936    OPC_DVPE     = 0x01 | (0 << 5) | OPC_MFMC0,
 937    OPC_EVPE     = 0x01 | (1 << 5) | OPC_MFMC0,
 938    OPC_DI       = (0 << 5) | (0x0C << 11) | OPC_MFMC0,
 939    OPC_EI       = (1 << 5) | (0x0C << 11) | OPC_MFMC0,
 940    OPC_DVP      = 0x04 | (0 << 3) | (1 << 5) | (0 << 11) | OPC_MFMC0,
 941    OPC_EVP      = 0x04 | (0 << 3) | (0 << 5) | (0 << 11) | OPC_MFMC0,
 942};
 943
 944/* Coprocessor 0 (with rs == C0) */
 945#define MASK_C0(op)        MASK_CP0(op) | (op & 0x3F)
 946
 947enum {
 948    OPC_TLBR     = 0x01 | OPC_C0,
 949    OPC_TLBWI    = 0x02 | OPC_C0,
 950    OPC_TLBINV   = 0x03 | OPC_C0,
 951    OPC_TLBINVF  = 0x04 | OPC_C0,
 952    OPC_TLBWR    = 0x06 | OPC_C0,
 953    OPC_TLBP     = 0x08 | OPC_C0,
 954    OPC_RFE      = 0x10 | OPC_C0,
 955    OPC_ERET     = 0x18 | OPC_C0,
 956    OPC_DERET    = 0x1F | OPC_C0,
 957    OPC_WAIT     = 0x20 | OPC_C0,
 958};
 959
 960/* Coprocessor 1 (rs field) */
 961#define MASK_CP1(op)       MASK_OP_MAJOR(op) | (op & (0x1F << 21))
 962
 963/* Values for the fmt field in FP instructions */
 964enum {
 965    /* 0 - 15 are reserved */
 966    FMT_S = 16,          /* single fp */
 967    FMT_D = 17,          /* double fp */
 968    FMT_E = 18,          /* extended fp */
 969    FMT_Q = 19,          /* quad fp */
 970    FMT_W = 20,          /* 32-bit fixed */
 971    FMT_L = 21,          /* 64-bit fixed */
 972    FMT_PS = 22,         /* paired single fp */
 973    /* 23 - 31 are reserved */
 974};
 975
 976enum {
 977    OPC_MFC1     = (0x00 << 21) | OPC_CP1,
 978    OPC_DMFC1    = (0x01 << 21) | OPC_CP1,
 979    OPC_CFC1     = (0x02 << 21) | OPC_CP1,
 980    OPC_MFHC1    = (0x03 << 21) | OPC_CP1,
 981    OPC_MTC1     = (0x04 << 21) | OPC_CP1,
 982    OPC_DMTC1    = (0x05 << 21) | OPC_CP1,
 983    OPC_CTC1     = (0x06 << 21) | OPC_CP1,
 984    OPC_MTHC1    = (0x07 << 21) | OPC_CP1,
 985    OPC_BC1      = (0x08 << 21) | OPC_CP1, /* bc */
 986    OPC_BC1ANY2  = (0x09 << 21) | OPC_CP1,
 987    OPC_BC1ANY4  = (0x0A << 21) | OPC_CP1,
 988    OPC_BZ_V     = (0x0B << 21) | OPC_CP1,
 989    OPC_BNZ_V    = (0x0F << 21) | OPC_CP1,
 990    OPC_S_FMT    = (FMT_S << 21) | OPC_CP1,
 991    OPC_D_FMT    = (FMT_D << 21) | OPC_CP1,
 992    OPC_E_FMT    = (FMT_E << 21) | OPC_CP1,
 993    OPC_Q_FMT    = (FMT_Q << 21) | OPC_CP1,
 994    OPC_W_FMT    = (FMT_W << 21) | OPC_CP1,
 995    OPC_L_FMT    = (FMT_L << 21) | OPC_CP1,
 996    OPC_PS_FMT   = (FMT_PS << 21) | OPC_CP1,
 997    OPC_BC1EQZ   = (0x09 << 21) | OPC_CP1,
 998    OPC_BC1NEZ   = (0x0D << 21) | OPC_CP1,
 999    OPC_BZ_B     = (0x18 << 21) | OPC_CP1,
1000    OPC_BZ_H     = (0x19 << 21) | OPC_CP1,
1001    OPC_BZ_W     = (0x1A << 21) | OPC_CP1,
1002    OPC_BZ_D     = (0x1B << 21) | OPC_CP1,
1003    OPC_BNZ_B    = (0x1C << 21) | OPC_CP1,
1004    OPC_BNZ_H    = (0x1D << 21) | OPC_CP1,
1005    OPC_BNZ_W    = (0x1E << 21) | OPC_CP1,
1006    OPC_BNZ_D    = (0x1F << 21) | OPC_CP1,
1007};
1008
1009#define MASK_CP1_FUNC(op)       MASK_CP1(op) | (op & 0x3F)
1010#define MASK_BC1(op)            MASK_CP1(op) | (op & (0x3 << 16))
1011
1012enum {
1013    OPC_BC1F     = (0x00 << 16) | OPC_BC1,
1014    OPC_BC1T     = (0x01 << 16) | OPC_BC1,
1015    OPC_BC1FL    = (0x02 << 16) | OPC_BC1,
1016    OPC_BC1TL    = (0x03 << 16) | OPC_BC1,
1017};
1018
1019enum {
1020    OPC_BC1FANY2     = (0x00 << 16) | OPC_BC1ANY2,
1021    OPC_BC1TANY2     = (0x01 << 16) | OPC_BC1ANY2,
1022};
1023
1024enum {
1025    OPC_BC1FANY4     = (0x00 << 16) | OPC_BC1ANY4,
1026    OPC_BC1TANY4     = (0x01 << 16) | OPC_BC1ANY4,
1027};
1028
1029#define MASK_CP2(op)       MASK_OP_MAJOR(op) | (op & (0x1F << 21))
1030
1031enum {
1032    OPC_MFC2    = (0x00 << 21) | OPC_CP2,
1033    OPC_DMFC2   = (0x01 << 21) | OPC_CP2,
1034    OPC_CFC2    = (0x02 << 21) | OPC_CP2,
1035    OPC_MFHC2   = (0x03 << 21) | OPC_CP2,
1036    OPC_MTC2    = (0x04 << 21) | OPC_CP2,
1037    OPC_DMTC2   = (0x05 << 21) | OPC_CP2,
1038    OPC_CTC2    = (0x06 << 21) | OPC_CP2,
1039    OPC_MTHC2   = (0x07 << 21) | OPC_CP2,
1040    OPC_BC2     = (0x08 << 21) | OPC_CP2,
1041    OPC_BC2EQZ  = (0x09 << 21) | OPC_CP2,
1042    OPC_BC2NEZ  = (0x0D << 21) | OPC_CP2,
1043};
1044
1045#define MASK_LMI(op)  (MASK_OP_MAJOR(op) | (op & (0x1F << 21)) | (op & 0x1F))
1046
1047enum {
1048    OPC_PADDSH  = (24 << 21) | (0x00) | OPC_CP2,
1049    OPC_PADDUSH = (25 << 21) | (0x00) | OPC_CP2,
1050    OPC_PADDH   = (26 << 21) | (0x00) | OPC_CP2,
1051    OPC_PADDW   = (27 << 21) | (0x00) | OPC_CP2,
1052    OPC_PADDSB  = (28 << 21) | (0x00) | OPC_CP2,
1053    OPC_PADDUSB = (29 << 21) | (0x00) | OPC_CP2,
1054    OPC_PADDB   = (30 << 21) | (0x00) | OPC_CP2,
1055    OPC_PADDD   = (31 << 21) | (0x00) | OPC_CP2,
1056
1057    OPC_PSUBSH  = (24 << 21) | (0x01) | OPC_CP2,
1058    OPC_PSUBUSH = (25 << 21) | (0x01) | OPC_CP2,
1059    OPC_PSUBH   = (26 << 21) | (0x01) | OPC_CP2,
1060    OPC_PSUBW   = (27 << 21) | (0x01) | OPC_CP2,
1061    OPC_PSUBSB  = (28 << 21) | (0x01) | OPC_CP2,
1062    OPC_PSUBUSB = (29 << 21) | (0x01) | OPC_CP2,
1063    OPC_PSUBB   = (30 << 21) | (0x01) | OPC_CP2,
1064    OPC_PSUBD   = (31 << 21) | (0x01) | OPC_CP2,
1065
1066    OPC_PSHUFH   = (24 << 21) | (0x02) | OPC_CP2,
1067    OPC_PACKSSWH = (25 << 21) | (0x02) | OPC_CP2,
1068    OPC_PACKSSHB = (26 << 21) | (0x02) | OPC_CP2,
1069    OPC_PACKUSHB = (27 << 21) | (0x02) | OPC_CP2,
1070    OPC_XOR_CP2  = (28 << 21) | (0x02) | OPC_CP2,
1071    OPC_NOR_CP2  = (29 << 21) | (0x02) | OPC_CP2,
1072    OPC_AND_CP2  = (30 << 21) | (0x02) | OPC_CP2,
1073    OPC_PANDN    = (31 << 21) | (0x02) | OPC_CP2,
1074
1075    OPC_PUNPCKLHW = (24 << 21) | (0x03) | OPC_CP2,
1076    OPC_PUNPCKHHW = (25 << 21) | (0x03) | OPC_CP2,
1077    OPC_PUNPCKLBH = (26 << 21) | (0x03) | OPC_CP2,
1078    OPC_PUNPCKHBH = (27 << 21) | (0x03) | OPC_CP2,
1079    OPC_PINSRH_0  = (28 << 21) | (0x03) | OPC_CP2,
1080    OPC_PINSRH_1  = (29 << 21) | (0x03) | OPC_CP2,
1081    OPC_PINSRH_2  = (30 << 21) | (0x03) | OPC_CP2,
1082    OPC_PINSRH_3  = (31 << 21) | (0x03) | OPC_CP2,
1083
1084    OPC_PAVGH   = (24 << 21) | (0x08) | OPC_CP2,
1085    OPC_PAVGB   = (25 << 21) | (0x08) | OPC_CP2,
1086    OPC_PMAXSH  = (26 << 21) | (0x08) | OPC_CP2,
1087    OPC_PMINSH  = (27 << 21) | (0x08) | OPC_CP2,
1088    OPC_PMAXUB  = (28 << 21) | (0x08) | OPC_CP2,
1089    OPC_PMINUB  = (29 << 21) | (0x08) | OPC_CP2,
1090
1091    OPC_PCMPEQW = (24 << 21) | (0x09) | OPC_CP2,
1092    OPC_PCMPGTW = (25 << 21) | (0x09) | OPC_CP2,
1093    OPC_PCMPEQH = (26 << 21) | (0x09) | OPC_CP2,
1094    OPC_PCMPGTH = (27 << 21) | (0x09) | OPC_CP2,
1095    OPC_PCMPEQB = (28 << 21) | (0x09) | OPC_CP2,
1096    OPC_PCMPGTB = (29 << 21) | (0x09) | OPC_CP2,
1097
1098    OPC_PSLLW   = (24 << 21) | (0x0A) | OPC_CP2,
1099    OPC_PSLLH   = (25 << 21) | (0x0A) | OPC_CP2,
1100    OPC_PMULLH  = (26 << 21) | (0x0A) | OPC_CP2,
1101    OPC_PMULHH  = (27 << 21) | (0x0A) | OPC_CP2,
1102    OPC_PMULUW  = (28 << 21) | (0x0A) | OPC_CP2,
1103    OPC_PMULHUH = (29 << 21) | (0x0A) | OPC_CP2,
1104
1105    OPC_PSRLW     = (24 << 21) | (0x0B) | OPC_CP2,
1106    OPC_PSRLH     = (25 << 21) | (0x0B) | OPC_CP2,
1107    OPC_PSRAW     = (26 << 21) | (0x0B) | OPC_CP2,
1108    OPC_PSRAH     = (27 << 21) | (0x0B) | OPC_CP2,
1109    OPC_PUNPCKLWD = (28 << 21) | (0x0B) | OPC_CP2,
1110    OPC_PUNPCKHWD = (29 << 21) | (0x0B) | OPC_CP2,
1111
1112    OPC_ADDU_CP2 = (24 << 21) | (0x0C) | OPC_CP2,
1113    OPC_OR_CP2   = (25 << 21) | (0x0C) | OPC_CP2,
1114    OPC_ADD_CP2  = (26 << 21) | (0x0C) | OPC_CP2,
1115    OPC_DADD_CP2 = (27 << 21) | (0x0C) | OPC_CP2,
1116    OPC_SEQU_CP2 = (28 << 21) | (0x0C) | OPC_CP2,
1117    OPC_SEQ_CP2  = (29 << 21) | (0x0C) | OPC_CP2,
1118
1119    OPC_SUBU_CP2 = (24 << 21) | (0x0D) | OPC_CP2,
1120    OPC_PASUBUB  = (25 << 21) | (0x0D) | OPC_CP2,
1121    OPC_SUB_CP2  = (26 << 21) | (0x0D) | OPC_CP2,
1122    OPC_DSUB_CP2 = (27 << 21) | (0x0D) | OPC_CP2,
1123    OPC_SLTU_CP2 = (28 << 21) | (0x0D) | OPC_CP2,
1124    OPC_SLT_CP2  = (29 << 21) | (0x0D) | OPC_CP2,
1125
1126    OPC_SLL_CP2  = (24 << 21) | (0x0E) | OPC_CP2,
1127    OPC_DSLL_CP2 = (25 << 21) | (0x0E) | OPC_CP2,
1128    OPC_PEXTRH   = (26 << 21) | (0x0E) | OPC_CP2,
1129    OPC_PMADDHW  = (27 << 21) | (0x0E) | OPC_CP2,
1130    OPC_SLEU_CP2 = (28 << 21) | (0x0E) | OPC_CP2,
1131    OPC_SLE_CP2  = (29 << 21) | (0x0E) | OPC_CP2,
1132
1133    OPC_SRL_CP2  = (24 << 21) | (0x0F) | OPC_CP2,
1134    OPC_DSRL_CP2 = (25 << 21) | (0x0F) | OPC_CP2,
1135    OPC_SRA_CP2  = (26 << 21) | (0x0F) | OPC_CP2,
1136    OPC_DSRA_CP2 = (27 << 21) | (0x0F) | OPC_CP2,
1137    OPC_BIADD    = (28 << 21) | (0x0F) | OPC_CP2,
1138    OPC_PMOVMSKB = (29 << 21) | (0x0F) | OPC_CP2,
1139};
1140
1141
1142#define MASK_CP3(op)       MASK_OP_MAJOR(op) | (op & 0x3F)
1143
1144enum {
1145    OPC_LWXC1   = 0x00 | OPC_CP3,
1146    OPC_LDXC1   = 0x01 | OPC_CP3,
1147    OPC_LUXC1   = 0x05 | OPC_CP3,
1148    OPC_SWXC1   = 0x08 | OPC_CP3,
1149    OPC_SDXC1   = 0x09 | OPC_CP3,
1150    OPC_SUXC1   = 0x0D | OPC_CP3,
1151    OPC_PREFX   = 0x0F | OPC_CP3,
1152    OPC_ALNV_PS = 0x1E | OPC_CP3,
1153    OPC_MADD_S  = 0x20 | OPC_CP3,
1154    OPC_MADD_D  = 0x21 | OPC_CP3,
1155    OPC_MADD_PS = 0x26 | OPC_CP3,
1156    OPC_MSUB_S  = 0x28 | OPC_CP3,
1157    OPC_MSUB_D  = 0x29 | OPC_CP3,
1158    OPC_MSUB_PS = 0x2E | OPC_CP3,
1159    OPC_NMADD_S = 0x30 | OPC_CP3,
1160    OPC_NMADD_D = 0x31 | OPC_CP3,
1161    OPC_NMADD_PS= 0x36 | OPC_CP3,
1162    OPC_NMSUB_S = 0x38 | OPC_CP3,
1163    OPC_NMSUB_D = 0x39 | OPC_CP3,
1164    OPC_NMSUB_PS= 0x3E | OPC_CP3,
1165};
1166
1167/* MSA Opcodes */
1168#define MASK_MSA_MINOR(op)    (MASK_OP_MAJOR(op) | (op & 0x3F))
1169enum {
1170    OPC_MSA_I8_00   = 0x00 | OPC_MSA,
1171    OPC_MSA_I8_01   = 0x01 | OPC_MSA,
1172    OPC_MSA_I8_02   = 0x02 | OPC_MSA,
1173    OPC_MSA_I5_06   = 0x06 | OPC_MSA,
1174    OPC_MSA_I5_07   = 0x07 | OPC_MSA,
1175    OPC_MSA_BIT_09  = 0x09 | OPC_MSA,
1176    OPC_MSA_BIT_0A  = 0x0A | OPC_MSA,
1177    OPC_MSA_3R_0D   = 0x0D | OPC_MSA,
1178    OPC_MSA_3R_0E   = 0x0E | OPC_MSA,
1179    OPC_MSA_3R_0F   = 0x0F | OPC_MSA,
1180    OPC_MSA_3R_10   = 0x10 | OPC_MSA,
1181    OPC_MSA_3R_11   = 0x11 | OPC_MSA,
1182    OPC_MSA_3R_12   = 0x12 | OPC_MSA,
1183    OPC_MSA_3R_13   = 0x13 | OPC_MSA,
1184    OPC_MSA_3R_14   = 0x14 | OPC_MSA,
1185    OPC_MSA_3R_15   = 0x15 | OPC_MSA,
1186    OPC_MSA_ELM     = 0x19 | OPC_MSA,
1187    OPC_MSA_3RF_1A  = 0x1A | OPC_MSA,
1188    OPC_MSA_3RF_1B  = 0x1B | OPC_MSA,
1189    OPC_MSA_3RF_1C  = 0x1C | OPC_MSA,
1190    OPC_MSA_VEC     = 0x1E | OPC_MSA,
1191
1192    /* MI10 instruction */
1193    OPC_LD_B    = (0x20) | OPC_MSA,
1194    OPC_LD_H    = (0x21) | OPC_MSA,
1195    OPC_LD_W    = (0x22) | OPC_MSA,
1196    OPC_LD_D    = (0x23) | OPC_MSA,
1197    OPC_ST_B    = (0x24) | OPC_MSA,
1198    OPC_ST_H    = (0x25) | OPC_MSA,
1199    OPC_ST_W    = (0x26) | OPC_MSA,
1200    OPC_ST_D    = (0x27) | OPC_MSA,
1201};
1202
1203enum {
1204    /* I5 instruction df(bits 22..21) = _b, _h, _w, _d */
1205    OPC_ADDVI_df    = (0x0 << 23) | OPC_MSA_I5_06,
1206    OPC_CEQI_df     = (0x0 << 23) | OPC_MSA_I5_07,
1207    OPC_SUBVI_df    = (0x1 << 23) | OPC_MSA_I5_06,
1208    OPC_MAXI_S_df   = (0x2 << 23) | OPC_MSA_I5_06,
1209    OPC_CLTI_S_df   = (0x2 << 23) | OPC_MSA_I5_07,
1210    OPC_MAXI_U_df   = (0x3 << 23) | OPC_MSA_I5_06,
1211    OPC_CLTI_U_df   = (0x3 << 23) | OPC_MSA_I5_07,
1212    OPC_MINI_S_df   = (0x4 << 23) | OPC_MSA_I5_06,
1213    OPC_CLEI_S_df   = (0x4 << 23) | OPC_MSA_I5_07,
1214    OPC_MINI_U_df   = (0x5 << 23) | OPC_MSA_I5_06,
1215    OPC_CLEI_U_df   = (0x5 << 23) | OPC_MSA_I5_07,
1216    OPC_LDI_df      = (0x6 << 23) | OPC_MSA_I5_07,
1217
1218    /* I8 instruction */
1219    OPC_ANDI_B  = (0x0 << 24) | OPC_MSA_I8_00,
1220    OPC_BMNZI_B = (0x0 << 24) | OPC_MSA_I8_01,
1221    OPC_SHF_B   = (0x0 << 24) | OPC_MSA_I8_02,
1222    OPC_ORI_B   = (0x1 << 24) | OPC_MSA_I8_00,
1223    OPC_BMZI_B  = (0x1 << 24) | OPC_MSA_I8_01,
1224    OPC_SHF_H   = (0x1 << 24) | OPC_MSA_I8_02,
1225    OPC_NORI_B  = (0x2 << 24) | OPC_MSA_I8_00,
1226    OPC_BSELI_B = (0x2 << 24) | OPC_MSA_I8_01,
1227    OPC_SHF_W   = (0x2 << 24) | OPC_MSA_I8_02,
1228    OPC_XORI_B  = (0x3 << 24) | OPC_MSA_I8_00,
1229
1230    /* VEC/2R/2RF instruction */
1231    OPC_AND_V   = (0x00 << 21) | OPC_MSA_VEC,
1232    OPC_OR_V    = (0x01 << 21) | OPC_MSA_VEC,
1233    OPC_NOR_V   = (0x02 << 21) | OPC_MSA_VEC,
1234    OPC_XOR_V   = (0x03 << 21) | OPC_MSA_VEC,
1235    OPC_BMNZ_V  = (0x04 << 21) | OPC_MSA_VEC,
1236    OPC_BMZ_V   = (0x05 << 21) | OPC_MSA_VEC,
1237    OPC_BSEL_V  = (0x06 << 21) | OPC_MSA_VEC,
1238
1239    OPC_MSA_2R      = (0x18 << 21) | OPC_MSA_VEC,
1240    OPC_MSA_2RF     = (0x19 << 21) | OPC_MSA_VEC,
1241
1242    /* 2R instruction df(bits 17..16) = _b, _h, _w, _d */
1243    OPC_FILL_df = (0x00 << 18) | OPC_MSA_2R,
1244    OPC_PCNT_df = (0x01 << 18) | OPC_MSA_2R,
1245    OPC_NLOC_df = (0x02 << 18) | OPC_MSA_2R,
1246    OPC_NLZC_df = (0x03 << 18) | OPC_MSA_2R,
1247
1248    /* 2RF instruction df(bit 16) = _w, _d */
1249    OPC_FCLASS_df   = (0x00 << 17) | OPC_MSA_2RF,
1250    OPC_FTRUNC_S_df = (0x01 << 17) | OPC_MSA_2RF,
1251    OPC_FTRUNC_U_df = (0x02 << 17) | OPC_MSA_2RF,
1252    OPC_FSQRT_df    = (0x03 << 17) | OPC_MSA_2RF,
1253    OPC_FRSQRT_df   = (0x04 << 17) | OPC_MSA_2RF,
1254    OPC_FRCP_df     = (0x05 << 17) | OPC_MSA_2RF,
1255    OPC_FRINT_df    = (0x06 << 17) | OPC_MSA_2RF,
1256    OPC_FLOG2_df    = (0x07 << 17) | OPC_MSA_2RF,
1257    OPC_FEXUPL_df   = (0x08 << 17) | OPC_MSA_2RF,
1258    OPC_FEXUPR_df   = (0x09 << 17) | OPC_MSA_2RF,
1259    OPC_FFQL_df     = (0x0A << 17) | OPC_MSA_2RF,
1260    OPC_FFQR_df     = (0x0B << 17) | OPC_MSA_2RF,
1261    OPC_FTINT_S_df  = (0x0C << 17) | OPC_MSA_2RF,
1262    OPC_FTINT_U_df  = (0x0D << 17) | OPC_MSA_2RF,
1263    OPC_FFINT_S_df  = (0x0E << 17) | OPC_MSA_2RF,
1264    OPC_FFINT_U_df  = (0x0F << 17) | OPC_MSA_2RF,
1265
1266    /* 3R instruction df(bits 22..21) = _b, _h, _w, d */
1267    OPC_SLL_df      = (0x0 << 23) | OPC_MSA_3R_0D,
1268    OPC_ADDV_df     = (0x0 << 23) | OPC_MSA_3R_0E,
1269    OPC_CEQ_df      = (0x0 << 23) | OPC_MSA_3R_0F,
1270    OPC_ADD_A_df    = (0x0 << 23) | OPC_MSA_3R_10,
1271    OPC_SUBS_S_df   = (0x0 << 23) | OPC_MSA_3R_11,
1272    OPC_MULV_df     = (0x0 << 23) | OPC_MSA_3R_12,
1273    OPC_DOTP_S_df   = (0x0 << 23) | OPC_MSA_3R_13,
1274    OPC_SLD_df      = (0x0 << 23) | OPC_MSA_3R_14,
1275    OPC_VSHF_df     = (0x0 << 23) | OPC_MSA_3R_15,
1276    OPC_SRA_df      = (0x1 << 23) | OPC_MSA_3R_0D,
1277    OPC_SUBV_df     = (0x1 << 23) | OPC_MSA_3R_0E,
1278    OPC_ADDS_A_df   = (0x1 << 23) | OPC_MSA_3R_10,
1279    OPC_SUBS_U_df   = (0x1 << 23) | OPC_MSA_3R_11,
1280    OPC_MADDV_df    = (0x1 << 23) | OPC_MSA_3R_12,
1281    OPC_DOTP_U_df   = (0x1 << 23) | OPC_MSA_3R_13,
1282    OPC_SPLAT_df    = (0x1 << 23) | OPC_MSA_3R_14,
1283    OPC_SRAR_df     = (0x1 << 23) | OPC_MSA_3R_15,
1284    OPC_SRL_df      = (0x2 << 23) | OPC_MSA_3R_0D,
1285    OPC_MAX_S_df    = (0x2 << 23) | OPC_MSA_3R_0E,
1286    OPC_CLT_S_df    = (0x2 << 23) | OPC_MSA_3R_0F,
1287    OPC_ADDS_S_df   = (0x2 << 23) | OPC_MSA_3R_10,
1288    OPC_SUBSUS_U_df = (0x2 << 23) | OPC_MSA_3R_11,
1289    OPC_MSUBV_df    = (0x2 << 23) | OPC_MSA_3R_12,
1290    OPC_DPADD_S_df  = (0x2 << 23) | OPC_MSA_3R_13,
1291    OPC_PCKEV_df    = (0x2 << 23) | OPC_MSA_3R_14,
1292    OPC_SRLR_df     = (0x2 << 23) | OPC_MSA_3R_15,
1293    OPC_BCLR_df     = (0x3 << 23) | OPC_MSA_3R_0D,
1294    OPC_MAX_U_df    = (0x3 << 23) | OPC_MSA_3R_0E,
1295    OPC_CLT_U_df    = (0x3 << 23) | OPC_MSA_3R_0F,
1296    OPC_ADDS_U_df   = (0x3 << 23) | OPC_MSA_3R_10,
1297    OPC_SUBSUU_S_df = (0x3 << 23) | OPC_MSA_3R_11,
1298    OPC_DPADD_U_df  = (0x3 << 23) | OPC_MSA_3R_13,
1299    OPC_PCKOD_df    = (0x3 << 23) | OPC_MSA_3R_14,
1300    OPC_BSET_df     = (0x4 << 23) | OPC_MSA_3R_0D,
1301    OPC_MIN_S_df    = (0x4 << 23) | OPC_MSA_3R_0E,
1302    OPC_CLE_S_df    = (0x4 << 23) | OPC_MSA_3R_0F,
1303    OPC_AVE_S_df    = (0x4 << 23) | OPC_MSA_3R_10,
1304    OPC_ASUB_S_df   = (0x4 << 23) | OPC_MSA_3R_11,
1305    OPC_DIV_S_df    = (0x4 << 23) | OPC_MSA_3R_12,
1306    OPC_DPSUB_S_df  = (0x4 << 23) | OPC_MSA_3R_13,
1307    OPC_ILVL_df     = (0x4 << 23) | OPC_MSA_3R_14,
1308    OPC_HADD_S_df   = (0x4 << 23) | OPC_MSA_3R_15,
1309    OPC_BNEG_df     = (0x5 << 23) | OPC_MSA_3R_0D,
1310    OPC_MIN_U_df    = (0x5 << 23) | OPC_MSA_3R_0E,
1311    OPC_CLE_U_df    = (0x5 << 23) | OPC_MSA_3R_0F,
1312    OPC_AVE_U_df    = (0x5 << 23) | OPC_MSA_3R_10,
1313    OPC_ASUB_U_df   = (0x5 << 23) | OPC_MSA_3R_11,
1314    OPC_DIV_U_df    = (0x5 << 23) | OPC_MSA_3R_12,
1315    OPC_DPSUB_U_df  = (0x5 << 23) | OPC_MSA_3R_13,
1316    OPC_ILVR_df     = (0x5 << 23) | OPC_MSA_3R_14,
1317    OPC_HADD_U_df   = (0x5 << 23) | OPC_MSA_3R_15,
1318    OPC_BINSL_df    = (0x6 << 23) | OPC_MSA_3R_0D,
1319    OPC_MAX_A_df    = (0x6 << 23) | OPC_MSA_3R_0E,
1320    OPC_AVER_S_df   = (0x6 << 23) | OPC_MSA_3R_10,
1321    OPC_MOD_S_df    = (0x6 << 23) | OPC_MSA_3R_12,
1322    OPC_ILVEV_df    = (0x6 << 23) | OPC_MSA_3R_14,
1323    OPC_HSUB_S_df   = (0x6 << 23) | OPC_MSA_3R_15,
1324    OPC_BINSR_df    = (0x7 << 23) | OPC_MSA_3R_0D,
1325    OPC_MIN_A_df    = (0x7 << 23) | OPC_MSA_3R_0E,
1326    OPC_AVER_U_df   = (0x7 << 23) | OPC_MSA_3R_10,
1327    OPC_MOD_U_df    = (0x7 << 23) | OPC_MSA_3R_12,
1328    OPC_ILVOD_df    = (0x7 << 23) | OPC_MSA_3R_14,
1329    OPC_HSUB_U_df   = (0x7 << 23) | OPC_MSA_3R_15,
1330
1331    /* ELM instructions df(bits 21..16) = _b, _h, _w, _d */
1332    OPC_SLDI_df     = (0x0 << 22) | (0x00 << 16) | OPC_MSA_ELM,
1333    OPC_CTCMSA      = (0x0 << 22) | (0x3E << 16) | OPC_MSA_ELM,
1334    OPC_SPLATI_df   = (0x1 << 22) | (0x00 << 16) | OPC_MSA_ELM,
1335    OPC_CFCMSA      = (0x1 << 22) | (0x3E << 16) | OPC_MSA_ELM,
1336    OPC_COPY_S_df   = (0x2 << 22) | (0x00 << 16) | OPC_MSA_ELM,
1337    OPC_MOVE_V      = (0x2 << 22) | (0x3E << 16) | OPC_MSA_ELM,
1338    OPC_COPY_U_df   = (0x3 << 22) | (0x00 << 16) | OPC_MSA_ELM,
1339    OPC_INSERT_df   = (0x4 << 22) | (0x00 << 16) | OPC_MSA_ELM,
1340    OPC_INSVE_df    = (0x5 << 22) | (0x00 << 16) | OPC_MSA_ELM,
1341
1342    /* 3RF instruction _df(bit 21) = _w, _d */
1343    OPC_FCAF_df     = (0x0 << 22) | OPC_MSA_3RF_1A,
1344    OPC_FADD_df     = (0x0 << 22) | OPC_MSA_3RF_1B,
1345    OPC_FCUN_df     = (0x1 << 22) | OPC_MSA_3RF_1A,
1346    OPC_FSUB_df     = (0x1 << 22) | OPC_MSA_3RF_1B,
1347    OPC_FCOR_df     = (0x1 << 22) | OPC_MSA_3RF_1C,
1348    OPC_FCEQ_df     = (0x2 << 22) | OPC_MSA_3RF_1A,
1349    OPC_FMUL_df     = (0x2 << 22) | OPC_MSA_3RF_1B,
1350    OPC_FCUNE_df    = (0x2 << 22) | OPC_MSA_3RF_1C,
1351    OPC_FCUEQ_df    = (0x3 << 22) | OPC_MSA_3RF_1A,
1352    OPC_FDIV_df     = (0x3 << 22) | OPC_MSA_3RF_1B,
1353    OPC_FCNE_df     = (0x3 << 22) | OPC_MSA_3RF_1C,
1354    OPC_FCLT_df     = (0x4 << 22) | OPC_MSA_3RF_1A,
1355    OPC_FMADD_df    = (0x4 << 22) | OPC_MSA_3RF_1B,
1356    OPC_MUL_Q_df    = (0x4 << 22) | OPC_MSA_3RF_1C,
1357    OPC_FCULT_df    = (0x5 << 22) | OPC_MSA_3RF_1A,
1358    OPC_FMSUB_df    = (0x5 << 22) | OPC_MSA_3RF_1B,
1359    OPC_MADD_Q_df   = (0x5 << 22) | OPC_MSA_3RF_1C,
1360    OPC_FCLE_df     = (0x6 << 22) | OPC_MSA_3RF_1A,
1361    OPC_MSUB_Q_df   = (0x6 << 22) | OPC_MSA_3RF_1C,
1362    OPC_FCULE_df    = (0x7 << 22) | OPC_MSA_3RF_1A,
1363    OPC_FEXP2_df    = (0x7 << 22) | OPC_MSA_3RF_1B,
1364    OPC_FSAF_df     = (0x8 << 22) | OPC_MSA_3RF_1A,
1365    OPC_FEXDO_df    = (0x8 << 22) | OPC_MSA_3RF_1B,
1366    OPC_FSUN_df     = (0x9 << 22) | OPC_MSA_3RF_1A,
1367    OPC_FSOR_df     = (0x9 << 22) | OPC_MSA_3RF_1C,
1368    OPC_FSEQ_df     = (0xA << 22) | OPC_MSA_3RF_1A,
1369    OPC_FTQ_df      = (0xA << 22) | OPC_MSA_3RF_1B,
1370    OPC_FSUNE_df    = (0xA << 22) | OPC_MSA_3RF_1C,
1371    OPC_FSUEQ_df    = (0xB << 22) | OPC_MSA_3RF_1A,
1372    OPC_FSNE_df     = (0xB << 22) | OPC_MSA_3RF_1C,
1373    OPC_FSLT_df     = (0xC << 22) | OPC_MSA_3RF_1A,
1374    OPC_FMIN_df     = (0xC << 22) | OPC_MSA_3RF_1B,
1375    OPC_MULR_Q_df   = (0xC << 22) | OPC_MSA_3RF_1C,
1376    OPC_FSULT_df    = (0xD << 22) | OPC_MSA_3RF_1A,
1377    OPC_FMIN_A_df   = (0xD << 22) | OPC_MSA_3RF_1B,
1378    OPC_MADDR_Q_df  = (0xD << 22) | OPC_MSA_3RF_1C,
1379    OPC_FSLE_df     = (0xE << 22) | OPC_MSA_3RF_1A,
1380    OPC_FMAX_df     = (0xE << 22) | OPC_MSA_3RF_1B,
1381    OPC_MSUBR_Q_df  = (0xE << 22) | OPC_MSA_3RF_1C,
1382    OPC_FSULE_df    = (0xF << 22) | OPC_MSA_3RF_1A,
1383    OPC_FMAX_A_df   = (0xF << 22) | OPC_MSA_3RF_1B,
1384
1385    /* BIT instruction df(bits 22..16) = _B _H _W _D */
1386    OPC_SLLI_df     = (0x0 << 23) | OPC_MSA_BIT_09,
1387    OPC_SAT_S_df    = (0x0 << 23) | OPC_MSA_BIT_0A,
1388    OPC_SRAI_df     = (0x1 << 23) | OPC_MSA_BIT_09,
1389    OPC_SAT_U_df    = (0x1 << 23) | OPC_MSA_BIT_0A,
1390    OPC_SRLI_df     = (0x2 << 23) | OPC_MSA_BIT_09,
1391    OPC_SRARI_df    = (0x2 << 23) | OPC_MSA_BIT_0A,
1392    OPC_BCLRI_df    = (0x3 << 23) | OPC_MSA_BIT_09,
1393    OPC_SRLRI_df    = (0x3 << 23) | OPC_MSA_BIT_0A,
1394    OPC_BSETI_df    = (0x4 << 23) | OPC_MSA_BIT_09,
1395    OPC_BNEGI_df    = (0x5 << 23) | OPC_MSA_BIT_09,
1396    OPC_BINSLI_df   = (0x6 << 23) | OPC_MSA_BIT_09,
1397    OPC_BINSRI_df   = (0x7 << 23) | OPC_MSA_BIT_09,
1398};
1399
1400
1401/*
1402 *    AN OVERVIEW OF MXU EXTENSION INSTRUCTION SET
1403 *    ============================================
1404 *
1405 * MXU (full name: MIPS eXtension/enhanced Unit) is an SIMD extension of MIPS32
1406 * instructions set. It is designed to fit the needs of signal, graphical and
1407 * video processing applications. MXU instruction set is used in Xburst family
1408 * of microprocessors by Ingenic.
1409 *
1410 * MXU unit contains 17 registers called X0-X16. X0 is always zero, and X16 is
1411 * the control register.
1412 *
1413 * The notation used in MXU assembler mnemonics
1414 * --------------------------------------------
1415 *
1416 *  Registers:
1417 *
1418 *   XRa, XRb, XRc, XRd - MXU registers
1419 *   Rb, Rc, Rd, Rs, Rt - general purpose MIPS registers
1420 *
1421 *  Subfields:
1422 *
1423 *   aptn1              - 1-bit accumulate add/subtract pattern
1424 *   aptn2              - 2-bit accumulate add/subtract pattern
1425 *   eptn2              - 2-bit execute add/subtract pattern
1426 *   optn2              - 2-bit operand pattern
1427 *   optn3              - 3-bit operand pattern
1428 *   sft4               - 4-bit shift amount
1429 *   strd2              - 2-bit stride amount
1430 *
1431 *  Prefixes:
1432 *
1433 *   <Operation parallel level><Operand size>
1434 *     S                         32
1435 *     D                         16
1436 *     Q                          8
1437 *
1438 *  Suffixes:
1439 *
1440 *   E - Expand results
1441 *   F - Fixed point multiplication
1442 *   L - Low part result
1443 *   R - Doing rounding
1444 *   V - Variable instead of immediate
1445 *   W - Combine above L and V
1446 *
1447 *  Operations:
1448 *
1449 *   ADD   - Add or subtract
1450 *   ADDC  - Add with carry-in
1451 *   ACC   - Accumulate
1452 *   ASUM  - Sum together then accumulate (add or subtract)
1453 *   ASUMC - Sum together then accumulate (add or subtract) with carry-in
1454 *   AVG   - Average between 2 operands
1455 *   ABD   - Absolute difference
1456 *   ALN   - Align data
1457 *   AND   - Logical bitwise 'and' operation
1458 *   CPS   - Copy sign
1459 *   EXTR  - Extract bits
1460 *   I2M   - Move from GPR register to MXU register
1461 *   LDD   - Load data from memory to XRF
1462 *   LDI   - Load data from memory to XRF (and increase the address base)
1463 *   LUI   - Load unsigned immediate
1464 *   MUL   - Multiply
1465 *   MULU  - Unsigned multiply
1466 *   MADD  - 64-bit operand add 32x32 product
1467 *   MSUB  - 64-bit operand subtract 32x32 product
1468 *   MAC   - Multiply and accumulate (add or subtract)
1469 *   MAD   - Multiply and add or subtract
1470 *   MAX   - Maximum between 2 operands
1471 *   MIN   - Minimum between 2 operands
1472 *   M2I   - Move from MXU register to GPR register
1473 *   MOVZ  - Move if zero
1474 *   MOVN  - Move if non-zero
1475 *   NOR   - Logical bitwise 'nor' operation
1476 *   OR    - Logical bitwise 'or' operation
1477 *   STD   - Store data from XRF to memory
1478 *   SDI   - Store data from XRF to memory (and increase the address base)
1479 *   SLT   - Set of less than comparison
1480 *   SAD   - Sum of absolute differences
1481 *   SLL   - Logical shift left
1482 *   SLR   - Logical shift right
1483 *   SAR   - Arithmetic shift right
1484 *   SAT   - Saturation
1485 *   SFL   - Shuffle
1486 *   SCOP  - Calculate x’s scope (-1, means x<0; 0, means x==0; 1, means x>0)
1487 *   XOR   - Logical bitwise 'exclusive or' operation
1488 *
1489 * Load/Store instructions           Multiplication instructions
1490 * -----------------------           ---------------------------
1491 *
1492 *  S32LDD XRa, Rb, s12               S32MADD XRa, XRd, Rs, Rt
1493 *  S32STD XRa, Rb, s12               S32MADDU XRa, XRd, Rs, Rt
1494 *  S32LDDV XRa, Rb, rc, strd2        S32MSUB XRa, XRd, Rs, Rt
1495 *  S32STDV XRa, Rb, rc, strd2        S32MSUBU XRa, XRd, Rs, Rt
1496 *  S32LDI XRa, Rb, s12               S32MUL XRa, XRd, Rs, Rt
1497 *  S32SDI XRa, Rb, s12               S32MULU XRa, XRd, Rs, Rt
1498 *  S32LDIV XRa, Rb, rc, strd2        D16MUL XRa, XRb, XRc, XRd, optn2
1499 *  S32SDIV XRa, Rb, rc, strd2        D16MULE XRa, XRb, XRc, optn2
1500 *  S32LDDR XRa, Rb, s12              D16MULF XRa, XRb, XRc, optn2
1501 *  S32STDR XRa, Rb, s12              D16MAC XRa, XRb, XRc, XRd, aptn2, optn2
1502 *  S32LDDVR XRa, Rb, rc, strd2       D16MACE XRa, XRb, XRc, XRd, aptn2, optn2
1503 *  S32STDVR XRa, Rb, rc, strd2       D16MACF XRa, XRb, XRc, XRd, aptn2, optn2
1504 *  S32LDIR XRa, Rb, s12              D16MADL XRa, XRb, XRc, XRd, aptn2, optn2
1505 *  S32SDIR XRa, Rb, s12              S16MAD XRa, XRb, XRc, XRd, aptn1, optn2
1506 *  S32LDIVR XRa, Rb, rc, strd2       Q8MUL XRa, XRb, XRc, XRd
1507 *  S32SDIVR XRa, Rb, rc, strd2       Q8MULSU XRa, XRb, XRc, XRd
1508 *  S16LDD XRa, Rb, s10, eptn2        Q8MAC XRa, XRb, XRc, XRd, aptn2
1509 *  S16STD XRa, Rb, s10, eptn2        Q8MACSU XRa, XRb, XRc, XRd, aptn2
1510 *  S16LDI XRa, Rb, s10, eptn2        Q8MADL XRa, XRb, XRc, XRd, aptn2
1511 *  S16SDI XRa, Rb, s10, eptn2
1512 *  S8LDD XRa, Rb, s8, eptn3
1513 *  S8STD XRa, Rb, s8, eptn3         Addition and subtraction instructions
1514 *  S8LDI XRa, Rb, s8, eptn3         -------------------------------------
1515 *  S8SDI XRa, Rb, s8, eptn3
1516 *  LXW Rd, Rs, Rt, strd2             D32ADD XRa, XRb, XRc, XRd, eptn2
1517 *  LXH Rd, Rs, Rt, strd2             D32ADDC XRa, XRb, XRc, XRd
1518 *  LXHU Rd, Rs, Rt, strd2            D32ACC XRa, XRb, XRc, XRd, eptn2
1519 *  LXB Rd, Rs, Rt, strd2             D32ACCM XRa, XRb, XRc, XRd, eptn2
1520 *  LXBU Rd, Rs, Rt, strd2            D32ASUM XRa, XRb, XRc, XRd, eptn2
1521 *                                    S32CPS XRa, XRb, XRc
1522 *                                    Q16ADD XRa, XRb, XRc, XRd, eptn2, optn2
1523 * Comparison instructions            Q16ACC XRa, XRb, XRc, XRd, eptn2
1524 * -----------------------            Q16ACCM XRa, XRb, XRc, XRd, eptn2
1525 *                                    D16ASUM XRa, XRb, XRc, XRd, eptn2
1526 *  S32MAX XRa, XRb, XRc              D16CPS XRa, XRb,
1527 *  S32MIN XRa, XRb, XRc              D16AVG XRa, XRb, XRc
1528 *  S32SLT XRa, XRb, XRc              D16AVGR XRa, XRb, XRc
1529 *  S32MOVZ XRa, XRb, XRc             Q8ADD XRa, XRb, XRc, eptn2
1530 *  S32MOVN XRa, XRb, XRc             Q8ADDE XRa, XRb, XRc, XRd, eptn2
1531 *  D16MAX XRa, XRb, XRc              Q8ACCE XRa, XRb, XRc, XRd, eptn2
1532 *  D16MIN XRa, XRb, XRc              Q8ABD XRa, XRb, XRc
1533 *  D16SLT XRa, XRb, XRc              Q8SAD XRa, XRb, XRc, XRd
1534 *  D16MOVZ XRa, XRb, XRc             Q8AVG XRa, XRb, XRc
1535 *  D16MOVN XRa, XRb, XRc             Q8AVGR XRa, XRb, XRc
1536 *  Q8MAX XRa, XRb, XRc               D8SUM XRa, XRb, XRc, XRd
1537 *  Q8MIN XRa, XRb, XRc               D8SUMC XRa, XRb, XRc, XRd
1538 *  Q8SLT XRa, XRb, XRc
1539 *  Q8SLTU XRa, XRb, XRc
1540 *  Q8MOVZ XRa, XRb, XRc             Shift instructions
1541 *  Q8MOVN XRa, XRb, XRc             ------------------
1542 *
1543 *                                    D32SLL XRa, XRb, XRc, XRd, sft4
1544 * Bitwise instructions               D32SLR XRa, XRb, XRc, XRd, sft4
1545 * --------------------               D32SAR XRa, XRb, XRc, XRd, sft4
1546 *                                    D32SARL XRa, XRb, XRc, sft4
1547 *  S32NOR XRa, XRb, XRc              D32SLLV XRa, XRb, Rb
1548 *  S32AND XRa, XRb, XRc              D32SLRV XRa, XRb, Rb
1549 *  S32XOR XRa, XRb, XRc              D32SARV XRa, XRb, Rb
1550 *  S32OR XRa, XRb, XRc               D32SARW XRa, XRb, XRc, Rb
1551 *                                    Q16SLL XRa, XRb, XRc, XRd, sft4
1552 *                                    Q16SLR XRa, XRb, XRc, XRd, sft4
1553 * Miscellaneous instructions         Q16SAR XRa, XRb, XRc, XRd, sft4
1554 * -------------------------          Q16SLLV XRa, XRb, Rb
1555 *                                    Q16SLRV XRa, XRb, Rb
1556 *  S32SFL XRa, XRb, XRc, XRd, optn2  Q16SARV XRa, XRb, Rb
1557 *  S32ALN XRa, XRb, XRc, Rb
1558 *  S32ALNI XRa, XRb, XRc, s3
1559 *  S32LUI XRa, s8, optn3            Move instructions
1560 *  S32EXTR XRa, XRb, Rb, bits5      -----------------
1561 *  S32EXTRV XRa, XRb, Rs, Rt
1562 *  Q16SCOP XRa, XRb, XRc, XRd        S32M2I XRa, Rb
1563 *  Q16SAT XRa, XRb, XRc              S32I2M XRa, Rb
1564 *
1565 *
1566 *              bits
1567 *             05..00
1568 *
1569 *          ┌─ 000000 ─ OPC_MXU_S32MADD
1570 *          ├─ 000001 ─ OPC_MXU_S32MADDU
1571 *          ├─ 000010 ─ <not assigned>   (non-MXU OPC_MUL)
1572 *          │
1573 *          │                               20..18
1574 *          ├─ 000011 ─ OPC_MXU__POOL00 ─┬─ 000 ─ OPC_MXU_S32MAX
1575 *          │                            ├─ 001 ─ OPC_MXU_S32MIN
1576 *          │                            ├─ 010 ─ OPC_MXU_D16MAX
1577 *          │                            ├─ 011 ─ OPC_MXU_D16MIN
1578 *          │                            ├─ 100 ─ OPC_MXU_Q8MAX
1579 *          │                            ├─ 101 ─ OPC_MXU_Q8MIN
1580 *          │                            ├─ 110 ─ OPC_MXU_Q8SLT
1581 *          │                            └─ 111 ─ OPC_MXU_Q8SLTU
1582 *          ├─ 000100 ─ OPC_MXU_S32MSUB
1583 *          ├─ 000101 ─ OPC_MXU_S32MSUBU    20..18
1584 *          ├─ 000110 ─ OPC_MXU__POOL01 ─┬─ 000 ─ OPC_MXU_S32SLT
1585 *          │                            ├─ 001 ─ OPC_MXU_D16SLT
1586 *          │                            ├─ 010 ─ OPC_MXU_D16AVG
1587 *          │                            ├─ 011 ─ OPC_MXU_D16AVGR
1588 *          │                            ├─ 100 ─ OPC_MXU_Q8AVG
1589 *          │                            ├─ 101 ─ OPC_MXU_Q8AVGR
1590 *          │                            └─ 111 ─ OPC_MXU_Q8ADD
1591 *          │
1592 *          │                               20..18
1593 *          ├─ 000111 ─ OPC_MXU__POOL02 ─┬─ 000 ─ OPC_MXU_S32CPS
1594 *          │                            ├─ 010 ─ OPC_MXU_D16CPS
1595 *          │                            ├─ 100 ─ OPC_MXU_Q8ABD
1596 *          │                            └─ 110 ─ OPC_MXU_Q16SAT
1597 *          ├─ 001000 ─ OPC_MXU_D16MUL
1598 *          │                               25..24
1599 *          ├─ 001001 ─ OPC_MXU__POOL03 ─┬─ 00 ─ OPC_MXU_D16MULF
1600 *          │                            └─ 01 ─ OPC_MXU_D16MULE
1601 *          ├─ 001010 ─ OPC_MXU_D16MAC
1602 *          ├─ 001011 ─ OPC_MXU_D16MACF
1603 *          ├─ 001100 ─ OPC_MXU_D16MADL
1604 *          ├─ 001101 ─ OPC_MXU_S16MAD
1605 *          ├─ 001110 ─ OPC_MXU_Q16ADD
1606 *          ├─ 001111 ─ OPC_MXU_D16MACE     23
1607 *          │                            ┌─ 0 ─ OPC_MXU_S32LDD
1608 *          ├─ 010000 ─ OPC_MXU__POOL04 ─┴─ 1 ─ OPC_MXU_S32LDDR
1609 *          │
1610 *          │                               23
1611 *          ├─ 010001 ─ OPC_MXU__POOL05 ─┬─ 0 ─ OPC_MXU_S32STD
1612 *          │                            └─ 1 ─ OPC_MXU_S32STDR
1613 *          │
1614 *          │                               13..10
1615 *          ├─ 010010 ─ OPC_MXU__POOL06 ─┬─ 0000 ─ OPC_MXU_S32LDDV
1616 *          │                            └─ 0001 ─ OPC_MXU_S32LDDVR
1617 *          │
1618 *          │                               13..10
1619 *          ├─ 010011 ─ OPC_MXU__POOL07 ─┬─ 0000 ─ OPC_MXU_S32STDV
1620 *          │                            └─ 0001 ─ OPC_MXU_S32STDVR
1621 *          │
1622 *          │                               23
1623 *          ├─ 010100 ─ OPC_MXU__POOL08 ─┬─ 0 ─ OPC_MXU_S32LDI
1624 *          │                            └─ 1 ─ OPC_MXU_S32LDIR
1625 *          │
1626 *          │                               23
1627 *          ├─ 010101 ─ OPC_MXU__POOL09 ─┬─ 0 ─ OPC_MXU_S32SDI
1628 *          │                            └─ 1 ─ OPC_MXU_S32SDIR
1629 *          │
1630 *          │                               13..10
1631 *          ├─ 010110 ─ OPC_MXU__POOL10 ─┬─ 0000 ─ OPC_MXU_S32LDIV
1632 *          │                            └─ 0001 ─ OPC_MXU_S32LDIVR
1633 *          │
1634 *          │                               13..10
1635 *          ├─ 010111 ─ OPC_MXU__POOL11 ─┬─ 0000 ─ OPC_MXU_S32SDIV
1636 *          │                            └─ 0001 ─ OPC_MXU_S32SDIVR
1637 *          ├─ 011000 ─ OPC_MXU_D32ADD
1638 *          │                               23..22
1639 *   MXU    ├─ 011001 ─ OPC_MXU__POOL12 ─┬─ 00 ─ OPC_MXU_D32ACC
1640 * opcodes ─┤                            ├─ 01 ─ OPC_MXU_D32ACCM
1641 *          │                            └─ 10 ─ OPC_MXU_D32ASUM
1642 *          ├─ 011010 ─ <not assigned>
1643 *          │                               23..22
1644 *          ├─ 011011 ─ OPC_MXU__POOL13 ─┬─ 00 ─ OPC_MXU_Q16ACC
1645 *          │                            ├─ 01 ─ OPC_MXU_Q16ACCM
1646 *          │                            └─ 10 ─ OPC_MXU_Q16ASUM
1647 *          │
1648 *          │                               23..22
1649 *          ├─ 011100 ─ OPC_MXU__POOL14 ─┬─ 00 ─ OPC_MXU_Q8ADDE
1650 *          │                            ├─ 01 ─ OPC_MXU_D8SUM
1651 *          ├─ 011101 ─ OPC_MXU_Q8ACCE   └─ 10 ─ OPC_MXU_D8SUMC
1652 *          ├─ 011110 ─ <not assigned>
1653 *          ├─ 011111 ─ <not assigned>
1654 *          ├─ 100000 ─ <not assigned>   (overlaps with CLZ)
1655 *          ├─ 100001 ─ <not assigned>   (overlaps with CLO)
1656 *          ├─ 100010 ─ OPC_MXU_S8LDD
1657 *          ├─ 100011 ─ OPC_MXU_S8STD       15..14
1658 *          ├─ 100100 ─ OPC_MXU_S8LDI    ┌─ 00 ─ OPC_MXU_S32MUL
1659 *          ├─ 100101 ─ OPC_MXU_S8SDI    ├─ 00 ─ OPC_MXU_S32MULU
1660 *          │                            ├─ 00 ─ OPC_MXU_S32EXTR
1661 *          ├─ 100110 ─ OPC_MXU__POOL15 ─┴─ 00 ─ OPC_MXU_S32EXTRV
1662 *          │
1663 *          │                               20..18
1664 *          ├─ 100111 ─ OPC_MXU__POOL16 ─┬─ 000 ─ OPC_MXU_D32SARW
1665 *          │                            ├─ 001 ─ OPC_MXU_S32ALN
1666 *          ├─ 101000 ─ OPC_MXU_LXB      ├─ 010 ─ OPC_MXU_S32ALNI
1667 *          ├─ 101001 ─ <not assigned>   ├─ 011 ─ OPC_MXU_S32NOR
1668 *          ├─ 101010 ─ OPC_MXU_S16LDD   ├─ 100 ─ OPC_MXU_S32AND
1669 *          ├─ 101011 ─ OPC_MXU_S16STD   ├─ 101 ─ OPC_MXU_S32OR
1670 *          ├─ 101100 ─ OPC_MXU_S16LDI   ├─ 110 ─ OPC_MXU_S32XOR
1671 *          ├─ 101101 ─ OPC_MXU_S16SDI   └─ 111 ─ OPC_MXU_S32LUI
1672 *          ├─ 101110 ─ OPC_MXU_S32M2I
1673 *          ├─ 101111 ─ OPC_MXU_S32I2M
1674 *          ├─ 110000 ─ OPC_MXU_D32SLL
1675 *          ├─ 110001 ─ OPC_MXU_D32SLR      20..18
1676 *          ├─ 110010 ─ OPC_MXU_D32SARL  ┌─ 000 ─ OPC_MXU_D32SLLV
1677 *          ├─ 110011 ─ OPC_MXU_D32SAR   ├─ 001 ─ OPC_MXU_D32SLRV
1678 *          ├─ 110100 ─ OPC_MXU_Q16SLL   ├─ 010 ─ OPC_MXU_D32SARV
1679 *          ├─ 110101 ─ OPC_MXU_Q16SLR   ├─ 011 ─ OPC_MXU_Q16SLLV
1680 *          │                            ├─ 100 ─ OPC_MXU_Q16SLRV
1681 *          ├─ 110110 ─ OPC_MXU__POOL17 ─┴─ 101 ─ OPC_MXU_Q16SARV
1682 *          │
1683 *          ├─ 110111 ─ OPC_MXU_Q16SAR
1684 *          │                               23..22
1685 *          ├─ 111000 ─ OPC_MXU__POOL18 ─┬─ 00 ─ OPC_MXU_Q8MUL
1686 *          │                            └─ 01 ─ OPC_MXU_Q8MULSU
1687 *          │
1688 *          │                               20..18
1689 *          ├─ 111001 ─ OPC_MXU__POOL19 ─┬─ 000 ─ OPC_MXU_Q8MOVZ
1690 *          │                            ├─ 001 ─ OPC_MXU_Q8MOVN
1691 *          │                            ├─ 010 ─ OPC_MXU_D16MOVZ
1692 *          │                            ├─ 011 ─ OPC_MXU_D16MOVN
1693 *          │                            ├─ 100 ─ OPC_MXU_S32MOVZ
1694 *          │                            └─ 101 ─ OPC_MXU_S32MOV
1695 *          │
1696 *          │                               23..22
1697 *          ├─ 111010 ─ OPC_MXU__POOL20 ─┬─ 00 ─ OPC_MXU_Q8MAC
1698 *          │                            └─ 10 ─ OPC_MXU_Q8MACSU
1699 *          ├─ 111011 ─ OPC_MXU_Q16SCOP
1700 *          ├─ 111100 ─ OPC_MXU_Q8MADL
1701 *          ├─ 111101 ─ OPC_MXU_S32SFL
1702 *          ├─ 111110 ─ OPC_MXU_Q8SAD
1703 *          └─ 111111 ─ <not assigned>   (overlaps with SDBBP)
1704 *
1705 *
1706 *   Compiled after:
1707 *
1708 *   "XBurst® Instruction Set Architecture MIPS eXtension/enhanced Unit
1709 *   Programming Manual", Ingenic Semiconductor Co, Ltd., 2017
1710 */
1711
1712enum {
1713    OPC_MXU_S32MADD  = 0x00,
1714    OPC_MXU_S32MADDU = 0x01,
1715    OPC__MXU_MUL     = 0x02,
1716    OPC_MXU__POOL00  = 0x03,
1717    OPC_MXU_S32MSUB  = 0x04,
1718    OPC_MXU_S32MSUBU = 0x05,
1719    OPC_MXU__POOL01  = 0x06,
1720    OPC_MXU__POOL02  = 0x07,
1721    OPC_MXU_D16MUL   = 0x08,
1722    OPC_MXU__POOL03  = 0x09,
1723    OPC_MXU_D16MAC   = 0x0A,
1724    OPC_MXU_D16MACF  = 0x0B,
1725    OPC_MXU_D16MADL  = 0x0C,
1726    OPC_MXU_S16MAD   = 0x0D,
1727    OPC_MXU_Q16ADD   = 0x0E,
1728    OPC_MXU_D16MACE  = 0x0F,
1729    OPC_MXU__POOL04  = 0x10,
1730    OPC_MXU__POOL05  = 0x11,
1731    OPC_MXU__POOL06  = 0x12,
1732    OPC_MXU__POOL07  = 0x13,
1733    OPC_MXU__POOL08  = 0x14,
1734    OPC_MXU__POOL09  = 0x15,
1735    OPC_MXU__POOL10  = 0x16,
1736    OPC_MXU__POOL11  = 0x17,
1737    OPC_MXU_D32ADD   = 0x18,
1738    OPC_MXU__POOL12  = 0x19,
1739    /* not assigned 0x1A */
1740    OPC_MXU__POOL13  = 0x1B,
1741    OPC_MXU__POOL14  = 0x1C,
1742    OPC_MXU_Q8ACCE   = 0x1D,
1743    /* not assigned 0x1E */
1744    /* not assigned 0x1F */
1745    /* not assigned 0x20 */
1746    /* not assigned 0x21 */
1747    OPC_MXU_S8LDD    = 0x22,
1748    OPC_MXU_S8STD    = 0x23,
1749    OPC_MXU_S8LDI    = 0x24,
1750    OPC_MXU_S8SDI    = 0x25,
1751    OPC_MXU__POOL15  = 0x26,
1752    OPC_MXU__POOL16  = 0x27,
1753    OPC_MXU_LXB      = 0x28,
1754    /* not assigned 0x29 */
1755    OPC_MXU_S16LDD   = 0x2A,
1756    OPC_MXU_S16STD   = 0x2B,
1757    OPC_MXU_S16LDI   = 0x2C,
1758    OPC_MXU_S16SDI   = 0x2D,
1759    OPC_MXU_S32M2I   = 0x2E,
1760    OPC_MXU_S32I2M   = 0x2F,
1761    OPC_MXU_D32SLL   = 0x30,
1762    OPC_MXU_D32SLR   = 0x31,
1763    OPC_MXU_D32SARL  = 0x32,
1764    OPC_MXU_D32SAR   = 0x33,
1765    OPC_MXU_Q16SLL   = 0x34,
1766    OPC_MXU_Q16SLR   = 0x35,
1767    OPC_MXU__POOL17  = 0x36,
1768    OPC_MXU_Q16SAR   = 0x37,
1769    OPC_MXU__POOL18  = 0x38,
1770    OPC_MXU__POOL19  = 0x39,
1771    OPC_MXU__POOL20  = 0x3A,
1772    OPC_MXU_Q16SCOP  = 0x3B,
1773    OPC_MXU_Q8MADL   = 0x3C,
1774    OPC_MXU_S32SFL   = 0x3D,
1775    OPC_MXU_Q8SAD    = 0x3E,
1776    /* not assigned 0x3F */
1777};
1778
1779
1780/*
1781 * MXU pool 00
1782 */
1783enum {
1784    OPC_MXU_S32MAX   = 0x00,
1785    OPC_MXU_S32MIN   = 0x01,
1786    OPC_MXU_D16MAX   = 0x02,
1787    OPC_MXU_D16MIN   = 0x03,
1788    OPC_MXU_Q8MAX    = 0x04,
1789    OPC_MXU_Q8MIN    = 0x05,
1790    OPC_MXU_Q8SLT    = 0x06,
1791    OPC_MXU_Q8SLTU   = 0x07,
1792};
1793
1794/*
1795 * MXU pool 01
1796 */
1797enum {
1798    OPC_MXU_S32SLT   = 0x00,
1799    OPC_MXU_D16SLT   = 0x01,
1800    OPC_MXU_D16AVG   = 0x02,
1801    OPC_MXU_D16AVGR  = 0x03,
1802    OPC_MXU_Q8AVG    = 0x04,
1803    OPC_MXU_Q8AVGR   = 0x05,
1804    OPC_MXU_Q8ADD    = 0x07,
1805};
1806
1807/*
1808 * MXU pool 02
1809 */
1810enum {
1811    OPC_MXU_S32CPS   = 0x00,
1812    OPC_MXU_D16CPS   = 0x02,
1813    OPC_MXU_Q8ABD    = 0x04,
1814    OPC_MXU_Q16SAT   = 0x06,
1815};
1816
1817/*
1818 * MXU pool 03
1819 */
1820enum {
1821    OPC_MXU_D16MULF  = 0x00,
1822    OPC_MXU_D16MULE  = 0x01,
1823};
1824
1825/*
1826 * MXU pool 04
1827 */
1828enum {
1829    OPC_MXU_S32LDD   = 0x00,
1830    OPC_MXU_S32LDDR  = 0x01,
1831};
1832
1833/*
1834 * MXU pool 05
1835 */
1836enum {
1837    OPC_MXU_S32STD   = 0x00,
1838    OPC_MXU_S32STDR  = 0x01,
1839};
1840
1841/*
1842 * MXU pool 06
1843 */
1844enum {
1845    OPC_MXU_S32LDDV  = 0x00,
1846    OPC_MXU_S32LDDVR = 0x01,
1847};
1848
1849/*
1850 * MXU pool 07
1851 */
1852enum {
1853    OPC_MXU_S32STDV  = 0x00,
1854    OPC_MXU_S32STDVR = 0x01,
1855};
1856
1857/*
1858 * MXU pool 08
1859 */
1860enum {
1861    OPC_MXU_S32LDI   = 0x00,
1862    OPC_MXU_S32LDIR  = 0x01,
1863};
1864
1865/*
1866 * MXU pool 09
1867 */
1868enum {
1869    OPC_MXU_S32SDI   = 0x00,
1870    OPC_MXU_S32SDIR  = 0x01,
1871};
1872
1873/*
1874 * MXU pool 10
1875 */
1876enum {
1877    OPC_MXU_S32LDIV  = 0x00,
1878    OPC_MXU_S32LDIVR = 0x01,
1879};
1880
1881/*
1882 * MXU pool 11
1883 */
1884enum {
1885    OPC_MXU_S32SDIV  = 0x00,
1886    OPC_MXU_S32SDIVR = 0x01,
1887};
1888
1889/*
1890 * MXU pool 12
1891 */
1892enum {
1893    OPC_MXU_D32ACC   = 0x00,
1894    OPC_MXU_D32ACCM  = 0x01,
1895    OPC_MXU_D32ASUM  = 0x02,
1896};
1897
1898/*
1899 * MXU pool 13
1900 */
1901enum {
1902    OPC_MXU_Q16ACC   = 0x00,
1903    OPC_MXU_Q16ACCM  = 0x01,
1904    OPC_MXU_Q16ASUM  = 0x02,
1905};
1906
1907/*
1908 * MXU pool 14
1909 */
1910enum {
1911    OPC_MXU_Q8ADDE   = 0x00,
1912    OPC_MXU_D8SUM    = 0x01,
1913    OPC_MXU_D8SUMC   = 0x02,
1914};
1915
1916/*
1917 * MXU pool 15
1918 */
1919enum {
1920    OPC_MXU_S32MUL   = 0x00,
1921    OPC_MXU_S32MULU  = 0x01,
1922    OPC_MXU_S32EXTR  = 0x02,
1923    OPC_MXU_S32EXTRV = 0x03,
1924};
1925
1926/*
1927 * MXU pool 16
1928 */
1929enum {
1930    OPC_MXU_D32SARW  = 0x00,
1931    OPC_MXU_S32ALN   = 0x01,
1932    OPC_MXU_S32ALNI  = 0x02,
1933    OPC_MXU_S32NOR   = 0x03,
1934    OPC_MXU_S32AND   = 0x04,
1935    OPC_MXU_S32OR    = 0x05,
1936    OPC_MXU_S32XOR   = 0x06,
1937    OPC_MXU_S32LUI   = 0x07,
1938};
1939
1940/*
1941 * MXU pool 17
1942 */
1943enum {
1944    OPC_MXU_D32SLLV  = 0x00,
1945    OPC_MXU_D32SLRV  = 0x01,
1946    OPC_MXU_D32SARV  = 0x03,
1947    OPC_MXU_Q16SLLV  = 0x04,
1948    OPC_MXU_Q16SLRV  = 0x05,
1949    OPC_MXU_Q16SARV  = 0x07,
1950};
1951
1952/*
1953 * MXU pool 18
1954 */
1955enum {
1956    OPC_MXU_Q8MUL    = 0x00,
1957    OPC_MXU_Q8MULSU  = 0x01,
1958};
1959
1960/*
1961 * MXU pool 19
1962 */
1963enum {
1964    OPC_MXU_Q8MOVZ   = 0x00,
1965    OPC_MXU_Q8MOVN   = 0x01,
1966    OPC_MXU_D16MOVZ  = 0x02,
1967    OPC_MXU_D16MOVN  = 0x03,
1968    OPC_MXU_S32MOVZ  = 0x04,
1969    OPC_MXU_S32MOVN  = 0x05,
1970};
1971
1972/*
1973 * MXU pool 20
1974 */
1975enum {
1976    OPC_MXU_Q8MAC    = 0x00,
1977    OPC_MXU_Q8MACSU  = 0x01,
1978};
1979
1980/*
1981 *     Overview of the TX79-specific instruction set
1982 *     =============================================
1983 *
1984 * The R5900 and the C790 have 128-bit wide GPRs, where the upper 64 bits
1985 * are only used by the specific quadword (128-bit) LQ/SQ load/store
1986 * instructions and certain multimedia instructions (MMIs). These MMIs
1987 * configure the 128-bit data path as two 64-bit, four 32-bit, eight 16-bit
1988 * or sixteen 8-bit paths.
1989 *
1990 * Reference:
1991 *
1992 * The Toshiba TX System RISC TX79 Core Architecture manual,
1993 * https://wiki.qemu.org/File:C790.pdf
1994 *
1995 *     Three-Operand Multiply and Multiply-Add (4 instructions)
1996 *     --------------------------------------------------------
1997 * MADD    [rd,] rs, rt      Multiply/Add
1998 * MADDU   [rd,] rs, rt      Multiply/Add Unsigned
1999 * MULT    [rd,] rs, rt      Multiply (3-operand)
2000 * MULTU   [rd,] rs, rt      Multiply Unsigned (3-operand)
2001 *
2002 *     Multiply Instructions for Pipeline 1 (10 instructions)
2003 *     ------------------------------------------------------
2004 * MULT1   [rd,] rs, rt      Multiply Pipeline 1
2005 * MULTU1  [rd,] rs, rt      Multiply Unsigned Pipeline 1
2006 * DIV1    rs, rt            Divide Pipeline 1
2007 * DIVU1   rs, rt            Divide Unsigned Pipeline 1
2008 * MADD1   [rd,] rs, rt      Multiply-Add Pipeline 1
2009 * MADDU1  [rd,] rs, rt      Multiply-Add Unsigned Pipeline 1
2010 * MFHI1   rd                Move From HI1 Register
2011 * MFLO1   rd                Move From LO1 Register
2012 * MTHI1   rs                Move To HI1 Register
2013 * MTLO1   rs                Move To LO1 Register
2014 *
2015 *     Arithmetic (19 instructions)
2016 *     ----------------------------
2017 * PADDB   rd, rs, rt        Parallel Add Byte
2018 * PSUBB   rd, rs, rt        Parallel Subtract Byte
2019 * PADDH   rd, rs, rt        Parallel Add Halfword
2020 * PSUBH   rd, rs, rt        Parallel Subtract Halfword
2021 * PADDW   rd, rs, rt        Parallel Add Word
2022 * PSUBW   rd, rs, rt        Parallel Subtract Word
2023 * PADSBH  rd, rs, rt        Parallel Add/Subtract Halfword
2024 * PADDSB  rd, rs, rt        Parallel Add with Signed Saturation Byte
2025 * PSUBSB  rd, rs, rt        Parallel Subtract with Signed Saturation Byte
2026 * PADDSH  rd, rs, rt        Parallel Add with Signed Saturation Halfword
2027 * PSUBSH  rd, rs, rt        Parallel Subtract with Signed Saturation Halfword
2028 * PADDSW  rd, rs, rt        Parallel Add with Signed Saturation Word
2029 * PSUBSW  rd, rs, rt        Parallel Subtract with Signed Saturation Word
2030 * PADDUB  rd, rs, rt        Parallel Add with Unsigned saturation Byte
2031 * PSUBUB  rd, rs, rt        Parallel Subtract with Unsigned saturation Byte
2032 * PADDUH  rd, rs, rt        Parallel Add with Unsigned saturation Halfword
2033 * PSUBUH  rd, rs, rt        Parallel Subtract with Unsigned saturation Halfword
2034 * PADDUW  rd, rs, rt        Parallel Add with Unsigned saturation Word
2035 * PSUBUW  rd, rs, rt        Parallel Subtract with Unsigned saturation Word
2036 *
2037 *     Min/Max (4 instructions)
2038 *     ------------------------
2039 * PMAXH   rd, rs, rt        Parallel Maximum Halfword
2040 * PMINH   rd, rs, rt        Parallel Minimum Halfword
2041 * PMAXW   rd, rs, rt        Parallel Maximum Word
2042 * PMINW   rd, rs, rt        Parallel Minimum Word
2043 *
2044 *     Absolute (2 instructions)
2045 *     -------------------------
2046 * PABSH   rd, rt            Parallel Absolute Halfword
2047 * PABSW   rd, rt            Parallel Absolute Word
2048 *
2049 *     Logical (4 instructions)
2050 *     ------------------------
2051 * PAND    rd, rs, rt        Parallel AND
2052 * POR     rd, rs, rt        Parallel OR
2053 * PXOR    rd, rs, rt        Parallel XOR
2054 * PNOR    rd, rs, rt        Parallel NOR
2055 *
2056 *     Shift (9 instructions)
2057 *     ----------------------
2058 * PSLLH   rd, rt, sa        Parallel Shift Left Logical Halfword
2059 * PSRLH   rd, rt, sa        Parallel Shift Right Logical Halfword
2060 * PSRAH   rd, rt, sa        Parallel Shift Right Arithmetic Halfword
2061 * PSLLW   rd, rt, sa        Parallel Shift Left Logical Word
2062 * PSRLW   rd, rt, sa        Parallel Shift Right Logical Word
2063 * PSRAW   rd, rt, sa        Parallel Shift Right Arithmetic Word
2064 * PSLLVW  rd, rt, rs        Parallel Shift Left Logical Variable Word
2065 * PSRLVW  rd, rt, rs        Parallel Shift Right Logical Variable Word
2066 * PSRAVW  rd, rt, rs        Parallel Shift Right Arithmetic Variable Word
2067 *
2068 *     Compare (6 instructions)
2069 *     ------------------------
2070 * PCGTB   rd, rs, rt        Parallel Compare for Greater Than Byte
2071 * PCEQB   rd, rs, rt        Parallel Compare for Equal Byte
2072 * PCGTH   rd, rs, rt        Parallel Compare for Greater Than Halfword
2073 * PCEQH   rd, rs, rt        Parallel Compare for Equal Halfword
2074 * PCGTW   rd, rs, rt        Parallel Compare for Greater Than Word
2075 * PCEQW   rd, rs, rt        Parallel Compare for Equal Word
2076 *
2077 *     LZC (1 instruction)
2078 *     -------------------
2079 * PLZCW   rd, rs            Parallel Leading Zero or One Count Word
2080 *
2081 *     Quadword Load and Store (2 instructions)
2082 *     ----------------------------------------
2083 * LQ      rt, offset(base)  Load Quadword
2084 * SQ      rt, offset(base)  Store Quadword
2085 *
2086 *     Multiply and Divide (19 instructions)
2087 *     -------------------------------------
2088 * PMULTW  rd, rs, rt        Parallel Multiply Word
2089 * PMULTUW rd, rs, rt        Parallel Multiply Unsigned Word
2090 * PDIVW   rs, rt            Parallel Divide Word
2091 * PDIVUW  rs, rt            Parallel Divide Unsigned Word
2092 * PMADDW  rd, rs, rt        Parallel Multiply-Add Word
2093 * PMADDUW rd, rs, rt        Parallel Multiply-Add Unsigned Word
2094 * PMSUBW  rd, rs, rt        Parallel Multiply-Subtract Word
2095 * PMULTH  rd, rs, rt        Parallel Multiply Halfword
2096 * PMADDH  rd, rs, rt        Parallel Multiply-Add Halfword
2097 * PMSUBH  rd, rs, rt        Parallel Multiply-Subtract Halfword
2098 * PHMADH  rd, rs, rt        Parallel Horizontal Multiply-Add Halfword
2099 * PHMSBH  rd, rs, rt        Parallel Horizontal Multiply-Subtract Halfword
2100 * PDIVBW  rs, rt            Parallel Divide Broadcast Word
2101 * PMFHI   rd                Parallel Move From HI Register
2102 * PMFLO   rd                Parallel Move From LO Register
2103 * PMTHI   rs                Parallel Move To HI Register
2104 * PMTLO   rs                Parallel Move To LO Register
2105 * PMFHL   rd                Parallel Move From HI/LO Register
2106 * PMTHL   rs                Parallel Move To HI/LO Register
2107 *
2108 *     Pack/Extend (11 instructions)
2109 *     -----------------------------
2110 * PPAC5   rd, rt            Parallel Pack to 5 bits
2111 * PPACB   rd, rs, rt        Parallel Pack to Byte
2112 * PPACH   rd, rs, rt        Parallel Pack to Halfword
2113 * PPACW   rd, rs, rt        Parallel Pack to Word
2114 * PEXT5   rd, rt            Parallel Extend Upper from 5 bits
2115 * PEXTUB  rd, rs, rt        Parallel Extend Upper from Byte
2116 * PEXTLB  rd, rs, rt        Parallel Extend Lower from Byte
2117 * PEXTUH  rd, rs, rt        Parallel Extend Upper from Halfword
2118 * PEXTLH  rd, rs, rt        Parallel Extend Lower from Halfword
2119 * PEXTUW  rd, rs, rt        Parallel Extend Upper from Word
2120 * PEXTLW  rd, rs, rt        Parallel Extend Lower from Word
2121 *
2122 *     Others (16 instructions)
2123 *     ------------------------
2124 * PCPYH   rd, rt            Parallel Copy Halfword
2125 * PCPYLD  rd, rs, rt        Parallel Copy Lower Doubleword
2126 * PCPYUD  rd, rs, rt        Parallel Copy Upper Doubleword
2127 * PREVH   rd, rt            Parallel Reverse Halfword
2128 * PINTH   rd, rs, rt        Parallel Interleave Halfword
2129 * PINTEH  rd, rs, rt        Parallel Interleave Even Halfword
2130 * PEXEH   rd, rt            Parallel Exchange Even Halfword
2131 * PEXCH   rd, rt            Parallel Exchange Center Halfword
2132 * PEXEW   rd, rt            Parallel Exchange Even Word
2133 * PEXCW   rd, rt            Parallel Exchange Center Word
2134 * QFSRV   rd, rs, rt        Quadword Funnel Shift Right Variable
2135 * MFSA    rd                Move from Shift Amount Register
2136 * MTSA    rs                Move to Shift Amount Register
2137 * MTSAB   rs, immediate     Move Byte Count to Shift Amount Register
2138 * MTSAH   rs, immediate     Move Halfword Count to Shift Amount Register
2139 * PROT3W  rd, rt            Parallel Rotate 3 Words
2140 *
2141 *     MMI (MultiMedia Instruction) encodings
2142 *     ======================================
2143 *
2144 * MMI instructions encoding table keys:
2145 *
2146 *     *   This code is reserved for future use. An attempt to execute it
2147 *         causes a Reserved Instruction exception.
2148 *     %   This code indicates an instruction class. The instruction word
2149 *         must be further decoded by examining additional tables that show
2150 *         the values for other instruction fields.
2151 *     #   This code is reserved for the unsupported instructions DMULT,
2152 *         DMULTU, DDIV, DDIVU, LL, LLD, SC, SCD, LWC2 and SWC2. An attempt
2153 *         to execute it causes a Reserved Instruction exception.
2154 *
2155 * MMI instructions encoded by opcode field (MMI, LQ, SQ):
2156 *
2157 *  31    26                                        0
2158 * +--------+----------------------------------------+
2159 * | opcode |                                        |
2160 * +--------+----------------------------------------+
2161 *
2162 *   opcode  bits 28..26
2163 *     bits |   0   |   1   |   2   |   3   |   4   |   5   |   6   |   7
2164 *   31..29 |  000  |  001  |  010  |  011  |  100  |  101  |  110  |  111
2165 *   -------+-------+-------+-------+-------+-------+-------+-------+-------
2166 *    0 000 |SPECIAL| REGIMM|   J   |  JAL  |  BEQ  |  BNE  |  BLEZ |  BGTZ
2167 *    1 001 |  ADDI | ADDIU |  SLTI | SLTIU |  ANDI |  ORI  |  XORI |  LUI
2168 *    2 010 |  COP0 |  COP1 |   *   |   *   |  BEQL |  BNEL | BLEZL | BGTZL
2169 *    3 011 | DADDI | DADDIU|  LDL  |  LDR  |  MMI% |   *   |   LQ  |   SQ
2170 *    4 100 |   LB  |   LH  |  LWL  |   LW  |  LBU  |  LHU  |  LWR  |  LWU
2171 *    5 101 |   SB  |   SH  |  SWL  |   SW  |  SDL  |  SDR  |  SWR  | CACHE
2172 *    6 110 |   #   |  LWC1 |   #   |  PREF |   #   |  LDC1 |   #   |   LD
2173 *    7 111 |   #   |  SWC1 |   #   |   *   |   #   |  SDC1 |   #   |   SD
2174 */
2175
2176enum {
2177    MMI_OPC_CLASS_MMI = 0x1C << 26,    /* Same as OPC_SPECIAL2 */
2178    MMI_OPC_LQ        = 0x1E << 26,    /* Same as OPC_MSA */
2179    MMI_OPC_SQ        = 0x1F << 26,    /* Same as OPC_SPECIAL3 */
2180};
2181
2182/*
2183 * MMI instructions with opcode field = MMI:
2184 *
2185 *  31    26                                 5      0
2186 * +--------+-------------------------------+--------+
2187 * |   MMI  |                               |function|
2188 * +--------+-------------------------------+--------+
2189 *
2190 * function  bits 2..0
2191 *     bits |   0   |   1   |   2   |   3   |   4   |   5   |   6   |   7
2192 *     5..3 |  000  |  001  |  010  |  011  |  100  |  101  |  110  |  111
2193 *   -------+-------+-------+-------+-------+-------+-------+-------+-------
2194 *    0 000 |  MADD | MADDU |   *   |   *   | PLZCW |   *   |   *   |   *
2195 *    1 001 | MMI0% | MMI2% |   *   |   *   |   *   |   *   |   *   |   *
2196 *    2 010 | MFHI1 | MTHI1 | MFLO1 | MTLO1 |   *   |   *   |   *   |   *
2197 *    3 011 | MULT1 | MULTU1|  DIV1 | DIVU1 |   *   |   *   |   *   |   *
2198 *    4 100 | MADD1 | MADDU1|   *   |   *   |   *   |   *   |   *   |   *
2199 *    5 101 | MMI1% | MMI3% |   *   |   *   |   *   |   *   |   *   |   *
2200 *    6 110 | PMFHL | PMTHL |   *   |   *   | PSLLH |   *   | PSRLH | PSRAH
2201 *    7 111 |   *   |   *   |   *   |   *   | PSLLW |   *   | PSRLW | PSRAW
2202 */
2203
2204#define MASK_MMI(op) (MASK_OP_MAJOR(op) | ((op) & 0x3F))
2205enum {
2206    MMI_OPC_MADD       = 0x00 | MMI_OPC_CLASS_MMI, /* Same as OPC_MADD */
2207    MMI_OPC_MADDU      = 0x01 | MMI_OPC_CLASS_MMI, /* Same as OPC_MADDU */
2208    MMI_OPC_PLZCW      = 0x04 | MMI_OPC_CLASS_MMI,
2209    MMI_OPC_CLASS_MMI0 = 0x08 | MMI_OPC_CLASS_MMI,
2210    MMI_OPC_CLASS_MMI2 = 0x09 | MMI_OPC_CLASS_MMI,
2211    MMI_OPC_MFHI1      = 0x10 | MMI_OPC_CLASS_MMI, /* Same minor as OPC_MFHI */
2212    MMI_OPC_MTHI1      = 0x11 | MMI_OPC_CLASS_MMI, /* Same minor as OPC_MTHI */
2213    MMI_OPC_MFLO1      = 0x12 | MMI_OPC_CLASS_MMI, /* Same minor as OPC_MFLO */
2214    MMI_OPC_MTLO1      = 0x13 | MMI_OPC_CLASS_MMI, /* Same minor as OPC_MTLO */
2215    MMI_OPC_MULT1      = 0x18 | MMI_OPC_CLASS_MMI, /* Same minor as OPC_MULT */
2216    MMI_OPC_MULTU1     = 0x19 | MMI_OPC_CLASS_MMI, /* Same min. as OPC_MULTU */
2217    MMI_OPC_DIV1       = 0x1A | MMI_OPC_CLASS_MMI, /* Same minor as OPC_DIV  */
2218    MMI_OPC_DIVU1      = 0x1B | MMI_OPC_CLASS_MMI, /* Same minor as OPC_DIVU */
2219    MMI_OPC_MADD1      = 0x20 | MMI_OPC_CLASS_MMI,
2220    MMI_OPC_MADDU1     = 0x21 | MMI_OPC_CLASS_MMI,
2221    MMI_OPC_CLASS_MMI1 = 0x28 | MMI_OPC_CLASS_MMI,
2222    MMI_OPC_CLASS_MMI3 = 0x29 | MMI_OPC_CLASS_MMI,
2223    MMI_OPC_PMFHL      = 0x30 | MMI_OPC_CLASS_MMI,
2224    MMI_OPC_PMTHL      = 0x31 | MMI_OPC_CLASS_MMI,
2225    MMI_OPC_PSLLH      = 0x34 | MMI_OPC_CLASS_MMI,
2226    MMI_OPC_PSRLH      = 0x36 | MMI_OPC_CLASS_MMI,
2227    MMI_OPC_PSRAH      = 0x37 | MMI_OPC_CLASS_MMI,
2228    MMI_OPC_PSLLW      = 0x3C | MMI_OPC_CLASS_MMI,
2229    MMI_OPC_PSRLW      = 0x3E | MMI_OPC_CLASS_MMI,
2230    MMI_OPC_PSRAW      = 0x3F | MMI_OPC_CLASS_MMI,
2231};
2232
2233/*
2234 * MMI instructions with opcode field = MMI and bits 5..0 = MMI0:
2235 *
2236 *  31    26                        10     6 5      0
2237 * +--------+----------------------+--------+--------+
2238 * |   MMI  |                      |function|  MMI0  |
2239 * +--------+----------------------+--------+--------+
2240 *
2241 * function  bits 7..6
2242 *     bits |   0   |   1   |   2   |   3
2243 *    10..8 |   00  |   01  |   10  |   11
2244 *   -------+-------+-------+-------+-------
2245 *    0 000 | PADDW | PSUBW | PCGTW | PMAXW
2246 *    1 001 | PADDH | PSUBH | PCGTH | PMAXH
2247 *    2 010 | PADDB | PSUBB | PCGTB |   *
2248 *    3 011 |   *   |   *   |   *   |   *
2249 *    4 100 | PADDSW| PSUBSW| PEXTLW| PPACW
2250 *    5 101 | PADDSH| PSUBSH| PEXTLH| PPACH
2251 *    6 110 | PADDSB| PSUBSB| PEXTLB| PPACB
2252 *    7 111 |   *   |   *   | PEXT5 | PPAC5
2253 */
2254
2255#define MASK_MMI0(op) (MASK_OP_MAJOR(op) | ((op) & 0x7FF))
2256enum {
2257    MMI_OPC_0_PADDW  = (0x00 << 6) | MMI_OPC_CLASS_MMI0,
2258    MMI_OPC_0_PSUBW  = (0x01 << 6) | MMI_OPC_CLASS_MMI0,
2259    MMI_OPC_0_PCGTW  = (0x02 << 6) | MMI_OPC_CLASS_MMI0,
2260    MMI_OPC_0_PMAXW  = (0x03 << 6) | MMI_OPC_CLASS_MMI0,
2261    MMI_OPC_0_PADDH  = (0x04 << 6) | MMI_OPC_CLASS_MMI0,
2262    MMI_OPC_0_PSUBH  = (0x05 << 6) | MMI_OPC_CLASS_MMI0,
2263    MMI_OPC_0_PCGTH  = (0x06 << 6) | MMI_OPC_CLASS_MMI0,
2264    MMI_OPC_0_PMAXH  = (0x07 << 6) | MMI_OPC_CLASS_MMI0,
2265    MMI_OPC_0_PADDB  = (0x08 << 6) | MMI_OPC_CLASS_MMI0,
2266    MMI_OPC_0_PSUBB  = (0x09 << 6) | MMI_OPC_CLASS_MMI0,
2267    MMI_OPC_0_PCGTB  = (0x0A << 6) | MMI_OPC_CLASS_MMI0,
2268    MMI_OPC_0_PADDSW = (0x10 << 6) | MMI_OPC_CLASS_MMI0,
2269    MMI_OPC_0_PSUBSW = (0x11 << 6) | MMI_OPC_CLASS_MMI0,
2270    MMI_OPC_0_PEXTLW = (0x12 << 6) | MMI_OPC_CLASS_MMI0,
2271    MMI_OPC_0_PPACW  = (0x13 << 6) | MMI_OPC_CLASS_MMI0,
2272    MMI_OPC_0_PADDSH = (0x14 << 6) | MMI_OPC_CLASS_MMI0,
2273    MMI_OPC_0_PSUBSH = (0x15 << 6) | MMI_OPC_CLASS_MMI0,
2274    MMI_OPC_0_PEXTLH = (0x16 << 6) | MMI_OPC_CLASS_MMI0,
2275    MMI_OPC_0_PPACH  = (0x17 << 6) | MMI_OPC_CLASS_MMI0,
2276    MMI_OPC_0_PADDSB = (0x18 << 6) | MMI_OPC_CLASS_MMI0,
2277    MMI_OPC_0_PSUBSB = (0x19 << 6) | MMI_OPC_CLASS_MMI0,
2278    MMI_OPC_0_PEXTLB = (0x1A << 6) | MMI_OPC_CLASS_MMI0,
2279    MMI_OPC_0_PPACB  = (0x1B << 6) | MMI_OPC_CLASS_MMI0,
2280    MMI_OPC_0_PEXT5  = (0x1E << 6) | MMI_OPC_CLASS_MMI0,
2281    MMI_OPC_0_PPAC5  = (0x1F << 6) | MMI_OPC_CLASS_MMI0,
2282};
2283
2284/*
2285 * MMI instructions with opcode field = MMI and bits 5..0 = MMI1:
2286 *
2287 *  31    26                        10     6 5      0
2288 * +--------+----------------------+--------+--------+
2289 * |   MMI  |                      |function|  MMI1  |
2290 * +--------+----------------------+--------+--------+
2291 *
2292 * function  bits 7..6
2293 *     bits |   0   |   1   |   2   |   3
2294 *    10..8 |   00  |   01  |   10  |   11
2295 *   -------+-------+-------+-------+-------
2296 *    0 000 |   *   | PABSW | PCEQW | PMINW
2297 *    1 001 | PADSBH| PABSH | PCEQH | PMINH
2298 *    2 010 |   *   |   *   | PCEQB |   *
2299 *    3 011 |   *   |   *   |   *   |   *
2300 *    4 100 | PADDUW| PSUBUW| PEXTUW|   *
2301 *    5 101 | PADDUH| PSUBUH| PEXTUH|   *
2302 *    6 110 | PADDUB| PSUBUB| PEXTUB| QFSRV
2303 *    7 111 |   *   |   *   |   *   |   *
2304 */
2305
2306#define MASK_MMI1(op) (MASK_OP_MAJOR(op) | ((op) & 0x7FF))
2307enum {
2308    MMI_OPC_1_PABSW  = (0x01 << 6) | MMI_OPC_CLASS_MMI1,
2309    MMI_OPC_1_PCEQW  = (0x02 << 6) | MMI_OPC_CLASS_MMI1,
2310    MMI_OPC_1_PMINW  = (0x03 << 6) | MMI_OPC_CLASS_MMI1,
2311    MMI_OPC_1_PADSBH = (0x04 << 6) | MMI_OPC_CLASS_MMI1,
2312    MMI_OPC_1_PABSH  = (0x05 << 6) | MMI_OPC_CLASS_MMI1,
2313    MMI_OPC_1_PCEQH  = (0x06 << 6) | MMI_OPC_CLASS_MMI1,
2314    MMI_OPC_1_PMINH  = (0x07 << 6) | MMI_OPC_CLASS_MMI1,
2315    MMI_OPC_1_PCEQB  = (0x0A << 6) | MMI_OPC_CLASS_MMI1,
2316    MMI_OPC_1_PADDUW = (0x10 << 6) | MMI_OPC_CLASS_MMI1,
2317    MMI_OPC_1_PSUBUW = (0x11 << 6) | MMI_OPC_CLASS_MMI1,
2318    MMI_OPC_1_PEXTUW = (0x12 << 6) | MMI_OPC_CLASS_MMI1,
2319    MMI_OPC_1_PADDUH = (0x14 << 6) | MMI_OPC_CLASS_MMI1,
2320    MMI_OPC_1_PSUBUH = (0x15 << 6) | MMI_OPC_CLASS_MMI1,
2321    MMI_OPC_1_PEXTUH = (0x16 << 6) | MMI_OPC_CLASS_MMI1,
2322    MMI_OPC_1_PADDUB = (0x18 << 6) | MMI_OPC_CLASS_MMI1,
2323    MMI_OPC_1_PSUBUB = (0x19 << 6) | MMI_OPC_CLASS_MMI1,
2324    MMI_OPC_1_PEXTUB = (0x1A << 6) | MMI_OPC_CLASS_MMI1,
2325    MMI_OPC_1_QFSRV  = (0x1B << 6) | MMI_OPC_CLASS_MMI1,
2326};
2327
2328/*
2329 * MMI instructions with opcode field = MMI and bits 5..0 = MMI2:
2330 *
2331 *  31    26                        10     6 5      0
2332 * +--------+----------------------+--------+--------+
2333 * |   MMI  |                      |function|  MMI2  |
2334 * +--------+----------------------+--------+--------+
2335 *
2336 * function  bits 7..6
2337 *     bits |   0   |   1   |   2   |   3
2338 *    10..8 |   00  |   01  |   10  |   11
2339 *   -------+-------+-------+-------+-------
2340 *    0 000 | PMADDW|   *   | PSLLVW| PSRLVW
2341 *    1 001 | PMSUBW|   *   |   *   |   *
2342 *    2 010 | PMFHI | PMFLO | PINTH |   *
2343 *    3 011 | PMULTW| PDIVW | PCPYLD|   *
2344 *    4 100 | PMADDH| PHMADH|  PAND |  PXOR
2345 *    5 101 | PMSUBH| PHMSBH|   *   |   *
2346 *    6 110 |   *   |   *   | PEXEH | PREVH
2347 *    7 111 | PMULTH| PDIVBW| PEXEW | PROT3W
2348 */
2349
2350#define MASK_MMI2(op) (MASK_OP_MAJOR(op) | ((op) & 0x7FF))
2351enum {
2352    MMI_OPC_2_PMADDW = (0x00 << 6) | MMI_OPC_CLASS_MMI2,
2353    MMI_OPC_2_PSLLVW = (0x02 << 6) | MMI_OPC_CLASS_MMI2,
2354    MMI_OPC_2_PSRLVW = (0x03 << 6) | MMI_OPC_CLASS_MMI2,
2355    MMI_OPC_2_PMSUBW = (0x04 << 6) | MMI_OPC_CLASS_MMI2,
2356    MMI_OPC_2_PMFHI  = (0x08 << 6) | MMI_OPC_CLASS_MMI2,
2357    MMI_OPC_2_PMFLO  = (0x09 << 6) | MMI_OPC_CLASS_MMI2,
2358    MMI_OPC_2_PINTH  = (0x0A << 6) | MMI_OPC_CLASS_MMI2,
2359    MMI_OPC_2_PMULTW = (0x0C << 6) | MMI_OPC_CLASS_MMI2,
2360    MMI_OPC_2_PDIVW  = (0x0D << 6) | MMI_OPC_CLASS_MMI2,
2361    MMI_OPC_2_PCPYLD = (0x0E << 6) | MMI_OPC_CLASS_MMI2,
2362    MMI_OPC_2_PMADDH = (0x10 << 6) | MMI_OPC_CLASS_MMI2,
2363    MMI_OPC_2_PHMADH = (0x11 << 6) | MMI_OPC_CLASS_MMI2,
2364    MMI_OPC_2_PAND   = (0x12 << 6) | MMI_OPC_CLASS_MMI2,
2365    MMI_OPC_2_PXOR   = (0x13 << 6) | MMI_OPC_CLASS_MMI2,
2366    MMI_OPC_2_PMSUBH = (0x14 << 6) | MMI_OPC_CLASS_MMI2,
2367    MMI_OPC_2_PHMSBH = (0x15 << 6) | MMI_OPC_CLASS_MMI2,
2368    MMI_OPC_2_PEXEH  = (0x1A << 6) | MMI_OPC_CLASS_MMI2,
2369    MMI_OPC_2_PREVH  = (0x1B << 6) | MMI_OPC_CLASS_MMI2,
2370    MMI_OPC_2_PMULTH = (0x1C << 6) | MMI_OPC_CLASS_MMI2,
2371    MMI_OPC_2_PDIVBW = (0x1D << 6) | MMI_OPC_CLASS_MMI2,
2372    MMI_OPC_2_PEXEW  = (0x1E << 6) | MMI_OPC_CLASS_MMI2,
2373    MMI_OPC_2_PROT3W = (0x1F << 6) | MMI_OPC_CLASS_MMI2,
2374};
2375
2376/*
2377 * MMI instructions with opcode field = MMI and bits 5..0 = MMI3:
2378 *
2379 *  31    26                        10     6 5      0
2380 * +--------+----------------------+--------+--------+
2381 * |   MMI  |                      |function|  MMI3  |
2382 * +--------+----------------------+--------+--------+
2383 *
2384 * function  bits 7..6
2385 *     bits |   0   |   1   |   2   |   3
2386 *    10..8 |   00  |   01  |   10  |   11
2387 *   -------+-------+-------+-------+-------
2388 *    0 000 |PMADDUW|   *   |   *   | PSRAVW
2389 *    1 001 |   *   |   *   |   *   |   *
2390 *    2 010 | PMTHI | PMTLO | PINTEH|   *
2391 *    3 011 |PMULTUW| PDIVUW| PCPYUD|   *
2392 *    4 100 |   *   |   *   |  POR  |  PNOR
2393 *    5 101 |   *   |   *   |   *   |   *
2394 *    6 110 |   *   |   *   | PEXCH | PCPYH
2395 *    7 111 |   *   |   *   | PEXCW |   *
2396 */
2397
2398#define MASK_MMI3(op) (MASK_OP_MAJOR(op) | ((op) & 0x7FF))
2399enum {
2400    MMI_OPC_3_PMADDUW = (0x00 << 6) | MMI_OPC_CLASS_MMI3,
2401    MMI_OPC_3_PSRAVW  = (0x03 << 6) | MMI_OPC_CLASS_MMI3,
2402    MMI_OPC_3_PMTHI   = (0x08 << 6) | MMI_OPC_CLASS_MMI3,
2403    MMI_OPC_3_PMTLO   = (0x09 << 6) | MMI_OPC_CLASS_MMI3,
2404    MMI_OPC_3_PINTEH  = (0x0A << 6) | MMI_OPC_CLASS_MMI3,
2405    MMI_OPC_3_PMULTUW = (0x0C << 6) | MMI_OPC_CLASS_MMI3,
2406    MMI_OPC_3_PDIVUW  = (0x0D << 6) | MMI_OPC_CLASS_MMI3,
2407    MMI_OPC_3_PCPYUD  = (0x0E << 6) | MMI_OPC_CLASS_MMI3,
2408    MMI_OPC_3_POR     = (0x12 << 6) | MMI_OPC_CLASS_MMI3,
2409    MMI_OPC_3_PNOR    = (0x13 << 6) | MMI_OPC_CLASS_MMI3,
2410    MMI_OPC_3_PEXCH   = (0x1A << 6) | MMI_OPC_CLASS_MMI3,
2411    MMI_OPC_3_PCPYH   = (0x1B << 6) | MMI_OPC_CLASS_MMI3,
2412    MMI_OPC_3_PEXCW   = (0x1E << 6) | MMI_OPC_CLASS_MMI3,
2413};
2414
2415/* global register indices */
2416static TCGv cpu_gpr[32], cpu_PC;
2417static TCGv cpu_HI[MIPS_DSP_ACC], cpu_LO[MIPS_DSP_ACC];
2418static TCGv cpu_dspctrl, btarget, bcond;
2419static TCGv_i32 hflags;
2420static TCGv_i32 fpu_fcr0, fpu_fcr31;
2421static TCGv_i64 fpu_f64[32];
2422static TCGv_i64 msa_wr_d[64];
2423
2424/* MXU registers */
2425static TCGv mxu_gpr[NUMBER_OF_MXU_REGISTERS - 1];
2426static TCGv mxu_CR;
2427
2428#include "exec/gen-icount.h"
2429
2430#define gen_helper_0e0i(name, arg) do {                           \
2431    TCGv_i32 helper_tmp = tcg_const_i32(arg);                     \
2432    gen_helper_##name(cpu_env, helper_tmp);                       \
2433    tcg_temp_free_i32(helper_tmp);                                \
2434    } while(0)
2435
2436#define gen_helper_0e1i(name, arg1, arg2) do {                    \
2437    TCGv_i32 helper_tmp = tcg_const_i32(arg2);                    \
2438    gen_helper_##name(cpu_env, arg1, helper_tmp);                 \
2439    tcg_temp_free_i32(helper_tmp);                                \
2440    } while(0)
2441
2442#define gen_helper_1e0i(name, ret, arg1) do {                     \
2443    TCGv_i32 helper_tmp = tcg_const_i32(arg1);                    \
2444    gen_helper_##name(ret, cpu_env, helper_tmp);                  \
2445    tcg_temp_free_i32(helper_tmp);                                \
2446    } while(0)
2447
2448#define gen_helper_1e1i(name, ret, arg1, arg2) do {               \
2449    TCGv_i32 helper_tmp = tcg_const_i32(arg2);                    \
2450    gen_helper_##name(ret, cpu_env, arg1, helper_tmp);            \
2451    tcg_temp_free_i32(helper_tmp);                                \
2452    } while(0)
2453
2454#define gen_helper_0e2i(name, arg1, arg2, arg3) do {              \
2455    TCGv_i32 helper_tmp = tcg_const_i32(arg3);                    \
2456    gen_helper_##name(cpu_env, arg1, arg2, helper_tmp);           \
2457    tcg_temp_free_i32(helper_tmp);                                \
2458    } while(0)
2459
2460#define gen_helper_1e2i(name, ret, arg1, arg2, arg3) do {         \
2461    TCGv_i32 helper_tmp = tcg_const_i32(arg3);                    \
2462    gen_helper_##name(ret, cpu_env, arg1, arg2, helper_tmp);      \
2463    tcg_temp_free_i32(helper_tmp);                                \
2464    } while(0)
2465
2466#define gen_helper_0e3i(name, arg1, arg2, arg3, arg4) do {        \
2467    TCGv_i32 helper_tmp = tcg_const_i32(arg4);                    \
2468    gen_helper_##name(cpu_env, arg1, arg2, arg3, helper_tmp);     \
2469    tcg_temp_free_i32(helper_tmp);                                \
2470    } while(0)
2471
2472typedef struct DisasContext {
2473    DisasContextBase base;
2474    target_ulong saved_pc;
2475    target_ulong page_start;
2476    uint32_t opcode;
2477    uint64_t insn_flags;
2478    int32_t CP0_Config1;
2479    int32_t CP0_Config2;
2480    int32_t CP0_Config3;
2481    int32_t CP0_Config5;
2482    /* Routine used to access memory */
2483    int mem_idx;
2484    TCGMemOp default_tcg_memop_mask;
2485    uint32_t hflags, saved_hflags;
2486    target_ulong btarget;
2487    bool ulri;
2488    int kscrexist;
2489    bool rxi;
2490    int ie;
2491    bool bi;
2492    bool bp;
2493    uint64_t PAMask;
2494    bool mvh;
2495    bool eva;
2496    bool sc;
2497    int CP0_LLAddr_shift;
2498    bool ps;
2499    bool vp;
2500    bool cmgcr;
2501    bool mrp;
2502    bool nan2008;
2503    bool abs2008;
2504} DisasContext;
2505
2506#define DISAS_STOP       DISAS_TARGET_0
2507#define DISAS_EXIT       DISAS_TARGET_1
2508
2509static const char * const regnames[] = {
2510    "r0", "at", "v0", "v1", "a0", "a1", "a2", "a3",
2511    "t0", "t1", "t2", "t3", "t4", "t5", "t6", "t7",
2512    "s0", "s1", "s2", "s3", "s4", "s5", "s6", "s7",
2513    "t8", "t9", "k0", "k1", "gp", "sp", "s8", "ra",
2514};
2515
2516static const char * const regnames_HI[] = {
2517    "HI0", "HI1", "HI2", "HI3",
2518};
2519
2520static const char * const regnames_LO[] = {
2521    "LO0", "LO1", "LO2", "LO3",
2522};
2523
2524static const char * const fregnames[] = {
2525    "f0",  "f1",  "f2",  "f3",  "f4",  "f5",  "f6",  "f7",
2526    "f8",  "f9",  "f10", "f11", "f12", "f13", "f14", "f15",
2527    "f16", "f17", "f18", "f19", "f20", "f21", "f22", "f23",
2528    "f24", "f25", "f26", "f27", "f28", "f29", "f30", "f31",
2529};
2530
2531static const char * const msaregnames[] = {
2532    "w0.d0",  "w0.d1",  "w1.d0",  "w1.d1",
2533    "w2.d0",  "w2.d1",  "w3.d0",  "w3.d1",
2534    "w4.d0",  "w4.d1",  "w5.d0",  "w5.d1",
2535    "w6.d0",  "w6.d1",  "w7.d0",  "w7.d1",
2536    "w8.d0",  "w8.d1",  "w9.d0",  "w9.d1",
2537    "w10.d0", "w10.d1", "w11.d0", "w11.d1",
2538    "w12.d0", "w12.d1", "w13.d0", "w13.d1",
2539    "w14.d0", "w14.d1", "w15.d0", "w15.d1",
2540    "w16.d0", "w16.d1", "w17.d0", "w17.d1",
2541    "w18.d0", "w18.d1", "w19.d0", "w19.d1",
2542    "w20.d0", "w20.d1", "w21.d0", "w21.d1",
2543    "w22.d0", "w22.d1", "w23.d0", "w23.d1",
2544    "w24.d0", "w24.d1", "w25.d0", "w25.d1",
2545    "w26.d0", "w26.d1", "w27.d0", "w27.d1",
2546    "w28.d0", "w28.d1", "w29.d0", "w29.d1",
2547    "w30.d0", "w30.d1", "w31.d0", "w31.d1",
2548};
2549
2550static const char * const mxuregnames[] = {
2551    "XR1",  "XR2",  "XR3",  "XR4",  "XR5",  "XR6",  "XR7",  "XR8",
2552    "XR9",  "XR10", "XR11", "XR12", "XR13", "XR14", "XR15", "MXU_CR",
2553};
2554
2555#define LOG_DISAS(...)                                                        \
2556    do {                                                                      \
2557        if (MIPS_DEBUG_DISAS) {                                               \
2558            qemu_log_mask(CPU_LOG_TB_IN_ASM, ## __VA_ARGS__);                 \
2559        }                                                                     \
2560    } while (0)
2561
2562#define MIPS_INVAL(op)                                                        \
2563    do {                                                                      \
2564        if (MIPS_DEBUG_DISAS) {                                               \
2565            qemu_log_mask(CPU_LOG_TB_IN_ASM,                                  \
2566                          TARGET_FMT_lx ": %08x Invalid %s %03x %03x %03x\n", \
2567                          ctx->base.pc_next, ctx->opcode, op,                 \
2568                          ctx->opcode >> 26, ctx->opcode & 0x3F,              \
2569                          ((ctx->opcode >> 16) & 0x1F));                      \
2570        }                                                                     \
2571    } while (0)
2572
2573/* General purpose registers moves. */
2574static inline void gen_load_gpr (TCGv t, int reg)
2575{
2576    if (reg == 0)
2577        tcg_gen_movi_tl(t, 0);
2578    else
2579        tcg_gen_mov_tl(t, cpu_gpr[reg]);
2580}
2581
2582static inline void gen_store_gpr (TCGv t, int reg)
2583{
2584    if (reg != 0)
2585        tcg_gen_mov_tl(cpu_gpr[reg], t);
2586}
2587
2588/* Moves to/from shadow registers. */
2589static inline void gen_load_srsgpr (int from, int to)
2590{
2591    TCGv t0 = tcg_temp_new();
2592
2593    if (from == 0)
2594        tcg_gen_movi_tl(t0, 0);
2595    else {
2596        TCGv_i32 t2 = tcg_temp_new_i32();
2597        TCGv_ptr addr = tcg_temp_new_ptr();
2598
2599        tcg_gen_ld_i32(t2, cpu_env, offsetof(CPUMIPSState, CP0_SRSCtl));
2600        tcg_gen_shri_i32(t2, t2, CP0SRSCtl_PSS);
2601        tcg_gen_andi_i32(t2, t2, 0xf);
2602        tcg_gen_muli_i32(t2, t2, sizeof(target_ulong) * 32);
2603        tcg_gen_ext_i32_ptr(addr, t2);
2604        tcg_gen_add_ptr(addr, cpu_env, addr);
2605
2606        tcg_gen_ld_tl(t0, addr, sizeof(target_ulong) * from);
2607        tcg_temp_free_ptr(addr);
2608        tcg_temp_free_i32(t2);
2609    }
2610    gen_store_gpr(t0, to);
2611    tcg_temp_free(t0);
2612}
2613
2614static inline void gen_store_srsgpr (int from, int to)
2615{
2616    if (to != 0) {
2617        TCGv t0 = tcg_temp_new();
2618        TCGv_i32 t2 = tcg_temp_new_i32();
2619        TCGv_ptr addr = tcg_temp_new_ptr();
2620
2621        gen_load_gpr(t0, from);
2622        tcg_gen_ld_i32(t2, cpu_env, offsetof(CPUMIPSState, CP0_SRSCtl));
2623        tcg_gen_shri_i32(t2, t2, CP0SRSCtl_PSS);
2624        tcg_gen_andi_i32(t2, t2, 0xf);
2625        tcg_gen_muli_i32(t2, t2, sizeof(target_ulong) * 32);
2626        tcg_gen_ext_i32_ptr(addr, t2);
2627        tcg_gen_add_ptr(addr, cpu_env, addr);
2628
2629        tcg_gen_st_tl(t0, addr, sizeof(target_ulong) * to);
2630        tcg_temp_free_ptr(addr);
2631        tcg_temp_free_i32(t2);
2632        tcg_temp_free(t0);
2633    }
2634}
2635
2636/* MXU General purpose registers moves. */
2637static inline void gen_load_mxu_gpr(TCGv t, unsigned int reg)
2638{
2639    if (reg == 0) {
2640        tcg_gen_movi_tl(t, 0);
2641    } else if (reg <= 15) {
2642        tcg_gen_mov_tl(t, mxu_gpr[reg - 1]);
2643    }
2644}
2645
2646static inline void gen_store_mxu_gpr(TCGv t, unsigned int reg)
2647{
2648    if (reg > 0 && reg <= 15) {
2649        tcg_gen_mov_tl(mxu_gpr[reg - 1], t);
2650    }
2651}
2652
2653/* MXU control register moves. */
2654static inline void gen_load_mxu_cr(TCGv t)
2655{
2656    tcg_gen_mov_tl(t, mxu_CR);
2657}
2658
2659static inline void gen_store_mxu_cr(TCGv t)
2660{
2661    /* TODO: Add handling of RW rules for MXU_CR. */
2662    tcg_gen_mov_tl(mxu_CR, t);
2663}
2664
2665
2666/* Tests */
2667static inline void gen_save_pc(target_ulong pc)
2668{
2669    tcg_gen_movi_tl(cpu_PC, pc);
2670}
2671
2672static inline void save_cpu_state(DisasContext *ctx, int do_save_pc)
2673{
2674    LOG_DISAS("hflags %08x saved %08x\n", ctx->hflags, ctx->saved_hflags);
2675    if (do_save_pc && ctx->base.pc_next != ctx->saved_pc) {
2676        gen_save_pc(ctx->base.pc_next);
2677        ctx->saved_pc = ctx->base.pc_next;
2678    }
2679    if (ctx->hflags != ctx->saved_hflags) {
2680        tcg_gen_movi_i32(hflags, ctx->hflags);
2681        ctx->saved_hflags = ctx->hflags;
2682        switch (ctx->hflags & MIPS_HFLAG_BMASK_BASE) {
2683        case MIPS_HFLAG_BR:
2684            break;
2685        case MIPS_HFLAG_BC:
2686        case MIPS_HFLAG_BL:
2687        case MIPS_HFLAG_B:
2688            tcg_gen_movi_tl(btarget, ctx->btarget);
2689            break;
2690        }
2691    }
2692}
2693
2694static inline void restore_cpu_state(CPUMIPSState *env, DisasContext *ctx)
2695{
2696    ctx->saved_hflags = ctx->hflags;
2697    switch (ctx->hflags & MIPS_HFLAG_BMASK_BASE) {
2698    case MIPS_HFLAG_BR:
2699        break;
2700    case MIPS_HFLAG_BC:
2701    case MIPS_HFLAG_BL:
2702    case MIPS_HFLAG_B:
2703        ctx->btarget = env->btarget;
2704        break;
2705    }
2706}
2707
2708static inline void generate_exception_err(DisasContext *ctx, int excp, int err)
2709{
2710    TCGv_i32 texcp = tcg_const_i32(excp);
2711    TCGv_i32 terr = tcg_const_i32(err);
2712    save_cpu_state(ctx, 1);
2713    gen_helper_raise_exception_err(cpu_env, texcp, terr);
2714    tcg_temp_free_i32(terr);
2715    tcg_temp_free_i32(texcp);
2716    ctx->base.is_jmp = DISAS_NORETURN;
2717}
2718
2719static inline void generate_exception(DisasContext *ctx, int excp)
2720{
2721    gen_helper_0e0i(raise_exception, excp);
2722}
2723
2724static inline void generate_exception_end(DisasContext *ctx, int excp)
2725{
2726    generate_exception_err(ctx, excp, 0);
2727}
2728
2729/* Floating point register moves. */
2730static void gen_load_fpr32(DisasContext *ctx, TCGv_i32 t, int reg)
2731{
2732    if (ctx->hflags & MIPS_HFLAG_FRE) {
2733        generate_exception(ctx, EXCP_RI);
2734    }
2735    tcg_gen_extrl_i64_i32(t, fpu_f64[reg]);
2736}
2737
2738static void gen_store_fpr32(DisasContext *ctx, TCGv_i32 t, int reg)
2739{
2740    TCGv_i64 t64;
2741    if (ctx->hflags & MIPS_HFLAG_FRE) {
2742        generate_exception(ctx, EXCP_RI);
2743    }
2744    t64 = tcg_temp_new_i64();
2745    tcg_gen_extu_i32_i64(t64, t);
2746    tcg_gen_deposit_i64(fpu_f64[reg], fpu_f64[reg], t64, 0, 32);
2747    tcg_temp_free_i64(t64);
2748}
2749
2750static void gen_load_fpr32h(DisasContext *ctx, TCGv_i32 t, int reg)
2751{
2752    if (ctx->hflags & MIPS_HFLAG_F64) {
2753        tcg_gen_extrh_i64_i32(t, fpu_f64[reg]);
2754    } else {
2755        gen_load_fpr32(ctx, t, reg | 1);
2756    }
2757}
2758
2759static void gen_store_fpr32h(DisasContext *ctx, TCGv_i32 t, int reg)
2760{
2761    if (ctx->hflags & MIPS_HFLAG_F64) {
2762        TCGv_i64 t64 = tcg_temp_new_i64();
2763        tcg_gen_extu_i32_i64(t64, t);
2764        tcg_gen_deposit_i64(fpu_f64[reg], fpu_f64[reg], t64, 32, 32);
2765        tcg_temp_free_i64(t64);
2766    } else {
2767        gen_store_fpr32(ctx, t, reg | 1);
2768    }
2769}
2770
2771static void gen_load_fpr64(DisasContext *ctx, TCGv_i64 t, int reg)
2772{
2773    if (ctx->hflags & MIPS_HFLAG_F64) {
2774        tcg_gen_mov_i64(t, fpu_f64[reg]);
2775    } else {
2776        tcg_gen_concat32_i64(t, fpu_f64[reg & ~1], fpu_f64[reg | 1]);
2777    }
2778}
2779
2780static void gen_store_fpr64(DisasContext *ctx, TCGv_i64 t, int reg)
2781{
2782    if (ctx->hflags & MIPS_HFLAG_F64) {
2783        tcg_gen_mov_i64(fpu_f64[reg], t);
2784    } else {
2785        TCGv_i64 t0;
2786        tcg_gen_deposit_i64(fpu_f64[reg & ~1], fpu_f64[reg & ~1], t, 0, 32);
2787        t0 = tcg_temp_new_i64();
2788        tcg_gen_shri_i64(t0, t, 32);
2789        tcg_gen_deposit_i64(fpu_f64[reg | 1], fpu_f64[reg | 1], t0, 0, 32);
2790        tcg_temp_free_i64(t0);
2791    }
2792}
2793
2794static inline int get_fp_bit (int cc)
2795{
2796    if (cc)
2797        return 24 + cc;
2798    else
2799        return 23;
2800}
2801
2802/* Addresses computation */
2803static inline void gen_op_addr_add (DisasContext *ctx, TCGv ret, TCGv arg0, TCGv arg1)
2804{
2805    tcg_gen_add_tl(ret, arg0, arg1);
2806
2807#if defined(TARGET_MIPS64)
2808    if (ctx->hflags & MIPS_HFLAG_AWRAP) {
2809        tcg_gen_ext32s_i64(ret, ret);
2810    }
2811#endif
2812}
2813
2814static inline void gen_op_addr_addi(DisasContext *ctx, TCGv ret, TCGv base,
2815                                    target_long ofs)
2816{
2817    tcg_gen_addi_tl(ret, base, ofs);
2818
2819#if defined(TARGET_MIPS64)
2820    if (ctx->hflags & MIPS_HFLAG_AWRAP) {
2821        tcg_gen_ext32s_i64(ret, ret);
2822    }
2823#endif
2824}
2825
2826/* Addresses computation (translation time) */
2827static target_long addr_add(DisasContext *ctx, target_long base,
2828                            target_long offset)
2829{
2830    target_long sum = base + offset;
2831
2832#if defined(TARGET_MIPS64)
2833    if (ctx->hflags & MIPS_HFLAG_AWRAP) {
2834        sum = (int32_t)sum;
2835    }
2836#endif
2837    return sum;
2838}
2839
2840/* Sign-extract the low 32-bits to a target_long.  */
2841static inline void gen_move_low32(TCGv ret, TCGv_i64 arg)
2842{
2843#if defined(TARGET_MIPS64)
2844    tcg_gen_ext32s_i64(ret, arg);
2845#else
2846    tcg_gen_extrl_i64_i32(ret, arg);
2847#endif
2848}
2849
2850/* Sign-extract the high 32-bits to a target_long.  */
2851static inline void gen_move_high32(TCGv ret, TCGv_i64 arg)
2852{
2853#if defined(TARGET_MIPS64)
2854    tcg_gen_sari_i64(ret, arg, 32);
2855#else
2856    tcg_gen_extrh_i64_i32(ret, arg);
2857#endif
2858}
2859
2860static inline void check_cp0_enabled(DisasContext *ctx)
2861{
2862    if (unlikely(!(ctx->hflags & MIPS_HFLAG_CP0)))
2863        generate_exception_err(ctx, EXCP_CpU, 0);
2864}
2865
2866static inline void check_cp1_enabled(DisasContext *ctx)
2867{
2868    if (unlikely(!(ctx->hflags & MIPS_HFLAG_FPU)))
2869        generate_exception_err(ctx, EXCP_CpU, 1);
2870}
2871
2872/* Verify that the processor is running with COP1X instructions enabled.
2873   This is associated with the nabla symbol in the MIPS32 and MIPS64
2874   opcode tables.  */
2875
2876static inline void check_cop1x(DisasContext *ctx)
2877{
2878    if (unlikely(!(ctx->hflags & MIPS_HFLAG_COP1X)))
2879        generate_exception_end(ctx, EXCP_RI);
2880}
2881
2882/* Verify that the processor is running with 64-bit floating-point
2883   operations enabled.  */
2884
2885static inline void check_cp1_64bitmode(DisasContext *ctx)
2886{
2887    if (unlikely(~ctx->hflags & (MIPS_HFLAG_F64 | MIPS_HFLAG_COP1X)))
2888        generate_exception_end(ctx, EXCP_RI);
2889}
2890
2891/*
2892 * Verify if floating point register is valid; an operation is not defined
2893 * if bit 0 of any register specification is set and the FR bit in the
2894 * Status register equals zero, since the register numbers specify an
2895 * even-odd pair of adjacent coprocessor general registers. When the FR bit
2896 * in the Status register equals one, both even and odd register numbers
2897 * are valid. This limitation exists only for 64 bit wide (d,l,ps) registers.
2898 *
2899 * Multiple 64 bit wide registers can be checked by calling
2900 * gen_op_cp1_registers(freg1 | freg2 | ... | fregN);
2901 */
2902static inline void check_cp1_registers(DisasContext *ctx, int regs)
2903{
2904    if (unlikely(!(ctx->hflags & MIPS_HFLAG_F64) && (regs & 1)))
2905        generate_exception_end(ctx, EXCP_RI);
2906}
2907
2908/* Verify that the processor is running with DSP instructions enabled.
2909   This is enabled by CP0 Status register MX(24) bit.
2910 */
2911
2912static inline void check_dsp(DisasContext *ctx)
2913{
2914    if (unlikely(!(ctx->hflags & MIPS_HFLAG_DSP))) {
2915        if (ctx->insn_flags & ASE_DSP) {
2916            generate_exception_end(ctx, EXCP_DSPDIS);
2917        } else {
2918            generate_exception_end(ctx, EXCP_RI);
2919        }
2920    }
2921}
2922
2923static inline void check_dsp_r2(DisasContext *ctx)
2924{
2925    if (unlikely(!(ctx->hflags & MIPS_HFLAG_DSP_R2))) {
2926        if (ctx->insn_flags & ASE_DSP) {
2927            generate_exception_end(ctx, EXCP_DSPDIS);
2928        } else {
2929            generate_exception_end(ctx, EXCP_RI);
2930        }
2931    }
2932}
2933
2934static inline void check_dsp_r3(DisasContext *ctx)
2935{
2936    if (unlikely(!(ctx->hflags & MIPS_HFLAG_DSP_R3))) {
2937        if (ctx->insn_flags & ASE_DSP) {
2938            generate_exception_end(ctx, EXCP_DSPDIS);
2939        } else {
2940            generate_exception_end(ctx, EXCP_RI);
2941        }
2942    }
2943}
2944
2945/* This code generates a "reserved instruction" exception if the
2946   CPU does not support the instruction set corresponding to flags. */
2947static inline void check_insn(DisasContext *ctx, uint64_t flags)
2948{
2949    if (unlikely(!(ctx->insn_flags & flags))) {
2950        generate_exception_end(ctx, EXCP_RI);
2951    }
2952}
2953
2954/* This code generates a "reserved instruction" exception if the
2955   CPU has corresponding flag set which indicates that the instruction
2956   has been removed. */
2957static inline void check_insn_opc_removed(DisasContext *ctx, uint64_t flags)
2958{
2959    if (unlikely(ctx->insn_flags & flags)) {
2960        generate_exception_end(ctx, EXCP_RI);
2961    }
2962}
2963
2964/*
2965 * The Linux kernel traps certain reserved instruction exceptions to
2966 * emulate the corresponding instructions. QEMU is the kernel in user
2967 * mode, so those traps are emulated by accepting the instructions.
2968 *
2969 * A reserved instruction exception is generated for flagged CPUs if
2970 * QEMU runs in system mode.
2971 */
2972static inline void check_insn_opc_user_only(DisasContext *ctx, uint64_t flags)
2973{
2974#ifndef CONFIG_USER_ONLY
2975    check_insn_opc_removed(ctx, flags);
2976#endif
2977}
2978
2979/* This code generates a "reserved instruction" exception if the
2980   CPU does not support 64-bit paired-single (PS) floating point data type */
2981static inline void check_ps(DisasContext *ctx)
2982{
2983    if (unlikely(!ctx->ps)) {
2984        generate_exception(ctx, EXCP_RI);
2985    }
2986    check_cp1_64bitmode(ctx);
2987}
2988
2989#ifdef TARGET_MIPS64
2990/* This code generates a "reserved instruction" exception if 64-bit
2991   instructions are not enabled. */
2992static inline void check_mips_64(DisasContext *ctx)
2993{
2994    if (unlikely(!(ctx->hflags & MIPS_HFLAG_64)))
2995        generate_exception_end(ctx, EXCP_RI);
2996}
2997#endif
2998
2999#ifndef CONFIG_USER_ONLY
3000static inline void check_mvh(DisasContext *ctx)
3001{
3002    if (unlikely(!ctx->mvh)) {
3003        generate_exception(ctx, EXCP_RI);
3004    }
3005}
3006#endif
3007
3008/*
3009 * This code generates a "reserved instruction" exception if the
3010 * Config5 XNP bit is set.
3011 */
3012static inline void check_xnp(DisasContext *ctx)
3013{
3014    if (unlikely(ctx->CP0_Config5 & (1 << CP0C5_XNP))) {
3015        generate_exception_end(ctx, EXCP_RI);
3016    }
3017}
3018
3019#ifndef CONFIG_USER_ONLY
3020/*
3021 * This code generates a "reserved instruction" exception if the
3022 * Config3 PW bit is NOT set.
3023 */
3024static inline void check_pw(DisasContext *ctx)
3025{
3026    if (unlikely(!(ctx->CP0_Config3 & (1 << CP0C3_PW)))) {
3027        generate_exception_end(ctx, EXCP_RI);
3028    }
3029}
3030#endif
3031
3032/*
3033 * This code generates a "reserved instruction" exception if the
3034 * Config3 MT bit is NOT set.
3035 */
3036static inline void check_mt(DisasContext *ctx)
3037{
3038    if (unlikely(!(ctx->CP0_Config3 & (1 << CP0C3_MT)))) {
3039        generate_exception_end(ctx, EXCP_RI);
3040    }
3041}
3042
3043#ifndef CONFIG_USER_ONLY
3044/*
3045 * This code generates a "coprocessor unusable" exception if CP0 is not
3046 * available, and, if that is not the case, generates a "reserved instruction"
3047 * exception if the Config5 MT bit is NOT set. This is needed for availability
3048 * control of some of MT ASE instructions.
3049 */
3050static inline void check_cp0_mt(DisasContext *ctx)
3051{
3052    if (unlikely(!(ctx->hflags & MIPS_HFLAG_CP0))) {
3053        generate_exception_err(ctx, EXCP_CpU, 0);
3054    } else {
3055        if (unlikely(!(ctx->CP0_Config3 & (1 << CP0C3_MT)))) {
3056            generate_exception_err(ctx, EXCP_RI, 0);
3057        }
3058    }
3059}
3060#endif
3061
3062/*
3063 * This code generates a "reserved instruction" exception if the
3064 * Config5 NMS bit is set.
3065 */
3066static inline void check_nms(DisasContext *ctx)
3067{
3068    if (unlikely(ctx->CP0_Config5 & (1 << CP0C5_NMS))) {
3069        generate_exception_end(ctx, EXCP_RI);
3070    }
3071}
3072
3073/*
3074 * This code generates a "reserved instruction" exception if the
3075 * Config5 NMS bit is set, and Config1 DL, Config1 IL, Config2 SL,
3076 * Config2 TL, and Config5 L2C are unset.
3077 */
3078static inline void check_nms_dl_il_sl_tl_l2c(DisasContext *ctx)
3079{
3080    if (unlikely(ctx->CP0_Config5 & (1 << CP0C5_NMS)) &&
3081        !(ctx->CP0_Config1 & (1 << CP0C1_DL)) &&
3082        !(ctx->CP0_Config1 & (1 << CP0C1_IL)) &&
3083        !(ctx->CP0_Config2 & (1 << CP0C2_SL)) &&
3084        !(ctx->CP0_Config2 & (1 << CP0C2_TL)) &&
3085        !(ctx->CP0_Config5 & (1 << CP0C5_L2C)))
3086    {
3087        generate_exception_end(ctx, EXCP_RI);
3088    }
3089}
3090
3091/*
3092 * This code generates a "reserved instruction" exception if the
3093 * Config5 EVA bit is NOT set.
3094 */
3095static inline void check_eva(DisasContext *ctx)
3096{
3097    if (unlikely(!(ctx->CP0_Config5 & (1 << CP0C5_EVA)))) {
3098        generate_exception_end(ctx, EXCP_RI);
3099    }
3100}
3101
3102
3103/* Define small wrappers for gen_load_fpr* so that we have a uniform
3104   calling interface for 32 and 64-bit FPRs.  No sense in changing
3105   all callers for gen_load_fpr32 when we need the CTX parameter for
3106   this one use.  */
3107#define gen_ldcmp_fpr32(ctx, x, y) gen_load_fpr32(ctx, x, y)
3108#define gen_ldcmp_fpr64(ctx, x, y) gen_load_fpr64(ctx, x, y)
3109#define FOP_CONDS(type, abs, fmt, ifmt, bits)                                 \
3110static inline void gen_cmp ## type ## _ ## fmt(DisasContext *ctx, int n,      \
3111                                               int ft, int fs, int cc)        \
3112{                                                                             \
3113    TCGv_i##bits fp0 = tcg_temp_new_i##bits ();                               \
3114    TCGv_i##bits fp1 = tcg_temp_new_i##bits ();                               \
3115    switch (ifmt) {                                                           \
3116    case FMT_PS:                                                              \
3117        check_ps(ctx);                                                        \
3118        break;                                                                \
3119    case FMT_D:                                                               \
3120        if (abs) {                                                            \
3121            check_cop1x(ctx);                                                 \
3122        }                                                                     \
3123        check_cp1_registers(ctx, fs | ft);                                    \
3124        break;                                                                \
3125    case FMT_S:                                                               \
3126        if (abs) {                                                            \
3127            check_cop1x(ctx);                                                 \
3128        }                                                                     \
3129        break;                                                                \
3130    }                                                                         \
3131    gen_ldcmp_fpr##bits (ctx, fp0, fs);                                       \
3132    gen_ldcmp_fpr##bits (ctx, fp1, ft);                                       \
3133    switch (n) {                                                              \
3134    case  0: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _f, fp0, fp1, cc);    break;\
3135    case  1: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _un, fp0, fp1, cc);   break;\
3136    case  2: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _eq, fp0, fp1, cc);   break;\
3137    case  3: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ueq, fp0, fp1, cc);  break;\
3138    case  4: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _olt, fp0, fp1, cc);  break;\
3139    case  5: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ult, fp0, fp1, cc);  break;\
3140    case  6: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ole, fp0, fp1, cc);  break;\
3141    case  7: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ule, fp0, fp1, cc);  break;\
3142    case  8: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _sf, fp0, fp1, cc);   break;\
3143    case  9: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ngle, fp0, fp1, cc); break;\
3144    case 10: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _seq, fp0, fp1, cc);  break;\
3145    case 11: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ngl, fp0, fp1, cc);  break;\
3146    case 12: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _lt, fp0, fp1, cc);   break;\
3147    case 13: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _nge, fp0, fp1, cc);  break;\
3148    case 14: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _le, fp0, fp1, cc);   break;\
3149    case 15: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ngt, fp0, fp1, cc);  break;\
3150    default: abort();                                                         \
3151    }                                                                         \
3152    tcg_temp_free_i##bits (fp0);                                              \
3153    tcg_temp_free_i##bits (fp1);                                              \
3154}
3155
3156FOP_CONDS(, 0, d, FMT_D, 64)
3157FOP_CONDS(abs, 1, d, FMT_D, 64)
3158FOP_CONDS(, 0, s, FMT_S, 32)
3159FOP_CONDS(abs, 1, s, FMT_S, 32)
3160FOP_CONDS(, 0, ps, FMT_PS, 64)
3161FOP_CONDS(abs, 1, ps, FMT_PS, 64)
3162#undef FOP_CONDS
3163
3164#define FOP_CONDNS(fmt, ifmt, bits, STORE)                              \
3165static inline void gen_r6_cmp_ ## fmt(DisasContext * ctx, int n,        \
3166                                      int ft, int fs, int fd)           \
3167{                                                                       \
3168    TCGv_i ## bits fp0 = tcg_temp_new_i ## bits();                      \
3169    TCGv_i ## bits fp1 = tcg_temp_new_i ## bits();                      \
3170    if (ifmt == FMT_D) {                                                \
3171        check_cp1_registers(ctx, fs | ft | fd);                         \
3172    }                                                                   \
3173    gen_ldcmp_fpr ## bits(ctx, fp0, fs);                                \
3174    gen_ldcmp_fpr ## bits(ctx, fp1, ft);                                \
3175    switch (n) {                                                        \
3176    case  0:                                                            \
3177        gen_helper_r6_cmp_ ## fmt ## _af(fp0, cpu_env, fp0, fp1);       \
3178        break;                                                          \
3179    case  1:                                                            \
3180        gen_helper_r6_cmp_ ## fmt ## _un(fp0, cpu_env, fp0, fp1);       \
3181        break;                                                          \
3182    case  2:                                                            \
3183        gen_helper_r6_cmp_ ## fmt ## _eq(fp0, cpu_env, fp0, fp1);       \
3184        break;                                                          \
3185    case  3:                                                            \
3186        gen_helper_r6_cmp_ ## fmt ## _ueq(fp0, cpu_env, fp0, fp1);      \
3187        break;                                                          \
3188    case  4:                                                            \
3189        gen_helper_r6_cmp_ ## fmt ## _lt(fp0, cpu_env, fp0, fp1);       \
3190        break;                                                          \
3191    case  5:                                                            \
3192        gen_helper_r6_cmp_ ## fmt ## _ult(fp0, cpu_env, fp0, fp1);      \
3193        break;                                                          \
3194    case  6:                                                            \
3195        gen_helper_r6_cmp_ ## fmt ## _le(fp0, cpu_env, fp0, fp1);       \
3196        break;                                                          \
3197    case  7:                                                            \
3198        gen_helper_r6_cmp_ ## fmt ## _ule(fp0, cpu_env, fp0, fp1);      \
3199        break;                                                          \
3200    case  8:                                                            \
3201        gen_helper_r6_cmp_ ## fmt ## _saf(fp0, cpu_env, fp0, fp1);      \
3202        break;                                                          \
3203    case  9:                                                            \
3204        gen_helper_r6_cmp_ ## fmt ## _sun(fp0, cpu_env, fp0, fp1);      \
3205        break;                                                          \
3206    case 10:                                                            \
3207        gen_helper_r6_cmp_ ## fmt ## _seq(fp0, cpu_env, fp0, fp1);      \
3208        break;                                                          \
3209    case 11:                                                            \
3210        gen_helper_r6_cmp_ ## fmt ## _sueq(fp0, cpu_env, fp0, fp1);     \
3211        break;                                                          \
3212    case 12:                                                            \
3213        gen_helper_r6_cmp_ ## fmt ## _slt(fp0, cpu_env, fp0, fp1);      \
3214        break;                                                          \
3215    case 13:                                                            \
3216        gen_helper_r6_cmp_ ## fmt ## _sult(fp0, cpu_env, fp0, fp1);     \
3217        break;                                                          \
3218    case 14:                                                            \
3219        gen_helper_r6_cmp_ ## fmt ## _sle(fp0, cpu_env, fp0, fp1);      \
3220        break;                                                          \
3221    case 15:                                                            \
3222        gen_helper_r6_cmp_ ## fmt ## _sule(fp0, cpu_env, fp0, fp1);     \
3223        break;                                                          \
3224    case 17:                                                            \
3225        gen_helper_r6_cmp_ ## fmt ## _or(fp0, cpu_env, fp0, fp1);       \
3226        break;                                                          \
3227    case 18:                                                            \
3228        gen_helper_r6_cmp_ ## fmt ## _une(fp0, cpu_env, fp0, fp1);      \
3229        break;                                                          \
3230    case 19:                                                            \
3231        gen_helper_r6_cmp_ ## fmt ## _ne(fp0, cpu_env, fp0, fp1);       \
3232        break;                                                          \
3233    case 25:                                                            \
3234        gen_helper_r6_cmp_ ## fmt ## _sor(fp0, cpu_env, fp0, fp1);      \
3235        break;                                                          \
3236    case 26:                                                            \
3237        gen_helper_r6_cmp_ ## fmt ## _sune(fp0, cpu_env, fp0, fp1);     \
3238        break;                                                          \
3239    case 27:                                                            \
3240        gen_helper_r6_cmp_ ## fmt ## _sne(fp0, cpu_env, fp0, fp1);      \
3241        break;                                                          \
3242    default:                                                            \
3243        abort();                                                        \
3244    }                                                                   \
3245    STORE;                                                              \
3246    tcg_temp_free_i ## bits (fp0);                                      \
3247    tcg_temp_free_i ## bits (fp1);                                      \
3248}
3249
3250FOP_CONDNS(d, FMT_D, 64, gen_store_fpr64(ctx, fp0, fd))
3251FOP_CONDNS(s, FMT_S, 32, gen_store_fpr32(ctx, fp0, fd))
3252#undef FOP_CONDNS
3253#undef gen_ldcmp_fpr32
3254#undef gen_ldcmp_fpr64
3255
3256/* load/store instructions. */
3257#ifdef CONFIG_USER_ONLY
3258#define OP_LD_ATOMIC(insn,fname)                                           \
3259static inline void op_ld_##insn(TCGv ret, TCGv arg1, int mem_idx,          \
3260                                DisasContext *ctx)                         \
3261{                                                                          \
3262    TCGv t0 = tcg_temp_new();                                              \
3263    tcg_gen_mov_tl(t0, arg1);                                              \
3264    tcg_gen_qemu_##fname(ret, arg1, ctx->mem_idx);                         \
3265    tcg_gen_st_tl(t0, cpu_env, offsetof(CPUMIPSState, lladdr));                \
3266    tcg_gen_st_tl(ret, cpu_env, offsetof(CPUMIPSState, llval));                \
3267    tcg_temp_free(t0);                                                     \
3268}
3269#else
3270#define OP_LD_ATOMIC(insn,fname)                                           \
3271static inline void op_ld_##insn(TCGv ret, TCGv arg1, int mem_idx,          \
3272                                DisasContext *ctx)                         \
3273{                                                                          \
3274    gen_helper_1e1i(insn, ret, arg1, mem_idx);                             \
3275}
3276#endif
3277OP_LD_ATOMIC(ll,ld32s);
3278#if defined(TARGET_MIPS64)
3279OP_LD_ATOMIC(lld,ld64);
3280#endif
3281#undef OP_LD_ATOMIC
3282
3283#ifdef CONFIG_USER_ONLY
3284#define OP_ST_ATOMIC(insn,fname,ldname,almask)                               \
3285static inline void op_st_##insn(TCGv arg1, TCGv arg2, int rt, int mem_idx,   \
3286                                DisasContext *ctx)                           \
3287{                                                                            \
3288    TCGv t0 = tcg_temp_new();                                                \
3289    TCGLabel *l1 = gen_new_label();                                          \
3290    TCGLabel *l2 = gen_new_label();                                          \
3291                                                                             \
3292    tcg_gen_andi_tl(t0, arg2, almask);                                       \
3293    tcg_gen_brcondi_tl(TCG_COND_EQ, t0, 0, l1);                              \
3294    tcg_gen_st_tl(arg2, cpu_env, offsetof(CPUMIPSState, CP0_BadVAddr));          \
3295    generate_exception(ctx, EXCP_AdES);                                      \
3296    gen_set_label(l1);                                                       \
3297    tcg_gen_ld_tl(t0, cpu_env, offsetof(CPUMIPSState, lladdr));                  \
3298    tcg_gen_brcond_tl(TCG_COND_NE, arg2, t0, l2);                            \
3299    tcg_gen_movi_tl(t0, rt | ((almask << 3) & 0x20));                        \
3300    tcg_gen_st_tl(t0, cpu_env, offsetof(CPUMIPSState, llreg));                   \
3301    tcg_gen_st_tl(arg1, cpu_env, offsetof(CPUMIPSState, llnewval));              \
3302    generate_exception_end(ctx, EXCP_SC);                                    \
3303    gen_set_label(l2);                                                       \
3304    tcg_gen_movi_tl(t0, 0);                                                  \
3305    gen_store_gpr(t0, rt);                                                   \
3306    tcg_temp_free(t0);                                                       \
3307}
3308#else
3309#define OP_ST_ATOMIC(insn,fname,ldname,almask)                               \
3310static inline void op_st_##insn(TCGv arg1, TCGv arg2, int rt, int mem_idx,   \
3311                                DisasContext *ctx)                           \
3312{                                                                            \
3313    TCGv t0 = tcg_temp_new();                                                \
3314    gen_helper_1e2i(insn, t0, arg1, arg2, mem_idx);                          \
3315    gen_store_gpr(t0, rt);                                                   \
3316    tcg_temp_free(t0);                                                       \
3317}
3318#endif
3319OP_ST_ATOMIC(sc,st32,ld32s,0x3);
3320#if defined(TARGET_MIPS64)
3321OP_ST_ATOMIC(scd,st64,ld64,0x7);
3322#endif
3323#undef OP_ST_ATOMIC
3324
3325static void gen_base_offset_addr (DisasContext *ctx, TCGv addr,
3326                                  int base, int offset)
3327{
3328    if (base == 0) {
3329        tcg_gen_movi_tl(addr, offset);
3330    } else if (offset == 0) {
3331        gen_load_gpr(addr, base);
3332    } else {
3333        tcg_gen_movi_tl(addr, offset);
3334        gen_op_addr_add(ctx, addr, cpu_gpr[base], addr);
3335    }
3336}
3337
3338static target_ulong pc_relative_pc (DisasContext *ctx)
3339{
3340    target_ulong pc = ctx->base.pc_next;
3341
3342    if (ctx->hflags & MIPS_HFLAG_BMASK) {
3343        int branch_bytes = ctx->hflags & MIPS_HFLAG_BDS16 ? 2 : 4;
3344
3345        pc -= branch_bytes;
3346    }
3347
3348    pc &= ~(target_ulong)3;
3349    return pc;
3350}
3351
3352/* Load */
3353static void gen_ld(DisasContext *ctx, uint32_t opc,
3354                   int rt, int base, int offset)
3355{
3356    TCGv t0, t1, t2;
3357    int mem_idx = ctx->mem_idx;
3358
3359    if (rt == 0 && ctx->insn_flags & (INSN_LOONGSON2E | INSN_LOONGSON2F)) {
3360        /* Loongson CPU uses a load to zero register for prefetch.
3361           We emulate it as a NOP. On other CPU we must perform the
3362           actual memory access. */
3363        return;
3364    }
3365
3366    t0 = tcg_temp_new();
3367    gen_base_offset_addr(ctx, t0, base, offset);
3368
3369    switch (opc) {
3370#if defined(TARGET_MIPS64)
3371    case OPC_LWU:
3372        tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TEUL |
3373                           ctx->default_tcg_memop_mask);
3374        gen_store_gpr(t0, rt);
3375        break;
3376    case OPC_LD:
3377        tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TEQ |
3378                           ctx->default_tcg_memop_mask);
3379        gen_store_gpr(t0, rt);
3380        break;
3381    case OPC_LLD:
3382    case R6_OPC_LLD:
3383        op_ld_lld(t0, t0, mem_idx, ctx);
3384        gen_store_gpr(t0, rt);
3385        break;
3386    case OPC_LDL:
3387        t1 = tcg_temp_new();
3388        /* Do a byte access to possibly trigger a page
3389           fault with the unaligned address.  */
3390        tcg_gen_qemu_ld_tl(t1, t0, mem_idx, MO_UB);
3391        tcg_gen_andi_tl(t1, t0, 7);
3392#ifndef TARGET_WORDS_BIGENDIAN
3393        tcg_gen_xori_tl(t1, t1, 7);
3394#endif
3395        tcg_gen_shli_tl(t1, t1, 3);
3396        tcg_gen_andi_tl(t0, t0, ~7);
3397        tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TEQ);
3398        tcg_gen_shl_tl(t0, t0, t1);
3399        t2 = tcg_const_tl(-1);
3400        tcg_gen_shl_tl(t2, t2, t1);
3401        gen_load_gpr(t1, rt);
3402        tcg_gen_andc_tl(t1, t1, t2);
3403        tcg_temp_free(t2);
3404        tcg_gen_or_tl(t0, t0, t1);
3405        tcg_temp_free(t1);
3406        gen_store_gpr(t0, rt);
3407        break;
3408    case OPC_LDR:
3409        t1 = tcg_temp_new();
3410        /* Do a byte access to possibly trigger a page
3411           fault with the unaligned address.  */
3412        tcg_gen_qemu_ld_tl(t1, t0, mem_idx, MO_UB);
3413        tcg_gen_andi_tl(t1, t0, 7);
3414#ifdef TARGET_WORDS_BIGENDIAN
3415        tcg_gen_xori_tl(t1, t1, 7);
3416#endif
3417        tcg_gen_shli_tl(t1, t1, 3);
3418        tcg_gen_andi_tl(t0, t0, ~7);
3419        tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TEQ);
3420        tcg_gen_shr_tl(t0, t0, t1);
3421        tcg_gen_xori_tl(t1, t1, 63);
3422        t2 = tcg_const_tl(0xfffffffffffffffeull);
3423        tcg_gen_shl_tl(t2, t2, t1);
3424        gen_load_gpr(t1, rt);
3425        tcg_gen_and_tl(t1, t1, t2);
3426        tcg_temp_free(t2);
3427        tcg_gen_or_tl(t0, t0, t1);
3428        tcg_temp_free(t1);
3429        gen_store_gpr(t0, rt);
3430        break;
3431    case OPC_LDPC:
3432        t1 = tcg_const_tl(pc_relative_pc(ctx));
3433        gen_op_addr_add(ctx, t0, t0, t1);
3434        tcg_temp_free(t1);
3435        tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TEQ);
3436        gen_store_gpr(t0, rt);
3437        break;
3438#endif
3439    case OPC_LWPC:
3440        t1 = tcg_const_tl(pc_relative_pc(ctx));
3441        gen_op_addr_add(ctx, t0, t0, t1);
3442        tcg_temp_free(t1);
3443        tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TESL);
3444        gen_store_gpr(t0, rt);
3445        break;
3446    case OPC_LWE:
3447        mem_idx = MIPS_HFLAG_UM;
3448        /* fall through */
3449    case OPC_LW:
3450        tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TESL |
3451                           ctx->default_tcg_memop_mask);
3452        gen_store_gpr(t0, rt);
3453        break;
3454    case OPC_LHE:
3455        mem_idx = MIPS_HFLAG_UM;
3456        /* fall through */
3457    case OPC_LH:
3458        tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TESW |
3459                           ctx->default_tcg_memop_mask);
3460        gen_store_gpr(t0, rt);
3461        break;
3462    case OPC_LHUE:
3463        mem_idx = MIPS_HFLAG_UM;
3464        /* fall through */
3465    case OPC_LHU:
3466        tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TEUW |
3467                           ctx->default_tcg_memop_mask);
3468        gen_store_gpr(t0, rt);
3469        break;
3470    case OPC_LBE:
3471        mem_idx = MIPS_HFLAG_UM;
3472        /* fall through */
3473    case OPC_LB:
3474        tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_SB);
3475        gen_store_gpr(t0, rt);
3476        break;
3477    case OPC_LBUE:
3478        mem_idx = MIPS_HFLAG_UM;
3479        /* fall through */
3480    case OPC_LBU:
3481        tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_UB);
3482        gen_store_gpr(t0, rt);
3483        break;
3484    case OPC_LWLE:
3485        mem_idx = MIPS_HFLAG_UM;
3486        /* fall through */
3487    case OPC_LWL:
3488        t1 = tcg_temp_new();
3489        /* Do a byte access to possibly trigger a page
3490           fault with the unaligned address.  */
3491        tcg_gen_qemu_ld_tl(t1, t0, mem_idx, MO_UB);
3492        tcg_gen_andi_tl(t1, t0, 3);
3493#ifndef TARGET_WORDS_BIGENDIAN
3494        tcg_gen_xori_tl(t1, t1, 3);
3495#endif
3496        tcg_gen_shli_tl(t1, t1, 3);
3497        tcg_gen_andi_tl(t0, t0, ~3);
3498        tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TEUL);
3499        tcg_gen_shl_tl(t0, t0, t1);
3500        t2 = tcg_const_tl(-1);
3501        tcg_gen_shl_tl(t2, t2, t1);
3502        gen_load_gpr(t1, rt);
3503        tcg_gen_andc_tl(t1, t1, t2);
3504        tcg_temp_free(t2);
3505        tcg_gen_or_tl(t0, t0, t1);
3506        tcg_temp_free(t1);
3507        tcg_gen_ext32s_tl(t0, t0);
3508        gen_store_gpr(t0, rt);
3509        break;
3510    case OPC_LWRE:
3511        mem_idx = MIPS_HFLAG_UM;
3512        /* fall through */
3513    case OPC_LWR:
3514        t1 = tcg_temp_new();
3515        /* Do a byte access to possibly trigger a page
3516           fault with the unaligned address.  */
3517        tcg_gen_qemu_ld_tl(t1, t0, mem_idx, MO_UB);
3518        tcg_gen_andi_tl(t1, t0, 3);
3519#ifdef TARGET_WORDS_BIGENDIAN
3520        tcg_gen_xori_tl(t1, t1, 3);
3521#endif
3522        tcg_gen_shli_tl(t1, t1, 3);
3523        tcg_gen_andi_tl(t0, t0, ~3);
3524        tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TEUL);
3525        tcg_gen_shr_tl(t0, t0, t1);
3526        tcg_gen_xori_tl(t1, t1, 31);
3527        t2 = tcg_const_tl(0xfffffffeull);
3528        tcg_gen_shl_tl(t2, t2, t1);
3529        gen_load_gpr(t1, rt);
3530        tcg_gen_and_tl(t1, t1, t2);
3531        tcg_temp_free(t2);
3532        tcg_gen_or_tl(t0, t0, t1);
3533        tcg_temp_free(t1);
3534        tcg_gen_ext32s_tl(t0, t0);
3535        gen_store_gpr(t0, rt);
3536        break;
3537    case OPC_LLE:
3538        mem_idx = MIPS_HFLAG_UM;
3539        /* fall through */
3540    case OPC_LL:
3541    case R6_OPC_LL:
3542        op_ld_ll(t0, t0, mem_idx, ctx);
3543        gen_store_gpr(t0, rt);
3544        break;
3545    }
3546    tcg_temp_free(t0);
3547}
3548
3549static void gen_llwp(DisasContext *ctx, uint32_t base, int16_t offset,
3550                    uint32_t reg1, uint32_t reg2)
3551{
3552    TCGv taddr = tcg_temp_new();
3553    TCGv_i64 tval = tcg_temp_new_i64();
3554    TCGv tmp1 = tcg_temp_new();
3555    TCGv tmp2 = tcg_temp_new();
3556
3557    gen_base_offset_addr(ctx, taddr, base, offset);
3558    tcg_gen_qemu_ld64(tval, taddr, ctx->mem_idx);
3559#ifdef TARGET_WORDS_BIGENDIAN
3560    tcg_gen_extr_i64_tl(tmp2, tmp1, tval);
3561#else
3562    tcg_gen_extr_i64_tl(tmp1, tmp2, tval);
3563#endif
3564    gen_store_gpr(tmp1, reg1);
3565    tcg_temp_free(tmp1);
3566    gen_store_gpr(tmp2, reg2);
3567    tcg_temp_free(tmp2);
3568    tcg_gen_st_i64(tval, cpu_env, offsetof(CPUMIPSState, llval_wp));
3569    tcg_temp_free_i64(tval);
3570    tcg_gen_st_tl(taddr, cpu_env, offsetof(CPUMIPSState, lladdr));
3571    tcg_temp_free(taddr);
3572}
3573
3574/* Store */
3575static void gen_st (DisasContext *ctx, uint32_t opc, int rt,
3576                    int base, int offset)
3577{
3578    TCGv t0 = tcg_temp_new();
3579    TCGv t1 = tcg_temp_new();
3580    int mem_idx = ctx->mem_idx;
3581
3582    gen_base_offset_addr(ctx, t0, base, offset);
3583    gen_load_gpr(t1, rt);
3584    switch (opc) {
3585#if defined(TARGET_MIPS64)
3586    case OPC_SD:
3587        tcg_gen_qemu_st_tl(t1, t0, mem_idx, MO_TEQ |
3588                           ctx->default_tcg_memop_mask);
3589        break;
3590    case OPC_SDL:
3591        gen_helper_0e2i(sdl, t1, t0, mem_idx);
3592        break;
3593    case OPC_SDR:
3594        gen_helper_0e2i(sdr, t1, t0, mem_idx);
3595        break;
3596#endif
3597    case OPC_SWE:
3598        mem_idx = MIPS_HFLAG_UM;
3599        /* fall through */
3600    case OPC_SW:
3601        tcg_gen_qemu_st_tl(t1, t0, mem_idx, MO_TEUL |
3602                           ctx->default_tcg_memop_mask);
3603        break;
3604    case OPC_SHE:
3605        mem_idx = MIPS_HFLAG_UM;
3606        /* fall through */
3607    case OPC_SH:
3608        tcg_gen_qemu_st_tl(t1, t0, mem_idx, MO_TEUW |
3609                           ctx->default_tcg_memop_mask);
3610        break;
3611    case OPC_SBE:
3612        mem_idx = MIPS_HFLAG_UM;
3613        /* fall through */
3614    case OPC_SB:
3615        tcg_gen_qemu_st_tl(t1, t0, mem_idx, MO_8);
3616        break;
3617    case OPC_SWLE:
3618        mem_idx = MIPS_HFLAG_UM;
3619        /* fall through */
3620    case OPC_SWL:
3621        gen_helper_0e2i(swl, t1, t0, mem_idx);
3622        break;
3623    case OPC_SWRE:
3624        mem_idx = MIPS_HFLAG_UM;
3625        /* fall through */
3626    case OPC_SWR:
3627        gen_helper_0e2i(swr, t1, t0, mem_idx);
3628        break;
3629    }
3630    tcg_temp_free(t0);
3631    tcg_temp_free(t1);
3632}
3633
3634
3635/* Store conditional */
3636static void gen_st_cond (DisasContext *ctx, uint32_t opc, int rt,
3637                         int base, int16_t offset)
3638{
3639    TCGv t0, t1;
3640    int mem_idx = ctx->mem_idx;
3641
3642#ifdef CONFIG_USER_ONLY
3643    t0 = tcg_temp_local_new();
3644    t1 = tcg_temp_local_new();
3645#else
3646    t0 = tcg_temp_new();
3647    t1 = tcg_temp_new();
3648#endif
3649    gen_base_offset_addr(ctx, t0, base, offset);
3650    gen_load_gpr(t1, rt);
3651    switch (opc) {
3652#if defined(TARGET_MIPS64)
3653    case OPC_SCD:
3654    case R6_OPC_SCD:
3655        op_st_scd(t1, t0, rt, mem_idx, ctx);
3656        break;
3657#endif
3658    case OPC_SCE:
3659        mem_idx = MIPS_HFLAG_UM;
3660        /* fall through */
3661    case OPC_SC:
3662    case R6_OPC_SC:
3663        op_st_sc(t1, t0, rt, mem_idx, ctx);
3664        break;
3665    }
3666    tcg_temp_free(t1);
3667    tcg_temp_free(t0);
3668}
3669
3670static void gen_scwp(DisasContext *ctx, uint32_t base, int16_t offset,
3671                    uint32_t reg1, uint32_t reg2)
3672{
3673    TCGv taddr = tcg_temp_local_new();
3674    TCGv lladdr = tcg_temp_local_new();
3675    TCGv_i64 tval = tcg_temp_new_i64();
3676    TCGv_i64 llval = tcg_temp_new_i64();
3677    TCGv_i64 val = tcg_temp_new_i64();
3678    TCGv tmp1 = tcg_temp_new();
3679    TCGv tmp2 = tcg_temp_new();
3680    TCGLabel *lab_fail = gen_new_label();
3681    TCGLabel *lab_done = gen_new_label();
3682
3683    gen_base_offset_addr(ctx, taddr, base, offset);
3684
3685    tcg_gen_ld_tl(lladdr, cpu_env, offsetof(CPUMIPSState, lladdr));
3686    tcg_gen_brcond_tl(TCG_COND_NE, taddr, lladdr, lab_fail);
3687
3688    gen_load_gpr(tmp1, reg1);
3689    gen_load_gpr(tmp2, reg2);
3690
3691#ifdef TARGET_WORDS_BIGENDIAN
3692    tcg_gen_concat_tl_i64(tval, tmp2, tmp1);
3693#else
3694    tcg_gen_concat_tl_i64(tval, tmp1, tmp2);
3695#endif
3696
3697    tcg_gen_ld_i64(llval, cpu_env, offsetof(CPUMIPSState, llval_wp));
3698    tcg_gen_atomic_cmpxchg_i64(val, taddr, llval, tval,
3699                               ctx->mem_idx, MO_64);
3700    if (reg1 != 0) {
3701        tcg_gen_movi_tl(cpu_gpr[reg1], 1);
3702    }
3703    tcg_gen_brcond_i64(TCG_COND_EQ, val, llval, lab_done);
3704
3705    gen_set_label(lab_fail);
3706
3707    if (reg1 != 0) {
3708        tcg_gen_movi_tl(cpu_gpr[reg1], 0);
3709    }
3710    gen_set_label(lab_done);
3711    tcg_gen_movi_tl(lladdr, -1);
3712    tcg_gen_st_tl(lladdr, cpu_env, offsetof(CPUMIPSState, lladdr));
3713}
3714
3715/* Load and store */
3716static void gen_flt_ldst (DisasContext *ctx, uint32_t opc, int ft,
3717                          TCGv t0)
3718{
3719    /* Don't do NOP if destination is zero: we must perform the actual
3720       memory access. */
3721    switch (opc) {
3722    case OPC_LWC1:
3723        {
3724            TCGv_i32 fp0 = tcg_temp_new_i32();
3725            tcg_gen_qemu_ld_i32(fp0, t0, ctx->mem_idx, MO_TESL |
3726                                ctx->default_tcg_memop_mask);
3727            gen_store_fpr32(ctx, fp0, ft);
3728            tcg_temp_free_i32(fp0);
3729        }
3730        break;
3731    case OPC_SWC1:
3732        {
3733            TCGv_i32 fp0 = tcg_temp_new_i32();
3734            gen_load_fpr32(ctx, fp0, ft);
3735            tcg_gen_qemu_st_i32(fp0, t0, ctx->mem_idx, MO_TEUL |
3736                                ctx->default_tcg_memop_mask);
3737            tcg_temp_free_i32(fp0);
3738        }
3739        break;
3740    case OPC_LDC1:
3741        {
3742            TCGv_i64 fp0 = tcg_temp_new_i64();
3743            tcg_gen_qemu_ld_i64(fp0, t0, ctx->mem_idx, MO_TEQ |
3744                                ctx->default_tcg_memop_mask);
3745            gen_store_fpr64(ctx, fp0, ft);
3746            tcg_temp_free_i64(fp0);
3747        }
3748        break;
3749    case OPC_SDC1:
3750        {
3751            TCGv_i64 fp0 = tcg_temp_new_i64();
3752            gen_load_fpr64(ctx, fp0, ft);
3753            tcg_gen_qemu_st_i64(fp0, t0, ctx->mem_idx, MO_TEQ |
3754                                ctx->default_tcg_memop_mask);
3755            tcg_temp_free_i64(fp0);
3756        }
3757        break;
3758    default:
3759        MIPS_INVAL("flt_ldst");
3760        generate_exception_end(ctx, EXCP_RI);
3761        break;
3762    }
3763}
3764
3765static void gen_cop1_ldst(DisasContext *ctx, uint32_t op, int rt,
3766                          int rs, int16_t imm)
3767{
3768    TCGv t0 = tcg_temp_new();
3769
3770    if (ctx->CP0_Config1 & (1 << CP0C1_FP)) {
3771        check_cp1_enabled(ctx);
3772        switch (op) {
3773        case OPC_LDC1:
3774        case OPC_SDC1:
3775            check_insn(ctx, ISA_MIPS2);
3776            /* Fallthrough */
3777        default:
3778            gen_base_offset_addr(ctx, t0, rs, imm);
3779            gen_flt_ldst(ctx, op, rt, t0);
3780        }
3781    } else {
3782        generate_exception_err(ctx, EXCP_CpU, 1);
3783    }
3784    tcg_temp_free(t0);
3785}
3786
3787/* Arithmetic with immediate operand */
3788static void gen_arith_imm(DisasContext *ctx, uint32_t opc,
3789                          int rt, int rs, int imm)
3790{
3791    target_ulong uimm = (target_long)imm; /* Sign extend to 32/64 bits */
3792
3793    if (rt == 0 && opc != OPC_ADDI && opc != OPC_DADDI) {
3794        /* If no destination, treat it as a NOP.
3795           For addi, we must generate the overflow exception when needed. */
3796        return;
3797    }
3798    switch (opc) {
3799    case OPC_ADDI:
3800        {
3801            TCGv t0 = tcg_temp_local_new();
3802            TCGv t1 = tcg_temp_new();
3803            TCGv t2 = tcg_temp_new();
3804            TCGLabel *l1 = gen_new_label();
3805
3806            gen_load_gpr(t1, rs);
3807            tcg_gen_addi_tl(t0, t1, uimm);
3808            tcg_gen_ext32s_tl(t0, t0);
3809
3810            tcg_gen_xori_tl(t1, t1, ~uimm);
3811            tcg_gen_xori_tl(t2, t0, uimm);
3812            tcg_gen_and_tl(t1, t1, t2);
3813            tcg_temp_free(t2);
3814            tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
3815            tcg_temp_free(t1);
3816            /* operands of same sign, result different sign */
3817            generate_exception(ctx, EXCP_OVERFLOW);
3818            gen_set_label(l1);
3819            tcg_gen_ext32s_tl(t0, t0);
3820            gen_store_gpr(t0, rt);
3821            tcg_temp_free(t0);
3822        }
3823        break;
3824    case OPC_ADDIU:
3825        if (rs != 0) {
3826            tcg_gen_addi_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
3827            tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
3828        } else {
3829            tcg_gen_movi_tl(cpu_gpr[rt], uimm);
3830        }
3831        break;
3832#if defined(TARGET_MIPS64)
3833    case OPC_DADDI:
3834        {
3835            TCGv t0 = tcg_temp_local_new();
3836            TCGv t1 = tcg_temp_new();
3837            TCGv t2 = tcg_temp_new();
3838            TCGLabel *l1 = gen_new_label();
3839
3840            gen_load_gpr(t1, rs);
3841            tcg_gen_addi_tl(t0, t1, uimm);
3842
3843            tcg_gen_xori_tl(t1, t1, ~uimm);
3844            tcg_gen_xori_tl(t2, t0, uimm);
3845            tcg_gen_and_tl(t1, t1, t2);
3846            tcg_temp_free(t2);
3847            tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
3848            tcg_temp_free(t1);
3849            /* operands of same sign, result different sign */
3850            generate_exception(ctx, EXCP_OVERFLOW);
3851            gen_set_label(l1);
3852            gen_store_gpr(t0, rt);
3853            tcg_temp_free(t0);
3854        }
3855        break;
3856    case OPC_DADDIU:
3857        if (rs != 0) {
3858            tcg_gen_addi_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
3859        } else {
3860            tcg_gen_movi_tl(cpu_gpr[rt], uimm);
3861        }
3862        break;
3863#endif
3864    }
3865}
3866
3867/* Logic with immediate operand */
3868static void gen_logic_imm(DisasContext *ctx, uint32_t opc,
3869                          int rt, int rs, int16_t imm)
3870{
3871    target_ulong uimm;
3872
3873    if (rt == 0) {
3874        /* If no destination, treat it as a NOP. */
3875        return;
3876    }
3877    uimm = (uint16_t)imm;
3878    switch (opc) {
3879    case OPC_ANDI:
3880        if (likely(rs != 0))
3881            tcg_gen_andi_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
3882        else
3883            tcg_gen_movi_tl(cpu_gpr[rt], 0);
3884        break;
3885    case OPC_ORI:
3886        if (rs != 0)
3887            tcg_gen_ori_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
3888        else
3889            tcg_gen_movi_tl(cpu_gpr[rt], uimm);
3890        break;
3891    case OPC_XORI:
3892        if (likely(rs != 0))
3893            tcg_gen_xori_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
3894        else
3895            tcg_gen_movi_tl(cpu_gpr[rt], uimm);
3896        break;
3897    case OPC_LUI:
3898        if (rs != 0 && (ctx->insn_flags & ISA_MIPS32R6)) {
3899            /* OPC_AUI */
3900            tcg_gen_addi_tl(cpu_gpr[rt], cpu_gpr[rs], imm << 16);
3901            tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
3902        } else {
3903            tcg_gen_movi_tl(cpu_gpr[rt], imm << 16);
3904        }
3905        break;
3906
3907    default:
3908        break;
3909    }
3910}
3911
3912/* Set on less than with immediate operand */
3913static void gen_slt_imm(DisasContext *ctx, uint32_t opc,
3914                        int rt, int rs, int16_t imm)
3915{
3916    target_ulong uimm = (target_long)imm; /* Sign extend to 32/64 bits */
3917    TCGv t0;
3918
3919    if (rt == 0) {
3920        /* If no destination, treat it as a NOP. */
3921        return;
3922    }
3923    t0 = tcg_temp_new();
3924    gen_load_gpr(t0, rs);
3925    switch (opc) {
3926    case OPC_SLTI:
3927        tcg_gen_setcondi_tl(TCG_COND_LT, cpu_gpr[rt], t0, uimm);
3928        break;
3929    case OPC_SLTIU:
3930        tcg_gen_setcondi_tl(TCG_COND_LTU, cpu_gpr[rt], t0, uimm);
3931        break;
3932    }
3933    tcg_temp_free(t0);
3934}
3935
3936/* Shifts with immediate operand */
3937static void gen_shift_imm(DisasContext *ctx, uint32_t opc,
3938                          int rt, int rs, int16_t imm)
3939{
3940    target_ulong uimm = ((uint16_t)imm) & 0x1f;
3941    TCGv t0;
3942
3943    if (rt == 0) {
3944        /* If no destination, treat it as a NOP. */
3945        return;
3946    }
3947
3948    t0 = tcg_temp_new();
3949    gen_load_gpr(t0, rs);
3950    switch (opc) {
3951    case OPC_SLL:
3952        tcg_gen_shli_tl(t0, t0, uimm);
3953        tcg_gen_ext32s_tl(cpu_gpr[rt], t0);
3954        break;
3955    case OPC_SRA:
3956        tcg_gen_sari_tl(cpu_gpr[rt], t0, uimm);
3957        break;
3958    case OPC_SRL:
3959        if (uimm != 0) {
3960            tcg_gen_ext32u_tl(t0, t0);
3961            tcg_gen_shri_tl(cpu_gpr[rt], t0, uimm);
3962        } else {
3963            tcg_gen_ext32s_tl(cpu_gpr[rt], t0);
3964        }
3965        break;
3966    case OPC_ROTR:
3967        if (uimm != 0) {
3968            TCGv_i32 t1 = tcg_temp_new_i32();
3969
3970            tcg_gen_trunc_tl_i32(t1, t0);
3971            tcg_gen_rotri_i32(t1, t1, uimm);
3972            tcg_gen_ext_i32_tl(cpu_gpr[rt], t1);
3973            tcg_temp_free_i32(t1);
3974        } else {
3975            tcg_gen_ext32s_tl(cpu_gpr[rt], t0);
3976        }
3977        break;
3978#if defined(TARGET_MIPS64)
3979    case OPC_DSLL:
3980        tcg_gen_shli_tl(cpu_gpr[rt], t0, uimm);
3981        break;
3982    case OPC_DSRA:
3983        tcg_gen_sari_tl(cpu_gpr[rt], t0, uimm);
3984        break;
3985    case OPC_DSRL:
3986        tcg_gen_shri_tl(cpu_gpr[rt], t0, uimm);
3987        break;
3988    case OPC_DROTR:
3989        if (uimm != 0) {
3990            tcg_gen_rotri_tl(cpu_gpr[rt], t0, uimm);
3991        } else {
3992            tcg_gen_mov_tl(cpu_gpr[rt], t0);
3993        }
3994        break;
3995    case OPC_DSLL32:
3996        tcg_gen_shli_tl(cpu_gpr[rt], t0, uimm + 32);
3997        break;
3998    case OPC_DSRA32:
3999        tcg_gen_sari_tl(cpu_gpr[rt], t0, uimm + 32);
4000        break;
4001    case OPC_DSRL32:
4002        tcg_gen_shri_tl(cpu_gpr[rt], t0, uimm + 32);
4003        break;
4004    case OPC_DROTR32:
4005        tcg_gen_rotri_tl(cpu_gpr[rt], t0, uimm + 32);
4006        break;
4007#endif
4008    }
4009    tcg_temp_free(t0);
4010}
4011
4012/* Arithmetic */
4013static void gen_arith(DisasContext *ctx, uint32_t opc,
4014                      int rd, int rs, int rt)
4015{
4016    if (rd == 0 && opc != OPC_ADD && opc != OPC_SUB
4017       && opc != OPC_DADD && opc != OPC_DSUB) {
4018        /* If no destination, treat it as a NOP.
4019           For add & sub, we must generate the overflow exception when needed. */
4020        return;
4021    }
4022
4023    switch (opc) {
4024    case OPC_ADD:
4025        {
4026            TCGv t0 = tcg_temp_local_new();
4027            TCGv t1 = tcg_temp_new();
4028            TCGv t2 = tcg_temp_new();
4029            TCGLabel *l1 = gen_new_label();
4030
4031            gen_load_gpr(t1, rs);
4032            gen_load_gpr(t2, rt);
4033            tcg_gen_add_tl(t0, t1, t2);
4034            tcg_gen_ext32s_tl(t0, t0);
4035            tcg_gen_xor_tl(t1, t1, t2);
4036            tcg_gen_xor_tl(t2, t0, t2);
4037            tcg_gen_andc_tl(t1, t2, t1);
4038            tcg_temp_free(t2);
4039            tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
4040            tcg_temp_free(t1);
4041            /* operands of same sign, result different sign */
4042            generate_exception(ctx, EXCP_OVERFLOW);
4043            gen_set_label(l1);
4044            gen_store_gpr(t0, rd);
4045            tcg_temp_free(t0);
4046        }
4047        break;
4048    case OPC_ADDU:
4049        if (rs != 0 && rt != 0) {
4050            tcg_gen_add_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
4051            tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
4052        } else if (rs == 0 && rt != 0) {
4053            tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
4054        } else if (rs != 0 && rt == 0) {
4055            tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
4056        } else {
4057            tcg_gen_movi_tl(cpu_gpr[rd], 0);
4058        }
4059        break;
4060    case OPC_SUB:
4061        {
4062            TCGv t0 = tcg_temp_local_new();
4063            TCGv t1 = tcg_temp_new();
4064            TCGv t2 = tcg_temp_new();
4065            TCGLabel *l1 = gen_new_label();
4066
4067            gen_load_gpr(t1, rs);
4068            gen_load_gpr(t2, rt);
4069            tcg_gen_sub_tl(t0, t1, t2);
4070            tcg_gen_ext32s_tl(t0, t0);
4071            tcg_gen_xor_tl(t2, t1, t2);
4072            tcg_gen_xor_tl(t1, t0, t1);
4073            tcg_gen_and_tl(t1, t1, t2);
4074            tcg_temp_free(t2);
4075            tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
4076            tcg_temp_free(t1);
4077            /* operands of different sign, first operand and result different sign */
4078            generate_exception(ctx, EXCP_OVERFLOW);
4079            gen_set_label(l1);
4080            gen_store_gpr(t0, rd);
4081            tcg_temp_free(t0);
4082        }
4083        break;
4084    case OPC_SUBU:
4085        if (rs != 0 && rt != 0) {
4086            tcg_gen_sub_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
4087            tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
4088        } else if (rs == 0 && rt != 0) {
4089            tcg_gen_neg_tl(cpu_gpr[rd], cpu_gpr[rt]);
4090            tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
4091        } else if (rs != 0 && rt == 0) {
4092            tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
4093        } else {
4094            tcg_gen_movi_tl(cpu_gpr[rd], 0);
4095        }
4096        break;
4097#if defined(TARGET_MIPS64)
4098    case OPC_DADD:
4099        {
4100            TCGv t0 = tcg_temp_local_new();
4101            TCGv t1 = tcg_temp_new();
4102            TCGv t2 = tcg_temp_new();
4103            TCGLabel *l1 = gen_new_label();
4104
4105            gen_load_gpr(t1, rs);
4106            gen_load_gpr(t2, rt);
4107            tcg_gen_add_tl(t0, t1, t2);
4108            tcg_gen_xor_tl(t1, t1, t2);
4109            tcg_gen_xor_tl(t2, t0, t2);
4110            tcg_gen_andc_tl(t1, t2, t1);
4111            tcg_temp_free(t2);
4112            tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
4113            tcg_temp_free(t1);
4114            /* operands of same sign, result different sign */
4115            generate_exception(ctx, EXCP_OVERFLOW);
4116            gen_set_label(l1);
4117            gen_store_gpr(t0, rd);
4118            tcg_temp_free(t0);
4119        }
4120        break;
4121    case OPC_DADDU:
4122        if (rs != 0 && rt != 0) {
4123            tcg_gen_add_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
4124        } else if (rs == 0 && rt != 0) {
4125            tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
4126        } else if (rs != 0 && rt == 0) {
4127            tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
4128        } else {
4129            tcg_gen_movi_tl(cpu_gpr[rd], 0);
4130        }
4131        break;
4132    case OPC_DSUB:
4133        {
4134            TCGv t0 = tcg_temp_local_new();
4135            TCGv t1 = tcg_temp_new();
4136            TCGv t2 = tcg_temp_new();
4137            TCGLabel *l1 = gen_new_label();
4138
4139            gen_load_gpr(t1, rs);
4140            gen_load_gpr(t2, rt);
4141            tcg_gen_sub_tl(t0, t1, t2);
4142            tcg_gen_xor_tl(t2, t1, t2);
4143            tcg_gen_xor_tl(t1, t0, t1);
4144            tcg_gen_and_tl(t1, t1, t2);
4145            tcg_temp_free(t2);
4146            tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
4147            tcg_temp_free(t1);
4148            /* operands of different sign, first operand and result different sign */
4149            generate_exception(ctx, EXCP_OVERFLOW);
4150            gen_set_label(l1);
4151            gen_store_gpr(t0, rd);
4152            tcg_temp_free(t0);
4153        }
4154        break;
4155    case OPC_DSUBU:
4156        if (rs != 0 && rt != 0) {
4157            tcg_gen_sub_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
4158        } else if (rs == 0 && rt != 0) {
4159            tcg_gen_neg_tl(cpu_gpr[rd], cpu_gpr[rt]);
4160        } else if (rs != 0 && rt == 0) {
4161            tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
4162        } else {
4163            tcg_gen_movi_tl(cpu_gpr[rd], 0);
4164        }
4165        break;
4166#endif
4167    case OPC_MUL:
4168        if (likely(rs != 0 && rt != 0)) {
4169            tcg_gen_mul_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
4170            tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
4171        } else {
4172            tcg_gen_movi_tl(cpu_gpr[rd], 0);
4173        }
4174        break;
4175    }
4176}
4177
4178/* Conditional move */
4179static void gen_cond_move(DisasContext *ctx, uint32_t opc,
4180                          int rd, int rs, int rt)
4181{
4182    TCGv t0, t1, t2;
4183
4184    if (rd == 0) {
4185        /* If no destination, treat it as a NOP. */
4186        return;
4187    }
4188
4189    t0 = tcg_temp_new();
4190    gen_load_gpr(t0, rt);
4191    t1 = tcg_const_tl(0);
4192    t2 = tcg_temp_new();
4193    gen_load_gpr(t2, rs);
4194    switch (opc) {
4195    case OPC_MOVN:
4196        tcg_gen_movcond_tl(TCG_COND_NE, cpu_gpr[rd], t0, t1, t2, cpu_gpr[rd]);
4197        break;
4198    case OPC_MOVZ:
4199        tcg_gen_movcond_tl(TCG_COND_EQ, cpu_gpr[rd], t0, t1, t2, cpu_gpr[rd]);
4200        break;
4201    case OPC_SELNEZ:
4202        tcg_gen_movcond_tl(TCG_COND_NE, cpu_gpr[rd], t0, t1, t2, t1);
4203        break;
4204    case OPC_SELEQZ:
4205        tcg_gen_movcond_tl(TCG_COND_EQ, cpu_gpr[rd], t0, t1, t2, t1);
4206        break;
4207    }
4208    tcg_temp_free(t2);
4209    tcg_temp_free(t1);
4210    tcg_temp_free(t0);
4211}
4212
4213/* Logic */
4214static void gen_logic(DisasContext *ctx, uint32_t opc,
4215                      int rd, int rs, int rt)
4216{
4217    if (rd == 0) {
4218        /* If no destination, treat it as a NOP. */
4219        return;
4220    }
4221
4222    switch (opc) {
4223    case OPC_AND:
4224        if (likely(rs != 0 && rt != 0)) {
4225            tcg_gen_and_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
4226        } else {
4227            tcg_gen_movi_tl(cpu_gpr[rd], 0);
4228        }
4229        break;
4230    case OPC_NOR:
4231        if (rs != 0 && rt != 0) {
4232            tcg_gen_nor_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
4233        } else if (rs == 0 && rt != 0) {
4234            tcg_gen_not_tl(cpu_gpr[rd], cpu_gpr[rt]);
4235        } else if (rs != 0 && rt == 0) {
4236            tcg_gen_not_tl(cpu_gpr[rd], cpu_gpr[rs]);
4237        } else {
4238            tcg_gen_movi_tl(cpu_gpr[rd], ~((target_ulong)0));
4239        }
4240        break;
4241    case OPC_OR:
4242        if (likely(rs != 0 && rt != 0)) {
4243            tcg_gen_or_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
4244        } else if (rs == 0 && rt != 0) {
4245            tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
4246        } else if (rs != 0 && rt == 0) {
4247            tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
4248        } else {
4249            tcg_gen_movi_tl(cpu_gpr[rd], 0);
4250        }
4251        break;
4252    case OPC_XOR:
4253        if (likely(rs != 0 && rt != 0)) {
4254            tcg_gen_xor_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
4255        } else if (rs == 0 && rt != 0) {
4256            tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
4257        } else if (rs != 0 && rt == 0) {
4258            tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
4259        } else {
4260            tcg_gen_movi_tl(cpu_gpr[rd], 0);
4261        }
4262        break;
4263    }
4264}
4265
4266/* Set on lower than */
4267static void gen_slt(DisasContext *ctx, uint32_t opc,
4268                    int rd, int rs, int rt)
4269{
4270    TCGv t0, t1;
4271
4272    if (rd == 0) {
4273        /* If no destination, treat it as a NOP. */
4274        return;
4275    }
4276
4277    t0 = tcg_temp_new();
4278    t1 = tcg_temp_new();
4279    gen_load_gpr(t0, rs);
4280    gen_load_gpr(t1, rt);
4281    switch (opc) {
4282    case OPC_SLT:
4283        tcg_gen_setcond_tl(TCG_COND_LT, cpu_gpr[rd], t0, t1);
4284        break;
4285    case OPC_SLTU:
4286        tcg_gen_setcond_tl(TCG_COND_LTU, cpu_gpr[rd], t0, t1);
4287        break;
4288    }
4289    tcg_temp_free(t0);
4290    tcg_temp_free(t1);
4291}
4292
4293/* Shifts */
4294static void gen_shift(DisasContext *ctx, uint32_t opc,
4295                      int rd, int rs, int rt)
4296{
4297    TCGv t0, t1;
4298
4299    if (rd == 0) {
4300        /* If no destination, treat it as a NOP.
4301           For add & sub, we must generate the overflow exception when needed. */
4302        return;
4303    }
4304
4305    t0 = tcg_temp_new();
4306    t1 = tcg_temp_new();
4307    gen_load_gpr(t0, rs);
4308    gen_load_gpr(t1, rt);
4309    switch (opc) {
4310    case OPC_SLLV:
4311        tcg_gen_andi_tl(t0, t0, 0x1f);
4312        tcg_gen_shl_tl(t0, t1, t0);
4313        tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
4314        break;
4315    case OPC_SRAV:
4316        tcg_gen_andi_tl(t0, t0, 0x1f);
4317        tcg_gen_sar_tl(cpu_gpr[rd], t1, t0);
4318        break;
4319    case OPC_SRLV:
4320        tcg_gen_ext32u_tl(t1, t1);
4321        tcg_gen_andi_tl(t0, t0, 0x1f);
4322        tcg_gen_shr_tl(t0, t1, t0);
4323        tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
4324        break;
4325    case OPC_ROTRV:
4326        {
4327            TCGv_i32 t2 = tcg_temp_new_i32();
4328            TCGv_i32 t3 = tcg_temp_new_i32();
4329
4330            tcg_gen_trunc_tl_i32(t2, t0);
4331            tcg_gen_trunc_tl_i32(t3, t1);
4332            tcg_gen_andi_i32(t2, t2, 0x1f);
4333            tcg_gen_rotr_i32(t2, t3, t2);
4334            tcg_gen_ext_i32_tl(cpu_gpr[rd], t2);
4335            tcg_temp_free_i32(t2);
4336            tcg_temp_free_i32(t3);
4337        }
4338        break;
4339#if defined(TARGET_MIPS64)
4340    case OPC_DSLLV:
4341        tcg_gen_andi_tl(t0, t0, 0x3f);
4342        tcg_gen_shl_tl(cpu_gpr[rd], t1, t0);
4343        break;
4344    case OPC_DSRAV:
4345        tcg_gen_andi_tl(t0, t0, 0x3f);
4346        tcg_gen_sar_tl(cpu_gpr[rd], t1, t0);
4347        break;
4348    case OPC_DSRLV:
4349        tcg_gen_andi_tl(t0, t0, 0x3f);
4350        tcg_gen_shr_tl(cpu_gpr[rd], t1, t0);
4351        break;
4352    case OPC_DROTRV:
4353        tcg_gen_andi_tl(t0, t0, 0x3f);
4354        tcg_gen_rotr_tl(cpu_gpr[rd], t1, t0);
4355        break;
4356#endif
4357    }
4358    tcg_temp_free(t0);
4359    tcg_temp_free(t1);
4360}
4361
4362/* Copy GPR to and from TX79 HI1/LO1 register. */
4363static void gen_HILO1_tx79(DisasContext *ctx, uint32_t opc, int reg)
4364{
4365    if (reg == 0 && (opc == MMI_OPC_MFHI1 || opc == MMI_OPC_MFLO1)) {
4366        /* Treat as NOP. */
4367        return;
4368    }
4369
4370    switch (opc) {
4371    case MMI_OPC_MFHI1:
4372        tcg_gen_mov_tl(cpu_gpr[reg], cpu_HI[1]);
4373        break;
4374    case MMI_OPC_MFLO1:
4375        tcg_gen_mov_tl(cpu_gpr[reg], cpu_LO[1]);
4376        break;
4377    case MMI_OPC_MTHI1:
4378        if (reg != 0) {
4379            tcg_gen_mov_tl(cpu_HI[1], cpu_gpr[reg]);
4380        } else {
4381            tcg_gen_movi_tl(cpu_HI[1], 0);
4382        }
4383        break;
4384    case MMI_OPC_MTLO1:
4385        if (reg != 0) {
4386            tcg_gen_mov_tl(cpu_LO[1], cpu_gpr[reg]);
4387        } else {
4388            tcg_gen_movi_tl(cpu_LO[1], 0);
4389        }
4390        break;
4391    default:
4392        MIPS_INVAL("mfthilo1 TX79");
4393        generate_exception_end(ctx, EXCP_RI);
4394        break;
4395    }
4396}
4397
4398/* Arithmetic on HI/LO registers */
4399static void gen_HILO(DisasContext *ctx, uint32_t opc, int acc, int reg)
4400{
4401    if (reg == 0 && (opc == OPC_MFHI || opc == OPC_MFLO)) {
4402        /* Treat as NOP. */
4403        return;
4404    }
4405
4406    if (acc != 0) {
4407        check_dsp(ctx);
4408    }
4409
4410    switch (opc) {
4411    case OPC_MFHI:
4412#if defined(TARGET_MIPS64)
4413        if (acc != 0) {
4414            tcg_gen_ext32s_tl(cpu_gpr[reg], cpu_HI[acc]);
4415        } else
4416#endif
4417        {
4418            tcg_gen_mov_tl(cpu_gpr[reg], cpu_HI[acc]);
4419        }
4420        break;
4421    case OPC_MFLO:
4422#if defined(TARGET_MIPS64)
4423        if (acc != 0) {
4424            tcg_gen_ext32s_tl(cpu_gpr[reg], cpu_LO[acc]);
4425        } else
4426#endif
4427        {
4428            tcg_gen_mov_tl(cpu_gpr[reg], cpu_LO[acc]);
4429        }
4430        break;
4431    case OPC_MTHI:
4432        if (reg != 0) {
4433#if defined(TARGET_MIPS64)
4434            if (acc != 0) {
4435                tcg_gen_ext32s_tl(cpu_HI[acc], cpu_gpr[reg]);
4436            } else
4437#endif
4438            {
4439                tcg_gen_mov_tl(cpu_HI[acc], cpu_gpr[reg]);
4440            }
4441        } else {
4442            tcg_gen_movi_tl(cpu_HI[acc], 0);
4443        }
4444        break;
4445    case OPC_MTLO:
4446        if (reg != 0) {
4447#if defined(TARGET_MIPS64)
4448            if (acc != 0) {
4449                tcg_gen_ext32s_tl(cpu_LO[acc], cpu_gpr[reg]);
4450            } else
4451#endif
4452            {
4453                tcg_gen_mov_tl(cpu_LO[acc], cpu_gpr[reg]);
4454            }
4455        } else {
4456            tcg_gen_movi_tl(cpu_LO[acc], 0);
4457        }
4458        break;
4459    }
4460}
4461
4462static inline void gen_r6_ld(target_long addr, int reg, int memidx,
4463                             TCGMemOp memop)
4464{
4465    TCGv t0 = tcg_const_tl(addr);
4466    tcg_gen_qemu_ld_tl(t0, t0, memidx, memop);
4467    gen_store_gpr(t0, reg);
4468    tcg_temp_free(t0);
4469}
4470
4471static inline void gen_pcrel(DisasContext *ctx, int opc, target_ulong pc,
4472                             int rs)
4473{
4474    target_long offset;
4475    target_long addr;
4476
4477    switch (MASK_OPC_PCREL_TOP2BITS(opc)) {
4478    case OPC_ADDIUPC:
4479        if (rs != 0) {
4480            offset = sextract32(ctx->opcode << 2, 0, 21);
4481            addr = addr_add(ctx, pc, offset);
4482            tcg_gen_movi_tl(cpu_gpr[rs], addr);
4483        }
4484        break;
4485    case R6_OPC_LWPC:
4486        offset = sextract32(ctx->opcode << 2, 0, 21);
4487        addr = addr_add(ctx, pc, offset);
4488        gen_r6_ld(addr, rs, ctx->mem_idx, MO_TESL);
4489        break;
4490#if defined(TARGET_MIPS64)
4491    case OPC_LWUPC:
4492        check_mips_64(ctx);
4493        offset = sextract32(ctx->opcode << 2, 0, 21);
4494        addr = addr_add(ctx, pc, offset);
4495        gen_r6_ld(addr, rs, ctx->mem_idx, MO_TEUL);
4496        break;
4497#endif
4498    default:
4499        switch (MASK_OPC_PCREL_TOP5BITS(opc)) {
4500        case OPC_AUIPC:
4501            if (rs != 0) {
4502                offset = sextract32(ctx->opcode, 0, 16) << 16;
4503                addr = addr_add(ctx, pc, offset);
4504                tcg_gen_movi_tl(cpu_gpr[rs], addr);
4505            }
4506            break;
4507        case OPC_ALUIPC:
4508            if (rs != 0) {
4509                offset = sextract32(ctx->opcode, 0, 16) << 16;
4510                addr = ~0xFFFF & addr_add(ctx, pc, offset);
4511                tcg_gen_movi_tl(cpu_gpr[rs], addr);
4512            }
4513            break;
4514#if defined(TARGET_MIPS64)
4515        case R6_OPC_LDPC: /* bits 16 and 17 are part of immediate */
4516        case R6_OPC_LDPC + (1 << 16):
4517        case R6_OPC_LDPC + (2 << 16):
4518        case R6_OPC_LDPC + (3 << 16):
4519            check_mips_64(ctx);
4520            offset = sextract32(ctx->opcode << 3, 0, 21);
4521            addr = addr_add(ctx, (pc & ~0x7), offset);
4522            gen_r6_ld(addr, rs, ctx->mem_idx, MO_TEQ);
4523            break;
4524#endif
4525        default:
4526            MIPS_INVAL("OPC_PCREL");
4527            generate_exception_end(ctx, EXCP_RI);
4528            break;
4529        }
4530        break;
4531    }
4532}
4533
4534static void gen_r6_muldiv(DisasContext *ctx, int opc, int rd, int rs, int rt)
4535{
4536    TCGv t0, t1;
4537
4538    if (rd == 0) {
4539        /* Treat as NOP. */
4540        return;
4541    }
4542
4543    t0 = tcg_temp_new();
4544    t1 = tcg_temp_new();
4545
4546    gen_load_gpr(t0, rs);
4547    gen_load_gpr(t1, rt);
4548
4549    switch (opc) {
4550    case R6_OPC_DIV:
4551        {
4552            TCGv t2 = tcg_temp_new();
4553            TCGv t3 = tcg_temp_new();
4554            tcg_gen_ext32s_tl(t0, t0);
4555            tcg_gen_ext32s_tl(t1, t1);
4556            tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, INT_MIN);
4557            tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1);
4558            tcg_gen_and_tl(t2, t2, t3);
4559            tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
4560            tcg_gen_or_tl(t2, t2, t3);
4561            tcg_gen_movi_tl(t3, 0);
4562            tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
4563            tcg_gen_div_tl(cpu_gpr[rd], t0, t1);
4564            tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
4565            tcg_temp_free(t3);
4566            tcg_temp_free(t2);
4567        }
4568        break;
4569    case R6_OPC_MOD:
4570        {
4571            TCGv t2 = tcg_temp_new();
4572            TCGv t3 = tcg_temp_new();
4573            tcg_gen_ext32s_tl(t0, t0);
4574            tcg_gen_ext32s_tl(t1, t1);
4575            tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, INT_MIN);
4576            tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1);
4577            tcg_gen_and_tl(t2, t2, t3);
4578            tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
4579            tcg_gen_or_tl(t2, t2, t3);
4580            tcg_gen_movi_tl(t3, 0);
4581            tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
4582            tcg_gen_rem_tl(cpu_gpr[rd], t0, t1);
4583            tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
4584            tcg_temp_free(t3);
4585            tcg_temp_free(t2);
4586        }
4587        break;
4588    case R6_OPC_DIVU:
4589        {
4590            TCGv t2 = tcg_const_tl(0);
4591            TCGv t3 = tcg_const_tl(1);
4592            tcg_gen_ext32u_tl(t0, t0);
4593            tcg_gen_ext32u_tl(t1, t1);
4594            tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
4595            tcg_gen_divu_tl(cpu_gpr[rd], t0, t1);
4596            tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
4597            tcg_temp_free(t3);
4598            tcg_temp_free(t2);
4599        }
4600        break;
4601    case R6_OPC_MODU:
4602        {
4603            TCGv t2 = tcg_const_tl(0);
4604            TCGv t3 = tcg_const_tl(1);
4605            tcg_gen_ext32u_tl(t0, t0);
4606            tcg_gen_ext32u_tl(t1, t1);
4607            tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
4608            tcg_gen_remu_tl(cpu_gpr[rd], t0, t1);
4609            tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
4610            tcg_temp_free(t3);
4611            tcg_temp_free(t2);
4612        }
4613        break;
4614    case R6_OPC_MUL:
4615        {
4616            TCGv_i32 t2 = tcg_temp_new_i32();
4617            TCGv_i32 t3 = tcg_temp_new_i32();
4618            tcg_gen_trunc_tl_i32(t2, t0);
4619            tcg_gen_trunc_tl_i32(t3, t1);
4620            tcg_gen_mul_i32(t2, t2, t3);
4621            tcg_gen_ext_i32_tl(cpu_gpr[rd], t2);
4622            tcg_temp_free_i32(t2);
4623            tcg_temp_free_i32(t3);
4624        }
4625        break;
4626    case R6_OPC_MUH:
4627        {
4628            TCGv_i32 t2 = tcg_temp_new_i32();
4629            TCGv_i32 t3 = tcg_temp_new_i32();
4630            tcg_gen_trunc_tl_i32(t2, t0);
4631            tcg_gen_trunc_tl_i32(t3, t1);
4632            tcg_gen_muls2_i32(t2, t3, t2, t3);
4633            tcg_gen_ext_i32_tl(cpu_gpr[rd], t3);
4634            tcg_temp_free_i32(t2);
4635            tcg_temp_free_i32(t3);
4636        }
4637        break;
4638    case R6_OPC_MULU:
4639        {
4640            TCGv_i32 t2 = tcg_temp_new_i32();
4641            TCGv_i32 t3 = tcg_temp_new_i32();
4642            tcg_gen_trunc_tl_i32(t2, t0);
4643            tcg_gen_trunc_tl_i32(t3, t1);
4644            tcg_gen_mul_i32(t2, t2, t3);
4645            tcg_gen_ext_i32_tl(cpu_gpr[rd], t2);
4646            tcg_temp_free_i32(t2);
4647            tcg_temp_free_i32(t3);
4648        }
4649        break;
4650    case R6_OPC_MUHU:
4651        {
4652            TCGv_i32 t2 = tcg_temp_new_i32();
4653            TCGv_i32 t3 = tcg_temp_new_i32();
4654            tcg_gen_trunc_tl_i32(t2, t0);
4655            tcg_gen_trunc_tl_i32(t3, t1);
4656            tcg_gen_mulu2_i32(t2, t3, t2, t3);
4657            tcg_gen_ext_i32_tl(cpu_gpr[rd], t3);
4658            tcg_temp_free_i32(t2);
4659            tcg_temp_free_i32(t3);
4660        }
4661        break;
4662#if defined(TARGET_MIPS64)
4663    case R6_OPC_DDIV:
4664        {
4665            TCGv t2 = tcg_temp_new();
4666            TCGv t3 = tcg_temp_new();
4667            tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, -1LL << 63);
4668            tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1LL);
4669            tcg_gen_and_tl(t2, t2, t3);
4670            tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
4671            tcg_gen_or_tl(t2, t2, t3);
4672            tcg_gen_movi_tl(t3, 0);
4673            tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
4674            tcg_gen_div_tl(cpu_gpr[rd], t0, t1);
4675            tcg_temp_free(t3);
4676            tcg_temp_free(t2);
4677        }
4678        break;
4679    case R6_OPC_DMOD:
4680        {
4681            TCGv t2 = tcg_temp_new();
4682            TCGv t3 = tcg_temp_new();
4683            tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, -1LL << 63);
4684            tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1LL);
4685            tcg_gen_and_tl(t2, t2, t3);
4686            tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
4687            tcg_gen_or_tl(t2, t2, t3);
4688            tcg_gen_movi_tl(t3, 0);
4689            tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
4690            tcg_gen_rem_tl(cpu_gpr[rd], t0, t1);
4691            tcg_temp_free(t3);
4692            tcg_temp_free(t2);
4693        }
4694        break;
4695    case R6_OPC_DDIVU:
4696        {
4697            TCGv t2 = tcg_const_tl(0);
4698            TCGv t3 = tcg_const_tl(1);
4699            tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
4700            tcg_gen_divu_i64(cpu_gpr[rd], t0, t1);
4701            tcg_temp_free(t3);
4702            tcg_temp_free(t2);
4703        }
4704        break;
4705    case R6_OPC_DMODU:
4706        {
4707            TCGv t2 = tcg_const_tl(0);
4708            TCGv t3 = tcg_const_tl(1);
4709            tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
4710            tcg_gen_remu_i64(cpu_gpr[rd], t0, t1);
4711            tcg_temp_free(t3);
4712            tcg_temp_free(t2);
4713        }
4714        break;
4715    case R6_OPC_DMUL:
4716        tcg_gen_mul_i64(cpu_gpr[rd], t0, t1);
4717        break;
4718    case R6_OPC_DMUH:
4719        {
4720            TCGv t2 = tcg_temp_new();
4721            tcg_gen_muls2_i64(t2, cpu_gpr[rd], t0, t1);
4722            tcg_temp_free(t2);
4723        }
4724        break;
4725    case R6_OPC_DMULU:
4726        tcg_gen_mul_i64(cpu_gpr[rd], t0, t1);
4727        break;
4728    case R6_OPC_DMUHU:
4729        {
4730            TCGv t2 = tcg_temp_new();
4731            tcg_gen_mulu2_i64(t2, cpu_gpr[rd], t0, t1);
4732            tcg_temp_free(t2);
4733        }
4734        break;
4735#endif
4736    default:
4737        MIPS_INVAL("r6 mul/div");
4738        generate_exception_end(ctx, EXCP_RI);
4739        goto out;
4740    }
4741 out:
4742    tcg_temp_free(t0);
4743    tcg_temp_free(t1);
4744}
4745
4746static void gen_div1_tx79(DisasContext *ctx, uint32_t opc, int rs, int rt)
4747{
4748    TCGv t0, t1;
4749
4750    t0 = tcg_temp_new();
4751    t1 = tcg_temp_new();
4752
4753    gen_load_gpr(t0, rs);
4754    gen_load_gpr(t1, rt);
4755
4756    switch (opc) {
4757    case MMI_OPC_DIV1:
4758        {
4759            TCGv t2 = tcg_temp_new();
4760            TCGv t3 = tcg_temp_new();
4761            tcg_gen_ext32s_tl(t0, t0);
4762            tcg_gen_ext32s_tl(t1, t1);
4763            tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, INT_MIN);
4764            tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1);
4765            tcg_gen_and_tl(t2, t2, t3);
4766            tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
4767            tcg_gen_or_tl(t2, t2, t3);
4768            tcg_gen_movi_tl(t3, 0);
4769            tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
4770            tcg_gen_div_tl(cpu_LO[1], t0, t1);
4771            tcg_gen_rem_tl(cpu_HI[1], t0, t1);
4772            tcg_gen_ext32s_tl(cpu_LO[1], cpu_LO[1]);
4773            tcg_gen_ext32s_tl(cpu_HI[1], cpu_HI[1]);
4774            tcg_temp_free(t3);
4775            tcg_temp_free(t2);
4776        }
4777        break;
4778    case MMI_OPC_DIVU1:
4779        {
4780            TCGv t2 = tcg_const_tl(0);
4781            TCGv t3 = tcg_const_tl(1);
4782            tcg_gen_ext32u_tl(t0, t0);
4783            tcg_gen_ext32u_tl(t1, t1);
4784            tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
4785            tcg_gen_divu_tl(cpu_LO[1], t0, t1);
4786            tcg_gen_remu_tl(cpu_HI[1], t0, t1);
4787            tcg_gen_ext32s_tl(cpu_LO[1], cpu_LO[1]);
4788            tcg_gen_ext32s_tl(cpu_HI[1], cpu_HI[1]);
4789            tcg_temp_free(t3);
4790            tcg_temp_free(t2);
4791        }
4792        break;
4793    default:
4794        MIPS_INVAL("div1 TX79");
4795        generate_exception_end(ctx, EXCP_RI);
4796        goto out;
4797    }
4798 out:
4799    tcg_temp_free(t0);
4800    tcg_temp_free(t1);
4801}
4802
4803static void gen_muldiv(DisasContext *ctx, uint32_t opc,
4804                       int acc, int rs, int rt)
4805{
4806    TCGv t0, t1;
4807
4808    t0 = tcg_temp_new();
4809    t1 = tcg_temp_new();
4810
4811    gen_load_gpr(t0, rs);
4812    gen_load_gpr(t1, rt);
4813
4814    if (acc != 0) {
4815        check_dsp(ctx);
4816    }
4817
4818    switch (opc) {
4819    case OPC_DIV:
4820        {
4821            TCGv t2 = tcg_temp_new();
4822            TCGv t3 = tcg_temp_new();
4823            tcg_gen_ext32s_tl(t0, t0);
4824            tcg_gen_ext32s_tl(t1, t1);
4825            tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, INT_MIN);
4826            tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1);
4827            tcg_gen_and_tl(t2, t2, t3);
4828            tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
4829            tcg_gen_or_tl(t2, t2, t3);
4830            tcg_gen_movi_tl(t3, 0);
4831            tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
4832            tcg_gen_div_tl(cpu_LO[acc], t0, t1);
4833            tcg_gen_rem_tl(cpu_HI[acc], t0, t1);
4834            tcg_gen_ext32s_tl(cpu_LO[acc], cpu_LO[acc]);
4835            tcg_gen_ext32s_tl(cpu_HI[acc], cpu_HI[acc]);
4836            tcg_temp_free(t3);
4837            tcg_temp_free(t2);
4838        }
4839        break;
4840    case OPC_DIVU:
4841        {
4842            TCGv t2 = tcg_const_tl(0);
4843            TCGv t3 = tcg_const_tl(1);
4844            tcg_gen_ext32u_tl(t0, t0);
4845            tcg_gen_ext32u_tl(t1, t1);
4846            tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
4847            tcg_gen_divu_tl(cpu_LO[acc], t0, t1);
4848            tcg_gen_remu_tl(cpu_HI[acc], t0, t1);
4849            tcg_gen_ext32s_tl(cpu_LO[acc], cpu_LO[acc]);
4850            tcg_gen_ext32s_tl(cpu_HI[acc], cpu_HI[acc]);
4851            tcg_temp_free(t3);
4852            tcg_temp_free(t2);
4853        }
4854        break;
4855    case OPC_MULT:
4856        {
4857            TCGv_i32 t2 = tcg_temp_new_i32();
4858            TCGv_i32 t3 = tcg_temp_new_i32();
4859            tcg_gen_trunc_tl_i32(t2, t0);
4860            tcg_gen_trunc_tl_i32(t3, t1);
4861            tcg_gen_muls2_i32(t2, t3, t2, t3);
4862            tcg_gen_ext_i32_tl(cpu_LO[acc], t2);
4863            tcg_gen_ext_i32_tl(cpu_HI[acc], t3);
4864            tcg_temp_free_i32(t2);
4865            tcg_temp_free_i32(t3);
4866        }
4867        break;
4868    case OPC_MULTU:
4869        {
4870            TCGv_i32 t2 = tcg_temp_new_i32();
4871            TCGv_i32 t3 = tcg_temp_new_i32();
4872            tcg_gen_trunc_tl_i32(t2, t0);
4873            tcg_gen_trunc_tl_i32(t3, t1);
4874            tcg_gen_mulu2_i32(t2, t3, t2, t3);
4875            tcg_gen_ext_i32_tl(cpu_LO[acc], t2);
4876            tcg_gen_ext_i32_tl(cpu_HI[acc], t3);
4877            tcg_temp_free_i32(t2);
4878            tcg_temp_free_i32(t3);
4879        }
4880        break;
4881#if defined(TARGET_MIPS64)
4882    case OPC_DDIV:
4883        {
4884            TCGv t2 = tcg_temp_new();
4885            TCGv t3 = tcg_temp_new();
4886            tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, -1LL << 63);
4887            tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1LL);
4888            tcg_gen_and_tl(t2, t2, t3);
4889            tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
4890            tcg_gen_or_tl(t2, t2, t3);
4891            tcg_gen_movi_tl(t3, 0);
4892            tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
4893            tcg_gen_div_tl(cpu_LO[acc], t0, t1);
4894            tcg_gen_rem_tl(cpu_HI[acc], t0, t1);
4895            tcg_temp_free(t3);
4896            tcg_temp_free(t2);
4897        }
4898        break;
4899    case OPC_DDIVU:
4900        {
4901            TCGv t2 = tcg_const_tl(0);
4902            TCGv t3 = tcg_const_tl(1);
4903            tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
4904            tcg_gen_divu_i64(cpu_LO[acc], t0, t1);
4905            tcg_gen_remu_i64(cpu_HI[acc], t0, t1);
4906            tcg_temp_free(t3);
4907            tcg_temp_free(t2);
4908        }
4909        break;
4910    case OPC_DMULT:
4911        tcg_gen_muls2_i64(cpu_LO[acc], cpu_HI[acc], t0, t1);
4912        break;
4913    case OPC_DMULTU:
4914        tcg_gen_mulu2_i64(cpu_LO[acc], cpu_HI[acc], t0, t1);
4915        break;
4916#endif
4917    case OPC_MADD:
4918        {
4919            TCGv_i64 t2 = tcg_temp_new_i64();
4920            TCGv_i64 t3 = tcg_temp_new_i64();
4921
4922            tcg_gen_ext_tl_i64(t2, t0);
4923            tcg_gen_ext_tl_i64(t3, t1);
4924            tcg_gen_mul_i64(t2, t2, t3);
4925            tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
4926            tcg_gen_add_i64(t2, t2, t3);
4927            tcg_temp_free_i64(t3);
4928            gen_move_low32(cpu_LO[acc], t2);
4929            gen_move_high32(cpu_HI[acc], t2);
4930            tcg_temp_free_i64(t2);
4931        }
4932        break;
4933    case OPC_MADDU:
4934        {
4935            TCGv_i64 t2 = tcg_temp_new_i64();
4936            TCGv_i64 t3 = tcg_temp_new_i64();
4937
4938            tcg_gen_ext32u_tl(t0, t0);
4939            tcg_gen_ext32u_tl(t1, t1);
4940            tcg_gen_extu_tl_i64(t2, t0);
4941            tcg_gen_extu_tl_i64(t3, t1);
4942            tcg_gen_mul_i64(t2, t2, t3);
4943            tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
4944            tcg_gen_add_i64(t2, t2, t3);
4945            tcg_temp_free_i64(t3);
4946            gen_move_low32(cpu_LO[acc], t2);
4947            gen_move_high32(cpu_HI[acc], t2);
4948            tcg_temp_free_i64(t2);
4949        }
4950        break;
4951    case OPC_MSUB:
4952        {
4953            TCGv_i64 t2 = tcg_temp_new_i64();
4954            TCGv_i64 t3 = tcg_temp_new_i64();
4955
4956            tcg_gen_ext_tl_i64(t2, t0);
4957            tcg_gen_ext_tl_i64(t3, t1);
4958            tcg_gen_mul_i64(t2, t2, t3);
4959            tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
4960            tcg_gen_sub_i64(t2, t3, t2);
4961            tcg_temp_free_i64(t3);
4962            gen_move_low32(cpu_LO[acc], t2);
4963            gen_move_high32(cpu_HI[acc], t2);
4964            tcg_temp_free_i64(t2);
4965        }
4966        break;
4967    case OPC_MSUBU:
4968        {
4969            TCGv_i64 t2 = tcg_temp_new_i64();
4970            TCGv_i64 t3 = tcg_temp_new_i64();
4971
4972            tcg_gen_ext32u_tl(t0, t0);
4973            tcg_gen_ext32u_tl(t1, t1);
4974            tcg_gen_extu_tl_i64(t2, t0);
4975            tcg_gen_extu_tl_i64(t3, t1);
4976            tcg_gen_mul_i64(t2, t2, t3);
4977            tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
4978            tcg_gen_sub_i64(t2, t3, t2);
4979            tcg_temp_free_i64(t3);
4980            gen_move_low32(cpu_LO[acc], t2);
4981            gen_move_high32(cpu_HI[acc], t2);
4982            tcg_temp_free_i64(t2);
4983        }
4984        break;
4985    default:
4986        MIPS_INVAL("mul/div");
4987        generate_exception_end(ctx, EXCP_RI);
4988        goto out;
4989    }
4990 out:
4991    tcg_temp_free(t0);
4992    tcg_temp_free(t1);
4993}
4994
4995/*
4996 * These MULT and MULTU instructions implemented in for example the
4997 * Toshiba/Sony R5900 and the Toshiba TX19, TX39 and TX79 core
4998 * architectures are special three-operand variants with the syntax
4999 *
5000 *     MULT[U][1] rd, rs, rt
5001 *
5002 * such that
5003 *
5004 *     (rd, LO, HI) <- rs * rt
5005 *
5006 * where the low-order 32-bits of the result is placed into both the
5007 * GPR rd and the special register LO. The high-order 32-bits of the
5008 * result is placed into the special register HI.
5009 *
5010 * If the GPR rd is omitted in assembly language, it is taken to be 0,
5011 * which is the zero register that always reads as 0.
5012 */
5013static void gen_mul_txx9(DisasContext *ctx, uint32_t opc,
5014                         int rd, int rs, int rt)
5015{
5016    TCGv t0 = tcg_temp_new();
5017    TCGv t1 = tcg_temp_new();
5018    int acc = 0;
5019
5020    gen_load_gpr(t0, rs);
5021    gen_load_gpr(t1, rt);
5022
5023    switch (opc) {
5024    case MMI_OPC_MULT1:
5025        acc = 1;
5026        /* Fall through */
5027    case OPC_MULT:
5028        {
5029            TCGv_i32 t2 = tcg_temp_new_i32();
5030            TCGv_i32 t3 = tcg_temp_new_i32();
5031            tcg_gen_trunc_tl_i32(t2, t0);
5032            tcg_gen_trunc_tl_i32(t3, t1);
5033            tcg_gen_muls2_i32(t2, t3, t2, t3);
5034            if (rd) {
5035                tcg_gen_ext_i32_tl(cpu_gpr[rd], t2);
5036            }
5037            tcg_gen_ext_i32_tl(cpu_LO[acc], t2);
5038            tcg_gen_ext_i32_tl(cpu_HI[acc], t3);
5039            tcg_temp_free_i32(t2);
5040            tcg_temp_free_i32(t3);
5041        }
5042        break;
5043    case MMI_OPC_MULTU1:
5044        acc = 1;
5045        /* Fall through */
5046    case OPC_MULTU:
5047        {
5048            TCGv_i32 t2 = tcg_temp_new_i32();
5049            TCGv_i32 t3 = tcg_temp_new_i32();
5050            tcg_gen_trunc_tl_i32(t2, t0);
5051            tcg_gen_trunc_tl_i32(t3, t1);
5052            tcg_gen_mulu2_i32(t2, t3, t2, t3);
5053            if (rd) {
5054                tcg_gen_ext_i32_tl(cpu_gpr[rd], t2);
5055            }
5056            tcg_gen_ext_i32_tl(cpu_LO[acc], t2);
5057            tcg_gen_ext_i32_tl(cpu_HI[acc], t3);
5058            tcg_temp_free_i32(t2);
5059            tcg_temp_free_i32(t3);
5060        }
5061        break;
5062    default:
5063        MIPS_INVAL("mul TXx9");
5064        generate_exception_end(ctx, EXCP_RI);
5065        goto out;
5066    }
5067
5068 out:
5069    tcg_temp_free(t0);
5070    tcg_temp_free(t1);
5071}
5072
5073static void gen_mul_vr54xx (DisasContext *ctx, uint32_t opc,
5074                            int rd, int rs, int rt)
5075{
5076    TCGv t0 = tcg_temp_new();
5077    TCGv t1 = tcg_temp_new();
5078
5079    gen_load_gpr(t0, rs);
5080    gen_load_gpr(t1, rt);
5081
5082    switch (opc) {
5083    case OPC_VR54XX_MULS:
5084        gen_helper_muls(t0, cpu_env, t0, t1);
5085        break;
5086    case OPC_VR54XX_MULSU:
5087        gen_helper_mulsu(t0, cpu_env, t0, t1);
5088        break;
5089    case OPC_VR54XX_MACC:
5090        gen_helper_macc(t0, cpu_env, t0, t1);
5091        break;
5092    case OPC_VR54XX_MACCU:
5093        gen_helper_maccu(t0, cpu_env, t0, t1);
5094        break;
5095    case OPC_VR54XX_MSAC:
5096        gen_helper_msac(t0, cpu_env, t0, t1);
5097        break;
5098    case OPC_VR54XX_MSACU:
5099        gen_helper_msacu(t0, cpu_env, t0, t1);
5100        break;
5101    case OPC_VR54XX_MULHI:
5102        gen_helper_mulhi(t0, cpu_env, t0, t1);
5103        break;
5104    case OPC_VR54XX_MULHIU:
5105        gen_helper_mulhiu(t0, cpu_env, t0, t1);
5106        break;
5107    case OPC_VR54XX_MULSHI:
5108        gen_helper_mulshi(t0, cpu_env, t0, t1);
5109        break;
5110    case OPC_VR54XX_MULSHIU:
5111        gen_helper_mulshiu(t0, cpu_env, t0, t1);
5112        break;
5113    case OPC_VR54XX_MACCHI:
5114        gen_helper_macchi(t0, cpu_env, t0, t1);
5115        break;
5116    case OPC_VR54XX_MACCHIU:
5117        gen_helper_macchiu(t0, cpu_env, t0, t1);
5118        break;
5119    case OPC_VR54XX_MSACHI:
5120        gen_helper_msachi(t0, cpu_env, t0, t1);
5121        break;
5122    case OPC_VR54XX_MSACHIU:
5123        gen_helper_msachiu(t0, cpu_env, t0, t1);
5124        break;
5125    default:
5126        MIPS_INVAL("mul vr54xx");
5127        generate_exception_end(ctx, EXCP_RI);
5128        goto out;
5129    }
5130    gen_store_gpr(t0, rd);
5131
5132 out:
5133    tcg_temp_free(t0);
5134    tcg_temp_free(t1);
5135}
5136
5137static void gen_cl (DisasContext *ctx, uint32_t opc,
5138                    int rd, int rs)
5139{
5140    TCGv t0;
5141
5142    if (rd == 0) {
5143        /* Treat as NOP. */
5144        return;
5145    }
5146    t0 = cpu_gpr[rd];
5147    gen_load_gpr(t0, rs);
5148
5149    switch (opc) {
5150    case OPC_CLO:
5151    case R6_OPC_CLO:
5152#if defined(TARGET_MIPS64)
5153    case OPC_DCLO:
5154    case R6_OPC_DCLO:
5155#endif
5156        tcg_gen_not_tl(t0, t0);
5157        break;
5158    }
5159
5160    switch (opc) {
5161    case OPC_CLO:
5162    case R6_OPC_CLO:
5163    case OPC_CLZ:
5164    case R6_OPC_CLZ:
5165        tcg_gen_ext32u_tl(t0, t0);
5166        tcg_gen_clzi_tl(t0, t0, TARGET_LONG_BITS);
5167        tcg_gen_subi_tl(t0, t0, TARGET_LONG_BITS - 32);
5168        break;
5169#if defined(TARGET_MIPS64)
5170    case OPC_DCLO:
5171    case R6_OPC_DCLO:
5172    case OPC_DCLZ:
5173    case R6_OPC_DCLZ:
5174        tcg_gen_clzi_i64(t0, t0, 64);
5175        break;
5176#endif
5177    }
5178}
5179
5180/* Godson integer instructions */
5181static void gen_loongson_integer(DisasContext *ctx, uint32_t opc,
5182                                 int rd, int rs, int rt)
5183{
5184    TCGv t0, t1;
5185
5186    if (rd == 0) {
5187        /* Treat as NOP. */
5188        return;
5189    }
5190
5191    switch (opc) {
5192    case OPC_MULT_G_2E:
5193    case OPC_MULT_G_2F:
5194    case OPC_MULTU_G_2E:
5195    case OPC_MULTU_G_2F:
5196#if defined(TARGET_MIPS64)
5197    case OPC_DMULT_G_2E:
5198    case OPC_DMULT_G_2F:
5199    case OPC_DMULTU_G_2E:
5200    case OPC_DMULTU_G_2F:
5201#endif
5202        t0 = tcg_temp_new();
5203        t1 = tcg_temp_new();
5204        break;
5205    default:
5206        t0 = tcg_temp_local_new();
5207        t1 = tcg_temp_local_new();
5208        break;
5209    }
5210
5211    gen_load_gpr(t0, rs);
5212    gen_load_gpr(t1, rt);
5213
5214    switch (opc) {
5215    case OPC_MULT_G_2E:
5216    case OPC_MULT_G_2F:
5217        tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
5218        tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
5219        break;
5220    case OPC_MULTU_G_2E:
5221    case OPC_MULTU_G_2F:
5222        tcg_gen_ext32u_tl(t0, t0);
5223        tcg_gen_ext32u_tl(t1, t1);
5224        tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
5225        tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
5226        break;
5227    case OPC_DIV_G_2E:
5228    case OPC_DIV_G_2F:
5229        {
5230            TCGLabel *l1 = gen_new_label();
5231            TCGLabel *l2 = gen_new_label();
5232            TCGLabel *l3 = gen_new_label();
5233            tcg_gen_ext32s_tl(t0, t0);
5234            tcg_gen_ext32s_tl(t1, t1);
5235            tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
5236            tcg_gen_movi_tl(cpu_gpr[rd], 0);
5237            tcg_gen_br(l3);
5238            gen_set_label(l1);
5239            tcg_gen_brcondi_tl(TCG_COND_NE, t0, INT_MIN, l2);
5240            tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1, l2);
5241            tcg_gen_mov_tl(cpu_gpr[rd], t0);
5242            tcg_gen_br(l3);
5243            gen_set_label(l2);
5244            tcg_gen_div_tl(cpu_gpr[rd], t0, t1);
5245            tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
5246            gen_set_label(l3);
5247        }
5248        break;
5249    case OPC_DIVU_G_2E:
5250    case OPC_DIVU_G_2F:
5251        {
5252            TCGLabel *l1 = gen_new_label();
5253            TCGLabel *l2 = gen_new_label();
5254            tcg_gen_ext32u_tl(t0, t0);
5255            tcg_gen_ext32u_tl(t1, t1);
5256            tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
5257            tcg_gen_movi_tl(cpu_gpr[rd], 0);
5258            tcg_gen_br(l2);
5259            gen_set_label(l1);
5260            tcg_gen_divu_tl(cpu_gpr[rd], t0, t1);
5261            tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
5262            gen_set_label(l2);
5263        }
5264        break;
5265    case OPC_MOD_G_2E:
5266    case OPC_MOD_G_2F:
5267        {
5268            TCGLabel *l1 = gen_new_label();
5269            TCGLabel *l2 = gen_new_label();
5270            TCGLabel *l3 = gen_new_label();
5271            tcg_gen_ext32u_tl(t0, t0);
5272            tcg_gen_ext32u_tl(t1, t1);
5273            tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
5274            tcg_gen_brcondi_tl(TCG_COND_NE, t0, INT_MIN, l2);
5275            tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1, l2);
5276            gen_set_label(l1);
5277            tcg_gen_movi_tl(cpu_gpr[rd], 0);
5278            tcg_gen_br(l3);
5279            gen_set_label(l2);
5280            tcg_gen_rem_tl(cpu_gpr[rd], t0, t1);
5281            tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
5282            gen_set_label(l3);
5283        }
5284        break;
5285    case OPC_MODU_G_2E:
5286    case OPC_MODU_G_2F:
5287        {
5288            TCGLabel *l1 = gen_new_label();
5289            TCGLabel *l2 = gen_new_label();
5290            tcg_gen_ext32u_tl(t0, t0);
5291            tcg_gen_ext32u_tl(t1, t1);
5292            tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
5293            tcg_gen_movi_tl(cpu_gpr[rd], 0);
5294            tcg_gen_br(l2);
5295            gen_set_label(l1);
5296            tcg_gen_remu_tl(cpu_gpr[rd], t0, t1);
5297            tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
5298            gen_set_label(l2);
5299        }
5300        break;
5301#if defined(TARGET_MIPS64)
5302    case OPC_DMULT_G_2E:
5303    case OPC_DMULT_G_2F:
5304        tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
5305        break;
5306    case OPC_DMULTU_G_2E:
5307    case OPC_DMULTU_G_2F:
5308        tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
5309        break;
5310    case OPC_DDIV_G_2E:
5311    case OPC_DDIV_G_2F:
5312        {
5313            TCGLabel *l1 = gen_new_label();
5314            TCGLabel *l2 = gen_new_label();
5315            TCGLabel *l3 = gen_new_label();
5316            tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
5317            tcg_gen_movi_tl(cpu_gpr[rd], 0);
5318            tcg_gen_br(l3);
5319            gen_set_label(l1);
5320            tcg_gen_brcondi_tl(TCG_COND_NE, t0, -1LL << 63, l2);
5321            tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1LL, l2);
5322            tcg_gen_mov_tl(cpu_gpr[rd], t0);
5323            tcg_gen_br(l3);
5324            gen_set_label(l2);
5325            tcg_gen_div_tl(cpu_gpr[rd], t0, t1);
5326            gen_set_label(l3);
5327        }
5328        break;
5329    case OPC_DDIVU_G_2E:
5330    case OPC_DDIVU_G_2F:
5331        {
5332            TCGLabel *l1 = gen_new_label();
5333            TCGLabel *l2 = gen_new_label();
5334            tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
5335            tcg_gen_movi_tl(cpu_gpr[rd], 0);
5336            tcg_gen_br(l2);
5337            gen_set_label(l1);
5338            tcg_gen_divu_tl(cpu_gpr[rd], t0, t1);
5339            gen_set_label(l2);
5340        }
5341        break;
5342    case OPC_DMOD_G_2E:
5343    case OPC_DMOD_G_2F:
5344        {
5345            TCGLabel *l1 = gen_new_label();
5346            TCGLabel *l2 = gen_new_label();
5347            TCGLabel *l3 = gen_new_label();
5348            tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
5349            tcg_gen_brcondi_tl(TCG_COND_NE, t0, -1LL << 63, l2);
5350            tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1LL, l2);
5351            gen_set_label(l1);
5352            tcg_gen_movi_tl(cpu_gpr[rd], 0);
5353            tcg_gen_br(l3);
5354            gen_set_label(l2);
5355            tcg_gen_rem_tl(cpu_gpr[rd], t0, t1);
5356            gen_set_label(l3);
5357        }
5358        break;
5359    case OPC_DMODU_G_2E:
5360    case OPC_DMODU_G_2F:
5361        {
5362            TCGLabel *l1 = gen_new_label();
5363            TCGLabel *l2 = gen_new_label();
5364            tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
5365            tcg_gen_movi_tl(cpu_gpr[rd], 0);
5366            tcg_gen_br(l2);
5367            gen_set_label(l1);
5368            tcg_gen_remu_tl(cpu_gpr[rd], t0, t1);
5369            gen_set_label(l2);
5370        }
5371        break;
5372#endif
5373    }
5374
5375    tcg_temp_free(t0);
5376    tcg_temp_free(t1);
5377}
5378
5379/* Loongson multimedia instructions */
5380static void gen_loongson_multimedia(DisasContext *ctx, int rd, int rs, int rt)
5381{
5382    uint32_t opc, shift_max;
5383    TCGv_i64 t0, t1;
5384
5385    opc = MASK_LMI(ctx->opcode);
5386    switch (opc) {
5387    case OPC_ADD_CP2:
5388    case OPC_SUB_CP2:
5389    case OPC_DADD_CP2:
5390    case OPC_DSUB_CP2:
5391        t0 = tcg_temp_local_new_i64();
5392        t1 = tcg_temp_local_new_i64();
5393        break;
5394    default:
5395        t0 = tcg_temp_new_i64();
5396        t1 = tcg_temp_new_i64();
5397        break;
5398    }
5399
5400    check_cp1_enabled(ctx);
5401    gen_load_fpr64(ctx, t0, rs);
5402    gen_load_fpr64(ctx, t1, rt);
5403
5404#define LMI_HELPER(UP, LO) \
5405    case OPC_##UP: gen_helper_##LO(t0, t0, t1); break
5406#define LMI_HELPER_1(UP, LO) \
5407    case OPC_##UP: gen_helper_##LO(t0, t0); break
5408#define LMI_DIRECT(UP, LO, OP) \
5409    case OPC_##UP: tcg_gen_##OP##_i64(t0, t0, t1); break
5410
5411    switch (opc) {
5412    LMI_HELPER(PADDSH, paddsh);
5413    LMI_HELPER(PADDUSH, paddush);
5414    LMI_HELPER(PADDH, paddh);
5415    LMI_HELPER(PADDW, paddw);
5416    LMI_HELPER(PADDSB, paddsb);
5417    LMI_HELPER(PADDUSB, paddusb);
5418    LMI_HELPER(PADDB, paddb);
5419
5420    LMI_HELPER(PSUBSH, psubsh);
5421    LMI_HELPER(PSUBUSH, psubush);
5422    LMI_HELPER(PSUBH, psubh);
5423    LMI_HELPER(PSUBW, psubw);
5424    LMI_HELPER(PSUBSB, psubsb);
5425    LMI_HELPER(PSUBUSB, psubusb);
5426    LMI_HELPER(PSUBB, psubb);
5427
5428    LMI_HELPER(PSHUFH, pshufh);
5429    LMI_HELPER(PACKSSWH, packsswh);
5430    LMI_HELPER(PACKSSHB, packsshb);
5431    LMI_HELPER(PACKUSHB, packushb);
5432
5433    LMI_HELPER(PUNPCKLHW, punpcklhw);
5434    LMI_HELPER(PUNPCKHHW, punpckhhw);
5435    LMI_HELPER(PUNPCKLBH, punpcklbh);
5436    LMI_HELPER(PUNPCKHBH, punpckhbh);
5437    LMI_HELPER(PUNPCKLWD, punpcklwd);
5438    LMI_HELPER(PUNPCKHWD, punpckhwd);
5439
5440    LMI_HELPER(PAVGH, pavgh);
5441    LMI_HELPER(PAVGB, pavgb);
5442    LMI_HELPER(PMAXSH, pmaxsh);
5443    LMI_HELPER(PMINSH, pminsh);
5444    LMI_HELPER(PMAXUB, pmaxub);
5445    LMI_HELPER(PMINUB, pminub);
5446
5447    LMI_HELPER(PCMPEQW, pcmpeqw);
5448    LMI_HELPER(PCMPGTW, pcmpgtw);
5449    LMI_HELPER(PCMPEQH, pcmpeqh);
5450    LMI_HELPER(PCMPGTH, pcmpgth);
5451    LMI_HELPER(PCMPEQB, pcmpeqb);
5452    LMI_HELPER(PCMPGTB, pcmpgtb);
5453
5454    LMI_HELPER(PSLLW, psllw);
5455    LMI_HELPER(PSLLH, psllh);
5456    LMI_HELPER(PSRLW, psrlw);
5457    LMI_HELPER(PSRLH, psrlh);
5458    LMI_HELPER(PSRAW, psraw);
5459    LMI_HELPER(PSRAH, psrah);
5460
5461    LMI_HELPER(PMULLH, pmullh);
5462    LMI_HELPER(PMULHH, pmulhh);
5463    LMI_HELPER(PMULHUH, pmulhuh);
5464    LMI_HELPER(PMADDHW, pmaddhw);
5465
5466    LMI_HELPER(PASUBUB, pasubub);
5467    LMI_HELPER_1(BIADD, biadd);
5468    LMI_HELPER_1(PMOVMSKB, pmovmskb);
5469
5470    LMI_DIRECT(PADDD, paddd, add);
5471    LMI_DIRECT(PSUBD, psubd, sub);
5472    LMI_DIRECT(XOR_CP2, xor, xor);
5473    LMI_DIRECT(NOR_CP2, nor, nor);
5474    LMI_DIRECT(AND_CP2, and, and);
5475    LMI_DIRECT(OR_CP2, or, or);
5476
5477    case OPC_PANDN:
5478        tcg_gen_andc_i64(t0, t1, t0);
5479        break;
5480
5481    case OPC_PINSRH_0:
5482        tcg_gen_deposit_i64(t0, t0, t1, 0, 16);
5483        break;
5484    case OPC_PINSRH_1:
5485        tcg_gen_deposit_i64(t0, t0, t1, 16, 16);
5486        break;
5487    case OPC_PINSRH_2:
5488        tcg_gen_deposit_i64(t0, t0, t1, 32, 16);
5489        break;
5490    case OPC_PINSRH_3:
5491        tcg_gen_deposit_i64(t0, t0, t1, 48, 16);
5492        break;
5493
5494    case OPC_PEXTRH:
5495        tcg_gen_andi_i64(t1, t1, 3);
5496        tcg_gen_shli_i64(t1, t1, 4);
5497        tcg_gen_shr_i64(t0, t0, t1);
5498        tcg_gen_ext16u_i64(t0, t0);
5499        break;
5500
5501    case OPC_ADDU_CP2:
5502        tcg_gen_add_i64(t0, t0, t1);
5503        tcg_gen_ext32s_i64(t0, t0);
5504        break;
5505    case OPC_SUBU_CP2:
5506        tcg_gen_sub_i64(t0, t0, t1);
5507        tcg_gen_ext32s_i64(t0, t0);
5508        break;
5509
5510    case OPC_SLL_CP2:
5511        shift_max = 32;
5512        goto do_shift;
5513    case OPC_SRL_CP2:
5514        shift_max = 32;
5515        goto do_shift;
5516    case OPC_SRA_CP2:
5517        shift_max = 32;
5518        goto do_shift;
5519    case OPC_DSLL_CP2:
5520        shift_max = 64;
5521        goto do_shift;
5522    case OPC_DSRL_CP2:
5523        shift_max = 64;
5524        goto do_shift;
5525    case OPC_DSRA_CP2:
5526        shift_max = 64;
5527        goto do_shift;
5528    do_shift:
5529        /* Make sure shift count isn't TCG undefined behaviour.  */
5530        tcg_gen_andi_i64(t1, t1, shift_max - 1);
5531
5532        switch (opc) {
5533        case OPC_SLL_CP2:
5534        case OPC_DSLL_CP2:
5535            tcg_gen_shl_i64(t0, t0, t1);
5536            break;
5537        case OPC_SRA_CP2:
5538        case OPC_DSRA_CP2:
5539            /* Since SRA is UndefinedResult without sign-extended inputs,
5540               we can treat SRA and DSRA the same.  */
5541            tcg_gen_sar_i64(t0, t0, t1);
5542            break;
5543        case OPC_SRL_CP2:
5544            /* We want to shift in zeros for SRL; zero-extend first.  */
5545            tcg_gen_ext32u_i64(t0, t0);
5546            /* FALLTHRU */
5547        case OPC_DSRL_CP2:
5548            tcg_gen_shr_i64(t0, t0, t1);
5549            break;
5550        }
5551
5552        if (shift_max == 32) {
5553            tcg_gen_ext32s_i64(t0, t0);
5554        }
5555
5556        /* Shifts larger than MAX produce zero.  */
5557        tcg_gen_setcondi_i64(TCG_COND_LTU, t1, t1, shift_max);
5558        tcg_gen_neg_i64(t1, t1);
5559        tcg_gen_and_i64(t0, t0, t1);
5560        break;
5561
5562    case OPC_ADD_CP2:
5563    case OPC_DADD_CP2:
5564        {
5565            TCGv_i64 t2 = tcg_temp_new_i64();
5566            TCGLabel *lab = gen_new_label();
5567
5568            tcg_gen_mov_i64(t2, t0);
5569            tcg_gen_add_i64(t0, t1, t2);
5570            if (opc == OPC_ADD_CP2) {
5571                tcg_gen_ext32s_i64(t0, t0);
5572            }
5573            tcg_gen_xor_i64(t1, t1, t2);
5574            tcg_gen_xor_i64(t2, t2, t0);
5575            tcg_gen_andc_i64(t1, t2, t1);
5576            tcg_temp_free_i64(t2);
5577            tcg_gen_brcondi_i64(TCG_COND_GE, t1, 0, lab);
5578            generate_exception(ctx, EXCP_OVERFLOW);
5579            gen_set_label(lab);
5580            break;
5581        }
5582
5583    case OPC_SUB_CP2:
5584    case OPC_DSUB_CP2:
5585        {
5586            TCGv_i64 t2 = tcg_temp_new_i64();
5587            TCGLabel *lab = gen_new_label();
5588
5589            tcg_gen_mov_i64(t2, t0);
5590            tcg_gen_sub_i64(t0, t1, t2);
5591            if (opc == OPC_SUB_CP2) {
5592                tcg_gen_ext32s_i64(t0, t0);
5593            }
5594            tcg_gen_xor_i64(t1, t1, t2);
5595            tcg_gen_xor_i64(t2, t2, t0);
5596            tcg_gen_and_i64(t1, t1, t2);
5597            tcg_temp_free_i64(t2);
5598            tcg_gen_brcondi_i64(TCG_COND_GE, t1, 0, lab);
5599            generate_exception(ctx, EXCP_OVERFLOW);
5600            gen_set_label(lab);
5601            break;
5602        }
5603
5604    case OPC_PMULUW:
5605        tcg_gen_ext32u_i64(t0, t0);
5606        tcg_gen_ext32u_i64(t1, t1);
5607        tcg_gen_mul_i64(t0, t0, t1);
5608        break;
5609
5610    case OPC_SEQU_CP2:
5611    case OPC_SEQ_CP2:
5612    case OPC_SLTU_CP2:
5613    case OPC_SLT_CP2:
5614    case OPC_SLEU_CP2:
5615    case OPC_SLE_CP2:
5616        /* ??? Document is unclear: Set FCC[CC].  Does that mean the
5617           FD field is the CC field?  */
5618    default:
5619        MIPS_INVAL("loongson_cp2");
5620        generate_exception_end(ctx, EXCP_RI);
5621        return;
5622    }
5623
5624#undef LMI_HELPER
5625#undef LMI_DIRECT
5626
5627    gen_store_fpr64(ctx, t0, rd);
5628
5629    tcg_temp_free_i64(t0);
5630    tcg_temp_free_i64(t1);
5631}
5632
5633/* Traps */
5634static void gen_trap (DisasContext *ctx, uint32_t opc,
5635                      int rs, int rt, int16_t imm)
5636{
5637    int cond;
5638    TCGv t0 = tcg_temp_new();
5639    TCGv t1 = tcg_temp_new();
5640
5641    cond = 0;
5642    /* Load needed operands */
5643    switch (opc) {
5644    case OPC_TEQ:
5645    case OPC_TGE:
5646    case OPC_TGEU:
5647    case OPC_TLT:
5648    case OPC_TLTU:
5649    case OPC_TNE:
5650        /* Compare two registers */
5651        if (rs != rt) {
5652            gen_load_gpr(t0, rs);
5653            gen_load_gpr(t1, rt);
5654            cond = 1;
5655        }
5656        break;
5657    case OPC_TEQI:
5658    case OPC_TGEI:
5659    case OPC_TGEIU:
5660    case OPC_TLTI:
5661    case OPC_TLTIU:
5662    case OPC_TNEI:
5663        /* Compare register to immediate */
5664        if (rs != 0 || imm != 0) {
5665            gen_load_gpr(t0, rs);
5666            tcg_gen_movi_tl(t1, (int32_t)imm);
5667            cond = 1;
5668        }
5669        break;
5670    }
5671    if (cond == 0) {
5672        switch (opc) {
5673        case OPC_TEQ:   /* rs == rs */
5674        case OPC_TEQI:  /* r0 == 0  */
5675        case OPC_TGE:   /* rs >= rs */
5676        case OPC_TGEI:  /* r0 >= 0  */
5677        case OPC_TGEU:  /* rs >= rs unsigned */
5678        case OPC_TGEIU: /* r0 >= 0  unsigned */
5679            /* Always trap */
5680            generate_exception_end(ctx, EXCP_TRAP);
5681            break;
5682        case OPC_TLT:   /* rs < rs           */
5683        case OPC_TLTI:  /* r0 < 0            */
5684        case OPC_TLTU:  /* rs < rs unsigned  */
5685        case OPC_TLTIU: /* r0 < 0  unsigned  */
5686        case OPC_TNE:   /* rs != rs          */
5687        case OPC_TNEI:  /* r0 != 0           */
5688            /* Never trap: treat as NOP. */
5689            break;
5690        }
5691    } else {
5692        TCGLabel *l1 = gen_new_label();
5693
5694        switch (opc) {
5695        case OPC_TEQ:
5696        case OPC_TEQI:
5697            tcg_gen_brcond_tl(TCG_COND_NE, t0, t1, l1);
5698            break;
5699        case OPC_TGE:
5700        case OPC_TGEI:
5701            tcg_gen_brcond_tl(TCG_COND_LT, t0, t1, l1);
5702            break;
5703        case OPC_TGEU:
5704        case OPC_TGEIU:
5705            tcg_gen_brcond_tl(TCG_COND_LTU, t0, t1, l1);
5706            break;
5707        case OPC_TLT:
5708        case OPC_TLTI:
5709            tcg_gen_brcond_tl(TCG_COND_GE, t0, t1, l1);
5710            break;
5711        case OPC_TLTU:
5712        case OPC_TLTIU:
5713            tcg_gen_brcond_tl(TCG_COND_GEU, t0, t1, l1);
5714            break;
5715        case OPC_TNE:
5716        case OPC_TNEI:
5717            tcg_gen_brcond_tl(TCG_COND_EQ, t0, t1, l1);
5718            break;
5719        }
5720        generate_exception(ctx, EXCP_TRAP);
5721        gen_set_label(l1);
5722    }
5723    tcg_temp_free(t0);
5724    tcg_temp_free(t1);
5725}
5726
5727static inline bool use_goto_tb(DisasContext *ctx, target_ulong dest)
5728{
5729    if (unlikely(ctx->base.singlestep_enabled)) {
5730        return false;
5731    }
5732
5733#ifndef CONFIG_USER_ONLY
5734    return (ctx->base.tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK);
5735#else
5736    return true;
5737#endif
5738}
5739
5740static inline void gen_goto_tb(DisasContext *ctx, int n, target_ulong dest)
5741{
5742    if (use_goto_tb(ctx, dest)) {
5743        tcg_gen_goto_tb(n);
5744        gen_save_pc(dest);
5745        tcg_gen_exit_tb(ctx->base.tb, n);
5746    } else {
5747        gen_save_pc(dest);
5748        if (ctx->base.singlestep_enabled) {
5749            save_cpu_state(ctx, 0);
5750            gen_helper_raise_exception_debug(cpu_env);
5751        }
5752        tcg_gen_lookup_and_goto_ptr();
5753    }
5754}
5755
5756/* Branches (before delay slot) */
5757static void gen_compute_branch (DisasContext *ctx, uint32_t opc,
5758                                int insn_bytes,
5759                                int rs, int rt, int32_t offset,
5760                                int delayslot_size)
5761{
5762    target_ulong btgt = -1;
5763    int blink = 0;
5764    int bcond_compute = 0;
5765    TCGv t0 = tcg_temp_new();
5766    TCGv t1 = tcg_temp_new();
5767
5768    if (ctx->hflags & MIPS_HFLAG_BMASK) {
5769#ifdef MIPS_DEBUG_DISAS
5770        LOG_DISAS("Branch in delay / forbidden slot at PC 0x"
5771                  TARGET_FMT_lx "\n", ctx->base.pc_next);
5772#endif
5773        generate_exception_end(ctx, EXCP_RI);
5774        goto out;
5775    }
5776
5777    /* Load needed operands */
5778    switch (opc) {
5779    case OPC_BEQ:
5780    case OPC_BEQL:
5781    case OPC_BNE:
5782    case OPC_BNEL:
5783        /* Compare two registers */
5784        if (rs != rt) {
5785            gen_load_gpr(t0, rs);
5786            gen_load_gpr(t1, rt);
5787            bcond_compute = 1;
5788        }
5789        btgt = ctx->base.pc_next + insn_bytes + offset;
5790        break;
5791    case OPC_BGEZ:
5792    case OPC_BGEZAL:
5793    case OPC_BGEZALL:
5794    case OPC_BGEZL:
5795    case OPC_BGTZ:
5796    case OPC_BGTZL:
5797    case OPC_BLEZ:
5798    case OPC_BLEZL:
5799    case OPC_BLTZ:
5800    case OPC_BLTZAL:
5801    case OPC_BLTZALL:
5802    case OPC_BLTZL:
5803        /* Compare to zero */
5804        if (rs != 0) {
5805            gen_load_gpr(t0, rs);
5806            bcond_compute = 1;
5807        }
5808        btgt = ctx->base.pc_next + insn_bytes + offset;
5809        break;
5810    case OPC_BPOSGE32:
5811#if defined(TARGET_MIPS64)
5812    case OPC_BPOSGE64:
5813        tcg_gen_andi_tl(t0, cpu_dspctrl, 0x7F);
5814#else
5815        tcg_gen_andi_tl(t0, cpu_dspctrl, 0x3F);
5816#endif
5817        bcond_compute = 1;
5818        btgt = ctx->base.pc_next + insn_bytes + offset;
5819        break;
5820    case OPC_J:
5821    case OPC_JAL:
5822    case OPC_JALX:
5823        /* Jump to immediate */
5824        btgt = ((ctx->base.pc_next + insn_bytes) & (int32_t)0xF0000000) |
5825            (uint32_t)offset;
5826        break;
5827    case OPC_JR:
5828    case OPC_JALR:
5829        /* Jump to register */
5830        if (offset != 0 && offset != 16) {
5831            /* Hint = 0 is JR/JALR, hint 16 is JR.HB/JALR.HB, the
5832               others are reserved. */
5833            MIPS_INVAL("jump hint");
5834            generate_exception_end(ctx, EXCP_RI);
5835            goto out;
5836        }
5837        gen_load_gpr(btarget, rs);
5838        break;
5839    default:
5840        MIPS_INVAL("branch/jump");
5841        generate_exception_end(ctx, EXCP_RI);
5842        goto out;
5843    }
5844    if (bcond_compute == 0) {
5845        /* No condition to be computed */
5846        switch (opc) {
5847        case OPC_BEQ:     /* rx == rx        */
5848        case OPC_BEQL:    /* rx == rx likely */
5849        case OPC_BGEZ:    /* 0 >= 0          */
5850        case OPC_BGEZL:   /* 0 >= 0 likely   */
5851        case OPC_BLEZ:    /* 0 <= 0          */
5852        case OPC_BLEZL:   /* 0 <= 0 likely   */
5853            /* Always take */
5854            ctx->hflags |= MIPS_HFLAG_B;
5855            break;
5856        case OPC_BGEZAL:  /* 0 >= 0          */
5857        case OPC_BGEZALL: /* 0 >= 0 likely   */
5858            /* Always take and link */
5859            blink = 31;
5860            ctx->hflags |= MIPS_HFLAG_B;
5861            break;
5862        case OPC_BNE:     /* rx != rx        */
5863        case OPC_BGTZ:    /* 0 > 0           */
5864        case OPC_BLTZ:    /* 0 < 0           */
5865            /* Treat as NOP. */
5866            goto out;
5867        case OPC_BLTZAL:  /* 0 < 0           */
5868            /* Handle as an unconditional branch to get correct delay
5869               slot checking.  */
5870            blink = 31;
5871            btgt = ctx->base.pc_next + insn_bytes + delayslot_size;
5872            ctx->hflags |= MIPS_HFLAG_B;
5873            break;
5874        case OPC_BLTZALL: /* 0 < 0 likely */
5875            tcg_gen_movi_tl(cpu_gpr[31], ctx->base.pc_next + 8);
5876            /* Skip the instruction in the delay slot */
5877            ctx->base.pc_next += 4;
5878            goto out;
5879        case OPC_BNEL:    /* rx != rx likely */
5880        case OPC_BGTZL:   /* 0 > 0 likely */
5881        case OPC_BLTZL:   /* 0 < 0 likely */
5882            /* Skip the instruction in the delay slot */
5883            ctx->base.pc_next += 4;
5884            goto out;
5885        case OPC_J:
5886            ctx->hflags |= MIPS_HFLAG_B;
5887            break;
5888        case OPC_JALX:
5889            ctx->hflags |= MIPS_HFLAG_BX;
5890            /* Fallthrough */
5891        case OPC_JAL:
5892            blink = 31;
5893            ctx->hflags |= MIPS_HFLAG_B;
5894            break;
5895        case OPC_JR:
5896            ctx->hflags |= MIPS_HFLAG_BR;
5897            break;
5898        case OPC_JALR:
5899            blink = rt;
5900            ctx->hflags |= MIPS_HFLAG_BR;
5901            break;
5902        default:
5903            MIPS_INVAL("branch/jump");
5904            generate_exception_end(ctx, EXCP_RI);
5905            goto out;
5906        }
5907    } else {
5908        switch (opc) {
5909        case OPC_BEQ:
5910            tcg_gen_setcond_tl(TCG_COND_EQ, bcond, t0, t1);
5911            goto not_likely;
5912        case OPC_BEQL:
5913            tcg_gen_setcond_tl(TCG_COND_EQ, bcond, t0, t1);
5914            goto likely;
5915        case OPC_BNE:
5916            tcg_gen_setcond_tl(TCG_COND_NE, bcond, t0, t1);
5917            goto not_likely;
5918        case OPC_BNEL:
5919            tcg_gen_setcond_tl(TCG_COND_NE, bcond, t0, t1);
5920            goto likely;
5921        case OPC_BGEZ:
5922            tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
5923            goto not_likely;
5924        case OPC_BGEZL:
5925            tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
5926            goto likely;
5927        case OPC_BGEZAL:
5928            tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
5929            blink = 31;
5930            goto not_likely;
5931        case OPC_BGEZALL:
5932            tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
5933            blink = 31;
5934            goto likely;
5935        case OPC_BGTZ:
5936            tcg_gen_setcondi_tl(TCG_COND_GT, bcond, t0, 0);
5937            goto not_likely;
5938        case OPC_BGTZL:
5939            tcg_gen_setcondi_tl(TCG_COND_GT, bcond, t0, 0);
5940            goto likely;
5941        case OPC_BLEZ:
5942            tcg_gen_setcondi_tl(TCG_COND_LE, bcond, t0, 0);
5943            goto not_likely;
5944        case OPC_BLEZL:
5945            tcg_gen_setcondi_tl(TCG_COND_LE, bcond, t0, 0);
5946            goto likely;
5947        case OPC_BLTZ:
5948            tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
5949            goto not_likely;
5950        case OPC_BLTZL:
5951            tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
5952            goto likely;
5953        case OPC_BPOSGE32:
5954            tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 32);
5955            goto not_likely;
5956#if defined(TARGET_MIPS64)
5957        case OPC_BPOSGE64:
5958            tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 64);
5959            goto not_likely;
5960#endif
5961        case OPC_BLTZAL:
5962            tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
5963            blink = 31;
5964        not_likely:
5965            ctx->hflags |= MIPS_HFLAG_BC;
5966            break;
5967        case OPC_BLTZALL:
5968            tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
5969            blink = 31;
5970        likely:
5971            ctx->hflags |= MIPS_HFLAG_BL;
5972            break;
5973        default:
5974            MIPS_INVAL("conditional branch/jump");
5975            generate_exception_end(ctx, EXCP_RI);
5976            goto out;
5977        }
5978    }
5979
5980    ctx->btarget = btgt;
5981
5982    switch (delayslot_size) {
5983    case 2:
5984        ctx->hflags |= MIPS_HFLAG_BDS16;
5985        break;
5986    case 4:
5987        ctx->hflags |= MIPS_HFLAG_BDS32;
5988        break;
5989    }
5990
5991    if (blink > 0) {
5992        int post_delay = insn_bytes + delayslot_size;
5993        int lowbit = !!(ctx->hflags & MIPS_HFLAG_M16);
5994
5995        tcg_gen_movi_tl(cpu_gpr[blink],
5996                        ctx->base.pc_next + post_delay + lowbit);
5997    }
5998
5999 out:
6000    if (insn_bytes == 2)
6001        ctx->hflags |= MIPS_HFLAG_B16;
6002    tcg_temp_free(t0);
6003    tcg_temp_free(t1);
6004}
6005
6006
6007/* nanoMIPS Branches */
6008static void gen_compute_branch_nm(DisasContext *ctx, uint32_t opc,
6009                                int insn_bytes,
6010                                int rs, int rt, int32_t offset)
6011{
6012    target_ulong btgt = -1;
6013    int bcond_compute = 0;
6014    TCGv t0 = tcg_temp_new();
6015    TCGv t1 = tcg_temp_new();
6016
6017    /* Load needed operands */
6018    switch (opc) {
6019    case OPC_BEQ:
6020    case OPC_BNE:
6021        /* Compare two registers */
6022        if (rs != rt) {
6023            gen_load_gpr(t0, rs);
6024            gen_load_gpr(t1, rt);
6025            bcond_compute = 1;
6026        }
6027        btgt = ctx->base.pc_next + insn_bytes + offset;
6028        break;
6029    case OPC_BGEZAL:
6030        /* Compare to zero */
6031        if (rs != 0) {
6032            gen_load_gpr(t0, rs);
6033            bcond_compute = 1;
6034        }
6035        btgt = ctx->base.pc_next + insn_bytes + offset;
6036        break;
6037    case OPC_BPOSGE32:
6038        tcg_gen_andi_tl(t0, cpu_dspctrl, 0x3F);
6039        bcond_compute = 1;
6040        btgt = ctx->base.pc_next + insn_bytes + offset;
6041        break;
6042    case OPC_JR:
6043    case OPC_JALR:
6044        /* Jump to register */
6045        if (offset != 0 && offset != 16) {
6046            /* Hint = 0 is JR/JALR, hint 16 is JR.HB/JALR.HB, the
6047               others are reserved. */
6048            MIPS_INVAL("jump hint");
6049            generate_exception_end(ctx, EXCP_RI);
6050            goto out;
6051        }
6052        gen_load_gpr(btarget, rs);
6053        break;
6054    default:
6055        MIPS_INVAL("branch/jump");
6056        generate_exception_end(ctx, EXCP_RI);
6057        goto out;
6058    }
6059    if (bcond_compute == 0) {
6060        /* No condition to be computed */
6061        switch (opc) {
6062        case OPC_BEQ:     /* rx == rx        */
6063            /* Always take */
6064            ctx->hflags |= MIPS_HFLAG_B;
6065            break;
6066        case OPC_BGEZAL:  /* 0 >= 0          */
6067            /* Always take and link */
6068            tcg_gen_movi_tl(cpu_gpr[31],
6069                            ctx->base.pc_next + insn_bytes);
6070            ctx->hflags |= MIPS_HFLAG_B;
6071            break;
6072        case OPC_BNE:     /* rx != rx        */
6073            tcg_gen_movi_tl(cpu_gpr[31], ctx->base.pc_next + 8);
6074            /* Skip the instruction in the delay slot */
6075            ctx->base.pc_next += 4;
6076            goto out;
6077        case OPC_JR:
6078            ctx->hflags |= MIPS_HFLAG_BR;
6079            break;
6080        case OPC_JALR:
6081            if (rt > 0) {
6082                tcg_gen_movi_tl(cpu_gpr[rt],
6083                                ctx->base.pc_next + insn_bytes);
6084            }
6085            ctx->hflags |= MIPS_HFLAG_BR;
6086            break;
6087        default:
6088            MIPS_INVAL("branch/jump");
6089            generate_exception_end(ctx, EXCP_RI);
6090            goto out;
6091        }
6092    } else {
6093        switch (opc) {
6094        case OPC_BEQ:
6095            tcg_gen_setcond_tl(TCG_COND_EQ, bcond, t0, t1);
6096            goto not_likely;
6097        case OPC_BNE:
6098            tcg_gen_setcond_tl(TCG_COND_NE, bcond, t0, t1);
6099            goto not_likely;
6100        case OPC_BGEZAL:
6101            tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
6102            tcg_gen_movi_tl(cpu_gpr[31],
6103                            ctx->base.pc_next + insn_bytes);
6104            goto not_likely;
6105        case OPC_BPOSGE32:
6106            tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 32);
6107        not_likely:
6108            ctx->hflags |= MIPS_HFLAG_BC;
6109            break;
6110        default:
6111            MIPS_INVAL("conditional branch/jump");
6112            generate_exception_end(ctx, EXCP_RI);
6113            goto out;
6114        }
6115    }
6116
6117    ctx->btarget = btgt;
6118
6119 out:
6120    if (insn_bytes == 2) {
6121        ctx->hflags |= MIPS_HFLAG_B16;
6122    }
6123    tcg_temp_free(t0);
6124    tcg_temp_free(t1);
6125}
6126
6127
6128/* special3 bitfield operations */
6129static void gen_bitops (DisasContext *ctx, uint32_t opc, int rt,
6130                        int rs, int lsb, int msb)
6131{
6132    TCGv t0 = tcg_temp_new();
6133    TCGv t1 = tcg_temp_new();
6134
6135    gen_load_gpr(t1, rs);
6136    switch (opc) {
6137    case OPC_EXT:
6138        if (lsb + msb > 31) {
6139            goto fail;
6140        }
6141        if (msb != 31) {
6142            tcg_gen_extract_tl(t0, t1, lsb, msb + 1);
6143        } else {
6144            /* The two checks together imply that lsb == 0,
6145               so this is a simple sign-extension.  */
6146            tcg_gen_ext32s_tl(t0, t1);
6147        }
6148        break;
6149#if defined(TARGET_MIPS64)
6150    case OPC_DEXTU:
6151        lsb += 32;
6152        goto do_dext;
6153    case OPC_DEXTM:
6154        msb += 32;
6155        goto do_dext;
6156    case OPC_DEXT:
6157    do_dext:
6158        if (lsb + msb > 63) {
6159            goto fail;
6160        }
6161        tcg_gen_extract_tl(t0, t1, lsb, msb + 1);
6162        break;
6163#endif
6164    case OPC_INS:
6165        if (lsb > msb) {
6166            goto fail;
6167        }
6168        gen_load_gpr(t0, rt);
6169        tcg_gen_deposit_tl(t0, t0, t1, lsb, msb - lsb + 1);
6170        tcg_gen_ext32s_tl(t0, t0);
6171        break;
6172#if defined(TARGET_MIPS64)
6173    case OPC_DINSU:
6174        lsb += 32;
6175        /* FALLTHRU */
6176    case OPC_DINSM:
6177        msb += 32;
6178        /* FALLTHRU */
6179    case OPC_DINS:
6180        if (lsb > msb) {
6181            goto fail;
6182        }
6183        gen_load_gpr(t0, rt);
6184        tcg_gen_deposit_tl(t0, t0, t1, lsb, msb - lsb + 1);
6185        break;
6186#endif
6187    default:
6188fail:
6189        MIPS_INVAL("bitops");
6190        generate_exception_end(ctx, EXCP_RI);
6191        tcg_temp_free(t0);
6192        tcg_temp_free(t1);
6193        return;
6194    }
6195    gen_store_gpr(t0, rt);
6196    tcg_temp_free(t0);
6197    tcg_temp_free(t1);
6198}
6199
6200static void gen_bshfl (DisasContext *ctx, uint32_t op2, int rt, int rd)
6201{
6202    TCGv t0;
6203
6204    if (rd == 0) {
6205        /* If no destination, treat it as a NOP. */
6206        return;
6207    }
6208
6209    t0 = tcg_temp_new();
6210    gen_load_gpr(t0, rt);
6211    switch (op2) {
6212    case OPC_WSBH:
6213        {
6214            TCGv t1 = tcg_temp_new();
6215            TCGv t2 = tcg_const_tl(0x00FF00FF);
6216
6217            tcg_gen_shri_tl(t1, t0, 8);
6218            tcg_gen_and_tl(t1, t1, t2);
6219            tcg_gen_and_tl(t0, t0, t2);
6220            tcg_gen_shli_tl(t0, t0, 8);
6221            tcg_gen_or_tl(t0, t0, t1);
6222            tcg_temp_free(t2);
6223            tcg_temp_free(t1);
6224            tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
6225        }
6226        break;
6227    case OPC_SEB:
6228        tcg_gen_ext8s_tl(cpu_gpr[rd], t0);
6229        break;
6230    case OPC_SEH:
6231        tcg_gen_ext16s_tl(cpu_gpr[rd], t0);
6232        break;
6233#if defined(TARGET_MIPS64)
6234    case OPC_DSBH:
6235        {
6236            TCGv t1 = tcg_temp_new();
6237            TCGv t2 = tcg_const_tl(0x00FF00FF00FF00FFULL);
6238
6239            tcg_gen_shri_tl(t1, t0, 8);
6240            tcg_gen_and_tl(t1, t1, t2);
6241            tcg_gen_and_tl(t0, t0, t2);
6242            tcg_gen_shli_tl(t0, t0, 8);
6243            tcg_gen_or_tl(cpu_gpr[rd], t0, t1);
6244            tcg_temp_free(t2);
6245            tcg_temp_free(t1);
6246        }
6247        break;
6248    case OPC_DSHD:
6249        {
6250            TCGv t1 = tcg_temp_new();
6251            TCGv t2 = tcg_const_tl(0x0000FFFF0000FFFFULL);
6252
6253            tcg_gen_shri_tl(t1, t0, 16);
6254            tcg_gen_and_tl(t1, t1, t2);
6255            tcg_gen_and_tl(t0, t0, t2);
6256            tcg_gen_shli_tl(t0, t0, 16);
6257            tcg_gen_or_tl(t0, t0, t1);
6258            tcg_gen_shri_tl(t1, t0, 32);
6259            tcg_gen_shli_tl(t0, t0, 32);
6260            tcg_gen_or_tl(cpu_gpr[rd], t0, t1);
6261            tcg_temp_free(t2);
6262            tcg_temp_free(t1);
6263        }
6264        break;
6265#endif
6266    default:
6267        MIPS_INVAL("bsfhl");
6268        generate_exception_end(ctx, EXCP_RI);
6269        tcg_temp_free(t0);
6270        return;
6271    }
6272    tcg_temp_free(t0);
6273}
6274
6275static void gen_lsa(DisasContext *ctx, int opc, int rd, int rs, int rt,
6276                    int imm2)
6277{
6278    TCGv t0;
6279    TCGv t1;
6280    if (rd == 0) {
6281        /* Treat as NOP. */
6282        return;
6283    }
6284    t0 = tcg_temp_new();
6285    t1 = tcg_temp_new();
6286    gen_load_gpr(t0, rs);
6287    gen_load_gpr(t1, rt);
6288    tcg_gen_shli_tl(t0, t0, imm2 + 1);
6289    tcg_gen_add_tl(cpu_gpr[rd], t0, t1);
6290    if (opc == OPC_LSA) {
6291        tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
6292    }
6293
6294    tcg_temp_free(t1);
6295    tcg_temp_free(t0);
6296
6297    return;
6298}
6299
6300static void gen_align_bits(DisasContext *ctx, int wordsz, int rd, int rs,
6301                           int rt, int bits)
6302{
6303    TCGv t0;
6304    if (rd == 0) {
6305        /* Treat as NOP. */
6306        return;
6307    }
6308    t0 = tcg_temp_new();
6309    if (bits == 0 || bits == wordsz) {
6310        if (bits == 0) {
6311            gen_load_gpr(t0, rt);
6312        } else {
6313            gen_load_gpr(t0, rs);
6314        }
6315        switch (wordsz) {
6316        case 32:
6317            tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
6318            break;
6319#if defined(TARGET_MIPS64)
6320        case 64:
6321            tcg_gen_mov_tl(cpu_gpr[rd], t0);
6322            break;
6323#endif
6324        }
6325    } else {
6326        TCGv t1 = tcg_temp_new();
6327        gen_load_gpr(t0, rt);
6328        gen_load_gpr(t1, rs);
6329        switch (wordsz) {
6330        case 32:
6331            {
6332                TCGv_i64 t2 = tcg_temp_new_i64();
6333                tcg_gen_concat_tl_i64(t2, t1, t0);
6334                tcg_gen_shri_i64(t2, t2, 32 - bits);
6335                gen_move_low32(cpu_gpr[rd], t2);
6336                tcg_temp_free_i64(t2);
6337            }
6338            break;
6339#if defined(TARGET_MIPS64)
6340        case 64:
6341            tcg_gen_shli_tl(t0, t0, bits);
6342            tcg_gen_shri_tl(t1, t1, 64 - bits);
6343            tcg_gen_or_tl(cpu_gpr[rd], t1, t0);
6344            break;
6345#endif
6346        }
6347        tcg_temp_free(t1);
6348    }
6349
6350    tcg_temp_free(t0);
6351}
6352
6353static void gen_align(DisasContext *ctx, int wordsz, int rd, int rs, int rt,
6354                      int bp)
6355{
6356    gen_align_bits(ctx, wordsz, rd, rs, rt, bp * 8);
6357}
6358
6359static void gen_ext(DisasContext *ctx, int wordsz, int rd, int rs, int rt,
6360                    int shift)
6361{
6362    gen_align_bits(ctx, wordsz, rd, rs, rt, wordsz - shift);
6363}
6364
6365static void gen_bitswap(DisasContext *ctx, int opc, int rd, int rt)
6366{
6367    TCGv t0;
6368    if (rd == 0) {
6369        /* Treat as NOP. */
6370        return;
6371    }
6372    t0 = tcg_temp_new();
6373    gen_load_gpr(t0, rt);
6374    switch (opc) {
6375    case OPC_BITSWAP:
6376        gen_helper_bitswap(cpu_gpr[rd], t0);
6377        break;
6378#if defined(TARGET_MIPS64)
6379    case OPC_DBITSWAP:
6380        gen_helper_dbitswap(cpu_gpr[rd], t0);
6381        break;
6382#endif
6383    }
6384    tcg_temp_free(t0);
6385}
6386
6387#ifndef CONFIG_USER_ONLY
6388/* CP0 (MMU and control) */
6389static inline void gen_mthc0_entrylo(TCGv arg, target_ulong off)
6390{
6391    TCGv_i64 t0 = tcg_temp_new_i64();
6392    TCGv_i64 t1 = tcg_temp_new_i64();
6393
6394    tcg_gen_ext_tl_i64(t0, arg);
6395    tcg_gen_ld_i64(t1, cpu_env, off);
6396#if defined(TARGET_MIPS64)
6397    tcg_gen_deposit_i64(t1, t1, t0, 30, 32);
6398#else
6399    tcg_gen_concat32_i64(t1, t1, t0);
6400#endif
6401    tcg_gen_st_i64(t1, cpu_env, off);
6402    tcg_temp_free_i64(t1);
6403    tcg_temp_free_i64(t0);
6404}
6405
6406static inline void gen_mthc0_store64(TCGv arg, target_ulong off)
6407{
6408    TCGv_i64 t0 = tcg_temp_new_i64();
6409    TCGv_i64 t1 = tcg_temp_new_i64();
6410
6411    tcg_gen_ext_tl_i64(t0, arg);
6412    tcg_gen_ld_i64(t1, cpu_env, off);
6413    tcg_gen_concat32_i64(t1, t1, t0);
6414    tcg_gen_st_i64(t1, cpu_env, off);
6415    tcg_temp_free_i64(t1);
6416    tcg_temp_free_i64(t0);
6417}
6418
6419static inline void gen_mfhc0_entrylo(TCGv arg, target_ulong off)
6420{
6421    TCGv_i64 t0 = tcg_temp_new_i64();
6422
6423    tcg_gen_ld_i64(t0, cpu_env, off);
6424#if defined(TARGET_MIPS64)
6425    tcg_gen_shri_i64(t0, t0, 30);
6426#else
6427    tcg_gen_shri_i64(t0, t0, 32);
6428#endif
6429    gen_move_low32(arg, t0);
6430    tcg_temp_free_i64(t0);
6431}
6432
6433static inline void gen_mfhc0_load64(TCGv arg, target_ulong off, int shift)
6434{
6435    TCGv_i64 t0 = tcg_temp_new_i64();
6436
6437    tcg_gen_ld_i64(t0, cpu_env, off);
6438    tcg_gen_shri_i64(t0, t0, 32 + shift);
6439    gen_move_low32(arg, t0);
6440    tcg_temp_free_i64(t0);
6441}
6442
6443static inline void gen_mfc0_load32 (TCGv arg, target_ulong off)
6444{
6445    TCGv_i32 t0 = tcg_temp_new_i32();
6446
6447    tcg_gen_ld_i32(t0, cpu_env, off);
6448    tcg_gen_ext_i32_tl(arg, t0);
6449    tcg_temp_free_i32(t0);
6450}
6451
6452static inline void gen_mfc0_load64 (TCGv arg, target_ulong off)
6453{
6454    tcg_gen_ld_tl(arg, cpu_env, off);
6455    tcg_gen_ext32s_tl(arg, arg);
6456}
6457
6458static inline void gen_mtc0_store32 (TCGv arg, target_ulong off)
6459{
6460    TCGv_i32 t0 = tcg_temp_new_i32();
6461
6462    tcg_gen_trunc_tl_i32(t0, arg);
6463    tcg_gen_st_i32(t0, cpu_env, off);
6464    tcg_temp_free_i32(t0);
6465}
6466
6467#define CP0_CHECK(c)                            \
6468    do {                                        \
6469        if (!(c)) {                             \
6470            goto cp0_unimplemented;             \
6471        }                                       \
6472    } while (0)
6473
6474static void gen_mfhc0(DisasContext *ctx, TCGv arg, int reg, int sel)
6475{
6476    const char *rn = "invalid";
6477
6478    switch (reg) {
6479    case 2:
6480        switch (sel) {
6481        case 0:
6482            CP0_CHECK(ctx->hflags & MIPS_HFLAG_ELPA);
6483            gen_mfhc0_entrylo(arg, offsetof(CPUMIPSState, CP0_EntryLo0));
6484            rn = "EntryLo0";
6485            break;
6486        default:
6487            goto cp0_unimplemented;
6488        }
6489        break;
6490    case 3:
6491        switch (sel) {
6492        case 0:
6493            CP0_CHECK(ctx->hflags & MIPS_HFLAG_ELPA);
6494            gen_mfhc0_entrylo(arg, offsetof(CPUMIPSState, CP0_EntryLo1));
6495            rn = "EntryLo1";
6496            break;
6497        default:
6498            goto cp0_unimplemented;
6499        }
6500        break;
6501    case 17:
6502        switch (sel) {
6503        case 0:
6504            gen_mfhc0_load64(arg, offsetof(CPUMIPSState, lladdr),
6505                             ctx->CP0_LLAddr_shift);
6506            rn = "LLAddr";
6507            break;
6508        case 1:
6509            CP0_CHECK(ctx->mrp);
6510            gen_helper_mfhc0_maar(arg, cpu_env);
6511            rn = "MAAR";
6512            break;
6513        default:
6514            goto cp0_unimplemented;
6515        }
6516        break;
6517    case 28:
6518        switch (sel) {
6519        case 0:
6520        case 2:
6521        case 4:
6522        case 6:
6523            gen_mfhc0_load64(arg, offsetof(CPUMIPSState, CP0_TagLo), 0);
6524            rn = "TagLo";
6525            break;
6526        default:
6527            goto cp0_unimplemented;
6528        }
6529        break;
6530    default:
6531        goto cp0_unimplemented;
6532    }
6533    trace_mips_translate_c0("mfhc0", rn, reg, sel);
6534    return;
6535
6536cp0_unimplemented:
6537    qemu_log_mask(LOG_UNIMP, "mfhc0 %s (reg %d sel %d)\n", rn, reg, sel);
6538    tcg_gen_movi_tl(arg, 0);
6539}
6540
6541static void gen_mthc0(DisasContext *ctx, TCGv arg, int reg, int sel)
6542{
6543    const char *rn = "invalid";
6544    uint64_t mask = ctx->PAMask >> 36;
6545
6546    switch (reg) {
6547    case 2:
6548        switch (sel) {
6549        case 0:
6550            CP0_CHECK(ctx->hflags & MIPS_HFLAG_ELPA);
6551            tcg_gen_andi_tl(arg, arg, mask);
6552            gen_mthc0_entrylo(arg, offsetof(CPUMIPSState, CP0_EntryLo0));
6553            rn = "EntryLo0";
6554            break;
6555        default:
6556            goto cp0_unimplemented;
6557        }
6558        break;
6559    case 3:
6560        switch (sel) {
6561        case 0:
6562            CP0_CHECK(ctx->hflags & MIPS_HFLAG_ELPA);
6563            tcg_gen_andi_tl(arg, arg, mask);
6564            gen_mthc0_entrylo(arg, offsetof(CPUMIPSState, CP0_EntryLo1));
6565            rn = "EntryLo1";
6566            break;
6567        default:
6568            goto cp0_unimplemented;
6569        }
6570        break;
6571    case 17:
6572        switch (sel) {
6573        case 0:
6574            /* LLAddr is read-only (the only exception is bit 0 if LLB is
6575               supported); the CP0_LLAddr_rw_bitmask does not seem to be
6576               relevant for modern MIPS cores supporting MTHC0, therefore
6577               treating MTHC0 to LLAddr as NOP. */
6578            rn = "LLAddr";
6579            break;
6580        case 1:
6581            CP0_CHECK(ctx->mrp);
6582            gen_helper_mthc0_maar(cpu_env, arg);
6583            rn = "MAAR";
6584            break;
6585        default:
6586            goto cp0_unimplemented;
6587        }
6588        break;
6589    case 28:
6590        switch (sel) {
6591        case 0:
6592        case 2:
6593        case 4:
6594        case 6:
6595            tcg_gen_andi_tl(arg, arg, mask);
6596            gen_mthc0_store64(arg, offsetof(CPUMIPSState, CP0_TagLo));
6597            rn = "TagLo";
6598            break;
6599        default:
6600            goto cp0_unimplemented;
6601        }
6602        break;
6603    default:
6604        goto cp0_unimplemented;
6605    }
6606    trace_mips_translate_c0("mthc0", rn, reg, sel);
6607
6608cp0_unimplemented:
6609    qemu_log_mask(LOG_UNIMP, "mthc0 %s (reg %d sel %d)\n", rn, reg, sel);
6610}
6611
6612static inline void gen_mfc0_unimplemented(DisasContext *ctx, TCGv arg)
6613{
6614    if (ctx->insn_flags & ISA_MIPS32R6) {
6615        tcg_gen_movi_tl(arg, 0);
6616    } else {
6617        tcg_gen_movi_tl(arg, ~0);
6618    }
6619}
6620
6621static void gen_mfc0(DisasContext *ctx, TCGv arg, int reg, int sel)
6622{
6623    const char *rn = "invalid";
6624
6625    if (sel != 0)
6626        check_insn(ctx, ISA_MIPS32);
6627
6628    switch (reg) {
6629    case 0:
6630        switch (sel) {
6631        case 0:
6632            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Index));
6633            rn = "Index";
6634            break;
6635        case 1:
6636            CP0_CHECK(ctx->insn_flags & ASE_MT);
6637            gen_helper_mfc0_mvpcontrol(arg, cpu_env);
6638            rn = "MVPControl";
6639            break;
6640        case 2:
6641            CP0_CHECK(ctx->insn_flags & ASE_MT);
6642            gen_helper_mfc0_mvpconf0(arg, cpu_env);
6643            rn = "MVPConf0";
6644            break;
6645        case 3:
6646            CP0_CHECK(ctx->insn_flags & ASE_MT);
6647            gen_helper_mfc0_mvpconf1(arg, cpu_env);
6648            rn = "MVPConf1";
6649            break;
6650        case 4:
6651            CP0_CHECK(ctx->vp);
6652            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPControl));
6653            rn = "VPControl";
6654            break;
6655        default:
6656            goto cp0_unimplemented;
6657        }
6658        break;
6659    case 1:
6660        switch (sel) {
6661        case 0:
6662            CP0_CHECK(!(ctx->insn_flags & ISA_MIPS32R6));
6663            gen_helper_mfc0_random(arg, cpu_env);
6664            rn = "Random";
6665            break;
6666        case 1:
6667            CP0_CHECK(ctx->insn_flags & ASE_MT);
6668            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEControl));
6669            rn = "VPEControl";
6670            break;
6671        case 2:
6672            CP0_CHECK(ctx->insn_flags & ASE_MT);
6673            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf0));
6674            rn = "VPEConf0";
6675            break;
6676        case 3:
6677            CP0_CHECK(ctx->insn_flags & ASE_MT);
6678            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf1));
6679            rn = "VPEConf1";
6680            break;
6681        case 4:
6682            CP0_CHECK(ctx->insn_flags & ASE_MT);
6683            gen_mfc0_load64(arg, offsetof(CPUMIPSState, CP0_YQMask));
6684            rn = "YQMask";
6685            break;
6686        case 5:
6687            CP0_CHECK(ctx->insn_flags & ASE_MT);
6688            gen_mfc0_load64(arg, offsetof(CPUMIPSState, CP0_VPESchedule));
6689            rn = "VPESchedule";
6690            break;
6691        case 6:
6692            CP0_CHECK(ctx->insn_flags & ASE_MT);
6693            gen_mfc0_load64(arg, offsetof(CPUMIPSState, CP0_VPEScheFBack));
6694            rn = "VPEScheFBack";
6695            break;
6696        case 7:
6697            CP0_CHECK(ctx->insn_flags & ASE_MT);
6698            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEOpt));
6699            rn = "VPEOpt";
6700            break;
6701        default:
6702            goto cp0_unimplemented;
6703        }
6704        break;
6705    case 2:
6706        switch (sel) {
6707        case 0:
6708            {
6709                TCGv_i64 tmp = tcg_temp_new_i64();
6710                tcg_gen_ld_i64(tmp, cpu_env,
6711                               offsetof(CPUMIPSState, CP0_EntryLo0));
6712#if defined(TARGET_MIPS64)
6713                if (ctx->rxi) {
6714                    /* Move RI/XI fields to bits 31:30 */
6715                    tcg_gen_shri_tl(arg, tmp, CP0EnLo_XI);
6716                    tcg_gen_deposit_tl(tmp, tmp, arg, 30, 2);
6717                }
6718#endif
6719                gen_move_low32(arg, tmp);
6720                tcg_temp_free_i64(tmp);
6721            }
6722            rn = "EntryLo0";
6723            break;
6724        case 1:
6725            CP0_CHECK(ctx->insn_flags & ASE_MT);
6726            gen_helper_mfc0_tcstatus(arg, cpu_env);
6727            rn = "TCStatus";
6728            break;
6729        case 2:
6730            CP0_CHECK(ctx->insn_flags & ASE_MT);
6731            gen_helper_mfc0_tcbind(arg, cpu_env);
6732            rn = "TCBind";
6733            break;
6734        case 3:
6735            CP0_CHECK(ctx->insn_flags & ASE_MT);
6736            gen_helper_mfc0_tcrestart(arg, cpu_env);
6737            rn = "TCRestart";
6738            break;
6739        case 4:
6740            CP0_CHECK(ctx->insn_flags & ASE_MT);
6741            gen_helper_mfc0_tchalt(arg, cpu_env);
6742            rn = "TCHalt";
6743            break;
6744        case 5:
6745            CP0_CHECK(ctx->insn_flags & ASE_MT);
6746            gen_helper_mfc0_tccontext(arg, cpu_env);
6747            rn = "TCContext";
6748            break;
6749        case 6:
6750            CP0_CHECK(ctx->insn_flags & ASE_MT);
6751            gen_helper_mfc0_tcschedule(arg, cpu_env);
6752            rn = "TCSchedule";
6753            break;
6754        case 7:
6755            CP0_CHECK(ctx->insn_flags & ASE_MT);
6756            gen_helper_mfc0_tcschefback(arg, cpu_env);
6757            rn = "TCScheFBack";
6758            break;
6759        default:
6760            goto cp0_unimplemented;
6761        }
6762        break;
6763    case 3:
6764        switch (sel) {
6765        case 0:
6766            {
6767                TCGv_i64 tmp = tcg_temp_new_i64();
6768                tcg_gen_ld_i64(tmp, cpu_env,
6769                               offsetof(CPUMIPSState, CP0_EntryLo1));
6770#if defined(TARGET_MIPS64)
6771                if (ctx->rxi) {
6772                    /* Move RI/XI fields to bits 31:30 */
6773                    tcg_gen_shri_tl(arg, tmp, CP0EnLo_XI);
6774                    tcg_gen_deposit_tl(tmp, tmp, arg, 30, 2);
6775                }
6776#endif
6777                gen_move_low32(arg, tmp);
6778                tcg_temp_free_i64(tmp);
6779            }
6780            rn = "EntryLo1";
6781            break;
6782        case 1:
6783            CP0_CHECK(ctx->vp);
6784            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_GlobalNumber));
6785            rn = "GlobalNumber";
6786            break;
6787        default:
6788            goto cp0_unimplemented;
6789        }
6790        break;
6791    case 4:
6792        switch (sel) {
6793        case 0:
6794            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_Context));
6795            tcg_gen_ext32s_tl(arg, arg);
6796            rn = "Context";
6797            break;
6798        case 1:
6799//            gen_helper_mfc0_contextconfig(arg); /* SmartMIPS ASE */
6800            rn = "ContextConfig";
6801            goto cp0_unimplemented;
6802        case 2:
6803            CP0_CHECK(ctx->ulri);
6804            tcg_gen_ld_tl(arg, cpu_env,
6805                          offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
6806            tcg_gen_ext32s_tl(arg, arg);
6807            rn = "UserLocal";
6808            break;
6809        default:
6810            goto cp0_unimplemented;
6811        }
6812        break;
6813    case 5:
6814        switch (sel) {
6815        case 0:
6816            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageMask));
6817            rn = "PageMask";
6818            break;
6819        case 1:
6820            check_insn(ctx, ISA_MIPS32R2);
6821            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageGrain));
6822            rn = "PageGrain";
6823            break;
6824        case 2:
6825            CP0_CHECK(ctx->sc);
6826            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_SegCtl0));
6827            tcg_gen_ext32s_tl(arg, arg);
6828            rn = "SegCtl0";
6829            break;
6830        case 3:
6831            CP0_CHECK(ctx->sc);
6832            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_SegCtl1));
6833            tcg_gen_ext32s_tl(arg, arg);
6834            rn = "SegCtl1";
6835            break;
6836        case 4:
6837            CP0_CHECK(ctx->sc);
6838            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_SegCtl2));
6839            tcg_gen_ext32s_tl(arg, arg);
6840            rn = "SegCtl2";
6841            break;
6842        case 5:
6843            check_pw(ctx);
6844            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PWBase));
6845            rn = "PWBase";
6846            break;
6847        case 6:
6848            check_pw(ctx);
6849            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PWField));
6850            rn = "PWField";
6851            break;
6852        case 7:
6853            check_pw(ctx);
6854            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PWSize));
6855            rn = "PWSize";
6856            break;
6857        default:
6858            goto cp0_unimplemented;
6859        }
6860        break;
6861    case 6:
6862        switch (sel) {
6863        case 0:
6864            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Wired));
6865            rn = "Wired";
6866            break;
6867        case 1:
6868            check_insn(ctx, ISA_MIPS32R2);
6869            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf0));
6870            rn = "SRSConf0";
6871            break;
6872        case 2:
6873            check_insn(ctx, ISA_MIPS32R2);
6874            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf1));
6875            rn = "SRSConf1";
6876            break;
6877        case 3:
6878            check_insn(ctx, ISA_MIPS32R2);
6879            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf2));
6880            rn = "SRSConf2";
6881            break;
6882        case 4:
6883            check_insn(ctx, ISA_MIPS32R2);
6884            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf3));
6885            rn = "SRSConf3";
6886            break;
6887        case 5:
6888            check_insn(ctx, ISA_MIPS32R2);
6889            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf4));
6890            rn = "SRSConf4";
6891            break;
6892        case 6:
6893            check_pw(ctx);
6894            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PWCtl));
6895            rn = "PWCtl";
6896            break;
6897        default:
6898            goto cp0_unimplemented;
6899        }
6900        break;
6901    case 7:
6902        switch (sel) {
6903        case 0:
6904            check_insn(ctx, ISA_MIPS32R2);
6905            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_HWREna));
6906            rn = "HWREna";
6907            break;
6908        default:
6909            goto cp0_unimplemented;
6910        }
6911        break;
6912    case 8:
6913        switch (sel) {
6914        case 0:
6915            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_BadVAddr));
6916            tcg_gen_ext32s_tl(arg, arg);
6917            rn = "BadVAddr";
6918            break;
6919        case 1:
6920            CP0_CHECK(ctx->bi);
6921            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_BadInstr));
6922            rn = "BadInstr";
6923            break;
6924        case 2:
6925            CP0_CHECK(ctx->bp);
6926            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_BadInstrP));
6927            rn = "BadInstrP";
6928            break;
6929        case 3:
6930            CP0_CHECK(ctx->bi);
6931            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_BadInstrX));
6932            tcg_gen_andi_tl(arg, arg, ~0xffff);
6933            rn = "BadInstrX";
6934            break;
6935       default:
6936            goto cp0_unimplemented;
6937        }
6938        break;
6939    case 9:
6940        switch (sel) {
6941        case 0:
6942            /* Mark as an IO operation because we read the time.  */
6943            if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
6944                gen_io_start();
6945            }
6946            gen_helper_mfc0_count(arg, cpu_env);
6947            if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
6948                gen_io_end();
6949            }
6950            /* Break the TB to be able to take timer interrupts immediately
6951               after reading count. DISAS_STOP isn't sufficient, we need to
6952               ensure we break completely out of translated code.  */
6953            gen_save_pc(ctx->base.pc_next + 4);
6954            ctx->base.is_jmp = DISAS_EXIT;
6955            rn = "Count";
6956            break;
6957        /* 6,7 are implementation dependent */
6958        default:
6959            goto cp0_unimplemented;
6960        }
6961        break;
6962    case 10:
6963        switch (sel) {
6964        case 0:
6965            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryHi));
6966            tcg_gen_ext32s_tl(arg, arg);
6967            rn = "EntryHi";
6968            break;
6969        default:
6970            goto cp0_unimplemented;
6971        }
6972        break;
6973    case 11:
6974        switch (sel) {
6975        case 0:
6976            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Compare));
6977            rn = "Compare";
6978            break;
6979        /* 6,7 are implementation dependent */
6980        default:
6981            goto cp0_unimplemented;
6982        }
6983        break;
6984    case 12:
6985        switch (sel) {
6986        case 0:
6987            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Status));
6988            rn = "Status";
6989            break;
6990        case 1:
6991            check_insn(ctx, ISA_MIPS32R2);
6992            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_IntCtl));
6993            rn = "IntCtl";
6994            break;
6995        case 2:
6996            check_insn(ctx, ISA_MIPS32R2);
6997            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSCtl));
6998            rn = "SRSCtl";
6999            break;
7000        case 3:
7001            check_insn(ctx, ISA_MIPS32R2);
7002            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSMap));
7003            rn = "SRSMap";
7004            break;
7005        default:
7006            goto cp0_unimplemented;
7007       }
7008        break;
7009    case 13:
7010        switch (sel) {
7011        case 0:
7012            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Cause));
7013            rn = "Cause";
7014            break;
7015        default:
7016            goto cp0_unimplemented;
7017       }
7018        break;
7019    case 14:
7020        switch (sel) {
7021        case 0:
7022            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EPC));
7023            tcg_gen_ext32s_tl(arg, arg);
7024            rn = "EPC";
7025            break;
7026        default:
7027            goto cp0_unimplemented;
7028        }
7029        break;
7030    case 15:
7031        switch (sel) {
7032        case 0:
7033            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PRid));
7034            rn = "PRid";
7035            break;
7036        case 1:
7037            check_insn(ctx, ISA_MIPS32R2);
7038            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EBase));
7039            tcg_gen_ext32s_tl(arg, arg);
7040            rn = "EBase";
7041            break;
7042        case 3:
7043            check_insn(ctx, ISA_MIPS32R2);
7044            CP0_CHECK(ctx->cmgcr);
7045            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_CMGCRBase));
7046            tcg_gen_ext32s_tl(arg, arg);
7047            rn = "CMGCRBase";
7048            break;
7049        default:
7050            goto cp0_unimplemented;
7051       }
7052        break;
7053    case 16:
7054        switch (sel) {
7055        case 0:
7056            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config0));
7057            rn = "Config";
7058            break;
7059        case 1:
7060            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config1));
7061            rn = "Config1";
7062            break;
7063        case 2:
7064            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config2));
7065            rn = "Config2";
7066            break;
7067        case 3:
7068            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config3));
7069            rn = "Config3";
7070            break;
7071        case 4:
7072            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config4));
7073            rn = "Config4";
7074            break;
7075        case 5:
7076            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config5));
7077            rn = "Config5";
7078            break;
7079        /* 6,7 are implementation dependent */
7080        case 6:
7081            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config6));
7082            rn = "Config6";
7083            break;
7084        case 7:
7085            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config7));
7086            rn = "Config7";
7087            break;
7088        default:
7089            goto cp0_unimplemented;
7090        }
7091        break;
7092    case 17:
7093        switch (sel) {
7094        case 0:
7095            gen_helper_mfc0_lladdr(arg, cpu_env);
7096            rn = "LLAddr";
7097            break;
7098        case 1:
7099            CP0_CHECK(ctx->mrp);
7100            gen_helper_mfc0_maar(arg, cpu_env);
7101            rn = "MAAR";
7102            break;
7103        case 2:
7104            CP0_CHECK(ctx->mrp);
7105            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_MAARI));
7106            rn = "MAARI";
7107            break;
7108        default:
7109            goto cp0_unimplemented;
7110        }
7111        break;
7112    case 18:
7113        switch (sel) {
7114        case 0:
7115        case 1:
7116        case 2:
7117        case 3:
7118        case 4:
7119        case 5:
7120        case 6:
7121        case 7:
7122            CP0_CHECK(ctx->CP0_Config1 & (1 << CP0C1_WR));
7123            gen_helper_1e0i(mfc0_watchlo, arg, sel);
7124            rn = "WatchLo";
7125            break;
7126        default:
7127            goto cp0_unimplemented;
7128        }
7129        break;
7130    case 19:
7131        switch (sel) {
7132        case 0:
7133        case 1:
7134        case 2:
7135        case 3:
7136        case 4:
7137        case 5:
7138        case 6:
7139        case 7:
7140            CP0_CHECK(ctx->CP0_Config1 & (1 << CP0C1_WR));
7141            gen_helper_1e0i(mfc0_watchhi, arg, sel);
7142            rn = "WatchHi";
7143            break;
7144        default:
7145            goto cp0_unimplemented;
7146        }
7147        break;
7148    case 20:
7149        switch (sel) {
7150        case 0:
7151#if defined(TARGET_MIPS64)
7152            check_insn(ctx, ISA_MIPS3);
7153            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_XContext));
7154            tcg_gen_ext32s_tl(arg, arg);
7155            rn = "XContext";
7156            break;
7157#endif
7158        default:
7159            goto cp0_unimplemented;
7160        }
7161        break;
7162    case 21:
7163       /* Officially reserved, but sel 0 is used for R1x000 framemask */
7164        CP0_CHECK(!(ctx->insn_flags & ISA_MIPS32R6));
7165        switch (sel) {
7166        case 0:
7167            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Framemask));
7168            rn = "Framemask";
7169            break;
7170        default:
7171            goto cp0_unimplemented;
7172        }
7173        break;
7174    case 22:
7175        tcg_gen_movi_tl(arg, 0); /* unimplemented */
7176        rn = "'Diagnostic"; /* implementation dependent */
7177        break;
7178    case 23:
7179        switch (sel) {
7180        case 0:
7181            gen_helper_mfc0_debug(arg, cpu_env); /* EJTAG support */
7182            rn = "Debug";
7183            break;
7184        case 1:
7185//            gen_helper_mfc0_tracecontrol(arg); /* PDtrace support */
7186            rn = "TraceControl";
7187            goto cp0_unimplemented;
7188        case 2:
7189//            gen_helper_mfc0_tracecontrol2(arg); /* PDtrace support */
7190            rn = "TraceControl2";
7191            goto cp0_unimplemented;
7192        case 3:
7193//            gen_helper_mfc0_usertracedata(arg); /* PDtrace support */
7194            rn = "UserTraceData";
7195            goto cp0_unimplemented;
7196        case 4:
7197//            gen_helper_mfc0_tracebpc(arg); /* PDtrace support */
7198            rn = "TraceBPC";
7199            goto cp0_unimplemented;
7200        default:
7201            goto cp0_unimplemented;
7202        }
7203        break;
7204    case 24:
7205        switch (sel) {
7206        case 0:
7207            /* EJTAG support */
7208            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_DEPC));
7209            tcg_gen_ext32s_tl(arg, arg);
7210            rn = "DEPC";
7211            break;
7212        default:
7213            goto cp0_unimplemented;
7214        }
7215        break;
7216    case 25:
7217        switch (sel) {
7218        case 0:
7219            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Performance0));
7220            rn = "Performance0";
7221            break;
7222        case 1:
7223//            gen_helper_mfc0_performance1(arg);
7224            rn = "Performance1";
7225            goto cp0_unimplemented;
7226        case 2:
7227//            gen_helper_mfc0_performance2(arg);
7228            rn = "Performance2";
7229            goto cp0_unimplemented;
7230        case 3:
7231//            gen_helper_mfc0_performance3(arg);
7232            rn = "Performance3";
7233            goto cp0_unimplemented;
7234        case 4:
7235//            gen_helper_mfc0_performance4(arg);
7236            rn = "Performance4";
7237            goto cp0_unimplemented;
7238        case 5:
7239//            gen_helper_mfc0_performance5(arg);
7240            rn = "Performance5";
7241            goto cp0_unimplemented;
7242        case 6:
7243//            gen_helper_mfc0_performance6(arg);
7244            rn = "Performance6";
7245            goto cp0_unimplemented;
7246        case 7:
7247//            gen_helper_mfc0_performance7(arg);
7248            rn = "Performance7";
7249            goto cp0_unimplemented;
7250        default:
7251            goto cp0_unimplemented;
7252        }
7253        break;
7254    case 26:
7255        switch (sel) {
7256        case 0:
7257            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_ErrCtl));
7258            rn = "ErrCtl";
7259            break;
7260        default:
7261            goto cp0_unimplemented;
7262        }
7263        break;
7264    case 27:
7265        switch (sel) {
7266        case 0:
7267        case 1:
7268        case 2:
7269        case 3:
7270            tcg_gen_movi_tl(arg, 0); /* unimplemented */
7271            rn = "CacheErr";
7272            break;
7273        default:
7274            goto cp0_unimplemented;
7275        }
7276        break;
7277    case 28:
7278        switch (sel) {
7279        case 0:
7280        case 2:
7281        case 4:
7282        case 6:
7283            {
7284                TCGv_i64 tmp = tcg_temp_new_i64();
7285                tcg_gen_ld_i64(tmp, cpu_env, offsetof(CPUMIPSState, CP0_TagLo));
7286                gen_move_low32(arg, tmp);
7287                tcg_temp_free_i64(tmp);
7288            }
7289            rn = "TagLo";
7290            break;
7291        case 1:
7292        case 3:
7293        case 5:
7294        case 7:
7295            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataLo));
7296            rn = "DataLo";
7297            break;
7298        default:
7299            goto cp0_unimplemented;
7300        }
7301        break;
7302    case 29:
7303        switch (sel) {
7304        case 0:
7305        case 2:
7306        case 4:
7307        case 6:
7308            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_TagHi));
7309            rn = "TagHi";
7310            break;
7311        case 1:
7312        case 3:
7313        case 5:
7314        case 7:
7315            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataHi));
7316            rn = "DataHi";
7317            break;
7318        default:
7319            goto cp0_unimplemented;
7320        }
7321        break;
7322    case 30:
7323        switch (sel) {
7324        case 0:
7325            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_ErrorEPC));
7326            tcg_gen_ext32s_tl(arg, arg);
7327            rn = "ErrorEPC";
7328            break;
7329        default:
7330            goto cp0_unimplemented;
7331        }
7332        break;
7333    case 31:
7334        switch (sel) {
7335        case 0:
7336            /* EJTAG support */
7337            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DESAVE));
7338            rn = "DESAVE";
7339            break;
7340        case 2:
7341        case 3:
7342        case 4:
7343        case 5:
7344        case 6:
7345        case 7:
7346            CP0_CHECK(ctx->kscrexist & (1 << sel));
7347            tcg_gen_ld_tl(arg, cpu_env,
7348                          offsetof(CPUMIPSState, CP0_KScratch[sel-2]));
7349            tcg_gen_ext32s_tl(arg, arg);
7350            rn = "KScratch";
7351            break;
7352        default:
7353            goto cp0_unimplemented;
7354        }
7355        break;
7356    default:
7357       goto cp0_unimplemented;
7358    }
7359    trace_mips_translate_c0("mfc0", rn, reg, sel);
7360    return;
7361
7362cp0_unimplemented:
7363    qemu_log_mask(LOG_UNIMP, "mfc0 %s (reg %d sel %d)\n", rn, reg, sel);
7364    gen_mfc0_unimplemented(ctx, arg);
7365}
7366
7367static void gen_mtc0(DisasContext *ctx, TCGv arg, int reg, int sel)
7368{
7369    const char *rn = "invalid";
7370
7371    if (sel != 0)
7372        check_insn(ctx, ISA_MIPS32);
7373
7374    if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
7375        gen_io_start();
7376    }
7377
7378    switch (reg) {
7379    case 0:
7380        switch (sel) {
7381        case 0:
7382            gen_helper_mtc0_index(cpu_env, arg);
7383            rn = "Index";
7384            break;
7385        case 1:
7386            CP0_CHECK(ctx->insn_flags & ASE_MT);
7387            gen_helper_mtc0_mvpcontrol(cpu_env, arg);
7388            rn = "MVPControl";
7389            break;
7390        case 2:
7391            CP0_CHECK(ctx->insn_flags & ASE_MT);
7392            /* ignored */
7393            rn = "MVPConf0";
7394            break;
7395        case 3:
7396            CP0_CHECK(ctx->insn_flags & ASE_MT);
7397            /* ignored */
7398            rn = "MVPConf1";
7399            break;
7400        case 4:
7401            CP0_CHECK(ctx->vp);
7402            /* ignored */
7403            rn = "VPControl";
7404            break;
7405        default:
7406            goto cp0_unimplemented;
7407        }
7408        break;
7409    case 1:
7410        switch (sel) {
7411        case 0:
7412            /* ignored */
7413            rn = "Random";
7414            break;
7415        case 1:
7416            CP0_CHECK(ctx->insn_flags & ASE_MT);
7417            gen_helper_mtc0_vpecontrol(cpu_env, arg);
7418            rn = "VPEControl";
7419            break;
7420        case 2:
7421            CP0_CHECK(ctx->insn_flags & ASE_MT);
7422            gen_helper_mtc0_vpeconf0(cpu_env, arg);
7423            rn = "VPEConf0";
7424            break;
7425        case 3:
7426            CP0_CHECK(ctx->insn_flags & ASE_MT);
7427            gen_helper_mtc0_vpeconf1(cpu_env, arg);
7428            rn = "VPEConf1";
7429            break;
7430        case 4:
7431            CP0_CHECK(ctx->insn_flags & ASE_MT);
7432            gen_helper_mtc0_yqmask(cpu_env, arg);
7433            rn = "YQMask";
7434            break;
7435        case 5:
7436            CP0_CHECK(ctx->insn_flags & ASE_MT);
7437            tcg_gen_st_tl(arg, cpu_env,
7438                          offsetof(CPUMIPSState, CP0_VPESchedule));
7439            rn = "VPESchedule";
7440            break;
7441        case 6:
7442            CP0_CHECK(ctx->insn_flags & ASE_MT);
7443            tcg_gen_st_tl(arg, cpu_env,
7444                          offsetof(CPUMIPSState, CP0_VPEScheFBack));
7445            rn = "VPEScheFBack";
7446            break;
7447        case 7:
7448            CP0_CHECK(ctx->insn_flags & ASE_MT);
7449            gen_helper_mtc0_vpeopt(cpu_env, arg);
7450            rn = "VPEOpt";
7451            break;
7452        default:
7453            goto cp0_unimplemented;
7454        }
7455        break;
7456    case 2:
7457        switch (sel) {
7458        case 0:
7459            gen_helper_mtc0_entrylo0(cpu_env, arg);
7460            rn = "EntryLo0";
7461            break;
7462        case 1:
7463            CP0_CHECK(ctx->insn_flags & ASE_MT);
7464            gen_helper_mtc0_tcstatus(cpu_env, arg);
7465            rn = "TCStatus";
7466            break;
7467        case 2:
7468            CP0_CHECK(ctx->insn_flags & ASE_MT);
7469            gen_helper_mtc0_tcbind(cpu_env, arg);
7470            rn = "TCBind";
7471            break;
7472        case 3:
7473            CP0_CHECK(ctx->insn_flags & ASE_MT);
7474            gen_helper_mtc0_tcrestart(cpu_env, arg);
7475            rn = "TCRestart";
7476            break;
7477        case 4:
7478            CP0_CHECK(ctx->insn_flags & ASE_MT);
7479            gen_helper_mtc0_tchalt(cpu_env, arg);
7480            rn = "TCHalt";
7481            break;
7482        case 5:
7483            CP0_CHECK(ctx->insn_flags & ASE_MT);
7484            gen_helper_mtc0_tccontext(cpu_env, arg);
7485            rn = "TCContext";
7486            break;
7487        case 6:
7488            CP0_CHECK(ctx->insn_flags & ASE_MT);
7489            gen_helper_mtc0_tcschedule(cpu_env, arg);
7490            rn = "TCSchedule";
7491            break;
7492        case 7:
7493            CP0_CHECK(ctx->insn_flags & ASE_MT);
7494            gen_helper_mtc0_tcschefback(cpu_env, arg);
7495            rn = "TCScheFBack";
7496            break;
7497        default:
7498            goto cp0_unimplemented;
7499        }
7500        break;
7501    case 3:
7502        switch (sel) {
7503        case 0:
7504            gen_helper_mtc0_entrylo1(cpu_env, arg);
7505            rn = "EntryLo1";
7506            break;
7507        case 1:
7508            CP0_CHECK(ctx->vp);
7509            /* ignored */
7510            rn = "GlobalNumber";
7511            break;
7512        default:
7513            goto cp0_unimplemented;
7514        }
7515        break;
7516    case 4:
7517        switch (sel) {
7518        case 0:
7519            gen_helper_mtc0_context(cpu_env, arg);
7520            rn = "Context";
7521            break;
7522        case 1:
7523//            gen_helper_mtc0_contextconfig(cpu_env, arg); /* SmartMIPS ASE */
7524            rn = "ContextConfig";
7525            goto cp0_unimplemented;
7526        case 2:
7527            CP0_CHECK(ctx->ulri);
7528            tcg_gen_st_tl(arg, cpu_env,
7529                          offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
7530            rn = "UserLocal";
7531            break;
7532        default:
7533            goto cp0_unimplemented;
7534        }
7535        break;
7536    case 5:
7537        switch (sel) {
7538        case 0:
7539            gen_helper_mtc0_pagemask(cpu_env, arg);
7540            rn = "PageMask";
7541            break;
7542        case 1:
7543            check_insn(ctx, ISA_MIPS32R2);
7544            gen_helper_mtc0_pagegrain(cpu_env, arg);
7545            rn = "PageGrain";
7546            ctx->base.is_jmp = DISAS_STOP;
7547            break;
7548        case 2:
7549            CP0_CHECK(ctx->sc);
7550            gen_helper_mtc0_segctl0(cpu_env, arg);
7551            rn = "SegCtl0";
7552            break;
7553        case 3:
7554            CP0_CHECK(ctx->sc);
7555            gen_helper_mtc0_segctl1(cpu_env, arg);
7556            rn = "SegCtl1";
7557            break;
7558        case 4:
7559            CP0_CHECK(ctx->sc);
7560            gen_helper_mtc0_segctl2(cpu_env, arg);
7561            rn = "SegCtl2";
7562            break;
7563        case 5:
7564            check_pw(ctx);
7565            gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_PWBase));
7566            rn = "PWBase";
7567            break;
7568        case 6:
7569            check_pw(ctx);
7570            gen_helper_mtc0_pwfield(cpu_env, arg);
7571            rn = "PWField";
7572            break;
7573        case 7:
7574            check_pw(ctx);
7575            gen_helper_mtc0_pwsize(cpu_env, arg);
7576            rn = "PWSize";
7577            break;
7578        default:
7579            goto cp0_unimplemented;
7580        }
7581        break;
7582    case 6:
7583        switch (sel) {
7584        case 0:
7585            gen_helper_mtc0_wired(cpu_env, arg);
7586            rn = "Wired";
7587            break;
7588        case 1:
7589            check_insn(ctx, ISA_MIPS32R2);
7590            gen_helper_mtc0_srsconf0(cpu_env, arg);
7591            rn = "SRSConf0";
7592            break;
7593        case 2:
7594            check_insn(ctx, ISA_MIPS32R2);
7595            gen_helper_mtc0_srsconf1(cpu_env, arg);
7596            rn = "SRSConf1";
7597            break;
7598        case 3:
7599            check_insn(ctx, ISA_MIPS32R2);
7600            gen_helper_mtc0_srsconf2(cpu_env, arg);
7601            rn = "SRSConf2";
7602            break;
7603        case 4:
7604            check_insn(ctx, ISA_MIPS32R2);
7605            gen_helper_mtc0_srsconf3(cpu_env, arg);
7606            rn = "SRSConf3";
7607            break;
7608        case 5:
7609            check_insn(ctx, ISA_MIPS32R2);
7610            gen_helper_mtc0_srsconf4(cpu_env, arg);
7611            rn = "SRSConf4";
7612            break;
7613        case 6:
7614            check_pw(ctx);
7615            gen_helper_mtc0_pwctl(cpu_env, arg);
7616            rn = "PWCtl";
7617            break;
7618        default:
7619            goto cp0_unimplemented;
7620        }
7621        break;
7622    case 7:
7623        switch (sel) {
7624        case 0:
7625            check_insn(ctx, ISA_MIPS32R2);
7626            gen_helper_mtc0_hwrena(cpu_env, arg);
7627            ctx->base.is_jmp = DISAS_STOP;
7628            rn = "HWREna";
7629            break;
7630        default:
7631            goto cp0_unimplemented;
7632        }
7633        break;
7634    case 8:
7635        switch (sel) {
7636        case 0:
7637            /* ignored */
7638            rn = "BadVAddr";
7639            break;
7640        case 1:
7641            /* ignored */
7642            rn = "BadInstr";
7643            break;
7644        case 2:
7645            /* ignored */
7646            rn = "BadInstrP";
7647            break;
7648        case 3:
7649            /* ignored */
7650            rn = "BadInstrX";
7651            break;
7652        default:
7653            goto cp0_unimplemented;
7654        }
7655        break;
7656    case 9:
7657        switch (sel) {
7658        case 0:
7659            gen_helper_mtc0_count(cpu_env, arg);
7660            rn = "Count";
7661            break;
7662        /* 6,7 are implementation dependent */
7663        default:
7664            goto cp0_unimplemented;
7665        }
7666        break;
7667    case 10:
7668        switch (sel) {
7669        case 0:
7670            gen_helper_mtc0_entryhi(cpu_env, arg);
7671            rn = "EntryHi";
7672            break;
7673        default:
7674            goto cp0_unimplemented;
7675        }
7676        break;
7677    case 11:
7678        switch (sel) {
7679        case 0:
7680            gen_helper_mtc0_compare(cpu_env, arg);
7681            rn = "Compare";
7682            break;
7683        /* 6,7 are implementation dependent */
7684        default:
7685            goto cp0_unimplemented;
7686        }
7687        break;
7688    case 12:
7689        switch (sel) {
7690        case 0:
7691            save_cpu_state(ctx, 1);
7692            gen_helper_mtc0_status(cpu_env, arg);
7693            /* DISAS_STOP isn't good enough here, hflags may have changed. */
7694            gen_save_pc(ctx->base.pc_next + 4);
7695            ctx->base.is_jmp = DISAS_EXIT;
7696            rn = "Status";
7697            break;
7698        case 1:
7699            check_insn(ctx, ISA_MIPS32R2);
7700            gen_helper_mtc0_intctl(cpu_env, arg);
7701            /* Stop translation as we may have switched the execution mode */
7702            ctx->base.is_jmp = DISAS_STOP;
7703            rn = "IntCtl";
7704            break;
7705        case 2:
7706            check_insn(ctx, ISA_MIPS32R2);
7707            gen_helper_mtc0_srsctl(cpu_env, arg);
7708            /* Stop translation as we may have switched the execution mode */
7709            ctx->base.is_jmp = DISAS_STOP;
7710            rn = "SRSCtl";
7711            break;
7712        case 3:
7713            check_insn(ctx, ISA_MIPS32R2);
7714            gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_SRSMap));
7715            /* Stop translation as we may have switched the execution mode */
7716            ctx->base.is_jmp = DISAS_STOP;
7717            rn = "SRSMap";
7718            break;
7719        default:
7720            goto cp0_unimplemented;
7721        }
7722        break;
7723    case 13:
7724        switch (sel) {
7725        case 0:
7726            save_cpu_state(ctx, 1);
7727            gen_helper_mtc0_cause(cpu_env, arg);
7728            /* Stop translation as we may have triggered an interrupt.
7729             * DISAS_STOP isn't sufficient, we need to ensure we break out of
7730             * translated code to check for pending interrupts.  */
7731            gen_save_pc(ctx->base.pc_next + 4);
7732            ctx->base.is_jmp = DISAS_EXIT;
7733            rn = "Cause";
7734            break;
7735        default:
7736            goto cp0_unimplemented;
7737        }
7738        break;
7739    case 14:
7740        switch (sel) {
7741        case 0:
7742            tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EPC));
7743            rn = "EPC";
7744            break;
7745        default:
7746            goto cp0_unimplemented;
7747        }
7748        break;
7749    case 15:
7750        switch (sel) {
7751        case 0:
7752            /* ignored */
7753            rn = "PRid";
7754            break;
7755        case 1:
7756            check_insn(ctx, ISA_MIPS32R2);
7757            gen_helper_mtc0_ebase(cpu_env, arg);
7758            rn = "EBase";
7759            break;
7760        default:
7761            goto cp0_unimplemented;
7762        }
7763        break;
7764    case 16:
7765        switch (sel) {
7766        case 0:
7767            gen_helper_mtc0_config0(cpu_env, arg);
7768            rn = "Config";
7769            /* Stop translation as we may have switched the execution mode */
7770            ctx->base.is_jmp = DISAS_STOP;
7771            break;
7772        case 1:
7773            /* ignored, read only */
7774            rn = "Config1";
7775            break;
7776        case 2:
7777            gen_helper_mtc0_config2(cpu_env, arg);
7778            rn = "Config2";
7779            /* Stop translation as we may have switched the execution mode */
7780            ctx->base.is_jmp = DISAS_STOP;
7781            break;
7782        case 3:
7783            gen_helper_mtc0_config3(cpu_env, arg);
7784            rn = "Config3";
7785            /* Stop translation as we may have switched the execution mode */
7786            ctx->base.is_jmp = DISAS_STOP;
7787            break;
7788        case 4:
7789            gen_helper_mtc0_config4(cpu_env, arg);
7790            rn = "Config4";
7791            ctx->base.is_jmp = DISAS_STOP;
7792            break;
7793        case 5:
7794            gen_helper_mtc0_config5(cpu_env, arg);
7795            rn = "Config5";
7796            /* Stop translation as we may have switched the execution mode */
7797            ctx->base.is_jmp = DISAS_STOP;
7798            break;
7799        /* 6,7 are implementation dependent */
7800        case 6:
7801            /* ignored */
7802            rn = "Config6";
7803            break;
7804        case 7:
7805            /* ignored */
7806            rn = "Config7";
7807            break;
7808        default:
7809            rn = "Invalid config selector";
7810            goto cp0_unimplemented;
7811        }
7812        break;
7813    case 17:
7814        switch (sel) {
7815        case 0:
7816            gen_helper_mtc0_lladdr(cpu_env, arg);
7817            rn = "LLAddr";
7818            break;
7819        case 1:
7820            CP0_CHECK(ctx->mrp);
7821            gen_helper_mtc0_maar(cpu_env, arg);
7822            rn = "MAAR";
7823            break;
7824        case 2:
7825            CP0_CHECK(ctx->mrp);
7826            gen_helper_mtc0_maari(cpu_env, arg);
7827            rn = "MAARI";
7828            break;
7829        default:
7830            goto cp0_unimplemented;
7831        }
7832        break;
7833    case 18:
7834        switch (sel) {
7835        case 0:
7836        case 1:
7837        case 2:
7838        case 3:
7839        case 4:
7840        case 5:
7841        case 6:
7842        case 7:
7843            CP0_CHECK(ctx->CP0_Config1 & (1 << CP0C1_WR));
7844            gen_helper_0e1i(mtc0_watchlo, arg, sel);
7845            rn = "WatchLo";
7846            break;
7847        default:
7848            goto cp0_unimplemented;
7849        }
7850        break;
7851    case 19:
7852        switch (sel) {
7853        case 0:
7854        case 1:
7855        case 2:
7856        case 3:
7857        case 4:
7858        case 5:
7859        case 6:
7860        case 7:
7861            CP0_CHECK(ctx->CP0_Config1 & (1 << CP0C1_WR));
7862            gen_helper_0e1i(mtc0_watchhi, arg, sel);
7863            rn = "WatchHi";
7864            break;
7865        default:
7866            goto cp0_unimplemented;
7867        }
7868        break;
7869    case 20:
7870        switch (sel) {
7871        case 0:
7872#if defined(TARGET_MIPS64)
7873            check_insn(ctx, ISA_MIPS3);
7874            gen_helper_mtc0_xcontext(cpu_env, arg);
7875            rn = "XContext";
7876            break;
7877#endif
7878        default:
7879            goto cp0_unimplemented;
7880        }
7881        break;
7882    case 21:
7883       /* Officially reserved, but sel 0 is used for R1x000 framemask */
7884        CP0_CHECK(!(ctx->insn_flags & ISA_MIPS32R6));
7885        switch (sel) {
7886        case 0:
7887            gen_helper_mtc0_framemask(cpu_env, arg);
7888            rn = "Framemask";
7889            break;
7890        default:
7891            goto cp0_unimplemented;
7892        }
7893        break;
7894    case 22:
7895        /* ignored */
7896        rn = "Diagnostic"; /* implementation dependent */
7897        break;
7898    case 23:
7899        switch (sel) {
7900        case 0:
7901            gen_helper_mtc0_debug(cpu_env, arg); /* EJTAG support */
7902            /* DISAS_STOP isn't good enough here, hflags may have changed. */
7903            gen_save_pc(ctx->base.pc_next + 4);
7904            ctx->base.is_jmp = DISAS_EXIT;
7905            rn = "Debug";
7906            break;
7907        case 1:
7908//            gen_helper_mtc0_tracecontrol(cpu_env, arg); /* PDtrace support */
7909            rn = "TraceControl";
7910            /* Stop translation as we may have switched the execution mode */
7911            ctx->base.is_jmp = DISAS_STOP;
7912            goto cp0_unimplemented;
7913        case 2:
7914//            gen_helper_mtc0_tracecontrol2(cpu_env, arg); /* PDtrace support */
7915            rn = "TraceControl2";
7916            /* Stop translation as we may have switched the execution mode */
7917            ctx->base.is_jmp = DISAS_STOP;
7918            goto cp0_unimplemented;
7919        case 3:
7920            /* Stop translation as we may have switched the execution mode */
7921            ctx->base.is_jmp = DISAS_STOP;
7922//            gen_helper_mtc0_usertracedata(cpu_env, arg); /* PDtrace support */
7923            rn = "UserTraceData";
7924            /* Stop translation as we may have switched the execution mode */
7925            ctx->base.is_jmp = DISAS_STOP;
7926            goto cp0_unimplemented;
7927        case 4:
7928//            gen_helper_mtc0_tracebpc(cpu_env, arg); /* PDtrace support */
7929            /* Stop translation as we may have switched the execution mode */
7930            ctx->base.is_jmp = DISAS_STOP;
7931            rn = "TraceBPC";
7932            goto cp0_unimplemented;
7933        default:
7934            goto cp0_unimplemented;
7935        }
7936        break;
7937    case 24:
7938        switch (sel) {
7939        case 0:
7940            /* EJTAG support */
7941            tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_DEPC));
7942            rn = "DEPC";
7943            break;
7944        default:
7945            goto cp0_unimplemented;
7946        }
7947        break;
7948    case 25:
7949        switch (sel) {
7950        case 0:
7951            gen_helper_mtc0_performance0(cpu_env, arg);
7952            rn = "Performance0";
7953            break;
7954        case 1:
7955//            gen_helper_mtc0_performance1(arg);
7956            rn = "Performance1";
7957            goto cp0_unimplemented;
7958        case 2:
7959//            gen_helper_mtc0_performance2(arg);
7960            rn = "Performance2";
7961            goto cp0_unimplemented;
7962        case 3:
7963//            gen_helper_mtc0_performance3(arg);
7964            rn = "Performance3";
7965            goto cp0_unimplemented;
7966        case 4:
7967//            gen_helper_mtc0_performance4(arg);
7968            rn = "Performance4";
7969            goto cp0_unimplemented;
7970        case 5:
7971//            gen_helper_mtc0_performance5(arg);
7972            rn = "Performance5";
7973            goto cp0_unimplemented;
7974        case 6:
7975//            gen_helper_mtc0_performance6(arg);
7976            rn = "Performance6";
7977            goto cp0_unimplemented;
7978        case 7:
7979//            gen_helper_mtc0_performance7(arg);
7980            rn = "Performance7";
7981            goto cp0_unimplemented;
7982        default:
7983            goto cp0_unimplemented;
7984        }
7985       break;
7986    case 26:
7987        switch (sel) {
7988        case 0:
7989            gen_helper_mtc0_errctl(cpu_env, arg);
7990            ctx->base.is_jmp = DISAS_STOP;
7991            rn = "ErrCtl";
7992            break;
7993        default:
7994            goto cp0_unimplemented;
7995        }
7996        break;
7997    case 27:
7998        switch (sel) {
7999        case 0:
8000        case 1:
8001        case 2:
8002        case 3:
8003            /* ignored */
8004            rn = "CacheErr";
8005            break;
8006        default:
8007            goto cp0_unimplemented;
8008        }
8009       break;
8010    case 28:
8011        switch (sel) {
8012        case 0:
8013        case 2:
8014        case 4:
8015        case 6:
8016            gen_helper_mtc0_taglo(cpu_env, arg);
8017            rn = "TagLo";
8018            break;
8019        case 1:
8020        case 3:
8021        case 5:
8022        case 7:
8023            gen_helper_mtc0_datalo(cpu_env, arg);
8024            rn = "DataLo";
8025            break;
8026        default:
8027            goto cp0_unimplemented;
8028        }
8029        break;
8030    case 29:
8031        switch (sel) {
8032        case 0:
8033        case 2:
8034        case 4:
8035        case 6:
8036            gen_helper_mtc0_taghi(cpu_env, arg);
8037            rn = "TagHi";
8038            break;
8039        case 1:
8040        case 3:
8041        case 5:
8042        case 7:
8043            gen_helper_mtc0_datahi(cpu_env, arg);
8044            rn = "DataHi";
8045            break;
8046        default:
8047            rn = "invalid sel";
8048            goto cp0_unimplemented;
8049        }
8050       break;
8051    case 30:
8052        switch (sel) {
8053        case 0:
8054            tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_ErrorEPC));
8055            rn = "ErrorEPC";
8056            break;
8057        default:
8058            goto cp0_unimplemented;
8059        }
8060        break;
8061    case 31:
8062        switch (sel) {
8063        case 0:
8064            /* EJTAG support */
8065            gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_DESAVE));
8066            rn = "DESAVE";
8067            break;
8068        case 2:
8069        case 3:
8070        case 4:
8071        case 5:
8072        case 6:
8073        case 7:
8074            CP0_CHECK(ctx->kscrexist & (1 << sel));
8075            tcg_gen_st_tl(arg, cpu_env,
8076                          offsetof(CPUMIPSState, CP0_KScratch[sel-2]));
8077            rn = "KScratch";
8078            break;
8079        default:
8080            goto cp0_unimplemented;
8081        }
8082        break;
8083    default:
8084       goto cp0_unimplemented;
8085    }
8086    trace_mips_translate_c0("mtc0", rn, reg, sel);
8087
8088    /* For simplicity assume that all writes can cause interrupts.  */
8089    if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
8090        gen_io_end();
8091        /* DISAS_STOP isn't sufficient, we need to ensure we break out of
8092         * translated code to check for pending interrupts.  */
8093        gen_save_pc(ctx->base.pc_next + 4);
8094        ctx->base.is_jmp = DISAS_EXIT;
8095    }
8096    return;
8097
8098cp0_unimplemented:
8099    qemu_log_mask(LOG_UNIMP, "mtc0 %s (reg %d sel %d)\n", rn, reg, sel);
8100}
8101
8102#if defined(TARGET_MIPS64)
8103static void gen_dmfc0(DisasContext *ctx, TCGv arg, int reg, int sel)
8104{
8105    const char *rn = "invalid";
8106
8107    if (sel != 0)
8108        check_insn(ctx, ISA_MIPS64);
8109
8110    switch (reg) {
8111    case 0:
8112        switch (sel) {
8113        case 0:
8114            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Index));
8115            rn = "Index";
8116            break;
8117        case 1:
8118            CP0_CHECK(ctx->insn_flags & ASE_MT);
8119            gen_helper_mfc0_mvpcontrol(arg, cpu_env);
8120            rn = "MVPControl";
8121            break;
8122        case 2:
8123            CP0_CHECK(ctx->insn_flags & ASE_MT);
8124            gen_helper_mfc0_mvpconf0(arg, cpu_env);
8125            rn = "MVPConf0";
8126            break;
8127        case 3:
8128            CP0_CHECK(ctx->insn_flags & ASE_MT);
8129            gen_helper_mfc0_mvpconf1(arg, cpu_env);
8130            rn = "MVPConf1";
8131            break;
8132        case 4:
8133            CP0_CHECK(ctx->vp);
8134            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPControl));
8135            rn = "VPControl";
8136            break;
8137        default:
8138            goto cp0_unimplemented;
8139        }
8140        break;
8141    case 1:
8142        switch (sel) {
8143        case 0:
8144            CP0_CHECK(!(ctx->insn_flags & ISA_MIPS32R6));
8145            gen_helper_mfc0_random(arg, cpu_env);
8146            rn = "Random";
8147            break;
8148        case 1:
8149            CP0_CHECK(ctx->insn_flags & ASE_MT);
8150            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEControl));
8151            rn = "VPEControl";
8152            break;
8153        case 2:
8154            CP0_CHECK(ctx->insn_flags & ASE_MT);
8155            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf0));
8156            rn = "VPEConf0";
8157            break;
8158        case 3:
8159            CP0_CHECK(ctx->insn_flags & ASE_MT);
8160            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf1));
8161            rn = "VPEConf1";
8162            break;
8163        case 4:
8164            CP0_CHECK(ctx->insn_flags & ASE_MT);
8165            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_YQMask));
8166            rn = "YQMask";
8167            break;
8168        case 5:
8169            CP0_CHECK(ctx->insn_flags & ASE_MT);
8170            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_VPESchedule));
8171            rn = "VPESchedule";
8172            break;
8173        case 6:
8174            CP0_CHECK(ctx->insn_flags & ASE_MT);
8175            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_VPEScheFBack));
8176            rn = "VPEScheFBack";
8177            break;
8178        case 7:
8179            CP0_CHECK(ctx->insn_flags & ASE_MT);
8180            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEOpt));
8181            rn = "VPEOpt";
8182            break;
8183        default:
8184            goto cp0_unimplemented;
8185        }
8186        break;
8187    case 2:
8188        switch (sel) {
8189        case 0:
8190            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryLo0));
8191            rn = "EntryLo0";
8192            break;
8193        case 1:
8194            CP0_CHECK(ctx->insn_flags & ASE_MT);
8195            gen_helper_mfc0_tcstatus(arg, cpu_env);
8196            rn = "TCStatus";
8197            break;
8198        case 2:
8199            CP0_CHECK(ctx->insn_flags & ASE_MT);
8200            gen_helper_mfc0_tcbind(arg, cpu_env);
8201            rn = "TCBind";
8202            break;
8203        case 3:
8204            CP0_CHECK(ctx->insn_flags & ASE_MT);
8205            gen_helper_dmfc0_tcrestart(arg, cpu_env);
8206            rn = "TCRestart";
8207            break;
8208        case 4:
8209            CP0_CHECK(ctx->insn_flags & ASE_MT);
8210            gen_helper_dmfc0_tchalt(arg, cpu_env);
8211            rn = "TCHalt";
8212            break;
8213        case 5:
8214            CP0_CHECK(ctx->insn_flags & ASE_MT);
8215            gen_helper_dmfc0_tccontext(arg, cpu_env);
8216            rn = "TCContext";
8217            break;
8218        case 6:
8219            CP0_CHECK(ctx->insn_flags & ASE_MT);
8220            gen_helper_dmfc0_tcschedule(arg, cpu_env);
8221            rn = "TCSchedule";
8222            break;
8223        case 7:
8224            CP0_CHECK(ctx->insn_flags & ASE_MT);
8225            gen_helper_dmfc0_tcschefback(arg, cpu_env);
8226            rn = "TCScheFBack";
8227            break;
8228        default:
8229            goto cp0_unimplemented;
8230        }
8231        break;
8232    case 3:
8233        switch (sel) {
8234        case 0:
8235            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryLo1));
8236            rn = "EntryLo1";
8237            break;
8238        case 1:
8239            CP0_CHECK(ctx->vp);
8240            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_GlobalNumber));
8241            rn = "GlobalNumber";
8242            break;
8243        default:
8244            goto cp0_unimplemented;
8245        }
8246        break;
8247    case 4:
8248        switch (sel) {
8249        case 0:
8250            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_Context));
8251            rn = "Context";
8252            break;
8253        case 1:
8254//            gen_helper_dmfc0_contextconfig(arg); /* SmartMIPS ASE */
8255            rn = "ContextConfig";
8256            goto cp0_unimplemented;
8257        case 2:
8258            CP0_CHECK(ctx->ulri);
8259            tcg_gen_ld_tl(arg, cpu_env,
8260                          offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
8261            rn = "UserLocal";
8262            break;
8263        default:
8264            goto cp0_unimplemented;
8265        }
8266        break;
8267    case 5:
8268        switch (sel) {
8269        case 0:
8270            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageMask));
8271            rn = "PageMask";
8272            break;
8273        case 1:
8274            check_insn(ctx, ISA_MIPS32R2);
8275            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageGrain));
8276            rn = "PageGrain";
8277            break;
8278        case 2:
8279            CP0_CHECK(ctx->sc);
8280            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_SegCtl0));
8281            rn = "SegCtl0";
8282            break;
8283        case 3:
8284            CP0_CHECK(ctx->sc);
8285            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_SegCtl1));
8286            rn = "SegCtl1";
8287            break;
8288        case 4:
8289            CP0_CHECK(ctx->sc);
8290            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_SegCtl2));
8291            rn = "SegCtl2";
8292            break;
8293        case 5:
8294            check_pw(ctx);
8295            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_PWBase));
8296            rn = "PWBase";
8297            break;
8298        case 6:
8299            check_pw(ctx);
8300            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_PWField));
8301            rn = "PWField";
8302            break;
8303        case 7:
8304            check_pw(ctx);
8305            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_PWSize));
8306            rn = "PWSize";
8307            break;
8308        default:
8309            goto cp0_unimplemented;
8310        }
8311        break;
8312    case 6:
8313        switch (sel) {
8314        case 0:
8315            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Wired));
8316            rn = "Wired";
8317            break;
8318        case 1:
8319            check_insn(ctx, ISA_MIPS32R2);
8320            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf0));
8321            rn = "SRSConf0";
8322            break;
8323        case 2:
8324            check_insn(ctx, ISA_MIPS32R2);
8325            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf1));
8326            rn = "SRSConf1";
8327            break;
8328        case 3:
8329            check_insn(ctx, ISA_MIPS32R2);
8330            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf2));
8331            rn = "SRSConf2";
8332            break;
8333        case 4:
8334            check_insn(ctx, ISA_MIPS32R2);
8335            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf3));
8336            rn = "SRSConf3";
8337            break;
8338        case 5:
8339            check_insn(ctx, ISA_MIPS32R2);
8340            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf4));
8341            rn = "SRSConf4";
8342            break;
8343        case 6:
8344            check_pw(ctx);
8345            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PWCtl));
8346            rn = "PWCtl";
8347            break;
8348        default:
8349            goto cp0_unimplemented;
8350        }
8351        break;
8352    case 7:
8353        switch (sel) {
8354        case 0:
8355            check_insn(ctx, ISA_MIPS32R2);
8356            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_HWREna));
8357            rn = "HWREna";
8358            break;
8359        default:
8360            goto cp0_unimplemented;
8361        }
8362        break;
8363    case 8:
8364        switch (sel) {
8365        case 0:
8366            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_BadVAddr));
8367            rn = "BadVAddr";
8368            break;
8369        case 1:
8370            CP0_CHECK(ctx->bi);
8371            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_BadInstr));
8372            rn = "BadInstr";
8373            break;
8374        case 2:
8375            CP0_CHECK(ctx->bp);
8376            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_BadInstrP));
8377            rn = "BadInstrP";
8378            break;
8379        case 3:
8380            CP0_CHECK(ctx->bi);
8381            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_BadInstrX));
8382            tcg_gen_andi_tl(arg, arg, ~0xffff);
8383            rn = "BadInstrX";
8384            break;
8385        default:
8386            goto cp0_unimplemented;
8387        }
8388        break;
8389    case 9:
8390        switch (sel) {
8391        case 0:
8392            /* Mark as an IO operation because we read the time.  */
8393            if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
8394                gen_io_start();
8395            }
8396            gen_helper_mfc0_count(arg, cpu_env);
8397            if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
8398                gen_io_end();
8399            }
8400            /* Break the TB to be able to take timer interrupts immediately
8401               after reading count. DISAS_STOP isn't sufficient, we need to
8402               ensure we break completely out of translated code.  */
8403            gen_save_pc(ctx->base.pc_next + 4);
8404            ctx->base.is_jmp = DISAS_EXIT;
8405            rn = "Count";
8406            break;
8407        /* 6,7 are implementation dependent */
8408        default:
8409            goto cp0_unimplemented;
8410        }
8411        break;
8412    case 10:
8413        switch (sel) {
8414        case 0:
8415            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryHi));
8416            rn = "EntryHi";
8417            break;
8418        default:
8419            goto cp0_unimplemented;
8420        }
8421        break;
8422    case 11:
8423        switch (sel) {
8424        case 0:
8425            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Compare));
8426            rn = "Compare";
8427            break;
8428        /* 6,7 are implementation dependent */
8429        default:
8430            goto cp0_unimplemented;
8431        }
8432        break;
8433    case 12:
8434        switch (sel) {
8435        case 0:
8436            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Status));
8437            rn = "Status";
8438            break;
8439        case 1:
8440            check_insn(ctx, ISA_MIPS32R2);
8441            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_IntCtl));
8442            rn = "IntCtl";
8443            break;
8444        case 2:
8445            check_insn(ctx, ISA_MIPS32R2);
8446            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSCtl));
8447            rn = "SRSCtl";
8448            break;
8449        case 3:
8450            check_insn(ctx, ISA_MIPS32R2);
8451            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSMap));
8452            rn = "SRSMap";
8453            break;
8454        default:
8455            goto cp0_unimplemented;
8456        }
8457        break;
8458    case 13:
8459        switch (sel) {
8460        case 0:
8461            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Cause));
8462            rn = "Cause";
8463            break;
8464        default:
8465            goto cp0_unimplemented;
8466        }
8467        break;
8468    case 14:
8469        switch (sel) {
8470        case 0:
8471            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EPC));
8472            rn = "EPC";
8473            break;
8474        default:
8475            goto cp0_unimplemented;
8476        }
8477        break;
8478    case 15:
8479        switch (sel) {
8480        case 0:
8481            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PRid));
8482            rn = "PRid";
8483            break;
8484        case 1:
8485            check_insn(ctx, ISA_MIPS32R2);
8486            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EBase));
8487            rn = "EBase";
8488            break;
8489        case 3:
8490            check_insn(ctx, ISA_MIPS32R2);
8491            CP0_CHECK(ctx->cmgcr);
8492            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_CMGCRBase));
8493            rn = "CMGCRBase";
8494            break;
8495        default:
8496            goto cp0_unimplemented;
8497        }
8498        break;
8499    case 16:
8500        switch (sel) {
8501        case 0:
8502            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config0));
8503            rn = "Config";
8504            break;
8505        case 1:
8506            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config1));
8507            rn = "Config1";
8508            break;
8509        case 2:
8510            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config2));
8511            rn = "Config2";
8512            break;
8513        case 3:
8514            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config3));
8515            rn = "Config3";
8516            break;
8517        case 4:
8518            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config4));
8519            rn = "Config4";
8520            break;
8521        case 5:
8522            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config5));
8523            rn = "Config5";
8524            break;
8525       /* 6,7 are implementation dependent */
8526        case 6:
8527            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config6));
8528            rn = "Config6";
8529            break;
8530        case 7:
8531            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config7));
8532            rn = "Config7";
8533            break;
8534        default:
8535            goto cp0_unimplemented;
8536        }
8537        break;
8538    case 17:
8539        switch (sel) {
8540        case 0:
8541            gen_helper_dmfc0_lladdr(arg, cpu_env);
8542            rn = "LLAddr";
8543            break;
8544        case 1:
8545            CP0_CHECK(ctx->mrp);
8546            gen_helper_dmfc0_maar(arg, cpu_env);
8547            rn = "MAAR";
8548            break;
8549        case 2:
8550            CP0_CHECK(ctx->mrp);
8551            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_MAARI));
8552            rn = "MAARI";
8553            break;
8554        default:
8555            goto cp0_unimplemented;
8556        }
8557        break;
8558    case 18:
8559        switch (sel) {
8560        case 0:
8561        case 1:
8562        case 2:
8563        case 3:
8564        case 4:
8565        case 5:
8566        case 6:
8567        case 7:
8568            CP0_CHECK(ctx->CP0_Config1 & (1 << CP0C1_WR));
8569            gen_helper_1e0i(dmfc0_watchlo, arg, sel);
8570            rn = "WatchLo";
8571            break;
8572        default:
8573            goto cp0_unimplemented;
8574        }
8575        break;
8576    case 19:
8577        switch (sel) {
8578        case 0:
8579        case 1:
8580        case 2:
8581        case 3:
8582        case 4:
8583        case 5:
8584        case 6:
8585        case 7:
8586            CP0_CHECK(ctx->CP0_Config1 & (1 << CP0C1_WR));
8587            gen_helper_1e0i(mfc0_watchhi, arg, sel);
8588            rn = "WatchHi";
8589            break;
8590        default:
8591            goto cp0_unimplemented;
8592        }
8593        break;
8594    case 20:
8595        switch (sel) {
8596        case 0:
8597            check_insn(ctx, ISA_MIPS3);
8598            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_XContext));
8599            rn = "XContext";
8600            break;
8601        default:
8602            goto cp0_unimplemented;
8603        }
8604        break;
8605    case 21:
8606       /* Officially reserved, but sel 0 is used for R1x000 framemask */
8607        CP0_CHECK(!(ctx->insn_flags & ISA_MIPS32R6));
8608        switch (sel) {
8609        case 0:
8610            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Framemask));
8611            rn = "Framemask";
8612            break;
8613        default:
8614            goto cp0_unimplemented;
8615        }
8616        break;
8617    case 22:
8618        tcg_gen_movi_tl(arg, 0); /* unimplemented */
8619        rn = "'Diagnostic"; /* implementation dependent */
8620        break;
8621    case 23:
8622        switch (sel) {
8623        case 0:
8624            gen_helper_mfc0_debug(arg, cpu_env); /* EJTAG support */
8625            rn = "Debug";
8626            break;
8627        case 1:
8628//            gen_helper_dmfc0_tracecontrol(arg, cpu_env); /* PDtrace support */
8629            rn = "TraceControl";
8630            goto cp0_unimplemented;
8631        case 2:
8632//            gen_helper_dmfc0_tracecontrol2(arg, cpu_env); /* PDtrace support */
8633            rn = "TraceControl2";
8634            goto cp0_unimplemented;
8635        case 3:
8636//            gen_helper_dmfc0_usertracedata(arg, cpu_env); /* PDtrace support */
8637            rn = "UserTraceData";
8638            goto cp0_unimplemented;
8639        case 4:
8640//            gen_helper_dmfc0_tracebpc(arg, cpu_env); /* PDtrace support */
8641            rn = "TraceBPC";
8642            goto cp0_unimplemented;
8643        default:
8644            goto cp0_unimplemented;
8645        }
8646        break;
8647    case 24:
8648        switch (sel) {
8649        case 0:
8650            /* EJTAG support */
8651            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_DEPC));
8652            rn = "DEPC";
8653            break;
8654        default:
8655            goto cp0_unimplemented;
8656        }
8657        break;
8658    case 25:
8659        switch (sel) {
8660        case 0:
8661            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Performance0));
8662            rn = "Performance0";
8663            break;
8664        case 1:
8665//            gen_helper_dmfc0_performance1(arg);
8666            rn = "Performance1";
8667            goto cp0_unimplemented;
8668        case 2:
8669//            gen_helper_dmfc0_performance2(arg);
8670            rn = "Performance2";
8671            goto cp0_unimplemented;
8672        case 3:
8673//            gen_helper_dmfc0_performance3(arg);
8674            rn = "Performance3";
8675            goto cp0_unimplemented;
8676        case 4:
8677//            gen_helper_dmfc0_performance4(arg);
8678            rn = "Performance4";
8679            goto cp0_unimplemented;
8680        case 5:
8681//            gen_helper_dmfc0_performance5(arg);
8682            rn = "Performance5";
8683            goto cp0_unimplemented;
8684        case 6:
8685//            gen_helper_dmfc0_performance6(arg);
8686            rn = "Performance6";
8687            goto cp0_unimplemented;
8688        case 7:
8689//            gen_helper_dmfc0_performance7(arg);
8690            rn = "Performance7";
8691            goto cp0_unimplemented;
8692        default:
8693            goto cp0_unimplemented;
8694        }
8695        break;
8696    case 26:
8697        switch (sel) {
8698        case 0:
8699            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_ErrCtl));
8700            rn = "ErrCtl";
8701            break;
8702        default:
8703            goto cp0_unimplemented;
8704        }
8705        break;
8706    case 27:
8707        switch (sel) {
8708        /* ignored */
8709        case 0:
8710        case 1:
8711        case 2:
8712        case 3:
8713            tcg_gen_movi_tl(arg, 0); /* unimplemented */
8714            rn = "CacheErr";
8715            break;
8716        default:
8717            goto cp0_unimplemented;
8718        }
8719        break;
8720    case 28:
8721        switch (sel) {
8722        case 0:
8723        case 2:
8724        case 4:
8725        case 6:
8726            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_TagLo));
8727            rn = "TagLo";
8728            break;
8729        case 1:
8730        case 3:
8731        case 5:
8732        case 7:
8733            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataLo));
8734            rn = "DataLo";
8735            break;
8736        default:
8737            goto cp0_unimplemented;
8738        }
8739        break;
8740    case 29:
8741        switch (sel) {
8742        case 0:
8743        case 2:
8744        case 4:
8745        case 6:
8746            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_TagHi));
8747            rn = "TagHi";
8748            break;
8749        case 1:
8750        case 3:
8751        case 5:
8752        case 7:
8753            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataHi));
8754            rn = "DataHi";
8755            break;
8756        default:
8757            goto cp0_unimplemented;
8758        }
8759        break;
8760    case 30:
8761        switch (sel) {
8762        case 0:
8763            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_ErrorEPC));
8764            rn = "ErrorEPC";
8765            break;
8766        default:
8767            goto cp0_unimplemented;
8768        }
8769        break;
8770    case 31:
8771        switch (sel) {
8772        case 0:
8773            /* EJTAG support */
8774            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DESAVE));
8775            rn = "DESAVE";
8776            break;
8777        case 2:
8778        case 3:
8779        case 4:
8780        case 5:
8781        case 6:
8782        case 7:
8783            CP0_CHECK(ctx->kscrexist & (1 << sel));
8784            tcg_gen_ld_tl(arg, cpu_env,
8785                          offsetof(CPUMIPSState, CP0_KScratch[sel-2]));
8786            rn = "KScratch";
8787            break;
8788        default:
8789            goto cp0_unimplemented;
8790        }
8791        break;
8792    default:
8793        goto cp0_unimplemented;
8794    }
8795    trace_mips_translate_c0("dmfc0", rn, reg, sel);
8796    return;
8797
8798cp0_unimplemented:
8799    qemu_log_mask(LOG_UNIMP, "dmfc0 %s (reg %d sel %d)\n", rn, reg, sel);
8800    gen_mfc0_unimplemented(ctx, arg);
8801}
8802
8803static void gen_dmtc0(DisasContext *ctx, TCGv arg, int reg, int sel)
8804{
8805    const char *rn = "invalid";
8806
8807    if (sel != 0)
8808        check_insn(ctx, ISA_MIPS64);
8809
8810    if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
8811        gen_io_start();
8812    }
8813
8814    switch (reg) {
8815    case 0:
8816        switch (sel) {
8817        case 0:
8818            gen_helper_mtc0_index(cpu_env, arg);
8819            rn = "Index";
8820            break;
8821        case 1:
8822            CP0_CHECK(ctx->insn_flags & ASE_MT);
8823            gen_helper_mtc0_mvpcontrol(cpu_env, arg);
8824            rn = "MVPControl";
8825            break;
8826        case 2:
8827            CP0_CHECK(ctx->insn_flags & ASE_MT);
8828            /* ignored */
8829            rn = "MVPConf0";
8830            break;
8831        case 3:
8832            CP0_CHECK(ctx->insn_flags & ASE_MT);
8833            /* ignored */
8834            rn = "MVPConf1";
8835            break;
8836        case 4:
8837            CP0_CHECK(ctx->vp);
8838            /* ignored */
8839            rn = "VPControl";
8840            break;
8841        default:
8842            goto cp0_unimplemented;
8843        }
8844        break;
8845    case 1:
8846        switch (sel) {
8847        case 0:
8848            /* ignored */
8849            rn = "Random";
8850            break;
8851        case 1:
8852            CP0_CHECK(ctx->insn_flags & ASE_MT);
8853            gen_helper_mtc0_vpecontrol(cpu_env, arg);
8854            rn = "VPEControl";
8855            break;
8856        case 2:
8857            CP0_CHECK(ctx->insn_flags & ASE_MT);
8858            gen_helper_mtc0_vpeconf0(cpu_env, arg);
8859            rn = "VPEConf0";
8860            break;
8861        case 3:
8862            CP0_CHECK(ctx->insn_flags & ASE_MT);
8863            gen_helper_mtc0_vpeconf1(cpu_env, arg);
8864            rn = "VPEConf1";
8865            break;
8866        case 4:
8867            CP0_CHECK(ctx->insn_flags & ASE_MT);
8868            gen_helper_mtc0_yqmask(cpu_env, arg);
8869            rn = "YQMask";
8870            break;
8871        case 5:
8872            CP0_CHECK(ctx->insn_flags & ASE_MT);
8873            tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_VPESchedule));
8874            rn = "VPESchedule";
8875            break;
8876        case 6:
8877            CP0_CHECK(ctx->insn_flags & ASE_MT);
8878            tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_VPEScheFBack));
8879            rn = "VPEScheFBack";
8880            break;
8881        case 7:
8882            CP0_CHECK(ctx->insn_flags & ASE_MT);
8883            gen_helper_mtc0_vpeopt(cpu_env, arg);
8884            rn = "VPEOpt";
8885            break;
8886        default:
8887            goto cp0_unimplemented;
8888        }
8889        break;
8890    case 2:
8891        switch (sel) {
8892        case 0:
8893            gen_helper_dmtc0_entrylo0(cpu_env, arg);
8894            rn = "EntryLo0";
8895            break;
8896        case 1:
8897            CP0_CHECK(ctx->insn_flags & ASE_MT);
8898            gen_helper_mtc0_tcstatus(cpu_env, arg);
8899            rn = "TCStatus";
8900            break;
8901        case 2:
8902            CP0_CHECK(ctx->insn_flags & ASE_MT);
8903            gen_helper_mtc0_tcbind(cpu_env, arg);
8904            rn = "TCBind";
8905            break;
8906        case 3:
8907            CP0_CHECK(ctx->insn_flags & ASE_MT);
8908            gen_helper_mtc0_tcrestart(cpu_env, arg);
8909            rn = "TCRestart";
8910            break;
8911        case 4:
8912            CP0_CHECK(ctx->insn_flags & ASE_MT);
8913            gen_helper_mtc0_tchalt(cpu_env, arg);
8914            rn = "TCHalt";
8915            break;
8916        case 5:
8917            CP0_CHECK(ctx->insn_flags & ASE_MT);
8918            gen_helper_mtc0_tccontext(cpu_env, arg);
8919            rn = "TCContext";
8920            break;
8921        case 6:
8922            CP0_CHECK(ctx->insn_flags & ASE_MT);
8923            gen_helper_mtc0_tcschedule(cpu_env, arg);
8924            rn = "TCSchedule";
8925            break;
8926        case 7:
8927            CP0_CHECK(ctx->insn_flags & ASE_MT);
8928            gen_helper_mtc0_tcschefback(cpu_env, arg);
8929            rn = "TCScheFBack";
8930            break;
8931        default:
8932            goto cp0_unimplemented;
8933        }
8934        break;
8935    case 3:
8936        switch (sel) {
8937        case 0:
8938            gen_helper_dmtc0_entrylo1(cpu_env, arg);
8939            rn = "EntryLo1";
8940            break;
8941        case 1:
8942            CP0_CHECK(ctx->vp);
8943            /* ignored */
8944            rn = "GlobalNumber";
8945            break;
8946        default:
8947            goto cp0_unimplemented;
8948        }
8949        break;
8950    case 4:
8951        switch (sel) {
8952        case 0:
8953            gen_helper_mtc0_context(cpu_env, arg);
8954            rn = "Context";
8955            break;
8956        case 1:
8957//           gen_helper_mtc0_contextconfig(cpu_env, arg); /* SmartMIPS ASE */
8958            rn = "ContextConfig";
8959            goto cp0_unimplemented;
8960        case 2:
8961            CP0_CHECK(ctx->ulri);
8962            tcg_gen_st_tl(arg, cpu_env,
8963                          offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
8964            rn = "UserLocal";
8965            break;
8966        default:
8967            goto cp0_unimplemented;
8968        }
8969        break;
8970    case 5:
8971        switch (sel) {
8972        case 0:
8973            gen_helper_mtc0_pagemask(cpu_env, arg);
8974            rn = "PageMask";
8975            break;
8976        case 1:
8977            check_insn(ctx, ISA_MIPS32R2);
8978            gen_helper_mtc0_pagegrain(cpu_env, arg);
8979            rn = "PageGrain";
8980            break;
8981        case 2:
8982            CP0_CHECK(ctx->sc);
8983            gen_helper_mtc0_segctl0(cpu_env, arg);
8984            rn = "SegCtl0";
8985            break;
8986        case 3:
8987            CP0_CHECK(ctx->sc);
8988            gen_helper_mtc0_segctl1(cpu_env, arg);
8989            rn = "SegCtl1";
8990            break;
8991        case 4:
8992            CP0_CHECK(ctx->sc);
8993            gen_helper_mtc0_segctl2(cpu_env, arg);
8994            rn = "SegCtl2";
8995            break;
8996        case 5:
8997            check_pw(ctx);
8998            tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_PWBase));
8999            rn = "PWBase";
9000            break;
9001        case 6:
9002            check_pw(ctx);
9003            gen_helper_mtc0_pwfield(cpu_env, arg);
9004            rn = "PWField";
9005            break;
9006        case 7:
9007            check_pw(ctx);
9008            gen_helper_mtc0_pwsize(cpu_env, arg);
9009            rn = "PWSize";
9010            break;
9011        default:
9012            goto cp0_unimplemented;
9013        }
9014        break;
9015    case 6:
9016        switch (sel) {
9017        case 0:
9018            gen_helper_mtc0_wired(cpu_env, arg);
9019            rn = "Wired";
9020            break;
9021        case 1:
9022            check_insn(ctx, ISA_MIPS32R2);
9023            gen_helper_mtc0_srsconf0(cpu_env, arg);
9024            rn = "SRSConf0";
9025            break;
9026        case 2:
9027            check_insn(ctx, ISA_MIPS32R2);
9028            gen_helper_mtc0_srsconf1(cpu_env, arg);
9029            rn = "SRSConf1";
9030            break;
9031        case 3:
9032            check_insn(ctx, ISA_MIPS32R2);
9033            gen_helper_mtc0_srsconf2(cpu_env, arg);
9034            rn = "SRSConf2";
9035            break;
9036        case 4:
9037            check_insn(ctx, ISA_MIPS32R2);
9038            gen_helper_mtc0_srsconf3(cpu_env, arg);
9039            rn = "SRSConf3";
9040            break;
9041        case 5:
9042            check_insn(ctx, ISA_MIPS32R2);
9043            gen_helper_mtc0_srsconf4(cpu_env, arg);
9044            rn = "SRSConf4";
9045            break;
9046        case 6:
9047            check_pw(ctx);
9048            gen_helper_mtc0_pwctl(cpu_env, arg);
9049            rn = "PWCtl";
9050            break;
9051        default:
9052            goto cp0_unimplemented;
9053        }
9054        break;
9055    case 7:
9056        switch (sel) {
9057        case 0:
9058            check_insn(ctx, ISA_MIPS32R2);
9059            gen_helper_mtc0_hwrena(cpu_env, arg);
9060            ctx->base.is_jmp = DISAS_STOP;
9061            rn = "HWREna";
9062            break;
9063        default:
9064            goto cp0_unimplemented;
9065        }
9066        break;
9067    case 8:
9068        switch (sel) {
9069        case 0:
9070            /* ignored */
9071            rn = "BadVAddr";
9072            break;
9073        case 1:
9074            /* ignored */
9075            rn = "BadInstr";
9076            break;
9077        case 2:
9078            /* ignored */
9079            rn = "BadInstrP";
9080            break;
9081        case 3:
9082            /* ignored */
9083            rn = "BadInstrX";
9084            break;
9085        default:
9086            goto cp0_unimplemented;
9087        }
9088        break;
9089    case 9:
9090        switch (sel) {
9091        case 0:
9092            gen_helper_mtc0_count(cpu_env, arg);
9093            rn = "Count";
9094            break;
9095        /* 6,7 are implementation dependent */
9096        default:
9097            goto cp0_unimplemented;
9098        }
9099        /* Stop translation as we may have switched the execution mode */
9100        ctx->base.is_jmp = DISAS_STOP;
9101        break;
9102    case 10:
9103        switch (sel) {
9104        case 0:
9105            gen_helper_mtc0_entryhi(cpu_env, arg);
9106            rn = "EntryHi";
9107            break;
9108        default:
9109            goto cp0_unimplemented;
9110        }
9111        break;
9112    case 11:
9113        switch (sel) {
9114        case 0:
9115            gen_helper_mtc0_compare(cpu_env, arg);
9116            rn = "Compare";
9117            break;
9118        /* 6,7 are implementation dependent */
9119        default:
9120            goto cp0_unimplemented;
9121        }
9122        /* Stop translation as we may have switched the execution mode */
9123        ctx->base.is_jmp = DISAS_STOP;
9124        break;
9125    case 12:
9126        switch (sel) {
9127        case 0:
9128            save_cpu_state(ctx, 1);
9129            gen_helper_mtc0_status(cpu_env, arg);
9130            /* DISAS_STOP isn't good enough here, hflags may have changed. */
9131            gen_save_pc(ctx->base.pc_next + 4);
9132            ctx->base.is_jmp = DISAS_EXIT;
9133            rn = "Status";
9134            break;
9135        case 1:
9136            check_insn(ctx, ISA_MIPS32R2);
9137            gen_helper_mtc0_intctl(cpu_env, arg);
9138            /* Stop translation as we may have switched the execution mode */
9139            ctx->base.is_jmp = DISAS_STOP;
9140            rn = "IntCtl";
9141            break;
9142        case 2:
9143            check_insn(ctx, ISA_MIPS32R2);
9144            gen_helper_mtc0_srsctl(cpu_env, arg);
9145            /* Stop translation as we may have switched the execution mode */
9146            ctx->base.is_jmp = DISAS_STOP;
9147            rn = "SRSCtl";
9148            break;
9149        case 3:
9150            check_insn(ctx, ISA_MIPS32R2);
9151            gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_SRSMap));
9152            /* Stop translation as we may have switched the execution mode */
9153            ctx->base.is_jmp = DISAS_STOP;
9154            rn = "SRSMap";
9155            break;
9156        default:
9157            goto cp0_unimplemented;
9158        }
9159        break;
9160    case 13:
9161        switch (sel) {
9162        case 0:
9163            save_cpu_state(ctx, 1);
9164            gen_helper_mtc0_cause(cpu_env, arg);
9165            /* Stop translation as we may have triggered an interrupt.
9166             * DISAS_STOP isn't sufficient, we need to ensure we break out of
9167             * translated code to check for pending interrupts.  */
9168            gen_save_pc(ctx->base.pc_next + 4);
9169            ctx->base.is_jmp = DISAS_EXIT;
9170            rn = "Cause";
9171            break;
9172        default:
9173            goto cp0_unimplemented;
9174        }
9175        break;
9176    case 14:
9177        switch (sel) {
9178        case 0:
9179            tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EPC));
9180            rn = "EPC";
9181            break;
9182        default:
9183            goto cp0_unimplemented;
9184        }
9185        break;
9186    case 15:
9187        switch (sel) {
9188        case 0:
9189            /* ignored */
9190            rn = "PRid";
9191            break;
9192        case 1:
9193            check_insn(ctx, ISA_MIPS32R2);
9194            gen_helper_mtc0_ebase(cpu_env, arg);
9195            rn = "EBase";
9196            break;
9197        default:
9198            goto cp0_unimplemented;
9199        }
9200        break;
9201    case 16:
9202        switch (sel) {
9203        case 0:
9204            gen_helper_mtc0_config0(cpu_env, arg);
9205            rn = "Config";
9206            /* Stop translation as we may have switched the execution mode */
9207            ctx->base.is_jmp = DISAS_STOP;
9208            break;
9209        case 1:
9210            /* ignored, read only */
9211            rn = "Config1";
9212            break;
9213        case 2:
9214            gen_helper_mtc0_config2(cpu_env, arg);
9215            rn = "Config2";
9216            /* Stop translation as we may have switched the execution mode */
9217            ctx->base.is_jmp = DISAS_STOP;
9218            break;
9219        case 3:
9220            gen_helper_mtc0_config3(cpu_env, arg);
9221            rn = "Config3";
9222            /* Stop translation as we may have switched the execution mode */
9223            ctx->base.is_jmp = DISAS_STOP;
9224            break;
9225        case 4:
9226            /* currently ignored */
9227            rn = "Config4";
9228            break;
9229        case 5:
9230            gen_helper_mtc0_config5(cpu_env, arg);
9231            rn = "Config5";
9232            /* Stop translation as we may have switched the execution mode */
9233            ctx->base.is_jmp = DISAS_STOP;
9234            break;
9235        /* 6,7 are implementation dependent */
9236        default:
9237            rn = "Invalid config selector";
9238            goto cp0_unimplemented;
9239        }
9240        break;
9241    case 17:
9242        switch (sel) {
9243        case 0:
9244            gen_helper_mtc0_lladdr(cpu_env, arg);
9245            rn = "LLAddr";
9246            break;
9247        case 1:
9248            CP0_CHECK(ctx->mrp);
9249            gen_helper_mtc0_maar(cpu_env, arg);
9250            rn = "MAAR";
9251            break;
9252        case 2:
9253            CP0_CHECK(ctx->mrp);
9254            gen_helper_mtc0_maari(cpu_env, arg);
9255            rn = "MAARI";
9256            break;
9257        default:
9258            goto cp0_unimplemented;
9259        }
9260        break;
9261    case 18:
9262        switch (sel) {
9263        case 0:
9264        case 1:
9265        case 2:
9266        case 3:
9267        case 4:
9268        case 5:
9269        case 6:
9270        case 7:
9271            CP0_CHECK(ctx->CP0_Config1 & (1 << CP0C1_WR));
9272            gen_helper_0e1i(mtc0_watchlo, arg, sel);
9273            rn = "WatchLo";
9274            break;
9275        default:
9276            goto cp0_unimplemented;
9277        }
9278        break;
9279    case 19:
9280        switch (sel) {
9281        case 0:
9282        case 1:
9283        case 2:
9284        case 3:
9285        case 4:
9286        case 5:
9287        case 6:
9288        case 7:
9289            CP0_CHECK(ctx->CP0_Config1 & (1 << CP0C1_WR));
9290            gen_helper_0e1i(mtc0_watchhi, arg, sel);
9291            rn = "WatchHi";
9292            break;
9293        default:
9294            goto cp0_unimplemented;
9295        }
9296        break;
9297    case 20:
9298        switch (sel) {
9299        case 0:
9300            check_insn(ctx, ISA_MIPS3);
9301            gen_helper_mtc0_xcontext(cpu_env, arg);
9302            rn = "XContext";
9303            break;
9304        default:
9305            goto cp0_unimplemented;
9306        }
9307        break;
9308    case 21:
9309       /* Officially reserved, but sel 0 is used for R1x000 framemask */
9310        CP0_CHECK(!(ctx->insn_flags & ISA_MIPS32R6));
9311        switch (sel) {
9312        case 0:
9313            gen_helper_mtc0_framemask(cpu_env, arg);
9314            rn = "Framemask";
9315            break;
9316        default:
9317            goto cp0_unimplemented;
9318        }
9319        break;
9320    case 22:
9321        /* ignored */
9322        rn = "Diagnostic"; /* implementation dependent */
9323        break;
9324    case 23:
9325        switch (sel) {
9326        case 0:
9327            gen_helper_mtc0_debug(cpu_env, arg); /* EJTAG support */
9328            /* DISAS_STOP isn't good enough here, hflags may have changed. */
9329            gen_save_pc(ctx->base.pc_next + 4);
9330            ctx->base.is_jmp = DISAS_EXIT;
9331            rn = "Debug";
9332            break;
9333        case 1:
9334//            gen_helper_mtc0_tracecontrol(cpu_env, arg); /* PDtrace support */
9335            /* Stop translation as we may have switched the execution mode */
9336            ctx->base.is_jmp = DISAS_STOP;
9337            rn = "TraceControl";
9338            goto cp0_unimplemented;
9339        case 2:
9340//            gen_helper_mtc0_tracecontrol2(cpu_env, arg); /* PDtrace support */
9341            /* Stop translation as we may have switched the execution mode */
9342            ctx->base.is_jmp = DISAS_STOP;
9343            rn = "TraceControl2";
9344            goto cp0_unimplemented;
9345        case 3:
9346//            gen_helper_mtc0_usertracedata(cpu_env, arg); /* PDtrace support */
9347            /* Stop translation as we may have switched the execution mode */
9348            ctx->base.is_jmp = DISAS_STOP;
9349            rn = "UserTraceData";
9350            goto cp0_unimplemented;
9351        case 4:
9352//            gen_helper_mtc0_tracebpc(cpu_env, arg); /* PDtrace support */
9353            /* Stop translation as we may have switched the execution mode */
9354            ctx->base.is_jmp = DISAS_STOP;
9355            rn = "TraceBPC";
9356            goto cp0_unimplemented;
9357        default:
9358            goto cp0_unimplemented;
9359        }
9360        break;
9361    case 24:
9362        switch (sel) {
9363        case 0:
9364            /* EJTAG support */
9365            tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_DEPC));
9366            rn = "DEPC";
9367            break;
9368        default:
9369            goto cp0_unimplemented;
9370        }
9371        break;
9372    case 25:
9373        switch (sel) {
9374        case 0:
9375            gen_helper_mtc0_performance0(cpu_env, arg);
9376            rn = "Performance0";
9377            break;
9378        case 1:
9379//            gen_helper_mtc0_performance1(cpu_env, arg);
9380            rn = "Performance1";
9381            goto cp0_unimplemented;
9382        case 2:
9383//            gen_helper_mtc0_performance2(cpu_env, arg);
9384            rn = "Performance2";
9385            goto cp0_unimplemented;
9386        case 3:
9387//            gen_helper_mtc0_performance3(cpu_env, arg);
9388            rn = "Performance3";
9389            goto cp0_unimplemented;
9390        case 4:
9391//            gen_helper_mtc0_performance4(cpu_env, arg);
9392            rn = "Performance4";
9393            goto cp0_unimplemented;
9394        case 5:
9395//            gen_helper_mtc0_performance5(cpu_env, arg);
9396            rn = "Performance5";
9397            goto cp0_unimplemented;
9398        case 6:
9399//            gen_helper_mtc0_performance6(cpu_env, arg);
9400            rn = "Performance6";
9401            goto cp0_unimplemented;
9402        case 7:
9403//            gen_helper_mtc0_performance7(cpu_env, arg);
9404            rn = "Performance7";
9405            goto cp0_unimplemented;
9406        default:
9407            goto cp0_unimplemented;
9408        }
9409        break;
9410    case 26:
9411        switch (sel) {
9412        case 0:
9413            gen_helper_mtc0_errctl(cpu_env, arg);
9414            ctx->base.is_jmp = DISAS_STOP;
9415            rn = "ErrCtl";
9416            break;
9417        default:
9418            goto cp0_unimplemented;
9419        }
9420        break;
9421    case 27:
9422        switch (sel) {
9423        case 0:
9424        case 1:
9425        case 2:
9426        case 3:
9427            /* ignored */
9428            rn = "CacheErr";
9429            break;
9430        default:
9431            goto cp0_unimplemented;
9432        }
9433        break;
9434    case 28:
9435        switch (sel) {
9436        case 0:
9437        case 2:
9438        case 4:
9439        case 6:
9440            gen_helper_mtc0_taglo(cpu_env, arg);
9441            rn = "TagLo";
9442            break;
9443        case 1:
9444        case 3:
9445        case 5:
9446        case 7:
9447            gen_helper_mtc0_datalo(cpu_env, arg);
9448            rn = "DataLo";
9449            break;
9450        default:
9451            goto cp0_unimplemented;
9452        }
9453        break;
9454    case 29:
9455        switch (sel) {
9456        case 0:
9457        case 2:
9458        case 4:
9459        case 6:
9460            gen_helper_mtc0_taghi(cpu_env, arg);
9461            rn = "TagHi";
9462            break;
9463        case 1:
9464        case 3:
9465        case 5:
9466        case 7:
9467            gen_helper_mtc0_datahi(cpu_env, arg);
9468            rn = "DataHi";
9469            break;
9470        default:
9471            rn = "invalid sel";
9472            goto cp0_unimplemented;
9473        }
9474        break;
9475    case 30:
9476        switch (sel) {
9477        case 0:
9478            tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_ErrorEPC));
9479            rn = "ErrorEPC";
9480            break;
9481        default:
9482            goto cp0_unimplemented;
9483        }
9484        break;
9485    case 31:
9486        switch (sel) {
9487        case 0:
9488            /* EJTAG support */
9489            gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_DESAVE));
9490            rn = "DESAVE";
9491            break;
9492        case 2:
9493        case 3:
9494        case 4:
9495        case 5:
9496        case 6:
9497        case 7:
9498            CP0_CHECK(ctx->kscrexist & (1 << sel));
9499            tcg_gen_st_tl(arg, cpu_env,
9500                          offsetof(CPUMIPSState, CP0_KScratch[sel-2]));
9501            rn = "KScratch";
9502            break;
9503        default:
9504            goto cp0_unimplemented;
9505        }
9506        break;
9507    default:
9508        goto cp0_unimplemented;
9509    }
9510    trace_mips_translate_c0("dmtc0", rn, reg, sel);
9511
9512    /* For simplicity assume that all writes can cause interrupts.  */
9513    if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
9514        gen_io_end();
9515        /* DISAS_STOP isn't sufficient, we need to ensure we break out of
9516         * translated code to check for pending interrupts.  */
9517        gen_save_pc(ctx->base.pc_next + 4);
9518        ctx->base.is_jmp = DISAS_EXIT;
9519    }
9520    return;
9521
9522cp0_unimplemented:
9523    qemu_log_mask(LOG_UNIMP, "dmtc0 %s (reg %d sel %d)\n", rn, reg, sel);
9524}
9525#endif /* TARGET_MIPS64 */
9526
9527static void gen_mftr(CPUMIPSState *env, DisasContext *ctx, int rt, int rd,
9528                     int u, int sel, int h)
9529{
9530    int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
9531    TCGv t0 = tcg_temp_local_new();
9532
9533    if ((env->CP0_VPEConf0 & (1 << CP0VPEC0_MVP)) == 0 &&
9534        ((env->tcs[other_tc].CP0_TCBind & (0xf << CP0TCBd_CurVPE)) !=
9535         (env->active_tc.CP0_TCBind & (0xf << CP0TCBd_CurVPE))))
9536        tcg_gen_movi_tl(t0, -1);
9537    else if ((env->CP0_VPEControl & (0xff << CP0VPECo_TargTC)) >
9538             (env->mvp->CP0_MVPConf0 & (0xff << CP0MVPC0_PTC)))
9539        tcg_gen_movi_tl(t0, -1);
9540    else if (u == 0) {
9541        switch (rt) {
9542        case 1:
9543            switch (sel) {
9544            case 1:
9545                gen_helper_mftc0_vpecontrol(t0, cpu_env);
9546                break;
9547            case 2:
9548                gen_helper_mftc0_vpeconf0(t0, cpu_env);
9549                break;
9550            default:
9551                goto die;
9552                break;
9553            }
9554            break;
9555        case 2:
9556            switch (sel) {
9557            case 1:
9558                gen_helper_mftc0_tcstatus(t0, cpu_env);
9559                break;
9560            case 2:
9561                gen_helper_mftc0_tcbind(t0, cpu_env);
9562                break;
9563            case 3:
9564                gen_helper_mftc0_tcrestart(t0, cpu_env);
9565                break;
9566            case 4:
9567                gen_helper_mftc0_tchalt(t0, cpu_env);
9568                break;
9569            case 5:
9570                gen_helper_mftc0_tccontext(t0, cpu_env);
9571                break;
9572            case 6:
9573                gen_helper_mftc0_tcschedule(t0, cpu_env);
9574                break;
9575            case 7:
9576                gen_helper_mftc0_tcschefback(t0, cpu_env);
9577                break;
9578            default:
9579                gen_mfc0(ctx, t0, rt, sel);
9580                break;
9581            }
9582            break;
9583        case 10:
9584            switch (sel) {
9585            case 0:
9586                gen_helper_mftc0_entryhi(t0, cpu_env);
9587                break;
9588            default:
9589                gen_mfc0(ctx, t0, rt, sel);
9590                break;
9591            }
9592        case 12:
9593            switch (sel) {
9594            case 0:
9595                gen_helper_mftc0_status(t0, cpu_env);
9596                break;
9597            default:
9598                gen_mfc0(ctx, t0, rt, sel);
9599                break;
9600            }
9601        case 13:
9602            switch (sel) {
9603            case 0:
9604                gen_helper_mftc0_cause(t0, cpu_env);
9605                break;
9606            default:
9607                goto die;
9608                break;
9609            }
9610            break;
9611        case 14:
9612            switch (sel) {
9613            case 0:
9614                gen_helper_mftc0_epc(t0, cpu_env);
9615                break;
9616            default:
9617                goto die;
9618                break;
9619            }
9620            break;
9621        case 15:
9622            switch (sel) {
9623            case 1:
9624                gen_helper_mftc0_ebase(t0, cpu_env);
9625                break;
9626            default:
9627                goto die;
9628                break;
9629            }
9630            break;
9631        case 16:
9632            switch (sel) {
9633            case 0:
9634            case 1:
9635            case 2:
9636            case 3:
9637            case 4:
9638            case 5:
9639            case 6:
9640            case 7:
9641                gen_helper_mftc0_configx(t0, cpu_env, tcg_const_tl(sel));
9642                break;
9643            default:
9644                goto die;
9645                break;
9646            }
9647            break;
9648        case 23:
9649            switch (sel) {
9650            case 0:
9651                gen_helper_mftc0_debug(t0, cpu_env);
9652                break;
9653            default:
9654                gen_mfc0(ctx, t0, rt, sel);
9655                break;
9656            }
9657            break;
9658        default:
9659            gen_mfc0(ctx, t0, rt, sel);
9660        }
9661    } else switch (sel) {
9662    /* GPR registers. */
9663    case 0:
9664        gen_helper_1e0i(mftgpr, t0, rt);
9665        break;
9666    /* Auxiliary CPU registers */
9667    case 1:
9668        switch (rt) {
9669        case 0:
9670            gen_helper_1e0i(mftlo, t0, 0);
9671            break;
9672        case 1:
9673            gen_helper_1e0i(mfthi, t0, 0);
9674            break;
9675        case 2:
9676            gen_helper_1e0i(mftacx, t0, 0);
9677            break;
9678        case 4:
9679            gen_helper_1e0i(mftlo, t0, 1);
9680            break;
9681        case 5:
9682            gen_helper_1e0i(mfthi, t0, 1);
9683            break;
9684        case 6:
9685            gen_helper_1e0i(mftacx, t0, 1);
9686            break;
9687        case 8:
9688            gen_helper_1e0i(mftlo, t0, 2);
9689            break;
9690        case 9:
9691            gen_helper_1e0i(mfthi, t0, 2);
9692            break;
9693        case 10:
9694            gen_helper_1e0i(mftacx, t0, 2);
9695            break;
9696        case 12:
9697            gen_helper_1e0i(mftlo, t0, 3);
9698            break;
9699        case 13:
9700            gen_helper_1e0i(mfthi, t0, 3);
9701            break;
9702        case 14:
9703            gen_helper_1e0i(mftacx, t0, 3);
9704            break;
9705        case 16:
9706            gen_helper_mftdsp(t0, cpu_env);
9707            break;
9708        default:
9709            goto die;
9710        }
9711        break;
9712    /* Floating point (COP1). */
9713    case 2:
9714        /* XXX: For now we support only a single FPU context. */
9715        if (h == 0) {
9716            TCGv_i32 fp0 = tcg_temp_new_i32();
9717
9718            gen_load_fpr32(ctx, fp0, rt);
9719            tcg_gen_ext_i32_tl(t0, fp0);
9720            tcg_temp_free_i32(fp0);
9721        } else {
9722            TCGv_i32 fp0 = tcg_temp_new_i32();
9723
9724            gen_load_fpr32h(ctx, fp0, rt);
9725            tcg_gen_ext_i32_tl(t0, fp0);
9726            tcg_temp_free_i32(fp0);
9727        }
9728        break;
9729    case 3:
9730        /* XXX: For now we support only a single FPU context. */
9731        gen_helper_1e0i(cfc1, t0, rt);
9732        break;
9733    /* COP2: Not implemented. */
9734    case 4:
9735    case 5:
9736        /* fall through */
9737    default:
9738        goto die;
9739    }
9740    trace_mips_translate_tr("mftr", rt, u, sel, h);
9741    gen_store_gpr(t0, rd);
9742    tcg_temp_free(t0);
9743    return;
9744
9745die:
9746    tcg_temp_free(t0);
9747    LOG_DISAS("mftr (reg %d u %d sel %d h %d)\n", rt, u, sel, h);
9748    generate_exception_end(ctx, EXCP_RI);
9749}
9750
9751static void gen_mttr(CPUMIPSState *env, DisasContext *ctx, int rd, int rt,
9752                     int u, int sel, int h)
9753{
9754    int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
9755    TCGv t0 = tcg_temp_local_new();
9756
9757    gen_load_gpr(t0, rt);
9758    if ((env->CP0_VPEConf0 & (1 << CP0VPEC0_MVP)) == 0 &&
9759        ((env->tcs[other_tc].CP0_TCBind & (0xf << CP0TCBd_CurVPE)) !=
9760         (env->active_tc.CP0_TCBind & (0xf << CP0TCBd_CurVPE))))
9761        /* NOP */ ;
9762    else if ((env->CP0_VPEControl & (0xff << CP0VPECo_TargTC)) >
9763             (env->mvp->CP0_MVPConf0 & (0xff << CP0MVPC0_PTC)))
9764        /* NOP */ ;
9765    else if (u == 0) {
9766        switch (rd) {
9767        case 1:
9768            switch (sel) {
9769            case 1:
9770                gen_helper_mttc0_vpecontrol(cpu_env, t0);
9771                break;
9772            case 2:
9773                gen_helper_mttc0_vpeconf0(cpu_env, t0);
9774                break;
9775            default:
9776                goto die;
9777                break;
9778            }
9779            break;
9780        case 2:
9781            switch (sel) {
9782            case 1:
9783                gen_helper_mttc0_tcstatus(cpu_env, t0);
9784                break;
9785            case 2:
9786                gen_helper_mttc0_tcbind(cpu_env, t0);
9787                break;
9788            case 3:
9789                gen_helper_mttc0_tcrestart(cpu_env, t0);
9790                break;
9791            case 4:
9792                gen_helper_mttc0_tchalt(cpu_env, t0);
9793                break;
9794            case 5:
9795                gen_helper_mttc0_tccontext(cpu_env, t0);
9796                break;
9797            case 6:
9798                gen_helper_mttc0_tcschedule(cpu_env, t0);
9799                break;
9800            case 7:
9801                gen_helper_mttc0_tcschefback(cpu_env, t0);
9802                break;
9803            default:
9804                gen_mtc0(ctx, t0, rd, sel);
9805                break;
9806            }
9807            break;
9808        case 10:
9809            switch (sel) {
9810            case 0:
9811                gen_helper_mttc0_entryhi(cpu_env, t0);
9812                break;
9813            default:
9814                gen_mtc0(ctx, t0, rd, sel);
9815                break;
9816            }
9817        case 12:
9818            switch (sel) {
9819            case 0:
9820                gen_helper_mttc0_status(cpu_env, t0);
9821                break;
9822            default:
9823                gen_mtc0(ctx, t0, rd, sel);
9824                break;
9825            }
9826        case 13:
9827            switch (sel) {
9828            case 0:
9829                gen_helper_mttc0_cause(cpu_env, t0);
9830                break;
9831            default:
9832                goto die;
9833                break;
9834            }
9835            break;
9836        case 15:
9837            switch (sel) {
9838            case 1:
9839                gen_helper_mttc0_ebase(cpu_env, t0);
9840                break;
9841            default:
9842                goto die;
9843                break;
9844            }
9845            break;
9846        case 23:
9847            switch (sel) {
9848            case 0:
9849                gen_helper_mttc0_debug(cpu_env, t0);
9850                break;
9851            default:
9852                gen_mtc0(ctx, t0, rd, sel);
9853                break;
9854            }
9855            break;
9856        default:
9857            gen_mtc0(ctx, t0, rd, sel);
9858        }
9859    } else switch (sel) {
9860    /* GPR registers. */
9861    case 0:
9862        gen_helper_0e1i(mttgpr, t0, rd);
9863        break;
9864    /* Auxiliary CPU registers */
9865    case 1:
9866        switch (rd) {
9867        case 0:
9868            gen_helper_0e1i(mttlo, t0, 0);
9869            break;
9870        case 1:
9871            gen_helper_0e1i(mtthi, t0, 0);
9872            break;
9873        case 2:
9874            gen_helper_0e1i(mttacx, t0, 0);
9875            break;
9876        case 4:
9877            gen_helper_0e1i(mttlo, t0, 1);
9878            break;
9879        case 5:
9880            gen_helper_0e1i(mtthi, t0, 1);
9881            break;
9882        case 6:
9883            gen_helper_0e1i(mttacx, t0, 1);
9884            break;
9885        case 8:
9886            gen_helper_0e1i(mttlo, t0, 2);
9887            break;
9888        case 9:
9889            gen_helper_0e1i(mtthi, t0, 2);
9890            break;
9891        case 10:
9892            gen_helper_0e1i(mttacx, t0, 2);
9893            break;
9894        case 12:
9895            gen_helper_0e1i(mttlo, t0, 3);
9896            break;
9897        case 13:
9898            gen_helper_0e1i(mtthi, t0, 3);
9899            break;
9900        case 14:
9901            gen_helper_0e1i(mttacx, t0, 3);
9902            break;
9903        case 16:
9904            gen_helper_mttdsp(cpu_env, t0);
9905            break;
9906        default:
9907            goto die;
9908        }
9909        break;
9910    /* Floating point (COP1). */
9911    case 2:
9912        /* XXX: For now we support only a single FPU context. */
9913        if (h == 0) {
9914            TCGv_i32 fp0 = tcg_temp_new_i32();
9915
9916            tcg_gen_trunc_tl_i32(fp0, t0);
9917            gen_store_fpr32(ctx, fp0, rd);
9918            tcg_temp_free_i32(fp0);
9919        } else {
9920            TCGv_i32 fp0 = tcg_temp_new_i32();
9921
9922            tcg_gen_trunc_tl_i32(fp0, t0);
9923            gen_store_fpr32h(ctx, fp0, rd);
9924            tcg_temp_free_i32(fp0);
9925        }
9926        break;
9927    case 3:
9928        /* XXX: For now we support only a single FPU context. */
9929        {
9930            TCGv_i32 fs_tmp = tcg_const_i32(rd);
9931
9932            gen_helper_0e2i(ctc1, t0, fs_tmp, rt);
9933            tcg_temp_free_i32(fs_tmp);
9934        }
9935        /* Stop translation as we may have changed hflags */
9936        ctx->base.is_jmp = DISAS_STOP;
9937        break;
9938    /* COP2: Not implemented. */
9939    case 4:
9940    case 5:
9941        /* fall through */
9942    default:
9943        goto die;
9944    }
9945    trace_mips_translate_tr("mttr", rd, u, sel, h);
9946    tcg_temp_free(t0);
9947    return;
9948
9949die:
9950    tcg_temp_free(t0);
9951    LOG_DISAS("mttr (reg %d u %d sel %d h %d)\n", rd, u, sel, h);
9952    generate_exception_end(ctx, EXCP_RI);
9953}
9954
9955static void gen_cp0 (CPUMIPSState *env, DisasContext *ctx, uint32_t opc, int rt, int rd)
9956{
9957    const char *opn = "ldst";
9958
9959    check_cp0_enabled(ctx);
9960    switch (opc) {
9961    case OPC_MFC0:
9962        if (rt == 0) {
9963            /* Treat as NOP. */
9964            return;
9965        }
9966        gen_mfc0(ctx, cpu_gpr[rt], rd, ctx->opcode & 0x7);
9967        opn = "mfc0";
9968        break;
9969    case OPC_MTC0:
9970        {
9971            TCGv t0 = tcg_temp_new();
9972
9973            gen_load_gpr(t0, rt);
9974            gen_mtc0(ctx, t0, rd, ctx->opcode & 0x7);
9975            tcg_temp_free(t0);
9976        }
9977        opn = "mtc0";
9978        break;
9979#if defined(TARGET_MIPS64)
9980    case OPC_DMFC0:
9981        check_insn(ctx, ISA_MIPS3);
9982        if (rt == 0) {
9983            /* Treat as NOP. */
9984            return;
9985        }
9986        gen_dmfc0(ctx, cpu_gpr[rt], rd, ctx->opcode & 0x7);
9987        opn = "dmfc0";
9988        break;
9989    case OPC_DMTC0:
9990        check_insn(ctx, ISA_MIPS3);
9991        {
9992            TCGv t0 = tcg_temp_new();
9993
9994            gen_load_gpr(t0, rt);
9995            gen_dmtc0(ctx, t0, rd, ctx->opcode & 0x7);
9996            tcg_temp_free(t0);
9997        }
9998        opn = "dmtc0";
9999        break;
10000#endif
10001    case OPC_MFHC0:
10002        check_mvh(ctx);
10003        if (rt == 0) {
10004            /* Treat as NOP. */
10005            return;
10006        }
10007        gen_mfhc0(ctx, cpu_gpr[rt], rd, ctx->opcode & 0x7);
10008        opn = "mfhc0";
10009        break;
10010    case OPC_MTHC0:
10011        check_mvh(ctx);
10012        {
10013            TCGv t0 = tcg_temp_new();
10014            gen_load_gpr(t0, rt);
10015            gen_mthc0(ctx, t0, rd, ctx->opcode & 0x7);
10016            tcg_temp_free(t0);
10017        }
10018        opn = "mthc0";
10019        break;
10020    case OPC_MFTR:
10021        check_cp0_enabled(ctx);
10022        if (rd == 0) {
10023            /* Treat as NOP. */
10024            return;
10025        }
10026        gen_mftr(env, ctx, rt, rd, (ctx->opcode >> 5) & 1,
10027                 ctx->opcode & 0x7, (ctx->opcode >> 4) & 1);
10028        opn = "mftr";
10029        break;
10030    case OPC_MTTR:
10031        check_cp0_enabled(ctx);
10032        gen_mttr(env, ctx, rd, rt, (ctx->opcode >> 5) & 1,
10033                 ctx->opcode & 0x7, (ctx->opcode >> 4) & 1);
10034        opn = "mttr";
10035        break;
10036    case OPC_TLBWI:
10037        opn = "tlbwi";
10038        if (!env->tlb->helper_tlbwi)
10039            goto die;
10040        gen_helper_tlbwi(cpu_env);
10041        break;
10042    case OPC_TLBINV:
10043        opn = "tlbinv";
10044        if (ctx->ie >= 2) {
10045            if (!env->tlb->helper_tlbinv) {
10046                goto die;
10047            }
10048            gen_helper_tlbinv(cpu_env);
10049        } /* treat as nop if TLBINV not supported */
10050        break;
10051    case OPC_TLBINVF:
10052        opn = "tlbinvf";
10053        if (ctx->ie >= 2) {
10054            if (!env->tlb->helper_tlbinvf) {
10055                goto die;
10056            }
10057            gen_helper_tlbinvf(cpu_env);
10058        } /* treat as nop if TLBINV not supported */
10059        break;
10060    case OPC_TLBWR:
10061        opn = "tlbwr";
10062        if (!env->tlb->helper_tlbwr)
10063            goto die;
10064        gen_helper_tlbwr(cpu_env);
10065        break;
10066    case OPC_TLBP:
10067        opn = "tlbp";
10068        if (!env->tlb->helper_tlbp)
10069            goto die;
10070        gen_helper_tlbp(cpu_env);
10071        break;
10072    case OPC_TLBR:
10073        opn = "tlbr";
10074        if (!env->tlb->helper_tlbr)
10075            goto die;
10076        gen_helper_tlbr(cpu_env);
10077        break;
10078    case OPC_ERET: /* OPC_ERETNC */
10079        if ((ctx->insn_flags & ISA_MIPS32R6) &&
10080            (ctx->hflags & MIPS_HFLAG_BMASK)) {
10081            goto die;
10082        } else {
10083            int bit_shift = (ctx->hflags & MIPS_HFLAG_M16) ? 16 : 6;
10084            if (ctx->opcode & (1 << bit_shift)) {
10085                /* OPC_ERETNC */
10086                opn = "eretnc";
10087                check_insn(ctx, ISA_MIPS32R5);
10088                gen_helper_eretnc(cpu_env);
10089            } else {
10090                /* OPC_ERET */
10091                opn = "eret";
10092                check_insn(ctx, ISA_MIPS2);
10093                gen_helper_eret(cpu_env);
10094            }
10095            ctx->base.is_jmp = DISAS_EXIT;
10096        }
10097        break;
10098    case OPC_DERET:
10099        opn = "deret";
10100        check_insn(ctx, ISA_MIPS32);
10101        if ((ctx->insn_flags & ISA_MIPS32R6) &&
10102            (ctx->hflags & MIPS_HFLAG_BMASK)) {
10103            goto die;
10104        }
10105        if (!(ctx->hflags & MIPS_HFLAG_DM)) {
10106            MIPS_INVAL(opn);
10107            generate_exception_end(ctx, EXCP_RI);
10108        } else {
10109            gen_helper_deret(cpu_env);
10110            ctx->base.is_jmp = DISAS_EXIT;
10111        }
10112        break;
10113    case OPC_WAIT:
10114        opn = "wait";
10115        check_insn(ctx, ISA_MIPS3 | ISA_MIPS32);
10116        if ((ctx->insn_flags & ISA_MIPS32R6) &&
10117            (ctx->hflags & MIPS_HFLAG_BMASK)) {
10118            goto die;
10119        }
10120        /* If we get an exception, we want to restart at next instruction */
10121        ctx->base.pc_next += 4;
10122        save_cpu_state(ctx, 1);
10123        ctx->base.pc_next -= 4;
10124        gen_helper_wait(cpu_env);
10125        ctx->base.is_jmp = DISAS_NORETURN;
10126        break;
10127    default:
10128 die:
10129        MIPS_INVAL(opn);
10130        generate_exception_end(ctx, EXCP_RI);
10131        return;
10132    }
10133    (void)opn; /* avoid a compiler warning */
10134}
10135#endif /* !CONFIG_USER_ONLY */
10136
10137/* CP1 Branches (before delay slot) */
10138static void gen_compute_branch1(DisasContext *ctx, uint32_t op,
10139                                int32_t cc, int32_t offset)
10140{
10141    target_ulong btarget;
10142    TCGv_i32 t0 = tcg_temp_new_i32();
10143
10144    if ((ctx->insn_flags & ISA_MIPS32R6) && (ctx->hflags & MIPS_HFLAG_BMASK)) {
10145        generate_exception_end(ctx, EXCP_RI);
10146        goto out;
10147    }
10148
10149    if (cc != 0)
10150        check_insn(ctx, ISA_MIPS4 | ISA_MIPS32);
10151
10152    btarget = ctx->base.pc_next + 4 + offset;
10153
10154    switch (op) {
10155    case OPC_BC1F:
10156        tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
10157        tcg_gen_not_i32(t0, t0);
10158        tcg_gen_andi_i32(t0, t0, 1);
10159        tcg_gen_extu_i32_tl(bcond, t0);
10160        goto not_likely;
10161    case OPC_BC1FL:
10162        tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
10163        tcg_gen_not_i32(t0, t0);
10164        tcg_gen_andi_i32(t0, t0, 1);
10165        tcg_gen_extu_i32_tl(bcond, t0);
10166        goto likely;
10167    case OPC_BC1T:
10168        tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
10169        tcg_gen_andi_i32(t0, t0, 1);
10170        tcg_gen_extu_i32_tl(bcond, t0);
10171        goto not_likely;
10172    case OPC_BC1TL:
10173        tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
10174        tcg_gen_andi_i32(t0, t0, 1);
10175        tcg_gen_extu_i32_tl(bcond, t0);
10176    likely:
10177        ctx->hflags |= MIPS_HFLAG_BL;
10178        break;
10179    case OPC_BC1FANY2:
10180        {
10181            TCGv_i32 t1 = tcg_temp_new_i32();
10182            tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
10183            tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+1));
10184            tcg_gen_nand_i32(t0, t0, t1);
10185            tcg_temp_free_i32(t1);
10186            tcg_gen_andi_i32(t0, t0, 1);
10187            tcg_gen_extu_i32_tl(bcond, t0);
10188        }
10189        goto not_likely;
10190    case OPC_BC1TANY2:
10191        {
10192            TCGv_i32 t1 = tcg_temp_new_i32();
10193            tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
10194            tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+1));
10195            tcg_gen_or_i32(t0, t0, t1);
10196            tcg_temp_free_i32(t1);
10197            tcg_gen_andi_i32(t0, t0, 1);
10198            tcg_gen_extu_i32_tl(bcond, t0);
10199        }
10200        goto not_likely;
10201    case OPC_BC1FANY4:
10202        {
10203            TCGv_i32 t1 = tcg_temp_new_i32();
10204            tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
10205            tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+1));
10206            tcg_gen_and_i32(t0, t0, t1);
10207            tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+2));
10208            tcg_gen_and_i32(t0, t0, t1);
10209            tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+3));
10210            tcg_gen_nand_i32(t0, t0, t1);
10211            tcg_temp_free_i32(t1);
10212            tcg_gen_andi_i32(t0, t0, 1);
10213            tcg_gen_extu_i32_tl(bcond, t0);
10214        }
10215        goto not_likely;
10216    case OPC_BC1TANY4:
10217        {
10218            TCGv_i32 t1 = tcg_temp_new_i32();
10219            tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
10220            tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+1));
10221            tcg_gen_or_i32(t0, t0, t1);
10222            tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+2));
10223            tcg_gen_or_i32(t0, t0, t1);
10224            tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+3));
10225            tcg_gen_or_i32(t0, t0, t1);
10226            tcg_temp_free_i32(t1);
10227            tcg_gen_andi_i32(t0, t0, 1);
10228            tcg_gen_extu_i32_tl(bcond, t0);
10229        }
10230    not_likely:
10231        ctx->hflags |= MIPS_HFLAG_BC;
10232        break;
10233    default:
10234        MIPS_INVAL("cp1 cond branch");
10235        generate_exception_end(ctx, EXCP_RI);
10236        goto out;
10237    }
10238    ctx->btarget = btarget;
10239    ctx->hflags |= MIPS_HFLAG_BDS32;
10240 out:
10241    tcg_temp_free_i32(t0);
10242}
10243
10244/* R6 CP1 Branches */
10245static void gen_compute_branch1_r6(DisasContext *ctx, uint32_t op,
10246                                   int32_t ft, int32_t offset,
10247                                   int delayslot_size)
10248{
10249    target_ulong btarget;
10250    TCGv_i64 t0 = tcg_temp_new_i64();
10251
10252    if (ctx->hflags & MIPS_HFLAG_BMASK) {
10253#ifdef MIPS_DEBUG_DISAS
10254        LOG_DISAS("Branch in delay / forbidden slot at PC 0x" TARGET_FMT_lx
10255                  "\n", ctx->base.pc_next);
10256#endif
10257        generate_exception_end(ctx, EXCP_RI);
10258        goto out;
10259    }
10260
10261    gen_load_fpr64(ctx, t0, ft);
10262    tcg_gen_andi_i64(t0, t0, 1);
10263
10264    btarget = addr_add(ctx, ctx->base.pc_next + 4, offset);
10265
10266    switch (op) {
10267    case OPC_BC1EQZ:
10268        tcg_gen_xori_i64(t0, t0, 1);
10269        ctx->hflags |= MIPS_HFLAG_BC;
10270        break;
10271    case OPC_BC1NEZ:
10272        /* t0 already set */
10273        ctx->hflags |= MIPS_HFLAG_BC;
10274        break;
10275    default:
10276        MIPS_INVAL("cp1 cond branch");
10277        generate_exception_end(ctx, EXCP_RI);
10278        goto out;
10279    }
10280
10281    tcg_gen_trunc_i64_tl(bcond, t0);
10282
10283    ctx->btarget = btarget;
10284
10285    switch (delayslot_size) {
10286    case 2:
10287        ctx->hflags |= MIPS_HFLAG_BDS16;
10288        break;
10289    case 4:
10290        ctx->hflags |= MIPS_HFLAG_BDS32;
10291        break;
10292    }
10293
10294out:
10295    tcg_temp_free_i64(t0);
10296}
10297
10298/* Coprocessor 1 (FPU) */
10299
10300#define FOP(func, fmt) (((fmt) << 21) | (func))
10301
10302enum fopcode {
10303    OPC_ADD_S = FOP(0, FMT_S),
10304    OPC_SUB_S = FOP(1, FMT_S),
10305    OPC_MUL_S = FOP(2, FMT_S),
10306    OPC_DIV_S = FOP(3, FMT_S),
10307    OPC_SQRT_S = FOP(4, FMT_S),
10308    OPC_ABS_S = FOP(5, FMT_S),
10309    OPC_MOV_S = FOP(6, FMT_S),
10310    OPC_NEG_S = FOP(7, FMT_S),
10311    OPC_ROUND_L_S = FOP(8, FMT_S),
10312    OPC_TRUNC_L_S = FOP(9, FMT_S),
10313    OPC_CEIL_L_S = FOP(10, FMT_S),
10314    OPC_FLOOR_L_S = FOP(11, FMT_S),
10315    OPC_ROUND_W_S = FOP(12, FMT_S),
10316    OPC_TRUNC_W_S = FOP(13, FMT_S),
10317    OPC_CEIL_W_S = FOP(14, FMT_S),
10318    OPC_FLOOR_W_S = FOP(15, FMT_S),
10319    OPC_SEL_S = FOP(16, FMT_S),
10320    OPC_MOVCF_S = FOP(17, FMT_S),
10321    OPC_MOVZ_S = FOP(18, FMT_S),
10322    OPC_MOVN_S = FOP(19, FMT_S),
10323    OPC_SELEQZ_S = FOP(20, FMT_S),
10324    OPC_RECIP_S = FOP(21, FMT_S),
10325    OPC_RSQRT_S = FOP(22, FMT_S),
10326    OPC_SELNEZ_S = FOP(23, FMT_S),
10327    OPC_MADDF_S = FOP(24, FMT_S),
10328    OPC_MSUBF_S = FOP(25, FMT_S),
10329    OPC_RINT_S = FOP(26, FMT_S),
10330    OPC_CLASS_S = FOP(27, FMT_S),
10331    OPC_MIN_S = FOP(28, FMT_S),
10332    OPC_RECIP2_S = FOP(28, FMT_S),
10333    OPC_MINA_S = FOP(29, FMT_S),
10334    OPC_RECIP1_S = FOP(29, FMT_S),
10335    OPC_MAX_S = FOP(30, FMT_S),
10336    OPC_RSQRT1_S = FOP(30, FMT_S),
10337    OPC_MAXA_S = FOP(31, FMT_S),
10338    OPC_RSQRT2_S = FOP(31, FMT_S),
10339    OPC_CVT_D_S = FOP(33, FMT_S),
10340    OPC_CVT_W_S = FOP(36, FMT_S),
10341    OPC_CVT_L_S = FOP(37, FMT_S),
10342    OPC_CVT_PS_S = FOP(38, FMT_S),
10343    OPC_CMP_F_S = FOP (48, FMT_S),
10344    OPC_CMP_UN_S = FOP (49, FMT_S),
10345    OPC_CMP_EQ_S = FOP (50, FMT_S),
10346    OPC_CMP_UEQ_S = FOP (51, FMT_S),
10347    OPC_CMP_OLT_S = FOP (52, FMT_S),
10348    OPC_CMP_ULT_S = FOP (53, FMT_S),
10349    OPC_CMP_OLE_S = FOP (54, FMT_S),
10350    OPC_CMP_ULE_S = FOP (55, FMT_S),
10351    OPC_CMP_SF_S = FOP (56, FMT_S),
10352    OPC_CMP_NGLE_S = FOP (57, FMT_S),
10353    OPC_CMP_SEQ_S = FOP (58, FMT_S),
10354    OPC_CMP_NGL_S = FOP (59, FMT_S),
10355    OPC_CMP_LT_S = FOP (60, FMT_S),
10356    OPC_CMP_NGE_S = FOP (61, FMT_S),
10357    OPC_CMP_LE_S = FOP (62, FMT_S),
10358    OPC_CMP_NGT_S = FOP (63, FMT_S),
10359
10360    OPC_ADD_D = FOP(0, FMT_D),
10361    OPC_SUB_D = FOP(1, FMT_D),
10362    OPC_MUL_D = FOP(2, FMT_D),
10363    OPC_DIV_D = FOP(3, FMT_D),
10364    OPC_SQRT_D = FOP(4, FMT_D),
10365    OPC_ABS_D = FOP(5, FMT_D),
10366    OPC_MOV_D = FOP(6, FMT_D),
10367    OPC_NEG_D = FOP(7, FMT_D),
10368    OPC_ROUND_L_D = FOP(8, FMT_D),
10369    OPC_TRUNC_L_D = FOP(9, FMT_D),
10370    OPC_CEIL_L_D = FOP(10, FMT_D),
10371    OPC_FLOOR_L_D = FOP(11, FMT_D),
10372    OPC_ROUND_W_D = FOP(12, FMT_D),
10373    OPC_TRUNC_W_D = FOP(13, FMT_D),
10374    OPC_CEIL_W_D = FOP(14, FMT_D),
10375    OPC_FLOOR_W_D = FOP(15, FMT_D),
10376    OPC_SEL_D = FOP(16, FMT_D),
10377    OPC_MOVCF_D = FOP(17, FMT_D),
10378    OPC_MOVZ_D = FOP(18, FMT_D),
10379    OPC_MOVN_D = FOP(19, FMT_D),
10380    OPC_SELEQZ_D = FOP(20, FMT_D),
10381    OPC_RECIP_D = FOP(21, FMT_D),
10382    OPC_RSQRT_D = FOP(22, FMT_D),
10383    OPC_SELNEZ_D = FOP(23, FMT_D),
10384    OPC_MADDF_D = FOP(24, FMT_D),
10385    OPC_MSUBF_D = FOP(25, FMT_D),
10386    OPC_RINT_D = FOP(26, FMT_D),
10387    OPC_CLASS_D = FOP(27, FMT_D),
10388    OPC_MIN_D = FOP(28, FMT_D),
10389    OPC_RECIP2_D = FOP(28, FMT_D),
10390    OPC_MINA_D = FOP(29, FMT_D),
10391    OPC_RECIP1_D = FOP(29, FMT_D),
10392    OPC_MAX_D = FOP(30, FMT_D),
10393    OPC_RSQRT1_D = FOP(30, FMT_D),
10394    OPC_MAXA_D = FOP(31, FMT_D),
10395    OPC_RSQRT2_D = FOP(31, FMT_D),
10396    OPC_CVT_S_D = FOP(32, FMT_D),
10397    OPC_CVT_W_D = FOP(36, FMT_D),
10398    OPC_CVT_L_D = FOP(37, FMT_D),
10399    OPC_CMP_F_D = FOP (48, FMT_D),
10400    OPC_CMP_UN_D = FOP (49, FMT_D),
10401    OPC_CMP_EQ_D = FOP (50, FMT_D),
10402    OPC_CMP_UEQ_D = FOP (51, FMT_D),
10403    OPC_CMP_OLT_D = FOP (52, FMT_D),
10404    OPC_CMP_ULT_D = FOP (53, FMT_D),
10405    OPC_CMP_OLE_D = FOP (54, FMT_D),
10406    OPC_CMP_ULE_D = FOP (55, FMT_D),
10407    OPC_CMP_SF_D = FOP (56, FMT_D),
10408    OPC_CMP_NGLE_D = FOP (57, FMT_D),
10409    OPC_CMP_SEQ_D = FOP (58, FMT_D),
10410    OPC_CMP_NGL_D = FOP (59, FMT_D),
10411    OPC_CMP_LT_D = FOP (60, FMT_D),
10412    OPC_CMP_NGE_D = FOP (61, FMT_D),
10413    OPC_CMP_LE_D = FOP (62, FMT_D),
10414    OPC_CMP_NGT_D = FOP (63, FMT_D),
10415
10416    OPC_CVT_S_W = FOP(32, FMT_W),
10417    OPC_CVT_D_W = FOP(33, FMT_W),
10418    OPC_CVT_S_L = FOP(32, FMT_L),
10419    OPC_CVT_D_L = FOP(33, FMT_L),
10420    OPC_CVT_PS_PW = FOP(38, FMT_W),
10421
10422    OPC_ADD_PS = FOP(0, FMT_PS),
10423    OPC_SUB_PS = FOP(1, FMT_PS),
10424    OPC_MUL_PS = FOP(2, FMT_PS),
10425    OPC_DIV_PS = FOP(3, FMT_PS),
10426    OPC_ABS_PS = FOP(5, FMT_PS),
10427    OPC_MOV_PS = FOP(6, FMT_PS),
10428    OPC_NEG_PS = FOP(7, FMT_PS),
10429    OPC_MOVCF_PS = FOP(17, FMT_PS),
10430    OPC_MOVZ_PS = FOP(18, FMT_PS),
10431    OPC_MOVN_PS = FOP(19, FMT_PS),
10432    OPC_ADDR_PS = FOP(24, FMT_PS),
10433    OPC_MULR_PS = FOP(26, FMT_PS),
10434    OPC_RECIP2_PS = FOP(28, FMT_PS),
10435    OPC_RECIP1_PS = FOP(29, FMT_PS),
10436    OPC_RSQRT1_PS = FOP(30, FMT_PS),
10437    OPC_RSQRT2_PS = FOP(31, FMT_PS),
10438
10439    OPC_CVT_S_PU = FOP(32, FMT_PS),
10440    OPC_CVT_PW_PS = FOP(36, FMT_PS),
10441    OPC_CVT_S_PL = FOP(40, FMT_PS),
10442    OPC_PLL_PS = FOP(44, FMT_PS),
10443    OPC_PLU_PS = FOP(45, FMT_PS),
10444    OPC_PUL_PS = FOP(46, FMT_PS),
10445    OPC_PUU_PS = FOP(47, FMT_PS),
10446    OPC_CMP_F_PS = FOP (48, FMT_PS),
10447    OPC_CMP_UN_PS = FOP (49, FMT_PS),
10448    OPC_CMP_EQ_PS = FOP (50, FMT_PS),
10449    OPC_CMP_UEQ_PS = FOP (51, FMT_PS),
10450    OPC_CMP_OLT_PS = FOP (52, FMT_PS),
10451    OPC_CMP_ULT_PS = FOP (53, FMT_PS),
10452    OPC_CMP_OLE_PS = FOP (54, FMT_PS),
10453    OPC_CMP_ULE_PS = FOP (55, FMT_PS),
10454    OPC_CMP_SF_PS = FOP (56, FMT_PS),
10455    OPC_CMP_NGLE_PS = FOP (57, FMT_PS),
10456    OPC_CMP_SEQ_PS = FOP (58, FMT_PS),
10457    OPC_CMP_NGL_PS = FOP (59, FMT_PS),
10458    OPC_CMP_LT_PS = FOP (60, FMT_PS),
10459    OPC_CMP_NGE_PS = FOP (61, FMT_PS),
10460    OPC_CMP_LE_PS = FOP (62, FMT_PS),
10461    OPC_CMP_NGT_PS = FOP (63, FMT_PS),
10462};
10463
10464enum r6_f_cmp_op {
10465    R6_OPC_CMP_AF_S   = FOP(0, FMT_W),
10466    R6_OPC_CMP_UN_S   = FOP(1, FMT_W),
10467    R6_OPC_CMP_EQ_S   = FOP(2, FMT_W),
10468    R6_OPC_CMP_UEQ_S  = FOP(3, FMT_W),
10469    R6_OPC_CMP_LT_S   = FOP(4, FMT_W),
10470    R6_OPC_CMP_ULT_S  = FOP(5, FMT_W),
10471    R6_OPC_CMP_LE_S   = FOP(6, FMT_W),
10472    R6_OPC_CMP_ULE_S  = FOP(7, FMT_W),
10473    R6_OPC_CMP_SAF_S  = FOP(8, FMT_W),
10474    R6_OPC_CMP_SUN_S  = FOP(9, FMT_W),
10475    R6_OPC_CMP_SEQ_S  = FOP(10, FMT_W),
10476    R6_OPC_CMP_SEUQ_S = FOP(11, FMT_W),
10477    R6_OPC_CMP_SLT_S  = FOP(12, FMT_W),
10478    R6_OPC_CMP_SULT_S = FOP(13, FMT_W),
10479    R6_OPC_CMP_SLE_S  = FOP(14, FMT_W),
10480    R6_OPC_CMP_SULE_S = FOP(15, FMT_W),
10481    R6_OPC_CMP_OR_S   = FOP(17, FMT_W),
10482    R6_OPC_CMP_UNE_S  = FOP(18, FMT_W),
10483    R6_OPC_CMP_NE_S   = FOP(19, FMT_W),
10484    R6_OPC_CMP_SOR_S  = FOP(25, FMT_W),
10485    R6_OPC_CMP_SUNE_S = FOP(26, FMT_W),
10486    R6_OPC_CMP_SNE_S  = FOP(27, FMT_W),
10487
10488    R6_OPC_CMP_AF_D   = FOP(0, FMT_L),
10489    R6_OPC_CMP_UN_D   = FOP(1, FMT_L),
10490    R6_OPC_CMP_EQ_D   = FOP(2, FMT_L),
10491    R6_OPC_CMP_UEQ_D  = FOP(3, FMT_L),
10492    R6_OPC_CMP_LT_D   = FOP(4, FMT_L),
10493    R6_OPC_CMP_ULT_D  = FOP(5, FMT_L),
10494    R6_OPC_CMP_LE_D   = FOP(6, FMT_L),
10495    R6_OPC_CMP_ULE_D  = FOP(7, FMT_L),
10496    R6_OPC_CMP_SAF_D  = FOP(8, FMT_L),
10497    R6_OPC_CMP_SUN_D  = FOP(9, FMT_L),
10498    R6_OPC_CMP_SEQ_D  = FOP(10, FMT_L),
10499    R6_OPC_CMP_SEUQ_D = FOP(11, FMT_L),
10500    R6_OPC_CMP_SLT_D  = FOP(12, FMT_L),
10501    R6_OPC_CMP_SULT_D = FOP(13, FMT_L),
10502    R6_OPC_CMP_SLE_D  = FOP(14, FMT_L),
10503    R6_OPC_CMP_SULE_D = FOP(15, FMT_L),
10504    R6_OPC_CMP_OR_D   = FOP(17, FMT_L),
10505    R6_OPC_CMP_UNE_D  = FOP(18, FMT_L),
10506    R6_OPC_CMP_NE_D   = FOP(19, FMT_L),
10507    R6_OPC_CMP_SOR_D  = FOP(25, FMT_L),
10508    R6_OPC_CMP_SUNE_D = FOP(26, FMT_L),
10509    R6_OPC_CMP_SNE_D  = FOP(27, FMT_L),
10510};
10511static void gen_cp1 (DisasContext *ctx, uint32_t opc, int rt, int fs)
10512{
10513    TCGv t0 = tcg_temp_new();
10514
10515    switch (opc) {
10516    case OPC_MFC1:
10517        {
10518            TCGv_i32 fp0 = tcg_temp_new_i32();
10519
10520            gen_load_fpr32(ctx, fp0, fs);
10521            tcg_gen_ext_i32_tl(t0, fp0);
10522            tcg_temp_free_i32(fp0);
10523        }
10524        gen_store_gpr(t0, rt);
10525        break;
10526    case OPC_MTC1:
10527        gen_load_gpr(t0, rt);
10528        {
10529            TCGv_i32 fp0 = tcg_temp_new_i32();
10530
10531            tcg_gen_trunc_tl_i32(fp0, t0);
10532            gen_store_fpr32(ctx, fp0, fs);
10533            tcg_temp_free_i32(fp0);
10534        }
10535        break;
10536    case OPC_CFC1:
10537        gen_helper_1e0i(cfc1, t0, fs);
10538        gen_store_gpr(t0, rt);
10539        break;
10540    case OPC_CTC1:
10541        gen_load_gpr(t0, rt);
10542        save_cpu_state(ctx, 0);
10543        {
10544            TCGv_i32 fs_tmp = tcg_const_i32(fs);
10545
10546            gen_helper_0e2i(ctc1, t0, fs_tmp, rt);
10547            tcg_temp_free_i32(fs_tmp);
10548        }
10549        /* Stop translation as we may have changed hflags */
10550        ctx->base.is_jmp = DISAS_STOP;
10551        break;
10552#if defined(TARGET_MIPS64)
10553    case OPC_DMFC1:
10554        gen_load_fpr64(ctx, t0, fs);
10555        gen_store_gpr(t0, rt);
10556        break;
10557    case OPC_DMTC1:
10558        gen_load_gpr(t0, rt);
10559        gen_store_fpr64(ctx, t0, fs);
10560        break;
10561#endif
10562    case OPC_MFHC1:
10563        {
10564            TCGv_i32 fp0 = tcg_temp_new_i32();
10565
10566            gen_load_fpr32h(ctx, fp0, fs);
10567            tcg_gen_ext_i32_tl(t0, fp0);
10568            tcg_temp_free_i32(fp0);
10569        }
10570        gen_store_gpr(t0, rt);
10571        break;
10572    case OPC_MTHC1:
10573        gen_load_gpr(t0, rt);
10574        {
10575            TCGv_i32 fp0 = tcg_temp_new_i32();
10576
10577            tcg_gen_trunc_tl_i32(fp0, t0);
10578            gen_store_fpr32h(ctx, fp0, fs);
10579            tcg_temp_free_i32(fp0);
10580        }
10581        break;
10582    default:
10583        MIPS_INVAL("cp1 move");
10584        generate_exception_end(ctx, EXCP_RI);
10585        goto out;
10586    }
10587
10588 out:
10589    tcg_temp_free(t0);
10590}
10591
10592static void gen_movci (DisasContext *ctx, int rd, int rs, int cc, int tf)
10593{
10594    TCGLabel *l1;
10595    TCGCond cond;
10596    TCGv_i32 t0;
10597
10598    if (rd == 0) {
10599        /* Treat as NOP. */
10600        return;
10601    }
10602
10603    if (tf)
10604        cond = TCG_COND_EQ;
10605    else
10606        cond = TCG_COND_NE;
10607
10608    l1 = gen_new_label();
10609    t0 = tcg_temp_new_i32();
10610    tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
10611    tcg_gen_brcondi_i32(cond, t0, 0, l1);
10612    tcg_temp_free_i32(t0);
10613    if (rs == 0) {
10614        tcg_gen_movi_tl(cpu_gpr[rd], 0);
10615    } else {
10616        tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
10617    }
10618    gen_set_label(l1);
10619}
10620
10621static inline void gen_movcf_s(DisasContext *ctx, int fs, int fd, int cc,
10622                               int tf)
10623{
10624    int cond;
10625    TCGv_i32 t0 = tcg_temp_new_i32();
10626    TCGLabel *l1 = gen_new_label();
10627
10628    if (tf)
10629        cond = TCG_COND_EQ;
10630    else
10631        cond = TCG_COND_NE;
10632
10633    tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
10634    tcg_gen_brcondi_i32(cond, t0, 0, l1);
10635    gen_load_fpr32(ctx, t0, fs);
10636    gen_store_fpr32(ctx, t0, fd);
10637    gen_set_label(l1);
10638    tcg_temp_free_i32(t0);
10639}
10640
10641static inline void gen_movcf_d (DisasContext *ctx, int fs, int fd, int cc, int tf)
10642{
10643    int cond;
10644    TCGv_i32 t0 = tcg_temp_new_i32();
10645    TCGv_i64 fp0;
10646    TCGLabel *l1 = gen_new_label();
10647
10648    if (tf)
10649        cond = TCG_COND_EQ;
10650    else
10651        cond = TCG_COND_NE;
10652
10653    tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
10654    tcg_gen_brcondi_i32(cond, t0, 0, l1);
10655    tcg_temp_free_i32(t0);
10656    fp0 = tcg_temp_new_i64();
10657    gen_load_fpr64(ctx, fp0, fs);
10658    gen_store_fpr64(ctx, fp0, fd);
10659    tcg_temp_free_i64(fp0);
10660    gen_set_label(l1);
10661}
10662
10663static inline void gen_movcf_ps(DisasContext *ctx, int fs, int fd,
10664                                int cc, int tf)
10665{
10666    int cond;
10667    TCGv_i32 t0 = tcg_temp_new_i32();
10668    TCGLabel *l1 = gen_new_label();
10669    TCGLabel *l2 = gen_new_label();
10670
10671    if (tf)
10672        cond = TCG_COND_EQ;
10673    else
10674        cond = TCG_COND_NE;
10675
10676    tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
10677    tcg_gen_brcondi_i32(cond, t0, 0, l1);
10678    gen_load_fpr32(ctx, t0, fs);
10679    gen_store_fpr32(ctx, t0, fd);
10680    gen_set_label(l1);
10681
10682    tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc+1));
10683    tcg_gen_brcondi_i32(cond, t0, 0, l2);
10684    gen_load_fpr32h(ctx, t0, fs);
10685    gen_store_fpr32h(ctx, t0, fd);
10686    tcg_temp_free_i32(t0);
10687    gen_set_label(l2);
10688}
10689
10690static void gen_sel_s(DisasContext *ctx, enum fopcode op1, int fd, int ft,
10691                      int fs)
10692{
10693    TCGv_i32 t1 = tcg_const_i32(0);
10694    TCGv_i32 fp0 = tcg_temp_new_i32();
10695    TCGv_i32 fp1 = tcg_temp_new_i32();
10696    TCGv_i32 fp2 = tcg_temp_new_i32();
10697    gen_load_fpr32(ctx, fp0, fd);
10698    gen_load_fpr32(ctx, fp1, ft);
10699    gen_load_fpr32(ctx, fp2, fs);
10700
10701    switch (op1) {
10702    case OPC_SEL_S:
10703        tcg_gen_andi_i32(fp0, fp0, 1);
10704        tcg_gen_movcond_i32(TCG_COND_NE, fp0, fp0, t1, fp1, fp2);
10705        break;
10706    case OPC_SELEQZ_S:
10707        tcg_gen_andi_i32(fp1, fp1, 1);
10708        tcg_gen_movcond_i32(TCG_COND_EQ, fp0, fp1, t1, fp2, t1);
10709        break;
10710    case OPC_SELNEZ_S:
10711        tcg_gen_andi_i32(fp1, fp1, 1);
10712        tcg_gen_movcond_i32(TCG_COND_NE, fp0, fp1, t1, fp2, t1);
10713        break;
10714    default:
10715        MIPS_INVAL("gen_sel_s");
10716        generate_exception_end(ctx, EXCP_RI);
10717        break;
10718    }
10719
10720    gen_store_fpr32(ctx, fp0, fd);
10721    tcg_temp_free_i32(fp2);
10722    tcg_temp_free_i32(fp1);
10723    tcg_temp_free_i32(fp0);
10724    tcg_temp_free_i32(t1);
10725}
10726
10727static void gen_sel_d(DisasContext *ctx, enum fopcode op1, int fd, int ft,
10728                      int fs)
10729{
10730    TCGv_i64 t1 = tcg_const_i64(0);
10731    TCGv_i64 fp0 = tcg_temp_new_i64();
10732    TCGv_i64 fp1 = tcg_temp_new_i64();
10733    TCGv_i64 fp2 = tcg_temp_new_i64();
10734    gen_load_fpr64(ctx, fp0, fd);
10735    gen_load_fpr64(ctx, fp1, ft);
10736    gen_load_fpr64(ctx, fp2, fs);
10737
10738    switch (op1) {
10739    case OPC_SEL_D:
10740        tcg_gen_andi_i64(fp0, fp0, 1);
10741        tcg_gen_movcond_i64(TCG_COND_NE, fp0, fp0, t1, fp1, fp2);
10742        break;
10743    case OPC_SELEQZ_D:
10744        tcg_gen_andi_i64(fp1, fp1, 1);
10745        tcg_gen_movcond_i64(TCG_COND_EQ, fp0, fp1, t1, fp2, t1);
10746        break;
10747    case OPC_SELNEZ_D:
10748        tcg_gen_andi_i64(fp1, fp1, 1);
10749        tcg_gen_movcond_i64(TCG_COND_NE, fp0, fp1, t1, fp2, t1);
10750        break;
10751    default:
10752        MIPS_INVAL("gen_sel_d");
10753        generate_exception_end(ctx, EXCP_RI);
10754        break;
10755    }
10756
10757    gen_store_fpr64(ctx, fp0, fd);
10758    tcg_temp_free_i64(fp2);
10759    tcg_temp_free_i64(fp1);
10760    tcg_temp_free_i64(fp0);
10761    tcg_temp_free_i64(t1);
10762}
10763
10764static void gen_farith (DisasContext *ctx, enum fopcode op1,
10765                        int ft, int fs, int fd, int cc)
10766{
10767    uint32_t func = ctx->opcode & 0x3f;
10768    switch (op1) {
10769    case OPC_ADD_S:
10770        {
10771            TCGv_i32 fp0 = tcg_temp_new_i32();
10772            TCGv_i32 fp1 = tcg_temp_new_i32();
10773
10774            gen_load_fpr32(ctx, fp0, fs);
10775            gen_load_fpr32(ctx, fp1, ft);
10776            gen_helper_float_add_s(fp0, cpu_env, fp0, fp1);
10777            tcg_temp_free_i32(fp1);
10778            gen_store_fpr32(ctx, fp0, fd);
10779            tcg_temp_free_i32(fp0);
10780        }
10781        break;
10782    case OPC_SUB_S:
10783        {
10784            TCGv_i32 fp0 = tcg_temp_new_i32();
10785            TCGv_i32 fp1 = tcg_temp_new_i32();
10786
10787            gen_load_fpr32(ctx, fp0, fs);
10788            gen_load_fpr32(ctx, fp1, ft);
10789            gen_helper_float_sub_s(fp0, cpu_env, fp0, fp1);
10790            tcg_temp_free_i32(fp1);
10791            gen_store_fpr32(ctx, fp0, fd);
10792            tcg_temp_free_i32(fp0);
10793        }
10794        break;
10795    case OPC_MUL_S:
10796        {
10797            TCGv_i32 fp0 = tcg_temp_new_i32();
10798            TCGv_i32 fp1 = tcg_temp_new_i32();
10799
10800            gen_load_fpr32(ctx, fp0, fs);
10801            gen_load_fpr32(ctx, fp1, ft);
10802            gen_helper_float_mul_s(fp0, cpu_env, fp0, fp1);
10803            tcg_temp_free_i32(fp1);
10804            gen_store_fpr32(ctx, fp0, fd);
10805            tcg_temp_free_i32(fp0);
10806        }
10807        break;
10808    case OPC_DIV_S:
10809        {
10810            TCGv_i32 fp0 = tcg_temp_new_i32();
10811            TCGv_i32 fp1 = tcg_temp_new_i32();
10812
10813            gen_load_fpr32(ctx, fp0, fs);
10814            gen_load_fpr32(ctx, fp1, ft);
10815            gen_helper_float_div_s(fp0, cpu_env, fp0, fp1);
10816            tcg_temp_free_i32(fp1);
10817            gen_store_fpr32(ctx, fp0, fd);
10818            tcg_temp_free_i32(fp0);
10819        }
10820        break;
10821    case OPC_SQRT_S:
10822        {
10823            TCGv_i32 fp0 = tcg_temp_new_i32();
10824
10825            gen_load_fpr32(ctx, fp0, fs);
10826            gen_helper_float_sqrt_s(fp0, cpu_env, fp0);
10827            gen_store_fpr32(ctx, fp0, fd);
10828            tcg_temp_free_i32(fp0);
10829        }
10830        break;
10831    case OPC_ABS_S:
10832        {
10833            TCGv_i32 fp0 = tcg_temp_new_i32();
10834
10835            gen_load_fpr32(ctx, fp0, fs);
10836            if (ctx->abs2008) {
10837                tcg_gen_andi_i32(fp0, fp0, 0x7fffffffUL);
10838            } else {
10839                gen_helper_float_abs_s(fp0, fp0);
10840            }
10841            gen_store_fpr32(ctx, fp0, fd);
10842            tcg_temp_free_i32(fp0);
10843        }
10844        break;
10845    case OPC_MOV_S:
10846        {
10847            TCGv_i32 fp0 = tcg_temp_new_i32();
10848
10849            gen_load_fpr32(ctx, fp0, fs);
10850            gen_store_fpr32(ctx, fp0, fd);
10851            tcg_temp_free_i32(fp0);
10852        }
10853        break;
10854    case OPC_NEG_S:
10855        {
10856            TCGv_i32 fp0 = tcg_temp_new_i32();
10857
10858            gen_load_fpr32(ctx, fp0, fs);
10859            if (ctx->abs2008) {
10860                tcg_gen_xori_i32(fp0, fp0, 1UL << 31);
10861            } else {
10862                gen_helper_float_chs_s(fp0, fp0);
10863            }
10864            gen_store_fpr32(ctx, fp0, fd);
10865            tcg_temp_free_i32(fp0);
10866        }
10867        break;
10868    case OPC_ROUND_L_S:
10869        check_cp1_64bitmode(ctx);
10870        {
10871            TCGv_i32 fp32 = tcg_temp_new_i32();
10872            TCGv_i64 fp64 = tcg_temp_new_i64();
10873
10874            gen_load_fpr32(ctx, fp32, fs);
10875            if (ctx->nan2008) {
10876                gen_helper_float_round_2008_l_s(fp64, cpu_env, fp32);
10877            } else {
10878                gen_helper_float_round_l_s(fp64, cpu_env, fp32);
10879            }
10880            tcg_temp_free_i32(fp32);
10881            gen_store_fpr64(ctx, fp64, fd);
10882            tcg_temp_free_i64(fp64);
10883        }
10884        break;
10885    case OPC_TRUNC_L_S:
10886        check_cp1_64bitmode(ctx);
10887        {
10888            TCGv_i32 fp32 = tcg_temp_new_i32();
10889            TCGv_i64 fp64 = tcg_temp_new_i64();
10890
10891            gen_load_fpr32(ctx, fp32, fs);
10892            if (ctx->nan2008) {
10893                gen_helper_float_trunc_2008_l_s(fp64, cpu_env, fp32);
10894            } else {
10895                gen_helper_float_trunc_l_s(fp64, cpu_env, fp32);
10896            }
10897            tcg_temp_free_i32(fp32);
10898            gen_store_fpr64(ctx, fp64, fd);
10899            tcg_temp_free_i64(fp64);
10900        }
10901        break;
10902    case OPC_CEIL_L_S:
10903        check_cp1_64bitmode(ctx);
10904        {
10905            TCGv_i32 fp32 = tcg_temp_new_i32();
10906            TCGv_i64 fp64 = tcg_temp_new_i64();
10907
10908            gen_load_fpr32(ctx, fp32, fs);
10909            if (ctx->nan2008) {
10910                gen_helper_float_ceil_2008_l_s(fp64, cpu_env, fp32);
10911            } else {
10912                gen_helper_float_ceil_l_s(fp64, cpu_env, fp32);
10913            }
10914            tcg_temp_free_i32(fp32);
10915            gen_store_fpr64(ctx, fp64, fd);
10916            tcg_temp_free_i64(fp64);
10917        }
10918        break;
10919    case OPC_FLOOR_L_S:
10920        check_cp1_64bitmode(ctx);
10921        {
10922            TCGv_i32 fp32 = tcg_temp_new_i32();
10923            TCGv_i64 fp64 = tcg_temp_new_i64();
10924
10925            gen_load_fpr32(ctx, fp32, fs);
10926            if (ctx->nan2008) {
10927                gen_helper_float_floor_2008_l_s(fp64, cpu_env, fp32);
10928            } else {
10929                gen_helper_float_floor_l_s(fp64, cpu_env, fp32);
10930            }
10931            tcg_temp_free_i32(fp32);
10932            gen_store_fpr64(ctx, fp64, fd);
10933            tcg_temp_free_i64(fp64);
10934        }
10935        break;
10936    case OPC_ROUND_W_S:
10937        {
10938            TCGv_i32 fp0 = tcg_temp_new_i32();
10939
10940            gen_load_fpr32(ctx, fp0, fs);
10941            if (ctx->nan2008) {
10942                gen_helper_float_round_2008_w_s(fp0, cpu_env, fp0);
10943            } else {
10944                gen_helper_float_round_w_s(fp0, cpu_env, fp0);
10945            }
10946            gen_store_fpr32(ctx, fp0, fd);
10947            tcg_temp_free_i32(fp0);
10948        }
10949        break;
10950    case OPC_TRUNC_W_S:
10951        {
10952            TCGv_i32 fp0 = tcg_temp_new_i32();
10953
10954            gen_load_fpr32(ctx, fp0, fs);
10955            if (ctx->nan2008) {
10956                gen_helper_float_trunc_2008_w_s(fp0, cpu_env, fp0);
10957            } else {
10958                gen_helper_float_trunc_w_s(fp0, cpu_env, fp0);
10959            }
10960            gen_store_fpr32(ctx, fp0, fd);
10961            tcg_temp_free_i32(fp0);
10962        }
10963        break;
10964    case OPC_CEIL_W_S:
10965        {
10966            TCGv_i32 fp0 = tcg_temp_new_i32();
10967
10968            gen_load_fpr32(ctx, fp0, fs);
10969            if (ctx->nan2008) {
10970                gen_helper_float_ceil_2008_w_s(fp0, cpu_env, fp0);
10971            } else {
10972                gen_helper_float_ceil_w_s(fp0, cpu_env, fp0);
10973            }
10974            gen_store_fpr32(ctx, fp0, fd);
10975            tcg_temp_free_i32(fp0);
10976        }
10977        break;
10978    case OPC_FLOOR_W_S:
10979        {
10980            TCGv_i32 fp0 = tcg_temp_new_i32();
10981
10982            gen_load_fpr32(ctx, fp0, fs);
10983            if (ctx->nan2008) {
10984                gen_helper_float_floor_2008_w_s(fp0, cpu_env, fp0);
10985            } else {
10986                gen_helper_float_floor_w_s(fp0, cpu_env, fp0);
10987            }
10988            gen_store_fpr32(ctx, fp0, fd);
10989            tcg_temp_free_i32(fp0);
10990        }
10991        break;
10992    case OPC_SEL_S:
10993        check_insn(ctx, ISA_MIPS32R6);
10994        gen_sel_s(ctx, op1, fd, ft, fs);
10995        break;
10996    case OPC_SELEQZ_S:
10997        check_insn(ctx, ISA_MIPS32R6);
10998        gen_sel_s(ctx, op1, fd, ft, fs);
10999        break;
11000    case OPC_SELNEZ_S:
11001        check_insn(ctx, ISA_MIPS32R6);
11002        gen_sel_s(ctx, op1, fd, ft, fs);
11003        break;
11004    case OPC_MOVCF_S:
11005        check_insn_opc_removed(ctx, ISA_MIPS32R6);
11006        gen_movcf_s(ctx, fs, fd, (ft >> 2) & 0x7, ft & 0x1);
11007        break;
11008    case OPC_MOVZ_S:
11009        check_insn_opc_removed(ctx, ISA_MIPS32R6);
11010        {
11011            TCGLabel *l1 = gen_new_label();
11012            TCGv_i32 fp0;
11013
11014            if (ft != 0) {
11015                tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[ft], 0, l1);
11016            }
11017            fp0 = tcg_temp_new_i32();
11018            gen_load_fpr32(ctx, fp0, fs);
11019            gen_store_fpr32(ctx, fp0, fd);
11020            tcg_temp_free_i32(fp0);
11021            gen_set_label(l1);
11022        }
11023        break;
11024    case OPC_MOVN_S:
11025        check_insn_opc_removed(ctx, ISA_MIPS32R6);
11026        {
11027            TCGLabel *l1 = gen_new_label();
11028            TCGv_i32 fp0;
11029
11030            if (ft != 0) {
11031                tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[ft], 0, l1);
11032                fp0 = tcg_temp_new_i32();
11033                gen_load_fpr32(ctx, fp0, fs);
11034                gen_store_fpr32(ctx, fp0, fd);
11035                tcg_temp_free_i32(fp0);
11036                gen_set_label(l1);
11037            }
11038        }
11039        break;
11040    case OPC_RECIP_S:
11041        {
11042            TCGv_i32 fp0 = tcg_temp_new_i32();
11043
11044            gen_load_fpr32(ctx, fp0, fs);
11045            gen_helper_float_recip_s(fp0, cpu_env, fp0);
11046            gen_store_fpr32(ctx, fp0, fd);
11047            tcg_temp_free_i32(fp0);
11048        }
11049        break;
11050    case OPC_RSQRT_S:
11051        {
11052            TCGv_i32 fp0 = tcg_temp_new_i32();
11053
11054            gen_load_fpr32(ctx, fp0, fs);
11055            gen_helper_float_rsqrt_s(fp0, cpu_env, fp0);
11056            gen_store_fpr32(ctx, fp0, fd);
11057            tcg_temp_free_i32(fp0);
11058        }
11059        break;
11060    case OPC_MADDF_S:
11061        check_insn(ctx, ISA_MIPS32R6);
11062        {
11063            TCGv_i32 fp0 = tcg_temp_new_i32();
11064            TCGv_i32 fp1 = tcg_temp_new_i32();
11065            TCGv_i32 fp2 = tcg_temp_new_i32();
11066            gen_load_fpr32(ctx, fp0, fs);
11067            gen_load_fpr32(ctx, fp1, ft);
11068            gen_load_fpr32(ctx, fp2, fd);
11069            gen_helper_float_maddf_s(fp2, cpu_env, fp0, fp1, fp2);
11070            gen_store_fpr32(ctx, fp2, fd);
11071            tcg_temp_free_i32(fp2);
11072            tcg_temp_free_i32(fp1);
11073            tcg_temp_free_i32(fp0);
11074        }
11075        break;
11076    case OPC_MSUBF_S:
11077        check_insn(ctx, ISA_MIPS32R6);
11078        {
11079            TCGv_i32 fp0 = tcg_temp_new_i32();
11080            TCGv_i32 fp1 = tcg_temp_new_i32();
11081            TCGv_i32 fp2 = tcg_temp_new_i32();
11082            gen_load_fpr32(ctx, fp0, fs);
11083            gen_load_fpr32(ctx, fp1, ft);
11084            gen_load_fpr32(ctx, fp2, fd);
11085            gen_helper_float_msubf_s(fp2, cpu_env, fp0, fp1, fp2);
11086            gen_store_fpr32(ctx, fp2, fd);
11087            tcg_temp_free_i32(fp2);
11088            tcg_temp_free_i32(fp1);
11089            tcg_temp_free_i32(fp0);
11090        }
11091        break;
11092    case OPC_RINT_S:
11093        check_insn(ctx, ISA_MIPS32R6);
11094        {
11095            TCGv_i32 fp0 = tcg_temp_new_i32();
11096            gen_load_fpr32(ctx, fp0, fs);
11097            gen_helper_float_rint_s(fp0, cpu_env, fp0);
11098            gen_store_fpr32(ctx, fp0, fd);
11099            tcg_temp_free_i32(fp0);
11100        }
11101        break;
11102    case OPC_CLASS_S:
11103        check_insn(ctx, ISA_MIPS32R6);
11104        {
11105            TCGv_i32 fp0 = tcg_temp_new_i32();
11106            gen_load_fpr32(ctx, fp0, fs);
11107            gen_helper_float_class_s(fp0, cpu_env, fp0);
11108            gen_store_fpr32(ctx, fp0, fd);
11109            tcg_temp_free_i32(fp0);
11110        }
11111        break;
11112    case OPC_MIN_S: /* OPC_RECIP2_S */
11113        if (ctx->insn_flags & ISA_MIPS32R6) {
11114            /* OPC_MIN_S */
11115            TCGv_i32 fp0 = tcg_temp_new_i32();
11116            TCGv_i32 fp1 = tcg_temp_new_i32();
11117            TCGv_i32 fp2 = tcg_temp_new_i32();
11118            gen_load_fpr32(ctx, fp0, fs);
11119            gen_load_fpr32(ctx, fp1, ft);
11120            gen_helper_float_min_s(fp2, cpu_env, fp0, fp1);
11121            gen_store_fpr32(ctx, fp2, fd);
11122            tcg_temp_free_i32(fp2);
11123            tcg_temp_free_i32(fp1);
11124            tcg_temp_free_i32(fp0);
11125        } else {
11126            /* OPC_RECIP2_S */
11127            check_cp1_64bitmode(ctx);
11128            {
11129                TCGv_i32 fp0 = tcg_temp_new_i32();
11130                TCGv_i32 fp1 = tcg_temp_new_i32();
11131
11132                gen_load_fpr32(ctx, fp0, fs);
11133                gen_load_fpr32(ctx, fp1, ft);
11134                gen_helper_float_recip2_s(fp0, cpu_env, fp0, fp1);
11135                tcg_temp_free_i32(fp1);
11136                gen_store_fpr32(ctx, fp0, fd);
11137                tcg_temp_free_i32(fp0);
11138            }
11139        }
11140        break;
11141    case OPC_MINA_S: /* OPC_RECIP1_S */
11142        if (ctx->insn_flags & ISA_MIPS32R6) {
11143            /* OPC_MINA_S */
11144            TCGv_i32 fp0 = tcg_temp_new_i32();
11145            TCGv_i32 fp1 = tcg_temp_new_i32();
11146            TCGv_i32 fp2 = tcg_temp_new_i32();
11147            gen_load_fpr32(ctx, fp0, fs);
11148            gen_load_fpr32(ctx, fp1, ft);
11149            gen_helper_float_mina_s(fp2, cpu_env, fp0, fp1);
11150            gen_store_fpr32(ctx, fp2, fd);
11151            tcg_temp_free_i32(fp2);
11152            tcg_temp_free_i32(fp1);
11153            tcg_temp_free_i32(fp0);
11154        } else {
11155            /* OPC_RECIP1_S */
11156            check_cp1_64bitmode(ctx);
11157            {
11158                TCGv_i32 fp0 = tcg_temp_new_i32();
11159
11160                gen_load_fpr32(ctx, fp0, fs);
11161                gen_helper_float_recip1_s(fp0, cpu_env, fp0);
11162                gen_store_fpr32(ctx, fp0, fd);
11163                tcg_temp_free_i32(fp0);
11164            }
11165        }
11166        break;
11167    case OPC_MAX_S: /* OPC_RSQRT1_S */
11168        if (ctx->insn_flags & ISA_MIPS32R6) {
11169            /* OPC_MAX_S */
11170            TCGv_i32 fp0 = tcg_temp_new_i32();
11171            TCGv_i32 fp1 = tcg_temp_new_i32();
11172            gen_load_fpr32(ctx, fp0, fs);
11173            gen_load_fpr32(ctx, fp1, ft);
11174            gen_helper_float_max_s(fp1, cpu_env, fp0, fp1);
11175            gen_store_fpr32(ctx, fp1, fd);
11176            tcg_temp_free_i32(fp1);
11177            tcg_temp_free_i32(fp0);
11178        } else {
11179            /* OPC_RSQRT1_S */
11180            check_cp1_64bitmode(ctx);
11181            {
11182                TCGv_i32 fp0 = tcg_temp_new_i32();
11183
11184                gen_load_fpr32(ctx, fp0, fs);
11185                gen_helper_float_rsqrt1_s(fp0, cpu_env, fp0);
11186                gen_store_fpr32(ctx, fp0, fd);
11187                tcg_temp_free_i32(fp0);
11188            }
11189        }
11190        break;
11191    case OPC_MAXA_S: /* OPC_RSQRT2_S */
11192        if (ctx->insn_flags & ISA_MIPS32R6) {
11193            /* OPC_MAXA_S */
11194            TCGv_i32 fp0 = tcg_temp_new_i32();
11195            TCGv_i32 fp1 = tcg_temp_new_i32();
11196            gen_load_fpr32(ctx, fp0, fs);
11197            gen_load_fpr32(ctx, fp1, ft);
11198            gen_helper_float_maxa_s(fp1, cpu_env, fp0, fp1);
11199            gen_store_fpr32(ctx, fp1, fd);
11200            tcg_temp_free_i32(fp1);
11201            tcg_temp_free_i32(fp0);
11202        } else {
11203            /* OPC_RSQRT2_S */
11204            check_cp1_64bitmode(ctx);
11205            {
11206                TCGv_i32 fp0 = tcg_temp_new_i32();
11207                TCGv_i32 fp1 = tcg_temp_new_i32();
11208
11209                gen_load_fpr32(ctx, fp0, fs);
11210                gen_load_fpr32(ctx, fp1, ft);
11211                gen_helper_float_rsqrt2_s(fp0, cpu_env, fp0, fp1);
11212                tcg_temp_free_i32(fp1);
11213                gen_store_fpr32(ctx, fp0, fd);
11214                tcg_temp_free_i32(fp0);
11215            }
11216        }
11217        break;
11218    case OPC_CVT_D_S:
11219        check_cp1_registers(ctx, fd);
11220        {
11221            TCGv_i32 fp32 = tcg_temp_new_i32();
11222            TCGv_i64 fp64 = tcg_temp_new_i64();
11223
11224            gen_load_fpr32(ctx, fp32, fs);
11225            gen_helper_float_cvtd_s(fp64, cpu_env, fp32);
11226            tcg_temp_free_i32(fp32);
11227            gen_store_fpr64(ctx, fp64, fd);
11228            tcg_temp_free_i64(fp64);
11229        }
11230        break;
11231    case OPC_CVT_W_S:
11232        {
11233            TCGv_i32 fp0 = tcg_temp_new_i32();
11234
11235            gen_load_fpr32(ctx, fp0, fs);
11236            if (ctx->nan2008) {
11237                gen_helper_float_cvt_2008_w_s(fp0, cpu_env, fp0);
11238            } else {
11239                gen_helper_float_cvt_w_s(fp0, cpu_env, fp0);
11240            }
11241            gen_store_fpr32(ctx, fp0, fd);
11242            tcg_temp_free_i32(fp0);
11243        }
11244        break;
11245    case OPC_CVT_L_S:
11246        check_cp1_64bitmode(ctx);
11247        {
11248            TCGv_i32 fp32 = tcg_temp_new_i32();
11249            TCGv_i64 fp64 = tcg_temp_new_i64();
11250
11251            gen_load_fpr32(ctx, fp32, fs);
11252            if (ctx->nan2008) {
11253                gen_helper_float_cvt_2008_l_s(fp64, cpu_env, fp32);
11254            } else {
11255                gen_helper_float_cvt_l_s(fp64, cpu_env, fp32);
11256            }
11257            tcg_temp_free_i32(fp32);
11258            gen_store_fpr64(ctx, fp64, fd);
11259            tcg_temp_free_i64(fp64);
11260        }
11261        break;
11262    case OPC_CVT_PS_S:
11263        check_ps(ctx);
11264        {
11265            TCGv_i64 fp64 = tcg_temp_new_i64();
11266            TCGv_i32 fp32_0 = tcg_temp_new_i32();
11267            TCGv_i32 fp32_1 = tcg_temp_new_i32();
11268
11269            gen_load_fpr32(ctx, fp32_0, fs);
11270            gen_load_fpr32(ctx, fp32_1, ft);
11271            tcg_gen_concat_i32_i64(fp64, fp32_1, fp32_0);
11272            tcg_temp_free_i32(fp32_1);
11273            tcg_temp_free_i32(fp32_0);
11274            gen_store_fpr64(ctx, fp64, fd);
11275            tcg_temp_free_i64(fp64);
11276        }
11277        break;
11278    case OPC_CMP_F_S:
11279    case OPC_CMP_UN_S:
11280    case OPC_CMP_EQ_S:
11281    case OPC_CMP_UEQ_S:
11282    case OPC_CMP_OLT_S:
11283    case OPC_CMP_ULT_S:
11284    case OPC_CMP_OLE_S:
11285    case OPC_CMP_ULE_S:
11286    case OPC_CMP_SF_S:
11287    case OPC_CMP_NGLE_S:
11288    case OPC_CMP_SEQ_S:
11289    case OPC_CMP_NGL_S:
11290    case OPC_CMP_LT_S:
11291    case OPC_CMP_NGE_S:
11292    case OPC_CMP_LE_S:
11293    case OPC_CMP_NGT_S:
11294        check_insn_opc_removed(ctx, ISA_MIPS32R6);
11295        if (ctx->opcode & (1 << 6)) {
11296            gen_cmpabs_s(ctx, func-48, ft, fs, cc);
11297        } else {
11298            gen_cmp_s(ctx, func-48, ft, fs, cc);
11299        }
11300        break;
11301    case OPC_ADD_D:
11302        check_cp1_registers(ctx, fs | ft | fd);
11303        {
11304            TCGv_i64 fp0 = tcg_temp_new_i64();
11305            TCGv_i64 fp1 = tcg_temp_new_i64();
11306
11307            gen_load_fpr64(ctx, fp0, fs);
11308            gen_load_fpr64(ctx, fp1, ft);
11309            gen_helper_float_add_d(fp0, cpu_env, fp0, fp1);
11310            tcg_temp_free_i64(fp1);
11311            gen_store_fpr64(ctx, fp0, fd);
11312            tcg_temp_free_i64(fp0);
11313        }
11314        break;
11315    case OPC_SUB_D:
11316        check_cp1_registers(ctx, fs | ft | fd);
11317        {
11318            TCGv_i64 fp0 = tcg_temp_new_i64();
11319            TCGv_i64 fp1 = tcg_temp_new_i64();
11320
11321            gen_load_fpr64(ctx, fp0, fs);
11322            gen_load_fpr64(ctx, fp1, ft);
11323            gen_helper_float_sub_d(fp0, cpu_env, fp0, fp1);
11324            tcg_temp_free_i64(fp1);
11325            gen_store_fpr64(ctx, fp0, fd);
11326            tcg_temp_free_i64(fp0);
11327        }
11328        break;
11329    case OPC_MUL_D:
11330        check_cp1_registers(ctx, fs | ft | fd);
11331        {
11332            TCGv_i64 fp0 = tcg_temp_new_i64();
11333            TCGv_i64 fp1 = tcg_temp_new_i64();
11334
11335            gen_load_fpr64(ctx, fp0, fs);
11336            gen_load_fpr64(ctx, fp1, ft);
11337            gen_helper_float_mul_d(fp0, cpu_env, fp0, fp1);
11338            tcg_temp_free_i64(fp1);
11339            gen_store_fpr64(ctx, fp0, fd);
11340            tcg_temp_free_i64(fp0);
11341        }
11342        break;
11343    case OPC_DIV_D:
11344        check_cp1_registers(ctx, fs | ft | fd);
11345        {
11346            TCGv_i64 fp0 = tcg_temp_new_i64();
11347            TCGv_i64 fp1 = tcg_temp_new_i64();
11348
11349            gen_load_fpr64(ctx, fp0, fs);
11350            gen_load_fpr64(ctx, fp1, ft);
11351            gen_helper_float_div_d(fp0, cpu_env, fp0, fp1);
11352            tcg_temp_free_i64(fp1);
11353            gen_store_fpr64(ctx, fp0, fd);
11354            tcg_temp_free_i64(fp0);
11355        }
11356        break;
11357    case OPC_SQRT_D:
11358        check_cp1_registers(ctx, fs | fd);
11359        {
11360            TCGv_i64 fp0 = tcg_temp_new_i64();
11361
11362            gen_load_fpr64(ctx, fp0, fs);
11363            gen_helper_float_sqrt_d(fp0, cpu_env, fp0);
11364            gen_store_fpr64(ctx, fp0, fd);
11365            tcg_temp_free_i64(fp0);
11366        }
11367        break;
11368    case OPC_ABS_D:
11369        check_cp1_registers(ctx, fs | fd);
11370        {
11371            TCGv_i64 fp0 = tcg_temp_new_i64();
11372
11373            gen_load_fpr64(ctx, fp0, fs);
11374            if (ctx->abs2008) {
11375                tcg_gen_andi_i64(fp0, fp0, 0x7fffffffffffffffULL);
11376            } else {
11377                gen_helper_float_abs_d(fp0, fp0);
11378            }
11379            gen_store_fpr64(ctx, fp0, fd);
11380            tcg_temp_free_i64(fp0);
11381        }
11382        break;
11383    case OPC_MOV_D:
11384        check_cp1_registers(ctx, fs | fd);
11385        {
11386            TCGv_i64 fp0 = tcg_temp_new_i64();
11387
11388            gen_load_fpr64(ctx, fp0, fs);
11389            gen_store_fpr64(ctx, fp0, fd);
11390            tcg_temp_free_i64(fp0);
11391        }
11392        break;
11393    case OPC_NEG_D:
11394        check_cp1_registers(ctx, fs | fd);
11395        {
11396            TCGv_i64 fp0 = tcg_temp_new_i64();
11397
11398            gen_load_fpr64(ctx, fp0, fs);
11399            if (ctx->abs2008) {
11400                tcg_gen_xori_i64(fp0, fp0, 1ULL << 63);
11401            } else {
11402                gen_helper_float_chs_d(fp0, fp0);
11403            }
11404            gen_store_fpr64(ctx, fp0, fd);
11405            tcg_temp_free_i64(fp0);
11406        }
11407        break;
11408    case OPC_ROUND_L_D:
11409        check_cp1_64bitmode(ctx);
11410        {
11411            TCGv_i64 fp0 = tcg_temp_new_i64();
11412
11413            gen_load_fpr64(ctx, fp0, fs);
11414            if (ctx->nan2008) {
11415                gen_helper_float_round_2008_l_d(fp0, cpu_env, fp0);
11416            } else {
11417                gen_helper_float_round_l_d(fp0, cpu_env, fp0);
11418            }
11419            gen_store_fpr64(ctx, fp0, fd);
11420            tcg_temp_free_i64(fp0);
11421        }
11422        break;
11423    case OPC_TRUNC_L_D:
11424        check_cp1_64bitmode(ctx);
11425        {
11426            TCGv_i64 fp0 = tcg_temp_new_i64();
11427
11428            gen_load_fpr64(ctx, fp0, fs);
11429            if (ctx->nan2008) {
11430                gen_helper_float_trunc_2008_l_d(fp0, cpu_env, fp0);
11431            } else {
11432                gen_helper_float_trunc_l_d(fp0, cpu_env, fp0);
11433            }
11434            gen_store_fpr64(ctx, fp0, fd);
11435            tcg_temp_free_i64(fp0);
11436        }
11437        break;
11438    case OPC_CEIL_L_D:
11439        check_cp1_64bitmode(ctx);
11440        {
11441            TCGv_i64 fp0 = tcg_temp_new_i64();
11442
11443            gen_load_fpr64(ctx, fp0, fs);
11444            if (ctx->nan2008) {
11445                gen_helper_float_ceil_2008_l_d(fp0, cpu_env, fp0);
11446            } else {
11447                gen_helper_float_ceil_l_d(fp0, cpu_env, fp0);
11448            }
11449            gen_store_fpr64(ctx, fp0, fd);
11450            tcg_temp_free_i64(fp0);
11451        }
11452        break;
11453    case OPC_FLOOR_L_D:
11454        check_cp1_64bitmode(ctx);
11455        {
11456            TCGv_i64 fp0 = tcg_temp_new_i64();
11457
11458            gen_load_fpr64(ctx, fp0, fs);
11459            if (ctx->nan2008) {
11460                gen_helper_float_floor_2008_l_d(fp0, cpu_env, fp0);
11461            } else {
11462                gen_helper_float_floor_l_d(fp0, cpu_env, fp0);
11463            }
11464            gen_store_fpr64(ctx, fp0, fd);
11465            tcg_temp_free_i64(fp0);
11466        }
11467        break;
11468    case OPC_ROUND_W_D:
11469        check_cp1_registers(ctx, fs);
11470        {
11471            TCGv_i32 fp32 = tcg_temp_new_i32();
11472            TCGv_i64 fp64 = tcg_temp_new_i64();
11473
11474            gen_load_fpr64(ctx, fp64, fs);
11475            if (ctx->nan2008) {
11476                gen_helper_float_round_2008_w_d(fp32, cpu_env, fp64);
11477            } else {
11478                gen_helper_float_round_w_d(fp32, cpu_env, fp64);
11479            }
11480            tcg_temp_free_i64(fp64);
11481            gen_store_fpr32(ctx, fp32, fd);
11482            tcg_temp_free_i32(fp32);
11483        }
11484        break;
11485    case OPC_TRUNC_W_D:
11486        check_cp1_registers(ctx, fs);
11487        {
11488            TCGv_i32 fp32 = tcg_temp_new_i32();
11489            TCGv_i64 fp64 = tcg_temp_new_i64();
11490
11491            gen_load_fpr64(ctx, fp64, fs);
11492            if (ctx->nan2008) {
11493                gen_helper_float_trunc_2008_w_d(fp32, cpu_env, fp64);
11494            } else {
11495                gen_helper_float_trunc_w_d(fp32, cpu_env, fp64);
11496            }
11497            tcg_temp_free_i64(fp64);
11498            gen_store_fpr32(ctx, fp32, fd);
11499            tcg_temp_free_i32(fp32);
11500        }
11501        break;
11502    case OPC_CEIL_W_D:
11503        check_cp1_registers(ctx, fs);
11504        {
11505            TCGv_i32 fp32 = tcg_temp_new_i32();
11506            TCGv_i64 fp64 = tcg_temp_new_i64();
11507
11508            gen_load_fpr64(ctx, fp64, fs);
11509            if (ctx->nan2008) {
11510                gen_helper_float_ceil_2008_w_d(fp32, cpu_env, fp64);
11511            } else {
11512                gen_helper_float_ceil_w_d(fp32, cpu_env, fp64);
11513            }
11514            tcg_temp_free_i64(fp64);
11515            gen_store_fpr32(ctx, fp32, fd);
11516            tcg_temp_free_i32(fp32);
11517        }
11518        break;
11519    case OPC_FLOOR_W_D:
11520        check_cp1_registers(ctx, fs);
11521        {
11522            TCGv_i32 fp32 = tcg_temp_new_i32();
11523            TCGv_i64 fp64 = tcg_temp_new_i64();
11524
11525            gen_load_fpr64(ctx, fp64, fs);
11526            if (ctx->nan2008) {
11527                gen_helper_float_floor_2008_w_d(fp32, cpu_env, fp64);
11528            } else {
11529                gen_helper_float_floor_w_d(fp32, cpu_env, fp64);
11530            }
11531            tcg_temp_free_i64(fp64);
11532            gen_store_fpr32(ctx, fp32, fd);
11533            tcg_temp_free_i32(fp32);
11534        }
11535        break;
11536    case OPC_SEL_D:
11537        check_insn(ctx, ISA_MIPS32R6);
11538        gen_sel_d(ctx, op1, fd, ft, fs);
11539        break;
11540    case OPC_SELEQZ_D:
11541        check_insn(ctx, ISA_MIPS32R6);
11542        gen_sel_d(ctx, op1, fd, ft, fs);
11543        break;
11544    case OPC_SELNEZ_D:
11545        check_insn(ctx, ISA_MIPS32R6);
11546        gen_sel_d(ctx, op1, fd, ft, fs);
11547        break;
11548    case OPC_MOVCF_D:
11549        check_insn_opc_removed(ctx, ISA_MIPS32R6);
11550        gen_movcf_d(ctx, fs, fd, (ft >> 2) & 0x7, ft & 0x1);
11551        break;
11552    case OPC_MOVZ_D:
11553        check_insn_opc_removed(ctx, ISA_MIPS32R6);
11554        {
11555            TCGLabel *l1 = gen_new_label();
11556            TCGv_i64 fp0;
11557
11558            if (ft != 0) {
11559                tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[ft], 0, l1);
11560            }
11561            fp0 = tcg_temp_new_i64();
11562            gen_load_fpr64(ctx, fp0, fs);
11563            gen_store_fpr64(ctx, fp0, fd);
11564            tcg_temp_free_i64(fp0);
11565            gen_set_label(l1);
11566        }
11567        break;
11568    case OPC_MOVN_D:
11569        check_insn_opc_removed(ctx, ISA_MIPS32R6);
11570        {
11571            TCGLabel *l1 = gen_new_label();
11572            TCGv_i64 fp0;
11573
11574            if (ft != 0) {
11575                tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[ft], 0, l1);
11576                fp0 = tcg_temp_new_i64();
11577                gen_load_fpr64(ctx, fp0, fs);
11578                gen_store_fpr64(ctx, fp0, fd);
11579                tcg_temp_free_i64(fp0);
11580                gen_set_label(l1);
11581            }
11582        }
11583        break;
11584    case OPC_RECIP_D:
11585        check_cp1_registers(ctx, fs | fd);
11586        {
11587            TCGv_i64 fp0 = tcg_temp_new_i64();
11588
11589            gen_load_fpr64(ctx, fp0, fs);
11590            gen_helper_float_recip_d(fp0, cpu_env, fp0);
11591            gen_store_fpr64(ctx, fp0, fd);
11592            tcg_temp_free_i64(fp0);
11593        }
11594        break;
11595    case OPC_RSQRT_D:
11596        check_cp1_registers(ctx, fs | fd);
11597        {
11598            TCGv_i64 fp0 = tcg_temp_new_i64();
11599
11600            gen_load_fpr64(ctx, fp0, fs);
11601            gen_helper_float_rsqrt_d(fp0, cpu_env, fp0);
11602            gen_store_fpr64(ctx, fp0, fd);
11603            tcg_temp_free_i64(fp0);
11604        }
11605        break;
11606    case OPC_MADDF_D:
11607        check_insn(ctx, ISA_MIPS32R6);
11608        {
11609            TCGv_i64 fp0 = tcg_temp_new_i64();
11610            TCGv_i64 fp1 = tcg_temp_new_i64();
11611            TCGv_i64 fp2 = tcg_temp_new_i64();
11612            gen_load_fpr64(ctx, fp0, fs);
11613            gen_load_fpr64(ctx, fp1, ft);
11614            gen_load_fpr64(ctx, fp2, fd);
11615            gen_helper_float_maddf_d(fp2, cpu_env, fp0, fp1, fp2);
11616            gen_store_fpr64(ctx, fp2, fd);
11617            tcg_temp_free_i64(fp2);
11618            tcg_temp_free_i64(fp1);
11619            tcg_temp_free_i64(fp0);
11620        }
11621        break;
11622    case OPC_MSUBF_D:
11623        check_insn(ctx, ISA_MIPS32R6);
11624        {
11625            TCGv_i64 fp0 = tcg_temp_new_i64();
11626            TCGv_i64 fp1 = tcg_temp_new_i64();
11627            TCGv_i64 fp2 = tcg_temp_new_i64();
11628            gen_load_fpr64(ctx, fp0, fs);
11629            gen_load_fpr64(ctx, fp1, ft);
11630            gen_load_fpr64(ctx, fp2, fd);
11631            gen_helper_float_msubf_d(fp2, cpu_env, fp0, fp1, fp2);
11632            gen_store_fpr64(ctx, fp2, fd);
11633            tcg_temp_free_i64(fp2);
11634            tcg_temp_free_i64(fp1);
11635            tcg_temp_free_i64(fp0);
11636        }
11637        break;
11638    case OPC_RINT_D:
11639        check_insn(ctx, ISA_MIPS32R6);
11640        {
11641            TCGv_i64 fp0 = tcg_temp_new_i64();
11642            gen_load_fpr64(ctx, fp0, fs);
11643            gen_helper_float_rint_d(fp0, cpu_env, fp0);
11644            gen_store_fpr64(ctx, fp0, fd);
11645            tcg_temp_free_i64(fp0);
11646        }
11647        break;
11648    case OPC_CLASS_D:
11649        check_insn(ctx, ISA_MIPS32R6);
11650        {
11651            TCGv_i64 fp0 = tcg_temp_new_i64();
11652            gen_load_fpr64(ctx, fp0, fs);
11653            gen_helper_float_class_d(fp0, cpu_env, fp0);
11654            gen_store_fpr64(ctx, fp0, fd);
11655            tcg_temp_free_i64(fp0);
11656        }
11657        break;
11658    case OPC_MIN_D: /* OPC_RECIP2_D */
11659        if (ctx->insn_flags & ISA_MIPS32R6) {
11660            /* OPC_MIN_D */
11661            TCGv_i64 fp0 = tcg_temp_new_i64();
11662            TCGv_i64 fp1 = tcg_temp_new_i64();
11663            gen_load_fpr64(ctx, fp0, fs);
11664            gen_load_fpr64(ctx, fp1, ft);
11665            gen_helper_float_min_d(fp1, cpu_env, fp0, fp1);
11666            gen_store_fpr64(ctx, fp1, fd);
11667            tcg_temp_free_i64(fp1);
11668            tcg_temp_free_i64(fp0);
11669        } else {
11670            /* OPC_RECIP2_D */
11671            check_cp1_64bitmode(ctx);
11672            {
11673                TCGv_i64 fp0 = tcg_temp_new_i64();
11674                TCGv_i64 fp1 = tcg_temp_new_i64();
11675
11676                gen_load_fpr64(ctx, fp0, fs);
11677                gen_load_fpr64(ctx, fp1, ft);
11678                gen_helper_float_recip2_d(fp0, cpu_env, fp0, fp1);
11679                tcg_temp_free_i64(fp1);
11680                gen_store_fpr64(ctx, fp0, fd);
11681                tcg_temp_free_i64(fp0);
11682            }
11683        }
11684        break;
11685    case OPC_MINA_D: /* OPC_RECIP1_D */
11686        if (ctx->insn_flags & ISA_MIPS32R6) {
11687            /* OPC_MINA_D */
11688            TCGv_i64 fp0 = tcg_temp_new_i64();
11689            TCGv_i64 fp1 = tcg_temp_new_i64();
11690            gen_load_fpr64(ctx, fp0, fs);
11691            gen_load_fpr64(ctx, fp1, ft);
11692            gen_helper_float_mina_d(fp1, cpu_env, fp0, fp1);
11693            gen_store_fpr64(ctx, fp1, fd);
11694            tcg_temp_free_i64(fp1);
11695            tcg_temp_free_i64(fp0);
11696        } else {
11697            /* OPC_RECIP1_D */
11698            check_cp1_64bitmode(ctx);
11699            {
11700                TCGv_i64 fp0 = tcg_temp_new_i64();
11701
11702                gen_load_fpr64(ctx, fp0, fs);
11703                gen_helper_float_recip1_d(fp0, cpu_env, fp0);
11704                gen_store_fpr64(ctx, fp0, fd);
11705                tcg_temp_free_i64(fp0);
11706            }
11707        }
11708        break;
11709    case OPC_MAX_D: /*  OPC_RSQRT1_D */
11710        if (ctx->insn_flags & ISA_MIPS32R6) {
11711            /* OPC_MAX_D */
11712            TCGv_i64 fp0 = tcg_temp_new_i64();
11713            TCGv_i64 fp1 = tcg_temp_new_i64();
11714            gen_load_fpr64(ctx, fp0, fs);
11715            gen_load_fpr64(ctx, fp1, ft);
11716            gen_helper_float_max_d(fp1, cpu_env, fp0, fp1);
11717            gen_store_fpr64(ctx, fp1, fd);
11718            tcg_temp_free_i64(fp1);
11719            tcg_temp_free_i64(fp0);
11720        } else {
11721            /* OPC_RSQRT1_D */
11722            check_cp1_64bitmode(ctx);
11723            {
11724                TCGv_i64 fp0 = tcg_temp_new_i64();
11725
11726                gen_load_fpr64(ctx, fp0, fs);
11727                gen_helper_float_rsqrt1_d(fp0, cpu_env, fp0);
11728                gen_store_fpr64(ctx, fp0, fd);
11729                tcg_temp_free_i64(fp0);
11730            }
11731        }
11732        break;
11733    case OPC_MAXA_D: /* OPC_RSQRT2_D */
11734        if (ctx->insn_flags & ISA_MIPS32R6) {
11735            /* OPC_MAXA_D */
11736            TCGv_i64 fp0 = tcg_temp_new_i64();
11737            TCGv_i64 fp1 = tcg_temp_new_i64();
11738            gen_load_fpr64(ctx, fp0, fs);
11739            gen_load_fpr64(ctx, fp1, ft);
11740            gen_helper_float_maxa_d(fp1, cpu_env, fp0, fp1);
11741            gen_store_fpr64(ctx, fp1, fd);
11742            tcg_temp_free_i64(fp1);
11743            tcg_temp_free_i64(fp0);
11744        } else {
11745            /* OPC_RSQRT2_D */
11746            check_cp1_64bitmode(ctx);
11747            {
11748                TCGv_i64 fp0 = tcg_temp_new_i64();
11749                TCGv_i64 fp1 = tcg_temp_new_i64();
11750
11751                gen_load_fpr64(ctx, fp0, fs);
11752                gen_load_fpr64(ctx, fp1, ft);
11753                gen_helper_float_rsqrt2_d(fp0, cpu_env, fp0, fp1);
11754                tcg_temp_free_i64(fp1);
11755                gen_store_fpr64(ctx, fp0, fd);
11756                tcg_temp_free_i64(fp0);
11757            }
11758        }
11759        break;
11760    case OPC_CMP_F_D:
11761    case OPC_CMP_UN_D:
11762    case OPC_CMP_EQ_D:
11763    case OPC_CMP_UEQ_D:
11764    case OPC_CMP_OLT_D:
11765    case OPC_CMP_ULT_D:
11766    case OPC_CMP_OLE_D:
11767    case OPC_CMP_ULE_D:
11768    case OPC_CMP_SF_D:
11769    case OPC_CMP_NGLE_D:
11770    case OPC_CMP_SEQ_D:
11771    case OPC_CMP_NGL_D:
11772    case OPC_CMP_LT_D:
11773    case OPC_CMP_NGE_D:
11774    case OPC_CMP_LE_D:
11775    case OPC_CMP_NGT_D:
11776        check_insn_opc_removed(ctx, ISA_MIPS32R6);
11777        if (ctx->opcode & (1 << 6)) {
11778            gen_cmpabs_d(ctx, func-48, ft, fs, cc);
11779        } else {
11780            gen_cmp_d(ctx, func-48, ft, fs, cc);
11781        }
11782        break;
11783    case OPC_CVT_S_D:
11784        check_cp1_registers(ctx, fs);
11785        {
11786            TCGv_i32 fp32 = tcg_temp_new_i32();
11787            TCGv_i64 fp64 = tcg_temp_new_i64();
11788
11789            gen_load_fpr64(ctx, fp64, fs);
11790            gen_helper_float_cvts_d(fp32, cpu_env, fp64);
11791            tcg_temp_free_i64(fp64);
11792            gen_store_fpr32(ctx, fp32, fd);
11793            tcg_temp_free_i32(fp32);
11794        }
11795        break;
11796    case OPC_CVT_W_D:
11797        check_cp1_registers(ctx, fs);
11798        {
11799            TCGv_i32 fp32 = tcg_temp_new_i32();
11800            TCGv_i64 fp64 = tcg_temp_new_i64();
11801
11802            gen_load_fpr64(ctx, fp64, fs);
11803            if (ctx->nan2008) {
11804                gen_helper_float_cvt_2008_w_d(fp32, cpu_env, fp64);
11805            } else {
11806                gen_helper_float_cvt_w_d(fp32, cpu_env, fp64);
11807            }
11808            tcg_temp_free_i64(fp64);
11809            gen_store_fpr32(ctx, fp32, fd);
11810            tcg_temp_free_i32(fp32);
11811        }
11812        break;
11813    case OPC_CVT_L_D:
11814        check_cp1_64bitmode(ctx);
11815        {
11816            TCGv_i64 fp0 = tcg_temp_new_i64();
11817
11818            gen_load_fpr64(ctx, fp0, fs);
11819            if (ctx->nan2008) {
11820                gen_helper_float_cvt_2008_l_d(fp0, cpu_env, fp0);
11821            } else {
11822                gen_helper_float_cvt_l_d(fp0, cpu_env, fp0);
11823            }
11824            gen_store_fpr64(ctx, fp0, fd);
11825            tcg_temp_free_i64(fp0);
11826        }
11827        break;
11828    case OPC_CVT_S_W:
11829        {
11830            TCGv_i32 fp0 = tcg_temp_new_i32();
11831
11832            gen_load_fpr32(ctx, fp0, fs);
11833            gen_helper_float_cvts_w(fp0, cpu_env, fp0);
11834            gen_store_fpr32(ctx, fp0, fd);
11835            tcg_temp_free_i32(fp0);
11836        }
11837        break;
11838    case OPC_CVT_D_W:
11839        check_cp1_registers(ctx, fd);
11840        {
11841            TCGv_i32 fp32 = tcg_temp_new_i32();
11842            TCGv_i64 fp64 = tcg_temp_new_i64();
11843
11844            gen_load_fpr32(ctx, fp32, fs);
11845            gen_helper_float_cvtd_w(fp64, cpu_env, fp32);
11846            tcg_temp_free_i32(fp32);
11847            gen_store_fpr64(ctx, fp64, fd);
11848            tcg_temp_free_i64(fp64);
11849        }
11850        break;
11851    case OPC_CVT_S_L:
11852        check_cp1_64bitmode(ctx);
11853        {
11854            TCGv_i32 fp32 = tcg_temp_new_i32();
11855            TCGv_i64 fp64 = tcg_temp_new_i64();
11856
11857            gen_load_fpr64(ctx, fp64, fs);
11858            gen_helper_float_cvts_l(fp32, cpu_env, fp64);
11859            tcg_temp_free_i64(fp64);
11860            gen_store_fpr32(ctx, fp32, fd);
11861            tcg_temp_free_i32(fp32);
11862        }
11863        break;
11864    case OPC_CVT_D_L:
11865        check_cp1_64bitmode(ctx);
11866        {
11867            TCGv_i64 fp0 = tcg_temp_new_i64();
11868
11869            gen_load_fpr64(ctx, fp0, fs);
11870            gen_helper_float_cvtd_l(fp0, cpu_env, fp0);
11871            gen_store_fpr64(ctx, fp0, fd);
11872            tcg_temp_free_i64(fp0);
11873        }
11874        break;
11875    case OPC_CVT_PS_PW:
11876        check_ps(ctx);
11877        {
11878            TCGv_i64 fp0 = tcg_temp_new_i64();
11879
11880            gen_load_fpr64(ctx, fp0, fs);
11881            gen_helper_float_cvtps_pw(fp0, cpu_env, fp0);
11882            gen_store_fpr64(ctx, fp0, fd);
11883            tcg_temp_free_i64(fp0);
11884        }
11885        break;
11886    case OPC_ADD_PS:
11887        check_ps(ctx);
11888        {
11889            TCGv_i64 fp0 = tcg_temp_new_i64();
11890            TCGv_i64 fp1 = tcg_temp_new_i64();
11891
11892            gen_load_fpr64(ctx, fp0, fs);
11893            gen_load_fpr64(ctx, fp1, ft);
11894            gen_helper_float_add_ps(fp0, cpu_env, fp0, fp1);
11895            tcg_temp_free_i64(fp1);
11896            gen_store_fpr64(ctx, fp0, fd);
11897            tcg_temp_free_i64(fp0);
11898        }
11899        break;
11900    case OPC_SUB_PS:
11901        check_ps(ctx);
11902        {
11903            TCGv_i64 fp0 = tcg_temp_new_i64();
11904            TCGv_i64 fp1 = tcg_temp_new_i64();
11905
11906            gen_load_fpr64(ctx, fp0, fs);
11907            gen_load_fpr64(ctx, fp1, ft);
11908            gen_helper_float_sub_ps(fp0, cpu_env, fp0, fp1);
11909            tcg_temp_free_i64(fp1);
11910            gen_store_fpr64(ctx, fp0, fd);
11911            tcg_temp_free_i64(fp0);
11912        }
11913        break;
11914    case OPC_MUL_PS:
11915        check_ps(ctx);
11916        {
11917            TCGv_i64 fp0 = tcg_temp_new_i64();
11918            TCGv_i64 fp1 = tcg_temp_new_i64();
11919
11920            gen_load_fpr64(ctx, fp0, fs);
11921            gen_load_fpr64(ctx, fp1, ft);
11922            gen_helper_float_mul_ps(fp0, cpu_env, fp0, fp1);
11923            tcg_temp_free_i64(fp1);
11924            gen_store_fpr64(ctx, fp0, fd);
11925            tcg_temp_free_i64(fp0);
11926        }
11927        break;
11928    case OPC_ABS_PS:
11929        check_ps(ctx);
11930        {
11931            TCGv_i64 fp0 = tcg_temp_new_i64();
11932
11933            gen_load_fpr64(ctx, fp0, fs);
11934            gen_helper_float_abs_ps(fp0, fp0);
11935            gen_store_fpr64(ctx, fp0, fd);
11936            tcg_temp_free_i64(fp0);
11937        }
11938        break;
11939    case OPC_MOV_PS:
11940        check_ps(ctx);
11941        {
11942            TCGv_i64 fp0 = tcg_temp_new_i64();
11943
11944            gen_load_fpr64(ctx, fp0, fs);
11945            gen_store_fpr64(ctx, fp0, fd);
11946            tcg_temp_free_i64(fp0);
11947        }
11948        break;
11949    case OPC_NEG_PS:
11950        check_ps(ctx);
11951        {
11952            TCGv_i64 fp0 = tcg_temp_new_i64();
11953
11954            gen_load_fpr64(ctx, fp0, fs);
11955            gen_helper_float_chs_ps(fp0, fp0);
11956            gen_store_fpr64(ctx, fp0, fd);
11957            tcg_temp_free_i64(fp0);
11958        }
11959        break;
11960    case OPC_MOVCF_PS:
11961        check_ps(ctx);
11962        gen_movcf_ps(ctx, fs, fd, (ft >> 2) & 0x7, ft & 0x1);
11963        break;
11964    case OPC_MOVZ_PS:
11965        check_ps(ctx);
11966        {
11967            TCGLabel *l1 = gen_new_label();
11968            TCGv_i64 fp0;
11969
11970            if (ft != 0)
11971                tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[ft], 0, l1);
11972            fp0 = tcg_temp_new_i64();
11973            gen_load_fpr64(ctx, fp0, fs);
11974            gen_store_fpr64(ctx, fp0, fd);
11975            tcg_temp_free_i64(fp0);
11976            gen_set_label(l1);
11977        }
11978        break;
11979    case OPC_MOVN_PS:
11980        check_ps(ctx);
11981        {
11982            TCGLabel *l1 = gen_new_label();
11983            TCGv_i64 fp0;
11984
11985            if (ft != 0) {
11986                tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[ft], 0, l1);
11987                fp0 = tcg_temp_new_i64();
11988                gen_load_fpr64(ctx, fp0, fs);
11989                gen_store_fpr64(ctx, fp0, fd);
11990                tcg_temp_free_i64(fp0);
11991                gen_set_label(l1);
11992            }
11993        }
11994        break;
11995    case OPC_ADDR_PS:
11996        check_ps(ctx);
11997        {
11998            TCGv_i64 fp0 = tcg_temp_new_i64();
11999            TCGv_i64 fp1 = tcg_temp_new_i64();
12000
12001            gen_load_fpr64(ctx, fp0, ft);
12002            gen_load_fpr64(ctx, fp1, fs);
12003            gen_helper_float_addr_ps(fp0, cpu_env, fp0, fp1);
12004            tcg_temp_free_i64(fp1);
12005            gen_store_fpr64(ctx, fp0, fd);
12006            tcg_temp_free_i64(fp0);
12007        }
12008        break;
12009    case OPC_MULR_PS:
12010        check_ps(ctx);
12011        {
12012            TCGv_i64 fp0 = tcg_temp_new_i64();
12013            TCGv_i64 fp1 = tcg_temp_new_i64();
12014
12015            gen_load_fpr64(ctx, fp0, ft);
12016            gen_load_fpr64(ctx, fp1, fs);
12017            gen_helper_float_mulr_ps(fp0, cpu_env, fp0, fp1);
12018            tcg_temp_free_i64(fp1);
12019            gen_store_fpr64(ctx, fp0, fd);
12020            tcg_temp_free_i64(fp0);
12021        }
12022        break;
12023    case OPC_RECIP2_PS:
12024        check_ps(ctx);
12025        {
12026            TCGv_i64 fp0 = tcg_temp_new_i64();
12027            TCGv_i64 fp1 = tcg_temp_new_i64();
12028
12029            gen_load_fpr64(ctx, fp0, fs);
12030            gen_load_fpr64(ctx, fp1, ft);
12031            gen_helper_float_recip2_ps(fp0, cpu_env, fp0, fp1);
12032            tcg_temp_free_i64(fp1);
12033            gen_store_fpr64(ctx, fp0, fd);
12034            tcg_temp_free_i64(fp0);
12035        }
12036        break;
12037    case OPC_RECIP1_PS:
12038        check_ps(ctx);
12039        {
12040            TCGv_i64 fp0 = tcg_temp_new_i64();
12041
12042            gen_load_fpr64(ctx, fp0, fs);
12043            gen_helper_float_recip1_ps(fp0, cpu_env, fp0);
12044            gen_store_fpr64(ctx, fp0, fd);
12045            tcg_temp_free_i64(fp0);
12046        }
12047        break;
12048    case OPC_RSQRT1_PS:
12049        check_ps(ctx);
12050        {
12051            TCGv_i64 fp0 = tcg_temp_new_i64();
12052
12053            gen_load_fpr64(ctx, fp0, fs);
12054            gen_helper_float_rsqrt1_ps(fp0, cpu_env, fp0);
12055            gen_store_fpr64(ctx, fp0, fd);
12056            tcg_temp_free_i64(fp0);
12057        }
12058        break;
12059    case OPC_RSQRT2_PS:
12060        check_ps(ctx);
12061        {
12062            TCGv_i64 fp0 = tcg_temp_new_i64();
12063            TCGv_i64 fp1 = tcg_temp_new_i64();
12064
12065            gen_load_fpr64(ctx, fp0, fs);
12066            gen_load_fpr64(ctx, fp1, ft);
12067            gen_helper_float_rsqrt2_ps(fp0, cpu_env, fp0, fp1);
12068            tcg_temp_free_i64(fp1);
12069            gen_store_fpr64(ctx, fp0, fd);
12070            tcg_temp_free_i64(fp0);
12071        }
12072        break;
12073    case OPC_CVT_S_PU:
12074        check_cp1_64bitmode(ctx);
12075        {
12076            TCGv_i32 fp0 = tcg_temp_new_i32();
12077
12078            gen_load_fpr32h(ctx, fp0, fs);
12079            gen_helper_float_cvts_pu(fp0, cpu_env, fp0);
12080            gen_store_fpr32(ctx, fp0, fd);
12081            tcg_temp_free_i32(fp0);
12082        }
12083        break;
12084    case OPC_CVT_PW_PS:
12085        check_ps(ctx);
12086        {
12087            TCGv_i64 fp0 = tcg_temp_new_i64();
12088
12089            gen_load_fpr64(ctx, fp0, fs);
12090            gen_helper_float_cvtpw_ps(fp0, cpu_env, fp0);
12091            gen_store_fpr64(ctx, fp0, fd);
12092            tcg_temp_free_i64(fp0);
12093        }
12094        break;
12095    case OPC_CVT_S_PL:
12096        check_cp1_64bitmode(ctx);
12097        {
12098            TCGv_i32 fp0 = tcg_temp_new_i32();
12099
12100            gen_load_fpr32(ctx, fp0, fs);
12101            gen_helper_float_cvts_pl(fp0, cpu_env, fp0);
12102            gen_store_fpr32(ctx, fp0, fd);
12103            tcg_temp_free_i32(fp0);
12104        }
12105        break;
12106    case OPC_PLL_PS:
12107        check_ps(ctx);
12108        {
12109            TCGv_i32 fp0 = tcg_temp_new_i32();
12110            TCGv_i32 fp1 = tcg_temp_new_i32();
12111
12112            gen_load_fpr32(ctx, fp0, fs);
12113            gen_load_fpr32(ctx, fp1, ft);
12114            gen_store_fpr32h(ctx, fp0, fd);
12115            gen_store_fpr32(ctx, fp1, fd);
12116            tcg_temp_free_i32(fp0);
12117            tcg_temp_free_i32(fp1);
12118        }
12119        break;
12120    case OPC_PLU_PS:
12121        check_ps(ctx);
12122        {
12123            TCGv_i32 fp0 = tcg_temp_new_i32();
12124            TCGv_i32 fp1 = tcg_temp_new_i32();
12125
12126            gen_load_fpr32(ctx, fp0, fs);
12127            gen_load_fpr32h(ctx, fp1, ft);
12128            gen_store_fpr32(ctx, fp1, fd);
12129            gen_store_fpr32h(ctx, fp0, fd);
12130            tcg_temp_free_i32(fp0);
12131            tcg_temp_free_i32(fp1);
12132        }
12133        break;
12134    case OPC_PUL_PS:
12135        check_ps(ctx);
12136        {
12137            TCGv_i32 fp0 = tcg_temp_new_i32();
12138            TCGv_i32 fp1 = tcg_temp_new_i32();
12139
12140            gen_load_fpr32h(ctx, fp0, fs);
12141            gen_load_fpr32(ctx, fp1, ft);
12142            gen_store_fpr32(ctx, fp1, fd);
12143            gen_store_fpr32h(ctx, fp0, fd);
12144            tcg_temp_free_i32(fp0);
12145            tcg_temp_free_i32(fp1);
12146        }
12147        break;
12148    case OPC_PUU_PS:
12149        check_ps(ctx);
12150        {
12151            TCGv_i32 fp0 = tcg_temp_new_i32();
12152            TCGv_i32 fp1 = tcg_temp_new_i32();
12153
12154            gen_load_fpr32h(ctx, fp0, fs);
12155            gen_load_fpr32h(ctx, fp1, ft);
12156            gen_store_fpr32(ctx, fp1, fd);
12157            gen_store_fpr32h(ctx, fp0, fd);
12158            tcg_temp_free_i32(fp0);
12159            tcg_temp_free_i32(fp1);
12160        }
12161        break;
12162    case OPC_CMP_F_PS:
12163    case OPC_CMP_UN_PS:
12164    case OPC_CMP_EQ_PS:
12165    case OPC_CMP_UEQ_PS:
12166    case OPC_CMP_OLT_PS:
12167    case OPC_CMP_ULT_PS:
12168    case OPC_CMP_OLE_PS:
12169    case OPC_CMP_ULE_PS:
12170    case OPC_CMP_SF_PS:
12171    case OPC_CMP_NGLE_PS:
12172    case OPC_CMP_SEQ_PS:
12173    case OPC_CMP_NGL_PS:
12174    case OPC_CMP_LT_PS:
12175    case OPC_CMP_NGE_PS:
12176    case OPC_CMP_LE_PS:
12177    case OPC_CMP_NGT_PS:
12178        if (ctx->opcode & (1 << 6)) {
12179            gen_cmpabs_ps(ctx, func-48, ft, fs, cc);
12180        } else {
12181            gen_cmp_ps(ctx, func-48, ft, fs, cc);
12182        }
12183        break;
12184    default:
12185        MIPS_INVAL("farith");
12186        generate_exception_end(ctx, EXCP_RI);
12187        return;
12188    }
12189}
12190
12191/* Coprocessor 3 (FPU) */
12192static void gen_flt3_ldst (DisasContext *ctx, uint32_t opc,
12193                           int fd, int fs, int base, int index)
12194{
12195    TCGv t0 = tcg_temp_new();
12196
12197    if (base == 0) {
12198        gen_load_gpr(t0, index);
12199    } else if (index == 0) {
12200        gen_load_gpr(t0, base);
12201    } else {
12202        gen_op_addr_add(ctx, t0, cpu_gpr[base], cpu_gpr[index]);
12203    }
12204    /* Don't do NOP if destination is zero: we must perform the actual
12205       memory access. */
12206    switch (opc) {
12207    case OPC_LWXC1:
12208        check_cop1x(ctx);
12209        {
12210            TCGv_i32 fp0 = tcg_temp_new_i32();
12211
12212            tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TESL);
12213            tcg_gen_trunc_tl_i32(fp0, t0);
12214            gen_store_fpr32(ctx, fp0, fd);
12215            tcg_temp_free_i32(fp0);
12216        }
12217        break;
12218    case OPC_LDXC1:
12219        check_cop1x(ctx);
12220        check_cp1_registers(ctx, fd);
12221        {
12222            TCGv_i64 fp0 = tcg_temp_new_i64();
12223            tcg_gen_qemu_ld_i64(fp0, t0, ctx->mem_idx, MO_TEQ);
12224            gen_store_fpr64(ctx, fp0, fd);
12225            tcg_temp_free_i64(fp0);
12226        }
12227        break;
12228    case OPC_LUXC1:
12229        check_cp1_64bitmode(ctx);
12230        tcg_gen_andi_tl(t0, t0, ~0x7);
12231        {
12232            TCGv_i64 fp0 = tcg_temp_new_i64();
12233
12234            tcg_gen_qemu_ld_i64(fp0, t0, ctx->mem_idx, MO_TEQ);
12235            gen_store_fpr64(ctx, fp0, fd);
12236            tcg_temp_free_i64(fp0);
12237        }
12238        break;
12239    case OPC_SWXC1:
12240        check_cop1x(ctx);
12241        {
12242            TCGv_i32 fp0 = tcg_temp_new_i32();
12243            gen_load_fpr32(ctx, fp0, fs);
12244            tcg_gen_qemu_st_i32(fp0, t0, ctx->mem_idx, MO_TEUL);
12245            tcg_temp_free_i32(fp0);
12246        }
12247        break;
12248    case OPC_SDXC1:
12249        check_cop1x(ctx);
12250        check_cp1_registers(ctx, fs);
12251        {
12252            TCGv_i64 fp0 = tcg_temp_new_i64();
12253            gen_load_fpr64(ctx, fp0, fs);
12254            tcg_gen_qemu_st_i64(fp0, t0, ctx->mem_idx, MO_TEQ);
12255            tcg_temp_free_i64(fp0);
12256        }
12257        break;
12258    case OPC_SUXC1:
12259        check_cp1_64bitmode(ctx);
12260        tcg_gen_andi_tl(t0, t0, ~0x7);
12261        {
12262            TCGv_i64 fp0 = tcg_temp_new_i64();
12263            gen_load_fpr64(ctx, fp0, fs);
12264            tcg_gen_qemu_st_i64(fp0, t0, ctx->mem_idx, MO_TEQ);
12265            tcg_temp_free_i64(fp0);
12266        }
12267        break;
12268    }
12269    tcg_temp_free(t0);
12270}
12271
12272static void gen_flt3_arith (DisasContext *ctx, uint32_t opc,
12273                            int fd, int fr, int fs, int ft)
12274{
12275    switch (opc) {
12276    case OPC_ALNV_PS:
12277        check_ps(ctx);
12278        {
12279            TCGv t0 = tcg_temp_local_new();
12280            TCGv_i32 fp = tcg_temp_new_i32();
12281            TCGv_i32 fph = tcg_temp_new_i32();
12282            TCGLabel *l1 = gen_new_label();
12283            TCGLabel *l2 = gen_new_label();
12284
12285            gen_load_gpr(t0, fr);
12286            tcg_gen_andi_tl(t0, t0, 0x7);
12287
12288            tcg_gen_brcondi_tl(TCG_COND_NE, t0, 0, l1);
12289            gen_load_fpr32(ctx, fp, fs);
12290            gen_load_fpr32h(ctx, fph, fs);
12291            gen_store_fpr32(ctx, fp, fd);
12292            gen_store_fpr32h(ctx, fph, fd);
12293            tcg_gen_br(l2);
12294            gen_set_label(l1);
12295            tcg_gen_brcondi_tl(TCG_COND_NE, t0, 4, l2);
12296            tcg_temp_free(t0);
12297#ifdef TARGET_WORDS_BIGENDIAN
12298            gen_load_fpr32(ctx, fp, fs);
12299            gen_load_fpr32h(ctx, fph, ft);
12300            gen_store_fpr32h(ctx, fp, fd);
12301            gen_store_fpr32(ctx, fph, fd);
12302#else
12303            gen_load_fpr32h(ctx, fph, fs);
12304            gen_load_fpr32(ctx, fp, ft);
12305            gen_store_fpr32(ctx, fph, fd);
12306            gen_store_fpr32h(ctx, fp, fd);
12307#endif
12308            gen_set_label(l2);
12309            tcg_temp_free_i32(fp);
12310            tcg_temp_free_i32(fph);
12311        }
12312        break;
12313    case OPC_MADD_S:
12314        check_cop1x(ctx);
12315        {
12316            TCGv_i32 fp0 = tcg_temp_new_i32();
12317            TCGv_i32 fp1 = tcg_temp_new_i32();
12318            TCGv_i32 fp2 = tcg_temp_new_i32();
12319
12320            gen_load_fpr32(ctx, fp0, fs);
12321            gen_load_fpr32(ctx, fp1, ft);
12322            gen_load_fpr32(ctx, fp2, fr);
12323            gen_helper_float_madd_s(fp2, cpu_env, fp0, fp1, fp2);
12324            tcg_temp_free_i32(fp0);
12325            tcg_temp_free_i32(fp1);
12326            gen_store_fpr32(ctx, fp2, fd);
12327            tcg_temp_free_i32(fp2);
12328        }
12329        break;
12330    case OPC_MADD_D:
12331        check_cop1x(ctx);
12332        check_cp1_registers(ctx, fd | fs | ft | fr);
12333        {
12334            TCGv_i64 fp0 = tcg_temp_new_i64();
12335            TCGv_i64 fp1 = tcg_temp_new_i64();
12336            TCGv_i64 fp2 = tcg_temp_new_i64();
12337
12338            gen_load_fpr64(ctx, fp0, fs);
12339            gen_load_fpr64(ctx, fp1, ft);
12340            gen_load_fpr64(ctx, fp2, fr);
12341            gen_helper_float_madd_d(fp2, cpu_env, fp0, fp1, fp2);
12342            tcg_temp_free_i64(fp0);
12343            tcg_temp_free_i64(fp1);
12344            gen_store_fpr64(ctx, fp2, fd);
12345            tcg_temp_free_i64(fp2);
12346        }
12347        break;
12348    case OPC_MADD_PS:
12349        check_ps(ctx);
12350        {
12351            TCGv_i64 fp0 = tcg_temp_new_i64();
12352            TCGv_i64 fp1 = tcg_temp_new_i64();
12353            TCGv_i64 fp2 = tcg_temp_new_i64();
12354
12355            gen_load_fpr64(ctx, fp0, fs);
12356            gen_load_fpr64(ctx, fp1, ft);
12357            gen_load_fpr64(ctx, fp2, fr);
12358            gen_helper_float_madd_ps(fp2, cpu_env, fp0, fp1, fp2);
12359            tcg_temp_free_i64(fp0);
12360            tcg_temp_free_i64(fp1);
12361            gen_store_fpr64(ctx, fp2, fd);
12362            tcg_temp_free_i64(fp2);
12363        }
12364        break;
12365    case OPC_MSUB_S:
12366        check_cop1x(ctx);
12367        {
12368            TCGv_i32 fp0 = tcg_temp_new_i32();
12369            TCGv_i32 fp1 = tcg_temp_new_i32();
12370            TCGv_i32 fp2 = tcg_temp_new_i32();
12371
12372            gen_load_fpr32(ctx, fp0, fs);
12373            gen_load_fpr32(ctx, fp1, ft);
12374            gen_load_fpr32(ctx, fp2, fr);
12375            gen_helper_float_msub_s(fp2, cpu_env, fp0, fp1, fp2);
12376            tcg_temp_free_i32(fp0);
12377            tcg_temp_free_i32(fp1);
12378            gen_store_fpr32(ctx, fp2, fd);
12379            tcg_temp_free_i32(fp2);
12380        }
12381        break;
12382    case OPC_MSUB_D:
12383        check_cop1x(ctx);
12384        check_cp1_registers(ctx, fd | fs | ft | fr);
12385        {
12386            TCGv_i64 fp0 = tcg_temp_new_i64();
12387            TCGv_i64 fp1 = tcg_temp_new_i64();
12388            TCGv_i64 fp2 = tcg_temp_new_i64();
12389
12390            gen_load_fpr64(ctx, fp0, fs);
12391            gen_load_fpr64(ctx, fp1, ft);
12392            gen_load_fpr64(ctx, fp2, fr);
12393            gen_helper_float_msub_d(fp2, cpu_env, fp0, fp1, fp2);
12394            tcg_temp_free_i64(fp0);
12395            tcg_temp_free_i64(fp1);
12396            gen_store_fpr64(ctx, fp2, fd);
12397            tcg_temp_free_i64(fp2);
12398        }
12399        break;
12400    case OPC_MSUB_PS:
12401        check_ps(ctx);
12402        {
12403            TCGv_i64 fp0 = tcg_temp_new_i64();
12404            TCGv_i64 fp1 = tcg_temp_new_i64();
12405            TCGv_i64 fp2 = tcg_temp_new_i64();
12406
12407            gen_load_fpr64(ctx, fp0, fs);
12408            gen_load_fpr64(ctx, fp1, ft);
12409            gen_load_fpr64(ctx, fp2, fr);
12410            gen_helper_float_msub_ps(fp2, cpu_env, fp0, fp1, fp2);
12411            tcg_temp_free_i64(fp0);
12412            tcg_temp_free_i64(fp1);
12413            gen_store_fpr64(ctx, fp2, fd);
12414            tcg_temp_free_i64(fp2);
12415        }
12416        break;
12417    case OPC_NMADD_S:
12418        check_cop1x(ctx);
12419        {
12420            TCGv_i32 fp0 = tcg_temp_new_i32();
12421            TCGv_i32 fp1 = tcg_temp_new_i32();
12422            TCGv_i32 fp2 = tcg_temp_new_i32();
12423
12424            gen_load_fpr32(ctx, fp0, fs);
12425            gen_load_fpr32(ctx, fp1, ft);
12426            gen_load_fpr32(ctx, fp2, fr);
12427            gen_helper_float_nmadd_s(fp2, cpu_env, fp0, fp1, fp2);
12428            tcg_temp_free_i32(fp0);
12429            tcg_temp_free_i32(fp1);
12430            gen_store_fpr32(ctx, fp2, fd);
12431            tcg_temp_free_i32(fp2);
12432        }
12433        break;
12434    case OPC_NMADD_D:
12435        check_cop1x(ctx);
12436        check_cp1_registers(ctx, fd | fs | ft | fr);
12437        {
12438            TCGv_i64 fp0 = tcg_temp_new_i64();
12439            TCGv_i64 fp1 = tcg_temp_new_i64();
12440            TCGv_i64 fp2 = tcg_temp_new_i64();
12441
12442            gen_load_fpr64(ctx, fp0, fs);
12443            gen_load_fpr64(ctx, fp1, ft);
12444            gen_load_fpr64(ctx, fp2, fr);
12445            gen_helper_float_nmadd_d(fp2, cpu_env, fp0, fp1, fp2);
12446            tcg_temp_free_i64(fp0);
12447            tcg_temp_free_i64(fp1);
12448            gen_store_fpr64(ctx, fp2, fd);
12449            tcg_temp_free_i64(fp2);
12450        }
12451        break;
12452    case OPC_NMADD_PS:
12453        check_ps(ctx);
12454        {
12455            TCGv_i64 fp0 = tcg_temp_new_i64();
12456            TCGv_i64 fp1 = tcg_temp_new_i64();
12457            TCGv_i64 fp2 = tcg_temp_new_i64();
12458
12459            gen_load_fpr64(ctx, fp0, fs);
12460            gen_load_fpr64(ctx, fp1, ft);
12461            gen_load_fpr64(ctx, fp2, fr);
12462            gen_helper_float_nmadd_ps(fp2, cpu_env, fp0, fp1, fp2);
12463            tcg_temp_free_i64(fp0);
12464            tcg_temp_free_i64(fp1);
12465            gen_store_fpr64(ctx, fp2, fd);
12466            tcg_temp_free_i64(fp2);
12467        }
12468        break;
12469    case OPC_NMSUB_S:
12470        check_cop1x(ctx);
12471        {
12472            TCGv_i32 fp0 = tcg_temp_new_i32();
12473            TCGv_i32 fp1 = tcg_temp_new_i32();
12474            TCGv_i32 fp2 = tcg_temp_new_i32();
12475
12476            gen_load_fpr32(ctx, fp0, fs);
12477            gen_load_fpr32(ctx, fp1, ft);
12478            gen_load_fpr32(ctx, fp2, fr);
12479            gen_helper_float_nmsub_s(fp2, cpu_env, fp0, fp1, fp2);
12480            tcg_temp_free_i32(fp0);
12481            tcg_temp_free_i32(fp1);
12482            gen_store_fpr32(ctx, fp2, fd);
12483            tcg_temp_free_i32(fp2);
12484        }
12485        break;
12486    case OPC_NMSUB_D:
12487        check_cop1x(ctx);
12488        check_cp1_registers(ctx, fd | fs | ft | fr);
12489        {
12490            TCGv_i64 fp0 = tcg_temp_new_i64();
12491            TCGv_i64 fp1 = tcg_temp_new_i64();
12492            TCGv_i64 fp2 = tcg_temp_new_i64();
12493
12494            gen_load_fpr64(ctx, fp0, fs);
12495            gen_load_fpr64(ctx, fp1, ft);
12496            gen_load_fpr64(ctx, fp2, fr);
12497            gen_helper_float_nmsub_d(fp2, cpu_env, fp0, fp1, fp2);
12498            tcg_temp_free_i64(fp0);
12499            tcg_temp_free_i64(fp1);
12500            gen_store_fpr64(ctx, fp2, fd);
12501            tcg_temp_free_i64(fp2);
12502        }
12503        break;
12504    case OPC_NMSUB_PS:
12505        check_ps(ctx);
12506        {
12507            TCGv_i64 fp0 = tcg_temp_new_i64();
12508            TCGv_i64 fp1 = tcg_temp_new_i64();
12509            TCGv_i64 fp2 = tcg_temp_new_i64();
12510
12511            gen_load_fpr64(ctx, fp0, fs);
12512            gen_load_fpr64(ctx, fp1, ft);
12513            gen_load_fpr64(ctx, fp2, fr);
12514            gen_helper_float_nmsub_ps(fp2, cpu_env, fp0, fp1, fp2);
12515            tcg_temp_free_i64(fp0);
12516            tcg_temp_free_i64(fp1);
12517            gen_store_fpr64(ctx, fp2, fd);
12518            tcg_temp_free_i64(fp2);
12519        }
12520        break;
12521    default:
12522        MIPS_INVAL("flt3_arith");
12523        generate_exception_end(ctx, EXCP_RI);
12524        return;
12525    }
12526}
12527
12528static void gen_rdhwr(DisasContext *ctx, int rt, int rd, int sel)
12529{
12530    TCGv t0;
12531
12532#if !defined(CONFIG_USER_ONLY)
12533    /* The Linux kernel will emulate rdhwr if it's not supported natively.
12534       Therefore only check the ISA in system mode.  */
12535    check_insn(ctx, ISA_MIPS32R2);
12536#endif
12537    t0 = tcg_temp_new();
12538
12539    switch (rd) {
12540    case 0:
12541        gen_helper_rdhwr_cpunum(t0, cpu_env);
12542        gen_store_gpr(t0, rt);
12543        break;
12544    case 1:
12545        gen_helper_rdhwr_synci_step(t0, cpu_env);
12546        gen_store_gpr(t0, rt);
12547        break;
12548    case 2:
12549        if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
12550            gen_io_start();
12551        }
12552        gen_helper_rdhwr_cc(t0, cpu_env);
12553        if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
12554            gen_io_end();
12555        }
12556        gen_store_gpr(t0, rt);
12557        /* Break the TB to be able to take timer interrupts immediately
12558           after reading count. DISAS_STOP isn't sufficient, we need to ensure
12559           we break completely out of translated code.  */
12560        gen_save_pc(ctx->base.pc_next + 4);
12561        ctx->base.is_jmp = DISAS_EXIT;
12562        break;
12563    case 3:
12564        gen_helper_rdhwr_ccres(t0, cpu_env);
12565        gen_store_gpr(t0, rt);
12566        break;
12567    case 4:
12568        check_insn(ctx, ISA_MIPS32R6);
12569        if (sel != 0) {
12570            /* Performance counter registers are not implemented other than
12571             * control register 0.
12572             */
12573            generate_exception(ctx, EXCP_RI);
12574        }
12575        gen_helper_rdhwr_performance(t0, cpu_env);
12576        gen_store_gpr(t0, rt);
12577        break;
12578    case 5:
12579        check_insn(ctx, ISA_MIPS32R6);
12580        gen_helper_rdhwr_xnp(t0, cpu_env);
12581        gen_store_gpr(t0, rt);
12582        break;
12583    case 29:
12584#if defined(CONFIG_USER_ONLY)
12585        tcg_gen_ld_tl(t0, cpu_env,
12586                      offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
12587        gen_store_gpr(t0, rt);
12588        break;
12589#else
12590        if ((ctx->hflags & MIPS_HFLAG_CP0) ||
12591            (ctx->hflags & MIPS_HFLAG_HWRENA_ULR)) {
12592            tcg_gen_ld_tl(t0, cpu_env,
12593                          offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
12594            gen_store_gpr(t0, rt);
12595        } else {
12596            generate_exception_end(ctx, EXCP_RI);
12597        }
12598        break;
12599#endif
12600    default:            /* Invalid */
12601        MIPS_INVAL("rdhwr");
12602        generate_exception_end(ctx, EXCP_RI);
12603        break;
12604    }
12605    tcg_temp_free(t0);
12606}
12607
12608static inline void clear_branch_hflags(DisasContext *ctx)
12609{
12610    ctx->hflags &= ~MIPS_HFLAG_BMASK;
12611    if (ctx->base.is_jmp == DISAS_NEXT) {
12612        save_cpu_state(ctx, 0);
12613    } else {
12614        /* it is not safe to save ctx->hflags as hflags may be changed
12615           in execution time by the instruction in delay / forbidden slot. */
12616        tcg_gen_andi_i32(hflags, hflags, ~MIPS_HFLAG_BMASK);
12617    }
12618}
12619
12620static void gen_branch(DisasContext *ctx, int insn_bytes)
12621{
12622    if (ctx->hflags & MIPS_HFLAG_BMASK) {
12623        int proc_hflags = ctx->hflags & MIPS_HFLAG_BMASK;
12624        /* Branches completion */
12625        clear_branch_hflags(ctx);
12626        ctx->base.is_jmp = DISAS_NORETURN;
12627        /* FIXME: Need to clear can_do_io.  */
12628        switch (proc_hflags & MIPS_HFLAG_BMASK_BASE) {
12629        case MIPS_HFLAG_FBNSLOT:
12630            gen_goto_tb(ctx, 0, ctx->base.pc_next + insn_bytes);
12631            break;
12632        case MIPS_HFLAG_B:
12633            /* unconditional branch */
12634            if (proc_hflags & MIPS_HFLAG_BX) {
12635                tcg_gen_xori_i32(hflags, hflags, MIPS_HFLAG_M16);
12636            }
12637            gen_goto_tb(ctx, 0, ctx->btarget);
12638            break;
12639        case MIPS_HFLAG_BL:
12640            /* blikely taken case */
12641            gen_goto_tb(ctx, 0, ctx->btarget);
12642            break;
12643        case MIPS_HFLAG_BC:
12644            /* Conditional branch */
12645            {
12646                TCGLabel *l1 = gen_new_label();
12647
12648                tcg_gen_brcondi_tl(TCG_COND_NE, bcond, 0, l1);
12649                gen_goto_tb(ctx, 1, ctx->base.pc_next + insn_bytes);
12650                gen_set_label(l1);
12651                gen_goto_tb(ctx, 0, ctx->btarget);
12652            }
12653            break;
12654        case MIPS_HFLAG_BR:
12655            /* unconditional branch to register */
12656            if (ctx->insn_flags & (ASE_MIPS16 | ASE_MICROMIPS)) {
12657                TCGv t0 = tcg_temp_new();
12658                TCGv_i32 t1 = tcg_temp_new_i32();
12659
12660                tcg_gen_andi_tl(t0, btarget, 0x1);
12661                tcg_gen_trunc_tl_i32(t1, t0);
12662                tcg_temp_free(t0);
12663                tcg_gen_andi_i32(hflags, hflags, ~(uint32_t)MIPS_HFLAG_M16);
12664                tcg_gen_shli_i32(t1, t1, MIPS_HFLAG_M16_SHIFT);
12665                tcg_gen_or_i32(hflags, hflags, t1);
12666                tcg_temp_free_i32(t1);
12667
12668                tcg_gen_andi_tl(cpu_PC, btarget, ~(target_ulong)0x1);
12669            } else {
12670                tcg_gen_mov_tl(cpu_PC, btarget);
12671            }
12672            if (ctx->base.singlestep_enabled) {
12673                save_cpu_state(ctx, 0);
12674                gen_helper_raise_exception_debug(cpu_env);
12675            }
12676            tcg_gen_lookup_and_goto_ptr();
12677            break;
12678        default:
12679            fprintf(stderr, "unknown branch 0x%x\n", proc_hflags);
12680            abort();
12681        }
12682    }
12683}
12684
12685/* Compact Branches */
12686static void gen_compute_compact_branch(DisasContext *ctx, uint32_t opc,
12687                                       int rs, int rt, int32_t offset)
12688{
12689    int bcond_compute = 0;
12690    TCGv t0 = tcg_temp_new();
12691    TCGv t1 = tcg_temp_new();
12692    int m16_lowbit = (ctx->hflags & MIPS_HFLAG_M16) != 0;
12693
12694    if (ctx->hflags & MIPS_HFLAG_BMASK) {
12695#ifdef MIPS_DEBUG_DISAS
12696        LOG_DISAS("Branch in delay / forbidden slot at PC 0x" TARGET_FMT_lx
12697                  "\n", ctx->base.pc_next);
12698#endif
12699        generate_exception_end(ctx, EXCP_RI);
12700        goto out;
12701    }
12702
12703    /* Load needed operands and calculate btarget */
12704    switch (opc) {
12705    /* compact branch */
12706    case OPC_BOVC: /* OPC_BEQZALC, OPC_BEQC */
12707    case OPC_BNVC: /* OPC_BNEZALC, OPC_BNEC */
12708        gen_load_gpr(t0, rs);
12709        gen_load_gpr(t1, rt);
12710        bcond_compute = 1;
12711        ctx->btarget = addr_add(ctx, ctx->base.pc_next + 4, offset);
12712        if (rs <= rt && rs == 0) {
12713            /* OPC_BEQZALC, OPC_BNEZALC */
12714            tcg_gen_movi_tl(cpu_gpr[31], ctx->base.pc_next + 4 + m16_lowbit);
12715        }
12716        break;
12717    case OPC_BLEZC: /* OPC_BGEZC, OPC_BGEC */
12718    case OPC_BGTZC: /* OPC_BLTZC, OPC_BLTC */
12719        gen_load_gpr(t0, rs);
12720        gen_load_gpr(t1, rt);
12721        bcond_compute = 1;
12722        ctx->btarget = addr_add(ctx, ctx->base.pc_next + 4, offset);
12723        break;
12724    case OPC_BLEZALC: /* OPC_BGEZALC, OPC_BGEUC */
12725    case OPC_BGTZALC: /* OPC_BLTZALC, OPC_BLTUC */
12726        if (rs == 0 || rs == rt) {
12727            /* OPC_BLEZALC, OPC_BGEZALC */
12728            /* OPC_BGTZALC, OPC_BLTZALC */
12729            tcg_gen_movi_tl(cpu_gpr[31], ctx->base.pc_next + 4 + m16_lowbit);
12730        }
12731        gen_load_gpr(t0, rs);
12732        gen_load_gpr(t1, rt);
12733        bcond_compute = 1;
12734        ctx->btarget = addr_add(ctx, ctx->base.pc_next + 4, offset);
12735        break;
12736    case OPC_BC:
12737    case OPC_BALC:
12738        ctx->btarget = addr_add(ctx, ctx->base.pc_next + 4, offset);
12739        break;
12740    case OPC_BEQZC:
12741    case OPC_BNEZC:
12742        if (rs != 0) {
12743            /* OPC_BEQZC, OPC_BNEZC */
12744            gen_load_gpr(t0, rs);
12745            bcond_compute = 1;
12746            ctx->btarget = addr_add(ctx, ctx->base.pc_next + 4, offset);
12747        } else {
12748            /* OPC_JIC, OPC_JIALC */
12749            TCGv tbase = tcg_temp_new();
12750            TCGv toffset = tcg_temp_new();
12751
12752            gen_load_gpr(tbase, rt);
12753            tcg_gen_movi_tl(toffset, offset);
12754            gen_op_addr_add(ctx, btarget, tbase, toffset);
12755            tcg_temp_free(tbase);
12756            tcg_temp_free(toffset);
12757        }
12758        break;
12759    default:
12760        MIPS_INVAL("Compact branch/jump");
12761        generate_exception_end(ctx, EXCP_RI);
12762        goto out;
12763    }
12764
12765    if (bcond_compute == 0) {
12766        /* Uncoditional compact branch */
12767        switch (opc) {
12768        case OPC_JIALC:
12769            tcg_gen_movi_tl(cpu_gpr[31], ctx->base.pc_next + 4 + m16_lowbit);
12770            /* Fallthrough */
12771        case OPC_JIC:
12772            ctx->hflags |= MIPS_HFLAG_BR;
12773            break;
12774        case OPC_BALC:
12775            tcg_gen_movi_tl(cpu_gpr[31], ctx->base.pc_next + 4 + m16_lowbit);
12776            /* Fallthrough */
12777        case OPC_BC:
12778            ctx->hflags |= MIPS_HFLAG_B;
12779            break;
12780        default:
12781            MIPS_INVAL("Compact branch/jump");
12782            generate_exception_end(ctx, EXCP_RI);
12783            goto out;
12784        }
12785
12786        /* Generating branch here as compact branches don't have delay slot */
12787        gen_branch(ctx, 4);
12788    } else {
12789        /* Conditional compact branch */
12790        TCGLabel *fs = gen_new_label();
12791        save_cpu_state(ctx, 0);
12792
12793        switch (opc) {
12794        case OPC_BLEZALC: /* OPC_BGEZALC, OPC_BGEUC */
12795            if (rs == 0 && rt != 0) {
12796                /* OPC_BLEZALC */
12797                tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LE), t1, 0, fs);
12798            } else if (rs != 0 && rt != 0 && rs == rt) {
12799                /* OPC_BGEZALC */
12800                tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GE), t1, 0, fs);
12801            } else {
12802                /* OPC_BGEUC */
12803                tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_GEU), t0, t1, fs);
12804            }
12805            break;
12806        case OPC_BGTZALC: /* OPC_BLTZALC, OPC_BLTUC */
12807            if (rs == 0 && rt != 0) {
12808                /* OPC_BGTZALC */
12809                tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GT), t1, 0, fs);
12810            } else if (rs != 0 && rt != 0 && rs == rt) {
12811                /* OPC_BLTZALC */
12812                tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LT), t1, 0, fs);
12813            } else {
12814                /* OPC_BLTUC */
12815                tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_LTU), t0, t1, fs);
12816            }
12817            break;
12818        case OPC_BLEZC: /* OPC_BGEZC, OPC_BGEC */
12819            if (rs == 0 && rt != 0) {
12820                /* OPC_BLEZC */
12821                tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LE), t1, 0, fs);
12822            } else if (rs != 0 && rt != 0 && rs == rt) {
12823                /* OPC_BGEZC */
12824                tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GE), t1, 0, fs);
12825            } else {
12826                /* OPC_BGEC */
12827                tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_GE), t0, t1, fs);
12828            }
12829            break;
12830        case OPC_BGTZC: /* OPC_BLTZC, OPC_BLTC */
12831            if (rs == 0 && rt != 0) {
12832                /* OPC_BGTZC */
12833                tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GT), t1, 0, fs);
12834            } else if (rs != 0 && rt != 0 && rs == rt) {
12835                /* OPC_BLTZC */
12836                tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LT), t1, 0, fs);
12837            } else {
12838                /* OPC_BLTC */
12839                tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_LT), t0, t1, fs);
12840            }
12841            break;
12842        case OPC_BOVC: /* OPC_BEQZALC, OPC_BEQC */
12843        case OPC_BNVC: /* OPC_BNEZALC, OPC_BNEC */
12844            if (rs >= rt) {
12845                /* OPC_BOVC, OPC_BNVC */
12846                TCGv t2 = tcg_temp_new();
12847                TCGv t3 = tcg_temp_new();
12848                TCGv t4 = tcg_temp_new();
12849                TCGv input_overflow = tcg_temp_new();
12850
12851                gen_load_gpr(t0, rs);
12852                gen_load_gpr(t1, rt);
12853                tcg_gen_ext32s_tl(t2, t0);
12854                tcg_gen_setcond_tl(TCG_COND_NE, input_overflow, t2, t0);
12855                tcg_gen_ext32s_tl(t3, t1);
12856                tcg_gen_setcond_tl(TCG_COND_NE, t4, t3, t1);
12857                tcg_gen_or_tl(input_overflow, input_overflow, t4);
12858
12859                tcg_gen_add_tl(t4, t2, t3);
12860                tcg_gen_ext32s_tl(t4, t4);
12861                tcg_gen_xor_tl(t2, t2, t3);
12862                tcg_gen_xor_tl(t3, t4, t3);
12863                tcg_gen_andc_tl(t2, t3, t2);
12864                tcg_gen_setcondi_tl(TCG_COND_LT, t4, t2, 0);
12865                tcg_gen_or_tl(t4, t4, input_overflow);
12866                if (opc == OPC_BOVC) {
12867                    /* OPC_BOVC */
12868                    tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_NE), t4, 0, fs);
12869                } else {
12870                    /* OPC_BNVC */
12871                    tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_EQ), t4, 0, fs);
12872                }
12873                tcg_temp_free(input_overflow);
12874                tcg_temp_free(t4);
12875                tcg_temp_free(t3);
12876                tcg_temp_free(t2);
12877            } else if (rs < rt && rs == 0) {
12878                /* OPC_BEQZALC, OPC_BNEZALC */
12879                if (opc == OPC_BEQZALC) {
12880                    /* OPC_BEQZALC */
12881                    tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_EQ), t1, 0, fs);
12882                } else {
12883                    /* OPC_BNEZALC */
12884                    tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_NE), t1, 0, fs);
12885                }
12886            } else {
12887                /* OPC_BEQC, OPC_BNEC */
12888                if (opc == OPC_BEQC) {
12889                    /* OPC_BEQC */
12890                    tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_EQ), t0, t1, fs);
12891                } else {
12892                    /* OPC_BNEC */
12893                    tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_NE), t0, t1, fs);
12894                }
12895            }
12896            break;
12897        case OPC_BEQZC:
12898            tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_EQ), t0, 0, fs);
12899            break;
12900        case OPC_BNEZC:
12901            tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_NE), t0, 0, fs);
12902            break;
12903        default:
12904            MIPS_INVAL("Compact conditional branch/jump");
12905            generate_exception_end(ctx, EXCP_RI);
12906            goto out;
12907        }
12908
12909        /* Generating branch here as compact branches don't have delay slot */
12910        gen_goto_tb(ctx, 1, ctx->btarget);
12911        gen_set_label(fs);
12912
12913        ctx->hflags |= MIPS_HFLAG_FBNSLOT;
12914    }
12915
12916out:
12917    tcg_temp_free(t0);
12918    tcg_temp_free(t1);
12919}
12920
12921/* ISA extensions (ASEs) */
12922/* MIPS16 extension to MIPS32 */
12923
12924/* MIPS16 major opcodes */
12925enum {
12926  M16_OPC_ADDIUSP = 0x00,
12927  M16_OPC_ADDIUPC = 0x01,
12928  M16_OPC_B = 0x02,
12929  M16_OPC_JAL = 0x03,
12930  M16_OPC_BEQZ = 0x04,
12931  M16_OPC_BNEQZ = 0x05,
12932  M16_OPC_SHIFT = 0x06,
12933  M16_OPC_LD = 0x07,
12934  M16_OPC_RRIA = 0x08,
12935  M16_OPC_ADDIU8 = 0x09,
12936  M16_OPC_SLTI = 0x0a,
12937  M16_OPC_SLTIU = 0x0b,
12938  M16_OPC_I8 = 0x0c,
12939  M16_OPC_LI = 0x0d,
12940  M16_OPC_CMPI = 0x0e,
12941  M16_OPC_SD = 0x0f,
12942  M16_OPC_LB = 0x10,
12943  M16_OPC_LH = 0x11,
12944  M16_OPC_LWSP = 0x12,
12945  M16_OPC_LW = 0x13,
12946  M16_OPC_LBU = 0x14,
12947  M16_OPC_LHU = 0x15,
12948  M16_OPC_LWPC = 0x16,
12949  M16_OPC_LWU = 0x17,
12950  M16_OPC_SB = 0x18,
12951  M16_OPC_SH = 0x19,
12952  M16_OPC_SWSP = 0x1a,
12953  M16_OPC_SW = 0x1b,
12954  M16_OPC_RRR = 0x1c,
12955  M16_OPC_RR = 0x1d,
12956  M16_OPC_EXTEND = 0x1e,
12957  M16_OPC_I64 = 0x1f
12958};
12959
12960/* I8 funct field */
12961enum {
12962  I8_BTEQZ = 0x0,
12963  I8_BTNEZ = 0x1,
12964  I8_SWRASP = 0x2,
12965  I8_ADJSP = 0x3,
12966  I8_SVRS = 0x4,
12967  I8_MOV32R = 0x5,
12968  I8_MOVR32 = 0x7
12969};
12970
12971/* RRR f field */
12972enum {
12973  RRR_DADDU = 0x0,
12974  RRR_ADDU = 0x1,
12975  RRR_DSUBU = 0x2,
12976  RRR_SUBU = 0x3
12977};
12978
12979/* RR funct field */
12980enum {
12981  RR_JR = 0x00,
12982  RR_SDBBP = 0x01,
12983  RR_SLT = 0x02,
12984  RR_SLTU = 0x03,
12985  RR_SLLV = 0x04,
12986  RR_BREAK = 0x05,
12987  RR_SRLV = 0x06,
12988  RR_SRAV = 0x07,
12989  RR_DSRL = 0x08,
12990  RR_CMP = 0x0a,
12991  RR_NEG = 0x0b,
12992  RR_AND = 0x0c,
12993  RR_OR = 0x0d,
12994  RR_XOR = 0x0e,
12995  RR_NOT = 0x0f,
12996  RR_MFHI = 0x10,
12997  RR_CNVT = 0x11,
12998  RR_MFLO = 0x12,
12999  RR_DSRA = 0x13,
13000  RR_DSLLV = 0x14,
13001  RR_DSRLV = 0x16,
13002  RR_DSRAV = 0x17,
13003  RR_MULT = 0x18,
13004  RR_MULTU = 0x19,
13005  RR_DIV = 0x1a,
13006  RR_DIVU = 0x1b,
13007  RR_DMULT = 0x1c,
13008  RR_DMULTU = 0x1d,
13009  RR_DDIV = 0x1e,
13010  RR_DDIVU = 0x1f
13011};
13012
13013/* I64 funct field */
13014enum {
13015  I64_LDSP = 0x0,
13016  I64_SDSP = 0x1,
13017  I64_SDRASP = 0x2,
13018  I64_DADJSP = 0x3,
13019  I64_LDPC = 0x4,
13020  I64_DADDIU5 = 0x5,
13021  I64_DADDIUPC = 0x6,
13022  I64_DADDIUSP = 0x7
13023};
13024
13025/* RR ry field for CNVT */
13026enum {
13027  RR_RY_CNVT_ZEB = 0x0,
13028  RR_RY_CNVT_ZEH = 0x1,
13029  RR_RY_CNVT_ZEW = 0x2,
13030  RR_RY_CNVT_SEB = 0x4,
13031  RR_RY_CNVT_SEH = 0x5,
13032  RR_RY_CNVT_SEW = 0x6,
13033};
13034
13035static int xlat (int r)
13036{
13037  static int map[] = { 16, 17, 2, 3, 4, 5, 6, 7 };
13038
13039  return map[r];
13040}
13041
13042static void gen_mips16_save (DisasContext *ctx,
13043                             int xsregs, int aregs,
13044                             int do_ra, int do_s0, int do_s1,
13045                             int framesize)
13046{
13047    TCGv t0 = tcg_temp_new();
13048    TCGv t1 = tcg_temp_new();
13049    TCGv t2 = tcg_temp_new();
13050    int args, astatic;
13051
13052    switch (aregs) {
13053    case 0:
13054    case 1:
13055    case 2:
13056    case 3:
13057    case 11:
13058        args = 0;
13059        break;
13060    case 4:
13061    case 5:
13062    case 6:
13063    case 7:
13064        args = 1;
13065        break;
13066    case 8:
13067    case 9:
13068    case 10:
13069        args = 2;
13070        break;
13071    case 12:
13072    case 13:
13073        args = 3;
13074        break;
13075    case 14:
13076        args = 4;
13077        break;
13078    default:
13079        generate_exception_end(ctx, EXCP_RI);
13080        return;
13081    }
13082
13083    switch (args) {
13084    case 4:
13085        gen_base_offset_addr(ctx, t0, 29, 12);
13086        gen_load_gpr(t1, 7);
13087        tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL);
13088        /* Fall through */
13089    case 3:
13090        gen_base_offset_addr(ctx, t0, 29, 8);
13091        gen_load_gpr(t1, 6);
13092        tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL);
13093        /* Fall through */
13094    case 2:
13095        gen_base_offset_addr(ctx, t0, 29, 4);
13096        gen_load_gpr(t1, 5);
13097        tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL);
13098        /* Fall through */
13099    case 1:
13100        gen_base_offset_addr(ctx, t0, 29, 0);
13101        gen_load_gpr(t1, 4);
13102        tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL);
13103    }
13104
13105    gen_load_gpr(t0, 29);
13106
13107#define DECR_AND_STORE(reg) do {                                 \
13108        tcg_gen_movi_tl(t2, -4);                                 \
13109        gen_op_addr_add(ctx, t0, t0, t2);                        \
13110        gen_load_gpr(t1, reg);                                   \
13111        tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL); \
13112    } while (0)
13113
13114    if (do_ra) {
13115        DECR_AND_STORE(31);
13116    }
13117
13118    switch (xsregs) {
13119    case 7:
13120        DECR_AND_STORE(30);
13121        /* Fall through */
13122    case 6:
13123        DECR_AND_STORE(23);
13124        /* Fall through */
13125    case 5:
13126        DECR_AND_STORE(22);
13127        /* Fall through */
13128    case 4:
13129        DECR_AND_STORE(21);
13130        /* Fall through */
13131    case 3:
13132        DECR_AND_STORE(20);
13133        /* Fall through */
13134    case 2:
13135        DECR_AND_STORE(19);
13136        /* Fall through */
13137    case 1:
13138        DECR_AND_STORE(18);
13139    }
13140
13141    if (do_s1) {
13142        DECR_AND_STORE(17);
13143    }
13144    if (do_s0) {
13145        DECR_AND_STORE(16);
13146    }
13147
13148    switch (aregs) {
13149    case 0:
13150    case 4:
13151    case 8:
13152    case 12:
13153    case 14:
13154        astatic = 0;
13155        break;
13156    case 1:
13157    case 5:
13158    case 9:
13159    case 13:
13160        astatic = 1;
13161        break;
13162    case 2:
13163    case 6:
13164    case 10:
13165        astatic = 2;
13166        break;
13167    case 3:
13168    case 7:
13169        astatic = 3;
13170        break;
13171    case 11:
13172        astatic = 4;
13173        break;
13174    default:
13175        generate_exception_end(ctx, EXCP_RI);
13176        return;
13177    }
13178
13179    if (astatic > 0) {
13180        DECR_AND_STORE(7);
13181        if (astatic > 1) {
13182            DECR_AND_STORE(6);
13183            if (astatic > 2) {
13184                DECR_AND_STORE(5);
13185                if (astatic > 3) {
13186                    DECR_AND_STORE(4);
13187                }
13188            }
13189        }
13190    }
13191#undef DECR_AND_STORE
13192
13193    tcg_gen_movi_tl(t2, -framesize);
13194    gen_op_addr_add(ctx, cpu_gpr[29], cpu_gpr[29], t2);
13195    tcg_temp_free(t0);
13196    tcg_temp_free(t1);
13197    tcg_temp_free(t2);
13198}
13199
13200static void gen_mips16_restore (DisasContext *ctx,
13201                                int xsregs, int aregs,
13202                                int do_ra, int do_s0, int do_s1,
13203                                int framesize)
13204{
13205    int astatic;
13206    TCGv t0 = tcg_temp_new();
13207    TCGv t1 = tcg_temp_new();
13208    TCGv t2 = tcg_temp_new();
13209
13210    tcg_gen_movi_tl(t2, framesize);
13211    gen_op_addr_add(ctx, t0, cpu_gpr[29], t2);
13212
13213#define DECR_AND_LOAD(reg) do {                            \
13214        tcg_gen_movi_tl(t2, -4);                           \
13215        gen_op_addr_add(ctx, t0, t0, t2);                  \
13216        tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TESL); \
13217        gen_store_gpr(t1, reg);                            \
13218    } while (0)
13219
13220    if (do_ra) {
13221        DECR_AND_LOAD(31);
13222    }
13223
13224    switch (xsregs) {
13225    case 7:
13226        DECR_AND_LOAD(30);
13227        /* Fall through */
13228    case 6:
13229        DECR_AND_LOAD(23);
13230        /* Fall through */
13231    case 5:
13232        DECR_AND_LOAD(22);
13233        /* Fall through */
13234    case 4:
13235        DECR_AND_LOAD(21);
13236        /* Fall through */
13237    case 3:
13238        DECR_AND_LOAD(20);
13239        /* Fall through */
13240    case 2:
13241        DECR_AND_LOAD(19);
13242        /* Fall through */
13243    case 1:
13244        DECR_AND_LOAD(18);
13245    }
13246
13247    if (do_s1) {
13248        DECR_AND_LOAD(17);
13249    }
13250    if (do_s0) {
13251        DECR_AND_LOAD(16);
13252    }
13253
13254    switch (aregs) {
13255    case 0:
13256    case 4:
13257    case 8:
13258    case 12:
13259    case 14:
13260        astatic = 0;
13261        break;
13262    case 1:
13263    case 5:
13264    case 9:
13265    case 13:
13266        astatic = 1;
13267        break;
13268    case 2:
13269    case 6:
13270    case 10:
13271        astatic = 2;
13272        break;
13273    case 3:
13274    case 7:
13275        astatic = 3;
13276        break;
13277    case 11:
13278        astatic = 4;
13279        break;
13280    default:
13281        generate_exception_end(ctx, EXCP_RI);
13282        return;
13283    }
13284
13285    if (astatic > 0) {
13286        DECR_AND_LOAD(7);
13287        if (astatic > 1) {
13288            DECR_AND_LOAD(6);
13289            if (astatic > 2) {
13290                DECR_AND_LOAD(5);
13291                if (astatic > 3) {
13292                    DECR_AND_LOAD(4);
13293                }
13294            }
13295        }
13296    }
13297#undef DECR_AND_LOAD
13298
13299    tcg_gen_movi_tl(t2, framesize);
13300    gen_op_addr_add(ctx, cpu_gpr[29], cpu_gpr[29], t2);
13301    tcg_temp_free(t0);
13302    tcg_temp_free(t1);
13303    tcg_temp_free(t2);
13304}
13305
13306static void gen_addiupc (DisasContext *ctx, int rx, int imm,
13307                         int is_64_bit, int extended)
13308{
13309    TCGv t0;
13310
13311    if (extended && (ctx->hflags & MIPS_HFLAG_BMASK)) {
13312        generate_exception_end(ctx, EXCP_RI);
13313        return;
13314    }
13315
13316    t0 = tcg_temp_new();
13317
13318    tcg_gen_movi_tl(t0, pc_relative_pc(ctx));
13319    tcg_gen_addi_tl(cpu_gpr[rx], t0, imm);
13320    if (!is_64_bit) {
13321        tcg_gen_ext32s_tl(cpu_gpr[rx], cpu_gpr[rx]);
13322    }
13323
13324    tcg_temp_free(t0);
13325}
13326
13327static void gen_cache_operation(DisasContext *ctx, uint32_t op, int base,
13328                                int16_t offset)
13329{
13330    TCGv_i32 t0 = tcg_const_i32(op);
13331    TCGv t1 = tcg_temp_new();
13332    gen_base_offset_addr(ctx, t1, base, offset);
13333    gen_helper_cache(cpu_env, t1, t0);
13334}
13335
13336#if defined(TARGET_MIPS64)
13337static void decode_i64_mips16 (DisasContext *ctx,
13338                               int ry, int funct, int16_t offset,
13339                               int extended)
13340{
13341    switch (funct) {
13342    case I64_LDSP:
13343        check_insn(ctx, ISA_MIPS3);
13344        check_mips_64(ctx);
13345        offset = extended ? offset : offset << 3;
13346        gen_ld(ctx, OPC_LD, ry, 29, offset);
13347        break;
13348    case I64_SDSP:
13349        check_insn(ctx, ISA_MIPS3);
13350        check_mips_64(ctx);
13351        offset = extended ? offset : offset << 3;
13352        gen_st(ctx, OPC_SD, ry, 29, offset);
13353        break;
13354    case I64_SDRASP:
13355        check_insn(ctx, ISA_MIPS3);
13356        check_mips_64(ctx);
13357        offset = extended ? offset : (ctx->opcode & 0xff) << 3;
13358        gen_st(ctx, OPC_SD, 31, 29, offset);
13359        break;
13360    case I64_DADJSP:
13361        check_insn(ctx, ISA_MIPS3);
13362        check_mips_64(ctx);
13363        offset = extended ? offset : ((int8_t)ctx->opcode) << 3;
13364        gen_arith_imm(ctx, OPC_DADDIU, 29, 29, offset);
13365        break;
13366    case I64_LDPC:
13367        check_insn(ctx, ISA_MIPS3);
13368        check_mips_64(ctx);
13369        if (extended && (ctx->hflags & MIPS_HFLAG_BMASK)) {
13370            generate_exception_end(ctx, EXCP_RI);
13371        } else {
13372            offset = extended ? offset : offset << 3;
13373            gen_ld(ctx, OPC_LDPC, ry, 0, offset);
13374        }
13375        break;
13376    case I64_DADDIU5:
13377        check_insn(ctx, ISA_MIPS3);
13378        check_mips_64(ctx);
13379        offset = extended ? offset : ((int8_t)(offset << 3)) >> 3;
13380        gen_arith_imm(ctx, OPC_DADDIU, ry, ry, offset);
13381        break;
13382    case I64_DADDIUPC:
13383        check_insn(ctx, ISA_MIPS3);
13384        check_mips_64(ctx);
13385        offset = extended ? offset : offset << 2;
13386        gen_addiupc(ctx, ry, offset, 1, extended);
13387        break;
13388    case I64_DADDIUSP:
13389        check_insn(ctx, ISA_MIPS3);
13390        check_mips_64(ctx);
13391        offset = extended ? offset : offset << 2;
13392        gen_arith_imm(ctx, OPC_DADDIU, ry, 29, offset);
13393        break;
13394    }
13395}
13396#endif
13397
13398static int decode_extended_mips16_opc (CPUMIPSState *env, DisasContext *ctx)
13399{
13400    int extend = cpu_lduw_code(env, ctx->base.pc_next + 2);
13401    int op, rx, ry, funct, sa;
13402    int16_t imm, offset;
13403
13404    ctx->opcode = (ctx->opcode << 16) | extend;
13405    op = (ctx->opcode >> 11) & 0x1f;
13406    sa = (ctx->opcode >> 22) & 0x1f;
13407    funct = (ctx->opcode >> 8) & 0x7;
13408    rx = xlat((ctx->opcode >> 8) & 0x7);
13409    ry = xlat((ctx->opcode >> 5) & 0x7);
13410    offset = imm = (int16_t) (((ctx->opcode >> 16) & 0x1f) << 11
13411                              | ((ctx->opcode >> 21) & 0x3f) << 5
13412                              | (ctx->opcode & 0x1f));
13413
13414    /* The extended opcodes cleverly reuse the opcodes from their 16-bit
13415       counterparts.  */
13416    switch (op) {
13417    case M16_OPC_ADDIUSP:
13418        gen_arith_imm(ctx, OPC_ADDIU, rx, 29, imm);
13419        break;
13420    case M16_OPC_ADDIUPC:
13421        gen_addiupc(ctx, rx, imm, 0, 1);
13422        break;
13423    case M16_OPC_B:
13424        gen_compute_branch(ctx, OPC_BEQ, 4, 0, 0, offset << 1, 0);
13425        /* No delay slot, so just process as a normal instruction */
13426        break;
13427    case M16_OPC_BEQZ:
13428        gen_compute_branch(ctx, OPC_BEQ, 4, rx, 0, offset << 1, 0);
13429        /* No delay slot, so just process as a normal instruction */
13430        break;
13431    case M16_OPC_BNEQZ:
13432        gen_compute_branch(ctx, OPC_BNE, 4, rx, 0, offset << 1, 0);
13433        /* No delay slot, so just process as a normal instruction */
13434        break;
13435    case M16_OPC_SHIFT:
13436        switch (ctx->opcode & 0x3) {
13437        case 0x0:
13438            gen_shift_imm(ctx, OPC_SLL, rx, ry, sa);
13439            break;
13440        case 0x1:
13441#if defined(TARGET_MIPS64)
13442            check_mips_64(ctx);
13443            gen_shift_imm(ctx, OPC_DSLL, rx, ry, sa);
13444#else
13445            generate_exception_end(ctx, EXCP_RI);
13446#endif
13447            break;
13448        case 0x2:
13449            gen_shift_imm(ctx, OPC_SRL, rx, ry, sa);
13450            break;
13451        case 0x3:
13452            gen_shift_imm(ctx, OPC_SRA, rx, ry, sa);
13453            break;
13454        }
13455        break;
13456#if defined(TARGET_MIPS64)
13457    case M16_OPC_LD:
13458        check_insn(ctx, ISA_MIPS3);
13459        check_mips_64(ctx);
13460        gen_ld(ctx, OPC_LD, ry, rx, offset);
13461        break;
13462#endif
13463    case M16_OPC_RRIA:
13464        imm = ctx->opcode & 0xf;
13465        imm = imm | ((ctx->opcode >> 20) & 0x7f) << 4;
13466        imm = imm | ((ctx->opcode >> 16) & 0xf) << 11;
13467        imm = (int16_t) (imm << 1) >> 1;
13468        if ((ctx->opcode >> 4) & 0x1) {
13469#if defined(TARGET_MIPS64)
13470            check_mips_64(ctx);
13471            gen_arith_imm(ctx, OPC_DADDIU, ry, rx, imm);
13472#else
13473            generate_exception_end(ctx, EXCP_RI);
13474#endif
13475        } else {
13476            gen_arith_imm(ctx, OPC_ADDIU, ry, rx, imm);
13477        }
13478        break;
13479    case M16_OPC_ADDIU8:
13480        gen_arith_imm(ctx, OPC_ADDIU, rx, rx, imm);
13481        break;
13482    case M16_OPC_SLTI:
13483        gen_slt_imm(ctx, OPC_SLTI, 24, rx, imm);
13484        break;
13485    case M16_OPC_SLTIU:
13486        gen_slt_imm(ctx, OPC_SLTIU, 24, rx, imm);
13487        break;
13488    case M16_OPC_I8:
13489        switch (funct) {
13490        case I8_BTEQZ:
13491            gen_compute_branch(ctx, OPC_BEQ, 4, 24, 0, offset << 1, 0);
13492            break;
13493        case I8_BTNEZ:
13494            gen_compute_branch(ctx, OPC_BNE, 4, 24, 0, offset << 1, 0);
13495            break;
13496        case I8_SWRASP:
13497            gen_st(ctx, OPC_SW, 31, 29, imm);
13498            break;
13499        case I8_ADJSP:
13500            gen_arith_imm(ctx, OPC_ADDIU, 29, 29, imm);
13501            break;
13502        case I8_SVRS:
13503            check_insn(ctx, ISA_MIPS32);
13504            {
13505                int xsregs = (ctx->opcode >> 24) & 0x7;
13506                int aregs = (ctx->opcode >> 16) & 0xf;
13507                int do_ra = (ctx->opcode >> 6) & 0x1;
13508                int do_s0 = (ctx->opcode >> 5) & 0x1;
13509                int do_s1 = (ctx->opcode >> 4) & 0x1;
13510                int framesize = (((ctx->opcode >> 20) & 0xf) << 4
13511                                 | (ctx->opcode & 0xf)) << 3;
13512
13513                if (ctx->opcode & (1 << 7)) {
13514                    gen_mips16_save(ctx, xsregs, aregs,
13515                                    do_ra, do_s0, do_s1,
13516                                    framesize);
13517                } else {
13518                    gen_mips16_restore(ctx, xsregs, aregs,
13519                                       do_ra, do_s0, do_s1,
13520                                       framesize);
13521                }
13522            }
13523            break;
13524        default:
13525            generate_exception_end(ctx, EXCP_RI);
13526            break;
13527        }
13528        break;
13529    case M16_OPC_LI:
13530        tcg_gen_movi_tl(cpu_gpr[rx], (uint16_t) imm);
13531        break;
13532    case M16_OPC_CMPI:
13533        tcg_gen_xori_tl(cpu_gpr[24], cpu_gpr[rx], (uint16_t) imm);
13534        break;
13535#if defined(TARGET_MIPS64)
13536    case M16_OPC_SD:
13537        check_insn(ctx, ISA_MIPS3);
13538        check_mips_64(ctx);
13539        gen_st(ctx, OPC_SD, ry, rx, offset);
13540        break;
13541#endif
13542    case M16_OPC_LB:
13543        gen_ld(ctx, OPC_LB, ry, rx, offset);
13544        break;
13545    case M16_OPC_LH:
13546        gen_ld(ctx, OPC_LH, ry, rx, offset);
13547        break;
13548    case M16_OPC_LWSP:
13549        gen_ld(ctx, OPC_LW, rx, 29, offset);
13550        break;
13551    case M16_OPC_LW:
13552        gen_ld(ctx, OPC_LW, ry, rx, offset);
13553        break;
13554    case M16_OPC_LBU:
13555        gen_ld(ctx, OPC_LBU, ry, rx, offset);
13556        break;
13557    case M16_OPC_LHU:
13558        gen_ld(ctx, OPC_LHU, ry, rx, offset);
13559        break;
13560    case M16_OPC_LWPC:
13561        gen_ld(ctx, OPC_LWPC, rx, 0, offset);
13562        break;
13563#if defined(TARGET_MIPS64)
13564    case M16_OPC_LWU:
13565        check_insn(ctx, ISA_MIPS3);
13566        check_mips_64(ctx);
13567        gen_ld(ctx, OPC_LWU, ry, rx, offset);
13568        break;
13569#endif
13570    case M16_OPC_SB:
13571        gen_st(ctx, OPC_SB, ry, rx, offset);
13572        break;
13573    case M16_OPC_SH:
13574        gen_st(ctx, OPC_SH, ry, rx, offset);
13575        break;
13576    case M16_OPC_SWSP:
13577        gen_st(ctx, OPC_SW, rx, 29, offset);
13578        break;
13579    case M16_OPC_SW:
13580        gen_st(ctx, OPC_SW, ry, rx, offset);
13581        break;
13582#if defined(TARGET_MIPS64)
13583    case M16_OPC_I64:
13584        decode_i64_mips16(ctx, ry, funct, offset, 1);
13585        break;
13586#endif
13587    default:
13588        generate_exception_end(ctx, EXCP_RI);
13589        break;
13590    }
13591
13592    return 4;
13593}
13594
13595static inline bool is_uhi(int sdbbp_code)
13596{
13597#ifdef CONFIG_USER_ONLY
13598    return false;
13599#else
13600    return semihosting_enabled() && sdbbp_code == 1;
13601#endif
13602}
13603
13604static int decode_mips16_opc (CPUMIPSState *env, DisasContext *ctx)
13605{
13606    int rx, ry;
13607    int sa;
13608    int op, cnvt_op, op1, offset;
13609    int funct;
13610    int n_bytes;
13611
13612    op = (ctx->opcode >> 11) & 0x1f;
13613    sa = (ctx->opcode >> 2) & 0x7;
13614    sa = sa == 0 ? 8 : sa;
13615    rx = xlat((ctx->opcode >> 8) & 0x7);
13616    cnvt_op = (ctx->opcode >> 5) & 0x7;
13617    ry = xlat((ctx->opcode >> 5) & 0x7);
13618    op1 = offset = ctx->opcode & 0x1f;
13619
13620    n_bytes = 2;
13621
13622    switch (op) {
13623    case M16_OPC_ADDIUSP:
13624        {
13625            int16_t imm = ((uint8_t) ctx->opcode) << 2;
13626
13627            gen_arith_imm(ctx, OPC_ADDIU, rx, 29, imm);
13628        }
13629        break;
13630    case M16_OPC_ADDIUPC:
13631        gen_addiupc(ctx, rx, ((uint8_t) ctx->opcode) << 2, 0, 0);
13632        break;
13633    case M16_OPC_B:
13634        offset = (ctx->opcode & 0x7ff) << 1;
13635        offset = (int16_t)(offset << 4) >> 4;
13636        gen_compute_branch(ctx, OPC_BEQ, 2, 0, 0, offset, 0);
13637        /* No delay slot, so just process as a normal instruction */
13638        break;
13639    case M16_OPC_JAL:
13640        offset = cpu_lduw_code(env, ctx->base.pc_next + 2);
13641        offset = (((ctx->opcode & 0x1f) << 21)
13642                  | ((ctx->opcode >> 5) & 0x1f) << 16
13643                  | offset) << 2;
13644        op = ((ctx->opcode >> 10) & 0x1) ? OPC_JALX : OPC_JAL;
13645        gen_compute_branch(ctx, op, 4, rx, ry, offset, 2);
13646        n_bytes = 4;
13647        break;
13648    case M16_OPC_BEQZ:
13649        gen_compute_branch(ctx, OPC_BEQ, 2, rx, 0,
13650                           ((int8_t)ctx->opcode) << 1, 0);
13651        /* No delay slot, so just process as a normal instruction */
13652        break;
13653    case M16_OPC_BNEQZ:
13654        gen_compute_branch(ctx, OPC_BNE, 2, rx, 0,
13655                           ((int8_t)ctx->opcode) << 1, 0);
13656        /* No delay slot, so just process as a normal instruction */
13657        break;
13658    case M16_OPC_SHIFT:
13659        switch (ctx->opcode & 0x3) {
13660        case 0x0:
13661            gen_shift_imm(ctx, OPC_SLL, rx, ry, sa);
13662            break;
13663        case 0x1:
13664#if defined(TARGET_MIPS64)
13665            check_insn(ctx, ISA_MIPS3);
13666            check_mips_64(ctx);
13667            gen_shift_imm(ctx, OPC_DSLL, rx, ry, sa);
13668#else
13669            generate_exception_end(ctx, EXCP_RI);
13670#endif
13671            break;
13672        case 0x2:
13673            gen_shift_imm(ctx, OPC_SRL, rx, ry, sa);
13674            break;
13675        case 0x3:
13676            gen_shift_imm(ctx, OPC_SRA, rx, ry, sa);
13677            break;
13678        }
13679        break;
13680#if defined(TARGET_MIPS64)
13681    case M16_OPC_LD:
13682        check_insn(ctx, ISA_MIPS3);
13683        check_mips_64(ctx);
13684        gen_ld(ctx, OPC_LD, ry, rx, offset << 3);
13685        break;
13686#endif
13687    case M16_OPC_RRIA:
13688        {
13689            int16_t imm = (int8_t)((ctx->opcode & 0xf) << 4) >> 4;
13690
13691            if ((ctx->opcode >> 4) & 1) {
13692#if defined(TARGET_MIPS64)
13693                check_insn(ctx, ISA_MIPS3);
13694                check_mips_64(ctx);
13695                gen_arith_imm(ctx, OPC_DADDIU, ry, rx, imm);
13696#else
13697                generate_exception_end(ctx, EXCP_RI);
13698#endif
13699            } else {
13700                gen_arith_imm(ctx, OPC_ADDIU, ry, rx, imm);
13701            }
13702        }
13703        break;
13704    case M16_OPC_ADDIU8:
13705        {
13706            int16_t imm = (int8_t) ctx->opcode;
13707
13708            gen_arith_imm(ctx, OPC_ADDIU, rx, rx, imm);
13709        }
13710        break;
13711    case M16_OPC_SLTI:
13712        {
13713            int16_t imm = (uint8_t) ctx->opcode;
13714            gen_slt_imm(ctx, OPC_SLTI, 24, rx, imm);
13715        }
13716        break;
13717    case M16_OPC_SLTIU:
13718        {
13719            int16_t imm = (uint8_t) ctx->opcode;
13720            gen_slt_imm(ctx, OPC_SLTIU, 24, rx, imm);
13721        }
13722        break;
13723    case M16_OPC_I8:
13724        {
13725            int reg32;
13726
13727            funct = (ctx->opcode >> 8) & 0x7;
13728            switch (funct) {
13729            case I8_BTEQZ:
13730                gen_compute_branch(ctx, OPC_BEQ, 2, 24, 0,
13731                                   ((int8_t)ctx->opcode) << 1, 0);
13732                break;
13733            case I8_BTNEZ:
13734                gen_compute_branch(ctx, OPC_BNE, 2, 24, 0,
13735                                   ((int8_t)ctx->opcode) << 1, 0);
13736                break;
13737            case I8_SWRASP:
13738                gen_st(ctx, OPC_SW, 31, 29, (ctx->opcode & 0xff) << 2);
13739                break;
13740            case I8_ADJSP:
13741                gen_arith_imm(ctx, OPC_ADDIU, 29, 29,
13742                              ((int8_t)ctx->opcode) << 3);
13743                break;
13744            case I8_SVRS:
13745                check_insn(ctx, ISA_MIPS32);
13746                {
13747                    int do_ra = ctx->opcode & (1 << 6);
13748                    int do_s0 = ctx->opcode & (1 << 5);
13749                    int do_s1 = ctx->opcode & (1 << 4);
13750                    int framesize = ctx->opcode & 0xf;
13751
13752                    if (framesize == 0) {
13753                        framesize = 128;
13754                    } else {
13755                        framesize = framesize << 3;
13756                    }
13757
13758                    if (ctx->opcode & (1 << 7)) {
13759                        gen_mips16_save(ctx, 0, 0,
13760                                        do_ra, do_s0, do_s1, framesize);
13761                    } else {
13762                        gen_mips16_restore(ctx, 0, 0,
13763                                           do_ra, do_s0, do_s1, framesize);
13764                    }
13765                }
13766                break;
13767            case I8_MOV32R:
13768                {
13769                    int rz = xlat(ctx->opcode & 0x7);
13770
13771                    reg32 = (((ctx->opcode >> 3) & 0x3) << 3) |
13772                        ((ctx->opcode >> 5) & 0x7);
13773                    gen_arith(ctx, OPC_ADDU, reg32, rz, 0);
13774                }
13775                break;
13776            case I8_MOVR32:
13777                reg32 = ctx->opcode & 0x1f;
13778                gen_arith(ctx, OPC_ADDU, ry, reg32, 0);
13779                break;
13780            default:
13781                generate_exception_end(ctx, EXCP_RI);
13782                break;
13783            }
13784        }
13785        break;
13786    case M16_OPC_LI:
13787        {
13788            int16_t imm = (uint8_t) ctx->opcode;
13789
13790            gen_arith_imm(ctx, OPC_ADDIU, rx, 0, imm);
13791        }
13792        break;
13793    case M16_OPC_CMPI:
13794        {
13795            int16_t imm = (uint8_t) ctx->opcode;
13796            gen_logic_imm(ctx, OPC_XORI, 24, rx, imm);
13797        }
13798        break;
13799#if defined(TARGET_MIPS64)
13800    case M16_OPC_SD:
13801        check_insn(ctx, ISA_MIPS3);
13802        check_mips_64(ctx);
13803        gen_st(ctx, OPC_SD, ry, rx, offset << 3);
13804        break;
13805#endif
13806    case M16_OPC_LB:
13807        gen_ld(ctx, OPC_LB, ry, rx, offset);
13808        break;
13809    case M16_OPC_LH:
13810        gen_ld(ctx, OPC_LH, ry, rx, offset << 1);
13811        break;
13812    case M16_OPC_LWSP:
13813        gen_ld(ctx, OPC_LW, rx, 29, ((uint8_t)ctx->opcode) << 2);
13814        break;
13815    case M16_OPC_LW:
13816        gen_ld(ctx, OPC_LW, ry, rx, offset << 2);
13817        break;
13818    case M16_OPC_LBU:
13819        gen_ld(ctx, OPC_LBU, ry, rx, offset);
13820        break;
13821    case M16_OPC_LHU:
13822        gen_ld(ctx, OPC_LHU, ry, rx, offset << 1);
13823        break;
13824    case M16_OPC_LWPC:
13825        gen_ld(ctx, OPC_LWPC, rx, 0, ((uint8_t)ctx->opcode) << 2);
13826        break;
13827#if defined (TARGET_MIPS64)
13828    case M16_OPC_LWU:
13829        check_insn(ctx, ISA_MIPS3);
13830        check_mips_64(ctx);
13831        gen_ld(ctx, OPC_LWU, ry, rx, offset << 2);
13832        break;
13833#endif
13834    case M16_OPC_SB:
13835        gen_st(ctx, OPC_SB, ry, rx, offset);
13836        break;
13837    case M16_OPC_SH:
13838        gen_st(ctx, OPC_SH, ry, rx, offset << 1);
13839        break;
13840    case M16_OPC_SWSP:
13841        gen_st(ctx, OPC_SW, rx, 29, ((uint8_t)ctx->opcode) << 2);
13842        break;
13843    case M16_OPC_SW:
13844        gen_st(ctx, OPC_SW, ry, rx, offset << 2);
13845        break;
13846    case M16_OPC_RRR:
13847        {
13848            int rz = xlat((ctx->opcode >> 2) & 0x7);
13849            int mips32_op;
13850
13851            switch (ctx->opcode & 0x3) {
13852            case RRR_ADDU:
13853                mips32_op = OPC_ADDU;
13854                break;
13855            case RRR_SUBU:
13856                mips32_op = OPC_SUBU;
13857                break;
13858#if defined(TARGET_MIPS64)
13859            case RRR_DADDU:
13860                mips32_op = OPC_DADDU;
13861                check_insn(ctx, ISA_MIPS3);
13862                check_mips_64(ctx);
13863                break;
13864            case RRR_DSUBU:
13865                mips32_op = OPC_DSUBU;
13866                check_insn(ctx, ISA_MIPS3);
13867                check_mips_64(ctx);
13868                break;
13869#endif
13870            default:
13871                generate_exception_end(ctx, EXCP_RI);
13872                goto done;
13873            }
13874
13875            gen_arith(ctx, mips32_op, rz, rx, ry);
13876        done:
13877            ;
13878        }
13879        break;
13880    case M16_OPC_RR:
13881        switch (op1) {
13882        case RR_JR:
13883            {
13884                int nd = (ctx->opcode >> 7) & 0x1;
13885                int link = (ctx->opcode >> 6) & 0x1;
13886                int ra = (ctx->opcode >> 5) & 0x1;
13887
13888                if (nd) {
13889                    check_insn(ctx, ISA_MIPS32);
13890                }
13891
13892                if (link) {
13893                    op = OPC_JALR;
13894                } else {
13895                    op = OPC_JR;
13896                }
13897
13898                gen_compute_branch(ctx, op, 2, ra ? 31 : rx, 31, 0,
13899                                   (nd ? 0 : 2));
13900            }
13901            break;
13902        case RR_SDBBP:
13903            if (is_uhi(extract32(ctx->opcode, 5, 6))) {
13904                gen_helper_do_semihosting(cpu_env);
13905            } else {
13906                /* XXX: not clear which exception should be raised
13907                 *      when in debug mode...
13908                 */
13909                check_insn(ctx, ISA_MIPS32);
13910                generate_exception_end(ctx, EXCP_DBp);
13911            }
13912            break;
13913        case RR_SLT:
13914            gen_slt(ctx, OPC_SLT, 24, rx, ry);
13915            break;
13916        case RR_SLTU:
13917            gen_slt(ctx, OPC_SLTU, 24, rx, ry);
13918            break;
13919        case RR_BREAK:
13920            generate_exception_end(ctx, EXCP_BREAK);
13921            break;
13922        case RR_SLLV:
13923            gen_shift(ctx, OPC_SLLV, ry, rx, ry);
13924            break;
13925        case RR_SRLV:
13926            gen_shift(ctx, OPC_SRLV, ry, rx, ry);
13927            break;
13928        case RR_SRAV:
13929            gen_shift(ctx, OPC_SRAV, ry, rx, ry);
13930            break;
13931#if defined (TARGET_MIPS64)
13932        case RR_DSRL:
13933            check_insn(ctx, ISA_MIPS3);
13934            check_mips_64(ctx);
13935            gen_shift_imm(ctx, OPC_DSRL, ry, ry, sa);
13936            break;
13937#endif
13938        case RR_CMP:
13939            gen_logic(ctx, OPC_XOR, 24, rx, ry);
13940            break;
13941        case RR_NEG:
13942            gen_arith(ctx, OPC_SUBU, rx, 0, ry);
13943            break;
13944        case RR_AND:
13945            gen_logic(ctx, OPC_AND, rx, rx, ry);
13946            break;
13947        case RR_OR:
13948            gen_logic(ctx, OPC_OR, rx, rx, ry);
13949            break;
13950        case RR_XOR:
13951            gen_logic(ctx, OPC_XOR, rx, rx, ry);
13952            break;
13953        case RR_NOT:
13954            gen_logic(ctx, OPC_NOR, rx, ry, 0);
13955            break;
13956        case RR_MFHI:
13957            gen_HILO(ctx, OPC_MFHI, 0, rx);
13958            break;
13959        case RR_CNVT:
13960            check_insn(ctx, ISA_MIPS32);
13961            switch (cnvt_op) {
13962            case RR_RY_CNVT_ZEB:
13963                tcg_gen_ext8u_tl(cpu_gpr[rx], cpu_gpr[rx]);
13964                break;
13965            case RR_RY_CNVT_ZEH:
13966                tcg_gen_ext16u_tl(cpu_gpr[rx], cpu_gpr[rx]);
13967                break;
13968            case RR_RY_CNVT_SEB:
13969                tcg_gen_ext8s_tl(cpu_gpr[rx], cpu_gpr[rx]);
13970                break;
13971            case RR_RY_CNVT_SEH:
13972                tcg_gen_ext16s_tl(cpu_gpr[rx], cpu_gpr[rx]);
13973                break;
13974#if defined (TARGET_MIPS64)
13975            case RR_RY_CNVT_ZEW:
13976                check_insn(ctx, ISA_MIPS64);
13977                check_mips_64(ctx);
13978                tcg_gen_ext32u_tl(cpu_gpr[rx], cpu_gpr[rx]);
13979                break;
13980            case RR_RY_CNVT_SEW:
13981                check_insn(ctx, ISA_MIPS64);
13982                check_mips_64(ctx);
13983                tcg_gen_ext32s_tl(cpu_gpr[rx], cpu_gpr[rx]);
13984                break;
13985#endif
13986            default:
13987                generate_exception_end(ctx, EXCP_RI);
13988                break;
13989            }
13990            break;
13991        case RR_MFLO:
13992            gen_HILO(ctx, OPC_MFLO, 0, rx);
13993            break;
13994#if defined (TARGET_MIPS64)
13995        case RR_DSRA:
13996            check_insn(ctx, ISA_MIPS3);
13997            check_mips_64(ctx);
13998            gen_shift_imm(ctx, OPC_DSRA, ry, ry, sa);
13999            break;
14000        case RR_DSLLV:
14001            check_insn(ctx, ISA_MIPS3);
14002            check_mips_64(ctx);
14003            gen_shift(ctx, OPC_DSLLV, ry, rx, ry);
14004            break;
14005        case RR_DSRLV:
14006            check_insn(ctx, ISA_MIPS3);
14007            check_mips_64(ctx);
14008            gen_shift(ctx, OPC_DSRLV, ry, rx, ry);
14009            break;
14010        case RR_DSRAV:
14011            check_insn(ctx, ISA_MIPS3);
14012            check_mips_64(ctx);
14013            gen_shift(ctx, OPC_DSRAV, ry, rx, ry);
14014            break;
14015#endif
14016        case RR_MULT:
14017            gen_muldiv(ctx, OPC_MULT, 0, rx, ry);
14018            break;
14019        case RR_MULTU:
14020            gen_muldiv(ctx, OPC_MULTU, 0, rx, ry);
14021            break;
14022        case RR_DIV:
14023            gen_muldiv(ctx, OPC_DIV, 0, rx, ry);
14024            break;
14025        case RR_DIVU:
14026            gen_muldiv(ctx, OPC_DIVU, 0, rx, ry);
14027            break;
14028#if defined (TARGET_MIPS64)
14029        case RR_DMULT:
14030            check_insn(ctx, ISA_MIPS3);
14031            check_mips_64(ctx);
14032            gen_muldiv(ctx, OPC_DMULT, 0, rx, ry);
14033            break;
14034        case RR_DMULTU:
14035            check_insn(ctx, ISA_MIPS3);
14036            check_mips_64(ctx);
14037            gen_muldiv(ctx, OPC_DMULTU, 0, rx, ry);
14038            break;
14039        case RR_DDIV:
14040            check_insn(ctx, ISA_MIPS3);
14041            check_mips_64(ctx);
14042            gen_muldiv(ctx, OPC_DDIV, 0, rx, ry);
14043            break;
14044        case RR_DDIVU:
14045            check_insn(ctx, ISA_MIPS3);
14046            check_mips_64(ctx);
14047            gen_muldiv(ctx, OPC_DDIVU, 0, rx, ry);
14048            break;
14049#endif
14050        default:
14051            generate_exception_end(ctx, EXCP_RI);
14052            break;
14053        }
14054        break;
14055    case M16_OPC_EXTEND:
14056        decode_extended_mips16_opc(env, ctx);
14057        n_bytes = 4;
14058        break;
14059#if defined(TARGET_MIPS64)
14060    case M16_OPC_I64:
14061        funct = (ctx->opcode >> 8) & 0x7;
14062        decode_i64_mips16(ctx, ry, funct, offset, 0);
14063        break;
14064#endif
14065    default:
14066        generate_exception_end(ctx, EXCP_RI);
14067        break;
14068    }
14069
14070    return n_bytes;
14071}
14072
14073/* microMIPS extension to MIPS32/MIPS64 */
14074
14075/*
14076 * microMIPS32/microMIPS64 major opcodes
14077 *
14078 * 1. MIPS Architecture for Programmers Volume II-B:
14079 *      The microMIPS32 Instruction Set (Revision 3.05)
14080 *
14081 *    Table 6.2 microMIPS32 Encoding of Major Opcode Field
14082 *
14083 * 2. MIPS Architecture For Programmers Volume II-A:
14084 *      The MIPS64 Instruction Set (Revision 3.51)
14085 */
14086
14087enum {
14088    POOL32A = 0x00,
14089    POOL16A = 0x01,
14090    LBU16 = 0x02,
14091    MOVE16 = 0x03,
14092    ADDI32 = 0x04,
14093    R6_LUI = 0x04,
14094    AUI = 0x04,
14095    LBU32 = 0x05,
14096    SB32 = 0x06,
14097    LB32 = 0x07,
14098
14099    POOL32B = 0x08,
14100    POOL16B = 0x09,
14101    LHU16 = 0x0a,
14102    ANDI16 = 0x0b,
14103    ADDIU32 = 0x0c,
14104    LHU32 = 0x0d,
14105    SH32 = 0x0e,
14106    LH32 = 0x0f,
14107
14108    POOL32I = 0x10,
14109    POOL16C = 0x11,
14110    LWSP16 = 0x12,
14111    POOL16D = 0x13,
14112    ORI32 = 0x14,
14113    POOL32F = 0x15,
14114    POOL32S = 0x16,  /* MIPS64 */
14115    DADDIU32 = 0x17, /* MIPS64 */
14116
14117    POOL32C = 0x18,
14118    LWGP16 = 0x19,
14119    LW16 = 0x1a,
14120    POOL16E = 0x1b,
14121    XORI32 = 0x1c,
14122    JALS32 = 0x1d,
14123    BOVC = 0x1d,
14124    BEQC = 0x1d,
14125    BEQZALC = 0x1d,
14126    ADDIUPC = 0x1e,
14127    PCREL = 0x1e,
14128    BNVC = 0x1f,
14129    BNEC = 0x1f,
14130    BNEZALC = 0x1f,
14131
14132    R6_BEQZC = 0x20,
14133    JIC = 0x20,
14134    POOL16F = 0x21,
14135    SB16 = 0x22,
14136    BEQZ16 = 0x23,
14137    BEQZC16 = 0x23,
14138    SLTI32 = 0x24,
14139    BEQ32 = 0x25,
14140    BC = 0x25,
14141    SWC132 = 0x26,
14142    LWC132 = 0x27,
14143
14144    /* 0x29 is reserved */
14145    RES_29 = 0x29,
14146    R6_BNEZC = 0x28,
14147    JIALC = 0x28,
14148    SH16 = 0x2a,
14149    BNEZ16 = 0x2b,
14150    BNEZC16 = 0x2b,
14151    SLTIU32 = 0x2c,
14152    BNE32 = 0x2d,
14153    BALC = 0x2d,
14154    SDC132 = 0x2e,
14155    LDC132 = 0x2f,
14156
14157    /* 0x31 is reserved */
14158    RES_31 = 0x31,
14159    BLEZALC = 0x30,
14160    BGEZALC = 0x30,
14161    BGEUC = 0x30,
14162    SWSP16 = 0x32,
14163    B16 = 0x33,
14164    BC16 = 0x33,
14165    ANDI32 = 0x34,
14166    J32 = 0x35,
14167    BGTZC = 0x35,
14168    BLTZC = 0x35,
14169    BLTC = 0x35,
14170    SD32 = 0x36, /* MIPS64 */
14171    LD32 = 0x37, /* MIPS64 */
14172
14173    /* 0x39 is reserved */
14174    RES_39 = 0x39,
14175    BGTZALC = 0x38,
14176    BLTZALC = 0x38,
14177    BLTUC = 0x38,
14178    SW16 = 0x3a,
14179    LI16 = 0x3b,
14180    JALX32 = 0x3c,
14181    JAL32 = 0x3d,
14182    BLEZC = 0x3d,
14183    BGEZC = 0x3d,
14184    BGEC = 0x3d,
14185    SW32 = 0x3e,
14186    LW32 = 0x3f
14187};
14188
14189/* PCREL Instructions perform PC-Relative address calculation. bits 20..16 */
14190enum {
14191    ADDIUPC_00 = 0x00,
14192    ADDIUPC_01 = 0x01,
14193    ADDIUPC_02 = 0x02,
14194    ADDIUPC_03 = 0x03,
14195    ADDIUPC_04 = 0x04,
14196    ADDIUPC_05 = 0x05,
14197    ADDIUPC_06 = 0x06,
14198    ADDIUPC_07 = 0x07,
14199    AUIPC = 0x1e,
14200    ALUIPC = 0x1f,
14201    LWPC_08 = 0x08,
14202    LWPC_09 = 0x09,
14203    LWPC_0A = 0x0A,
14204    LWPC_0B = 0x0B,
14205    LWPC_0C = 0x0C,
14206    LWPC_0D = 0x0D,
14207    LWPC_0E = 0x0E,
14208    LWPC_0F = 0x0F,
14209};
14210
14211/* POOL32A encoding of minor opcode field */
14212
14213enum {
14214    /* These opcodes are distinguished only by bits 9..6; those bits are
14215     * what are recorded below. */
14216    SLL32 = 0x0,
14217    SRL32 = 0x1,
14218    SRA = 0x2,
14219    ROTR = 0x3,
14220    SELEQZ = 0x5,
14221    SELNEZ = 0x6,
14222    R6_RDHWR = 0x7,
14223
14224    SLLV = 0x0,
14225    SRLV = 0x1,
14226    SRAV = 0x2,
14227    ROTRV = 0x3,
14228    ADD = 0x4,
14229    ADDU32 = 0x5,
14230    SUB = 0x6,
14231    SUBU32 = 0x7,
14232    MUL = 0x8,
14233    AND = 0x9,
14234    OR32 = 0xa,
14235    NOR = 0xb,
14236    XOR32 = 0xc,
14237    SLT = 0xd,
14238    SLTU = 0xe,
14239
14240    MOVN = 0x0,
14241    R6_MUL  = 0x0,
14242    MOVZ = 0x1,
14243    MUH  = 0x1,
14244    MULU = 0x2,
14245    MUHU = 0x3,
14246    LWXS = 0x4,
14247    R6_DIV  = 0x4,
14248    MOD  = 0x5,
14249    R6_DIVU = 0x6,
14250    MODU = 0x7,
14251
14252    /* The following can be distinguished by their lower 6 bits. */
14253    BREAK32 = 0x07,
14254    INS = 0x0c,
14255    LSA = 0x0f,
14256    ALIGN = 0x1f,
14257    EXT = 0x2c,
14258    POOL32AXF = 0x3c,
14259    SIGRIE = 0x3f
14260};
14261
14262/* POOL32AXF encoding of minor opcode field extension */
14263
14264/*
14265 * 1. MIPS Architecture for Programmers Volume II-B:
14266 *      The microMIPS32 Instruction Set (Revision 3.05)
14267 *
14268 *    Table 6.5 POOL32Axf Encoding of Minor Opcode Extension Field
14269 *
14270 * 2. MIPS Architecture for Programmers VolumeIV-e:
14271 *      The MIPS DSP Application-Specific Extension
14272 *        to the microMIPS32 Architecture (Revision 2.34)
14273 *
14274 *    Table 5.5 POOL32Axf Encoding of Minor Opcode Extension Field
14275 */
14276
14277enum {
14278    /* bits 11..6 */
14279    TEQ = 0x00,
14280    TGE = 0x08,
14281    TGEU = 0x10,
14282    TLT = 0x20,
14283    TLTU = 0x28,
14284    TNE = 0x30,
14285
14286    MFC0 = 0x03,
14287    MTC0 = 0x0b,
14288
14289    /* begin of microMIPS32 DSP */
14290
14291    /* bits 13..12 for 0x01 */
14292    MFHI_ACC = 0x0,
14293    MFLO_ACC = 0x1,
14294    MTHI_ACC = 0x2,
14295    MTLO_ACC = 0x3,
14296
14297    /* bits 13..12 for 0x2a */
14298    MADD_ACC = 0x0,
14299    MADDU_ACC = 0x1,
14300    MSUB_ACC = 0x2,
14301    MSUBU_ACC = 0x3,
14302
14303    /* bits 13..12 for 0x32 */
14304    MULT_ACC = 0x0,
14305    MULTU_ACC = 0x1,
14306
14307    /* end of microMIPS32 DSP */
14308
14309    /* bits 15..12 for 0x2c */
14310    BITSWAP = 0x0,
14311    SEB = 0x2,
14312    SEH = 0x3,
14313    CLO = 0x4,
14314    CLZ = 0x5,
14315    RDHWR = 0x6,
14316    WSBH = 0x7,
14317    MULT = 0x8,
14318    MULTU = 0x9,
14319    DIV = 0xa,
14320    DIVU = 0xb,
14321    MADD = 0xc,
14322    MADDU = 0xd,
14323    MSUB = 0xe,
14324    MSUBU = 0xf,
14325
14326    /* bits 15..12 for 0x34 */
14327    MFC2 = 0x4,
14328    MTC2 = 0x5,
14329    MFHC2 = 0x8,
14330    MTHC2 = 0x9,
14331    CFC2 = 0xc,
14332    CTC2 = 0xd,
14333
14334    /* bits 15..12 for 0x3c */
14335    JALR = 0x0,
14336    JR = 0x0,                   /* alias */
14337    JALRC = 0x0,
14338    JRC = 0x0,
14339    JALR_HB = 0x1,
14340    JALRC_HB = 0x1,
14341    JALRS = 0x4,
14342    JALRS_HB = 0x5,
14343
14344    /* bits 15..12 for 0x05 */
14345    RDPGPR = 0xe,
14346    WRPGPR = 0xf,
14347
14348    /* bits 15..12 for 0x0d */
14349    TLBP = 0x0,
14350    TLBR = 0x1,
14351    TLBWI = 0x2,
14352    TLBWR = 0x3,
14353    TLBINV = 0x4,
14354    TLBINVF = 0x5,
14355    WAIT = 0x9,
14356    IRET = 0xd,
14357    DERET = 0xe,
14358    ERET = 0xf,
14359
14360    /* bits 15..12 for 0x15 */
14361    DMT = 0x0,
14362    DVPE = 0x1,
14363    EMT = 0x2,
14364    EVPE = 0x3,
14365
14366    /* bits 15..12 for 0x1d */
14367    DI = 0x4,
14368    EI = 0x5,
14369
14370    /* bits 15..12 for 0x2d */
14371    SYNC = 0x6,
14372    SYSCALL = 0x8,
14373    SDBBP = 0xd,
14374
14375    /* bits 15..12 for 0x35 */
14376    MFHI32 = 0x0,
14377    MFLO32 = 0x1,
14378    MTHI32 = 0x2,
14379    MTLO32 = 0x3,
14380};
14381
14382/* POOL32B encoding of minor opcode field (bits 15..12) */
14383
14384enum {
14385    LWC2 = 0x0,
14386    LWP = 0x1,
14387    LDP = 0x4,
14388    LWM32 = 0x5,
14389    CACHE = 0x6,
14390    LDM = 0x7,
14391    SWC2 = 0x8,
14392    SWP = 0x9,
14393    SDP = 0xc,
14394    SWM32 = 0xd,
14395    SDM = 0xf
14396};
14397
14398/* POOL32C encoding of minor opcode field (bits 15..12) */
14399
14400enum {
14401    LWL = 0x0,
14402    SWL = 0x8,
14403    LWR = 0x1,
14404    SWR = 0x9,
14405    PREF = 0x2,
14406    ST_EVA = 0xa,
14407    LL = 0x3,
14408    SC = 0xb,
14409    LDL = 0x4,
14410    SDL = 0xc,
14411    LDR = 0x5,
14412    SDR = 0xd,
14413    LD_EVA = 0x6,
14414    LWU = 0xe,
14415    LLD = 0x7,
14416    SCD = 0xf
14417};
14418
14419/* POOL32C LD-EVA encoding of minor opcode field (bits 11..9) */
14420
14421enum {
14422    LBUE = 0x0,
14423    LHUE = 0x1,
14424    LWLE = 0x2,
14425    LWRE = 0x3,
14426    LBE = 0x4,
14427    LHE = 0x5,
14428    LLE = 0x6,
14429    LWE = 0x7,
14430};
14431
14432/* POOL32C ST-EVA encoding of minor opcode field (bits 11..9) */
14433
14434enum {
14435    SWLE = 0x0,
14436    SWRE = 0x1,
14437    PREFE = 0x2,
14438    CACHEE = 0x3,
14439    SBE = 0x4,
14440    SHE = 0x5,
14441    SCE = 0x6,
14442    SWE = 0x7,
14443};
14444
14445/* POOL32F encoding of minor opcode field (bits 5..0) */
14446
14447enum {
14448    /* These are the bit 7..6 values */
14449    ADD_FMT = 0x0,
14450
14451    SUB_FMT = 0x1,
14452
14453    MUL_FMT = 0x2,
14454
14455    DIV_FMT = 0x3,
14456
14457    /* These are the bit 8..6 values */
14458    MOVN_FMT = 0x0,
14459    RSQRT2_FMT = 0x0,
14460    MOVF_FMT = 0x0,
14461    RINT_FMT = 0x0,
14462    SELNEZ_FMT = 0x0,
14463
14464    MOVZ_FMT = 0x1,
14465    LWXC1 = 0x1,
14466    MOVT_FMT = 0x1,
14467    CLASS_FMT = 0x1,
14468    SELEQZ_FMT = 0x1,
14469
14470    PLL_PS = 0x2,
14471    SWXC1 = 0x2,
14472    SEL_FMT = 0x2,
14473
14474    PLU_PS = 0x3,
14475    LDXC1 = 0x3,
14476
14477    MOVN_FMT_04 = 0x4,
14478    PUL_PS = 0x4,
14479    SDXC1 = 0x4,
14480    RECIP2_FMT = 0x4,
14481
14482    MOVZ_FMT_05 = 0x05,
14483    PUU_PS = 0x5,
14484    LUXC1 = 0x5,
14485
14486    CVT_PS_S = 0x6,
14487    SUXC1 = 0x6,
14488    ADDR_PS = 0x6,
14489    PREFX = 0x6,
14490    MADDF_FMT = 0x6,
14491
14492    MULR_PS = 0x7,
14493    MSUBF_FMT = 0x7,
14494
14495    MADD_S = 0x01,
14496    MADD_D = 0x09,
14497    MADD_PS = 0x11,
14498    ALNV_PS = 0x19,
14499    MSUB_S = 0x21,
14500    MSUB_D = 0x29,
14501    MSUB_PS = 0x31,
14502
14503    NMADD_S = 0x02,
14504    NMADD_D = 0x0a,
14505    NMADD_PS = 0x12,
14506    NMSUB_S = 0x22,
14507    NMSUB_D = 0x2a,
14508    NMSUB_PS = 0x32,
14509
14510    MIN_FMT = 0x3,
14511    MAX_FMT = 0xb,
14512    MINA_FMT = 0x23,
14513    MAXA_FMT = 0x2b,
14514    POOL32FXF = 0x3b,
14515
14516    CABS_COND_FMT = 0x1c,              /* MIPS3D */
14517    C_COND_FMT = 0x3c,
14518
14519    CMP_CONDN_S = 0x5,
14520    CMP_CONDN_D = 0x15
14521};
14522
14523/* POOL32Fxf encoding of minor opcode extension field */
14524
14525enum {
14526    CVT_L = 0x04,
14527    RSQRT_FMT = 0x08,
14528    FLOOR_L = 0x0c,
14529    CVT_PW_PS = 0x1c,
14530    CVT_W = 0x24,
14531    SQRT_FMT = 0x28,
14532    FLOOR_W = 0x2c,
14533    CVT_PS_PW = 0x3c,
14534    CFC1 = 0x40,
14535    RECIP_FMT = 0x48,
14536    CEIL_L = 0x4c,
14537    CTC1 = 0x60,
14538    CEIL_W = 0x6c,
14539    MFC1 = 0x80,
14540    CVT_S_PL = 0x84,
14541    TRUNC_L = 0x8c,
14542    MTC1 = 0xa0,
14543    CVT_S_PU = 0xa4,
14544    TRUNC_W = 0xac,
14545    MFHC1 = 0xc0,
14546    ROUND_L = 0xcc,
14547    MTHC1 = 0xe0,
14548    ROUND_W = 0xec,
14549
14550    MOV_FMT = 0x01,
14551    MOVF = 0x05,
14552    ABS_FMT = 0x0d,
14553    RSQRT1_FMT = 0x1d,
14554    MOVT = 0x25,
14555    NEG_FMT = 0x2d,
14556    CVT_D = 0x4d,
14557    RECIP1_FMT = 0x5d,
14558    CVT_S = 0x6d
14559};
14560
14561/* POOL32I encoding of minor opcode field (bits 25..21) */
14562
14563enum {
14564    BLTZ = 0x00,
14565    BLTZAL = 0x01,
14566    BGEZ = 0x02,
14567    BGEZAL = 0x03,
14568    BLEZ = 0x04,
14569    BNEZC = 0x05,
14570    BGTZ = 0x06,
14571    BEQZC = 0x07,
14572    TLTI = 0x08,
14573    BC1EQZC = 0x08,
14574    TGEI = 0x09,
14575    BC1NEZC = 0x09,
14576    TLTIU = 0x0a,
14577    BC2EQZC = 0x0a,
14578    TGEIU = 0x0b,
14579    BC2NEZC = 0x0a,
14580    TNEI = 0x0c,
14581    R6_SYNCI = 0x0c,
14582    LUI = 0x0d,
14583    TEQI = 0x0e,
14584    SYNCI = 0x10,
14585    BLTZALS = 0x11,
14586    BGEZALS = 0x13,
14587    BC2F = 0x14,
14588    BC2T = 0x15,
14589    BPOSGE64 = 0x1a,
14590    BPOSGE32 = 0x1b,
14591    /* These overlap and are distinguished by bit16 of the instruction */
14592    BC1F = 0x1c,
14593    BC1T = 0x1d,
14594    BC1ANY2F = 0x1c,
14595    BC1ANY2T = 0x1d,
14596    BC1ANY4F = 0x1e,
14597    BC1ANY4T = 0x1f
14598};
14599
14600/* POOL16A encoding of minor opcode field */
14601
14602enum {
14603    ADDU16 = 0x0,
14604    SUBU16 = 0x1
14605};
14606
14607/* POOL16B encoding of minor opcode field */
14608
14609enum {
14610    SLL16 = 0x0,
14611    SRL16 = 0x1
14612};
14613
14614/* POOL16C encoding of minor opcode field */
14615
14616enum {
14617    NOT16 = 0x00,
14618    XOR16 = 0x04,
14619    AND16 = 0x08,
14620    OR16 = 0x0c,
14621    LWM16 = 0x10,
14622    SWM16 = 0x14,
14623    JR16 = 0x18,
14624    JRC16 = 0x1a,
14625    JALR16 = 0x1c,
14626    JALR16S = 0x1e,
14627    MFHI16 = 0x20,
14628    MFLO16 = 0x24,
14629    BREAK16 = 0x28,
14630    SDBBP16 = 0x2c,
14631    JRADDIUSP = 0x30
14632};
14633
14634/* R6 POOL16C encoding of minor opcode field (bits 0..5) */
14635
14636enum {
14637    R6_NOT16    = 0x00,
14638    R6_AND16    = 0x01,
14639    R6_LWM16    = 0x02,
14640    R6_JRC16    = 0x03,
14641    MOVEP       = 0x04,
14642    MOVEP_05    = 0x05,
14643    MOVEP_06    = 0x06,
14644    MOVEP_07    = 0x07,
14645    R6_XOR16    = 0x08,
14646    R6_OR16     = 0x09,
14647    R6_SWM16    = 0x0a,
14648    JALRC16     = 0x0b,
14649    MOVEP_0C    = 0x0c,
14650    MOVEP_0D    = 0x0d,
14651    MOVEP_0E    = 0x0e,
14652    MOVEP_0F    = 0x0f,
14653    JRCADDIUSP  = 0x13,
14654    R6_BREAK16  = 0x1b,
14655    R6_SDBBP16  = 0x3b
14656};
14657
14658/* POOL16D encoding of minor opcode field */
14659
14660enum {
14661    ADDIUS5 = 0x0,
14662    ADDIUSP = 0x1
14663};
14664
14665/* POOL16E encoding of minor opcode field */
14666
14667enum {
14668    ADDIUR2 = 0x0,
14669    ADDIUR1SP = 0x1
14670};
14671
14672static int mmreg (int r)
14673{
14674    static const int map[] = { 16, 17, 2, 3, 4, 5, 6, 7 };
14675
14676    return map[r];
14677}
14678
14679/* Used for 16-bit store instructions.  */
14680static int mmreg2 (int r)
14681{
14682    static const int map[] = { 0, 17, 2, 3, 4, 5, 6, 7 };
14683
14684    return map[r];
14685}
14686
14687#define uMIPS_RD(op) ((op >> 7) & 0x7)
14688#define uMIPS_RS(op) ((op >> 4) & 0x7)
14689#define uMIPS_RS2(op) uMIPS_RS(op)
14690#define uMIPS_RS1(op) ((op >> 1) & 0x7)
14691#define uMIPS_RD5(op) ((op >> 5) & 0x1f)
14692#define uMIPS_RS5(op) (op & 0x1f)
14693
14694/* Signed immediate */
14695#define SIMM(op, start, width)                                          \
14696    ((int32_t)(((op >> start) & ((~0U) >> (32-width)))                 \
14697               << (32-width))                                           \
14698     >> (32-width))
14699/* Zero-extended immediate */
14700#define ZIMM(op, start, width) ((op >> start) & ((~0U) >> (32-width)))
14701
14702static void gen_addiur1sp(DisasContext *ctx)
14703{
14704    int rd = mmreg(uMIPS_RD(ctx->opcode));
14705
14706    gen_arith_imm(ctx, OPC_ADDIU, rd, 29, ((ctx->opcode >> 1) & 0x3f) << 2);
14707}
14708
14709static void gen_addiur2(DisasContext *ctx)
14710{
14711    static const int decoded_imm[] = { 1, 4, 8, 12, 16, 20, 24, -1 };
14712    int rd = mmreg(uMIPS_RD(ctx->opcode));
14713    int rs = mmreg(uMIPS_RS(ctx->opcode));
14714
14715    gen_arith_imm(ctx, OPC_ADDIU, rd, rs, decoded_imm[ZIMM(ctx->opcode, 1, 3)]);
14716}
14717
14718static void gen_addiusp(DisasContext *ctx)
14719{
14720    int encoded = ZIMM(ctx->opcode, 1, 9);
14721    int decoded;
14722
14723    if (encoded <= 1) {
14724        decoded = 256 + encoded;
14725    } else if (encoded <= 255) {
14726        decoded = encoded;
14727    } else if (encoded <= 509) {
14728        decoded = encoded - 512;
14729    } else {
14730        decoded = encoded - 768;
14731    }
14732
14733    gen_arith_imm(ctx, OPC_ADDIU, 29, 29, decoded << 2);
14734}
14735
14736static void gen_addius5(DisasContext *ctx)
14737{
14738    int imm = SIMM(ctx->opcode, 1, 4);
14739    int rd = (ctx->opcode >> 5) & 0x1f;
14740
14741    gen_arith_imm(ctx, OPC_ADDIU, rd, rd, imm);
14742}
14743
14744static void gen_andi16(DisasContext *ctx)
14745{
14746    static const int decoded_imm[] = { 128, 1, 2, 3, 4, 7, 8, 15, 16,
14747                                 31, 32, 63, 64, 255, 32768, 65535 };
14748    int rd = mmreg(uMIPS_RD(ctx->opcode));
14749    int rs = mmreg(uMIPS_RS(ctx->opcode));
14750    int encoded = ZIMM(ctx->opcode, 0, 4);
14751
14752    gen_logic_imm(ctx, OPC_ANDI, rd, rs, decoded_imm[encoded]);
14753}
14754
14755static void gen_ldst_multiple (DisasContext *ctx, uint32_t opc, int reglist,
14756                               int base, int16_t offset)
14757{
14758    TCGv t0, t1;
14759    TCGv_i32 t2;
14760
14761    if (ctx->hflags & MIPS_HFLAG_BMASK) {
14762        generate_exception_end(ctx, EXCP_RI);
14763        return;
14764    }
14765
14766    t0 = tcg_temp_new();
14767
14768    gen_base_offset_addr(ctx, t0, base, offset);
14769
14770    t1 = tcg_const_tl(reglist);
14771    t2 = tcg_const_i32(ctx->mem_idx);
14772
14773    save_cpu_state(ctx, 1);
14774    switch (opc) {
14775    case LWM32:
14776        gen_helper_lwm(cpu_env, t0, t1, t2);
14777        break;
14778    case SWM32:
14779        gen_helper_swm(cpu_env, t0, t1, t2);
14780        break;
14781#ifdef TARGET_MIPS64
14782    case LDM:
14783        gen_helper_ldm(cpu_env, t0, t1, t2);
14784        break;
14785    case SDM:
14786        gen_helper_sdm(cpu_env, t0, t1, t2);
14787        break;
14788#endif
14789    }
14790    tcg_temp_free(t0);
14791    tcg_temp_free(t1);
14792    tcg_temp_free_i32(t2);
14793}
14794
14795
14796static void gen_pool16c_insn(DisasContext *ctx)
14797{
14798    int rd = mmreg((ctx->opcode >> 3) & 0x7);
14799    int rs = mmreg(ctx->opcode & 0x7);
14800
14801    switch (((ctx->opcode) >> 4) & 0x3f) {
14802    case NOT16 + 0:
14803    case NOT16 + 1:
14804    case NOT16 + 2:
14805    case NOT16 + 3:
14806        gen_logic(ctx, OPC_NOR, rd, rs, 0);
14807        break;
14808    case XOR16 + 0:
14809    case XOR16 + 1:
14810    case XOR16 + 2:
14811    case XOR16 + 3:
14812        gen_logic(ctx, OPC_XOR, rd, rd, rs);
14813        break;
14814    case AND16 + 0:
14815    case AND16 + 1:
14816    case AND16 + 2:
14817    case AND16 + 3:
14818        gen_logic(ctx, OPC_AND, rd, rd, rs);
14819        break;
14820    case OR16 + 0:
14821    case OR16 + 1:
14822    case OR16 + 2:
14823    case OR16 + 3:
14824        gen_logic(ctx, OPC_OR, rd, rd, rs);
14825        break;
14826    case LWM16 + 0:
14827    case LWM16 + 1:
14828    case LWM16 + 2:
14829    case LWM16 + 3:
14830        {
14831            static const int lwm_convert[] = { 0x11, 0x12, 0x13, 0x14 };
14832            int offset = ZIMM(ctx->opcode, 0, 4);
14833
14834            gen_ldst_multiple(ctx, LWM32, lwm_convert[(ctx->opcode >> 4) & 0x3],
14835                              29, offset << 2);
14836        }
14837        break;
14838    case SWM16 + 0:
14839    case SWM16 + 1:
14840    case SWM16 + 2:
14841    case SWM16 + 3:
14842        {
14843            static const int swm_convert[] = { 0x11, 0x12, 0x13, 0x14 };
14844            int offset = ZIMM(ctx->opcode, 0, 4);
14845
14846            gen_ldst_multiple(ctx, SWM32, swm_convert[(ctx->opcode >> 4) & 0x3],
14847                              29, offset << 2);
14848        }
14849        break;
14850    case JR16 + 0:
14851    case JR16 + 1:
14852        {
14853            int reg = ctx->opcode & 0x1f;
14854
14855            gen_compute_branch(ctx, OPC_JR, 2, reg, 0, 0, 4);
14856        }
14857        break;
14858    case JRC16 + 0:
14859    case JRC16 + 1:
14860        {
14861            int reg = ctx->opcode & 0x1f;
14862            gen_compute_branch(ctx, OPC_JR, 2, reg, 0, 0, 0);
14863            /* Let normal delay slot handling in our caller take us
14864               to the branch target.  */
14865        }
14866        break;
14867    case JALR16 + 0:
14868    case JALR16 + 1:
14869        gen_compute_branch(ctx, OPC_JALR, 2, ctx->opcode & 0x1f, 31, 0, 4);
14870        ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
14871        break;
14872    case JALR16S + 0:
14873    case JALR16S + 1:
14874        gen_compute_branch(ctx, OPC_JALR, 2, ctx->opcode & 0x1f, 31, 0, 2);
14875        ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
14876        break;
14877    case MFHI16 + 0:
14878    case MFHI16 + 1:
14879        gen_HILO(ctx, OPC_MFHI, 0, uMIPS_RS5(ctx->opcode));
14880        break;
14881    case MFLO16 + 0:
14882    case MFLO16 + 1:
14883        gen_HILO(ctx, OPC_MFLO, 0, uMIPS_RS5(ctx->opcode));
14884        break;
14885    case BREAK16:
14886        generate_exception_end(ctx, EXCP_BREAK);
14887        break;
14888    case SDBBP16:
14889        if (is_uhi(extract32(ctx->opcode, 0, 4))) {
14890            gen_helper_do_semihosting(cpu_env);
14891        } else {
14892            /* XXX: not clear which exception should be raised
14893             *      when in debug mode...
14894             */
14895            check_insn(ctx, ISA_MIPS32);
14896            generate_exception_end(ctx, EXCP_DBp);
14897        }
14898        break;
14899    case JRADDIUSP + 0:
14900    case JRADDIUSP + 1:
14901        {
14902            int imm = ZIMM(ctx->opcode, 0, 5);
14903            gen_compute_branch(ctx, OPC_JR, 2, 31, 0, 0, 0);
14904            gen_arith_imm(ctx, OPC_ADDIU, 29, 29, imm << 2);
14905            /* Let normal delay slot handling in our caller take us
14906               to the branch target.  */
14907        }
14908        break;
14909    default:
14910        generate_exception_end(ctx, EXCP_RI);
14911        break;
14912    }
14913}
14914
14915static inline void gen_movep(DisasContext *ctx, int enc_dest, int enc_rt,
14916                             int enc_rs)
14917{
14918    int rd, rs, re, rt;
14919    static const int rd_enc[] = { 5, 5, 6, 4, 4, 4, 4, 4 };
14920    static const int re_enc[] = { 6, 7, 7, 21, 22, 5, 6, 7 };
14921    static const int rs_rt_enc[] = { 0, 17, 2, 3, 16, 18, 19, 20 };
14922    rd = rd_enc[enc_dest];
14923    re = re_enc[enc_dest];
14924    rs = rs_rt_enc[enc_rs];
14925    rt = rs_rt_enc[enc_rt];
14926    if (rs) {
14927        tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
14928    } else {
14929        tcg_gen_movi_tl(cpu_gpr[rd], 0);
14930    }
14931    if (rt) {
14932        tcg_gen_mov_tl(cpu_gpr[re], cpu_gpr[rt]);
14933    } else {
14934        tcg_gen_movi_tl(cpu_gpr[re], 0);
14935    }
14936}
14937
14938static void gen_pool16c_r6_insn(DisasContext *ctx)
14939{
14940    int rt = mmreg((ctx->opcode >> 7) & 0x7);
14941    int rs = mmreg((ctx->opcode >> 4) & 0x7);
14942
14943    switch (ctx->opcode & 0xf) {
14944    case R6_NOT16:
14945        gen_logic(ctx, OPC_NOR, rt, rs, 0);
14946        break;
14947    case R6_AND16:
14948        gen_logic(ctx, OPC_AND, rt, rt, rs);
14949        break;
14950    case R6_LWM16:
14951        {
14952            int lwm_converted = 0x11 + extract32(ctx->opcode, 8, 2);
14953            int offset = extract32(ctx->opcode, 4, 4);
14954            gen_ldst_multiple(ctx, LWM32, lwm_converted, 29, offset << 2);
14955        }
14956        break;
14957    case R6_JRC16: /* JRCADDIUSP */
14958        if ((ctx->opcode >> 4) & 1) {
14959            /* JRCADDIUSP */
14960            int imm = extract32(ctx->opcode, 5, 5);
14961            gen_compute_branch(ctx, OPC_JR, 2, 31, 0, 0, 0);
14962            gen_arith_imm(ctx, OPC_ADDIU, 29, 29, imm << 2);
14963        } else {
14964            /* JRC16 */
14965            rs = extract32(ctx->opcode, 5, 5);
14966            gen_compute_branch(ctx, OPC_JR, 2, rs, 0, 0, 0);
14967        }
14968        break;
14969    case MOVEP:
14970    case MOVEP_05:
14971    case MOVEP_06:
14972    case MOVEP_07:
14973    case MOVEP_0C:
14974    case MOVEP_0D:
14975    case MOVEP_0E:
14976    case MOVEP_0F:
14977        {
14978            int enc_dest = uMIPS_RD(ctx->opcode);
14979            int enc_rt = uMIPS_RS2(ctx->opcode);
14980            int enc_rs = (ctx->opcode & 3) | ((ctx->opcode >> 1) & 4);
14981            gen_movep(ctx, enc_dest, enc_rt, enc_rs);
14982        }
14983        break;
14984    case R6_XOR16:
14985        gen_logic(ctx, OPC_XOR, rt, rt, rs);
14986        break;
14987    case R6_OR16:
14988        gen_logic(ctx, OPC_OR, rt, rt, rs);
14989        break;
14990    case R6_SWM16:
14991        {
14992            int swm_converted = 0x11 + extract32(ctx->opcode, 8, 2);
14993            int offset = extract32(ctx->opcode, 4, 4);
14994            gen_ldst_multiple(ctx, SWM32, swm_converted, 29, offset << 2);
14995        }
14996        break;
14997    case JALRC16: /* BREAK16, SDBBP16 */
14998        switch (ctx->opcode & 0x3f) {
14999        case JALRC16:
15000        case JALRC16 + 0x20:
15001            /* JALRC16 */
15002            gen_compute_branch(ctx, OPC_JALR, 2, (ctx->opcode >> 5) & 0x1f,
15003                               31, 0, 0);
15004            break;
15005        case R6_BREAK16:
15006            /* BREAK16 */
15007            generate_exception(ctx, EXCP_BREAK);
15008            break;
15009        case R6_SDBBP16:
15010            /* SDBBP16 */
15011            if (is_uhi(extract32(ctx->opcode, 6, 4))) {
15012                gen_helper_do_semihosting(cpu_env);
15013            } else {
15014                if (ctx->hflags & MIPS_HFLAG_SBRI) {
15015                    generate_exception(ctx, EXCP_RI);
15016                } else {
15017                    generate_exception(ctx, EXCP_DBp);
15018                }
15019            }
15020            break;
15021        }
15022        break;
15023    default:
15024        generate_exception(ctx, EXCP_RI);
15025        break;
15026    }
15027}
15028
15029static void gen_ldxs (DisasContext *ctx, int base, int index, int rd)
15030{
15031    TCGv t0 = tcg_temp_new();
15032    TCGv t1 = tcg_temp_new();
15033
15034    gen_load_gpr(t0, base);
15035
15036    if (index != 0) {
15037        gen_load_gpr(t1, index);
15038        tcg_gen_shli_tl(t1, t1, 2);
15039        gen_op_addr_add(ctx, t0, t1, t0);
15040    }
15041
15042    tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TESL);
15043    gen_store_gpr(t1, rd);
15044
15045    tcg_temp_free(t0);
15046    tcg_temp_free(t1);
15047}
15048
15049static void gen_ldst_pair (DisasContext *ctx, uint32_t opc, int rd,
15050                           int base, int16_t offset)
15051{
15052    TCGv t0, t1;
15053
15054    if (ctx->hflags & MIPS_HFLAG_BMASK || rd == 31) {
15055        generate_exception_end(ctx, EXCP_RI);
15056        return;
15057    }
15058
15059    t0 = tcg_temp_new();
15060    t1 = tcg_temp_new();
15061
15062    gen_base_offset_addr(ctx, t0, base, offset);
15063
15064    switch (opc) {
15065    case LWP:
15066        if (rd == base) {
15067            generate_exception_end(ctx, EXCP_RI);
15068            return;
15069        }
15070        tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TESL);
15071        gen_store_gpr(t1, rd);
15072        tcg_gen_movi_tl(t1, 4);
15073        gen_op_addr_add(ctx, t0, t0, t1);
15074        tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TESL);
15075        gen_store_gpr(t1, rd+1);
15076        break;
15077    case SWP:
15078        gen_load_gpr(t1, rd);
15079        tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL);
15080        tcg_gen_movi_tl(t1, 4);
15081        gen_op_addr_add(ctx, t0, t0, t1);
15082        gen_load_gpr(t1, rd+1);
15083        tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL);
15084        break;
15085#ifdef TARGET_MIPS64
15086    case LDP:
15087        if (rd == base) {
15088            generate_exception_end(ctx, EXCP_RI);
15089            return;
15090        }
15091        tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TEQ);
15092        gen_store_gpr(t1, rd);
15093        tcg_gen_movi_tl(t1, 8);
15094        gen_op_addr_add(ctx, t0, t0, t1);
15095        tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TEQ);
15096        gen_store_gpr(t1, rd+1);
15097        break;
15098    case SDP:
15099        gen_load_gpr(t1, rd);
15100        tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEQ);
15101        tcg_gen_movi_tl(t1, 8);
15102        gen_op_addr_add(ctx, t0, t0, t1);
15103        gen_load_gpr(t1, rd+1);
15104        tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEQ);
15105        break;
15106#endif
15107    }
15108    tcg_temp_free(t0);
15109    tcg_temp_free(t1);
15110}
15111
15112static void gen_sync(int stype)
15113{
15114    TCGBar tcg_mo = TCG_BAR_SC;
15115
15116    switch (stype) {
15117    case 0x4: /* SYNC_WMB */
15118        tcg_mo |= TCG_MO_ST_ST;
15119        break;
15120    case 0x10: /* SYNC_MB */
15121        tcg_mo |= TCG_MO_ALL;
15122        break;
15123    case 0x11: /* SYNC_ACQUIRE */
15124        tcg_mo |= TCG_MO_LD_LD | TCG_MO_LD_ST;
15125        break;
15126    case 0x12: /* SYNC_RELEASE */
15127        tcg_mo |= TCG_MO_ST_ST | TCG_MO_LD_ST;
15128        break;
15129    case 0x13: /* SYNC_RMB */
15130        tcg_mo |= TCG_MO_LD_LD;
15131        break;
15132    default:
15133        tcg_mo |= TCG_MO_ALL;
15134        break;
15135    }
15136
15137    tcg_gen_mb(tcg_mo);
15138}
15139
15140static void gen_pool32axf (CPUMIPSState *env, DisasContext *ctx, int rt, int rs)
15141{
15142    int extension = (ctx->opcode >> 6) & 0x3f;
15143    int minor = (ctx->opcode >> 12) & 0xf;
15144    uint32_t mips32_op;
15145
15146    switch (extension) {
15147    case TEQ:
15148        mips32_op = OPC_TEQ;
15149        goto do_trap;
15150    case TGE:
15151        mips32_op = OPC_TGE;
15152        goto do_trap;
15153    case TGEU:
15154        mips32_op = OPC_TGEU;
15155        goto do_trap;
15156    case TLT:
15157        mips32_op = OPC_TLT;
15158        goto do_trap;
15159    case TLTU:
15160        mips32_op = OPC_TLTU;
15161        goto do_trap;
15162    case TNE:
15163        mips32_op = OPC_TNE;
15164    do_trap:
15165        gen_trap(ctx, mips32_op, rs, rt, -1);
15166        break;
15167#ifndef CONFIG_USER_ONLY
15168    case MFC0:
15169    case MFC0 + 32:
15170        check_cp0_enabled(ctx);
15171        if (rt == 0) {
15172            /* Treat as NOP. */
15173            break;
15174        }
15175        gen_mfc0(ctx, cpu_gpr[rt], rs, (ctx->opcode >> 11) & 0x7);
15176        break;
15177    case MTC0:
15178    case MTC0 + 32:
15179        check_cp0_enabled(ctx);
15180        {
15181            TCGv t0 = tcg_temp_new();
15182
15183            gen_load_gpr(t0, rt);
15184            gen_mtc0(ctx, t0, rs, (ctx->opcode >> 11) & 0x7);
15185            tcg_temp_free(t0);
15186        }
15187        break;
15188#endif
15189    case 0x2a:
15190        switch (minor & 3) {
15191        case MADD_ACC:
15192            gen_muldiv(ctx, OPC_MADD, (ctx->opcode >> 14) & 3, rs, rt);
15193            break;
15194        case MADDU_ACC:
15195            gen_muldiv(ctx, OPC_MADDU, (ctx->opcode >> 14) & 3, rs, rt);
15196            break;
15197        case MSUB_ACC:
15198            gen_muldiv(ctx, OPC_MSUB, (ctx->opcode >> 14) & 3, rs, rt);
15199            break;
15200        case MSUBU_ACC:
15201            gen_muldiv(ctx, OPC_MSUBU, (ctx->opcode >> 14) & 3, rs, rt);
15202            break;
15203        default:
15204            goto pool32axf_invalid;
15205        }
15206        break;
15207    case 0x32:
15208        switch (minor & 3) {
15209        case MULT_ACC:
15210            gen_muldiv(ctx, OPC_MULT, (ctx->opcode >> 14) & 3, rs, rt);
15211            break;
15212        case MULTU_ACC:
15213            gen_muldiv(ctx, OPC_MULTU, (ctx->opcode >> 14) & 3, rs, rt);
15214            break;
15215        default:
15216            goto pool32axf_invalid;
15217        }
15218        break;
15219    case 0x2c:
15220        switch (minor) {
15221        case BITSWAP:
15222            check_insn(ctx, ISA_MIPS32R6);
15223            gen_bitswap(ctx, OPC_BITSWAP, rs, rt);
15224            break;
15225        case SEB:
15226            gen_bshfl(ctx, OPC_SEB, rs, rt);
15227            break;
15228        case SEH:
15229            gen_bshfl(ctx, OPC_SEH, rs, rt);
15230            break;
15231        case CLO:
15232            mips32_op = OPC_CLO;
15233            goto do_cl;
15234        case CLZ:
15235            mips32_op = OPC_CLZ;
15236        do_cl:
15237            check_insn(ctx, ISA_MIPS32);
15238            gen_cl(ctx, mips32_op, rt, rs);
15239            break;
15240        case RDHWR:
15241            check_insn_opc_removed(ctx, ISA_MIPS32R6);
15242            gen_rdhwr(ctx, rt, rs, 0);
15243            break;
15244        case WSBH:
15245            gen_bshfl(ctx, OPC_WSBH, rs, rt);
15246            break;
15247        case MULT:
15248            check_insn_opc_removed(ctx, ISA_MIPS32R6);
15249            mips32_op = OPC_MULT;
15250            goto do_mul;
15251        case MULTU:
15252            check_insn_opc_removed(ctx, ISA_MIPS32R6);
15253            mips32_op = OPC_MULTU;
15254            goto do_mul;
15255        case DIV:
15256            check_insn_opc_removed(ctx, ISA_MIPS32R6);
15257            mips32_op = OPC_DIV;
15258            goto do_div;
15259        case DIVU:
15260            check_insn_opc_removed(ctx, ISA_MIPS32R6);
15261            mips32_op = OPC_DIVU;
15262            goto do_div;
15263        do_div:
15264            check_insn(ctx, ISA_MIPS32);
15265            gen_muldiv(ctx, mips32_op, 0, rs, rt);
15266            break;
15267        case MADD:
15268            check_insn_opc_removed(ctx, ISA_MIPS32R6);
15269            mips32_op = OPC_MADD;
15270            goto do_mul;
15271        case MADDU:
15272            check_insn_opc_removed(ctx, ISA_MIPS32R6);
15273            mips32_op = OPC_MADDU;
15274            goto do_mul;
15275        case MSUB:
15276            check_insn_opc_removed(ctx, ISA_MIPS32R6);
15277            mips32_op = OPC_MSUB;
15278            goto do_mul;
15279        case MSUBU:
15280            check_insn_opc_removed(ctx, ISA_MIPS32R6);
15281            mips32_op = OPC_MSUBU;
15282        do_mul:
15283            check_insn(ctx, ISA_MIPS32);
15284            gen_muldiv(ctx, mips32_op, 0, rs, rt);
15285            break;
15286        default:
15287            goto pool32axf_invalid;
15288        }
15289        break;
15290    case 0x34:
15291        switch (minor) {
15292        case MFC2:
15293        case MTC2:
15294        case MFHC2:
15295        case MTHC2:
15296        case CFC2:
15297        case CTC2:
15298            generate_exception_err(ctx, EXCP_CpU, 2);
15299            break;
15300        default:
15301            goto pool32axf_invalid;
15302        }
15303        break;
15304    case 0x3c:
15305        switch (minor) {
15306        case JALR:    /* JALRC */
15307        case JALR_HB: /* JALRC_HB */
15308            if (ctx->insn_flags & ISA_MIPS32R6) {
15309                /* JALRC, JALRC_HB */
15310                gen_compute_branch(ctx, OPC_JALR, 4, rs, rt, 0, 0);
15311            } else {
15312                /* JALR, JALR_HB */
15313                gen_compute_branch(ctx, OPC_JALR, 4, rs, rt, 0, 4);
15314                ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
15315            }
15316            break;
15317        case JALRS:
15318        case JALRS_HB:
15319            check_insn_opc_removed(ctx, ISA_MIPS32R6);
15320            gen_compute_branch(ctx, OPC_JALR, 4, rs, rt, 0, 2);
15321            ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
15322            break;
15323        default:
15324            goto pool32axf_invalid;
15325        }
15326        break;
15327    case 0x05:
15328        switch (minor) {
15329        case RDPGPR:
15330            check_cp0_enabled(ctx);
15331            check_insn(ctx, ISA_MIPS32R2);
15332            gen_load_srsgpr(rs, rt);
15333            break;
15334        case WRPGPR:
15335            check_cp0_enabled(ctx);
15336            check_insn(ctx, ISA_MIPS32R2);
15337            gen_store_srsgpr(rs, rt);
15338            break;
15339        default:
15340            goto pool32axf_invalid;
15341        }
15342        break;
15343#ifndef CONFIG_USER_ONLY
15344    case 0x0d:
15345        switch (minor) {
15346        case TLBP:
15347            mips32_op = OPC_TLBP;
15348            goto do_cp0;
15349        case TLBR:
15350            mips32_op = OPC_TLBR;
15351            goto do_cp0;
15352        case TLBWI:
15353            mips32_op = OPC_TLBWI;
15354            goto do_cp0;
15355        case TLBWR:
15356            mips32_op = OPC_TLBWR;
15357            goto do_cp0;
15358        case TLBINV:
15359            mips32_op = OPC_TLBINV;
15360            goto do_cp0;
15361        case TLBINVF:
15362            mips32_op = OPC_TLBINVF;
15363            goto do_cp0;
15364        case WAIT:
15365            mips32_op = OPC_WAIT;
15366            goto do_cp0;
15367        case DERET:
15368            mips32_op = OPC_DERET;
15369            goto do_cp0;
15370        case ERET:
15371            mips32_op = OPC_ERET;
15372        do_cp0:
15373            gen_cp0(env, ctx, mips32_op, rt, rs);
15374            break;
15375        default:
15376            goto pool32axf_invalid;
15377        }
15378        break;
15379    case 0x1d:
15380        switch (minor) {
15381        case DI:
15382            check_cp0_enabled(ctx);
15383            {
15384                TCGv t0 = tcg_temp_new();
15385
15386                save_cpu_state(ctx, 1);
15387                gen_helper_di(t0, cpu_env);
15388                gen_store_gpr(t0, rs);
15389                /* Stop translation as we may have switched the execution mode */
15390                ctx->base.is_jmp = DISAS_STOP;
15391                tcg_temp_free(t0);
15392            }
15393            break;
15394        case EI:
15395            check_cp0_enabled(ctx);
15396            {
15397                TCGv t0 = tcg_temp_new();
15398
15399                save_cpu_state(ctx, 1);
15400                gen_helper_ei(t0, cpu_env);
15401                gen_store_gpr(t0, rs);
15402                /* DISAS_STOP isn't sufficient, we need to ensure we break out
15403                   of translated code to check for pending interrupts.  */
15404                gen_save_pc(ctx->base.pc_next + 4);
15405                ctx->base.is_jmp = DISAS_EXIT;
15406                tcg_temp_free(t0);
15407            }
15408            break;
15409        default:
15410            goto pool32axf_invalid;
15411        }
15412        break;
15413#endif
15414    case 0x2d:
15415        switch (minor) {
15416        case SYNC:
15417            gen_sync(extract32(ctx->opcode, 16, 5));
15418            break;
15419        case SYSCALL:
15420            generate_exception_end(ctx, EXCP_SYSCALL);
15421            break;
15422        case SDBBP:
15423            if (is_uhi(extract32(ctx->opcode, 16, 10))) {
15424                gen_helper_do_semihosting(cpu_env);
15425            } else {
15426                check_insn(ctx, ISA_MIPS32);
15427                if (ctx->hflags & MIPS_HFLAG_SBRI) {
15428                    generate_exception_end(ctx, EXCP_RI);
15429                } else {
15430                    generate_exception_end(ctx, EXCP_DBp);
15431                }
15432            }
15433            break;
15434        default:
15435            goto pool32axf_invalid;
15436        }
15437        break;
15438    case 0x01:
15439        switch (minor & 3) {
15440        case MFHI_ACC:
15441            gen_HILO(ctx, OPC_MFHI, minor >> 2, rs);
15442            break;
15443        case MFLO_ACC:
15444            gen_HILO(ctx, OPC_MFLO, minor >> 2, rs);
15445            break;
15446        case MTHI_ACC:
15447            gen_HILO(ctx, OPC_MTHI, minor >> 2, rs);
15448            break;
15449        case MTLO_ACC:
15450            gen_HILO(ctx, OPC_MTLO, minor >> 2, rs);
15451            break;
15452        default:
15453            goto pool32axf_invalid;
15454        }
15455        break;
15456    case 0x35:
15457        check_insn_opc_removed(ctx, ISA_MIPS32R6);
15458        switch (minor) {
15459        case MFHI32:
15460            gen_HILO(ctx, OPC_MFHI, 0, rs);
15461            break;
15462        case MFLO32:
15463            gen_HILO(ctx, OPC_MFLO, 0, rs);
15464            break;
15465        case MTHI32:
15466            gen_HILO(ctx, OPC_MTHI, 0, rs);
15467            break;
15468        case MTLO32:
15469            gen_HILO(ctx, OPC_MTLO, 0, rs);
15470            break;
15471        default:
15472            goto pool32axf_invalid;
15473        }
15474        break;
15475    default:
15476    pool32axf_invalid:
15477        MIPS_INVAL("pool32axf");
15478        generate_exception_end(ctx, EXCP_RI);
15479        break;
15480    }
15481}
15482
15483/* Values for microMIPS fmt field.  Variable-width, depending on which
15484   formats the instruction supports.  */
15485
15486enum {
15487    FMT_SD_S = 0,
15488    FMT_SD_D = 1,
15489
15490    FMT_SDPS_S = 0,
15491    FMT_SDPS_D = 1,
15492    FMT_SDPS_PS = 2,
15493
15494    FMT_SWL_S = 0,
15495    FMT_SWL_W = 1,
15496    FMT_SWL_L = 2,
15497
15498    FMT_DWL_D = 0,
15499    FMT_DWL_W = 1,
15500    FMT_DWL_L = 2
15501};
15502
15503static void gen_pool32fxf(DisasContext *ctx, int rt, int rs)
15504{
15505    int extension = (ctx->opcode >> 6) & 0x3ff;
15506    uint32_t mips32_op;
15507
15508#define FLOAT_1BIT_FMT(opc, fmt) (fmt << 8) | opc
15509#define FLOAT_2BIT_FMT(opc, fmt) (fmt << 7) | opc
15510#define COND_FLOAT_MOV(opc, cond) (cond << 7) | opc
15511
15512    switch (extension) {
15513    case FLOAT_1BIT_FMT(CFC1, 0):
15514        mips32_op = OPC_CFC1;
15515        goto do_cp1;
15516    case FLOAT_1BIT_FMT(CTC1, 0):
15517        mips32_op = OPC_CTC1;
15518        goto do_cp1;
15519    case FLOAT_1BIT_FMT(MFC1, 0):
15520        mips32_op = OPC_MFC1;
15521        goto do_cp1;
15522    case FLOAT_1BIT_FMT(MTC1, 0):
15523        mips32_op = OPC_MTC1;
15524        goto do_cp1;
15525    case FLOAT_1BIT_FMT(MFHC1, 0):
15526        mips32_op = OPC_MFHC1;
15527        goto do_cp1;
15528    case FLOAT_1BIT_FMT(MTHC1, 0):
15529        mips32_op = OPC_MTHC1;
15530    do_cp1:
15531        gen_cp1(ctx, mips32_op, rt, rs);
15532        break;
15533
15534        /* Reciprocal square root */
15535    case FLOAT_1BIT_FMT(RSQRT_FMT, FMT_SD_S):
15536        mips32_op = OPC_RSQRT_S;
15537        goto do_unaryfp;
15538    case FLOAT_1BIT_FMT(RSQRT_FMT, FMT_SD_D):
15539        mips32_op = OPC_RSQRT_D;
15540        goto do_unaryfp;
15541
15542        /* Square root */
15543    case FLOAT_1BIT_FMT(SQRT_FMT, FMT_SD_S):
15544        mips32_op = OPC_SQRT_S;
15545        goto do_unaryfp;
15546    case FLOAT_1BIT_FMT(SQRT_FMT, FMT_SD_D):
15547        mips32_op = OPC_SQRT_D;
15548        goto do_unaryfp;
15549
15550        /* Reciprocal */
15551    case FLOAT_1BIT_FMT(RECIP_FMT, FMT_SD_S):
15552        mips32_op = OPC_RECIP_S;
15553        goto do_unaryfp;
15554    case FLOAT_1BIT_FMT(RECIP_FMT, FMT_SD_D):
15555        mips32_op = OPC_RECIP_D;
15556        goto do_unaryfp;
15557
15558        /* Floor */
15559    case FLOAT_1BIT_FMT(FLOOR_L, FMT_SD_S):
15560        mips32_op = OPC_FLOOR_L_S;
15561        goto do_unaryfp;
15562    case FLOAT_1BIT_FMT(FLOOR_L, FMT_SD_D):
15563        mips32_op = OPC_FLOOR_L_D;
15564        goto do_unaryfp;
15565    case FLOAT_1BIT_FMT(FLOOR_W, FMT_SD_S):
15566        mips32_op = OPC_FLOOR_W_S;
15567        goto do_unaryfp;
15568    case FLOAT_1BIT_FMT(FLOOR_W, FMT_SD_D):
15569        mips32_op = OPC_FLOOR_W_D;
15570        goto do_unaryfp;
15571
15572        /* Ceiling */
15573    case FLOAT_1BIT_FMT(CEIL_L, FMT_SD_S):
15574        mips32_op = OPC_CEIL_L_S;
15575        goto do_unaryfp;
15576    case FLOAT_1BIT_FMT(CEIL_L, FMT_SD_D):
15577        mips32_op = OPC_CEIL_L_D;
15578        goto do_unaryfp;
15579    case FLOAT_1BIT_FMT(CEIL_W, FMT_SD_S):
15580        mips32_op = OPC_CEIL_W_S;
15581        goto do_unaryfp;
15582    case FLOAT_1BIT_FMT(CEIL_W, FMT_SD_D):
15583        mips32_op = OPC_CEIL_W_D;
15584        goto do_unaryfp;
15585
15586        /* Truncation */
15587    case FLOAT_1BIT_FMT(TRUNC_L, FMT_SD_S):
15588        mips32_op = OPC_TRUNC_L_S;
15589        goto do_unaryfp;
15590    case FLOAT_1BIT_FMT(TRUNC_L, FMT_SD_D):
15591        mips32_op = OPC_TRUNC_L_D;
15592        goto do_unaryfp;
15593    case FLOAT_1BIT_FMT(TRUNC_W, FMT_SD_S):
15594        mips32_op = OPC_TRUNC_W_S;
15595        goto do_unaryfp;
15596    case FLOAT_1BIT_FMT(TRUNC_W, FMT_SD_D):
15597        mips32_op = OPC_TRUNC_W_D;
15598        goto do_unaryfp;
15599
15600        /* Round */
15601    case FLOAT_1BIT_FMT(ROUND_L, FMT_SD_S):
15602        mips32_op = OPC_ROUND_L_S;
15603        goto do_unaryfp;
15604    case FLOAT_1BIT_FMT(ROUND_L, FMT_SD_D):
15605        mips32_op = OPC_ROUND_L_D;
15606        goto do_unaryfp;
15607    case FLOAT_1BIT_FMT(ROUND_W, FMT_SD_S):
15608        mips32_op = OPC_ROUND_W_S;
15609        goto do_unaryfp;
15610    case FLOAT_1BIT_FMT(ROUND_W, FMT_SD_D):
15611        mips32_op = OPC_ROUND_W_D;
15612        goto do_unaryfp;
15613
15614        /* Integer to floating-point conversion */
15615    case FLOAT_1BIT_FMT(CVT_L, FMT_SD_S):
15616        mips32_op = OPC_CVT_L_S;
15617        goto do_unaryfp;
15618    case FLOAT_1BIT_FMT(CVT_L, FMT_SD_D):
15619        mips32_op = OPC_CVT_L_D;
15620        goto do_unaryfp;
15621    case FLOAT_1BIT_FMT(CVT_W, FMT_SD_S):
15622        mips32_op = OPC_CVT_W_S;
15623        goto do_unaryfp;
15624    case FLOAT_1BIT_FMT(CVT_W, FMT_SD_D):
15625        mips32_op = OPC_CVT_W_D;
15626        goto do_unaryfp;
15627
15628        /* Paired-foo conversions */
15629    case FLOAT_1BIT_FMT(CVT_S_PL, 0):
15630        mips32_op = OPC_CVT_S_PL;
15631        goto do_unaryfp;
15632    case FLOAT_1BIT_FMT(CVT_S_PU, 0):
15633        mips32_op = OPC_CVT_S_PU;
15634        goto do_unaryfp;
15635    case FLOAT_1BIT_FMT(CVT_PW_PS, 0):
15636        mips32_op = OPC_CVT_PW_PS;
15637        goto do_unaryfp;
15638    case FLOAT_1BIT_FMT(CVT_PS_PW, 0):
15639        mips32_op = OPC_CVT_PS_PW;
15640        goto do_unaryfp;
15641
15642        /* Floating-point moves */
15643    case FLOAT_2BIT_FMT(MOV_FMT, FMT_SDPS_S):
15644        mips32_op = OPC_MOV_S;
15645        goto do_unaryfp;
15646    case FLOAT_2BIT_FMT(MOV_FMT, FMT_SDPS_D):
15647        mips32_op = OPC_MOV_D;
15648        goto do_unaryfp;
15649    case FLOAT_2BIT_FMT(MOV_FMT, FMT_SDPS_PS):
15650        mips32_op = OPC_MOV_PS;
15651        goto do_unaryfp;
15652
15653        /* Absolute value */
15654    case FLOAT_2BIT_FMT(ABS_FMT, FMT_SDPS_S):
15655        mips32_op = OPC_ABS_S;
15656        goto do_unaryfp;
15657    case FLOAT_2BIT_FMT(ABS_FMT, FMT_SDPS_D):
15658        mips32_op = OPC_ABS_D;
15659        goto do_unaryfp;
15660    case FLOAT_2BIT_FMT(ABS_FMT, FMT_SDPS_PS):
15661        mips32_op = OPC_ABS_PS;
15662        goto do_unaryfp;
15663
15664        /* Negation */
15665    case FLOAT_2BIT_FMT(NEG_FMT, FMT_SDPS_S):
15666        mips32_op = OPC_NEG_S;
15667        goto do_unaryfp;
15668    case FLOAT_2BIT_FMT(NEG_FMT, FMT_SDPS_D):
15669        mips32_op = OPC_NEG_D;
15670        goto do_unaryfp;
15671    case FLOAT_2BIT_FMT(NEG_FMT, FMT_SDPS_PS):
15672        mips32_op = OPC_NEG_PS;
15673        goto do_unaryfp;
15674
15675        /* Reciprocal square root step */
15676    case FLOAT_2BIT_FMT(RSQRT1_FMT, FMT_SDPS_S):
15677        mips32_op = OPC_RSQRT1_S;
15678        goto do_unaryfp;
15679    case FLOAT_2BIT_FMT(RSQRT1_FMT, FMT_SDPS_D):
15680        mips32_op = OPC_RSQRT1_D;
15681        goto do_unaryfp;
15682    case FLOAT_2BIT_FMT(RSQRT1_FMT, FMT_SDPS_PS):
15683        mips32_op = OPC_RSQRT1_PS;
15684        goto do_unaryfp;
15685
15686        /* Reciprocal step */
15687    case FLOAT_2BIT_FMT(RECIP1_FMT, FMT_SDPS_S):
15688        mips32_op = OPC_RECIP1_S;
15689        goto do_unaryfp;
15690    case FLOAT_2BIT_FMT(RECIP1_FMT, FMT_SDPS_D):
15691        mips32_op = OPC_RECIP1_S;
15692        goto do_unaryfp;
15693    case FLOAT_2BIT_FMT(RECIP1_FMT, FMT_SDPS_PS):
15694        mips32_op = OPC_RECIP1_PS;
15695        goto do_unaryfp;
15696
15697        /* Conversions from double */
15698    case FLOAT_2BIT_FMT(CVT_D, FMT_SWL_S):
15699        mips32_op = OPC_CVT_D_S;
15700        goto do_unaryfp;
15701    case FLOAT_2BIT_FMT(CVT_D, FMT_SWL_W):
15702        mips32_op = OPC_CVT_D_W;
15703        goto do_unaryfp;
15704    case FLOAT_2BIT_FMT(CVT_D, FMT_SWL_L):
15705        mips32_op = OPC_CVT_D_L;
15706        goto do_unaryfp;
15707
15708        /* Conversions from single */
15709    case FLOAT_2BIT_FMT(CVT_S, FMT_DWL_D):
15710        mips32_op = OPC_CVT_S_D;
15711        goto do_unaryfp;
15712    case FLOAT_2BIT_FMT(CVT_S, FMT_DWL_W):
15713        mips32_op = OPC_CVT_S_W;
15714        goto do_unaryfp;
15715    case FLOAT_2BIT_FMT(CVT_S, FMT_DWL_L):
15716        mips32_op = OPC_CVT_S_L;
15717    do_unaryfp:
15718        gen_farith(ctx, mips32_op, -1, rs, rt, 0);
15719        break;
15720
15721        /* Conditional moves on floating-point codes */
15722    case COND_FLOAT_MOV(MOVT, 0):
15723    case COND_FLOAT_MOV(MOVT, 1):
15724    case COND_FLOAT_MOV(MOVT, 2):
15725    case COND_FLOAT_MOV(MOVT, 3):
15726    case COND_FLOAT_MOV(MOVT, 4):
15727    case COND_FLOAT_MOV(MOVT, 5):
15728    case COND_FLOAT_MOV(MOVT, 6):
15729    case COND_FLOAT_MOV(MOVT, 7):
15730        check_insn_opc_removed(ctx, ISA_MIPS32R6);
15731        gen_movci(ctx, rt, rs, (ctx->opcode >> 13) & 0x7, 1);
15732        break;
15733    case COND_FLOAT_MOV(MOVF, 0):
15734    case COND_FLOAT_MOV(MOVF, 1):
15735    case COND_FLOAT_MOV(MOVF, 2):
15736    case COND_FLOAT_MOV(MOVF, 3):
15737    case COND_FLOAT_MOV(MOVF, 4):
15738    case COND_FLOAT_MOV(MOVF, 5):
15739    case COND_FLOAT_MOV(MOVF, 6):
15740    case COND_FLOAT_MOV(MOVF, 7):
15741        check_insn_opc_removed(ctx, ISA_MIPS32R6);
15742        gen_movci(ctx, rt, rs, (ctx->opcode >> 13) & 0x7, 0);
15743        break;
15744    default:
15745        MIPS_INVAL("pool32fxf");
15746        generate_exception_end(ctx, EXCP_RI);
15747        break;
15748    }
15749}
15750
15751static void decode_micromips32_opc(CPUMIPSState *env, DisasContext *ctx)
15752{
15753    int32_t offset;
15754    uint16_t insn;
15755    int rt, rs, rd, rr;
15756    int16_t imm;
15757    uint32_t op, minor, minor2, mips32_op;
15758    uint32_t cond, fmt, cc;
15759
15760    insn = cpu_lduw_code(env, ctx->base.pc_next + 2);
15761    ctx->opcode = (ctx->opcode << 16) | insn;
15762
15763    rt = (ctx->opcode >> 21) & 0x1f;
15764    rs = (ctx->opcode >> 16) & 0x1f;
15765    rd = (ctx->opcode >> 11) & 0x1f;
15766    rr = (ctx->opcode >> 6) & 0x1f;
15767    imm = (int16_t) ctx->opcode;
15768
15769    op = (ctx->opcode >> 26) & 0x3f;
15770    switch (op) {
15771    case POOL32A:
15772        minor = ctx->opcode & 0x3f;
15773        switch (minor) {
15774        case 0x00:
15775            minor = (ctx->opcode >> 6) & 0xf;
15776            switch (minor) {
15777            case SLL32:
15778                mips32_op = OPC_SLL;
15779                goto do_shifti;
15780            case SRA:
15781                mips32_op = OPC_SRA;
15782                goto do_shifti;
15783            case SRL32:
15784                mips32_op = OPC_SRL;
15785                goto do_shifti;
15786            case ROTR:
15787                mips32_op = OPC_ROTR;
15788            do_shifti:
15789                gen_shift_imm(ctx, mips32_op, rt, rs, rd);
15790                break;
15791            case SELEQZ:
15792                check_insn(ctx, ISA_MIPS32R6);
15793                gen_cond_move(ctx, OPC_SELEQZ, rd, rs, rt);
15794                break;
15795            case SELNEZ:
15796                check_insn(ctx, ISA_MIPS32R6);
15797                gen_cond_move(ctx, OPC_SELNEZ, rd, rs, rt);
15798                break;
15799            case R6_RDHWR:
15800                check_insn(ctx, ISA_MIPS32R6);
15801                gen_rdhwr(ctx, rt, rs, extract32(ctx->opcode, 11, 3));
15802                break;
15803            default:
15804                goto pool32a_invalid;
15805            }
15806            break;
15807        case 0x10:
15808            minor = (ctx->opcode >> 6) & 0xf;
15809            switch (minor) {
15810                /* Arithmetic */
15811            case ADD:
15812                mips32_op = OPC_ADD;
15813                goto do_arith;
15814            case ADDU32:
15815                mips32_op = OPC_ADDU;
15816                goto do_arith;
15817            case SUB:
15818                mips32_op = OPC_SUB;
15819                goto do_arith;
15820            case SUBU32:
15821                mips32_op = OPC_SUBU;
15822                goto do_arith;
15823            case MUL:
15824                check_insn_opc_removed(ctx, ISA_MIPS32R6);
15825                mips32_op = OPC_MUL;
15826            do_arith:
15827                gen_arith(ctx, mips32_op, rd, rs, rt);
15828                break;
15829                /* Shifts */
15830            case SLLV:
15831                mips32_op = OPC_SLLV;
15832                goto do_shift;
15833            case SRLV:
15834                mips32_op = OPC_SRLV;
15835                goto do_shift;
15836            case SRAV:
15837                mips32_op = OPC_SRAV;
15838                goto do_shift;
15839            case ROTRV:
15840                mips32_op = OPC_ROTRV;
15841            do_shift:
15842                gen_shift(ctx, mips32_op, rd, rs, rt);
15843                break;
15844                /* Logical operations */
15845            case AND:
15846                mips32_op = OPC_AND;
15847                goto do_logic;
15848            case OR32:
15849                mips32_op = OPC_OR;
15850                goto do_logic;
15851            case NOR:
15852                mips32_op = OPC_NOR;
15853                goto do_logic;
15854            case XOR32:
15855                mips32_op = OPC_XOR;
15856            do_logic:
15857                gen_logic(ctx, mips32_op, rd, rs, rt);
15858                break;
15859                /* Set less than */
15860            case SLT:
15861                mips32_op = OPC_SLT;
15862                goto do_slt;
15863            case SLTU:
15864                mips32_op = OPC_SLTU;
15865            do_slt:
15866                gen_slt(ctx, mips32_op, rd, rs, rt);
15867                break;
15868            default:
15869                goto pool32a_invalid;
15870            }
15871            break;
15872        case 0x18:
15873            minor = (ctx->opcode >> 6) & 0xf;
15874            switch (minor) {
15875                /* Conditional moves */
15876            case MOVN: /* MUL */
15877                if (ctx->insn_flags & ISA_MIPS32R6) {
15878                    /* MUL */
15879                    gen_r6_muldiv(ctx, R6_OPC_MUL, rd, rs, rt);
15880                } else {
15881                    /* MOVN */
15882                    gen_cond_move(ctx, OPC_MOVN, rd, rs, rt);
15883                }
15884                break;
15885            case MOVZ: /* MUH */
15886                if (ctx->insn_flags & ISA_MIPS32R6) {
15887                    /* MUH */
15888                    gen_r6_muldiv(ctx, R6_OPC_MUH, rd, rs, rt);
15889                } else {
15890                    /* MOVZ */
15891                    gen_cond_move(ctx, OPC_MOVZ, rd, rs, rt);
15892                }
15893                break;
15894            case MULU:
15895                check_insn(ctx, ISA_MIPS32R6);
15896                gen_r6_muldiv(ctx, R6_OPC_MULU, rd, rs, rt);
15897                break;
15898            case MUHU:
15899                check_insn(ctx, ISA_MIPS32R6);
15900                gen_r6_muldiv(ctx, R6_OPC_MUHU, rd, rs, rt);
15901                break;
15902            case LWXS: /* DIV */
15903                if (ctx->insn_flags & ISA_MIPS32R6) {
15904                    /* DIV */
15905                    gen_r6_muldiv(ctx, R6_OPC_DIV, rd, rs, rt);
15906                } else {
15907                    /* LWXS */
15908                    gen_ldxs(ctx, rs, rt, rd);
15909                }
15910                break;
15911            case MOD:
15912                check_insn(ctx, ISA_MIPS32R6);
15913                gen_r6_muldiv(ctx, R6_OPC_MOD, rd, rs, rt);
15914                break;
15915            case R6_DIVU:
15916                check_insn(ctx, ISA_MIPS32R6);
15917                gen_r6_muldiv(ctx, R6_OPC_DIVU, rd, rs, rt);
15918                break;
15919            case MODU:
15920                check_insn(ctx, ISA_MIPS32R6);
15921                gen_r6_muldiv(ctx, R6_OPC_MODU, rd, rs, rt);
15922                break;
15923            default:
15924                goto pool32a_invalid;
15925            }
15926            break;
15927        case INS:
15928            gen_bitops(ctx, OPC_INS, rt, rs, rr, rd);
15929            return;
15930        case LSA:
15931            check_insn(ctx, ISA_MIPS32R6);
15932            gen_lsa(ctx, OPC_LSA, rd, rs, rt,
15933                    extract32(ctx->opcode, 9, 2));
15934            break;
15935        case ALIGN:
15936            check_insn(ctx, ISA_MIPS32R6);
15937            gen_align(ctx, 32, rd, rs, rt, extract32(ctx->opcode, 9, 2));
15938            break;
15939        case EXT:
15940            gen_bitops(ctx, OPC_EXT, rt, rs, rr, rd);
15941            return;
15942        case POOL32AXF:
15943            gen_pool32axf(env, ctx, rt, rs);
15944            break;
15945        case BREAK32:
15946            generate_exception_end(ctx, EXCP_BREAK);
15947            break;
15948        case SIGRIE:
15949            check_insn(ctx, ISA_MIPS32R6);
15950            generate_exception_end(ctx, EXCP_RI);
15951            break;
15952        default:
15953        pool32a_invalid:
15954                MIPS_INVAL("pool32a");
15955                generate_exception_end(ctx, EXCP_RI);
15956                break;
15957        }
15958        break;
15959    case POOL32B:
15960        minor = (ctx->opcode >> 12) & 0xf;
15961        switch (minor) {
15962        case CACHE:
15963            check_cp0_enabled(ctx);
15964            if (ctx->hflags & MIPS_HFLAG_ITC_CACHE) {
15965                gen_cache_operation(ctx, rt, rs, imm);
15966            }
15967            break;
15968        case LWC2:
15969        case SWC2:
15970            /* COP2: Not implemented. */
15971            generate_exception_err(ctx, EXCP_CpU, 2);
15972            break;
15973#ifdef TARGET_MIPS64
15974        case LDP:
15975        case SDP:
15976            check_insn(ctx, ISA_MIPS3);
15977            check_mips_64(ctx);
15978#endif
15979            /* fall through */
15980        case LWP:
15981        case SWP:
15982            gen_ldst_pair(ctx, minor, rt, rs, SIMM(ctx->opcode, 0, 12));
15983            break;
15984#ifdef TARGET_MIPS64
15985        case LDM:
15986        case SDM:
15987            check_insn(ctx, ISA_MIPS3);
15988            check_mips_64(ctx);
15989#endif
15990            /* fall through */
15991        case LWM32:
15992        case SWM32:
15993            gen_ldst_multiple(ctx, minor, rt, rs, SIMM(ctx->opcode, 0, 12));
15994            break;
15995        default:
15996            MIPS_INVAL("pool32b");
15997            generate_exception_end(ctx, EXCP_RI);
15998            break;
15999        }
16000        break;
16001    case POOL32F:
16002        if (ctx->CP0_Config1 & (1 << CP0C1_FP)) {
16003            minor = ctx->opcode & 0x3f;
16004            check_cp1_enabled(ctx);
16005            switch (minor) {
16006            case ALNV_PS:
16007                check_insn_opc_removed(ctx, ISA_MIPS32R6);
16008                mips32_op = OPC_ALNV_PS;
16009                goto do_madd;
16010            case MADD_S:
16011                check_insn_opc_removed(ctx, ISA_MIPS32R6);
16012                mips32_op = OPC_MADD_S;
16013                goto do_madd;
16014            case MADD_D:
16015                check_insn_opc_removed(ctx, ISA_MIPS32R6);
16016                mips32_op = OPC_MADD_D;
16017                goto do_madd;
16018            case MADD_PS:
16019                check_insn_opc_removed(ctx, ISA_MIPS32R6);
16020                mips32_op = OPC_MADD_PS;
16021                goto do_madd;
16022            case MSUB_S:
16023                check_insn_opc_removed(ctx, ISA_MIPS32R6);
16024                mips32_op = OPC_MSUB_S;
16025                goto do_madd;
16026            case MSUB_D:
16027                check_insn_opc_removed(ctx, ISA_MIPS32R6);
16028                mips32_op = OPC_MSUB_D;
16029                goto do_madd;
16030            case MSUB_PS:
16031                check_insn_opc_removed(ctx, ISA_MIPS32R6);
16032                mips32_op = OPC_MSUB_PS;
16033                goto do_madd;
16034            case NMADD_S:
16035                check_insn_opc_removed(ctx, ISA_MIPS32R6);
16036                mips32_op = OPC_NMADD_S;
16037                goto do_madd;
16038            case NMADD_D:
16039                check_insn_opc_removed(ctx, ISA_MIPS32R6);
16040                mips32_op = OPC_NMADD_D;
16041                goto do_madd;
16042            case NMADD_PS:
16043                check_insn_opc_removed(ctx, ISA_MIPS32R6);
16044                mips32_op = OPC_NMADD_PS;
16045                goto do_madd;
16046            case NMSUB_S:
16047                check_insn_opc_removed(ctx, ISA_MIPS32R6);
16048                mips32_op = OPC_NMSUB_S;
16049                goto do_madd;
16050            case NMSUB_D:
16051                check_insn_opc_removed(ctx, ISA_MIPS32R6);
16052                mips32_op = OPC_NMSUB_D;
16053                goto do_madd;
16054            case NMSUB_PS:
16055                check_insn_opc_removed(ctx, ISA_MIPS32R6);
16056                mips32_op = OPC_NMSUB_PS;
16057            do_madd:
16058                gen_flt3_arith(ctx, mips32_op, rd, rr, rs, rt);
16059                break;
16060            case CABS_COND_FMT:
16061                check_insn_opc_removed(ctx, ISA_MIPS32R6);
16062                cond = (ctx->opcode >> 6) & 0xf;
16063                cc = (ctx->opcode >> 13) & 0x7;
16064                fmt = (ctx->opcode >> 10) & 0x3;
16065                switch (fmt) {
16066                case 0x0:
16067                    gen_cmpabs_s(ctx, cond, rt, rs, cc);
16068                    break;
16069                case 0x1:
16070                    gen_cmpabs_d(ctx, cond, rt, rs, cc);
16071                    break;
16072                case 0x2:
16073                    gen_cmpabs_ps(ctx, cond, rt, rs, cc);
16074                    break;
16075                default:
16076                    goto pool32f_invalid;
16077                }
16078                break;
16079            case C_COND_FMT:
16080                check_insn_opc_removed(ctx, ISA_MIPS32R6);
16081                cond = (ctx->opcode >> 6) & 0xf;
16082                cc = (ctx->opcode >> 13) & 0x7;
16083                fmt = (ctx->opcode >> 10) & 0x3;
16084                switch (fmt) {
16085                case 0x0:
16086                    gen_cmp_s(ctx, cond, rt, rs, cc);
16087                    break;
16088                case 0x1:
16089                    gen_cmp_d(ctx, cond, rt, rs, cc);
16090                    break;
16091                case 0x2:
16092                    gen_cmp_ps(ctx, cond, rt, rs, cc);
16093                    break;
16094                default:
16095                    goto pool32f_invalid;
16096                }
16097                break;
16098            case CMP_CONDN_S:
16099                check_insn(ctx, ISA_MIPS32R6);
16100                gen_r6_cmp_s(ctx, (ctx->opcode >> 6) & 0x1f, rt, rs, rd);
16101                break;
16102            case CMP_CONDN_D:
16103                check_insn(ctx, ISA_MIPS32R6);
16104                gen_r6_cmp_d(ctx, (ctx->opcode >> 6) & 0x1f, rt, rs, rd);
16105                break;
16106            case POOL32FXF:
16107                gen_pool32fxf(ctx, rt, rs);
16108                break;
16109            case 0x00:
16110                /* PLL foo */
16111                switch ((ctx->opcode >> 6) & 0x7) {
16112                case PLL_PS:
16113                    mips32_op = OPC_PLL_PS;
16114                    goto do_ps;
16115                case PLU_PS:
16116                    mips32_op = OPC_PLU_PS;
16117                    goto do_ps;
16118                case PUL_PS:
16119                    mips32_op = OPC_PUL_PS;
16120                    goto do_ps;
16121                case PUU_PS:
16122                    mips32_op = OPC_PUU_PS;
16123                    goto do_ps;
16124                case CVT_PS_S:
16125                    check_insn_opc_removed(ctx, ISA_MIPS32R6);
16126                    mips32_op = OPC_CVT_PS_S;
16127                do_ps:
16128                    gen_farith(ctx, mips32_op, rt, rs, rd, 0);
16129                    break;
16130                default:
16131                    goto pool32f_invalid;
16132                }
16133                break;
16134            case MIN_FMT:
16135                check_insn(ctx, ISA_MIPS32R6);
16136                switch ((ctx->opcode >> 9) & 0x3) {
16137                case FMT_SDPS_S:
16138                    gen_farith(ctx, OPC_MIN_S, rt, rs, rd, 0);
16139                    break;
16140                case FMT_SDPS_D:
16141                    gen_farith(ctx, OPC_MIN_D, rt, rs, rd, 0);
16142                    break;
16143                default:
16144                    goto pool32f_invalid;
16145                }
16146                break;
16147            case 0x08:
16148                /* [LS][WDU]XC1 */
16149                switch ((ctx->opcode >> 6) & 0x7) {
16150                case LWXC1:
16151                    check_insn_opc_removed(ctx, ISA_MIPS32R6);
16152                    mips32_op = OPC_LWXC1;
16153                    goto do_ldst_cp1;
16154                case SWXC1:
16155                    check_insn_opc_removed(ctx, ISA_MIPS32R6);
16156                    mips32_op = OPC_SWXC1;
16157                    goto do_ldst_cp1;
16158                case LDXC1:
16159                    check_insn_opc_removed(ctx, ISA_MIPS32R6);
16160                    mips32_op = OPC_LDXC1;
16161                    goto do_ldst_cp1;
16162                case SDXC1:
16163                    check_insn_opc_removed(ctx, ISA_MIPS32R6);
16164                    mips32_op = OPC_SDXC1;
16165                    goto do_ldst_cp1;
16166                case LUXC1:
16167                    check_insn_opc_removed(ctx, ISA_MIPS32R6);
16168                    mips32_op = OPC_LUXC1;
16169                    goto do_ldst_cp1;
16170                case SUXC1:
16171                    check_insn_opc_removed(ctx, ISA_MIPS32R6);
16172                    mips32_op = OPC_SUXC1;
16173                do_ldst_cp1:
16174                    gen_flt3_ldst(ctx, mips32_op, rd, rd, rt, rs);
16175                    break;
16176                default:
16177                    goto pool32f_invalid;
16178                }
16179                break;
16180            case MAX_FMT:
16181                check_insn(ctx, ISA_MIPS32R6);
16182                switch ((ctx->opcode >> 9) & 0x3) {
16183                case FMT_SDPS_S:
16184                    gen_farith(ctx, OPC_MAX_S, rt, rs, rd, 0);
16185                    break;
16186                case FMT_SDPS_D:
16187                    gen_farith(ctx, OPC_MAX_D, rt, rs, rd, 0);
16188                    break;
16189                default:
16190                    goto pool32f_invalid;
16191                }
16192                break;
16193            case 0x18:
16194                /* 3D insns */
16195                check_insn_opc_removed(ctx, ISA_MIPS32R6);
16196                fmt = (ctx->opcode >> 9) & 0x3;
16197                switch ((ctx->opcode >> 6) & 0x7) {
16198                case RSQRT2_FMT:
16199                    switch (fmt) {
16200                    case FMT_SDPS_S:
16201                        mips32_op = OPC_RSQRT2_S;
16202                        goto do_3d;
16203                    case FMT_SDPS_D:
16204                        mips32_op = OPC_RSQRT2_D;
16205                        goto do_3d;
16206                    case FMT_SDPS_PS:
16207                        mips32_op = OPC_RSQRT2_PS;
16208                        goto do_3d;
16209                    default:
16210                        goto pool32f_invalid;
16211                    }
16212                    break;
16213                case RECIP2_FMT:
16214                    switch (fmt) {
16215                    case FMT_SDPS_S:
16216                        mips32_op = OPC_RECIP2_S;
16217                        goto do_3d;
16218                    case FMT_SDPS_D:
16219                        mips32_op = OPC_RECIP2_D;
16220                        goto do_3d;
16221                    case FMT_SDPS_PS:
16222                        mips32_op = OPC_RECIP2_PS;
16223                        goto do_3d;
16224                    default:
16225                        goto pool32f_invalid;
16226                    }
16227                    break;
16228                case ADDR_PS:
16229                    mips32_op = OPC_ADDR_PS;
16230                    goto do_3d;
16231                case MULR_PS:
16232                    mips32_op = OPC_MULR_PS;
16233                do_3d:
16234                    gen_farith(ctx, mips32_op, rt, rs, rd, 0);
16235                    break;
16236                default:
16237                    goto pool32f_invalid;
16238                }
16239                break;
16240            case 0x20:
16241                /* MOV[FT].fmt, PREFX, RINT.fmt, CLASS.fmt*/
16242                cc = (ctx->opcode >> 13) & 0x7;
16243                fmt = (ctx->opcode >> 9) & 0x3;
16244                switch ((ctx->opcode >> 6) & 0x7) {
16245                case MOVF_FMT: /* RINT_FMT */
16246                    if (ctx->insn_flags & ISA_MIPS32R6) {
16247                        /* RINT_FMT */
16248                        switch (fmt) {
16249                        case FMT_SDPS_S:
16250                            gen_farith(ctx, OPC_RINT_S, 0, rt, rs, 0);
16251                            break;
16252                        case FMT_SDPS_D:
16253                            gen_farith(ctx, OPC_RINT_D, 0, rt, rs, 0);
16254                            break;
16255                        default:
16256                            goto pool32f_invalid;
16257                        }
16258                    } else {
16259                        /* MOVF_FMT */
16260                        switch (fmt) {
16261                        case FMT_SDPS_S:
16262                            gen_movcf_s(ctx, rs, rt, cc, 0);
16263                            break;
16264                        case FMT_SDPS_D:
16265                            gen_movcf_d(ctx, rs, rt, cc, 0);
16266                            break;
16267                        case FMT_SDPS_PS:
16268                            check_ps(ctx);
16269                            gen_movcf_ps(ctx, rs, rt, cc, 0);
16270                            break;
16271                        default:
16272                            goto pool32f_invalid;
16273                        }
16274                    }
16275                    break;
16276                case MOVT_FMT: /* CLASS_FMT */
16277                    if (ctx->insn_flags & ISA_MIPS32R6) {
16278                        /* CLASS_FMT */
16279                        switch (fmt) {
16280                        case FMT_SDPS_S:
16281                            gen_farith(ctx, OPC_CLASS_S, 0, rt, rs, 0);
16282                            break;
16283                        case FMT_SDPS_D:
16284                            gen_farith(ctx, OPC_CLASS_D, 0, rt, rs, 0);
16285                            break;
16286                        default:
16287                            goto pool32f_invalid;
16288                        }
16289                    } else {
16290                        /* MOVT_FMT */
16291                        switch (fmt) {
16292                        case FMT_SDPS_S:
16293                            gen_movcf_s(ctx, rs, rt, cc, 1);
16294                            break;
16295                        case FMT_SDPS_D:
16296                            gen_movcf_d(ctx, rs, rt, cc, 1);
16297                            break;
16298                        case FMT_SDPS_PS:
16299                            check_ps(ctx);
16300                            gen_movcf_ps(ctx, rs, rt, cc, 1);
16301                            break;
16302                        default:
16303                            goto pool32f_invalid;
16304                        }
16305                    }
16306                    break;
16307                case PREFX:
16308                    check_insn_opc_removed(ctx, ISA_MIPS32R6);
16309                    break;
16310                default:
16311                    goto pool32f_invalid;
16312                }
16313                break;
16314#define FINSN_3ARG_SDPS(prfx)                           \
16315                switch ((ctx->opcode >> 8) & 0x3) {     \
16316                case FMT_SDPS_S:                        \
16317                    mips32_op = OPC_##prfx##_S;         \
16318                    goto do_fpop;                       \
16319                case FMT_SDPS_D:                        \
16320                    mips32_op = OPC_##prfx##_D;         \
16321                    goto do_fpop;                       \
16322                case FMT_SDPS_PS:                       \
16323                    check_ps(ctx);                      \
16324                    mips32_op = OPC_##prfx##_PS;        \
16325                    goto do_fpop;                       \
16326                default:                                \
16327                    goto pool32f_invalid;               \
16328                }
16329            case MINA_FMT:
16330                check_insn(ctx, ISA_MIPS32R6);
16331                switch ((ctx->opcode >> 9) & 0x3) {
16332                case FMT_SDPS_S:
16333                    gen_farith(ctx, OPC_MINA_S, rt, rs, rd, 0);
16334                    break;
16335                case FMT_SDPS_D:
16336                    gen_farith(ctx, OPC_MINA_D, rt, rs, rd, 0);
16337                    break;
16338                default:
16339                    goto pool32f_invalid;
16340                }
16341                break;
16342            case MAXA_FMT:
16343                check_insn(ctx, ISA_MIPS32R6);
16344                switch ((ctx->opcode >> 9) & 0x3) {
16345                case FMT_SDPS_S:
16346                    gen_farith(ctx, OPC_MAXA_S, rt, rs, rd, 0);
16347                    break;
16348                case FMT_SDPS_D:
16349                    gen_farith(ctx, OPC_MAXA_D, rt, rs, rd, 0);
16350                    break;
16351                default:
16352                    goto pool32f_invalid;
16353                }
16354                break;
16355            case 0x30:
16356                /* regular FP ops */
16357                switch ((ctx->opcode >> 6) & 0x3) {
16358                case ADD_FMT:
16359                    FINSN_3ARG_SDPS(ADD);
16360                    break;
16361                case SUB_FMT:
16362                    FINSN_3ARG_SDPS(SUB);
16363                    break;
16364                case MUL_FMT:
16365                    FINSN_3ARG_SDPS(MUL);
16366                    break;
16367                case DIV_FMT:
16368                    fmt = (ctx->opcode >> 8) & 0x3;
16369                    if (fmt == 1) {
16370                        mips32_op = OPC_DIV_D;
16371                    } else if (fmt == 0) {
16372                        mips32_op = OPC_DIV_S;
16373                    } else {
16374                        goto pool32f_invalid;
16375                    }
16376                    goto do_fpop;
16377                default:
16378                    goto pool32f_invalid;
16379                }
16380                break;
16381            case 0x38:
16382                /* cmovs */
16383                switch ((ctx->opcode >> 6) & 0x7) {
16384                case MOVN_FMT: /* SELEQZ_FMT */
16385                    if (ctx->insn_flags & ISA_MIPS32R6) {
16386                        /* SELEQZ_FMT */
16387                        switch ((ctx->opcode >> 9) & 0x3) {
16388                        case FMT_SDPS_S:
16389                            gen_sel_s(ctx, OPC_SELEQZ_S, rd, rt, rs);
16390                            break;
16391                        case FMT_SDPS_D:
16392                            gen_sel_d(ctx, OPC_SELEQZ_D, rd, rt, rs);
16393                            break;
16394                        default:
16395                            goto pool32f_invalid;
16396                        }
16397                    } else {
16398                        /* MOVN_FMT */
16399                        FINSN_3ARG_SDPS(MOVN);
16400                    }
16401                    break;
16402                case MOVN_FMT_04:
16403                    check_insn_opc_removed(ctx, ISA_MIPS32R6);
16404                    FINSN_3ARG_SDPS(MOVN);
16405                    break;
16406                case MOVZ_FMT: /* SELNEZ_FMT */
16407                    if (ctx->insn_flags & ISA_MIPS32R6) {
16408                        /* SELNEZ_FMT */
16409                        switch ((ctx->opcode >> 9) & 0x3) {
16410                        case FMT_SDPS_S:
16411                            gen_sel_s(ctx, OPC_SELNEZ_S, rd, rt, rs);
16412                            break;
16413                        case FMT_SDPS_D:
16414                            gen_sel_d(ctx, OPC_SELNEZ_D, rd, rt, rs);
16415                            break;
16416                        default:
16417                            goto pool32f_invalid;
16418                        }
16419                    } else {
16420                        /* MOVZ_FMT */
16421                        FINSN_3ARG_SDPS(MOVZ);
16422                    }
16423                    break;
16424                case MOVZ_FMT_05:
16425                    check_insn_opc_removed(ctx, ISA_MIPS32R6);
16426                    FINSN_3ARG_SDPS(MOVZ);
16427                    break;
16428                case SEL_FMT:
16429                    check_insn(ctx, ISA_MIPS32R6);
16430                    switch ((ctx->opcode >> 9) & 0x3) {
16431                    case FMT_SDPS_S:
16432                        gen_sel_s(ctx, OPC_SEL_S, rd, rt, rs);
16433                        break;
16434                    case FMT_SDPS_D:
16435                        gen_sel_d(ctx, OPC_SEL_D, rd, rt, rs);
16436                        break;
16437                    default:
16438                        goto pool32f_invalid;
16439                    }
16440                    break;
16441                case MADDF_FMT:
16442                    check_insn(ctx, ISA_MIPS32R6);
16443                    switch ((ctx->opcode >> 9) & 0x3) {
16444                    case FMT_SDPS_S:
16445                        mips32_op = OPC_MADDF_S;
16446                        goto do_fpop;
16447                    case FMT_SDPS_D:
16448                        mips32_op = OPC_MADDF_D;
16449                        goto do_fpop;
16450                    default:
16451                        goto pool32f_invalid;
16452                    }
16453                    break;
16454                case MSUBF_FMT:
16455                    check_insn(ctx, ISA_MIPS32R6);
16456                    switch ((ctx->opcode >> 9) & 0x3) {
16457                    case FMT_SDPS_S:
16458                        mips32_op = OPC_MSUBF_S;
16459                        goto do_fpop;
16460                    case FMT_SDPS_D:
16461                        mips32_op = OPC_MSUBF_D;
16462                        goto do_fpop;
16463                    default:
16464                        goto pool32f_invalid;
16465                    }
16466                    break;
16467                default:
16468                    goto pool32f_invalid;
16469                }
16470                break;
16471            do_fpop:
16472                gen_farith(ctx, mips32_op, rt, rs, rd, 0);
16473                break;
16474            default:
16475            pool32f_invalid:
16476                MIPS_INVAL("pool32f");
16477                generate_exception_end(ctx, EXCP_RI);
16478                break;
16479            }
16480        } else {
16481            generate_exception_err(ctx, EXCP_CpU, 1);
16482        }
16483        break;
16484    case POOL32I:
16485        minor = (ctx->opcode >> 21) & 0x1f;
16486        switch (minor) {
16487        case BLTZ:
16488            check_insn_opc_removed(ctx, ISA_MIPS32R6);
16489            gen_compute_branch(ctx, OPC_BLTZ, 4, rs, -1, imm << 1, 4);
16490            break;
16491        case BLTZAL:
16492            check_insn_opc_removed(ctx, ISA_MIPS32R6);
16493            gen_compute_branch(ctx, OPC_BLTZAL, 4, rs, -1, imm << 1, 4);
16494            ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
16495            break;
16496        case BLTZALS:
16497            check_insn_opc_removed(ctx, ISA_MIPS32R6);
16498            gen_compute_branch(ctx, OPC_BLTZAL, 4, rs, -1, imm << 1, 2);
16499            ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
16500            break;
16501        case BGEZ:
16502            check_insn_opc_removed(ctx, ISA_MIPS32R6);
16503            gen_compute_branch(ctx, OPC_BGEZ, 4, rs, -1, imm << 1, 4);
16504            break;
16505        case BGEZAL:
16506            check_insn_opc_removed(ctx, ISA_MIPS32R6);
16507            gen_compute_branch(ctx, OPC_BGEZAL, 4, rs, -1, imm << 1, 4);
16508            ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
16509            break;
16510        case BGEZALS:
16511            check_insn_opc_removed(ctx, ISA_MIPS32R6);
16512            gen_compute_branch(ctx, OPC_BGEZAL, 4, rs, -1, imm << 1, 2);
16513            ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
16514            break;
16515        case BLEZ:
16516            check_insn_opc_removed(ctx, ISA_MIPS32R6);
16517            gen_compute_branch(ctx, OPC_BLEZ, 4, rs, -1, imm << 1, 4);
16518            break;
16519        case BGTZ:
16520            check_insn_opc_removed(ctx, ISA_MIPS32R6);
16521            gen_compute_branch(ctx, OPC_BGTZ, 4, rs, -1, imm << 1, 4);
16522            break;
16523
16524            /* Traps */
16525        case TLTI: /* BC1EQZC */
16526            if (ctx->insn_flags & ISA_MIPS32R6) {
16527                /* BC1EQZC */
16528                check_cp1_enabled(ctx);
16529                gen_compute_branch1_r6(ctx, OPC_BC1EQZ, rs, imm << 1, 0);
16530            } else {
16531                /* TLTI */
16532                mips32_op = OPC_TLTI;
16533                goto do_trapi;
16534            }
16535            break;
16536        case TGEI: /* BC1NEZC */
16537            if (ctx->insn_flags & ISA_MIPS32R6) {
16538                /* BC1NEZC */
16539                check_cp1_enabled(ctx);
16540                gen_compute_branch1_r6(ctx, OPC_BC1NEZ, rs, imm << 1, 0);
16541            } else {
16542                /* TGEI */
16543                mips32_op = OPC_TGEI;
16544                goto do_trapi;
16545            }
16546            break;
16547        case TLTIU:
16548            check_insn_opc_removed(ctx, ISA_MIPS32R6);
16549            mips32_op = OPC_TLTIU;
16550            goto do_trapi;
16551        case TGEIU:
16552            check_insn_opc_removed(ctx, ISA_MIPS32R6);
16553            mips32_op = OPC_TGEIU;
16554            goto do_trapi;
16555        case TNEI: /* SYNCI */
16556            if (ctx->insn_flags & ISA_MIPS32R6) {
16557                /* SYNCI */
16558                /* Break the TB to be able to sync copied instructions
16559                   immediately */
16560                ctx->base.is_jmp = DISAS_STOP;
16561            } else {
16562                /* TNEI */
16563                mips32_op = OPC_TNEI;
16564                goto do_trapi;
16565            }
16566            break;
16567        case TEQI:
16568            check_insn_opc_removed(ctx, ISA_MIPS32R6);
16569            mips32_op = OPC_TEQI;
16570        do_trapi:
16571            gen_trap(ctx, mips32_op, rs, -1, imm);
16572            break;
16573
16574        case BNEZC:
16575        case BEQZC:
16576            check_insn_opc_removed(ctx, ISA_MIPS32R6);
16577            gen_compute_branch(ctx, minor == BNEZC ? OPC_BNE : OPC_BEQ,
16578                               4, rs, 0, imm << 1, 0);
16579            /* Compact branches don't have a delay slot, so just let
16580               the normal delay slot handling take us to the branch
16581               target. */
16582            break;
16583        case LUI:
16584            check_insn_opc_removed(ctx, ISA_MIPS32R6);
16585            gen_logic_imm(ctx, OPC_LUI, rs, 0, imm);
16586            break;
16587        case SYNCI:
16588            check_insn_opc_removed(ctx, ISA_MIPS32R6);
16589            /* Break the TB to be able to sync copied instructions
16590               immediately */
16591            ctx->base.is_jmp = DISAS_STOP;
16592            break;
16593        case BC2F:
16594        case BC2T:
16595            check_insn_opc_removed(ctx, ISA_MIPS32R6);
16596            /* COP2: Not implemented. */
16597            generate_exception_err(ctx, EXCP_CpU, 2);
16598            break;
16599        case BC1F:
16600            check_insn_opc_removed(ctx, ISA_MIPS32R6);
16601            mips32_op = (ctx->opcode & (1 << 16)) ? OPC_BC1FANY2 : OPC_BC1F;
16602            goto do_cp1branch;
16603        case BC1T:
16604            check_insn_opc_removed(ctx, ISA_MIPS32R6);
16605            mips32_op = (ctx->opcode & (1 << 16)) ? OPC_BC1TANY2 : OPC_BC1T;
16606            goto do_cp1branch;
16607        case BC1ANY4F:
16608            check_insn_opc_removed(ctx, ISA_MIPS32R6);
16609            mips32_op = OPC_BC1FANY4;
16610            goto do_cp1mips3d;
16611        case BC1ANY4T:
16612            check_insn_opc_removed(ctx, ISA_MIPS32R6);
16613            mips32_op = OPC_BC1TANY4;
16614        do_cp1mips3d:
16615            check_cop1x(ctx);
16616            check_insn(ctx, ASE_MIPS3D);
16617            /* Fall through */
16618        do_cp1branch:
16619            if (env->CP0_Config1 & (1 << CP0C1_FP)) {
16620                check_cp1_enabled(ctx);
16621                gen_compute_branch1(ctx, mips32_op,
16622                                    (ctx->opcode >> 18) & 0x7, imm << 1);
16623            } else {
16624                generate_exception_err(ctx, EXCP_CpU, 1);
16625            }
16626            break;
16627        case BPOSGE64:
16628        case BPOSGE32:
16629            /* MIPS DSP: not implemented */
16630            /* Fall through */
16631        default:
16632            MIPS_INVAL("pool32i");
16633            generate_exception_end(ctx, EXCP_RI);
16634            break;
16635        }
16636        break;
16637    case POOL32C:
16638        minor = (ctx->opcode >> 12) & 0xf;
16639        offset = sextract32(ctx->opcode, 0,
16640                            (ctx->insn_flags & ISA_MIPS32R6) ? 9 : 12);
16641        switch (minor) {
16642        case LWL:
16643            check_insn_opc_removed(ctx, ISA_MIPS32R6);
16644            mips32_op = OPC_LWL;
16645            goto do_ld_lr;
16646        case SWL:
16647            check_insn_opc_removed(ctx, ISA_MIPS32R6);
16648            mips32_op = OPC_SWL;
16649            goto do_st_lr;
16650        case LWR:
16651            check_insn_opc_removed(ctx, ISA_MIPS32R6);
16652            mips32_op = OPC_LWR;
16653            goto do_ld_lr;
16654        case SWR:
16655            check_insn_opc_removed(ctx, ISA_MIPS32R6);
16656            mips32_op = OPC_SWR;
16657            goto do_st_lr;
16658#if defined(TARGET_MIPS64)
16659        case LDL:
16660            check_insn(ctx, ISA_MIPS3);
16661            check_mips_64(ctx);
16662            check_insn_opc_removed(ctx, ISA_MIPS32R6);
16663            mips32_op = OPC_LDL;
16664            goto do_ld_lr;
16665        case SDL:
16666            check_insn(ctx, ISA_MIPS3);
16667            check_mips_64(ctx);
16668            check_insn_opc_removed(ctx, ISA_MIPS32R6);
16669            mips32_op = OPC_SDL;
16670            goto do_st_lr;
16671        case LDR:
16672            check_insn(ctx, ISA_MIPS3);
16673            check_mips_64(ctx);
16674            check_insn_opc_removed(ctx, ISA_MIPS32R6);
16675            mips32_op = OPC_LDR;
16676            goto do_ld_lr;
16677        case SDR:
16678            check_insn(ctx, ISA_MIPS3);
16679            check_mips_64(ctx);
16680            check_insn_opc_removed(ctx, ISA_MIPS32R6);
16681            mips32_op = OPC_SDR;
16682            goto do_st_lr;
16683        case LWU:
16684            check_insn(ctx, ISA_MIPS3);
16685            check_mips_64(ctx);
16686            mips32_op = OPC_LWU;
16687            goto do_ld_lr;
16688        case LLD:
16689            check_insn(ctx, ISA_MIPS3);
16690            check_mips_64(ctx);
16691            mips32_op = OPC_LLD;
16692            goto do_ld_lr;
16693#endif
16694        case LL:
16695            mips32_op = OPC_LL;
16696            goto do_ld_lr;
16697        do_ld_lr:
16698            gen_ld(ctx, mips32_op, rt, rs, offset);
16699            break;
16700        do_st_lr:
16701            gen_st(ctx, mips32_op, rt, rs, offset);
16702            break;
16703        case SC:
16704            gen_st_cond(ctx, OPC_SC, rt, rs, offset);
16705            break;
16706#if defined(TARGET_MIPS64)
16707        case SCD:
16708            check_insn(ctx, ISA_MIPS3);
16709            check_mips_64(ctx);
16710            gen_st_cond(ctx, OPC_SCD, rt, rs, offset);
16711            break;
16712#endif
16713        case LD_EVA:
16714            if (!ctx->eva) {
16715                MIPS_INVAL("pool32c ld-eva");
16716                generate_exception_end(ctx, EXCP_RI);
16717                break;
16718            }
16719            check_cp0_enabled(ctx);
16720
16721            minor2 = (ctx->opcode >> 9) & 0x7;
16722            offset = sextract32(ctx->opcode, 0, 9);
16723            switch (minor2) {
16724            case LBUE:
16725                mips32_op = OPC_LBUE;
16726                goto do_ld_lr;
16727            case LHUE:
16728                mips32_op = OPC_LHUE;
16729                goto do_ld_lr;
16730            case LWLE:
16731                check_insn_opc_removed(ctx, ISA_MIPS32R6);
16732                mips32_op = OPC_LWLE;
16733                goto do_ld_lr;
16734            case LWRE:
16735                check_insn_opc_removed(ctx, ISA_MIPS32R6);
16736                mips32_op = OPC_LWRE;
16737                goto do_ld_lr;
16738            case LBE:
16739                mips32_op = OPC_LBE;
16740                goto do_ld_lr;
16741            case LHE:
16742                mips32_op = OPC_LHE;
16743                goto do_ld_lr;
16744            case LLE:
16745                mips32_op = OPC_LLE;
16746                goto do_ld_lr;
16747            case LWE:
16748                mips32_op = OPC_LWE;
16749                goto do_ld_lr;
16750            };
16751            break;
16752        case ST_EVA:
16753            if (!ctx->eva) {
16754                MIPS_INVAL("pool32c st-eva");
16755                generate_exception_end(ctx, EXCP_RI);
16756                break;
16757            }
16758            check_cp0_enabled(ctx);
16759
16760            minor2 = (ctx->opcode >> 9) & 0x7;
16761            offset = sextract32(ctx->opcode, 0, 9);
16762            switch (minor2) {
16763            case SWLE:
16764                check_insn_opc_removed(ctx, ISA_MIPS32R6);
16765                mips32_op = OPC_SWLE;
16766                goto do_st_lr;
16767            case SWRE:
16768                check_insn_opc_removed(ctx, ISA_MIPS32R6);
16769                mips32_op = OPC_SWRE;
16770                goto do_st_lr;
16771            case PREFE:
16772                /* Treat as no-op */
16773                if ((ctx->insn_flags & ISA_MIPS32R6) && (rt >= 24)) {
16774                    /* hint codes 24-31 are reserved and signal RI */
16775                    generate_exception(ctx, EXCP_RI);
16776                }
16777                break;
16778            case CACHEE:
16779                /* Treat as no-op */
16780                if (ctx->hflags & MIPS_HFLAG_ITC_CACHE) {
16781                    gen_cache_operation(ctx, rt, rs, offset);
16782                }
16783                break;
16784            case SBE:
16785                mips32_op = OPC_SBE;
16786                goto do_st_lr;
16787            case SHE:
16788                mips32_op = OPC_SHE;
16789                goto do_st_lr;
16790            case SCE:
16791                gen_st_cond(ctx, OPC_SCE, rt, rs, offset);
16792                break;
16793            case SWE:
16794                mips32_op = OPC_SWE;
16795                goto do_st_lr;
16796            };
16797            break;
16798        case PREF:
16799            /* Treat as no-op */
16800            if ((ctx->insn_flags & ISA_MIPS32R6) && (rt >= 24)) {
16801                /* hint codes 24-31 are reserved and signal RI */
16802                generate_exception(ctx, EXCP_RI);
16803            }
16804            break;
16805        default:
16806            MIPS_INVAL("pool32c");
16807            generate_exception_end(ctx, EXCP_RI);
16808            break;
16809        }
16810        break;
16811    case ADDI32: /* AUI, LUI */
16812        if (ctx->insn_flags & ISA_MIPS32R6) {
16813            /* AUI, LUI */
16814            gen_logic_imm(ctx, OPC_LUI, rt, rs, imm);
16815        } else {
16816            /* ADDI32 */
16817            mips32_op = OPC_ADDI;
16818            goto do_addi;
16819        }
16820        break;
16821    case ADDIU32:
16822        mips32_op = OPC_ADDIU;
16823    do_addi:
16824        gen_arith_imm(ctx, mips32_op, rt, rs, imm);
16825        break;
16826
16827        /* Logical operations */
16828    case ORI32:
16829        mips32_op = OPC_ORI;
16830        goto do_logici;
16831    case XORI32:
16832        mips32_op = OPC_XORI;
16833        goto do_logici;
16834    case ANDI32:
16835        mips32_op = OPC_ANDI;
16836    do_logici:
16837        gen_logic_imm(ctx, mips32_op, rt, rs, imm);
16838        break;
16839
16840        /* Set less than immediate */
16841    case SLTI32:
16842        mips32_op = OPC_SLTI;
16843        goto do_slti;
16844    case SLTIU32:
16845        mips32_op = OPC_SLTIU;
16846    do_slti:
16847        gen_slt_imm(ctx, mips32_op, rt, rs, imm);
16848        break;
16849    case JALX32:
16850        check_insn_opc_removed(ctx, ISA_MIPS32R6);
16851        offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 2;
16852        gen_compute_branch(ctx, OPC_JALX, 4, rt, rs, offset, 4);
16853        ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
16854        break;
16855    case JALS32: /* BOVC, BEQC, BEQZALC */
16856        if (ctx->insn_flags & ISA_MIPS32R6) {
16857            if (rs >= rt) {
16858                /* BOVC */
16859                mips32_op = OPC_BOVC;
16860            } else if (rs < rt && rs == 0) {
16861                /* BEQZALC */
16862                mips32_op = OPC_BEQZALC;
16863            } else {
16864                /* BEQC */
16865                mips32_op = OPC_BEQC;
16866            }
16867            gen_compute_compact_branch(ctx, mips32_op, rs, rt, imm << 1);
16868        } else {
16869            /* JALS32 */
16870            offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 1;
16871            gen_compute_branch(ctx, OPC_JAL, 4, rt, rs, offset, 2);
16872            ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
16873        }
16874        break;
16875    case BEQ32: /* BC */
16876        if (ctx->insn_flags & ISA_MIPS32R6) {
16877            /* BC */
16878            gen_compute_compact_branch(ctx, OPC_BC, 0, 0,
16879                                       sextract32(ctx->opcode << 1, 0, 27));
16880        } else {
16881            /* BEQ32 */
16882            gen_compute_branch(ctx, OPC_BEQ, 4, rt, rs, imm << 1, 4);
16883        }
16884        break;
16885    case BNE32: /* BALC */
16886        if (ctx->insn_flags & ISA_MIPS32R6) {
16887            /* BALC */
16888            gen_compute_compact_branch(ctx, OPC_BALC, 0, 0,
16889                                       sextract32(ctx->opcode << 1, 0, 27));
16890        } else {
16891            /* BNE32 */
16892            gen_compute_branch(ctx, OPC_BNE, 4, rt, rs, imm << 1, 4);
16893        }
16894        break;
16895    case J32: /* BGTZC, BLTZC, BLTC */
16896        if (ctx->insn_flags & ISA_MIPS32R6) {
16897            if (rs == 0 && rt != 0) {
16898                /* BGTZC */
16899                mips32_op = OPC_BGTZC;
16900            } else if (rs != 0 && rt != 0 && rs == rt) {
16901                /* BLTZC */
16902                mips32_op = OPC_BLTZC;
16903            } else {
16904                /* BLTC */
16905                mips32_op = OPC_BLTC;
16906            }
16907            gen_compute_compact_branch(ctx, mips32_op, rs, rt, imm << 1);
16908        } else {
16909            /* J32 */
16910            gen_compute_branch(ctx, OPC_J, 4, rt, rs,
16911                               (int32_t)(ctx->opcode & 0x3FFFFFF) << 1, 4);
16912        }
16913        break;
16914    case JAL32: /* BLEZC, BGEZC, BGEC */
16915        if (ctx->insn_flags & ISA_MIPS32R6) {
16916            if (rs == 0 && rt != 0) {
16917                /* BLEZC */
16918                mips32_op = OPC_BLEZC;
16919            } else if (rs != 0 && rt != 0 && rs == rt) {
16920                /* BGEZC */
16921                mips32_op = OPC_BGEZC;
16922            } else {
16923                /* BGEC */
16924                mips32_op = OPC_BGEC;
16925            }
16926            gen_compute_compact_branch(ctx, mips32_op, rs, rt, imm << 1);
16927        } else {
16928            /* JAL32 */
16929            gen_compute_branch(ctx, OPC_JAL, 4, rt, rs,
16930                               (int32_t)(ctx->opcode & 0x3FFFFFF) << 1, 4);
16931            ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
16932        }
16933        break;
16934        /* Floating point (COP1) */
16935    case LWC132:
16936        mips32_op = OPC_LWC1;
16937        goto do_cop1;
16938    case LDC132:
16939        mips32_op = OPC_LDC1;
16940        goto do_cop1;
16941    case SWC132:
16942        mips32_op = OPC_SWC1;
16943        goto do_cop1;
16944    case SDC132:
16945        mips32_op = OPC_SDC1;
16946    do_cop1:
16947        gen_cop1_ldst(ctx, mips32_op, rt, rs, imm);
16948        break;
16949    case ADDIUPC: /* PCREL: ADDIUPC, AUIPC, ALUIPC, LWPC */
16950        if (ctx->insn_flags & ISA_MIPS32R6) {
16951            /* PCREL: ADDIUPC, AUIPC, ALUIPC, LWPC */
16952            switch ((ctx->opcode >> 16) & 0x1f) {
16953            case ADDIUPC_00:
16954            case ADDIUPC_01:
16955            case ADDIUPC_02:
16956            case ADDIUPC_03:
16957            case ADDIUPC_04:
16958            case ADDIUPC_05:
16959            case ADDIUPC_06:
16960            case ADDIUPC_07:
16961                gen_pcrel(ctx, OPC_ADDIUPC, ctx->base.pc_next & ~0x3, rt);
16962                break;
16963            case AUIPC:
16964                gen_pcrel(ctx, OPC_AUIPC, ctx->base.pc_next, rt);
16965                break;
16966            case ALUIPC:
16967                gen_pcrel(ctx, OPC_ALUIPC, ctx->base.pc_next, rt);
16968                break;
16969            case LWPC_08:
16970            case LWPC_09:
16971            case LWPC_0A:
16972            case LWPC_0B:
16973            case LWPC_0C:
16974            case LWPC_0D:
16975            case LWPC_0E:
16976            case LWPC_0F:
16977                gen_pcrel(ctx, R6_OPC_LWPC, ctx->base.pc_next & ~0x3, rt);
16978                break;
16979            default:
16980                generate_exception(ctx, EXCP_RI);
16981                break;
16982            }
16983        } else {
16984            /* ADDIUPC */
16985            int reg = mmreg(ZIMM(ctx->opcode, 23, 3));
16986            offset = SIMM(ctx->opcode, 0, 23) << 2;
16987
16988            gen_addiupc(ctx, reg, offset, 0, 0);
16989        }
16990        break;
16991    case BNVC: /* BNEC, BNEZALC */
16992        check_insn(ctx, ISA_MIPS32R6);
16993        if (rs >= rt) {
16994            /* BNVC */
16995            mips32_op = OPC_BNVC;
16996        } else if (rs < rt && rs == 0) {
16997            /* BNEZALC */
16998            mips32_op = OPC_BNEZALC;
16999        } else {
17000            /* BNEC */
17001            mips32_op = OPC_BNEC;
17002        }
17003        gen_compute_compact_branch(ctx, mips32_op, rs, rt, imm << 1);
17004        break;
17005    case R6_BNEZC: /* JIALC */
17006        check_insn(ctx, ISA_MIPS32R6);
17007        if (rt != 0) {
17008            /* BNEZC */
17009            gen_compute_compact_branch(ctx, OPC_BNEZC, rt, 0,
17010                                       sextract32(ctx->opcode << 1, 0, 22));
17011        } else {
17012            /* JIALC */
17013            gen_compute_compact_branch(ctx, OPC_JIALC, 0, rs, imm);
17014        }
17015        break;
17016    case R6_BEQZC: /* JIC */
17017        check_insn(ctx, ISA_MIPS32R6);
17018        if (rt != 0) {
17019            /* BEQZC */
17020            gen_compute_compact_branch(ctx, OPC_BEQZC, rt, 0,
17021                                       sextract32(ctx->opcode << 1, 0, 22));
17022        } else {
17023            /* JIC */
17024            gen_compute_compact_branch(ctx, OPC_JIC, 0, rs, imm);
17025        }
17026        break;
17027    case BLEZALC: /* BGEZALC, BGEUC */
17028        check_insn(ctx, ISA_MIPS32R6);
17029        if (rs == 0 && rt != 0) {
17030            /* BLEZALC */
17031            mips32_op = OPC_BLEZALC;
17032        } else if (rs != 0 && rt != 0 && rs == rt) {
17033            /* BGEZALC */
17034            mips32_op = OPC_BGEZALC;
17035        } else {
17036            /* BGEUC */
17037            mips32_op = OPC_BGEUC;
17038        }
17039        gen_compute_compact_branch(ctx, mips32_op, rs, rt, imm << 1);
17040        break;
17041    case BGTZALC: /* BLTZALC, BLTUC */
17042        check_insn(ctx, ISA_MIPS32R6);
17043        if (rs == 0 && rt != 0) {
17044            /* BGTZALC */
17045            mips32_op = OPC_BGTZALC;
17046        } else if (rs != 0 && rt != 0 && rs == rt) {
17047            /* BLTZALC */
17048            mips32_op = OPC_BLTZALC;
17049        } else {
17050            /* BLTUC */
17051            mips32_op = OPC_BLTUC;
17052        }
17053        gen_compute_compact_branch(ctx, mips32_op, rs, rt, imm << 1);
17054        break;
17055        /* Loads and stores */
17056    case LB32:
17057        mips32_op = OPC_LB;
17058        goto do_ld;
17059    case LBU32:
17060        mips32_op = OPC_LBU;
17061        goto do_ld;
17062    case LH32:
17063        mips32_op = OPC_LH;
17064        goto do_ld;
17065    case LHU32:
17066        mips32_op = OPC_LHU;
17067        goto do_ld;
17068    case LW32:
17069        mips32_op = OPC_LW;
17070        goto do_ld;
17071#ifdef TARGET_MIPS64
17072    case LD32:
17073        check_insn(ctx, ISA_MIPS3);
17074        check_mips_64(ctx);
17075        mips32_op = OPC_LD;
17076        goto do_ld;
17077    case SD32:
17078        check_insn(ctx, ISA_MIPS3);
17079        check_mips_64(ctx);
17080        mips32_op = OPC_SD;
17081        goto do_st;
17082#endif
17083    case SB32:
17084        mips32_op = OPC_SB;
17085        goto do_st;
17086    case SH32:
17087        mips32_op = OPC_SH;
17088        goto do_st;
17089    case SW32:
17090        mips32_op = OPC_SW;
17091        goto do_st;
17092    do_ld:
17093        gen_ld(ctx, mips32_op, rt, rs, imm);
17094        break;
17095    do_st:
17096        gen_st(ctx, mips32_op, rt, rs, imm);
17097        break;
17098    default:
17099        generate_exception_end(ctx, EXCP_RI);
17100        break;
17101    }
17102}
17103
17104static int decode_micromips_opc (CPUMIPSState *env, DisasContext *ctx)
17105{
17106    uint32_t op;
17107
17108    /* make sure instructions are on a halfword boundary */
17109    if (ctx->base.pc_next & 0x1) {
17110        env->CP0_BadVAddr = ctx->base.pc_next;
17111        generate_exception_end(ctx, EXCP_AdEL);
17112        return 2;
17113    }
17114
17115    op = (ctx->opcode >> 10) & 0x3f;
17116    /* Enforce properly-sized instructions in a delay slot */
17117    if (ctx->hflags & MIPS_HFLAG_BDS_STRICT) {
17118        switch (op & 0x7) { /* MSB-3..MSB-5 */
17119        case 0:
17120        /* POOL32A, POOL32B, POOL32I, POOL32C */
17121        case 4:
17122        /* ADDI32, ADDIU32, ORI32, XORI32, SLTI32, SLTIU32, ANDI32, JALX32 */
17123        case 5:
17124        /* LBU32, LHU32, POOL32F, JALS32, BEQ32, BNE32, J32, JAL32 */
17125        case 6:
17126        /* SB32, SH32, ADDIUPC, SWC132, SDC132, SW32 */
17127        case 7:
17128        /* LB32, LH32, LWC132, LDC132, LW32 */
17129            if (ctx->hflags & MIPS_HFLAG_BDS16) {
17130                generate_exception_end(ctx, EXCP_RI);
17131                return 2;
17132            }
17133            break;
17134        case 1:
17135        /* POOL16A, POOL16B, POOL16C, LWGP16, POOL16F */
17136        case 2:
17137        /* LBU16, LHU16, LWSP16, LW16, SB16, SH16, SWSP16, SW16 */
17138        case 3:
17139        /* MOVE16, ANDI16, POOL16D, POOL16E, BEQZ16, BNEZ16, B16, LI16 */
17140            if (ctx->hflags & MIPS_HFLAG_BDS32) {
17141                generate_exception_end(ctx, EXCP_RI);
17142                return 2;
17143            }
17144            break;
17145        }
17146    }
17147
17148    switch (op) {
17149    case POOL16A:
17150        {
17151            int rd = mmreg(uMIPS_RD(ctx->opcode));
17152            int rs1 = mmreg(uMIPS_RS1(ctx->opcode));
17153            int rs2 = mmreg(uMIPS_RS2(ctx->opcode));
17154            uint32_t opc = 0;
17155
17156            switch (ctx->opcode & 0x1) {
17157            case ADDU16:
17158                opc = OPC_ADDU;
17159                break;
17160            case SUBU16:
17161                opc = OPC_SUBU;
17162                break;
17163            }
17164            if (ctx->insn_flags & ISA_MIPS32R6) {
17165                /* In the Release 6 the register number location in
17166                 * the instruction encoding has changed.
17167                 */
17168                gen_arith(ctx, opc, rs1, rd, rs2);
17169            } else {
17170                gen_arith(ctx, opc, rd, rs1, rs2);
17171            }
17172        }
17173        break;
17174    case POOL16B:
17175        {
17176            int rd = mmreg(uMIPS_RD(ctx->opcode));
17177            int rs = mmreg(uMIPS_RS(ctx->opcode));
17178            int amount = (ctx->opcode >> 1) & 0x7;
17179            uint32_t opc = 0;
17180            amount = amount == 0 ? 8 : amount;
17181
17182            switch (ctx->opcode & 0x1) {
17183            case SLL16:
17184                opc = OPC_SLL;
17185                break;
17186            case SRL16:
17187                opc = OPC_SRL;
17188                break;
17189            }
17190
17191            gen_shift_imm(ctx, opc, rd, rs, amount);
17192        }
17193        break;
17194    case POOL16C:
17195        if (ctx->insn_flags & ISA_MIPS32R6) {
17196            gen_pool16c_r6_insn(ctx);
17197        } else {
17198            gen_pool16c_insn(ctx);
17199        }
17200        break;
17201    case LWGP16:
17202        {
17203            int rd = mmreg(uMIPS_RD(ctx->opcode));
17204            int rb = 28;            /* GP */
17205            int16_t offset = SIMM(ctx->opcode, 0, 7) << 2;
17206
17207            gen_ld(ctx, OPC_LW, rd, rb, offset);
17208        }
17209        break;
17210    case POOL16F:
17211        check_insn_opc_removed(ctx, ISA_MIPS32R6);
17212        if (ctx->opcode & 1) {
17213            generate_exception_end(ctx, EXCP_RI);
17214        } else {
17215            /* MOVEP */
17216            int enc_dest = uMIPS_RD(ctx->opcode);
17217            int enc_rt = uMIPS_RS2(ctx->opcode);
17218            int enc_rs = uMIPS_RS1(ctx->opcode);
17219            gen_movep(ctx, enc_dest, enc_rt, enc_rs);
17220        }
17221        break;
17222    case LBU16:
17223        {
17224            int rd = mmreg(uMIPS_RD(ctx->opcode));
17225            int rb = mmreg(uMIPS_RS(ctx->opcode));
17226            int16_t offset = ZIMM(ctx->opcode, 0, 4);
17227            offset = (offset == 0xf ? -1 : offset);
17228
17229            gen_ld(ctx, OPC_LBU, rd, rb, offset);
17230        }
17231        break;
17232    case LHU16:
17233        {
17234            int rd = mmreg(uMIPS_RD(ctx->opcode));
17235            int rb = mmreg(uMIPS_RS(ctx->opcode));
17236            int16_t offset = ZIMM(ctx->opcode, 0, 4) << 1;
17237
17238            gen_ld(ctx, OPC_LHU, rd, rb, offset);
17239        }
17240        break;
17241    case LWSP16:
17242        {
17243            int rd = (ctx->opcode >> 5) & 0x1f;
17244            int rb = 29;            /* SP */
17245            int16_t offset = ZIMM(ctx->opcode, 0, 5) << 2;
17246
17247            gen_ld(ctx, OPC_LW, rd, rb, offset);
17248        }
17249        break;
17250    case LW16:
17251        {
17252            int rd = mmreg(uMIPS_RD(ctx->opcode));
17253            int rb = mmreg(uMIPS_RS(ctx->opcode));
17254            int16_t offset = ZIMM(ctx->opcode, 0, 4) << 2;
17255
17256            gen_ld(ctx, OPC_LW, rd, rb, offset);
17257        }
17258        break;
17259    case SB16:
17260        {
17261            int rd = mmreg2(uMIPS_RD(ctx->opcode));
17262            int rb = mmreg(uMIPS_RS(ctx->opcode));
17263            int16_t offset = ZIMM(ctx->opcode, 0, 4);
17264
17265            gen_st(ctx, OPC_SB, rd, rb, offset);
17266        }
17267        break;
17268    case SH16:
17269        {
17270            int rd = mmreg2(uMIPS_RD(ctx->opcode));
17271            int rb = mmreg(uMIPS_RS(ctx->opcode));
17272            int16_t offset = ZIMM(ctx->opcode, 0, 4) << 1;
17273
17274            gen_st(ctx, OPC_SH, rd, rb, offset);
17275        }
17276        break;
17277    case SWSP16:
17278        {
17279            int rd = (ctx->opcode >> 5) & 0x1f;
17280            int rb = 29;            /* SP */
17281            int16_t offset = ZIMM(ctx->opcode, 0, 5) << 2;
17282
17283            gen_st(ctx, OPC_SW, rd, rb, offset);
17284        }
17285        break;
17286    case SW16:
17287        {
17288            int rd = mmreg2(uMIPS_RD(ctx->opcode));
17289            int rb = mmreg(uMIPS_RS(ctx->opcode));
17290            int16_t offset = ZIMM(ctx->opcode, 0, 4) << 2;
17291
17292            gen_st(ctx, OPC_SW, rd, rb, offset);
17293        }
17294        break;
17295    case MOVE16:
17296        {
17297            int rd = uMIPS_RD5(ctx->opcode);
17298            int rs = uMIPS_RS5(ctx->opcode);
17299
17300            gen_arith(ctx, OPC_ADDU, rd, rs, 0);
17301        }
17302        break;
17303    case ANDI16:
17304        gen_andi16(ctx);
17305        break;
17306    case POOL16D:
17307        switch (ctx->opcode & 0x1) {
17308        case ADDIUS5:
17309            gen_addius5(ctx);
17310            break;
17311        case ADDIUSP:
17312            gen_addiusp(ctx);
17313            break;
17314        }
17315        break;
17316    case POOL16E:
17317        switch (ctx->opcode & 0x1) {
17318        case ADDIUR2:
17319            gen_addiur2(ctx);
17320            break;
17321        case ADDIUR1SP:
17322            gen_addiur1sp(ctx);
17323            break;
17324        }
17325        break;
17326    case B16: /* BC16 */
17327        gen_compute_branch(ctx, OPC_BEQ, 2, 0, 0,
17328                           sextract32(ctx->opcode, 0, 10) << 1,
17329                           (ctx->insn_flags & ISA_MIPS32R6) ? 0 : 4);
17330        break;
17331    case BNEZ16: /* BNEZC16 */
17332    case BEQZ16: /* BEQZC16 */
17333        gen_compute_branch(ctx, op == BNEZ16 ? OPC_BNE : OPC_BEQ, 2,
17334                           mmreg(uMIPS_RD(ctx->opcode)),
17335                           0, sextract32(ctx->opcode, 0, 7) << 1,
17336                           (ctx->insn_flags & ISA_MIPS32R6) ? 0 : 4);
17337
17338        break;
17339    case LI16:
17340        {
17341            int reg = mmreg(uMIPS_RD(ctx->opcode));
17342            int imm = ZIMM(ctx->opcode, 0, 7);
17343
17344            imm = (imm == 0x7f ? -1 : imm);
17345            tcg_gen_movi_tl(cpu_gpr[reg], imm);
17346        }
17347        break;
17348    case RES_29:
17349    case RES_31:
17350    case RES_39:
17351        generate_exception_end(ctx, EXCP_RI);
17352        break;
17353    default:
17354        decode_micromips32_opc(env, ctx);
17355        return 4;
17356    }
17357
17358    return 2;
17359}
17360
17361/*
17362 *
17363 * nanoMIPS opcodes
17364 *
17365 */
17366
17367/* MAJOR, P16, and P32 pools opcodes */
17368enum {
17369    NM_P_ADDIU      = 0x00,
17370    NM_ADDIUPC      = 0x01,
17371    NM_MOVE_BALC    = 0x02,
17372    NM_P16_MV       = 0x04,
17373    NM_LW16         = 0x05,
17374    NM_BC16         = 0x06,
17375    NM_P16_SR       = 0x07,
17376
17377    NM_POOL32A      = 0x08,
17378    NM_P_BAL        = 0x0a,
17379    NM_P16_SHIFT    = 0x0c,
17380    NM_LWSP16       = 0x0d,
17381    NM_BALC16       = 0x0e,
17382    NM_P16_4X4      = 0x0f,
17383
17384    NM_P_GP_W       = 0x10,
17385    NM_P_GP_BH      = 0x11,
17386    NM_P_J          = 0x12,
17387    NM_P16C         = 0x14,
17388    NM_LWGP16       = 0x15,
17389    NM_P16_LB       = 0x17,
17390
17391    NM_P48I         = 0x18,
17392    NM_P16_A1       = 0x1c,
17393    NM_LW4X4        = 0x1d,
17394    NM_P16_LH       = 0x1f,
17395
17396    NM_P_U12        = 0x20,
17397    NM_P_LS_U12     = 0x21,
17398    NM_P_BR1        = 0x22,
17399    NM_P16_A2       = 0x24,
17400    NM_SW16         = 0x25,
17401    NM_BEQZC16      = 0x26,
17402
17403    NM_POOL32F      = 0x28,
17404    NM_P_LS_S9      = 0x29,
17405    NM_P_BR2        = 0x2a,
17406
17407    NM_P16_ADDU     = 0x2c,
17408    NM_SWSP16       = 0x2d,
17409    NM_BNEZC16      = 0x2e,
17410    NM_MOVEP        = 0x2f,
17411
17412    NM_POOL32S      = 0x30,
17413    NM_P_BRI        = 0x32,
17414    NM_LI16         = 0x34,
17415    NM_SWGP16       = 0x35,
17416    NM_P16_BR       = 0x36,
17417
17418    NM_P_LUI        = 0x38,
17419    NM_ANDI16       = 0x3c,
17420    NM_SW4X4        = 0x3d,
17421    NM_MOVEPREV     = 0x3f,
17422};
17423
17424/* POOL32A instruction pool */
17425enum {
17426    NM_POOL32A0    = 0x00,
17427    NM_SPECIAL2    = 0x01,
17428    NM_COP2_1      = 0x02,
17429    NM_UDI         = 0x03,
17430    NM_POOL32A5    = 0x05,
17431    NM_POOL32A7    = 0x07,
17432};
17433
17434/* P.GP.W instruction pool */
17435enum {
17436    NM_ADDIUGP_W = 0x00,
17437    NM_LWGP      = 0x02,
17438    NM_SWGP      = 0x03,
17439};
17440
17441/* P48I instruction pool */
17442enum {
17443    NM_LI48        = 0x00,
17444    NM_ADDIU48     = 0x01,
17445    NM_ADDIUGP48   = 0x02,
17446    NM_ADDIUPC48   = 0x03,
17447    NM_LWPC48      = 0x0b,
17448    NM_SWPC48      = 0x0f,
17449};
17450
17451/* P.U12 instruction pool */
17452enum {
17453    NM_ORI      = 0x00,
17454    NM_XORI     = 0x01,
17455    NM_ANDI     = 0x02,
17456    NM_P_SR     = 0x03,
17457    NM_SLTI     = 0x04,
17458    NM_SLTIU    = 0x05,
17459    NM_SEQI     = 0x06,
17460    NM_ADDIUNEG = 0x08,
17461    NM_P_SHIFT  = 0x0c,
17462    NM_P_ROTX   = 0x0d,
17463    NM_P_INS    = 0x0e,
17464    NM_P_EXT    = 0x0f,
17465};
17466
17467/* POOL32F instruction pool */
17468enum {
17469    NM_POOL32F_0   = 0x00,
17470    NM_POOL32F_3   = 0x03,
17471    NM_POOL32F_5   = 0x05,
17472};
17473
17474/* POOL32S instruction pool */
17475enum {
17476    NM_POOL32S_0   = 0x00,
17477    NM_POOL32S_4   = 0x04,
17478};
17479
17480/* P.LUI instruction pool */
17481enum {
17482    NM_LUI      = 0x00,
17483    NM_ALUIPC   = 0x01,
17484};
17485
17486/* P.GP.BH instruction pool */
17487enum {
17488    NM_LBGP      = 0x00,
17489    NM_SBGP      = 0x01,
17490    NM_LBUGP     = 0x02,
17491    NM_ADDIUGP_B = 0x03,
17492    NM_P_GP_LH   = 0x04,
17493    NM_P_GP_SH   = 0x05,
17494    NM_P_GP_CP1  = 0x06,
17495};
17496
17497/* P.LS.U12 instruction pool */
17498enum {
17499    NM_LB        = 0x00,
17500    NM_SB        = 0x01,
17501    NM_LBU       = 0x02,
17502    NM_P_PREFU12 = 0x03,
17503    NM_LH        = 0x04,
17504    NM_SH        = 0x05,
17505    NM_LHU       = 0x06,
17506    NM_LWU       = 0x07,
17507    NM_LW        = 0x08,
17508    NM_SW        = 0x09,
17509    NM_LWC1      = 0x0a,
17510    NM_SWC1      = 0x0b,
17511    NM_LDC1      = 0x0e,
17512    NM_SDC1      = 0x0f,
17513};
17514
17515/* P.LS.S9 instruction pool */
17516enum {
17517    NM_P_LS_S0         = 0x00,
17518    NM_P_LS_S1         = 0x01,
17519    NM_P_LS_E0         = 0x02,
17520    NM_P_LS_WM         = 0x04,
17521    NM_P_LS_UAWM       = 0x05,
17522};
17523
17524/* P.BAL instruction pool */
17525enum {
17526    NM_BC       = 0x00,
17527    NM_BALC     = 0x01,
17528};
17529
17530/* P.J instruction pool */
17531enum {
17532    NM_JALRC    = 0x00,
17533    NM_JALRC_HB = 0x01,
17534    NM_P_BALRSC = 0x08,
17535};
17536
17537/* P.BR1 instruction pool */
17538enum {
17539    NM_BEQC     = 0x00,
17540    NM_P_BR3A   = 0x01,
17541    NM_BGEC     = 0x02,
17542    NM_BGEUC    = 0x03,
17543};
17544
17545/* P.BR2 instruction pool */
17546enum {
17547    NM_BNEC     = 0x00,
17548    NM_BLTC     = 0x02,
17549    NM_BLTUC    = 0x03,
17550};
17551
17552/* P.BRI instruction pool */
17553enum {
17554    NM_BEQIC    = 0x00,
17555    NM_BBEQZC   = 0x01,
17556    NM_BGEIC    = 0x02,
17557    NM_BGEIUC   = 0x03,
17558    NM_BNEIC    = 0x04,
17559    NM_BBNEZC   = 0x05,
17560    NM_BLTIC    = 0x06,
17561    NM_BLTIUC   = 0x07,
17562};
17563
17564/* P16.SHIFT instruction pool */
17565enum {
17566    NM_SLL16    = 0x00,
17567    NM_SRL16    = 0x01,
17568};
17569
17570/* POOL16C instruction pool */
17571enum {
17572    NM_POOL16C_0  = 0x00,
17573    NM_LWXS16     = 0x01,
17574};
17575
17576/* P16.A1 instruction pool */
17577enum {
17578    NM_ADDIUR1SP = 0x01,
17579};
17580
17581/* P16.A2 instruction pool */
17582enum {
17583    NM_ADDIUR2  = 0x00,
17584    NM_P_ADDIURS5  = 0x01,
17585};
17586
17587/* P16.ADDU instruction pool */
17588enum {
17589    NM_ADDU16     = 0x00,
17590    NM_SUBU16     = 0x01,
17591};
17592
17593/* P16.SR instruction pool */
17594enum {
17595    NM_SAVE16        = 0x00,
17596    NM_RESTORE_JRC16 = 0x01,
17597};
17598
17599/* P16.4X4 instruction pool */
17600enum {
17601    NM_ADDU4X4      = 0x00,
17602    NM_MUL4X4       = 0x01,
17603};
17604
17605/* P16.LB instruction pool */
17606enum {
17607    NM_LB16       = 0x00,
17608    NM_SB16       = 0x01,
17609    NM_LBU16      = 0x02,
17610};
17611
17612/* P16.LH  instruction pool */
17613enum {
17614    NM_LH16     = 0x00,
17615    NM_SH16     = 0x01,
17616    NM_LHU16    = 0x02,
17617};
17618
17619/* P.RI instruction pool */
17620enum {
17621    NM_SIGRIE       = 0x00,
17622    NM_P_SYSCALL    = 0x01,
17623    NM_BREAK        = 0x02,
17624    NM_SDBBP        = 0x03,
17625};
17626
17627/* POOL32A0 instruction pool */
17628enum {
17629    NM_P_TRAP   = 0x00,
17630    NM_SEB      = 0x01,
17631    NM_SLLV     = 0x02,
17632    NM_MUL      = 0x03,
17633    NM_MFC0     = 0x06,
17634    NM_MFHC0    = 0x07,
17635    NM_SEH      = 0x09,
17636    NM_SRLV     = 0x0a,
17637    NM_MUH      = 0x0b,
17638    NM_MTC0     = 0x0e,
17639    NM_MTHC0    = 0x0f,
17640    NM_SRAV     = 0x12,
17641    NM_MULU     = 0x13,
17642    NM_ROTRV    = 0x1a,
17643    NM_MUHU     = 0x1b,
17644    NM_ADD      = 0x22,
17645    NM_DIV      = 0x23,
17646    NM_ADDU     = 0x2a,
17647    NM_MOD      = 0x2b,
17648    NM_SUB      = 0x32,
17649    NM_DIVU     = 0x33,
17650    NM_RDHWR    = 0x38,
17651    NM_SUBU     = 0x3a,
17652    NM_MODU     = 0x3b,
17653    NM_P_CMOVE  = 0x42,
17654    NM_FORK     = 0x45,
17655    NM_MFTR     = 0x46,
17656    NM_MFHTR    = 0x47,
17657    NM_AND      = 0x4a,
17658    NM_YIELD    = 0x4d,
17659    NM_MTTR     = 0x4e,
17660    NM_MTHTR    = 0x4f,
17661    NM_OR       = 0x52,
17662    NM_D_E_MT_VPE = 0x56,
17663    NM_NOR      = 0x5a,
17664    NM_XOR      = 0x62,
17665    NM_SLT      = 0x6a,
17666    NM_P_SLTU   = 0x72,
17667    NM_SOV      = 0x7a,
17668};
17669
17670/* CRC32 instruction pool */
17671enum {
17672    NM_CRC32B   = 0x00,
17673    NM_CRC32H   = 0x01,
17674    NM_CRC32W   = 0x02,
17675    NM_CRC32CB  = 0x04,
17676    NM_CRC32CH  = 0x05,
17677    NM_CRC32CW  = 0x06,
17678};
17679
17680/* POOL32A5 instruction pool */
17681enum {
17682    NM_CMP_EQ_PH        = 0x00,
17683    NM_CMP_LT_PH        = 0x08,
17684    NM_CMP_LE_PH        = 0x10,
17685    NM_CMPGU_EQ_QB      = 0x18,
17686    NM_CMPGU_LT_QB      = 0x20,
17687    NM_CMPGU_LE_QB      = 0x28,
17688    NM_CMPGDU_EQ_QB     = 0x30,
17689    NM_CMPGDU_LT_QB     = 0x38,
17690    NM_CMPGDU_LE_QB     = 0x40,
17691    NM_CMPU_EQ_QB       = 0x48,
17692    NM_CMPU_LT_QB       = 0x50,
17693    NM_CMPU_LE_QB       = 0x58,
17694    NM_ADDQ_S_W         = 0x60,
17695    NM_SUBQ_S_W         = 0x68,
17696    NM_ADDSC            = 0x70,
17697    NM_ADDWC            = 0x78,
17698
17699    NM_ADDQ_S_PH   = 0x01,
17700    NM_ADDQH_R_PH  = 0x09,
17701    NM_ADDQH_R_W   = 0x11,
17702    NM_ADDU_S_QB   = 0x19,
17703    NM_ADDU_S_PH   = 0x21,
17704    NM_ADDUH_R_QB  = 0x29,
17705    NM_SHRAV_R_PH  = 0x31,
17706    NM_SHRAV_R_QB  = 0x39,
17707    NM_SUBQ_S_PH   = 0x41,
17708    NM_SUBQH_R_PH  = 0x49,
17709    NM_SUBQH_R_W   = 0x51,
17710    NM_SUBU_S_QB   = 0x59,
17711    NM_SUBU_S_PH   = 0x61,
17712    NM_SUBUH_R_QB  = 0x69,
17713    NM_SHLLV_S_PH  = 0x71,
17714    NM_PRECR_SRA_R_PH_W = 0x79,
17715
17716    NM_MULEU_S_PH_QBL   = 0x12,
17717    NM_MULEU_S_PH_QBR   = 0x1a,
17718    NM_MULQ_RS_PH       = 0x22,
17719    NM_MULQ_S_PH        = 0x2a,
17720    NM_MULQ_RS_W        = 0x32,
17721    NM_MULQ_S_W         = 0x3a,
17722    NM_APPEND           = 0x42,
17723    NM_MODSUB           = 0x52,
17724    NM_SHRAV_R_W        = 0x5a,
17725    NM_SHRLV_PH         = 0x62,
17726    NM_SHRLV_QB         = 0x6a,
17727    NM_SHLLV_QB         = 0x72,
17728    NM_SHLLV_S_W        = 0x7a,
17729
17730    NM_SHILO            = 0x03,
17731
17732    NM_MULEQ_S_W_PHL    = 0x04,
17733    NM_MULEQ_S_W_PHR    = 0x0c,
17734
17735    NM_MUL_S_PH         = 0x05,
17736    NM_PRECR_QB_PH      = 0x0d,
17737    NM_PRECRQ_QB_PH     = 0x15,
17738    NM_PRECRQ_PH_W      = 0x1d,
17739    NM_PRECRQ_RS_PH_W   = 0x25,
17740    NM_PRECRQU_S_QB_PH  = 0x2d,
17741    NM_PACKRL_PH        = 0x35,
17742    NM_PICK_QB          = 0x3d,
17743    NM_PICK_PH          = 0x45,
17744
17745    NM_SHRA_R_W         = 0x5e,
17746    NM_SHRA_R_PH        = 0x66,
17747    NM_SHLL_S_PH        = 0x76,
17748    NM_SHLL_S_W         = 0x7e,
17749
17750    NM_REPL_PH          = 0x07
17751};
17752
17753/* POOL32A7 instruction pool */
17754enum {
17755    NM_P_LSX        = 0x00,
17756    NM_LSA          = 0x01,
17757    NM_EXTW         = 0x03,
17758    NM_POOL32AXF    = 0x07,
17759};
17760
17761/* P.SR instruction pool */
17762enum {
17763    NM_PP_SR           = 0x00,
17764    NM_P_SR_F          = 0x01,
17765};
17766
17767/* P.SHIFT instruction pool */
17768enum {
17769    NM_P_SLL        = 0x00,
17770    NM_SRL          = 0x02,
17771    NM_SRA          = 0x04,
17772    NM_ROTR         = 0x06,
17773};
17774
17775/* P.ROTX instruction pool */
17776enum {
17777    NM_ROTX         = 0x00,
17778};
17779
17780/* P.INS instruction pool */
17781enum {
17782    NM_INS          = 0x00,
17783};
17784
17785/* P.EXT instruction pool */
17786enum {
17787    NM_EXT          = 0x00,
17788};
17789
17790/* POOL32F_0 (fmt) instruction pool */
17791enum {
17792    NM_RINT_S              = 0x04,
17793    NM_RINT_D              = 0x44,
17794    NM_ADD_S               = 0x06,
17795    NM_SELEQZ_S            = 0x07,
17796    NM_SELEQZ_D            = 0x47,
17797    NM_CLASS_S             = 0x0c,
17798    NM_CLASS_D             = 0x4c,
17799    NM_SUB_S               = 0x0e,
17800    NM_SELNEZ_S            = 0x0f,
17801    NM_SELNEZ_D            = 0x4f,
17802    NM_MUL_S               = 0x16,
17803    NM_SEL_S               = 0x17,
17804    NM_SEL_D               = 0x57,
17805    NM_DIV_S               = 0x1e,
17806    NM_ADD_D               = 0x26,
17807    NM_SUB_D               = 0x2e,
17808    NM_MUL_D               = 0x36,
17809    NM_MADDF_S             = 0x37,
17810    NM_MADDF_D             = 0x77,
17811    NM_DIV_D               = 0x3e,
17812    NM_MSUBF_S             = 0x3f,
17813    NM_MSUBF_D             = 0x7f,
17814};
17815
17816/* POOL32F_3  instruction pool */
17817enum {
17818    NM_MIN_FMT         = 0x00,
17819    NM_MAX_FMT         = 0x01,
17820    NM_MINA_FMT        = 0x04,
17821    NM_MAXA_FMT        = 0x05,
17822    NM_POOL32FXF       = 0x07,
17823};
17824
17825/* POOL32F_5  instruction pool */
17826enum {
17827    NM_CMP_CONDN_S     = 0x00,
17828    NM_CMP_CONDN_D     = 0x02,
17829};
17830
17831/* P.GP.LH instruction pool */
17832enum {
17833    NM_LHGP    = 0x00,
17834    NM_LHUGP   = 0x01,
17835};
17836
17837/* P.GP.SH instruction pool */
17838enum {
17839    NM_SHGP    = 0x00,
17840};
17841
17842/* P.GP.CP1 instruction pool */
17843enum {
17844    NM_LWC1GP       = 0x00,
17845    NM_SWC1GP       = 0x01,
17846    NM_LDC1GP       = 0x02,
17847    NM_SDC1GP       = 0x03,
17848};
17849
17850/* P.LS.S0 instruction pool */
17851enum {
17852    NM_LBS9     = 0x00,
17853    NM_LHS9     = 0x04,
17854    NM_LWS9     = 0x08,
17855    NM_LDS9     = 0x0c,
17856
17857    NM_SBS9     = 0x01,
17858    NM_SHS9     = 0x05,
17859    NM_SWS9     = 0x09,
17860    NM_SDS9     = 0x0d,
17861
17862    NM_LBUS9    = 0x02,
17863    NM_LHUS9    = 0x06,
17864    NM_LWC1S9   = 0x0a,
17865    NM_LDC1S9   = 0x0e,
17866
17867    NM_P_PREFS9 = 0x03,
17868    NM_LWUS9    = 0x07,
17869    NM_SWC1S9   = 0x0b,
17870    NM_SDC1S9   = 0x0f,
17871};
17872
17873/* P.LS.S1 instruction pool */
17874enum {
17875    NM_ASET_ACLR = 0x02,
17876    NM_UALH      = 0x04,
17877    NM_UASH      = 0x05,
17878    NM_CACHE     = 0x07,
17879    NM_P_LL      = 0x0a,
17880    NM_P_SC      = 0x0b,
17881};
17882
17883/* P.LS.E0 instruction pool */
17884enum {
17885    NM_LBE      = 0x00,
17886    NM_SBE      = 0x01,
17887    NM_LBUE     = 0x02,
17888    NM_P_PREFE  = 0x03,
17889    NM_LHE      = 0x04,
17890    NM_SHE      = 0x05,
17891    NM_LHUE     = 0x06,
17892    NM_CACHEE   = 0x07,
17893    NM_LWE      = 0x08,
17894    NM_SWE      = 0x09,
17895    NM_P_LLE    = 0x0a,
17896    NM_P_SCE    = 0x0b,
17897};
17898
17899/* P.PREFE instruction pool */
17900enum {
17901    NM_SYNCIE   = 0x00,
17902    NM_PREFE    = 0x01,
17903};
17904
17905/* P.LLE instruction pool */
17906enum {
17907    NM_LLE      = 0x00,
17908    NM_LLWPE    = 0x01,
17909};
17910
17911/* P.SCE instruction pool */
17912enum {
17913    NM_SCE      = 0x00,
17914    NM_SCWPE    = 0x01,
17915};
17916
17917/* P.LS.WM instruction pool */
17918enum {
17919    NM_LWM       = 0x00,
17920    NM_SWM       = 0x01,
17921};
17922
17923/* P.LS.UAWM instruction pool */
17924enum {
17925    NM_UALWM       = 0x00,
17926    NM_UASWM       = 0x01,
17927};
17928
17929/* P.BR3A instruction pool */
17930enum {
17931    NM_BC1EQZC          = 0x00,
17932    NM_BC1NEZC          = 0x01,
17933    NM_BC2EQZC          = 0x02,
17934    NM_BC2NEZC          = 0x03,
17935    NM_BPOSGE32C        = 0x04,
17936};
17937
17938/* P16.RI instruction pool */
17939enum {
17940    NM_P16_SYSCALL  = 0x01,
17941    NM_BREAK16      = 0x02,
17942    NM_SDBBP16      = 0x03,
17943};
17944
17945/* POOL16C_0 instruction pool */
17946enum {
17947    NM_POOL16C_00      = 0x00,
17948};
17949
17950/* P16.JRC instruction pool */
17951enum {
17952    NM_JRC          = 0x00,
17953    NM_JALRC16      = 0x01,
17954};
17955
17956/* P.SYSCALL instruction pool */
17957enum {
17958    NM_SYSCALL      = 0x00,
17959    NM_HYPCALL      = 0x01,
17960};
17961
17962/* P.TRAP instruction pool */
17963enum {
17964    NM_TEQ          = 0x00,
17965    NM_TNE          = 0x01,
17966};
17967
17968/* P.CMOVE instruction pool */
17969enum {
17970    NM_MOVZ            = 0x00,
17971    NM_MOVN            = 0x01,
17972};
17973
17974/* POOL32Axf instruction pool */
17975enum {
17976    NM_POOL32AXF_1 = 0x01,
17977    NM_POOL32AXF_2 = 0x02,
17978    NM_POOL32AXF_4 = 0x04,
17979    NM_POOL32AXF_5 = 0x05,
17980    NM_POOL32AXF_7 = 0x07,
17981};
17982
17983/* POOL32Axf_1 instruction pool */
17984enum {
17985    NM_POOL32AXF_1_0 = 0x00,
17986    NM_POOL32AXF_1_1 = 0x01,
17987    NM_POOL32AXF_1_3 = 0x03,
17988    NM_POOL32AXF_1_4 = 0x04,
17989    NM_POOL32AXF_1_5 = 0x05,
17990    NM_POOL32AXF_1_7 = 0x07,
17991};
17992
17993/* POOL32Axf_2 instruction pool */
17994enum {
17995    NM_POOL32AXF_2_0_7     = 0x00,
17996    NM_POOL32AXF_2_8_15    = 0x01,
17997    NM_POOL32AXF_2_16_23   = 0x02,
17998    NM_POOL32AXF_2_24_31   = 0x03,
17999};
18000
18001/* POOL32Axf_7 instruction pool */
18002enum {
18003    NM_SHRA_R_QB    = 0x0,
18004    NM_SHRL_PH      = 0x1,
18005    NM_REPL_QB      = 0x2,
18006};
18007
18008/* POOL32Axf_1_0 instruction pool */
18009enum {
18010    NM_MFHI = 0x0,
18011    NM_MFLO = 0x1,
18012    NM_MTHI = 0x2,
18013    NM_MTLO = 0x3,
18014};
18015
18016/* POOL32Axf_1_1 instruction pool */
18017enum {
18018    NM_MTHLIP = 0x0,
18019    NM_SHILOV = 0x1,
18020};
18021
18022/* POOL32Axf_1_3 instruction pool */
18023enum {
18024    NM_RDDSP    = 0x0,
18025    NM_WRDSP    = 0x1,
18026    NM_EXTP     = 0x2,
18027    NM_EXTPDP   = 0x3,
18028};
18029
18030/* POOL32Axf_1_4 instruction pool */
18031enum {
18032    NM_SHLL_QB  = 0x0,
18033    NM_SHRL_QB  = 0x1,
18034};
18035
18036/* POOL32Axf_1_5 instruction pool */
18037enum {
18038    NM_MAQ_S_W_PHR   = 0x0,
18039    NM_MAQ_S_W_PHL   = 0x1,
18040    NM_MAQ_SA_W_PHR  = 0x2,
18041    NM_MAQ_SA_W_PHL  = 0x3,
18042};
18043
18044/* POOL32Axf_1_7 instruction pool */
18045enum {
18046    NM_EXTR_W       = 0x0,
18047    NM_EXTR_R_W     = 0x1,
18048    NM_EXTR_RS_W    = 0x2,
18049    NM_EXTR_S_H     = 0x3,
18050};
18051
18052/* POOL32Axf_2_0_7 instruction pool */
18053enum {
18054    NM_DPA_W_PH     = 0x0,
18055    NM_DPAQ_S_W_PH  = 0x1,
18056    NM_DPS_W_PH     = 0x2,
18057    NM_DPSQ_S_W_PH  = 0x3,
18058    NM_BALIGN       = 0x4,
18059    NM_MADD         = 0x5,
18060    NM_MULT         = 0x6,
18061    NM_EXTRV_W      = 0x7,
18062};
18063
18064/* POOL32Axf_2_8_15 instruction pool */
18065enum {
18066    NM_DPAX_W_PH    = 0x0,
18067    NM_DPAQ_SA_L_W  = 0x1,
18068    NM_DPSX_W_PH    = 0x2,
18069    NM_DPSQ_SA_L_W  = 0x3,
18070    NM_MADDU        = 0x5,
18071    NM_MULTU        = 0x6,
18072    NM_EXTRV_R_W    = 0x7,
18073};
18074
18075/* POOL32Axf_2_16_23 instruction pool */
18076enum {
18077    NM_DPAU_H_QBL       = 0x0,
18078    NM_DPAQX_S_W_PH     = 0x1,
18079    NM_DPSU_H_QBL       = 0x2,
18080    NM_DPSQX_S_W_PH     = 0x3,
18081    NM_EXTPV            = 0x4,
18082    NM_MSUB             = 0x5,
18083    NM_MULSA_W_PH       = 0x6,
18084    NM_EXTRV_RS_W       = 0x7,
18085};
18086
18087/* POOL32Axf_2_24_31 instruction pool */
18088enum {
18089    NM_DPAU_H_QBR       = 0x0,
18090    NM_DPAQX_SA_W_PH    = 0x1,
18091    NM_DPSU_H_QBR       = 0x2,
18092    NM_DPSQX_SA_W_PH    = 0x3,
18093    NM_EXTPDPV          = 0x4,
18094    NM_MSUBU            = 0x5,
18095    NM_MULSAQ_S_W_PH    = 0x6,
18096    NM_EXTRV_S_H        = 0x7,
18097};
18098
18099/* POOL32Axf_{4, 5} instruction pool */
18100enum {
18101    NM_CLO      = 0x25,
18102    NM_CLZ      = 0x2d,
18103
18104    NM_TLBP     = 0x01,
18105    NM_TLBR     = 0x09,
18106    NM_TLBWI    = 0x11,
18107    NM_TLBWR    = 0x19,
18108    NM_TLBINV   = 0x03,
18109    NM_TLBINVF  = 0x0b,
18110    NM_DI       = 0x23,
18111    NM_EI       = 0x2b,
18112    NM_RDPGPR   = 0x70,
18113    NM_WRPGPR   = 0x78,
18114    NM_WAIT     = 0x61,
18115    NM_DERET    = 0x71,
18116    NM_ERETX    = 0x79,
18117
18118    /* nanoMIPS DSP instructions */
18119    NM_ABSQ_S_QB        = 0x00,
18120    NM_ABSQ_S_PH        = 0x08,
18121    NM_ABSQ_S_W         = 0x10,
18122    NM_PRECEQ_W_PHL     = 0x28,
18123    NM_PRECEQ_W_PHR     = 0x30,
18124    NM_PRECEQU_PH_QBL   = 0x38,
18125    NM_PRECEQU_PH_QBR   = 0x48,
18126    NM_PRECEU_PH_QBL    = 0x58,
18127    NM_PRECEU_PH_QBR    = 0x68,
18128    NM_PRECEQU_PH_QBLA  = 0x39,
18129    NM_PRECEQU_PH_QBRA  = 0x49,
18130    NM_PRECEU_PH_QBLA   = 0x59,
18131    NM_PRECEU_PH_QBRA   = 0x69,
18132    NM_REPLV_PH         = 0x01,
18133    NM_REPLV_QB         = 0x09,
18134    NM_BITREV           = 0x18,
18135    NM_INSV             = 0x20,
18136    NM_RADDU_W_QB       = 0x78,
18137
18138    NM_BITSWAP          = 0x05,
18139    NM_WSBH             = 0x3d,
18140};
18141
18142/* PP.SR instruction pool */
18143enum {
18144    NM_SAVE         = 0x00,
18145    NM_RESTORE      = 0x02,
18146    NM_RESTORE_JRC  = 0x03,
18147};
18148
18149/* P.SR.F instruction pool */
18150enum {
18151    NM_SAVEF        = 0x00,
18152    NM_RESTOREF     = 0x01,
18153};
18154
18155/* P16.SYSCALL  instruction pool */
18156enum {
18157    NM_SYSCALL16     = 0x00,
18158    NM_HYPCALL16     = 0x01,
18159};
18160
18161/* POOL16C_00 instruction pool */
18162enum {
18163    NM_NOT16           = 0x00,
18164    NM_XOR16           = 0x01,
18165    NM_AND16           = 0x02,
18166    NM_OR16            = 0x03,
18167};
18168
18169/* PP.LSX and PP.LSXS instruction pool */
18170enum {
18171    NM_LBX      = 0x00,
18172    NM_LHX      = 0x04,
18173    NM_LWX      = 0x08,
18174    NM_LDX      = 0x0c,
18175
18176    NM_SBX      = 0x01,
18177    NM_SHX      = 0x05,
18178    NM_SWX      = 0x09,
18179    NM_SDX      = 0x0d,
18180
18181    NM_LBUX     = 0x02,
18182    NM_LHUX     = 0x06,
18183    NM_LWC1X    = 0x0a,
18184    NM_LDC1X    = 0x0e,
18185
18186    NM_LWUX     = 0x07,
18187    NM_SWC1X    = 0x0b,
18188    NM_SDC1X    = 0x0f,
18189
18190    NM_LHXS     = 0x04,
18191    NM_LWXS     = 0x08,
18192    NM_LDXS     = 0x0c,
18193
18194    NM_SHXS     = 0x05,
18195    NM_SWXS     = 0x09,
18196    NM_SDXS     = 0x0d,
18197
18198    NM_LHUXS    = 0x06,
18199    NM_LWC1XS   = 0x0a,
18200    NM_LDC1XS   = 0x0e,
18201
18202    NM_LWUXS    = 0x07,
18203    NM_SWC1XS   = 0x0b,
18204    NM_SDC1XS   = 0x0f,
18205};
18206
18207/* ERETx instruction pool */
18208enum {
18209    NM_ERET     = 0x00,
18210    NM_ERETNC   = 0x01,
18211};
18212
18213/* POOL32FxF_{0, 1} insturction pool */
18214enum {
18215    NM_CFC1     = 0x40,
18216    NM_CTC1     = 0x60,
18217    NM_MFC1     = 0x80,
18218    NM_MTC1     = 0xa0,
18219    NM_MFHC1    = 0xc0,
18220    NM_MTHC1    = 0xe0,
18221
18222    NM_CVT_S_PL = 0x84,
18223    NM_CVT_S_PU = 0xa4,
18224
18225    NM_CVT_L_S     = 0x004,
18226    NM_CVT_L_D     = 0x104,
18227    NM_CVT_W_S     = 0x024,
18228    NM_CVT_W_D     = 0x124,
18229
18230    NM_RSQRT_S     = 0x008,
18231    NM_RSQRT_D     = 0x108,
18232
18233    NM_SQRT_S      = 0x028,
18234    NM_SQRT_D      = 0x128,
18235
18236    NM_RECIP_S     = 0x048,
18237    NM_RECIP_D     = 0x148,
18238
18239    NM_FLOOR_L_S   = 0x00c,
18240    NM_FLOOR_L_D   = 0x10c,
18241
18242    NM_FLOOR_W_S   = 0x02c,
18243    NM_FLOOR_W_D   = 0x12c,
18244
18245    NM_CEIL_L_S    = 0x04c,
18246    NM_CEIL_L_D    = 0x14c,
18247    NM_CEIL_W_S    = 0x06c,
18248    NM_CEIL_W_D    = 0x16c,
18249    NM_TRUNC_L_S   = 0x08c,
18250    NM_TRUNC_L_D   = 0x18c,
18251    NM_TRUNC_W_S   = 0x0ac,
18252    NM_TRUNC_W_D   = 0x1ac,
18253    NM_ROUND_L_S   = 0x0cc,
18254    NM_ROUND_L_D   = 0x1cc,
18255    NM_ROUND_W_S   = 0x0ec,
18256    NM_ROUND_W_D   = 0x1ec,
18257
18258    NM_MOV_S       = 0x01,
18259    NM_MOV_D       = 0x81,
18260    NM_ABS_S       = 0x0d,
18261    NM_ABS_D       = 0x8d,
18262    NM_NEG_S       = 0x2d,
18263    NM_NEG_D       = 0xad,
18264    NM_CVT_D_S     = 0x04d,
18265    NM_CVT_D_W     = 0x0cd,
18266    NM_CVT_D_L     = 0x14d,
18267    NM_CVT_S_D     = 0x06d,
18268    NM_CVT_S_W     = 0x0ed,
18269    NM_CVT_S_L     = 0x16d,
18270};
18271
18272/* P.LL instruction pool */
18273enum {
18274    NM_LL       = 0x00,
18275    NM_LLWP     = 0x01,
18276};
18277
18278/* P.SC instruction pool */
18279enum {
18280    NM_SC       = 0x00,
18281    NM_SCWP     = 0x01,
18282};
18283
18284/* P.DVP instruction pool */
18285enum {
18286    NM_DVP      = 0x00,
18287    NM_EVP      = 0x01,
18288};
18289
18290
18291/*
18292 *
18293 * nanoMIPS decoding engine
18294 *
18295 */
18296
18297
18298/* extraction utilities */
18299
18300#define NANOMIPS_EXTRACT_RD(op) ((op >> 7) & 0x7)
18301#define NANOMIPS_EXTRACT_RS(op) ((op >> 4) & 0x7)
18302#define NANOMIPS_EXTRACT_RS2(op) uMIPS_RS(op)
18303#define NANOMIPS_EXTRACT_RS1(op) ((op >> 1) & 0x7)
18304#define NANOMIPS_EXTRACT_RD5(op) ((op >> 5) & 0x1f)
18305#define NANOMIPS_EXTRACT_RS5(op) (op & 0x1f)
18306
18307/* Implement nanoMIPS pseudocode decode_gpr(encoded_gpr, 'gpr3'). */
18308static inline int decode_gpr_gpr3(int r)
18309{
18310    static const int map[] = { 16, 17, 18, 19,  4,  5,  6,  7 };
18311
18312    return map[r & 0x7];
18313}
18314
18315/* Implement nanoMIPS pseudocode decode_gpr(encoded_gpr, 'gpr3.src.store'). */
18316static inline int decode_gpr_gpr3_src_store(int r)
18317{
18318    static const int map[] = {  0, 17, 18, 19,  4,  5,  6,  7 };
18319
18320    return map[r & 0x7];
18321}
18322
18323/* Implement nanoMIPS pseudocode decode_gpr(encoded_gpr, 'gpr4'). */
18324static inline int decode_gpr_gpr4(int r)
18325{
18326    static const int map[] = {  8,  9, 10, 11,  4,  5,  6,  7,
18327                               16, 17, 18, 19, 20, 21, 22, 23 };
18328
18329    return map[r & 0xf];
18330}
18331
18332/* Implement nanoMIPS pseudocode decode_gpr(encoded_gpr, 'gpr4.zero'). */
18333static inline int decode_gpr_gpr4_zero(int r)
18334{
18335    static const int map[] = {  8,  9, 10,  0,  4,  5,  6,  7,
18336                               16, 17, 18, 19, 20, 21, 22, 23 };
18337
18338    return map[r & 0xf];
18339}
18340
18341
18342/* extraction utilities */
18343
18344#define NANOMIPS_EXTRACT_RD(op) ((op >> 7) & 0x7)
18345#define NANOMIPS_EXTRACT_RS(op) ((op >> 4) & 0x7)
18346#define NANOMIPS_EXTRACT_RS2(op) uMIPS_RS(op)
18347#define NANOMIPS_EXTRACT_RS1(op) ((op >> 1) & 0x7)
18348#define NANOMIPS_EXTRACT_RD5(op) ((op >> 5) & 0x1f)
18349#define NANOMIPS_EXTRACT_RS5(op) (op & 0x1f)
18350
18351
18352static void gen_adjust_sp(DisasContext *ctx, int u)
18353{
18354    gen_op_addr_addi(ctx, cpu_gpr[29], cpu_gpr[29], u);
18355}
18356
18357static void gen_save(DisasContext *ctx, uint8_t rt, uint8_t count,
18358                     uint8_t gp, uint16_t u)
18359{
18360    int counter = 0;
18361    TCGv va = tcg_temp_new();
18362    TCGv t0 = tcg_temp_new();
18363
18364    while (counter != count) {
18365        bool use_gp = gp && (counter == count - 1);
18366        int this_rt = use_gp ? 28 : (rt & 0x10) | ((rt + counter) & 0x1f);
18367        int this_offset = -((counter + 1) << 2);
18368        gen_base_offset_addr(ctx, va, 29, this_offset);
18369        gen_load_gpr(t0, this_rt);
18370        tcg_gen_qemu_st_tl(t0, va, ctx->mem_idx,
18371                           (MO_TEUL | ctx->default_tcg_memop_mask));
18372        counter++;
18373    }
18374
18375    /* adjust stack pointer */
18376    gen_adjust_sp(ctx, -u);
18377
18378    tcg_temp_free(t0);
18379    tcg_temp_free(va);
18380}
18381
18382static void gen_restore(DisasContext *ctx, uint8_t rt, uint8_t count,
18383                        uint8_t gp, uint16_t u)
18384{
18385    int counter = 0;
18386    TCGv va = tcg_temp_new();
18387    TCGv t0 = tcg_temp_new();
18388
18389    while (counter != count) {
18390        bool use_gp = gp && (counter == count - 1);
18391        int this_rt = use_gp ? 28 : (rt & 0x10) | ((rt + counter) & 0x1f);
18392        int this_offset = u - ((counter + 1) << 2);
18393        gen_base_offset_addr(ctx, va, 29, this_offset);
18394        tcg_gen_qemu_ld_tl(t0, va, ctx->mem_idx, MO_TESL |
18395                        ctx->default_tcg_memop_mask);
18396        tcg_gen_ext32s_tl(t0, t0);
18397        gen_store_gpr(t0, this_rt);
18398        counter++;
18399    }
18400
18401    /* adjust stack pointer */
18402    gen_adjust_sp(ctx, u);
18403
18404    tcg_temp_free(t0);
18405    tcg_temp_free(va);
18406}
18407
18408static void gen_pool16c_nanomips_insn(DisasContext *ctx)
18409{
18410    int rt = decode_gpr_gpr3(NANOMIPS_EXTRACT_RD(ctx->opcode));
18411    int rs = decode_gpr_gpr3(NANOMIPS_EXTRACT_RS(ctx->opcode));
18412
18413    switch (extract32(ctx->opcode, 2, 2)) {
18414    case NM_NOT16:
18415        gen_logic(ctx, OPC_NOR, rt, rs, 0);
18416        break;
18417    case NM_AND16:
18418        gen_logic(ctx, OPC_AND, rt, rt, rs);
18419        break;
18420    case NM_XOR16:
18421        gen_logic(ctx, OPC_XOR, rt, rt, rs);
18422        break;
18423    case NM_OR16:
18424        gen_logic(ctx, OPC_OR, rt, rt, rs);
18425        break;
18426    }
18427}
18428
18429static void gen_pool32a0_nanomips_insn(CPUMIPSState *env, DisasContext *ctx)
18430{
18431    int rt = extract32(ctx->opcode, 21, 5);
18432    int rs = extract32(ctx->opcode, 16, 5);
18433    int rd = extract32(ctx->opcode, 11, 5);
18434
18435    switch (extract32(ctx->opcode, 3, 7)) {
18436    case NM_P_TRAP:
18437        switch (extract32(ctx->opcode, 10, 1)) {
18438        case NM_TEQ:
18439            check_nms(ctx);
18440            gen_trap(ctx, OPC_TEQ, rs, rt, -1);
18441            break;
18442        case NM_TNE:
18443            check_nms(ctx);
18444            gen_trap(ctx, OPC_TNE, rs, rt, -1);
18445            break;
18446        }
18447        break;
18448    case NM_RDHWR:
18449        check_nms(ctx);
18450        gen_rdhwr(ctx, rt, rs, extract32(ctx->opcode, 11, 3));
18451        break;
18452    case NM_SEB:
18453        check_nms(ctx);
18454        gen_bshfl(ctx, OPC_SEB, rs, rt);
18455        break;
18456    case NM_SEH:
18457        gen_bshfl(ctx, OPC_SEH, rs, rt);
18458        break;
18459    case NM_SLLV:
18460        gen_shift(ctx, OPC_SLLV, rd, rt, rs);
18461        break;
18462    case NM_SRLV:
18463        gen_shift(ctx, OPC_SRLV, rd, rt, rs);
18464        break;
18465    case NM_SRAV:
18466        gen_shift(ctx, OPC_SRAV, rd, rt, rs);
18467        break;
18468    case NM_ROTRV:
18469        gen_shift(ctx, OPC_ROTRV, rd, rt, rs);
18470        break;
18471    case NM_ADD:
18472        gen_arith(ctx, OPC_ADD, rd, rs, rt);
18473        break;
18474    case NM_ADDU:
18475        gen_arith(ctx, OPC_ADDU, rd, rs, rt);
18476        break;
18477    case NM_SUB:
18478        check_nms(ctx);
18479        gen_arith(ctx, OPC_SUB, rd, rs, rt);
18480        break;
18481    case NM_SUBU:
18482        gen_arith(ctx, OPC_SUBU, rd, rs, rt);
18483        break;
18484    case NM_P_CMOVE:
18485        switch (extract32(ctx->opcode, 10, 1)) {
18486        case NM_MOVZ:
18487            gen_cond_move(ctx, OPC_MOVZ, rd, rs, rt);
18488            break;
18489        case NM_MOVN:
18490            gen_cond_move(ctx, OPC_MOVN, rd, rs, rt);
18491            break;
18492        }
18493        break;
18494    case NM_AND:
18495        gen_logic(ctx, OPC_AND, rd, rs, rt);
18496        break;
18497    case NM_OR:
18498        gen_logic(ctx, OPC_OR, rd, rs, rt);
18499        break;
18500    case NM_NOR:
18501        gen_logic(ctx, OPC_NOR, rd, rs, rt);
18502        break;
18503    case NM_XOR:
18504        gen_logic(ctx, OPC_XOR, rd, rs, rt);
18505        break;
18506    case NM_SLT:
18507        gen_slt(ctx, OPC_SLT, rd, rs, rt);
18508        break;
18509    case NM_P_SLTU:
18510        if (rd == 0) {
18511            /* P_DVP */
18512#ifndef CONFIG_USER_ONLY
18513            TCGv t0 = tcg_temp_new();
18514            switch (extract32(ctx->opcode, 10, 1)) {
18515            case NM_DVP:
18516                if (ctx->vp) {
18517                    check_cp0_enabled(ctx);
18518                    gen_helper_dvp(t0, cpu_env);
18519                    gen_store_gpr(t0, rt);
18520                }
18521                break;
18522            case NM_EVP:
18523                if (ctx->vp) {
18524                    check_cp0_enabled(ctx);
18525                    gen_helper_evp(t0, cpu_env);
18526                    gen_store_gpr(t0, rt);
18527                }
18528                break;
18529            }
18530            tcg_temp_free(t0);
18531#endif
18532        } else {
18533            gen_slt(ctx, OPC_SLTU, rd, rs, rt);
18534        }
18535        break;
18536    case NM_SOV:
18537        {
18538            TCGv t0 = tcg_temp_new();
18539            TCGv t1 = tcg_temp_new();
18540            TCGv t2 = tcg_temp_new();
18541
18542            gen_load_gpr(t1, rs);
18543            gen_load_gpr(t2, rt);
18544            tcg_gen_add_tl(t0, t1, t2);
18545            tcg_gen_ext32s_tl(t0, t0);
18546            tcg_gen_xor_tl(t1, t1, t2);
18547            tcg_gen_xor_tl(t2, t0, t2);
18548            tcg_gen_andc_tl(t1, t2, t1);
18549
18550            /* operands of same sign, result different sign */
18551            tcg_gen_setcondi_tl(TCG_COND_LT, t0, t1, 0);
18552            gen_store_gpr(t0, rd);
18553
18554            tcg_temp_free(t0);
18555            tcg_temp_free(t1);
18556            tcg_temp_free(t2);
18557        }
18558        break;
18559    case NM_MUL:
18560        gen_r6_muldiv(ctx, R6_OPC_MUL, rd, rs, rt);
18561        break;
18562    case NM_MUH:
18563        gen_r6_muldiv(ctx, R6_OPC_MUH, rd, rs, rt);
18564        break;
18565    case NM_MULU:
18566        gen_r6_muldiv(ctx, R6_OPC_MULU, rd, rs, rt);
18567        break;
18568    case NM_MUHU:
18569        gen_r6_muldiv(ctx, R6_OPC_MUHU, rd, rs, rt);
18570        break;
18571    case NM_DIV:
18572        gen_r6_muldiv(ctx, R6_OPC_DIV, rd, rs, rt);
18573        break;
18574    case NM_MOD:
18575        gen_r6_muldiv(ctx, R6_OPC_MOD, rd, rs, rt);
18576        break;
18577    case NM_DIVU:
18578        gen_r6_muldiv(ctx, R6_OPC_DIVU, rd, rs, rt);
18579        break;
18580    case NM_MODU:
18581        gen_r6_muldiv(ctx, R6_OPC_MODU, rd, rs, rt);
18582        break;
18583#ifndef CONFIG_USER_ONLY
18584    case NM_MFC0:
18585        check_cp0_enabled(ctx);
18586        if (rt == 0) {
18587            /* Treat as NOP. */
18588            break;
18589        }
18590        gen_mfc0(ctx, cpu_gpr[rt], rs, extract32(ctx->opcode, 11, 3));
18591        break;
18592    case NM_MTC0:
18593        check_cp0_enabled(ctx);
18594        {
18595            TCGv t0 = tcg_temp_new();
18596
18597            gen_load_gpr(t0, rt);
18598            gen_mtc0(ctx, t0, rs, extract32(ctx->opcode, 11, 3));
18599            tcg_temp_free(t0);
18600        }
18601        break;
18602    case NM_D_E_MT_VPE:
18603        {
18604            uint8_t sc = extract32(ctx->opcode, 10, 1);
18605            TCGv t0 = tcg_temp_new();
18606
18607            switch (sc) {
18608            case 0:
18609                if (rs == 1) {
18610                    /* DMT */
18611                    check_cp0_mt(ctx);
18612                    gen_helper_dmt(t0);
18613                    gen_store_gpr(t0, rt);
18614                } else if (rs == 0) {
18615                    /* DVPE */
18616                    check_cp0_mt(ctx);
18617                    gen_helper_dvpe(t0, cpu_env);
18618                    gen_store_gpr(t0, rt);
18619                } else {
18620                    generate_exception_end(ctx, EXCP_RI);
18621                }
18622                break;
18623            case 1:
18624                if (rs == 1) {
18625                    /* EMT */
18626                    check_cp0_mt(ctx);
18627                    gen_helper_emt(t0);
18628                    gen_store_gpr(t0, rt);
18629                } else if (rs == 0) {
18630                    /* EVPE */
18631                    check_cp0_mt(ctx);
18632                    gen_helper_evpe(t0, cpu_env);
18633                    gen_store_gpr(t0, rt);
18634                } else {
18635                    generate_exception_end(ctx, EXCP_RI);
18636                }
18637                break;
18638            }
18639
18640            tcg_temp_free(t0);
18641        }
18642        break;
18643    case NM_FORK:
18644        check_mt(ctx);
18645        {
18646            TCGv t0 = tcg_temp_new();
18647            TCGv t1 = tcg_temp_new();
18648
18649            gen_load_gpr(t0, rt);
18650            gen_load_gpr(t1, rs);
18651            gen_helper_fork(t0, t1);
18652            tcg_temp_free(t0);
18653            tcg_temp_free(t1);
18654        }
18655        break;
18656    case NM_MFTR:
18657    case NM_MFHTR:
18658        check_cp0_enabled(ctx);
18659        if (rd == 0) {
18660            /* Treat as NOP. */
18661            return;
18662        }
18663        gen_mftr(env, ctx, rs, rt, extract32(ctx->opcode, 10, 1),
18664                 extract32(ctx->opcode, 11, 5), extract32(ctx->opcode, 3, 1));
18665        break;
18666    case NM_MTTR:
18667    case NM_MTHTR:
18668        check_cp0_enabled(ctx);
18669        gen_mttr(env, ctx, rs, rt, extract32(ctx->opcode, 10, 1),
18670                 extract32(ctx->opcode, 11, 5), extract32(ctx->opcode, 3, 1));
18671        break;
18672    case NM_YIELD:
18673        check_mt(ctx);
18674        {
18675            TCGv t0 = tcg_temp_new();
18676
18677            gen_load_gpr(t0, rs);
18678            gen_helper_yield(t0, cpu_env, t0);
18679            gen_store_gpr(t0, rt);
18680            tcg_temp_free(t0);
18681        }
18682        break;
18683#endif
18684    default:
18685        generate_exception_end(ctx, EXCP_RI);
18686        break;
18687    }
18688}
18689
18690/* dsp */
18691static void gen_pool32axf_1_5_nanomips_insn(DisasContext *ctx, uint32_t opc,
18692                                            int ret, int v1, int v2)
18693{
18694    TCGv_i32 t0;
18695    TCGv v0_t;
18696    TCGv v1_t;
18697
18698    t0 = tcg_temp_new_i32();
18699
18700    v0_t = tcg_temp_new();
18701    v1_t = tcg_temp_new();
18702
18703    tcg_gen_movi_i32(t0, v2 >> 3);
18704
18705    gen_load_gpr(v0_t, ret);
18706    gen_load_gpr(v1_t, v1);
18707
18708    switch (opc) {
18709    case NM_MAQ_S_W_PHR:
18710        check_dsp(ctx);
18711        gen_helper_maq_s_w_phr(t0, v1_t, v0_t, cpu_env);
18712        break;
18713    case NM_MAQ_S_W_PHL:
18714        check_dsp(ctx);
18715        gen_helper_maq_s_w_phl(t0, v1_t, v0_t, cpu_env);
18716        break;
18717    case NM_MAQ_SA_W_PHR:
18718        check_dsp(ctx);
18719        gen_helper_maq_sa_w_phr(t0, v1_t, v0_t, cpu_env);
18720        break;
18721    case NM_MAQ_SA_W_PHL:
18722        check_dsp(ctx);
18723        gen_helper_maq_sa_w_phl(t0, v1_t, v0_t, cpu_env);
18724        break;
18725    default:
18726        generate_exception_end(ctx, EXCP_RI);
18727        break;
18728    }
18729
18730    tcg_temp_free_i32(t0);
18731
18732    tcg_temp_free(v0_t);
18733    tcg_temp_free(v1_t);
18734}
18735
18736
18737static void gen_pool32axf_1_nanomips_insn(DisasContext *ctx, uint32_t opc,
18738                                    int ret, int v1, int v2)
18739{
18740    int16_t imm;
18741    TCGv t0 = tcg_temp_new();
18742    TCGv t1 = tcg_temp_new();
18743    TCGv v0_t = tcg_temp_new();
18744
18745    gen_load_gpr(v0_t, v1);
18746
18747    switch (opc) {
18748    case NM_POOL32AXF_1_0:
18749        check_dsp(ctx);
18750        switch (extract32(ctx->opcode, 12, 2)) {
18751        case NM_MFHI:
18752            gen_HILO(ctx, OPC_MFHI, v2 >> 3, ret);
18753            break;
18754        case NM_MFLO:
18755            gen_HILO(ctx, OPC_MFLO, v2 >> 3, ret);
18756            break;
18757        case NM_MTHI:
18758            gen_HILO(ctx, OPC_MTHI, v2 >> 3, v1);
18759            break;
18760        case NM_MTLO:
18761            gen_HILO(ctx, OPC_MTLO, v2 >> 3, v1);
18762            break;
18763        }
18764        break;
18765    case NM_POOL32AXF_1_1:
18766        check_dsp(ctx);
18767        switch (extract32(ctx->opcode, 12, 2)) {
18768        case NM_MTHLIP:
18769            tcg_gen_movi_tl(t0, v2);
18770            gen_helper_mthlip(t0, v0_t, cpu_env);
18771            break;
18772        case NM_SHILOV:
18773            tcg_gen_movi_tl(t0, v2 >> 3);
18774            gen_helper_shilo(t0, v0_t, cpu_env);
18775            break;
18776        default:
18777            generate_exception_end(ctx, EXCP_RI);
18778            break;
18779        }
18780        break;
18781    case NM_POOL32AXF_1_3:
18782        check_dsp(ctx);
18783        imm = extract32(ctx->opcode, 14, 7);
18784        switch (extract32(ctx->opcode, 12, 2)) {
18785        case NM_RDDSP:
18786            tcg_gen_movi_tl(t0, imm);
18787            gen_helper_rddsp(t0, t0, cpu_env);
18788            gen_store_gpr(t0, ret);
18789            break;
18790        case NM_WRDSP:
18791            gen_load_gpr(t0, ret);
18792            tcg_gen_movi_tl(t1, imm);
18793            gen_helper_wrdsp(t0, t1, cpu_env);
18794            break;
18795        case NM_EXTP:
18796            tcg_gen_movi_tl(t0, v2 >> 3);
18797            tcg_gen_movi_tl(t1, v1);
18798            gen_helper_extp(t0, t0, t1, cpu_env);
18799            gen_store_gpr(t0, ret);
18800            break;
18801        case NM_EXTPDP:
18802            tcg_gen_movi_tl(t0, v2 >> 3);
18803            tcg_gen_movi_tl(t1, v1);
18804            gen_helper_extpdp(t0, t0, t1, cpu_env);
18805            gen_store_gpr(t0, ret);
18806            break;
18807        }
18808        break;
18809    case NM_POOL32AXF_1_4:
18810        check_dsp(ctx);
18811        tcg_gen_movi_tl(t0, v2 >> 2);
18812        switch (extract32(ctx->opcode, 12, 1)) {
18813        case NM_SHLL_QB:
18814            gen_helper_shll_qb(t0, t0, v0_t, cpu_env);
18815            gen_store_gpr(t0, ret);
18816            break;
18817        case NM_SHRL_QB:
18818            gen_helper_shrl_qb(t0, t0, v0_t);
18819            gen_store_gpr(t0, ret);
18820            break;
18821        }
18822        break;
18823    case NM_POOL32AXF_1_5:
18824        opc = extract32(ctx->opcode, 12, 2);
18825        gen_pool32axf_1_5_nanomips_insn(ctx, opc, ret, v1, v2);
18826        break;
18827    case NM_POOL32AXF_1_7:
18828        check_dsp(ctx);
18829        tcg_gen_movi_tl(t0, v2 >> 3);
18830        tcg_gen_movi_tl(t1, v1);
18831        switch (extract32(ctx->opcode, 12, 2)) {
18832        case NM_EXTR_W:
18833            gen_helper_extr_w(t0, t0, t1, cpu_env);
18834            gen_store_gpr(t0, ret);
18835            break;
18836        case NM_EXTR_R_W:
18837            gen_helper_extr_r_w(t0, t0, t1, cpu_env);
18838            gen_store_gpr(t0, ret);
18839            break;
18840        case NM_EXTR_RS_W:
18841            gen_helper_extr_rs_w(t0, t0, t1, cpu_env);
18842            gen_store_gpr(t0, ret);
18843            break;
18844        case NM_EXTR_S_H:
18845            gen_helper_extr_s_h(t0, t0, t1, cpu_env);
18846            gen_store_gpr(t0, ret);
18847            break;
18848        }
18849        break;
18850    default:
18851        generate_exception_end(ctx, EXCP_RI);
18852        break;
18853    }
18854
18855    tcg_temp_free(t0);
18856    tcg_temp_free(t1);
18857    tcg_temp_free(v0_t);
18858}
18859
18860static void gen_pool32axf_2_multiply(DisasContext *ctx, uint32_t opc,
18861                                    TCGv v0, TCGv v1, int rd)
18862{
18863    TCGv_i32 t0;
18864
18865    t0 = tcg_temp_new_i32();
18866
18867    tcg_gen_movi_i32(t0, rd >> 3);
18868
18869    switch (opc) {
18870    case NM_POOL32AXF_2_0_7:
18871        switch (extract32(ctx->opcode, 9, 3)) {
18872        case NM_DPA_W_PH:
18873            check_dsp_r2(ctx);
18874            gen_helper_dpa_w_ph(t0, v1, v0, cpu_env);
18875            break;
18876        case NM_DPAQ_S_W_PH:
18877            check_dsp(ctx);
18878            gen_helper_dpaq_s_w_ph(t0, v1, v0, cpu_env);
18879            break;
18880        case NM_DPS_W_PH:
18881            check_dsp_r2(ctx);
18882            gen_helper_dps_w_ph(t0, v1, v0, cpu_env);
18883            break;
18884        case NM_DPSQ_S_W_PH:
18885            check_dsp(ctx);
18886            gen_helper_dpsq_s_w_ph(t0, v1, v0, cpu_env);
18887            break;
18888        default:
18889            generate_exception_end(ctx, EXCP_RI);
18890            break;
18891        }
18892        break;
18893    case NM_POOL32AXF_2_8_15:
18894        switch (extract32(ctx->opcode, 9, 3)) {
18895        case NM_DPAX_W_PH:
18896            check_dsp_r2(ctx);
18897            gen_helper_dpax_w_ph(t0, v0, v1, cpu_env);
18898            break;
18899        case NM_DPAQ_SA_L_W:
18900            check_dsp(ctx);
18901            gen_helper_dpaq_sa_l_w(t0, v0, v1, cpu_env);
18902            break;
18903        case NM_DPSX_W_PH:
18904            check_dsp_r2(ctx);
18905            gen_helper_dpsx_w_ph(t0, v0, v1, cpu_env);
18906            break;
18907        case NM_DPSQ_SA_L_W:
18908            check_dsp(ctx);
18909            gen_helper_dpsq_sa_l_w(t0, v0, v1, cpu_env);
18910            break;
18911        default:
18912            generate_exception_end(ctx, EXCP_RI);
18913            break;
18914        }
18915        break;
18916    case NM_POOL32AXF_2_16_23:
18917        switch (extract32(ctx->opcode, 9, 3)) {
18918        case NM_DPAU_H_QBL:
18919            check_dsp(ctx);
18920            gen_helper_dpau_h_qbl(t0, v0, v1, cpu_env);
18921            break;
18922        case NM_DPAQX_S_W_PH:
18923            check_dsp_r2(ctx);
18924            gen_helper_dpaqx_s_w_ph(t0, v0, v1, cpu_env);
18925            break;
18926        case NM_DPSU_H_QBL:
18927            check_dsp(ctx);
18928            gen_helper_dpsu_h_qbl(t0, v0, v1, cpu_env);
18929            break;
18930        case NM_DPSQX_S_W_PH:
18931            check_dsp_r2(ctx);
18932            gen_helper_dpsqx_s_w_ph(t0, v0, v1, cpu_env);
18933            break;
18934        case NM_MULSA_W_PH:
18935            check_dsp_r2(ctx);
18936            gen_helper_mulsa_w_ph(t0, v0, v1, cpu_env);
18937            break;
18938        default:
18939            generate_exception_end(ctx, EXCP_RI);
18940            break;
18941        }
18942        break;
18943    case NM_POOL32AXF_2_24_31:
18944        switch (extract32(ctx->opcode, 9, 3)) {
18945        case NM_DPAU_H_QBR:
18946            check_dsp(ctx);
18947            gen_helper_dpau_h_qbr(t0, v1, v0, cpu_env);
18948            break;
18949        case NM_DPAQX_SA_W_PH:
18950            check_dsp_r2(ctx);
18951            gen_helper_dpaqx_sa_w_ph(t0, v1, v0, cpu_env);
18952            break;
18953        case NM_DPSU_H_QBR:
18954            check_dsp(ctx);
18955            gen_helper_dpsu_h_qbr(t0, v1, v0, cpu_env);
18956            break;
18957        case NM_DPSQX_SA_W_PH:
18958            check_dsp_r2(ctx);
18959            gen_helper_dpsqx_sa_w_ph(t0, v1, v0, cpu_env);
18960            break;
18961        case NM_MULSAQ_S_W_PH:
18962            check_dsp(ctx);
18963            gen_helper_mulsaq_s_w_ph(t0, v1, v0, cpu_env);
18964            break;
18965        default:
18966            generate_exception_end(ctx, EXCP_RI);
18967            break;
18968        }
18969        break;
18970    default:
18971        generate_exception_end(ctx, EXCP_RI);
18972        break;
18973    }
18974
18975    tcg_temp_free_i32(t0);
18976}
18977
18978static void gen_pool32axf_2_nanomips_insn(DisasContext *ctx, uint32_t opc,
18979                                          int rt, int rs, int rd)
18980{
18981    int ret = rt;
18982    TCGv t0 = tcg_temp_new();
18983    TCGv t1 = tcg_temp_new();
18984    TCGv v0_t = tcg_temp_new();
18985    TCGv v1_t = tcg_temp_new();
18986
18987    gen_load_gpr(v0_t, rt);
18988    gen_load_gpr(v1_t, rs);
18989
18990    switch (opc) {
18991    case NM_POOL32AXF_2_0_7:
18992        switch (extract32(ctx->opcode, 9, 3)) {
18993        case NM_DPA_W_PH:
18994        case NM_DPAQ_S_W_PH:
18995        case NM_DPS_W_PH:
18996        case NM_DPSQ_S_W_PH:
18997            gen_pool32axf_2_multiply(ctx, opc, v0_t, v1_t, rd);
18998            break;
18999        case NM_BALIGN:
19000            check_dsp_r2(ctx);
19001            if (rt != 0) {
19002                gen_load_gpr(t0, rs);
19003                rd &= 3;
19004                if (rd != 0 && rd != 2) {
19005                    tcg_gen_shli_tl(cpu_gpr[ret], cpu_gpr[ret], 8 * rd);
19006                    tcg_gen_ext32u_tl(t0, t0);
19007                    tcg_gen_shri_tl(t0, t0, 8 * (4 - rd));
19008                    tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
19009                }
19010                tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]);
19011            }
19012            break;
19013        case NM_MADD:
19014            check_dsp(ctx);
19015            {
19016                int acc = extract32(ctx->opcode, 14, 2);
19017                TCGv_i64 t2 = tcg_temp_new_i64();
19018                TCGv_i64 t3 = tcg_temp_new_i64();
19019
19020                gen_load_gpr(t0, rt);
19021                gen_load_gpr(t1, rs);
19022                tcg_gen_ext_tl_i64(t2, t0);
19023                tcg_gen_ext_tl_i64(t3, t1);
19024                tcg_gen_mul_i64(t2, t2, t3);
19025                tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
19026                tcg_gen_add_i64(t2, t2, t3);
19027                tcg_temp_free_i64(t3);
19028                gen_move_low32(cpu_LO[acc], t2);
19029                gen_move_high32(cpu_HI[acc], t2);
19030                tcg_temp_free_i64(t2);
19031            }
19032            break;
19033        case NM_MULT:
19034            check_dsp(ctx);
19035            {
19036                int acc = extract32(ctx->opcode, 14, 2);
19037                TCGv_i32 t2 = tcg_temp_new_i32();
19038                TCGv_i32 t3 = tcg_temp_new_i32();
19039
19040                gen_load_gpr(t0, rs);
19041                gen_load_gpr(t1, rt);
19042                tcg_gen_trunc_tl_i32(t2, t0);
19043                tcg_gen_trunc_tl_i32(t3, t1);
19044                tcg_gen_muls2_i32(t2, t3, t2, t3);
19045                tcg_gen_ext_i32_tl(cpu_LO[acc], t2);
19046                tcg_gen_ext_i32_tl(cpu_HI[acc], t3);
19047                tcg_temp_free_i32(t2);
19048                tcg_temp_free_i32(t3);
19049            }
19050            break;
19051        case NM_EXTRV_W:
19052            check_dsp(ctx);
19053            gen_load_gpr(v1_t, rs);
19054            tcg_gen_movi_tl(t0, rd >> 3);
19055            gen_helper_extr_w(t0, t0, v1_t, cpu_env);
19056            gen_store_gpr(t0, ret);
19057            break;
19058        }
19059        break;
19060    case NM_POOL32AXF_2_8_15:
19061        switch (extract32(ctx->opcode, 9, 3)) {
19062        case NM_DPAX_W_PH:
19063        case NM_DPAQ_SA_L_W:
19064        case NM_DPSX_W_PH:
19065        case NM_DPSQ_SA_L_W:
19066            gen_pool32axf_2_multiply(ctx, opc, v0_t, v1_t, rd);
19067            break;
19068        case NM_MADDU:
19069            check_dsp(ctx);
19070            {
19071                int acc = extract32(ctx->opcode, 14, 2);
19072                TCGv_i64 t2 = tcg_temp_new_i64();
19073                TCGv_i64 t3 = tcg_temp_new_i64();
19074
19075                gen_load_gpr(t0, rs);
19076                gen_load_gpr(t1, rt);
19077                tcg_gen_ext32u_tl(t0, t0);
19078                tcg_gen_ext32u_tl(t1, t1);
19079                tcg_gen_extu_tl_i64(t2, t0);
19080                tcg_gen_extu_tl_i64(t3, t1);
19081                tcg_gen_mul_i64(t2, t2, t3);
19082                tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
19083                tcg_gen_add_i64(t2, t2, t3);
19084                tcg_temp_free_i64(t3);
19085                gen_move_low32(cpu_LO[acc], t2);
19086                gen_move_high32(cpu_HI[acc], t2);
19087                tcg_temp_free_i64(t2);
19088            }
19089            break;
19090        case NM_MULTU:
19091            check_dsp(ctx);
19092            {
19093                int acc = extract32(ctx->opcode, 14, 2);
19094                TCGv_i32 t2 = tcg_temp_new_i32();
19095                TCGv_i32 t3 = tcg_temp_new_i32();
19096
19097                gen_load_gpr(t0, rs);
19098                gen_load_gpr(t1, rt);
19099                tcg_gen_trunc_tl_i32(t2, t0);
19100                tcg_gen_trunc_tl_i32(t3, t1);
19101                tcg_gen_mulu2_i32(t2, t3, t2, t3);
19102                tcg_gen_ext_i32_tl(cpu_LO[acc], t2);
19103                tcg_gen_ext_i32_tl(cpu_HI[acc], t3);
19104                tcg_temp_free_i32(t2);
19105                tcg_temp_free_i32(t3);
19106            }
19107            break;
19108        case NM_EXTRV_R_W:
19109            check_dsp(ctx);
19110            tcg_gen_movi_tl(t0, rd >> 3);
19111            gen_helper_extr_r_w(t0, t0, v1_t, cpu_env);
19112            gen_store_gpr(t0, ret);
19113            break;
19114        default:
19115            generate_exception_end(ctx, EXCP_RI);
19116            break;
19117        }
19118        break;
19119    case NM_POOL32AXF_2_16_23:
19120        switch (extract32(ctx->opcode, 9, 3)) {
19121        case NM_DPAU_H_QBL:
19122        case NM_DPAQX_S_W_PH:
19123        case NM_DPSU_H_QBL:
19124        case NM_DPSQX_S_W_PH:
19125        case NM_MULSA_W_PH:
19126            gen_pool32axf_2_multiply(ctx, opc, v0_t, v1_t, rd);
19127            break;
19128        case NM_EXTPV:
19129            check_dsp(ctx);
19130            tcg_gen_movi_tl(t0, rd >> 3);
19131            gen_helper_extp(t0, t0, v1_t, cpu_env);
19132            gen_store_gpr(t0, ret);
19133            break;
19134        case NM_MSUB:
19135            check_dsp(ctx);
19136            {
19137                int acc = extract32(ctx->opcode, 14, 2);
19138                TCGv_i64 t2 = tcg_temp_new_i64();
19139                TCGv_i64 t3 = tcg_temp_new_i64();
19140
19141                gen_load_gpr(t0, rs);
19142                gen_load_gpr(t1, rt);
19143                tcg_gen_ext_tl_i64(t2, t0);
19144                tcg_gen_ext_tl_i64(t3, t1);
19145                tcg_gen_mul_i64(t2, t2, t3);
19146                tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
19147                tcg_gen_sub_i64(t2, t3, t2);
19148                tcg_temp_free_i64(t3);
19149                gen_move_low32(cpu_LO[acc], t2);
19150                gen_move_high32(cpu_HI[acc], t2);
19151                tcg_temp_free_i64(t2);
19152            }
19153            break;
19154        case NM_EXTRV_RS_W:
19155            check_dsp(ctx);
19156            tcg_gen_movi_tl(t0, rd >> 3);
19157            gen_helper_extr_rs_w(t0, t0, v1_t, cpu_env);
19158            gen_store_gpr(t0, ret);
19159            break;
19160        }
19161        break;
19162    case NM_POOL32AXF_2_24_31:
19163        switch (extract32(ctx->opcode, 9, 3)) {
19164        case NM_DPAU_H_QBR:
19165        case NM_DPAQX_SA_W_PH:
19166        case NM_DPSU_H_QBR:
19167        case NM_DPSQX_SA_W_PH:
19168        case NM_MULSAQ_S_W_PH:
19169            gen_pool32axf_2_multiply(ctx, opc, v0_t, v1_t, rd);
19170            break;
19171        case NM_EXTPDPV:
19172            check_dsp(ctx);
19173            tcg_gen_movi_tl(t0, rd >> 3);
19174            gen_helper_extpdp(t0, t0, v1_t, cpu_env);
19175            gen_store_gpr(t0, ret);
19176            break;
19177        case NM_MSUBU:
19178            check_dsp(ctx);
19179            {
19180                int acc = extract32(ctx->opcode, 14, 2);
19181                TCGv_i64 t2 = tcg_temp_new_i64();
19182                TCGv_i64 t3 = tcg_temp_new_i64();
19183
19184                gen_load_gpr(t0, rs);
19185                gen_load_gpr(t1, rt);
19186                tcg_gen_ext32u_tl(t0, t0);
19187                tcg_gen_ext32u_tl(t1, t1);
19188                tcg_gen_extu_tl_i64(t2, t0);
19189                tcg_gen_extu_tl_i64(t3, t1);
19190                tcg_gen_mul_i64(t2, t2, t3);
19191                tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
19192                tcg_gen_sub_i64(t2, t3, t2);
19193                tcg_temp_free_i64(t3);
19194                gen_move_low32(cpu_LO[acc], t2);
19195                gen_move_high32(cpu_HI[acc], t2);
19196                tcg_temp_free_i64(t2);
19197            }
19198            break;
19199        case NM_EXTRV_S_H:
19200            check_dsp(ctx);
19201            tcg_gen_movi_tl(t0, rd >> 3);
19202            gen_helper_extr_s_h(t0, t0, v0_t, cpu_env);
19203            gen_store_gpr(t0, ret);
19204            break;
19205        }
19206        break;
19207    default:
19208        generate_exception_end(ctx, EXCP_RI);
19209        break;
19210    }
19211
19212    tcg_temp_free(t0);
19213    tcg_temp_free(t1);
19214
19215    tcg_temp_free(v0_t);
19216    tcg_temp_free(v1_t);
19217}
19218
19219static void gen_pool32axf_4_nanomips_insn(DisasContext *ctx, uint32_t opc,
19220                                          int rt, int rs)
19221{
19222    int ret = rt;
19223    TCGv t0 = tcg_temp_new();
19224    TCGv v0_t = tcg_temp_new();
19225
19226    gen_load_gpr(v0_t, rs);
19227
19228    switch (opc) {
19229    case NM_ABSQ_S_QB:
19230        check_dsp_r2(ctx);
19231        gen_helper_absq_s_qb(v0_t, v0_t, cpu_env);
19232        gen_store_gpr(v0_t, ret);
19233        break;
19234    case NM_ABSQ_S_PH:
19235        check_dsp(ctx);
19236        gen_helper_absq_s_ph(v0_t, v0_t, cpu_env);
19237        gen_store_gpr(v0_t, ret);
19238        break;
19239    case NM_ABSQ_S_W:
19240        check_dsp(ctx);
19241        gen_helper_absq_s_w(v0_t, v0_t, cpu_env);
19242        gen_store_gpr(v0_t, ret);
19243        break;
19244    case NM_PRECEQ_W_PHL:
19245        check_dsp(ctx);
19246        tcg_gen_andi_tl(v0_t, v0_t, 0xFFFF0000);
19247        tcg_gen_ext32s_tl(v0_t, v0_t);
19248        gen_store_gpr(v0_t, ret);
19249        break;
19250    case NM_PRECEQ_W_PHR:
19251        check_dsp(ctx);
19252        tcg_gen_andi_tl(v0_t, v0_t, 0x0000FFFF);
19253        tcg_gen_shli_tl(v0_t, v0_t, 16);
19254        tcg_gen_ext32s_tl(v0_t, v0_t);
19255        gen_store_gpr(v0_t, ret);
19256        break;
19257    case NM_PRECEQU_PH_QBL:
19258        check_dsp(ctx);
19259        gen_helper_precequ_ph_qbl(v0_t, v0_t);
19260        gen_store_gpr(v0_t, ret);
19261        break;
19262    case NM_PRECEQU_PH_QBR:
19263        check_dsp(ctx);
19264        gen_helper_precequ_ph_qbr(v0_t, v0_t);
19265        gen_store_gpr(v0_t, ret);
19266        break;
19267    case NM_PRECEQU_PH_QBLA:
19268        check_dsp(ctx);
19269        gen_helper_precequ_ph_qbla(v0_t, v0_t);
19270        gen_store_gpr(v0_t, ret);
19271        break;
19272    case NM_PRECEQU_PH_QBRA:
19273        check_dsp(ctx);
19274        gen_helper_precequ_ph_qbra(v0_t, v0_t);
19275        gen_store_gpr(v0_t, ret);
19276        break;
19277    case NM_PRECEU_PH_QBL:
19278        check_dsp(ctx);
19279        gen_helper_preceu_ph_qbl(v0_t, v0_t);
19280        gen_store_gpr(v0_t, ret);
19281        break;
19282    case NM_PRECEU_PH_QBR:
19283        check_dsp(ctx);
19284        gen_helper_preceu_ph_qbr(v0_t, v0_t);
19285        gen_store_gpr(v0_t, ret);
19286        break;
19287    case NM_PRECEU_PH_QBLA:
19288        check_dsp(ctx);
19289        gen_helper_preceu_ph_qbla(v0_t, v0_t);
19290        gen_store_gpr(v0_t, ret);
19291        break;
19292    case NM_PRECEU_PH_QBRA:
19293        check_dsp(ctx);
19294        gen_helper_preceu_ph_qbra(v0_t, v0_t);
19295        gen_store_gpr(v0_t, ret);
19296        break;
19297    case NM_REPLV_PH:
19298        check_dsp(ctx);
19299        tcg_gen_ext16u_tl(v0_t, v0_t);
19300        tcg_gen_shli_tl(t0, v0_t, 16);
19301        tcg_gen_or_tl(v0_t, v0_t, t0);
19302        tcg_gen_ext32s_tl(v0_t, v0_t);
19303        gen_store_gpr(v0_t, ret);
19304        break;
19305    case NM_REPLV_QB:
19306        check_dsp(ctx);
19307        tcg_gen_ext8u_tl(v0_t, v0_t);
19308        tcg_gen_shli_tl(t0, v0_t, 8);
19309        tcg_gen_or_tl(v0_t, v0_t, t0);
19310        tcg_gen_shli_tl(t0, v0_t, 16);
19311        tcg_gen_or_tl(v0_t, v0_t, t0);
19312        tcg_gen_ext32s_tl(v0_t, v0_t);
19313        gen_store_gpr(v0_t, ret);
19314        break;
19315    case NM_BITREV:
19316        check_dsp(ctx);
19317        gen_helper_bitrev(v0_t, v0_t);
19318        gen_store_gpr(v0_t, ret);
19319        break;
19320    case NM_INSV:
19321        check_dsp(ctx);
19322        {
19323            TCGv tv0 = tcg_temp_new();
19324
19325            gen_load_gpr(tv0, rt);
19326            gen_helper_insv(v0_t, cpu_env, v0_t, tv0);
19327            gen_store_gpr(v0_t, ret);
19328            tcg_temp_free(tv0);
19329        }
19330        break;
19331    case NM_RADDU_W_QB:
19332        check_dsp(ctx);
19333        gen_helper_raddu_w_qb(v0_t, v0_t);
19334        gen_store_gpr(v0_t, ret);
19335        break;
19336    case NM_BITSWAP:
19337        gen_bitswap(ctx, OPC_BITSWAP, ret, rs);
19338        break;
19339    case NM_CLO:
19340        check_nms(ctx);
19341        gen_cl(ctx, OPC_CLO, ret, rs);
19342        break;
19343    case NM_CLZ:
19344        check_nms(ctx);
19345        gen_cl(ctx, OPC_CLZ, ret, rs);
19346        break;
19347    case NM_WSBH:
19348        gen_bshfl(ctx, OPC_WSBH, ret, rs);
19349        break;
19350    default:
19351        generate_exception_end(ctx, EXCP_RI);
19352        break;
19353    }
19354
19355    tcg_temp_free(v0_t);
19356    tcg_temp_free(t0);
19357}
19358
19359static void gen_pool32axf_7_nanomips_insn(DisasContext *ctx, uint32_t opc,
19360                                          int rt, int rs, int rd)
19361{
19362    TCGv t0 = tcg_temp_new();
19363    TCGv rs_t = tcg_temp_new();
19364
19365    gen_load_gpr(rs_t, rs);
19366
19367    switch (opc) {
19368    case NM_SHRA_R_QB:
19369        check_dsp_r2(ctx);
19370        tcg_gen_movi_tl(t0, rd >> 2);
19371        switch (extract32(ctx->opcode, 12, 1)) {
19372        case 0:
19373            /* NM_SHRA_QB */
19374            gen_helper_shra_qb(t0, t0, rs_t);
19375            gen_store_gpr(t0, rt);
19376            break;
19377        case 1:
19378            /* NM_SHRA_R_QB */
19379            gen_helper_shra_r_qb(t0, t0, rs_t);
19380            gen_store_gpr(t0, rt);
19381            break;
19382        }
19383        break;
19384    case NM_SHRL_PH:
19385        check_dsp_r2(ctx);
19386        tcg_gen_movi_tl(t0, rd >> 1);
19387        gen_helper_shrl_ph(t0, t0, rs_t);
19388        gen_store_gpr(t0, rt);
19389        break;
19390    case NM_REPL_QB:
19391        check_dsp(ctx);
19392        {
19393            int16_t imm;
19394            target_long result;
19395            imm = extract32(ctx->opcode, 13, 8);
19396            result = (uint32_t)imm << 24 |
19397                     (uint32_t)imm << 16 |
19398                     (uint32_t)imm << 8  |
19399                     (uint32_t)imm;
19400            result = (int32_t)result;
19401            tcg_gen_movi_tl(t0, result);
19402            gen_store_gpr(t0, rt);
19403        }
19404        break;
19405    default:
19406        generate_exception_end(ctx, EXCP_RI);
19407        break;
19408    }
19409    tcg_temp_free(t0);
19410    tcg_temp_free(rs_t);
19411}
19412
19413
19414static void gen_pool32axf_nanomips_insn(CPUMIPSState *env, DisasContext *ctx)
19415{
19416    int rt = extract32(ctx->opcode, 21, 5);
19417    int rs = extract32(ctx->opcode, 16, 5);
19418    int rd = extract32(ctx->opcode, 11, 5);
19419
19420    switch (extract32(ctx->opcode, 6, 3)) {
19421    case NM_POOL32AXF_1:
19422        {
19423            int32_t op1 = extract32(ctx->opcode, 9, 3);
19424            gen_pool32axf_1_nanomips_insn(ctx, op1, rt, rs, rd);
19425        }
19426        break;
19427    case NM_POOL32AXF_2:
19428        {
19429            int32_t op1 = extract32(ctx->opcode, 12, 2);
19430            gen_pool32axf_2_nanomips_insn(ctx, op1, rt, rs, rd);
19431        }
19432        break;
19433    case NM_POOL32AXF_4:
19434        {
19435            int32_t op1 = extract32(ctx->opcode, 9, 7);
19436            gen_pool32axf_4_nanomips_insn(ctx, op1, rt, rs);
19437        }
19438        break;
19439    case NM_POOL32AXF_5:
19440        switch (extract32(ctx->opcode, 9, 7)) {
19441#ifndef CONFIG_USER_ONLY
19442        case NM_TLBP:
19443            gen_cp0(env, ctx, OPC_TLBP, 0, 0);
19444            break;
19445        case NM_TLBR:
19446            gen_cp0(env, ctx, OPC_TLBR, 0, 0);
19447            break;
19448        case NM_TLBWI:
19449            gen_cp0(env, ctx, OPC_TLBWI, 0, 0);
19450            break;
19451        case NM_TLBWR:
19452            gen_cp0(env, ctx, OPC_TLBWR, 0, 0);
19453            break;
19454        case NM_TLBINV:
19455            gen_cp0(env, ctx, OPC_TLBINV, 0, 0);
19456            break;
19457        case NM_TLBINVF:
19458            gen_cp0(env, ctx, OPC_TLBINVF, 0, 0);
19459            break;
19460        case NM_DI:
19461            check_cp0_enabled(ctx);
19462            {
19463                TCGv t0 = tcg_temp_new();
19464
19465                save_cpu_state(ctx, 1);
19466                gen_helper_di(t0, cpu_env);
19467                gen_store_gpr(t0, rt);
19468            /* Stop translation as we may have switched the execution mode */
19469                ctx->base.is_jmp = DISAS_STOP;
19470                tcg_temp_free(t0);
19471            }
19472            break;
19473        case NM_EI:
19474            check_cp0_enabled(ctx);
19475            {
19476                TCGv t0 = tcg_temp_new();
19477
19478                save_cpu_state(ctx, 1);
19479                gen_helper_ei(t0, cpu_env);
19480                gen_store_gpr(t0, rt);
19481            /* Stop translation as we may have switched the execution mode */
19482                ctx->base.is_jmp = DISAS_STOP;
19483                tcg_temp_free(t0);
19484            }
19485            break;
19486        case NM_RDPGPR:
19487            gen_load_srsgpr(rs, rt);
19488            break;
19489        case NM_WRPGPR:
19490            gen_store_srsgpr(rs, rt);
19491            break;
19492        case NM_WAIT:
19493            gen_cp0(env, ctx, OPC_WAIT, 0, 0);
19494            break;
19495        case NM_DERET:
19496            gen_cp0(env, ctx, OPC_DERET, 0, 0);
19497            break;
19498        case NM_ERETX:
19499            gen_cp0(env, ctx, OPC_ERET, 0, 0);
19500            break;
19501#endif
19502        default:
19503            generate_exception_end(ctx, EXCP_RI);
19504            break;
19505        }
19506        break;
19507    case NM_POOL32AXF_7:
19508        {
19509            int32_t op1 = extract32(ctx->opcode, 9, 3);
19510            gen_pool32axf_7_nanomips_insn(ctx, op1, rt, rs, rd);
19511        }
19512        break;
19513    default:
19514        generate_exception_end(ctx, EXCP_RI);
19515        break;
19516    }
19517}
19518
19519/* Immediate Value Compact Branches */
19520static void gen_compute_imm_branch(DisasContext *ctx, uint32_t opc,
19521                                   int rt, int32_t imm, int32_t offset)
19522{
19523    TCGCond cond;
19524    int bcond_compute = 0;
19525    TCGv t0 = tcg_temp_new();
19526    TCGv t1 = tcg_temp_new();
19527
19528    gen_load_gpr(t0, rt);
19529    tcg_gen_movi_tl(t1, imm);
19530    ctx->btarget = addr_add(ctx, ctx->base.pc_next + 4, offset);
19531
19532    /* Load needed operands and calculate btarget */
19533    switch (opc) {
19534    case NM_BEQIC:
19535        if (rt == 0 && imm == 0) {
19536            /* Unconditional branch */
19537        } else if (rt == 0 && imm != 0) {
19538            /* Treat as NOP */
19539            goto out;
19540        } else {
19541            bcond_compute = 1;
19542            cond = TCG_COND_EQ;
19543        }
19544        break;
19545    case NM_BBEQZC:
19546    case NM_BBNEZC:
19547        check_nms(ctx);
19548        if (imm >= 32 && !(ctx->hflags & MIPS_HFLAG_64)) {
19549            generate_exception_end(ctx, EXCP_RI);
19550            goto out;
19551        } else if (rt == 0 && opc == NM_BBEQZC) {
19552            /* Unconditional branch */
19553        } else if (rt == 0 && opc == NM_BBNEZC) {
19554            /* Treat as NOP */
19555            goto out;
19556        } else {
19557            tcg_gen_shri_tl(t0, t0, imm);
19558            tcg_gen_andi_tl(t0, t0, 1);
19559            tcg_gen_movi_tl(t1, 0);
19560            bcond_compute = 1;
19561            if (opc == NM_BBEQZC) {
19562                cond = TCG_COND_EQ;
19563            } else {
19564                cond = TCG_COND_NE;
19565            }
19566        }
19567        break;
19568    case NM_BNEIC:
19569        if (rt == 0 && imm == 0) {
19570            /* Treat as NOP */
19571            goto out;
19572        } else if (rt == 0 && imm != 0) {
19573            /* Unconditional branch */
19574        } else {
19575            bcond_compute = 1;
19576            cond = TCG_COND_NE;
19577        }
19578        break;
19579    case NM_BGEIC:
19580        if (rt == 0 && imm == 0) {
19581            /* Unconditional branch */
19582        } else  {
19583            bcond_compute = 1;
19584            cond = TCG_COND_GE;
19585        }
19586        break;
19587    case NM_BLTIC:
19588        bcond_compute = 1;
19589        cond = TCG_COND_LT;
19590        break;
19591    case NM_BGEIUC:
19592        if (rt == 0 && imm == 0) {
19593            /* Unconditional branch */
19594        } else  {
19595            bcond_compute = 1;
19596            cond = TCG_COND_GEU;
19597        }
19598        break;
19599    case NM_BLTIUC:
19600        bcond_compute = 1;
19601        cond = TCG_COND_LTU;
19602        break;
19603    default:
19604        MIPS_INVAL("Immediate Value Compact branch");
19605        generate_exception_end(ctx, EXCP_RI);
19606        goto out;
19607    }
19608
19609    if (bcond_compute == 0) {
19610        /* Uncoditional compact branch */
19611        gen_goto_tb(ctx, 0, ctx->btarget);
19612    } else {
19613        /* Conditional compact branch */
19614        TCGLabel *fs = gen_new_label();
19615
19616        tcg_gen_brcond_tl(tcg_invert_cond(cond), t0, t1, fs);
19617
19618        gen_goto_tb(ctx, 1, ctx->btarget);
19619        gen_set_label(fs);
19620
19621        gen_goto_tb(ctx, 0, ctx->base.pc_next + 4);
19622    }
19623
19624out:
19625    tcg_temp_free(t0);
19626    tcg_temp_free(t1);
19627}
19628
19629/* P.BALRSC type nanoMIPS R6 branches: BALRSC and BRSC */
19630static void gen_compute_nanomips_pbalrsc_branch(DisasContext *ctx, int rs,
19631                                                int rt)
19632{
19633    TCGv t0 = tcg_temp_new();
19634    TCGv t1 = tcg_temp_new();
19635
19636    /* load rs */
19637    gen_load_gpr(t0, rs);
19638
19639    /* link */
19640    if (rt != 0) {
19641        tcg_gen_movi_tl(cpu_gpr[rt], ctx->base.pc_next + 4);
19642    }
19643
19644    /* calculate btarget */
19645    tcg_gen_shli_tl(t0, t0, 1);
19646    tcg_gen_movi_tl(t1, ctx->base.pc_next + 4);
19647    gen_op_addr_add(ctx, btarget, t1, t0);
19648
19649    /* unconditional branch to register */
19650    tcg_gen_mov_tl(cpu_PC, btarget);
19651    tcg_gen_lookup_and_goto_ptr();
19652
19653    tcg_temp_free(t0);
19654    tcg_temp_free(t1);
19655}
19656
19657/* nanoMIPS Branches */
19658static void gen_compute_compact_branch_nm(DisasContext *ctx, uint32_t opc,
19659                                       int rs, int rt, int32_t offset)
19660{
19661    int bcond_compute = 0;
19662    TCGv t0 = tcg_temp_new();
19663    TCGv t1 = tcg_temp_new();
19664
19665    /* Load needed operands and calculate btarget */
19666    switch (opc) {
19667    /* compact branch */
19668    case OPC_BGEC:
19669    case OPC_BLTC:
19670        gen_load_gpr(t0, rs);
19671        gen_load_gpr(t1, rt);
19672        bcond_compute = 1;
19673        ctx->btarget = addr_add(ctx, ctx->base.pc_next + 4, offset);
19674        break;
19675    case OPC_BGEUC:
19676    case OPC_BLTUC:
19677        if (rs == 0 || rs == rt) {
19678            /* OPC_BLEZALC, OPC_BGEZALC */
19679            /* OPC_BGTZALC, OPC_BLTZALC */
19680            tcg_gen_movi_tl(cpu_gpr[31], ctx->base.pc_next + 4);
19681        }
19682        gen_load_gpr(t0, rs);
19683        gen_load_gpr(t1, rt);
19684        bcond_compute = 1;
19685        ctx->btarget = addr_add(ctx, ctx->base.pc_next + 4, offset);
19686        break;
19687    case OPC_BC:
19688        ctx->btarget = addr_add(ctx, ctx->base.pc_next + 4, offset);
19689        break;
19690    case OPC_BEQZC:
19691        if (rs != 0) {
19692            /* OPC_BEQZC, OPC_BNEZC */
19693            gen_load_gpr(t0, rs);
19694            bcond_compute = 1;
19695            ctx->btarget = addr_add(ctx, ctx->base.pc_next + 4, offset);
19696        } else {
19697            /* OPC_JIC, OPC_JIALC */
19698            TCGv tbase = tcg_temp_new();
19699            TCGv toffset = tcg_temp_new();
19700
19701            gen_load_gpr(tbase, rt);
19702            tcg_gen_movi_tl(toffset, offset);
19703            gen_op_addr_add(ctx, btarget, tbase, toffset);
19704            tcg_temp_free(tbase);
19705            tcg_temp_free(toffset);
19706        }
19707        break;
19708    default:
19709        MIPS_INVAL("Compact branch/jump");
19710        generate_exception_end(ctx, EXCP_RI);
19711        goto out;
19712    }
19713
19714    if (bcond_compute == 0) {
19715        /* Uncoditional compact branch */
19716        switch (opc) {
19717        case OPC_BC:
19718            gen_goto_tb(ctx, 0, ctx->btarget);
19719            break;
19720        default:
19721            MIPS_INVAL("Compact branch/jump");
19722            generate_exception_end(ctx, EXCP_RI);
19723            goto out;
19724        }
19725    } else {
19726        /* Conditional compact branch */
19727        TCGLabel *fs = gen_new_label();
19728
19729        switch (opc) {
19730        case OPC_BGEUC:
19731            if (rs == 0 && rt != 0) {
19732                /* OPC_BLEZALC */
19733                tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LE), t1, 0, fs);
19734            } else if (rs != 0 && rt != 0 && rs == rt) {
19735                /* OPC_BGEZALC */
19736                tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GE), t1, 0, fs);
19737            } else {
19738                /* OPC_BGEUC */
19739                tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_GEU), t0, t1, fs);
19740            }
19741            break;
19742        case OPC_BLTUC:
19743            if (rs == 0 && rt != 0) {
19744                /* OPC_BGTZALC */
19745                tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GT), t1, 0, fs);
19746            } else if (rs != 0 && rt != 0 && rs == rt) {
19747                /* OPC_BLTZALC */
19748                tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LT), t1, 0, fs);
19749            } else {
19750                /* OPC_BLTUC */
19751                tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_LTU), t0, t1, fs);
19752            }
19753            break;
19754        case OPC_BGEC:
19755            if (rs == 0 && rt != 0) {
19756                /* OPC_BLEZC */
19757                tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LE), t1, 0, fs);
19758            } else if (rs != 0 && rt != 0 && rs == rt) {
19759                /* OPC_BGEZC */
19760                tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GE), t1, 0, fs);
19761            } else {
19762                /* OPC_BGEC */
19763                tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_GE), t0, t1, fs);
19764            }
19765            break;
19766        case OPC_BLTC:
19767            if (rs == 0 && rt != 0) {
19768                /* OPC_BGTZC */
19769                tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GT), t1, 0, fs);
19770            } else if (rs != 0 && rt != 0 && rs == rt) {
19771                /* OPC_BLTZC */
19772                tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LT), t1, 0, fs);
19773            } else {
19774                /* OPC_BLTC */
19775                tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_LT), t0, t1, fs);
19776            }
19777            break;
19778        case OPC_BEQZC:
19779            tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_EQ), t0, 0, fs);
19780            break;
19781        default:
19782            MIPS_INVAL("Compact conditional branch/jump");
19783            generate_exception_end(ctx, EXCP_RI);
19784            goto out;
19785        }
19786
19787        /* Generating branch here as compact branches don't have delay slot */
19788        gen_goto_tb(ctx, 1, ctx->btarget);
19789        gen_set_label(fs);
19790
19791        gen_goto_tb(ctx, 0, ctx->base.pc_next + 4);
19792    }
19793
19794out:
19795    tcg_temp_free(t0);
19796    tcg_temp_free(t1);
19797}
19798
19799
19800/* nanoMIPS CP1 Branches */
19801static void gen_compute_branch_cp1_nm(DisasContext *ctx, uint32_t op,
19802                                   int32_t ft, int32_t offset)
19803{
19804    target_ulong btarget;
19805    TCGv_i64 t0 = tcg_temp_new_i64();
19806
19807    gen_load_fpr64(ctx, t0, ft);
19808    tcg_gen_andi_i64(t0, t0, 1);
19809
19810    btarget = addr_add(ctx, ctx->base.pc_next + 4, offset);
19811
19812    switch (op) {
19813    case NM_BC1EQZC:
19814        tcg_gen_xori_i64(t0, t0, 1);
19815        ctx->hflags |= MIPS_HFLAG_BC;
19816        break;
19817    case NM_BC1NEZC:
19818        /* t0 already set */
19819        ctx->hflags |= MIPS_HFLAG_BC;
19820        break;
19821    default:
19822        MIPS_INVAL("cp1 cond branch");
19823        generate_exception_end(ctx, EXCP_RI);
19824        goto out;
19825    }
19826
19827    tcg_gen_trunc_i64_tl(bcond, t0);
19828
19829    ctx->btarget = btarget;
19830
19831out:
19832    tcg_temp_free_i64(t0);
19833}
19834
19835
19836static void gen_p_lsx(DisasContext *ctx, int rd, int rs, int rt)
19837{
19838    TCGv t0, t1;
19839    t0 = tcg_temp_new();
19840    t1 = tcg_temp_new();
19841
19842    gen_load_gpr(t0, rs);
19843    gen_load_gpr(t1, rt);
19844
19845    if ((extract32(ctx->opcode, 6, 1)) == 1) {
19846        /* PP.LSXS instructions require shifting */
19847        switch (extract32(ctx->opcode, 7, 4)) {
19848        case NM_SHXS:
19849            check_nms(ctx);
19850        case NM_LHXS:
19851        case NM_LHUXS:
19852            tcg_gen_shli_tl(t0, t0, 1);
19853            break;
19854        case NM_SWXS:
19855            check_nms(ctx);
19856        case NM_LWXS:
19857        case NM_LWC1XS:
19858        case NM_SWC1XS:
19859            tcg_gen_shli_tl(t0, t0, 2);
19860            break;
19861        case NM_LDC1XS:
19862        case NM_SDC1XS:
19863            tcg_gen_shli_tl(t0, t0, 3);
19864            break;
19865        }
19866    }
19867    gen_op_addr_add(ctx, t0, t0, t1);
19868
19869    switch (extract32(ctx->opcode, 7, 4)) {
19870    case NM_LBX:
19871        tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx,
19872                           MO_SB);
19873        gen_store_gpr(t0, rd);
19874        break;
19875    case NM_LHX:
19876    /*case NM_LHXS:*/
19877        tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx,
19878                           MO_TESW);
19879        gen_store_gpr(t0, rd);
19880        break;
19881    case NM_LWX:
19882    /*case NM_LWXS:*/
19883        tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx,
19884                           MO_TESL);
19885        gen_store_gpr(t0, rd);
19886        break;
19887    case NM_LBUX:
19888        tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx,
19889                           MO_UB);
19890        gen_store_gpr(t0, rd);
19891        break;
19892    case NM_LHUX:
19893    /*case NM_LHUXS:*/
19894        tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx,
19895                           MO_TEUW);
19896        gen_store_gpr(t0, rd);
19897        break;
19898    case NM_SBX:
19899        check_nms(ctx);
19900        gen_load_gpr(t1, rd);
19901        tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx,
19902                           MO_8);
19903        break;
19904    case NM_SHX:
19905    /*case NM_SHXS:*/
19906        check_nms(ctx);
19907        gen_load_gpr(t1, rd);
19908        tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx,
19909                           MO_TEUW);
19910        break;
19911    case NM_SWX:
19912    /*case NM_SWXS:*/
19913        check_nms(ctx);
19914        gen_load_gpr(t1, rd);
19915        tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx,
19916                           MO_TEUL);
19917        break;
19918    case NM_LWC1X:
19919    /*case NM_LWC1XS:*/
19920    case NM_LDC1X:
19921    /*case NM_LDC1XS:*/
19922    case NM_SWC1X:
19923    /*case NM_SWC1XS:*/
19924    case NM_SDC1X:
19925    /*case NM_SDC1XS:*/
19926        if (ctx->CP0_Config1 & (1 << CP0C1_FP)) {
19927            check_cp1_enabled(ctx);
19928            switch (extract32(ctx->opcode, 7, 4)) {
19929            case NM_LWC1X:
19930            /*case NM_LWC1XS:*/
19931                gen_flt_ldst(ctx, OPC_LWC1, rd, t0);
19932                break;
19933            case NM_LDC1X:
19934            /*case NM_LDC1XS:*/
19935                gen_flt_ldst(ctx, OPC_LDC1, rd, t0);
19936                break;
19937            case NM_SWC1X:
19938            /*case NM_SWC1XS:*/
19939                gen_flt_ldst(ctx, OPC_SWC1, rd, t0);
19940                break;
19941            case NM_SDC1X:
19942            /*case NM_SDC1XS:*/
19943                gen_flt_ldst(ctx, OPC_SDC1, rd, t0);
19944                break;
19945            }
19946        } else {
19947            generate_exception_err(ctx, EXCP_CpU, 1);
19948        }
19949        break;
19950    default:
19951        generate_exception_end(ctx, EXCP_RI);
19952        break;
19953    }
19954
19955    tcg_temp_free(t0);
19956    tcg_temp_free(t1);
19957}
19958
19959static void gen_pool32f_nanomips_insn(DisasContext *ctx)
19960{
19961    int rt, rs, rd;
19962
19963    rt = extract32(ctx->opcode, 21, 5);
19964    rs = extract32(ctx->opcode, 16, 5);
19965    rd = extract32(ctx->opcode, 11, 5);
19966
19967    if (!(ctx->CP0_Config1 & (1 << CP0C1_FP))) {
19968        generate_exception_end(ctx, EXCP_RI);
19969        return;
19970    }
19971    check_cp1_enabled(ctx);
19972    switch (extract32(ctx->opcode, 0, 3)) {
19973    case NM_POOL32F_0:
19974        switch (extract32(ctx->opcode, 3, 7)) {
19975        case NM_RINT_S:
19976            gen_farith(ctx, OPC_RINT_S, 0, rt, rs, 0);
19977            break;
19978        case NM_RINT_D:
19979            gen_farith(ctx, OPC_RINT_D, 0, rt, rs, 0);
19980            break;
19981        case NM_CLASS_S:
19982            gen_farith(ctx, OPC_CLASS_S, 0, rt, rs, 0);
19983            break;
19984        case NM_CLASS_D:
19985            gen_farith(ctx, OPC_CLASS_D, 0, rt, rs, 0);
19986            break;
19987        case NM_ADD_S:
19988            gen_farith(ctx, OPC_ADD_S, rt, rs, rd, 0);
19989            break;
19990        case NM_ADD_D:
19991            gen_farith(ctx, OPC_ADD_D, rt, rs, rd, 0);
19992            break;
19993        case NM_SUB_S:
19994            gen_farith(ctx, OPC_SUB_S, rt, rs, rd, 0);
19995            break;
19996        case NM_SUB_D:
19997            gen_farith(ctx, OPC_SUB_D, rt, rs, rd, 0);
19998            break;
19999        case NM_MUL_S:
20000            gen_farith(ctx, OPC_MUL_S, rt, rs, rd, 0);
20001            break;
20002        case NM_MUL_D:
20003            gen_farith(ctx, OPC_MUL_D, rt, rs, rd, 0);
20004            break;
20005        case NM_DIV_S:
20006            gen_farith(ctx, OPC_DIV_S, rt, rs, rd, 0);
20007            break;
20008        case NM_DIV_D:
20009            gen_farith(ctx, OPC_DIV_D, rt, rs, rd, 0);
20010            break;
20011        case NM_SELEQZ_S:
20012            gen_sel_s(ctx, OPC_SELEQZ_S, rd, rt, rs);
20013            break;
20014        case NM_SELEQZ_D:
20015            gen_sel_d(ctx, OPC_SELEQZ_D, rd, rt, rs);
20016            break;
20017        case NM_SELNEZ_S:
20018            gen_sel_s(ctx, OPC_SELNEZ_S, rd, rt, rs);
20019            break;
20020        case NM_SELNEZ_D:
20021            gen_sel_d(ctx, OPC_SELNEZ_D, rd, rt, rs);
20022            break;
20023        case NM_SEL_S:
20024            gen_sel_s(ctx, OPC_SEL_S, rd, rt, rs);
20025            break;
20026        case NM_SEL_D:
20027            gen_sel_d(ctx, OPC_SEL_D, rd, rt, rs);
20028            break;
20029        case NM_MADDF_S:
20030            gen_farith(ctx, OPC_MADDF_S, rt, rs, rd, 0);
20031            break;
20032        case NM_MADDF_D:
20033            gen_farith(ctx, OPC_MADDF_D, rt, rs, rd, 0);
20034            break;
20035        case NM_MSUBF_S:
20036            gen_farith(ctx, OPC_MSUBF_S, rt, rs, rd, 0);
20037            break;
20038        case NM_MSUBF_D:
20039            gen_farith(ctx, OPC_MSUBF_D, rt, rs, rd, 0);
20040            break;
20041        default:
20042            generate_exception_end(ctx, EXCP_RI);
20043            break;
20044        }
20045        break;
20046    case NM_POOL32F_3:
20047        switch (extract32(ctx->opcode, 3, 3)) {
20048        case NM_MIN_FMT:
20049            switch (extract32(ctx->opcode, 9, 1)) {
20050            case FMT_SDPS_S:
20051                gen_farith(ctx, OPC_MIN_S, rt, rs, rd, 0);
20052                break;
20053            case FMT_SDPS_D:
20054                gen_farith(ctx, OPC_MIN_D, rt, rs, rd, 0);
20055                break;
20056            }
20057            break;
20058        case NM_MAX_FMT:
20059            switch (extract32(ctx->opcode, 9, 1)) {
20060            case FMT_SDPS_S:
20061                gen_farith(ctx, OPC_MAX_S, rt, rs, rd, 0);
20062                break;
20063            case FMT_SDPS_D:
20064                gen_farith(ctx, OPC_MAX_D, rt, rs, rd, 0);
20065                break;
20066            }
20067            break;
20068        case NM_MINA_FMT:
20069            switch (extract32(ctx->opcode, 9, 1)) {
20070            case FMT_SDPS_S:
20071                gen_farith(ctx, OPC_MINA_S, rt, rs, rd, 0);
20072                break;
20073            case FMT_SDPS_D:
20074                gen_farith(ctx, OPC_MINA_D, rt, rs, rd, 0);
20075                break;
20076            }
20077            break;
20078        case NM_MAXA_FMT:
20079            switch (extract32(ctx->opcode, 9, 1)) {
20080            case FMT_SDPS_S:
20081                gen_farith(ctx, OPC_MAXA_S, rt, rs, rd, 0);
20082                break;
20083            case FMT_SDPS_D:
20084                gen_farith(ctx, OPC_MAXA_D, rt, rs, rd, 0);
20085                break;
20086            }
20087            break;
20088        case NM_POOL32FXF:
20089            switch (extract32(ctx->opcode, 6, 8)) {
20090            case NM_CFC1:
20091                gen_cp1(ctx, OPC_CFC1, rt, rs);
20092                break;
20093            case NM_CTC1:
20094                gen_cp1(ctx, OPC_CTC1, rt, rs);
20095                break;
20096            case NM_MFC1:
20097                gen_cp1(ctx, OPC_MFC1, rt, rs);
20098                break;
20099            case NM_MTC1:
20100                gen_cp1(ctx, OPC_MTC1, rt, rs);
20101                break;
20102            case NM_MFHC1:
20103                gen_cp1(ctx, OPC_MFHC1, rt, rs);
20104                break;
20105            case NM_MTHC1:
20106                gen_cp1(ctx, OPC_MTHC1, rt, rs);
20107                break;
20108            case NM_CVT_S_PL:
20109                gen_farith(ctx, OPC_CVT_S_PL, -1, rs, rt, 0);
20110                break;
20111            case NM_CVT_S_PU:
20112                gen_farith(ctx, OPC_CVT_S_PU, -1, rs, rt, 0);
20113                break;
20114            default:
20115                switch (extract32(ctx->opcode, 6, 9)) {
20116                case NM_CVT_L_S:
20117                    gen_farith(ctx, OPC_CVT_L_S, -1, rs, rt, 0);
20118                    break;
20119                case NM_CVT_L_D:
20120                    gen_farith(ctx, OPC_CVT_L_D, -1, rs, rt, 0);
20121                    break;
20122                case NM_CVT_W_S:
20123                    gen_farith(ctx, OPC_CVT_W_S, -1, rs, rt, 0);
20124                    break;
20125                case NM_CVT_W_D:
20126                    gen_farith(ctx, OPC_CVT_W_D, -1, rs, rt, 0);
20127                    break;
20128                case NM_RSQRT_S:
20129                    gen_farith(ctx, OPC_RSQRT_S, -1, rs, rt, 0);
20130                    break;
20131                case NM_RSQRT_D:
20132                    gen_farith(ctx, OPC_RSQRT_D, -1, rs, rt, 0);
20133                    break;
20134                case NM_SQRT_S:
20135                    gen_farith(ctx, OPC_SQRT_S, -1, rs, rt, 0);
20136                    break;
20137                case NM_SQRT_D:
20138                    gen_farith(ctx, OPC_SQRT_D, -1, rs, rt, 0);
20139                    break;
20140                case NM_RECIP_S:
20141                    gen_farith(ctx, OPC_RECIP_S, -1, rs, rt, 0);
20142                    break;
20143                case NM_RECIP_D:
20144                    gen_farith(ctx, OPC_RECIP_D, -1, rs, rt, 0);
20145                    break;
20146                case NM_FLOOR_L_S:
20147                    gen_farith(ctx, OPC_FLOOR_L_S, -1, rs, rt, 0);
20148                    break;
20149                case NM_FLOOR_L_D:
20150                    gen_farith(ctx, OPC_FLOOR_L_D, -1, rs, rt, 0);
20151                    break;
20152                case NM_FLOOR_W_S:
20153                    gen_farith(ctx, OPC_FLOOR_W_S, -1, rs, rt, 0);
20154                    break;
20155                case NM_FLOOR_W_D:
20156                    gen_farith(ctx, OPC_FLOOR_W_D, -1, rs, rt, 0);
20157                    break;
20158                case NM_CEIL_L_S:
20159                    gen_farith(ctx, OPC_CEIL_L_S, -1, rs, rt, 0);
20160                    break;
20161                case NM_CEIL_L_D:
20162                    gen_farith(ctx, OPC_CEIL_L_D, -1, rs, rt, 0);
20163                    break;
20164                case NM_CEIL_W_S:
20165                    gen_farith(ctx, OPC_CEIL_W_S, -1, rs, rt, 0);
20166                    break;
20167                case NM_CEIL_W_D:
20168                    gen_farith(ctx, OPC_CEIL_W_D, -1, rs, rt, 0);
20169                    break;
20170                case NM_TRUNC_L_S:
20171                    gen_farith(ctx, OPC_TRUNC_L_S, -1, rs, rt, 0);
20172                    break;
20173                case NM_TRUNC_L_D:
20174                    gen_farith(ctx, OPC_TRUNC_L_D, -1, rs, rt, 0);
20175                    break;
20176                case NM_TRUNC_W_S:
20177                    gen_farith(ctx, OPC_TRUNC_W_S, -1, rs, rt, 0);
20178                    break;
20179                case NM_TRUNC_W_D:
20180                    gen_farith(ctx, OPC_TRUNC_W_D, -1, rs, rt, 0);
20181                    break;
20182                case NM_ROUND_L_S:
20183                    gen_farith(ctx, OPC_ROUND_L_S, -1, rs, rt, 0);
20184                    break;
20185                case NM_ROUND_L_D:
20186                    gen_farith(ctx, OPC_ROUND_L_D, -1, rs, rt, 0);
20187                    break;
20188                case NM_ROUND_W_S:
20189                    gen_farith(ctx, OPC_ROUND_W_S, -1, rs, rt, 0);
20190                    break;
20191                case NM_ROUND_W_D:
20192                    gen_farith(ctx, OPC_ROUND_W_D, -1, rs, rt, 0);
20193                    break;
20194                case NM_MOV_S:
20195                    gen_farith(ctx, OPC_MOV_S, -1, rs, rt, 0);
20196                    break;
20197                case NM_MOV_D:
20198                    gen_farith(ctx, OPC_MOV_D, -1, rs, rt, 0);
20199                    break;
20200                case NM_ABS_S:
20201                    gen_farith(ctx, OPC_ABS_S, -1, rs, rt, 0);
20202                    break;
20203                case NM_ABS_D:
20204                    gen_farith(ctx, OPC_ABS_D, -1, rs, rt, 0);
20205                    break;
20206                case NM_NEG_S:
20207                    gen_farith(ctx, OPC_NEG_S, -1, rs, rt, 0);
20208                    break;
20209                case NM_NEG_D:
20210                    gen_farith(ctx, OPC_NEG_D, -1, rs, rt, 0);
20211                    break;
20212                case NM_CVT_D_S:
20213                    gen_farith(ctx, OPC_CVT_D_S, -1, rs, rt, 0);
20214                    break;
20215                case NM_CVT_D_W:
20216                    gen_farith(ctx, OPC_CVT_D_W, -1, rs, rt, 0);
20217                    break;
20218                case NM_CVT_D_L:
20219                    gen_farith(ctx, OPC_CVT_D_L, -1, rs, rt, 0);
20220                    break;
20221                case NM_CVT_S_D:
20222                    gen_farith(ctx, OPC_CVT_S_D, -1, rs, rt, 0);
20223                    break;
20224                case NM_CVT_S_W:
20225                    gen_farith(ctx, OPC_CVT_S_W, -1, rs, rt, 0);
20226                    break;
20227                case NM_CVT_S_L:
20228                    gen_farith(ctx, OPC_CVT_S_L, -1, rs, rt, 0);
20229                    break;
20230                default:
20231                    generate_exception_end(ctx, EXCP_RI);
20232                    break;
20233                }
20234                break;
20235            }
20236            break;
20237        }
20238        break;
20239    case NM_POOL32F_5:
20240        switch (extract32(ctx->opcode, 3, 3)) {
20241        case NM_CMP_CONDN_S:
20242            gen_r6_cmp_s(ctx, extract32(ctx->opcode, 6, 5), rt, rs, rd);
20243            break;
20244        case NM_CMP_CONDN_D:
20245            gen_r6_cmp_d(ctx, extract32(ctx->opcode, 6, 5), rt, rs, rd);
20246            break;
20247        default:
20248            generate_exception_end(ctx, EXCP_RI);
20249            break;
20250        }
20251        break;
20252    default:
20253        generate_exception_end(ctx, EXCP_RI);
20254        break;
20255    }
20256}
20257
20258static void gen_pool32a5_nanomips_insn(DisasContext *ctx, int opc,
20259                                       int rd, int rs, int rt)
20260{
20261    int ret = rd;
20262    TCGv t0 = tcg_temp_new();
20263    TCGv v1_t = tcg_temp_new();
20264    TCGv v2_t = tcg_temp_new();
20265
20266    gen_load_gpr(v1_t, rs);
20267    gen_load_gpr(v2_t, rt);
20268
20269    switch (opc) {
20270    case NM_CMP_EQ_PH:
20271        check_dsp(ctx);
20272        gen_helper_cmp_eq_ph(v1_t, v2_t, cpu_env);
20273        break;
20274    case NM_CMP_LT_PH:
20275        check_dsp(ctx);
20276        gen_helper_cmp_lt_ph(v1_t, v2_t, cpu_env);
20277        break;
20278    case NM_CMP_LE_PH:
20279        check_dsp(ctx);
20280        gen_helper_cmp_le_ph(v1_t, v2_t, cpu_env);
20281        break;
20282    case NM_CMPU_EQ_QB:
20283        check_dsp(ctx);
20284        gen_helper_cmpu_eq_qb(v1_t, v2_t, cpu_env);
20285        break;
20286    case NM_CMPU_LT_QB:
20287        check_dsp(ctx);
20288        gen_helper_cmpu_lt_qb(v1_t, v2_t, cpu_env);
20289        break;
20290    case NM_CMPU_LE_QB:
20291        check_dsp(ctx);
20292        gen_helper_cmpu_le_qb(v1_t, v2_t, cpu_env);
20293        break;
20294    case NM_CMPGU_EQ_QB:
20295        check_dsp(ctx);
20296        gen_helper_cmpgu_eq_qb(v1_t, v1_t, v2_t);
20297        gen_store_gpr(v1_t, ret);
20298        break;
20299    case NM_CMPGU_LT_QB:
20300        check_dsp(ctx);
20301        gen_helper_cmpgu_lt_qb(v1_t, v1_t, v2_t);
20302        gen_store_gpr(v1_t, ret);
20303        break;
20304    case NM_CMPGU_LE_QB:
20305        check_dsp(ctx);
20306        gen_helper_cmpgu_le_qb(v1_t, v1_t, v2_t);
20307        gen_store_gpr(v1_t, ret);
20308        break;
20309    case NM_CMPGDU_EQ_QB:
20310        check_dsp_r2(ctx);
20311        gen_helper_cmpgu_eq_qb(v1_t, v1_t, v2_t);
20312        tcg_gen_deposit_tl(cpu_dspctrl, cpu_dspctrl, v1_t, 24, 4);
20313        gen_store_gpr(v1_t, ret);
20314        break;
20315    case NM_CMPGDU_LT_QB:
20316        check_dsp_r2(ctx);
20317        gen_helper_cmpgu_lt_qb(v1_t, v1_t, v2_t);
20318        tcg_gen_deposit_tl(cpu_dspctrl, cpu_dspctrl, v1_t, 24, 4);
20319        gen_store_gpr(v1_t, ret);
20320        break;
20321    case NM_CMPGDU_LE_QB:
20322        check_dsp_r2(ctx);
20323        gen_helper_cmpgu_le_qb(v1_t, v1_t, v2_t);
20324        tcg_gen_deposit_tl(cpu_dspctrl, cpu_dspctrl, v1_t, 24, 4);
20325        gen_store_gpr(v1_t, ret);
20326        break;
20327    case NM_PACKRL_PH:
20328        check_dsp(ctx);
20329        gen_helper_packrl_ph(v1_t, v1_t, v2_t);
20330        gen_store_gpr(v1_t, ret);
20331        break;
20332    case NM_PICK_QB:
20333        check_dsp(ctx);
20334        gen_helper_pick_qb(v1_t, v1_t, v2_t, cpu_env);
20335        gen_store_gpr(v1_t, ret);
20336        break;
20337    case NM_PICK_PH:
20338        check_dsp(ctx);
20339        gen_helper_pick_ph(v1_t, v1_t, v2_t, cpu_env);
20340        gen_store_gpr(v1_t, ret);
20341        break;
20342    case NM_ADDQ_S_W:
20343        check_dsp(ctx);
20344        gen_helper_addq_s_w(v1_t, v1_t, v2_t, cpu_env);
20345        gen_store_gpr(v1_t, ret);
20346        break;
20347    case NM_SUBQ_S_W:
20348        check_dsp(ctx);
20349        gen_helper_subq_s_w(v1_t, v1_t, v2_t, cpu_env);
20350        gen_store_gpr(v1_t, ret);
20351        break;
20352    case NM_ADDSC:
20353        check_dsp(ctx);
20354        gen_helper_addsc(v1_t, v1_t, v2_t, cpu_env);
20355        gen_store_gpr(v1_t, ret);
20356        break;
20357    case NM_ADDWC:
20358        check_dsp(ctx);
20359        gen_helper_addwc(v1_t, v1_t, v2_t, cpu_env);
20360        gen_store_gpr(v1_t, ret);
20361        break;
20362    case NM_ADDQ_S_PH:
20363        check_dsp(ctx);
20364        switch (extract32(ctx->opcode, 10, 1)) {
20365        case 0:
20366            /* ADDQ_PH */
20367            gen_helper_addq_ph(v1_t, v1_t, v2_t, cpu_env);
20368            gen_store_gpr(v1_t, ret);
20369            break;
20370        case 1:
20371            /* ADDQ_S_PH */
20372            gen_helper_addq_s_ph(v1_t, v1_t, v2_t, cpu_env);
20373            gen_store_gpr(v1_t, ret);
20374            break;
20375        }
20376        break;
20377    case NM_ADDQH_R_PH:
20378        check_dsp_r2(ctx);
20379        switch (extract32(ctx->opcode, 10, 1)) {
20380        case 0:
20381            /* ADDQH_PH */
20382            gen_helper_addqh_ph(v1_t, v1_t, v2_t);
20383            gen_store_gpr(v1_t, ret);
20384            break;
20385        case 1:
20386            /* ADDQH_R_PH */
20387            gen_helper_addqh_r_ph(v1_t, v1_t, v2_t);
20388            gen_store_gpr(v1_t, ret);
20389            break;
20390        }
20391        break;
20392    case NM_ADDQH_R_W:
20393        check_dsp_r2(ctx);
20394        switch (extract32(ctx->opcode, 10, 1)) {
20395        case 0:
20396            /* ADDQH_W */
20397            gen_helper_addqh_w(v1_t, v1_t, v2_t);
20398            gen_store_gpr(v1_t, ret);
20399            break;
20400        case 1:
20401            /* ADDQH_R_W */
20402            gen_helper_addqh_r_w(v1_t, v1_t, v2_t);
20403            gen_store_gpr(v1_t, ret);
20404            break;
20405        }
20406        break;
20407    case NM_ADDU_S_QB:
20408        check_dsp(ctx);
20409        switch (extract32(ctx->opcode, 10, 1)) {
20410        case 0:
20411            /* ADDU_QB */
20412            gen_helper_addu_qb(v1_t, v1_t, v2_t, cpu_env);
20413            gen_store_gpr(v1_t, ret);
20414            break;
20415        case 1:
20416            /* ADDU_S_QB */
20417            gen_helper_addu_s_qb(v1_t, v1_t, v2_t, cpu_env);
20418            gen_store_gpr(v1_t, ret);
20419            break;
20420        }
20421        break;
20422    case NM_ADDU_S_PH:
20423        check_dsp_r2(ctx);
20424        switch (extract32(ctx->opcode, 10, 1)) {
20425        case 0:
20426            /* ADDU_PH */
20427            gen_helper_addu_ph(v1_t, v1_t, v2_t, cpu_env);
20428            gen_store_gpr(v1_t, ret);
20429            break;
20430        case 1:
20431            /* ADDU_S_PH */
20432            gen_helper_addu_s_ph(v1_t, v1_t, v2_t, cpu_env);
20433            gen_store_gpr(v1_t, ret);
20434            break;
20435        }
20436        break;
20437    case NM_ADDUH_R_QB:
20438        check_dsp_r2(ctx);
20439        switch (extract32(ctx->opcode, 10, 1)) {
20440        case 0:
20441            /* ADDUH_QB */
20442            gen_helper_adduh_qb(v1_t, v1_t, v2_t);
20443            gen_store_gpr(v1_t, ret);
20444            break;
20445        case 1:
20446            /* ADDUH_R_QB */
20447            gen_helper_adduh_r_qb(v1_t, v1_t, v2_t);
20448            gen_store_gpr(v1_t, ret);
20449            break;
20450        }
20451        break;
20452    case NM_SHRAV_R_PH:
20453        check_dsp(ctx);
20454        switch (extract32(ctx->opcode, 10, 1)) {
20455        case 0:
20456            /* SHRAV_PH */
20457            gen_helper_shra_ph(v1_t, v1_t, v2_t);
20458            gen_store_gpr(v1_t, ret);
20459            break;
20460        case 1:
20461            /* SHRAV_R_PH */
20462            gen_helper_shra_r_ph(v1_t, v1_t, v2_t);
20463            gen_store_gpr(v1_t, ret);
20464            break;
20465        }
20466        break;
20467    case NM_SHRAV_R_QB:
20468        check_dsp_r2(ctx);
20469        switch (extract32(ctx->opcode, 10, 1)) {
20470        case 0:
20471            /* SHRAV_QB */
20472            gen_helper_shra_qb(v1_t, v1_t, v2_t);
20473            gen_store_gpr(v1_t, ret);
20474            break;
20475        case 1:
20476            /* SHRAV_R_QB */
20477            gen_helper_shra_r_qb(v1_t, v1_t, v2_t);
20478            gen_store_gpr(v1_t, ret);
20479            break;
20480        }
20481        break;
20482    case NM_SUBQ_S_PH:
20483        check_dsp(ctx);
20484        switch (extract32(ctx->opcode, 10, 1)) {
20485        case 0:
20486            /* SUBQ_PH */
20487            gen_helper_subq_ph(v1_t, v1_t, v2_t, cpu_env);
20488            gen_store_gpr(v1_t, ret);
20489            break;
20490        case 1:
20491            /* SUBQ_S_PH */
20492            gen_helper_subq_s_ph(v1_t, v1_t, v2_t, cpu_env);
20493            gen_store_gpr(v1_t, ret);
20494            break;
20495        }
20496        break;
20497    case NM_SUBQH_R_PH:
20498        check_dsp_r2(ctx);
20499        switch (extract32(ctx->opcode, 10, 1)) {
20500        case 0:
20501            /* SUBQH_PH */
20502            gen_helper_subqh_ph(v1_t, v1_t, v2_t);
20503            gen_store_gpr(v1_t, ret);
20504            break;
20505        case 1:
20506            /* SUBQH_R_PH */
20507            gen_helper_subqh_r_ph(v1_t, v1_t, v2_t);
20508            gen_store_gpr(v1_t, ret);
20509            break;
20510        }
20511        break;
20512    case NM_SUBQH_R_W:
20513        check_dsp_r2(ctx);
20514        switch (extract32(ctx->opcode, 10, 1)) {
20515        case 0:
20516            /* SUBQH_W */
20517            gen_helper_subqh_w(v1_t, v1_t, v2_t);
20518            gen_store_gpr(v1_t, ret);
20519            break;
20520        case 1:
20521            /* SUBQH_R_W */
20522            gen_helper_subqh_r_w(v1_t, v1_t, v2_t);
20523            gen_store_gpr(v1_t, ret);
20524            break;
20525        }
20526        break;
20527    case NM_SUBU_S_QB:
20528        check_dsp(ctx);
20529        switch (extract32(ctx->opcode, 10, 1)) {
20530        case 0:
20531            /* SUBU_QB */
20532            gen_helper_subu_qb(v1_t, v1_t, v2_t, cpu_env);
20533            gen_store_gpr(v1_t, ret);
20534            break;
20535        case 1:
20536            /* SUBU_S_QB */
20537            gen_helper_subu_s_qb(v1_t, v1_t, v2_t, cpu_env);
20538            gen_store_gpr(v1_t, ret);
20539            break;
20540        }
20541        break;
20542    case NM_SUBU_S_PH:
20543        check_dsp_r2(ctx);
20544        switch (extract32(ctx->opcode, 10, 1)) {
20545        case 0:
20546            /* SUBU_PH */
20547            gen_helper_subu_ph(v1_t, v1_t, v2_t, cpu_env);
20548            gen_store_gpr(v1_t, ret);
20549            break;
20550        case 1:
20551            /* SUBU_S_PH */
20552            gen_helper_subu_s_ph(v1_t, v1_t, v2_t, cpu_env);
20553            gen_store_gpr(v1_t, ret);
20554            break;
20555        }
20556        break;
20557    case NM_SUBUH_R_QB:
20558        check_dsp_r2(ctx);
20559        switch (extract32(ctx->opcode, 10, 1)) {
20560        case 0:
20561            /* SUBUH_QB */
20562            gen_helper_subuh_qb(v1_t, v1_t, v2_t);
20563            gen_store_gpr(v1_t, ret);
20564            break;
20565        case 1:
20566            /* SUBUH_R_QB */
20567            gen_helper_subuh_r_qb(v1_t, v1_t, v2_t);
20568            gen_store_gpr(v1_t, ret);
20569            break;
20570        }
20571        break;
20572    case NM_SHLLV_S_PH:
20573        check_dsp(ctx);
20574        switch (extract32(ctx->opcode, 10, 1)) {
20575        case 0:
20576            /* SHLLV_PH */
20577            gen_helper_shll_ph(v1_t, v1_t, v2_t, cpu_env);
20578            gen_store_gpr(v1_t, ret);
20579            break;
20580        case 1:
20581            /* SHLLV_S_PH */
20582            gen_helper_shll_s_ph(v1_t, v1_t, v2_t, cpu_env);
20583            gen_store_gpr(v1_t, ret);
20584            break;
20585        }
20586        break;
20587    case NM_PRECR_SRA_R_PH_W:
20588        check_dsp_r2(ctx);
20589        switch (extract32(ctx->opcode, 10, 1)) {
20590        case 0:
20591            /* PRECR_SRA_PH_W */
20592            {
20593                TCGv_i32 sa_t = tcg_const_i32(rd);
20594                gen_helper_precr_sra_ph_w(v1_t, sa_t, v1_t,
20595                                          cpu_gpr[rt]);
20596                gen_store_gpr(v1_t, rt);
20597                tcg_temp_free_i32(sa_t);
20598            }
20599            break;
20600        case 1:
20601            /* PRECR_SRA_R_PH_W */
20602            {
20603                TCGv_i32 sa_t = tcg_const_i32(rd);
20604                gen_helper_precr_sra_r_ph_w(v1_t, sa_t, v1_t,
20605                                            cpu_gpr[rt]);
20606                gen_store_gpr(v1_t, rt);
20607                tcg_temp_free_i32(sa_t);
20608            }
20609            break;
20610       }
20611        break;
20612    case NM_MULEU_S_PH_QBL:
20613        check_dsp(ctx);
20614        gen_helper_muleu_s_ph_qbl(v1_t, v1_t, v2_t, cpu_env);
20615        gen_store_gpr(v1_t, ret);
20616        break;
20617    case NM_MULEU_S_PH_QBR:
20618        check_dsp(ctx);
20619        gen_helper_muleu_s_ph_qbr(v1_t, v1_t, v2_t, cpu_env);
20620        gen_store_gpr(v1_t, ret);
20621        break;
20622    case NM_MULQ_RS_PH:
20623        check_dsp(ctx);
20624        gen_helper_mulq_rs_ph(v1_t, v1_t, v2_t, cpu_env);
20625        gen_store_gpr(v1_t, ret);
20626        break;
20627    case NM_MULQ_S_PH:
20628        check_dsp_r2(ctx);
20629        gen_helper_mulq_s_ph(v1_t, v1_t, v2_t, cpu_env);
20630        gen_store_gpr(v1_t, ret);
20631        break;
20632    case NM_MULQ_RS_W:
20633        check_dsp_r2(ctx);
20634        gen_helper_mulq_rs_w(v1_t, v1_t, v2_t, cpu_env);
20635        gen_store_gpr(v1_t, ret);
20636        break;
20637    case NM_MULQ_S_W:
20638        check_dsp_r2(ctx);
20639        gen_helper_mulq_s_w(v1_t, v1_t, v2_t, cpu_env);
20640        gen_store_gpr(v1_t, ret);
20641        break;
20642    case NM_APPEND:
20643        check_dsp_r2(ctx);
20644        gen_load_gpr(t0, rs);
20645        if (rd != 0) {
20646            tcg_gen_deposit_tl(cpu_gpr[rt], t0, cpu_gpr[rt], rd, 32 - rd);
20647        }
20648        tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
20649        break;
20650    case NM_MODSUB:
20651        check_dsp(ctx);
20652        gen_helper_modsub(v1_t, v1_t, v2_t);
20653        gen_store_gpr(v1_t, ret);
20654        break;
20655    case NM_SHRAV_R_W:
20656        check_dsp(ctx);
20657        gen_helper_shra_r_w(v1_t, v1_t, v2_t);
20658        gen_store_gpr(v1_t, ret);
20659        break;
20660    case NM_SHRLV_PH:
20661        check_dsp_r2(ctx);
20662        gen_helper_shrl_ph(v1_t, v1_t, v2_t);
20663        gen_store_gpr(v1_t, ret);
20664        break;
20665    case NM_SHRLV_QB:
20666        check_dsp(ctx);
20667        gen_helper_shrl_qb(v1_t, v1_t, v2_t);
20668        gen_store_gpr(v1_t, ret);
20669        break;
20670    case NM_SHLLV_QB:
20671        check_dsp(ctx);
20672        gen_helper_shll_qb(v1_t, v1_t, v2_t, cpu_env);
20673        gen_store_gpr(v1_t, ret);
20674        break;
20675    case NM_SHLLV_S_W:
20676        check_dsp(ctx);
20677        gen_helper_shll_s_w(v1_t, v1_t, v2_t, cpu_env);
20678        gen_store_gpr(v1_t, ret);
20679        break;
20680    case NM_SHILO:
20681        check_dsp(ctx);
20682        {
20683            TCGv tv0 = tcg_temp_new();
20684            TCGv tv1 = tcg_temp_new();
20685            int16_t imm = extract32(ctx->opcode, 16, 7);
20686
20687            tcg_gen_movi_tl(tv0, rd >> 3);
20688            tcg_gen_movi_tl(tv1, imm);
20689            gen_helper_shilo(tv0, tv1, cpu_env);
20690        }
20691        break;
20692    case NM_MULEQ_S_W_PHL:
20693        check_dsp(ctx);
20694        gen_helper_muleq_s_w_phl(v1_t, v1_t, v2_t, cpu_env);
20695        gen_store_gpr(v1_t, ret);
20696        break;
20697    case NM_MULEQ_S_W_PHR:
20698        check_dsp(ctx);
20699        gen_helper_muleq_s_w_phr(v1_t, v1_t, v2_t, cpu_env);
20700        gen_store_gpr(v1_t, ret);
20701        break;
20702    case NM_MUL_S_PH:
20703        check_dsp_r2(ctx);
20704        switch (extract32(ctx->opcode, 10, 1)) {
20705        case 0:
20706            /* MUL_PH */
20707            gen_helper_mul_ph(v1_t, v1_t, v2_t, cpu_env);
20708            gen_store_gpr(v1_t, ret);
20709            break;
20710        case 1:
20711            /* MUL_S_PH */
20712            gen_helper_mul_s_ph(v1_t, v1_t, v2_t, cpu_env);
20713            gen_store_gpr(v1_t, ret);
20714            break;
20715        }
20716        break;
20717    case NM_PRECR_QB_PH:
20718        check_dsp_r2(ctx);
20719        gen_helper_precr_qb_ph(v1_t, v1_t, v2_t);
20720        gen_store_gpr(v1_t, ret);
20721        break;
20722    case NM_PRECRQ_QB_PH:
20723        check_dsp(ctx);
20724        gen_helper_precrq_qb_ph(v1_t, v1_t, v2_t);
20725        gen_store_gpr(v1_t, ret);
20726        break;
20727    case NM_PRECRQ_PH_W:
20728        check_dsp(ctx);
20729        gen_helper_precrq_ph_w(v1_t, v1_t, v2_t);
20730        gen_store_gpr(v1_t, ret);
20731        break;
20732    case NM_PRECRQ_RS_PH_W:
20733        check_dsp(ctx);
20734        gen_helper_precrq_rs_ph_w(v1_t, v1_t, v2_t, cpu_env);
20735        gen_store_gpr(v1_t, ret);
20736        break;
20737    case NM_PRECRQU_S_QB_PH:
20738        check_dsp(ctx);
20739        gen_helper_precrqu_s_qb_ph(v1_t, v1_t, v2_t, cpu_env);
20740        gen_store_gpr(v1_t, ret);
20741        break;
20742    case NM_SHRA_R_W:
20743        check_dsp(ctx);
20744        tcg_gen_movi_tl(t0, rd);
20745        gen_helper_shra_r_w(v1_t, t0, v1_t);
20746        gen_store_gpr(v1_t, rt);
20747        break;
20748    case NM_SHRA_R_PH:
20749        check_dsp(ctx);
20750        tcg_gen_movi_tl(t0, rd >> 1);
20751        switch (extract32(ctx->opcode, 10, 1)) {
20752        case 0:
20753            /* SHRA_PH */
20754            gen_helper_shra_ph(v1_t, t0, v1_t);
20755            gen_store_gpr(v1_t, rt);
20756            break;
20757        case 1:
20758            /* SHRA_R_PH */
20759            gen_helper_shra_r_ph(v1_t, t0, v1_t);
20760            gen_store_gpr(v1_t, rt);
20761            break;
20762        }
20763        break;
20764    case NM_SHLL_S_PH:
20765        check_dsp(ctx);
20766        tcg_gen_movi_tl(t0, rd >> 1);
20767        switch (extract32(ctx->opcode, 10, 2)) {
20768        case 0:
20769            /* SHLL_PH */
20770            gen_helper_shll_ph(v1_t, t0, v1_t, cpu_env);
20771            gen_store_gpr(v1_t, rt);
20772            break;
20773        case 2:
20774            /* SHLL_S_PH */
20775            gen_helper_shll_s_ph(v1_t, t0, v1_t, cpu_env);
20776            gen_store_gpr(v1_t, rt);
20777            break;
20778        default:
20779            generate_exception_end(ctx, EXCP_RI);
20780            break;
20781        }
20782        break;
20783    case NM_SHLL_S_W:
20784        check_dsp(ctx);
20785        tcg_gen_movi_tl(t0, rd);
20786        gen_helper_shll_s_w(v1_t, t0, v1_t, cpu_env);
20787        gen_store_gpr(v1_t, rt);
20788        break;
20789    case NM_REPL_PH:
20790        check_dsp(ctx);
20791        {
20792            int16_t imm;
20793            imm = sextract32(ctx->opcode, 11, 11);
20794            imm = (int16_t)(imm << 6) >> 6;
20795            if (rt != 0) {
20796                tcg_gen_movi_tl(cpu_gpr[rt], dup_const(MO_16, imm));
20797            }
20798        }
20799        break;
20800    default:
20801        generate_exception_end(ctx, EXCP_RI);
20802        break;
20803    }
20804}
20805
20806static int decode_nanomips_32_48_opc(CPUMIPSState *env, DisasContext *ctx)
20807{
20808    uint16_t insn;
20809    uint32_t op;
20810    int rt, rs, rd;
20811    int offset;
20812    int imm;
20813
20814    insn = cpu_lduw_code(env, ctx->base.pc_next + 2);
20815    ctx->opcode = (ctx->opcode << 16) | insn;
20816
20817    rt = extract32(ctx->opcode, 21, 5);
20818    rs = extract32(ctx->opcode, 16, 5);
20819    rd = extract32(ctx->opcode, 11, 5);
20820
20821    op = extract32(ctx->opcode, 26, 6);
20822    switch (op) {
20823    case NM_P_ADDIU:
20824        if (rt == 0) {
20825            /* P.RI */
20826            switch (extract32(ctx->opcode, 19, 2)) {
20827            case NM_SIGRIE:
20828            default:
20829                generate_exception_end(ctx, EXCP_RI);
20830                break;
20831            case NM_P_SYSCALL:
20832                if ((extract32(ctx->opcode, 18, 1)) == NM_SYSCALL) {
20833                    generate_exception_end(ctx, EXCP_SYSCALL);
20834                } else {
20835                    generate_exception_end(ctx, EXCP_RI);
20836                }
20837                break;
20838            case NM_BREAK:
20839                generate_exception_end(ctx, EXCP_BREAK);
20840                break;
20841            case NM_SDBBP:
20842                if (is_uhi(extract32(ctx->opcode, 0, 19))) {
20843                    gen_helper_do_semihosting(cpu_env);
20844                } else {
20845                    if (ctx->hflags & MIPS_HFLAG_SBRI) {
20846                        generate_exception_end(ctx, EXCP_RI);
20847                    } else {
20848                        generate_exception_end(ctx, EXCP_DBp);
20849                    }
20850                }
20851                break;
20852            }
20853        } else {
20854            /* NM_ADDIU */
20855            imm = extract32(ctx->opcode, 0, 16);
20856            if (rs != 0) {
20857                tcg_gen_addi_tl(cpu_gpr[rt], cpu_gpr[rs], imm);
20858            } else {
20859                tcg_gen_movi_tl(cpu_gpr[rt], imm);
20860            }
20861            tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
20862        }
20863        break;
20864    case NM_ADDIUPC:
20865        if (rt != 0) {
20866            offset = sextract32(ctx->opcode, 0, 1) << 21 |
20867                     extract32(ctx->opcode, 1, 20) << 1;
20868            target_long addr = addr_add(ctx, ctx->base.pc_next + 4, offset);
20869            tcg_gen_movi_tl(cpu_gpr[rt], addr);
20870        }
20871        break;
20872    case NM_POOL32A:
20873        switch (ctx->opcode & 0x07) {
20874        case NM_POOL32A0:
20875            gen_pool32a0_nanomips_insn(env, ctx);
20876            break;
20877        case NM_POOL32A5:
20878            {
20879                int32_t op1 = extract32(ctx->opcode, 3, 7);
20880                gen_pool32a5_nanomips_insn(ctx, op1, rd, rs, rt);
20881            }
20882            break;
20883        case NM_POOL32A7:
20884            switch (extract32(ctx->opcode, 3, 3)) {
20885            case NM_P_LSX:
20886                gen_p_lsx(ctx, rd, rs, rt);
20887                break;
20888            case NM_LSA:
20889                /* In nanoMIPS, the shift field directly encodes the shift
20890                 * amount, meaning that the supported shift values are in
20891                 * the range 0 to 3 (instead of 1 to 4 in MIPSR6). */
20892                gen_lsa(ctx, OPC_LSA, rd, rs, rt,
20893                        extract32(ctx->opcode, 9, 2) - 1);
20894                break;
20895            case NM_EXTW:
20896                gen_ext(ctx, 32, rd, rs, rt, extract32(ctx->opcode, 6, 5));
20897                break;
20898            case NM_POOL32AXF:
20899                gen_pool32axf_nanomips_insn(env, ctx);
20900                break;
20901            default:
20902                generate_exception_end(ctx, EXCP_RI);
20903                break;
20904            }
20905            break;
20906        default:
20907            generate_exception_end(ctx, EXCP_RI);
20908            break;
20909        }
20910        break;
20911    case NM_P_GP_W:
20912        switch (ctx->opcode & 0x03) {
20913        case NM_ADDIUGP_W:
20914            if (rt != 0) {
20915                offset = extract32(ctx->opcode, 0, 21);
20916                gen_op_addr_addi(ctx, cpu_gpr[rt], cpu_gpr[28], offset);
20917            }
20918            break;
20919        case NM_LWGP:
20920            gen_ld(ctx, OPC_LW, rt, 28, extract32(ctx->opcode, 2, 19) << 2);
20921            break;
20922        case NM_SWGP:
20923            gen_st(ctx, OPC_SW, rt, 28, extract32(ctx->opcode, 2, 19) << 2);
20924            break;
20925        default:
20926            generate_exception_end(ctx, EXCP_RI);
20927            break;
20928        }
20929        break;
20930    case NM_P48I:
20931        {
20932            insn = cpu_lduw_code(env, ctx->base.pc_next + 4);
20933            target_long addr_off = extract32(ctx->opcode, 0, 16) | insn << 16;
20934            switch (extract32(ctx->opcode, 16, 5)) {
20935            case NM_LI48:
20936                check_nms(ctx);
20937                if (rt != 0) {
20938                    tcg_gen_movi_tl(cpu_gpr[rt], addr_off);
20939                }
20940                break;
20941            case NM_ADDIU48:
20942                check_nms(ctx);
20943                if (rt != 0) {
20944                    tcg_gen_addi_tl(cpu_gpr[rt], cpu_gpr[rt], addr_off);
20945                    tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
20946                }
20947                break;
20948            case NM_ADDIUGP48:
20949                check_nms(ctx);
20950                if (rt != 0) {
20951                    gen_op_addr_addi(ctx, cpu_gpr[rt], cpu_gpr[28], addr_off);
20952                }
20953                break;
20954            case NM_ADDIUPC48:
20955                check_nms(ctx);
20956                if (rt != 0) {
20957                    target_long addr = addr_add(ctx, ctx->base.pc_next + 6,
20958                                                addr_off);
20959
20960                    tcg_gen_movi_tl(cpu_gpr[rt], addr);
20961                }
20962                break;
20963            case NM_LWPC48:
20964                check_nms(ctx);
20965                if (rt != 0) {
20966                    TCGv t0;
20967                    t0 = tcg_temp_new();
20968
20969                    target_long addr = addr_add(ctx, ctx->base.pc_next + 6,
20970                                                addr_off);
20971
20972                    tcg_gen_movi_tl(t0, addr);
20973                    tcg_gen_qemu_ld_tl(cpu_gpr[rt], t0, ctx->mem_idx, MO_TESL);
20974                    tcg_temp_free(t0);
20975                }
20976                break;
20977            case NM_SWPC48:
20978                check_nms(ctx);
20979                {
20980                    TCGv t0, t1;
20981                    t0 = tcg_temp_new();
20982                    t1 = tcg_temp_new();
20983
20984                    target_long addr = addr_add(ctx, ctx->base.pc_next + 6,
20985                                                addr_off);
20986
20987                    tcg_gen_movi_tl(t0, addr);
20988                    gen_load_gpr(t1, rt);
20989
20990                    tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL);
20991
20992                    tcg_temp_free(t0);
20993                    tcg_temp_free(t1);
20994                }
20995                break;
20996            default:
20997                generate_exception_end(ctx, EXCP_RI);
20998                break;
20999            }
21000            return 6;
21001        }
21002    case NM_P_U12:
21003        switch (extract32(ctx->opcode, 12, 4)) {
21004        case NM_ORI:
21005            gen_logic_imm(ctx, OPC_ORI, rt, rs, extract32(ctx->opcode, 0, 12));
21006            break;
21007        case NM_XORI:
21008            gen_logic_imm(ctx, OPC_XORI, rt, rs, extract32(ctx->opcode, 0, 12));
21009            break;
21010        case NM_ANDI:
21011            gen_logic_imm(ctx, OPC_ANDI, rt, rs, extract32(ctx->opcode, 0, 12));
21012            break;
21013        case NM_P_SR:
21014            switch (extract32(ctx->opcode, 20, 1)) {
21015            case NM_PP_SR:
21016                switch (ctx->opcode & 3) {
21017                case NM_SAVE:
21018                    gen_save(ctx, rt, extract32(ctx->opcode, 16, 4),
21019                             extract32(ctx->opcode, 2, 1),
21020                             extract32(ctx->opcode, 3, 9) << 3);
21021                    break;
21022                case NM_RESTORE:
21023                case NM_RESTORE_JRC:
21024                    gen_restore(ctx, rt, extract32(ctx->opcode, 16, 4),
21025                                extract32(ctx->opcode, 2, 1),
21026                                extract32(ctx->opcode, 3, 9) << 3);
21027                    if ((ctx->opcode & 3) == NM_RESTORE_JRC) {
21028                        gen_compute_branch_nm(ctx, OPC_JR, 2, 31, 0, 0);
21029                    }
21030                    break;
21031                default:
21032                    generate_exception_end(ctx, EXCP_RI);
21033                    break;
21034                }
21035                break;
21036            case NM_P_SR_F:
21037                generate_exception_end(ctx, EXCP_RI);
21038                break;
21039            }
21040            break;
21041        case NM_SLTI:
21042            gen_slt_imm(ctx, OPC_SLTI, rt, rs, extract32(ctx->opcode, 0, 12));
21043            break;
21044        case NM_SLTIU:
21045            gen_slt_imm(ctx, OPC_SLTIU, rt, rs, extract32(ctx->opcode, 0, 12));
21046            break;
21047        case NM_SEQI:
21048            {
21049                TCGv t0 = tcg_temp_new();
21050
21051                imm = extract32(ctx->opcode, 0, 12);
21052                gen_load_gpr(t0, rs);
21053                tcg_gen_setcondi_tl(TCG_COND_EQ, t0, t0, imm);
21054                gen_store_gpr(t0, rt);
21055
21056                tcg_temp_free(t0);
21057            }
21058            break;
21059        case NM_ADDIUNEG:
21060            imm = (int16_t) extract32(ctx->opcode, 0, 12);
21061            gen_arith_imm(ctx, OPC_ADDIU, rt, rs, -imm);
21062            break;
21063        case NM_P_SHIFT:
21064            {
21065                int shift = extract32(ctx->opcode, 0, 5);
21066                switch (extract32(ctx->opcode, 5, 4)) {
21067                case NM_P_SLL:
21068                    if (rt == 0 && shift == 0) {
21069                        /* NOP */
21070                    } else if (rt == 0 && shift == 3) {
21071                        /* EHB - treat as NOP */
21072                    } else if (rt == 0 && shift == 5) {
21073                        /* PAUSE - treat as NOP */
21074                    } else if (rt == 0 && shift == 6) {
21075                        /* SYNC */
21076                        gen_sync(extract32(ctx->opcode, 16, 5));
21077                    } else {
21078                        /* SLL */
21079                        gen_shift_imm(ctx, OPC_SLL, rt, rs,
21080                                      extract32(ctx->opcode, 0, 5));
21081                    }
21082                    break;
21083                case NM_SRL:
21084                    gen_shift_imm(ctx, OPC_SRL, rt, rs,
21085                                  extract32(ctx->opcode, 0, 5));
21086                    break;
21087                case NM_SRA:
21088                    gen_shift_imm(ctx, OPC_SRA, rt, rs,
21089                                  extract32(ctx->opcode, 0, 5));
21090                    break;
21091                case NM_ROTR:
21092                    gen_shift_imm(ctx, OPC_ROTR, rt, rs,
21093                                  extract32(ctx->opcode, 0, 5));
21094                    break;
21095                }
21096            }
21097            break;
21098        case NM_P_ROTX:
21099            check_nms(ctx);
21100            if (rt != 0) {
21101                TCGv t0 = tcg_temp_new();
21102                TCGv_i32 shift = tcg_const_i32(extract32(ctx->opcode, 0, 5));
21103                TCGv_i32 shiftx = tcg_const_i32(extract32(ctx->opcode, 7, 4)
21104                                                << 1);
21105                TCGv_i32 stripe = tcg_const_i32(extract32(ctx->opcode, 6, 1));
21106
21107                gen_load_gpr(t0, rs);
21108                gen_helper_rotx(cpu_gpr[rt], t0, shift, shiftx, stripe);
21109                tcg_temp_free(t0);
21110
21111                tcg_temp_free_i32(shift);
21112                tcg_temp_free_i32(shiftx);
21113                tcg_temp_free_i32(stripe);
21114            }
21115            break;
21116        case NM_P_INS:
21117            switch (((ctx->opcode >> 10) & 2) |
21118                    (extract32(ctx->opcode, 5, 1))) {
21119            case NM_INS:
21120                check_nms(ctx);
21121                gen_bitops(ctx, OPC_INS, rt, rs, extract32(ctx->opcode, 0, 5),
21122                           extract32(ctx->opcode, 6, 5));
21123                break;
21124            default:
21125                generate_exception_end(ctx, EXCP_RI);
21126                break;
21127            }
21128            break;
21129        case NM_P_EXT:
21130            switch (((ctx->opcode >> 10) & 2) |
21131                    (extract32(ctx->opcode, 5, 1))) {
21132            case NM_EXT:
21133                check_nms(ctx);
21134                gen_bitops(ctx, OPC_EXT, rt, rs, extract32(ctx->opcode, 0, 5),
21135                           extract32(ctx->opcode, 6, 5));
21136                break;
21137            default:
21138                generate_exception_end(ctx, EXCP_RI);
21139                break;
21140            }
21141            break;
21142        default:
21143            generate_exception_end(ctx, EXCP_RI);
21144            break;
21145        }
21146        break;
21147    case NM_POOL32F:
21148        gen_pool32f_nanomips_insn(ctx);
21149        break;
21150    case NM_POOL32S:
21151        break;
21152    case NM_P_LUI:
21153        switch (extract32(ctx->opcode, 1, 1)) {
21154        case NM_LUI:
21155            if (rt != 0) {
21156                tcg_gen_movi_tl(cpu_gpr[rt],
21157                                sextract32(ctx->opcode, 0, 1) << 31 |
21158                                extract32(ctx->opcode, 2, 10) << 21 |
21159                                extract32(ctx->opcode, 12, 9) << 12);
21160            }
21161            break;
21162        case NM_ALUIPC:
21163            if (rt != 0) {
21164                offset = sextract32(ctx->opcode, 0, 1) << 31 |
21165                         extract32(ctx->opcode, 2, 10) << 21 |
21166                         extract32(ctx->opcode, 12, 9) << 12;
21167                target_long addr;
21168                addr = ~0xFFF & addr_add(ctx, ctx->base.pc_next + 4, offset);
21169                tcg_gen_movi_tl(cpu_gpr[rt], addr);
21170            }
21171            break;
21172        }
21173        break;
21174    case NM_P_GP_BH:
21175        {
21176            uint32_t u = extract32(ctx->opcode, 0, 18);
21177
21178            switch (extract32(ctx->opcode, 18, 3)) {
21179            case NM_LBGP:
21180                gen_ld(ctx, OPC_LB, rt, 28, u);
21181                break;
21182            case NM_SBGP:
21183                gen_st(ctx, OPC_SB, rt, 28, u);
21184                break;
21185            case NM_LBUGP:
21186                gen_ld(ctx, OPC_LBU, rt, 28, u);
21187                break;
21188            case NM_ADDIUGP_B:
21189                if (rt != 0) {
21190                    gen_op_addr_addi(ctx, cpu_gpr[rt], cpu_gpr[28], u);
21191                }
21192                break;
21193            case NM_P_GP_LH:
21194                u &= ~1;
21195                switch (ctx->opcode & 1) {
21196                case NM_LHGP:
21197                    gen_ld(ctx, OPC_LH, rt, 28, u);
21198                    break;
21199                case NM_LHUGP:
21200                    gen_ld(ctx, OPC_LHU, rt, 28, u);
21201                    break;
21202                }
21203                break;
21204            case NM_P_GP_SH:
21205                u &= ~1;
21206                switch (ctx->opcode & 1) {
21207                case NM_SHGP:
21208                    gen_st(ctx, OPC_SH, rt, 28, u);
21209                    break;
21210                default:
21211                    generate_exception_end(ctx, EXCP_RI);
21212                    break;
21213                }
21214                break;
21215            case NM_P_GP_CP1:
21216                u &= ~0x3;
21217                switch (ctx->opcode & 0x3) {
21218                case NM_LWC1GP:
21219                    gen_cop1_ldst(ctx, OPC_LWC1, rt, 28, u);
21220                    break;
21221                case NM_LDC1GP:
21222                    gen_cop1_ldst(ctx, OPC_LDC1, rt, 28, u);
21223                    break;
21224                case NM_SWC1GP:
21225                    gen_cop1_ldst(ctx, OPC_SWC1, rt, 28, u);
21226                    break;
21227                case NM_SDC1GP:
21228                    gen_cop1_ldst(ctx, OPC_SDC1, rt, 28, u);
21229                    break;
21230                }
21231                break;
21232            default:
21233                generate_exception_end(ctx, EXCP_RI);
21234                break;
21235            }
21236        }
21237        break;
21238    case NM_P_LS_U12:
21239        {
21240            uint32_t u = extract32(ctx->opcode, 0, 12);
21241
21242            switch (extract32(ctx->opcode, 12, 4)) {
21243            case NM_P_PREFU12:
21244                if (rt == 31) {
21245                    /* SYNCI */
21246                    /* Break the TB to be able to sync copied instructions
21247                       immediately */
21248                    ctx->base.is_jmp = DISAS_STOP;
21249                } else {
21250                    /* PREF */
21251                    /* Treat as NOP. */
21252                }
21253                break;
21254            case NM_LB:
21255                gen_ld(ctx, OPC_LB, rt, rs, u);
21256                break;
21257            case NM_LH:
21258                gen_ld(ctx, OPC_LH, rt, rs, u);
21259                break;
21260            case NM_LW:
21261                gen_ld(ctx, OPC_LW, rt, rs, u);
21262                break;
21263            case NM_LBU:
21264                gen_ld(ctx, OPC_LBU, rt, rs, u);
21265                break;
21266            case NM_LHU:
21267                gen_ld(ctx, OPC_LHU, rt, rs, u);
21268                break;
21269            case NM_SB:
21270                gen_st(ctx, OPC_SB, rt, rs, u);
21271                break;
21272            case NM_SH:
21273                gen_st(ctx, OPC_SH, rt, rs, u);
21274                break;
21275            case NM_SW:
21276                gen_st(ctx, OPC_SW, rt, rs, u);
21277                break;
21278            case NM_LWC1:
21279                gen_cop1_ldst(ctx, OPC_LWC1, rt, rs, u);
21280                break;
21281            case NM_LDC1:
21282                gen_cop1_ldst(ctx, OPC_LDC1, rt, rs, u);
21283                break;
21284            case NM_SWC1:
21285                gen_cop1_ldst(ctx, OPC_SWC1, rt, rs, u);
21286                break;
21287            case NM_SDC1:
21288                gen_cop1_ldst(ctx, OPC_SDC1, rt, rs, u);
21289                break;
21290            default:
21291                generate_exception_end(ctx, EXCP_RI);
21292                break;
21293            }
21294        }
21295        break;
21296    case NM_P_LS_S9:
21297        {
21298            int32_t s = (sextract32(ctx->opcode, 15, 1) << 8) |
21299                        extract32(ctx->opcode, 0, 8);
21300
21301            switch (extract32(ctx->opcode, 8, 3)) {
21302            case NM_P_LS_S0:
21303                switch (extract32(ctx->opcode, 11, 4)) {
21304                case NM_LBS9:
21305                    gen_ld(ctx, OPC_LB, rt, rs, s);
21306                    break;
21307                case NM_LHS9:
21308                    gen_ld(ctx, OPC_LH, rt, rs, s);
21309                    break;
21310                case NM_LWS9:
21311                    gen_ld(ctx, OPC_LW, rt, rs, s);
21312                    break;
21313                case NM_LBUS9:
21314                    gen_ld(ctx, OPC_LBU, rt, rs, s);
21315                    break;
21316                case NM_LHUS9:
21317                    gen_ld(ctx, OPC_LHU, rt, rs, s);
21318                    break;
21319                case NM_SBS9:
21320                    gen_st(ctx, OPC_SB, rt, rs, s);
21321                    break;
21322                case NM_SHS9:
21323                    gen_st(ctx, OPC_SH, rt, rs, s);
21324                    break;
21325                case NM_SWS9:
21326                    gen_st(ctx, OPC_SW, rt, rs, s);
21327                    break;
21328                case NM_LWC1S9:
21329                    gen_cop1_ldst(ctx, OPC_LWC1, rt, rs, s);
21330                    break;
21331                case NM_LDC1S9:
21332                    gen_cop1_ldst(ctx, OPC_LDC1, rt, rs, s);
21333                    break;
21334                case NM_SWC1S9:
21335                    gen_cop1_ldst(ctx, OPC_SWC1, rt, rs, s);
21336                    break;
21337                case NM_SDC1S9:
21338                    gen_cop1_ldst(ctx, OPC_SDC1, rt, rs, s);
21339                    break;
21340                case NM_P_PREFS9:
21341                    if (rt == 31) {
21342                        /* SYNCI */
21343                        /* Break the TB to be able to sync copied instructions
21344                           immediately */
21345                        ctx->base.is_jmp = DISAS_STOP;
21346                    } else {
21347                        /* PREF */
21348                        /* Treat as NOP. */
21349                    }
21350                    break;
21351                default:
21352                    generate_exception_end(ctx, EXCP_RI);
21353                    break;
21354                }
21355                break;
21356            case NM_P_LS_S1:
21357                switch (extract32(ctx->opcode, 11, 4)) {
21358                case NM_UALH:
21359                case NM_UASH:
21360                    check_nms(ctx);
21361                    {
21362                        TCGv t0 = tcg_temp_new();
21363                        TCGv t1 = tcg_temp_new();
21364
21365                        gen_base_offset_addr(ctx, t0, rs, s);
21366
21367                        switch (extract32(ctx->opcode, 11, 4)) {
21368                        case NM_UALH:
21369                            tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TESW |
21370                                               MO_UNALN);
21371                            gen_store_gpr(t0, rt);
21372                            break;
21373                        case NM_UASH:
21374                            gen_load_gpr(t1, rt);
21375                            tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUW |
21376                                               MO_UNALN);
21377                            break;
21378                        }
21379                        tcg_temp_free(t0);
21380                        tcg_temp_free(t1);
21381                    }
21382                    break;
21383                case NM_P_LL:
21384                    switch (ctx->opcode & 0x03) {
21385                    case NM_LL:
21386                        gen_ld(ctx, OPC_LL, rt, rs, s);
21387                        break;
21388                    case NM_LLWP:
21389                        check_xnp(ctx);
21390                        gen_llwp(ctx, rs, 0, rt, extract32(ctx->opcode, 3, 5));
21391                        break;
21392                    }
21393                    break;
21394                case NM_P_SC:
21395                    switch (ctx->opcode & 0x03) {
21396                    case NM_SC:
21397                        gen_st_cond(ctx, OPC_SC, rt, rs, s);
21398                        break;
21399                    case NM_SCWP:
21400                        check_xnp(ctx);
21401                        gen_scwp(ctx, rs, 0, rt, extract32(ctx->opcode, 3, 5));
21402                        break;
21403                    }
21404                    break;
21405                case NM_CACHE:
21406                    check_cp0_enabled(ctx);
21407                    if (ctx->hflags & MIPS_HFLAG_ITC_CACHE) {
21408                        gen_cache_operation(ctx, rt, rs, s);
21409                    }
21410                    break;
21411                }
21412                break;
21413            case NM_P_LS_E0:
21414                switch (extract32(ctx->opcode, 11, 4)) {
21415                case NM_LBE:
21416                    check_eva(ctx);
21417                    check_cp0_enabled(ctx);
21418                    gen_ld(ctx, OPC_LBE, rt, rs, s);
21419                    break;
21420                case NM_SBE:
21421                    check_eva(ctx);
21422                    check_cp0_enabled(ctx);
21423                    gen_st(ctx, OPC_SBE, rt, rs, s);
21424                    break;
21425                case NM_LBUE:
21426                    check_eva(ctx);
21427                    check_cp0_enabled(ctx);
21428                    gen_ld(ctx, OPC_LBUE, rt, rs, s);
21429                    break;
21430                case NM_P_PREFE:
21431                    if (rt == 31) {
21432                        /* case NM_SYNCIE */
21433                        check_eva(ctx);
21434                        check_cp0_enabled(ctx);
21435                        /* Break the TB to be able to sync copied instructions
21436                           immediately */
21437                        ctx->base.is_jmp = DISAS_STOP;
21438                    } else {
21439                        /* case NM_PREFE */
21440                        check_eva(ctx);
21441                        check_cp0_enabled(ctx);
21442                        /* Treat as NOP. */
21443                    }
21444                    break;
21445                case NM_LHE:
21446                    check_eva(ctx);
21447                    check_cp0_enabled(ctx);
21448                    gen_ld(ctx, OPC_LHE, rt, rs, s);
21449                    break;
21450                case NM_SHE:
21451                    check_eva(ctx);
21452                    check_cp0_enabled(ctx);
21453                    gen_st(ctx, OPC_SHE, rt, rs, s);
21454                    break;
21455                case NM_LHUE:
21456                    check_eva(ctx);
21457                    check_cp0_enabled(ctx);
21458                    gen_ld(ctx, OPC_LHUE, rt, rs, s);
21459                    break;
21460                case NM_CACHEE:
21461                    check_nms_dl_il_sl_tl_l2c(ctx);
21462                    gen_cache_operation(ctx, rt, rs, s);
21463                    break;
21464                case NM_LWE:
21465                    check_eva(ctx);
21466                    check_cp0_enabled(ctx);
21467                    gen_ld(ctx, OPC_LWE, rt, rs, s);
21468                    break;
21469                case NM_SWE:
21470                    check_eva(ctx);
21471                    check_cp0_enabled(ctx);
21472                    gen_st(ctx, OPC_SWE, rt, rs, s);
21473                    break;
21474                case NM_P_LLE:
21475                    switch (extract32(ctx->opcode, 2, 2)) {
21476                    case NM_LLE:
21477                        check_xnp(ctx);
21478                        check_eva(ctx);
21479                        check_cp0_enabled(ctx);
21480                        gen_ld(ctx, OPC_LLE, rt, rs, s);
21481                        break;
21482                    case NM_LLWPE:
21483                        check_xnp(ctx);
21484                        check_eva(ctx);
21485                        check_cp0_enabled(ctx);
21486                        gen_llwp(ctx, rs, 0, rt, extract32(ctx->opcode, 3, 5));
21487                        break;
21488                    default:
21489                        generate_exception_end(ctx, EXCP_RI);
21490                        break;
21491                    }
21492                    break;
21493                case NM_P_SCE:
21494                    switch (extract32(ctx->opcode, 2, 2)) {
21495                    case NM_SCE:
21496                        check_xnp(ctx);
21497                        check_eva(ctx);
21498                        check_cp0_enabled(ctx);
21499                        gen_st_cond(ctx, OPC_SCE, rt, rs, s);
21500                        break;
21501                    case NM_SCWPE:
21502                        check_xnp(ctx);
21503                        check_eva(ctx);
21504                        check_cp0_enabled(ctx);
21505                        gen_scwp(ctx, rs, 0, rt, extract32(ctx->opcode, 3, 5));
21506                        break;
21507                    default:
21508                        generate_exception_end(ctx, EXCP_RI);
21509                        break;
21510                    }
21511                    break;
21512                }
21513                break;
21514            case NM_P_LS_WM:
21515            case NM_P_LS_UAWM:
21516                check_nms(ctx);
21517                {
21518                    int count = extract32(ctx->opcode, 12, 3);
21519                    int counter = 0;
21520
21521                    offset = sextract32(ctx->opcode, 15, 1) << 8 |
21522                             extract32(ctx->opcode, 0, 8);
21523                    TCGv va = tcg_temp_new();
21524                    TCGv t1 = tcg_temp_new();
21525                    TCGMemOp memop = (extract32(ctx->opcode, 8, 3)) ==
21526                                      NM_P_LS_UAWM ? MO_UNALN : 0;
21527
21528                    count = (count == 0) ? 8 : count;
21529                    while (counter != count) {
21530                        int this_rt = ((rt + counter) & 0x1f) | (rt & 0x10);
21531                        int this_offset = offset + (counter << 2);
21532
21533                        gen_base_offset_addr(ctx, va, rs, this_offset);
21534
21535                        switch (extract32(ctx->opcode, 11, 1)) {
21536                        case NM_LWM:
21537                            tcg_gen_qemu_ld_tl(t1, va, ctx->mem_idx,
21538                                               memop | MO_TESL);
21539                            gen_store_gpr(t1, this_rt);
21540                            if ((this_rt == rs) &&
21541                                (counter != (count - 1))) {
21542                                /* UNPREDICTABLE */
21543                            }
21544                            break;
21545                        case NM_SWM:
21546                            this_rt = (rt == 0) ? 0 : this_rt;
21547                            gen_load_gpr(t1, this_rt);
21548                            tcg_gen_qemu_st_tl(t1, va, ctx->mem_idx,
21549                                               memop | MO_TEUL);
21550                            break;
21551                        }
21552                        counter++;
21553                    }
21554                    tcg_temp_free(va);
21555                    tcg_temp_free(t1);
21556                }
21557                break;
21558            default:
21559                generate_exception_end(ctx, EXCP_RI);
21560                break;
21561            }
21562        }
21563        break;
21564    case NM_MOVE_BALC:
21565        check_nms(ctx);
21566        {
21567            TCGv t0 = tcg_temp_new();
21568            int32_t s = sextract32(ctx->opcode, 0, 1) << 21 |
21569                        extract32(ctx->opcode, 1, 20) << 1;
21570            rd = (extract32(ctx->opcode, 24, 1)) == 0 ? 4 : 5;
21571            rt = decode_gpr_gpr4_zero(extract32(ctx->opcode, 25, 1) << 3 |
21572                            extract32(ctx->opcode, 21, 3));
21573            gen_load_gpr(t0, rt);
21574            tcg_gen_mov_tl(cpu_gpr[rd], t0);
21575            gen_compute_branch_nm(ctx, OPC_BGEZAL, 4, 0, 0, s);
21576            tcg_temp_free(t0);
21577        }
21578        break;
21579    case NM_P_BAL:
21580        {
21581            int32_t s = sextract32(ctx->opcode, 0, 1) << 25 |
21582                        extract32(ctx->opcode, 1, 24) << 1;
21583
21584            if ((extract32(ctx->opcode, 25, 1)) == 0) {
21585                /* BC */
21586                gen_compute_branch_nm(ctx, OPC_BEQ, 4, 0, 0, s);
21587            } else {
21588                /* BALC */
21589                gen_compute_branch_nm(ctx, OPC_BGEZAL, 4, 0, 0, s);
21590            }
21591        }
21592        break;
21593    case NM_P_J:
21594        switch (extract32(ctx->opcode, 12, 4)) {
21595        case NM_JALRC:
21596        case NM_JALRC_HB:
21597            gen_compute_branch_nm(ctx, OPC_JALR, 4, rs, rt, 0);
21598            break;
21599        case NM_P_BALRSC:
21600            gen_compute_nanomips_pbalrsc_branch(ctx, rs, rt);
21601            break;
21602        default:
21603            generate_exception_end(ctx, EXCP_RI);
21604            break;
21605        }
21606        break;
21607    case NM_P_BR1:
21608        {
21609            int32_t s = sextract32(ctx->opcode, 0, 1) << 14 |
21610                        extract32(ctx->opcode, 1, 13) << 1;
21611            switch (extract32(ctx->opcode, 14, 2)) {
21612            case NM_BEQC:
21613                check_nms(ctx);
21614                gen_compute_branch_nm(ctx, OPC_BEQ, 4, rs, rt, s);
21615                break;
21616            case NM_P_BR3A:
21617                s = sextract32(ctx->opcode, 0, 1) << 14 |
21618                    extract32(ctx->opcode, 1, 13) << 1;
21619                check_cp1_enabled(ctx);
21620                switch (extract32(ctx->opcode, 16, 5)) {
21621                case NM_BC1EQZC:
21622                    gen_compute_branch_cp1_nm(ctx, OPC_BC1EQZ, rt, s);
21623                    break;
21624                case NM_BC1NEZC:
21625                    gen_compute_branch_cp1_nm(ctx, OPC_BC1NEZ, rt, s);
21626                    break;
21627                case NM_BPOSGE32C:
21628                    check_dsp_r3(ctx);
21629                    {
21630                        int32_t imm = extract32(ctx->opcode, 1, 13) |
21631                                      extract32(ctx->opcode, 0, 1) << 13;
21632
21633                        gen_compute_branch_nm(ctx, OPC_BPOSGE32, 4, -1, -2,
21634                                              imm);
21635                    }
21636                    break;
21637                default:
21638                    generate_exception_end(ctx, EXCP_RI);
21639                    break;
21640                }
21641                break;
21642            case NM_BGEC:
21643                if (rs == rt) {
21644                    gen_compute_compact_branch_nm(ctx, OPC_BC, rs, rt, s);
21645                } else {
21646                    gen_compute_compact_branch_nm(ctx, OPC_BGEC, rs, rt, s);
21647                }
21648                break;
21649            case NM_BGEUC:
21650                if (rs == rt || rt == 0) {
21651                    gen_compute_compact_branch_nm(ctx, OPC_BC, 0, 0, s);
21652                } else if (rs == 0) {
21653                    gen_compute_compact_branch_nm(ctx, OPC_BEQZC, rt, 0, s);
21654                } else {
21655                    gen_compute_compact_branch_nm(ctx, OPC_BGEUC, rs, rt, s);
21656                }
21657                break;
21658            }
21659        }
21660        break;
21661    case NM_P_BR2:
21662        {
21663            int32_t s = sextract32(ctx->opcode, 0, 1) << 14 |
21664                        extract32(ctx->opcode, 1, 13) << 1;
21665            switch (extract32(ctx->opcode, 14, 2)) {
21666            case NM_BNEC:
21667                check_nms(ctx);
21668                gen_compute_branch_nm(ctx, OPC_BNE, 4, rs, rt, s);
21669                break;
21670            case NM_BLTC:
21671                if (rs != 0 && rt != 0 && rs == rt) {
21672                    /* NOP */
21673                    ctx->hflags |= MIPS_HFLAG_FBNSLOT;
21674                } else {
21675                    gen_compute_compact_branch_nm(ctx, OPC_BLTC, rs, rt, s);
21676                }
21677                break;
21678            case NM_BLTUC:
21679                if (rs == 0 || rs == rt) {
21680                    /* NOP */
21681                    ctx->hflags |= MIPS_HFLAG_FBNSLOT;
21682                } else {
21683                    gen_compute_compact_branch_nm(ctx, OPC_BLTUC, rs, rt, s);
21684                }
21685                break;
21686            default:
21687                generate_exception_end(ctx, EXCP_RI);
21688                break;
21689            }
21690        }
21691        break;
21692    case NM_P_BRI:
21693        {
21694            int32_t s = sextract32(ctx->opcode, 0, 1) << 11 |
21695                        extract32(ctx->opcode, 1, 10) << 1;
21696            uint32_t u = extract32(ctx->opcode, 11, 7);
21697
21698            gen_compute_imm_branch(ctx, extract32(ctx->opcode, 18, 3),
21699                                   rt, u, s);
21700        }
21701        break;
21702    default:
21703        generate_exception_end(ctx, EXCP_RI);
21704        break;
21705    }
21706    return 4;
21707}
21708
21709static int decode_nanomips_opc(CPUMIPSState *env, DisasContext *ctx)
21710{
21711    uint32_t op;
21712    int rt = decode_gpr_gpr3(NANOMIPS_EXTRACT_RD(ctx->opcode));
21713    int rs = decode_gpr_gpr3(NANOMIPS_EXTRACT_RS(ctx->opcode));
21714    int rd = decode_gpr_gpr3(NANOMIPS_EXTRACT_RS1(ctx->opcode));
21715    int offset;
21716    int imm;
21717
21718    /* make sure instructions are on a halfword boundary */
21719    if (ctx->base.pc_next & 0x1) {
21720        TCGv tmp = tcg_const_tl(ctx->base.pc_next);
21721        tcg_gen_st_tl(tmp, cpu_env, offsetof(CPUMIPSState, CP0_BadVAddr));
21722        tcg_temp_free(tmp);
21723        generate_exception_end(ctx, EXCP_AdEL);
21724        return 2;
21725    }
21726
21727    op = extract32(ctx->opcode, 10, 6);
21728    switch (op) {
21729    case NM_P16_MV:
21730        rt = NANOMIPS_EXTRACT_RD5(ctx->opcode);
21731        if (rt != 0) {
21732            /* MOVE */
21733            rs = NANOMIPS_EXTRACT_RS5(ctx->opcode);
21734            gen_arith(ctx, OPC_ADDU, rt, rs, 0);
21735        } else {
21736            /* P16.RI */
21737            switch (extract32(ctx->opcode, 3, 2)) {
21738            case NM_P16_SYSCALL:
21739                if (extract32(ctx->opcode, 2, 1) == 0) {
21740                    generate_exception_end(ctx, EXCP_SYSCALL);
21741                } else {
21742                    generate_exception_end(ctx, EXCP_RI);
21743                }
21744                break;
21745            case NM_BREAK16:
21746                generate_exception_end(ctx, EXCP_BREAK);
21747                break;
21748            case NM_SDBBP16:
21749                if (is_uhi(extract32(ctx->opcode, 0, 3))) {
21750                    gen_helper_do_semihosting(cpu_env);
21751                } else {
21752                    if (ctx->hflags & MIPS_HFLAG_SBRI) {
21753                        generate_exception_end(ctx, EXCP_RI);
21754                    } else {
21755                        generate_exception_end(ctx, EXCP_DBp);
21756                    }
21757                }
21758                break;
21759            default:
21760                generate_exception_end(ctx, EXCP_RI);
21761                break;
21762            }
21763        }
21764        break;
21765    case NM_P16_SHIFT:
21766        {
21767            int shift = extract32(ctx->opcode, 0, 3);
21768            uint32_t opc = 0;
21769            shift = (shift == 0) ? 8 : shift;
21770
21771            switch (extract32(ctx->opcode, 3, 1)) {
21772            case NM_SLL16:
21773                opc = OPC_SLL;
21774                break;
21775            case NM_SRL16:
21776                opc = OPC_SRL;
21777                break;
21778            }
21779            gen_shift_imm(ctx, opc, rt, rs, shift);
21780        }
21781        break;
21782    case NM_P16C:
21783        switch (ctx->opcode & 1) {
21784        case NM_POOL16C_0:
21785            gen_pool16c_nanomips_insn(ctx);
21786            break;
21787        case NM_LWXS16:
21788            gen_ldxs(ctx, rt, rs, rd);
21789            break;
21790        }
21791        break;
21792    case NM_P16_A1:
21793        switch (extract32(ctx->opcode, 6, 1)) {
21794        case NM_ADDIUR1SP:
21795            imm = extract32(ctx->opcode, 0, 6) << 2;
21796            gen_arith_imm(ctx, OPC_ADDIU, rt, 29, imm);
21797            break;
21798        default:
21799            generate_exception_end(ctx, EXCP_RI);
21800            break;
21801        }
21802        break;
21803    case NM_P16_A2:
21804        switch (extract32(ctx->opcode, 3, 1)) {
21805        case NM_ADDIUR2:
21806            imm = extract32(ctx->opcode, 0, 3) << 2;
21807            gen_arith_imm(ctx, OPC_ADDIU, rt, rs, imm);
21808            break;
21809        case NM_P_ADDIURS5:
21810            rt = extract32(ctx->opcode, 5, 5);
21811            if (rt != 0) {
21812                /* imm = sign_extend(s[3] . s[2:0] , from_nbits = 4) */
21813                imm = (sextract32(ctx->opcode, 4, 1) << 3) |
21814                      (extract32(ctx->opcode, 0, 3));
21815                gen_arith_imm(ctx, OPC_ADDIU, rt, rt, imm);
21816            }
21817            break;
21818        }
21819        break;
21820    case NM_P16_ADDU:
21821        switch (ctx->opcode & 0x1) {
21822        case NM_ADDU16:
21823            gen_arith(ctx, OPC_ADDU, rd, rs, rt);
21824            break;
21825        case NM_SUBU16:
21826            gen_arith(ctx, OPC_SUBU, rd, rs, rt);
21827            break;
21828        }
21829        break;
21830    case NM_P16_4X4:
21831        rt = (extract32(ctx->opcode, 9, 1) << 3) |
21832              extract32(ctx->opcode, 5, 3);
21833        rs = (extract32(ctx->opcode, 4, 1) << 3) |
21834              extract32(ctx->opcode, 0, 3);
21835        rt = decode_gpr_gpr4(rt);
21836        rs = decode_gpr_gpr4(rs);
21837        switch ((extract32(ctx->opcode, 7, 2) & 0x2) |
21838                (extract32(ctx->opcode, 3, 1))) {
21839        case NM_ADDU4X4:
21840            check_nms(ctx);
21841            gen_arith(ctx, OPC_ADDU, rt, rs, rt);
21842            break;
21843        case NM_MUL4X4:
21844            check_nms(ctx);
21845            gen_r6_muldiv(ctx, R6_OPC_MUL, rt, rs, rt);
21846            break;
21847        default:
21848            generate_exception_end(ctx, EXCP_RI);
21849            break;
21850        }
21851        break;
21852    case NM_LI16:
21853        {
21854            int imm = extract32(ctx->opcode, 0, 7);
21855            imm = (imm == 0x7f ? -1 : imm);
21856            if (rt != 0) {
21857                tcg_gen_movi_tl(cpu_gpr[rt], imm);
21858            }
21859        }
21860        break;
21861    case NM_ANDI16:
21862        {
21863            uint32_t u = extract32(ctx->opcode, 0, 4);
21864            u = (u == 12) ? 0xff :
21865                (u == 13) ? 0xffff : u;
21866            gen_logic_imm(ctx, OPC_ANDI, rt, rs, u);
21867        }
21868        break;
21869    case NM_P16_LB:
21870        offset = extract32(ctx->opcode, 0, 2);
21871        switch (extract32(ctx->opcode, 2, 2)) {
21872        case NM_LB16:
21873            gen_ld(ctx, OPC_LB, rt, rs, offset);
21874            break;
21875        case NM_SB16:
21876            rt = decode_gpr_gpr3_src_store(
21877                     NANOMIPS_EXTRACT_RD(ctx->opcode));
21878            gen_st(ctx, OPC_SB, rt, rs, offset);
21879            break;
21880        case NM_LBU16:
21881            gen_ld(ctx, OPC_LBU, rt, rs, offset);
21882            break;
21883        default:
21884            generate_exception_end(ctx, EXCP_RI);
21885            break;
21886        }
21887        break;
21888    case NM_P16_LH:
21889        offset = extract32(ctx->opcode, 1, 2) << 1;
21890        switch ((extract32(ctx->opcode, 3, 1) << 1) | (ctx->opcode & 1)) {
21891        case NM_LH16:
21892            gen_ld(ctx, OPC_LH, rt, rs, offset);
21893            break;
21894        case NM_SH16:
21895            rt = decode_gpr_gpr3_src_store(
21896                     NANOMIPS_EXTRACT_RD(ctx->opcode));
21897            gen_st(ctx, OPC_SH, rt, rs, offset);
21898            break;
21899        case NM_LHU16:
21900            gen_ld(ctx, OPC_LHU, rt, rs, offset);
21901            break;
21902        default:
21903            generate_exception_end(ctx, EXCP_RI);
21904            break;
21905        }
21906        break;
21907    case NM_LW16:
21908        offset = extract32(ctx->opcode, 0, 4) << 2;
21909        gen_ld(ctx, OPC_LW, rt, rs, offset);
21910        break;
21911    case NM_LWSP16:
21912        rt = NANOMIPS_EXTRACT_RD5(ctx->opcode);
21913        offset = extract32(ctx->opcode, 0, 5) << 2;
21914        gen_ld(ctx, OPC_LW, rt, 29, offset);
21915        break;
21916    case NM_LW4X4:
21917        check_nms(ctx);
21918        rt = (extract32(ctx->opcode, 9, 1) << 3) |
21919             extract32(ctx->opcode, 5, 3);
21920        rs = (extract32(ctx->opcode, 4, 1) << 3) |
21921             extract32(ctx->opcode, 0, 3);
21922        offset = (extract32(ctx->opcode, 3, 1) << 3) |
21923                 (extract32(ctx->opcode, 8, 1) << 2);
21924        rt = decode_gpr_gpr4(rt);
21925        rs = decode_gpr_gpr4(rs);
21926        gen_ld(ctx, OPC_LW, rt, rs, offset);
21927        break;
21928    case NM_SW4X4:
21929        check_nms(ctx);
21930        rt = (extract32(ctx->opcode, 9, 1) << 3) |
21931             extract32(ctx->opcode, 5, 3);
21932        rs = (extract32(ctx->opcode, 4, 1) << 3) |
21933             extract32(ctx->opcode, 0, 3);
21934        offset = (extract32(ctx->opcode, 3, 1) << 3) |
21935                 (extract32(ctx->opcode, 8, 1) << 2);
21936        rt = decode_gpr_gpr4_zero(rt);
21937        rs = decode_gpr_gpr4(rs);
21938        gen_st(ctx, OPC_SW, rt, rs, offset);
21939        break;
21940    case NM_LWGP16:
21941        offset = extract32(ctx->opcode, 0, 7) << 2;
21942        gen_ld(ctx, OPC_LW, rt, 28, offset);
21943        break;
21944    case NM_SWSP16:
21945        rt = NANOMIPS_EXTRACT_RD5(ctx->opcode);
21946        offset = extract32(ctx->opcode, 0, 5) << 2;
21947        gen_st(ctx, OPC_SW, rt, 29, offset);
21948        break;
21949    case NM_SW16:
21950        rt = decode_gpr_gpr3_src_store(
21951                 NANOMIPS_EXTRACT_RD(ctx->opcode));
21952        rs = decode_gpr_gpr3(NANOMIPS_EXTRACT_RS(ctx->opcode));
21953        offset = extract32(ctx->opcode, 0, 4) << 2;
21954        gen_st(ctx, OPC_SW, rt, rs, offset);
21955        break;
21956    case NM_SWGP16:
21957        rt = decode_gpr_gpr3_src_store(
21958                 NANOMIPS_EXTRACT_RD(ctx->opcode));
21959        offset = extract32(ctx->opcode, 0, 7) << 2;
21960        gen_st(ctx, OPC_SW, rt, 28, offset);
21961        break;
21962    case NM_BC16:
21963        gen_compute_branch_nm(ctx, OPC_BEQ, 2, 0, 0,
21964                           (sextract32(ctx->opcode, 0, 1) << 10) |
21965                           (extract32(ctx->opcode, 1, 9) << 1));
21966        break;
21967    case NM_BALC16:
21968        gen_compute_branch_nm(ctx, OPC_BGEZAL, 2, 0, 0,
21969                           (sextract32(ctx->opcode, 0, 1) << 10) |
21970                           (extract32(ctx->opcode, 1, 9) << 1));
21971        break;
21972    case NM_BEQZC16:
21973        gen_compute_branch_nm(ctx, OPC_BEQ, 2, rt, 0,
21974                           (sextract32(ctx->opcode, 0, 1) << 7) |
21975                           (extract32(ctx->opcode, 1, 6) << 1));
21976        break;
21977    case NM_BNEZC16:
21978        gen_compute_branch_nm(ctx, OPC_BNE, 2, rt, 0,
21979                           (sextract32(ctx->opcode, 0, 1) << 7) |
21980                           (extract32(ctx->opcode, 1, 6) << 1));
21981        break;
21982    case NM_P16_BR:
21983        switch (ctx->opcode & 0xf) {
21984        case 0:
21985            /* P16.JRC */
21986            switch (extract32(ctx->opcode, 4, 1)) {
21987            case NM_JRC:
21988                gen_compute_branch_nm(ctx, OPC_JR, 2,
21989                                   extract32(ctx->opcode, 5, 5), 0, 0);
21990                break;
21991            case NM_JALRC16:
21992                gen_compute_branch_nm(ctx, OPC_JALR, 2,
21993                                   extract32(ctx->opcode, 5, 5), 31, 0);
21994                break;
21995            }
21996            break;
21997        default:
21998            {
21999                /* P16.BRI */
22000                uint32_t opc = extract32(ctx->opcode, 4, 3) <
22001                               extract32(ctx->opcode, 7, 3) ? OPC_BEQ : OPC_BNE;
22002                gen_compute_branch_nm(ctx, opc, 2, rs, rt,
22003                                   extract32(ctx->opcode, 0, 4) << 1);
22004            }
22005            break;
22006        }
22007        break;
22008    case NM_P16_SR:
22009        {
22010            int count = extract32(ctx->opcode, 0, 4);
22011            int u = extract32(ctx->opcode, 4, 4) << 4;
22012
22013            rt = 30 + extract32(ctx->opcode, 9, 1);
22014            switch (extract32(ctx->opcode, 8, 1)) {
22015            case NM_SAVE16:
22016                gen_save(ctx, rt, count, 0, u);
22017                break;
22018            case NM_RESTORE_JRC16:
22019                gen_restore(ctx, rt, count, 0, u);
22020                gen_compute_branch_nm(ctx, OPC_JR, 2, 31, 0, 0);
22021                break;
22022            }
22023        }
22024        break;
22025    case NM_MOVEP:
22026    case NM_MOVEPREV:
22027        check_nms(ctx);
22028        {
22029            static const int gpr2reg1[] = {4, 5, 6, 7};
22030            static const int gpr2reg2[] = {5, 6, 7, 8};
22031            int re;
22032            int rd2 = extract32(ctx->opcode, 3, 1) << 1 |
22033                      extract32(ctx->opcode, 8, 1);
22034            int r1 = gpr2reg1[rd2];
22035            int r2 = gpr2reg2[rd2];
22036            int r3 = extract32(ctx->opcode, 4, 1) << 3 |
22037                     extract32(ctx->opcode, 0, 3);
22038            int r4 = extract32(ctx->opcode, 9, 1) << 3 |
22039                     extract32(ctx->opcode, 5, 3);
22040            TCGv t0 = tcg_temp_new();
22041            TCGv t1 = tcg_temp_new();
22042            if (op == NM_MOVEP) {
22043                rd = r1;
22044                re = r2;
22045                rs = decode_gpr_gpr4_zero(r3);
22046                rt = decode_gpr_gpr4_zero(r4);
22047            } else {
22048                rd = decode_gpr_gpr4(r3);
22049                re = decode_gpr_gpr4(r4);
22050                rs = r1;
22051                rt = r2;
22052            }
22053            gen_load_gpr(t0, rs);
22054            gen_load_gpr(t1, rt);
22055            tcg_gen_mov_tl(cpu_gpr[rd], t0);
22056            tcg_gen_mov_tl(cpu_gpr[re], t1);
22057            tcg_temp_free(t0);
22058            tcg_temp_free(t1);
22059        }
22060        break;
22061    default:
22062        return decode_nanomips_32_48_opc(env, ctx);
22063    }
22064
22065    return 2;
22066}
22067
22068
22069/* SmartMIPS extension to MIPS32 */
22070
22071#if defined(TARGET_MIPS64)
22072
22073/* MDMX extension to MIPS64 */
22074
22075#endif
22076
22077/* MIPSDSP functions. */
22078static void gen_mipsdsp_ld(DisasContext *ctx, uint32_t opc,
22079                           int rd, int base, int offset)
22080{
22081    TCGv t0;
22082
22083    check_dsp(ctx);
22084    t0 = tcg_temp_new();
22085
22086    if (base == 0) {
22087        gen_load_gpr(t0, offset);
22088    } else if (offset == 0) {
22089        gen_load_gpr(t0, base);
22090    } else {
22091        gen_op_addr_add(ctx, t0, cpu_gpr[base], cpu_gpr[offset]);
22092    }
22093
22094    switch (opc) {
22095    case OPC_LBUX:
22096        tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_UB);
22097        gen_store_gpr(t0, rd);
22098        break;
22099    case OPC_LHX:
22100        tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TESW);
22101        gen_store_gpr(t0, rd);
22102        break;
22103    case OPC_LWX:
22104        tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TESL);
22105        gen_store_gpr(t0, rd);
22106        break;
22107#if defined(TARGET_MIPS64)
22108    case OPC_LDX:
22109        tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEQ);
22110        gen_store_gpr(t0, rd);
22111        break;
22112#endif
22113    }
22114    tcg_temp_free(t0);
22115}
22116
22117static void gen_mipsdsp_arith(DisasContext *ctx, uint32_t op1, uint32_t op2,
22118                              int ret, int v1, int v2)
22119{
22120    TCGv v1_t;
22121    TCGv v2_t;
22122
22123    if (ret == 0) {
22124        /* Treat as NOP. */
22125        return;
22126    }
22127
22128    v1_t = tcg_temp_new();
22129    v2_t = tcg_temp_new();
22130
22131    gen_load_gpr(v1_t, v1);
22132    gen_load_gpr(v2_t, v2);
22133
22134    switch (op1) {
22135    /* OPC_MULT_G_2E is equal OPC_ADDUH_QB_DSP */
22136    case OPC_MULT_G_2E:
22137        check_dsp_r2(ctx);
22138        switch (op2) {
22139        case OPC_ADDUH_QB:
22140            gen_helper_adduh_qb(cpu_gpr[ret], v1_t, v2_t);
22141            break;
22142        case OPC_ADDUH_R_QB:
22143            gen_helper_adduh_r_qb(cpu_gpr[ret], v1_t, v2_t);
22144            break;
22145        case OPC_ADDQH_PH:
22146            gen_helper_addqh_ph(cpu_gpr[ret], v1_t, v2_t);
22147            break;
22148        case OPC_ADDQH_R_PH:
22149            gen_helper_addqh_r_ph(cpu_gpr[ret], v1_t, v2_t);
22150            break;
22151        case OPC_ADDQH_W:
22152            gen_helper_addqh_w(cpu_gpr[ret], v1_t, v2_t);
22153            break;
22154        case OPC_ADDQH_R_W:
22155            gen_helper_addqh_r_w(cpu_gpr[ret], v1_t, v2_t);
22156            break;
22157        case OPC_SUBUH_QB:
22158            gen_helper_subuh_qb(cpu_gpr[ret], v1_t, v2_t);
22159            break;
22160        case OPC_SUBUH_R_QB:
22161            gen_helper_subuh_r_qb(cpu_gpr[ret], v1_t, v2_t);
22162            break;
22163        case OPC_SUBQH_PH:
22164            gen_helper_subqh_ph(cpu_gpr[ret], v1_t, v2_t);
22165            break;
22166        case OPC_SUBQH_R_PH:
22167            gen_helper_subqh_r_ph(cpu_gpr[ret], v1_t, v2_t);
22168            break;
22169        case OPC_SUBQH_W:
22170            gen_helper_subqh_w(cpu_gpr[ret], v1_t, v2_t);
22171            break;
22172        case OPC_SUBQH_R_W:
22173            gen_helper_subqh_r_w(cpu_gpr[ret], v1_t, v2_t);
22174            break;
22175        }
22176        break;
22177    case OPC_ABSQ_S_PH_DSP:
22178        switch (op2) {
22179        case OPC_ABSQ_S_QB:
22180            check_dsp_r2(ctx);
22181            gen_helper_absq_s_qb(cpu_gpr[ret], v2_t, cpu_env);
22182            break;
22183        case OPC_ABSQ_S_PH:
22184            check_dsp(ctx);
22185            gen_helper_absq_s_ph(cpu_gpr[ret], v2_t, cpu_env);
22186            break;
22187        case OPC_ABSQ_S_W:
22188            check_dsp(ctx);
22189            gen_helper_absq_s_w(cpu_gpr[ret], v2_t, cpu_env);
22190            break;
22191        case OPC_PRECEQ_W_PHL:
22192            check_dsp(ctx);
22193            tcg_gen_andi_tl(cpu_gpr[ret], v2_t, 0xFFFF0000);
22194            tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]);
22195            break;
22196        case OPC_PRECEQ_W_PHR:
22197            check_dsp(ctx);
22198            tcg_gen_andi_tl(cpu_gpr[ret], v2_t, 0x0000FFFF);
22199            tcg_gen_shli_tl(cpu_gpr[ret], cpu_gpr[ret], 16);
22200            tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]);
22201            break;
22202        case OPC_PRECEQU_PH_QBL:
22203            check_dsp(ctx);
22204            gen_helper_precequ_ph_qbl(cpu_gpr[ret], v2_t);
22205            break;
22206        case OPC_PRECEQU_PH_QBR:
22207            check_dsp(ctx);
22208            gen_helper_precequ_ph_qbr(cpu_gpr[ret], v2_t);
22209            break;
22210        case OPC_PRECEQU_PH_QBLA:
22211            check_dsp(ctx);
22212            gen_helper_precequ_ph_qbla(cpu_gpr[ret], v2_t);
22213            break;
22214        case OPC_PRECEQU_PH_QBRA:
22215            check_dsp(ctx);
22216            gen_helper_precequ_ph_qbra(cpu_gpr[ret], v2_t);
22217            break;
22218        case OPC_PRECEU_PH_QBL:
22219            check_dsp(ctx);
22220            gen_helper_preceu_ph_qbl(cpu_gpr[ret], v2_t);
22221            break;
22222        case OPC_PRECEU_PH_QBR:
22223            check_dsp(ctx);
22224            gen_helper_preceu_ph_qbr(cpu_gpr[ret], v2_t);
22225            break;
22226        case OPC_PRECEU_PH_QBLA:
22227            check_dsp(ctx);
22228            gen_helper_preceu_ph_qbla(cpu_gpr[ret], v2_t);
22229            break;
22230        case OPC_PRECEU_PH_QBRA:
22231            check_dsp(ctx);
22232            gen_helper_preceu_ph_qbra(cpu_gpr[ret], v2_t);
22233            break;
22234        }
22235        break;
22236    case OPC_ADDU_QB_DSP:
22237        switch (op2) {
22238        case OPC_ADDQ_PH:
22239            check_dsp(ctx);
22240            gen_helper_addq_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22241            break;
22242        case OPC_ADDQ_S_PH:
22243            check_dsp(ctx);
22244            gen_helper_addq_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22245            break;
22246        case OPC_ADDQ_S_W:
22247            check_dsp(ctx);
22248            gen_helper_addq_s_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22249            break;
22250        case OPC_ADDU_QB:
22251            check_dsp(ctx);
22252            gen_helper_addu_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22253            break;
22254        case OPC_ADDU_S_QB:
22255            check_dsp(ctx);
22256            gen_helper_addu_s_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22257            break;
22258        case OPC_ADDU_PH:
22259            check_dsp_r2(ctx);
22260            gen_helper_addu_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22261            break;
22262        case OPC_ADDU_S_PH:
22263            check_dsp_r2(ctx);
22264            gen_helper_addu_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22265            break;
22266        case OPC_SUBQ_PH:
22267            check_dsp(ctx);
22268            gen_helper_subq_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22269            break;
22270        case OPC_SUBQ_S_PH:
22271            check_dsp(ctx);
22272            gen_helper_subq_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22273            break;
22274        case OPC_SUBQ_S_W:
22275            check_dsp(ctx);
22276            gen_helper_subq_s_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22277            break;
22278        case OPC_SUBU_QB:
22279            check_dsp(ctx);
22280            gen_helper_subu_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22281            break;
22282        case OPC_SUBU_S_QB:
22283            check_dsp(ctx);
22284            gen_helper_subu_s_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22285            break;
22286        case OPC_SUBU_PH:
22287            check_dsp_r2(ctx);
22288            gen_helper_subu_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22289            break;
22290        case OPC_SUBU_S_PH:
22291            check_dsp_r2(ctx);
22292            gen_helper_subu_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22293            break;
22294        case OPC_ADDSC:
22295            check_dsp(ctx);
22296            gen_helper_addsc(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22297            break;
22298        case OPC_ADDWC:
22299            check_dsp(ctx);
22300            gen_helper_addwc(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22301            break;
22302        case OPC_MODSUB:
22303            check_dsp(ctx);
22304            gen_helper_modsub(cpu_gpr[ret], v1_t, v2_t);
22305            break;
22306        case OPC_RADDU_W_QB:
22307            check_dsp(ctx);
22308            gen_helper_raddu_w_qb(cpu_gpr[ret], v1_t);
22309            break;
22310        }
22311        break;
22312    case OPC_CMPU_EQ_QB_DSP:
22313        switch (op2) {
22314        case OPC_PRECR_QB_PH:
22315            check_dsp_r2(ctx);
22316            gen_helper_precr_qb_ph(cpu_gpr[ret], v1_t, v2_t);
22317            break;
22318        case OPC_PRECRQ_QB_PH:
22319            check_dsp(ctx);
22320            gen_helper_precrq_qb_ph(cpu_gpr[ret], v1_t, v2_t);
22321            break;
22322        case OPC_PRECR_SRA_PH_W:
22323            check_dsp_r2(ctx);
22324            {
22325                TCGv_i32 sa_t = tcg_const_i32(v2);
22326                gen_helper_precr_sra_ph_w(cpu_gpr[ret], sa_t, v1_t,
22327                                          cpu_gpr[ret]);
22328                tcg_temp_free_i32(sa_t);
22329                break;
22330            }
22331        case OPC_PRECR_SRA_R_PH_W:
22332            check_dsp_r2(ctx);
22333            {
22334                TCGv_i32 sa_t = tcg_const_i32(v2);
22335                gen_helper_precr_sra_r_ph_w(cpu_gpr[ret], sa_t, v1_t,
22336                                            cpu_gpr[ret]);
22337                tcg_temp_free_i32(sa_t);
22338                break;
22339            }
22340        case OPC_PRECRQ_PH_W:
22341            check_dsp(ctx);
22342            gen_helper_precrq_ph_w(cpu_gpr[ret], v1_t, v2_t);
22343            break;
22344        case OPC_PRECRQ_RS_PH_W:
22345            check_dsp(ctx);
22346            gen_helper_precrq_rs_ph_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22347            break;
22348        case OPC_PRECRQU_S_QB_PH:
22349            check_dsp(ctx);
22350            gen_helper_precrqu_s_qb_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22351            break;
22352        }
22353        break;
22354#ifdef TARGET_MIPS64
22355    case OPC_ABSQ_S_QH_DSP:
22356        switch (op2) {
22357        case OPC_PRECEQ_L_PWL:
22358            check_dsp(ctx);
22359            tcg_gen_andi_tl(cpu_gpr[ret], v2_t, 0xFFFFFFFF00000000ull);
22360            break;
22361        case OPC_PRECEQ_L_PWR:
22362            check_dsp(ctx);
22363            tcg_gen_shli_tl(cpu_gpr[ret], v2_t, 32);
22364            break;
22365        case OPC_PRECEQ_PW_QHL:
22366            check_dsp(ctx);
22367            gen_helper_preceq_pw_qhl(cpu_gpr[ret], v2_t);
22368            break;
22369        case OPC_PRECEQ_PW_QHR:
22370            check_dsp(ctx);
22371            gen_helper_preceq_pw_qhr(cpu_gpr[ret], v2_t);
22372            break;
22373        case OPC_PRECEQ_PW_QHLA:
22374            check_dsp(ctx);
22375            gen_helper_preceq_pw_qhla(cpu_gpr[ret], v2_t);
22376            break;
22377        case OPC_PRECEQ_PW_QHRA:
22378            check_dsp(ctx);
22379            gen_helper_preceq_pw_qhra(cpu_gpr[ret], v2_t);
22380            break;
22381        case OPC_PRECEQU_QH_OBL:
22382            check_dsp(ctx);
22383            gen_helper_precequ_qh_obl(cpu_gpr[ret], v2_t);
22384            break;
22385        case OPC_PRECEQU_QH_OBR:
22386            check_dsp(ctx);
22387            gen_helper_precequ_qh_obr(cpu_gpr[ret], v2_t);
22388            break;
22389        case OPC_PRECEQU_QH_OBLA:
22390            check_dsp(ctx);
22391            gen_helper_precequ_qh_obla(cpu_gpr[ret], v2_t);
22392            break;
22393        case OPC_PRECEQU_QH_OBRA:
22394            check_dsp(ctx);
22395            gen_helper_precequ_qh_obra(cpu_gpr[ret], v2_t);
22396            break;
22397        case OPC_PRECEU_QH_OBL:
22398            check_dsp(ctx);
22399            gen_helper_preceu_qh_obl(cpu_gpr[ret], v2_t);
22400            break;
22401        case OPC_PRECEU_QH_OBR:
22402            check_dsp(ctx);
22403            gen_helper_preceu_qh_obr(cpu_gpr[ret], v2_t);
22404            break;
22405        case OPC_PRECEU_QH_OBLA:
22406            check_dsp(ctx);
22407            gen_helper_preceu_qh_obla(cpu_gpr[ret], v2_t);
22408            break;
22409        case OPC_PRECEU_QH_OBRA:
22410            check_dsp(ctx);
22411            gen_helper_preceu_qh_obra(cpu_gpr[ret], v2_t);
22412            break;
22413        case OPC_ABSQ_S_OB:
22414            check_dsp_r2(ctx);
22415            gen_helper_absq_s_ob(cpu_gpr[ret], v2_t, cpu_env);
22416            break;
22417        case OPC_ABSQ_S_PW:
22418            check_dsp(ctx);
22419            gen_helper_absq_s_pw(cpu_gpr[ret], v2_t, cpu_env);
22420            break;
22421        case OPC_ABSQ_S_QH:
22422            check_dsp(ctx);
22423            gen_helper_absq_s_qh(cpu_gpr[ret], v2_t, cpu_env);
22424            break;
22425        }
22426        break;
22427    case OPC_ADDU_OB_DSP:
22428        switch (op2) {
22429        case OPC_RADDU_L_OB:
22430            check_dsp(ctx);
22431            gen_helper_raddu_l_ob(cpu_gpr[ret], v1_t);
22432            break;
22433        case OPC_SUBQ_PW:
22434            check_dsp(ctx);
22435            gen_helper_subq_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22436            break;
22437        case OPC_SUBQ_S_PW:
22438            check_dsp(ctx);
22439            gen_helper_subq_s_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22440            break;
22441        case OPC_SUBQ_QH:
22442            check_dsp(ctx);
22443            gen_helper_subq_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22444            break;
22445        case OPC_SUBQ_S_QH:
22446            check_dsp(ctx);
22447            gen_helper_subq_s_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22448            break;
22449        case OPC_SUBU_OB:
22450            check_dsp(ctx);
22451            gen_helper_subu_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22452            break;
22453        case OPC_SUBU_S_OB:
22454            check_dsp(ctx);
22455            gen_helper_subu_s_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22456            break;
22457        case OPC_SUBU_QH:
22458            check_dsp_r2(ctx);
22459            gen_helper_subu_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22460            break;
22461        case OPC_SUBU_S_QH:
22462            check_dsp_r2(ctx);
22463            gen_helper_subu_s_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22464            break;
22465        case OPC_SUBUH_OB:
22466            check_dsp_r2(ctx);
22467            gen_helper_subuh_ob(cpu_gpr[ret], v1_t, v2_t);
22468            break;
22469        case OPC_SUBUH_R_OB:
22470            check_dsp_r2(ctx);
22471            gen_helper_subuh_r_ob(cpu_gpr[ret], v1_t, v2_t);
22472            break;
22473        case OPC_ADDQ_PW:
22474            check_dsp(ctx);
22475            gen_helper_addq_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22476            break;
22477        case OPC_ADDQ_S_PW:
22478            check_dsp(ctx);
22479            gen_helper_addq_s_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22480            break;
22481        case OPC_ADDQ_QH:
22482            check_dsp(ctx);
22483            gen_helper_addq_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22484            break;
22485        case OPC_ADDQ_S_QH:
22486            check_dsp(ctx);
22487            gen_helper_addq_s_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22488            break;
22489        case OPC_ADDU_OB:
22490            check_dsp(ctx);
22491            gen_helper_addu_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22492            break;
22493        case OPC_ADDU_S_OB:
22494            check_dsp(ctx);
22495            gen_helper_addu_s_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22496            break;
22497        case OPC_ADDU_QH:
22498            check_dsp_r2(ctx);
22499            gen_helper_addu_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22500            break;
22501        case OPC_ADDU_S_QH:
22502            check_dsp_r2(ctx);
22503            gen_helper_addu_s_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22504            break;
22505        case OPC_ADDUH_OB:
22506            check_dsp_r2(ctx);
22507            gen_helper_adduh_ob(cpu_gpr[ret], v1_t, v2_t);
22508            break;
22509        case OPC_ADDUH_R_OB:
22510            check_dsp_r2(ctx);
22511            gen_helper_adduh_r_ob(cpu_gpr[ret], v1_t, v2_t);
22512            break;
22513        }
22514        break;
22515    case OPC_CMPU_EQ_OB_DSP:
22516        switch (op2) {
22517        case OPC_PRECR_OB_QH:
22518            check_dsp_r2(ctx);
22519            gen_helper_precr_ob_qh(cpu_gpr[ret], v1_t, v2_t);
22520            break;
22521        case OPC_PRECR_SRA_QH_PW:
22522            check_dsp_r2(ctx);
22523            {
22524                TCGv_i32 ret_t = tcg_const_i32(ret);
22525                gen_helper_precr_sra_qh_pw(v2_t, v1_t, v2_t, ret_t);
22526                tcg_temp_free_i32(ret_t);
22527                break;
22528            }
22529        case OPC_PRECR_SRA_R_QH_PW:
22530            check_dsp_r2(ctx);
22531            {
22532                TCGv_i32 sa_v = tcg_const_i32(ret);
22533                gen_helper_precr_sra_r_qh_pw(v2_t, v1_t, v2_t, sa_v);
22534                tcg_temp_free_i32(sa_v);
22535                break;
22536            }
22537        case OPC_PRECRQ_OB_QH:
22538            check_dsp(ctx);
22539            gen_helper_precrq_ob_qh(cpu_gpr[ret], v1_t, v2_t);
22540            break;
22541        case OPC_PRECRQ_PW_L:
22542            check_dsp(ctx);
22543            gen_helper_precrq_pw_l(cpu_gpr[ret], v1_t, v2_t);
22544            break;
22545        case OPC_PRECRQ_QH_PW:
22546            check_dsp(ctx);
22547            gen_helper_precrq_qh_pw(cpu_gpr[ret], v1_t, v2_t);
22548            break;
22549        case OPC_PRECRQ_RS_QH_PW:
22550            check_dsp(ctx);
22551            gen_helper_precrq_rs_qh_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22552            break;
22553        case OPC_PRECRQU_S_OB_QH:
22554            check_dsp(ctx);
22555            gen_helper_precrqu_s_ob_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22556            break;
22557        }
22558        break;
22559#endif
22560    }
22561
22562    tcg_temp_free(v1_t);
22563    tcg_temp_free(v2_t);
22564}
22565
22566static void gen_mipsdsp_shift(DisasContext *ctx, uint32_t opc,
22567                              int ret, int v1, int v2)
22568{
22569    uint32_t op2;
22570    TCGv t0;
22571    TCGv v1_t;
22572    TCGv v2_t;
22573
22574    if (ret == 0) {
22575        /* Treat as NOP. */
22576        return;
22577    }
22578
22579    t0 = tcg_temp_new();
22580    v1_t = tcg_temp_new();
22581    v2_t = tcg_temp_new();
22582
22583    tcg_gen_movi_tl(t0, v1);
22584    gen_load_gpr(v1_t, v1);
22585    gen_load_gpr(v2_t, v2);
22586
22587    switch (opc) {
22588    case OPC_SHLL_QB_DSP:
22589        {
22590            op2 = MASK_SHLL_QB(ctx->opcode);
22591            switch (op2) {
22592            case OPC_SHLL_QB:
22593                check_dsp(ctx);
22594                gen_helper_shll_qb(cpu_gpr[ret], t0, v2_t, cpu_env);
22595                break;
22596            case OPC_SHLLV_QB:
22597                check_dsp(ctx);
22598                gen_helper_shll_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22599                break;
22600            case OPC_SHLL_PH:
22601                check_dsp(ctx);
22602                gen_helper_shll_ph(cpu_gpr[ret], t0, v2_t, cpu_env);
22603                break;
22604            case OPC_SHLLV_PH:
22605                check_dsp(ctx);
22606                gen_helper_shll_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22607                break;
22608            case OPC_SHLL_S_PH:
22609                check_dsp(ctx);
22610                gen_helper_shll_s_ph(cpu_gpr[ret], t0, v2_t, cpu_env);
22611                break;
22612            case OPC_SHLLV_S_PH:
22613                check_dsp(ctx);
22614                gen_helper_shll_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22615                break;
22616            case OPC_SHLL_S_W:
22617                check_dsp(ctx);
22618                gen_helper_shll_s_w(cpu_gpr[ret], t0, v2_t, cpu_env);
22619                break;
22620            case OPC_SHLLV_S_W:
22621                check_dsp(ctx);
22622                gen_helper_shll_s_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22623                break;
22624            case OPC_SHRL_QB:
22625                check_dsp(ctx);
22626                gen_helper_shrl_qb(cpu_gpr[ret], t0, v2_t);
22627                break;
22628            case OPC_SHRLV_QB:
22629                check_dsp(ctx);
22630                gen_helper_shrl_qb(cpu_gpr[ret], v1_t, v2_t);
22631                break;
22632            case OPC_SHRL_PH:
22633                check_dsp_r2(ctx);
22634                gen_helper_shrl_ph(cpu_gpr[ret], t0, v2_t);
22635                break;
22636            case OPC_SHRLV_PH:
22637                check_dsp_r2(ctx);
22638                gen_helper_shrl_ph(cpu_gpr[ret], v1_t, v2_t);
22639                break;
22640            case OPC_SHRA_QB:
22641                check_dsp_r2(ctx);
22642                gen_helper_shra_qb(cpu_gpr[ret], t0, v2_t);
22643                break;
22644            case OPC_SHRA_R_QB:
22645                check_dsp_r2(ctx);
22646                gen_helper_shra_r_qb(cpu_gpr[ret], t0, v2_t);
22647                break;
22648            case OPC_SHRAV_QB:
22649                check_dsp_r2(ctx);
22650                gen_helper_shra_qb(cpu_gpr[ret], v1_t, v2_t);
22651                break;
22652            case OPC_SHRAV_R_QB:
22653                check_dsp_r2(ctx);
22654                gen_helper_shra_r_qb(cpu_gpr[ret], v1_t, v2_t);
22655                break;
22656            case OPC_SHRA_PH:
22657                check_dsp(ctx);
22658                gen_helper_shra_ph(cpu_gpr[ret], t0, v2_t);
22659                break;
22660            case OPC_SHRA_R_PH:
22661                check_dsp(ctx);
22662                gen_helper_shra_r_ph(cpu_gpr[ret], t0, v2_t);
22663                break;
22664            case OPC_SHRAV_PH:
22665                check_dsp(ctx);
22666                gen_helper_shra_ph(cpu_gpr[ret], v1_t, v2_t);
22667                break;
22668            case OPC_SHRAV_R_PH:
22669                check_dsp(ctx);
22670                gen_helper_shra_r_ph(cpu_gpr[ret], v1_t, v2_t);
22671                break;
22672            case OPC_SHRA_R_W:
22673                check_dsp(ctx);
22674                gen_helper_shra_r_w(cpu_gpr[ret], t0, v2_t);
22675                break;
22676            case OPC_SHRAV_R_W:
22677                check_dsp(ctx);
22678                gen_helper_shra_r_w(cpu_gpr[ret], v1_t, v2_t);
22679                break;
22680            default:            /* Invalid */
22681                MIPS_INVAL("MASK SHLL.QB");
22682                generate_exception_end(ctx, EXCP_RI);
22683                break;
22684            }
22685            break;
22686        }
22687#ifdef TARGET_MIPS64
22688    case OPC_SHLL_OB_DSP:
22689        op2 = MASK_SHLL_OB(ctx->opcode);
22690        switch (op2) {
22691        case OPC_SHLL_PW:
22692            check_dsp(ctx);
22693            gen_helper_shll_pw(cpu_gpr[ret], v2_t, t0, cpu_env);
22694            break;
22695        case OPC_SHLLV_PW:
22696            check_dsp(ctx);
22697            gen_helper_shll_pw(cpu_gpr[ret], v2_t, v1_t, cpu_env);
22698            break;
22699        case OPC_SHLL_S_PW:
22700            check_dsp(ctx);
22701            gen_helper_shll_s_pw(cpu_gpr[ret], v2_t, t0, cpu_env);
22702            break;
22703        case OPC_SHLLV_S_PW:
22704            check_dsp(ctx);
22705            gen_helper_shll_s_pw(cpu_gpr[ret], v2_t, v1_t, cpu_env);
22706            break;
22707        case OPC_SHLL_OB:
22708            check_dsp(ctx);
22709            gen_helper_shll_ob(cpu_gpr[ret], v2_t, t0, cpu_env);
22710            break;
22711        case OPC_SHLLV_OB:
22712            check_dsp(ctx);
22713            gen_helper_shll_ob(cpu_gpr[ret], v2_t, v1_t, cpu_env);
22714            break;
22715        case OPC_SHLL_QH:
22716            check_dsp(ctx);
22717            gen_helper_shll_qh(cpu_gpr[ret], v2_t, t0, cpu_env);
22718            break;
22719        case OPC_SHLLV_QH:
22720            check_dsp(ctx);
22721            gen_helper_shll_qh(cpu_gpr[ret], v2_t, v1_t, cpu_env);
22722            break;
22723        case OPC_SHLL_S_QH:
22724            check_dsp(ctx);
22725            gen_helper_shll_s_qh(cpu_gpr[ret], v2_t, t0, cpu_env);
22726            break;
22727        case OPC_SHLLV_S_QH:
22728            check_dsp(ctx);
22729            gen_helper_shll_s_qh(cpu_gpr[ret], v2_t, v1_t, cpu_env);
22730            break;
22731        case OPC_SHRA_OB:
22732            check_dsp_r2(ctx);
22733            gen_helper_shra_ob(cpu_gpr[ret], v2_t, t0);
22734            break;
22735        case OPC_SHRAV_OB:
22736            check_dsp_r2(ctx);
22737            gen_helper_shra_ob(cpu_gpr[ret], v2_t, v1_t);
22738            break;
22739        case OPC_SHRA_R_OB:
22740            check_dsp_r2(ctx);
22741            gen_helper_shra_r_ob(cpu_gpr[ret], v2_t, t0);
22742            break;
22743        case OPC_SHRAV_R_OB:
22744            check_dsp_r2(ctx);
22745            gen_helper_shra_r_ob(cpu_gpr[ret], v2_t, v1_t);
22746            break;
22747        case OPC_SHRA_PW:
22748            check_dsp(ctx);
22749            gen_helper_shra_pw(cpu_gpr[ret], v2_t, t0);
22750            break;
22751        case OPC_SHRAV_PW:
22752            check_dsp(ctx);
22753            gen_helper_shra_pw(cpu_gpr[ret], v2_t, v1_t);
22754            break;
22755        case OPC_SHRA_R_PW:
22756            check_dsp(ctx);
22757            gen_helper_shra_r_pw(cpu_gpr[ret], v2_t, t0);
22758            break;
22759        case OPC_SHRAV_R_PW:
22760            check_dsp(ctx);
22761            gen_helper_shra_r_pw(cpu_gpr[ret], v2_t, v1_t);
22762            break;
22763        case OPC_SHRA_QH:
22764            check_dsp(ctx);
22765            gen_helper_shra_qh(cpu_gpr[ret], v2_t, t0);
22766            break;
22767        case OPC_SHRAV_QH:
22768            check_dsp(ctx);
22769            gen_helper_shra_qh(cpu_gpr[ret], v2_t, v1_t);
22770            break;
22771        case OPC_SHRA_R_QH:
22772            check_dsp(ctx);
22773            gen_helper_shra_r_qh(cpu_gpr[ret], v2_t, t0);
22774            break;
22775        case OPC_SHRAV_R_QH:
22776            check_dsp(ctx);
22777            gen_helper_shra_r_qh(cpu_gpr[ret], v2_t, v1_t);
22778            break;
22779        case OPC_SHRL_OB:
22780            check_dsp(ctx);
22781            gen_helper_shrl_ob(cpu_gpr[ret], v2_t, t0);
22782            break;
22783        case OPC_SHRLV_OB:
22784            check_dsp(ctx);
22785            gen_helper_shrl_ob(cpu_gpr[ret], v2_t, v1_t);
22786            break;
22787        case OPC_SHRL_QH:
22788            check_dsp_r2(ctx);
22789            gen_helper_shrl_qh(cpu_gpr[ret], v2_t, t0);
22790            break;
22791        case OPC_SHRLV_QH:
22792            check_dsp_r2(ctx);
22793            gen_helper_shrl_qh(cpu_gpr[ret], v2_t, v1_t);
22794            break;
22795        default:            /* Invalid */
22796            MIPS_INVAL("MASK SHLL.OB");
22797            generate_exception_end(ctx, EXCP_RI);
22798            break;
22799        }
22800        break;
22801#endif
22802    }
22803
22804    tcg_temp_free(t0);
22805    tcg_temp_free(v1_t);
22806    tcg_temp_free(v2_t);
22807}
22808
22809static void gen_mipsdsp_multiply(DisasContext *ctx, uint32_t op1, uint32_t op2,
22810                                 int ret, int v1, int v2, int check_ret)
22811{
22812    TCGv_i32 t0;
22813    TCGv v1_t;
22814    TCGv v2_t;
22815
22816    if ((ret == 0) && (check_ret == 1)) {
22817        /* Treat as NOP. */
22818        return;
22819    }
22820
22821    t0 = tcg_temp_new_i32();
22822    v1_t = tcg_temp_new();
22823    v2_t = tcg_temp_new();
22824
22825    tcg_gen_movi_i32(t0, ret);
22826    gen_load_gpr(v1_t, v1);
22827    gen_load_gpr(v2_t, v2);
22828
22829    switch (op1) {
22830    /* OPC_MULT_G_2E, OPC_ADDUH_QB_DSP, OPC_MUL_PH_DSP have
22831     * the same mask and op1. */
22832    case OPC_MULT_G_2E:
22833        check_dsp_r2(ctx);
22834        switch (op2) {
22835        case  OPC_MUL_PH:
22836            gen_helper_mul_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22837            break;
22838        case  OPC_MUL_S_PH:
22839            gen_helper_mul_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22840            break;
22841        case OPC_MULQ_S_W:
22842            gen_helper_mulq_s_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22843            break;
22844        case OPC_MULQ_RS_W:
22845            gen_helper_mulq_rs_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22846            break;
22847        }
22848        break;
22849    case OPC_DPA_W_PH_DSP:
22850        switch (op2) {
22851        case OPC_DPAU_H_QBL:
22852            check_dsp(ctx);
22853            gen_helper_dpau_h_qbl(t0, v1_t, v2_t, cpu_env);
22854            break;
22855        case OPC_DPAU_H_QBR:
22856            check_dsp(ctx);
22857            gen_helper_dpau_h_qbr(t0, v1_t, v2_t, cpu_env);
22858            break;
22859        case OPC_DPSU_H_QBL:
22860            check_dsp(ctx);
22861            gen_helper_dpsu_h_qbl(t0, v1_t, v2_t, cpu_env);
22862            break;
22863        case OPC_DPSU_H_QBR:
22864            check_dsp(ctx);
22865            gen_helper_dpsu_h_qbr(t0, v1_t, v2_t, cpu_env);
22866            break;
22867        case OPC_DPA_W_PH:
22868            check_dsp_r2(ctx);
22869            gen_helper_dpa_w_ph(t0, v1_t, v2_t, cpu_env);
22870            break;
22871        case OPC_DPAX_W_PH:
22872            check_dsp_r2(ctx);
22873            gen_helper_dpax_w_ph(t0, v1_t, v2_t, cpu_env);
22874            break;
22875        case OPC_DPAQ_S_W_PH:
22876            check_dsp(ctx);
22877            gen_helper_dpaq_s_w_ph(t0, v1_t, v2_t, cpu_env);
22878            break;
22879        case OPC_DPAQX_S_W_PH:
22880            check_dsp_r2(ctx);
22881            gen_helper_dpaqx_s_w_ph(t0, v1_t, v2_t, cpu_env);
22882            break;
22883        case OPC_DPAQX_SA_W_PH:
22884            check_dsp_r2(ctx);
22885            gen_helper_dpaqx_sa_w_ph(t0, v1_t, v2_t, cpu_env);
22886            break;
22887        case OPC_DPS_W_PH:
22888            check_dsp_r2(ctx);
22889            gen_helper_dps_w_ph(t0, v1_t, v2_t, cpu_env);
22890            break;
22891        case OPC_DPSX_W_PH:
22892            check_dsp_r2(ctx);
22893            gen_helper_dpsx_w_ph(t0, v1_t, v2_t, cpu_env);
22894            break;
22895        case OPC_DPSQ_S_W_PH:
22896            check_dsp(ctx);
22897            gen_helper_dpsq_s_w_ph(t0, v1_t, v2_t, cpu_env);
22898            break;
22899        case OPC_DPSQX_S_W_PH:
22900            check_dsp_r2(ctx);
22901            gen_helper_dpsqx_s_w_ph(t0, v1_t, v2_t, cpu_env);
22902            break;
22903        case OPC_DPSQX_SA_W_PH:
22904            check_dsp_r2(ctx);
22905            gen_helper_dpsqx_sa_w_ph(t0, v1_t, v2_t, cpu_env);
22906            break;
22907        case OPC_MULSAQ_S_W_PH:
22908            check_dsp(ctx);
22909            gen_helper_mulsaq_s_w_ph(t0, v1_t, v2_t, cpu_env);
22910            break;
22911        case OPC_DPAQ_SA_L_W:
22912            check_dsp(ctx);
22913            gen_helper_dpaq_sa_l_w(t0, v1_t, v2_t, cpu_env);
22914            break;
22915        case OPC_DPSQ_SA_L_W:
22916            check_dsp(ctx);
22917            gen_helper_dpsq_sa_l_w(t0, v1_t, v2_t, cpu_env);
22918            break;
22919        case OPC_MAQ_S_W_PHL:
22920            check_dsp(ctx);
22921            gen_helper_maq_s_w_phl(t0, v1_t, v2_t, cpu_env);
22922            break;
22923        case OPC_MAQ_S_W_PHR:
22924            check_dsp(ctx);
22925            gen_helper_maq_s_w_phr(t0, v1_t, v2_t, cpu_env);
22926            break;
22927        case OPC_MAQ_SA_W_PHL:
22928            check_dsp(ctx);
22929            gen_helper_maq_sa_w_phl(t0, v1_t, v2_t, cpu_env);
22930            break;
22931        case OPC_MAQ_SA_W_PHR:
22932            check_dsp(ctx);
22933            gen_helper_maq_sa_w_phr(t0, v1_t, v2_t, cpu_env);
22934            break;
22935        case OPC_MULSA_W_PH:
22936            check_dsp_r2(ctx);
22937            gen_helper_mulsa_w_ph(t0, v1_t, v2_t, cpu_env);
22938            break;
22939        }
22940        break;
22941#ifdef TARGET_MIPS64
22942    case OPC_DPAQ_W_QH_DSP:
22943        {
22944            int ac = ret & 0x03;
22945            tcg_gen_movi_i32(t0, ac);
22946
22947            switch (op2) {
22948            case OPC_DMADD:
22949                check_dsp(ctx);
22950                gen_helper_dmadd(v1_t, v2_t, t0, cpu_env);
22951                break;
22952            case OPC_DMADDU:
22953                check_dsp(ctx);
22954                gen_helper_dmaddu(v1_t, v2_t, t0, cpu_env);
22955                break;
22956            case OPC_DMSUB:
22957                check_dsp(ctx);
22958                gen_helper_dmsub(v1_t, v2_t, t0, cpu_env);
22959                break;
22960            case OPC_DMSUBU:
22961                check_dsp(ctx);
22962                gen_helper_dmsubu(v1_t, v2_t, t0, cpu_env);
22963                break;
22964            case OPC_DPA_W_QH:
22965                check_dsp_r2(ctx);
22966                gen_helper_dpa_w_qh(v1_t, v2_t, t0, cpu_env);
22967                break;
22968            case OPC_DPAQ_S_W_QH:
22969                check_dsp(ctx);
22970                gen_helper_dpaq_s_w_qh(v1_t, v2_t, t0, cpu_env);
22971                break;
22972            case OPC_DPAQ_SA_L_PW:
22973                check_dsp(ctx);
22974                gen_helper_dpaq_sa_l_pw(v1_t, v2_t, t0, cpu_env);
22975                break;
22976            case OPC_DPAU_H_OBL:
22977                check_dsp(ctx);
22978                gen_helper_dpau_h_obl(v1_t, v2_t, t0, cpu_env);
22979                break;
22980            case OPC_DPAU_H_OBR:
22981                check_dsp(ctx);
22982                gen_helper_dpau_h_obr(v1_t, v2_t, t0, cpu_env);
22983                break;
22984            case OPC_DPS_W_QH:
22985                check_dsp_r2(ctx);
22986                gen_helper_dps_w_qh(v1_t, v2_t, t0, cpu_env);
22987                break;
22988            case OPC_DPSQ_S_W_QH:
22989                check_dsp(ctx);
22990                gen_helper_dpsq_s_w_qh(v1_t, v2_t, t0, cpu_env);
22991                break;
22992            case OPC_DPSQ_SA_L_PW:
22993                check_dsp(ctx);
22994                gen_helper_dpsq_sa_l_pw(v1_t, v2_t, t0, cpu_env);
22995                break;
22996            case OPC_DPSU_H_OBL:
22997                check_dsp(ctx);
22998                gen_helper_dpsu_h_obl(v1_t, v2_t, t0, cpu_env);
22999                break;
23000            case OPC_DPSU_H_OBR:
23001                check_dsp(ctx);
23002                gen_helper_dpsu_h_obr(v1_t, v2_t, t0, cpu_env);
23003                break;
23004            case OPC_MAQ_S_L_PWL:
23005                check_dsp(ctx);
23006                gen_helper_maq_s_l_pwl(v1_t, v2_t, t0, cpu_env);
23007                break;
23008            case OPC_MAQ_S_L_PWR:
23009                check_dsp(ctx);
23010                gen_helper_maq_s_l_pwr(v1_t, v2_t, t0, cpu_env);
23011                break;
23012            case OPC_MAQ_S_W_QHLL:
23013                check_dsp(ctx);
23014                gen_helper_maq_s_w_qhll(v1_t, v2_t, t0, cpu_env);
23015                break;
23016            case OPC_MAQ_SA_W_QHLL:
23017                check_dsp(ctx);
23018                gen_helper_maq_sa_w_qhll(v1_t, v2_t, t0, cpu_env);
23019                break;
23020            case OPC_MAQ_S_W_QHLR:
23021                check_dsp(ctx);
23022                gen_helper_maq_s_w_qhlr(v1_t, v2_t, t0, cpu_env);
23023                break;
23024            case OPC_MAQ_SA_W_QHLR:
23025                check_dsp(ctx);
23026                gen_helper_maq_sa_w_qhlr(v1_t, v2_t, t0, cpu_env);
23027                break;
23028            case OPC_MAQ_S_W_QHRL:
23029                check_dsp(ctx);
23030                gen_helper_maq_s_w_qhrl(v1_t, v2_t, t0, cpu_env);
23031                break;
23032            case OPC_MAQ_SA_W_QHRL:
23033                check_dsp(ctx);
23034                gen_helper_maq_sa_w_qhrl(v1_t, v2_t, t0, cpu_env);
23035                break;
23036            case OPC_MAQ_S_W_QHRR:
23037                check_dsp(ctx);
23038                gen_helper_maq_s_w_qhrr(v1_t, v2_t, t0, cpu_env);
23039                break;
23040            case OPC_MAQ_SA_W_QHRR:
23041                check_dsp(ctx);
23042                gen_helper_maq_sa_w_qhrr(v1_t, v2_t, t0, cpu_env);
23043                break;
23044            case OPC_MULSAQ_S_L_PW:
23045                check_dsp(ctx);
23046                gen_helper_mulsaq_s_l_pw(v1_t, v2_t, t0, cpu_env);
23047                break;
23048            case OPC_MULSAQ_S_W_QH:
23049                check_dsp(ctx);
23050                gen_helper_mulsaq_s_w_qh(v1_t, v2_t, t0, cpu_env);
23051                break;
23052            }
23053        }
23054        break;
23055#endif
23056    case OPC_ADDU_QB_DSP:
23057        switch (op2) {
23058        case OPC_MULEU_S_PH_QBL:
23059            check_dsp(ctx);
23060            gen_helper_muleu_s_ph_qbl(cpu_gpr[ret], v1_t, v2_t, cpu_env);
23061            break;
23062        case OPC_MULEU_S_PH_QBR:
23063            check_dsp(ctx);
23064            gen_helper_muleu_s_ph_qbr(cpu_gpr[ret], v1_t, v2_t, cpu_env);
23065            break;
23066        case OPC_MULQ_RS_PH:
23067            check_dsp(ctx);
23068            gen_helper_mulq_rs_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
23069            break;
23070        case OPC_MULEQ_S_W_PHL:
23071            check_dsp(ctx);
23072            gen_helper_muleq_s_w_phl(cpu_gpr[ret], v1_t, v2_t, cpu_env);
23073            break;
23074        case OPC_MULEQ_S_W_PHR:
23075            check_dsp(ctx);
23076            gen_helper_muleq_s_w_phr(cpu_gpr[ret], v1_t, v2_t, cpu_env);
23077            break;
23078        case OPC_MULQ_S_PH:
23079            check_dsp_r2(ctx);
23080            gen_helper_mulq_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
23081            break;
23082        }
23083        break;
23084#ifdef TARGET_MIPS64
23085    case OPC_ADDU_OB_DSP:
23086        switch (op2) {
23087        case OPC_MULEQ_S_PW_QHL:
23088            check_dsp(ctx);
23089            gen_helper_muleq_s_pw_qhl(cpu_gpr[ret], v1_t, v2_t, cpu_env);
23090            break;
23091        case OPC_MULEQ_S_PW_QHR:
23092            check_dsp(ctx);
23093            gen_helper_muleq_s_pw_qhr(cpu_gpr[ret], v1_t, v2_t, cpu_env);
23094            break;
23095        case OPC_MULEU_S_QH_OBL:
23096            check_dsp(ctx);
23097            gen_helper_muleu_s_qh_obl(cpu_gpr[ret], v1_t, v2_t, cpu_env);
23098            break;
23099        case OPC_MULEU_S_QH_OBR:
23100            check_dsp(ctx);
23101            gen_helper_muleu_s_qh_obr(cpu_gpr[ret], v1_t, v2_t, cpu_env);
23102            break;
23103        case OPC_MULQ_RS_QH:
23104            check_dsp(ctx);
23105            gen_helper_mulq_rs_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
23106            break;
23107        }
23108        break;
23109#endif
23110    }
23111
23112    tcg_temp_free_i32(t0);
23113    tcg_temp_free(v1_t);
23114    tcg_temp_free(v2_t);
23115}
23116
23117static void gen_mipsdsp_bitinsn(DisasContext *ctx, uint32_t op1, uint32_t op2,
23118                                int ret, int val)
23119{
23120    int16_t imm;
23121    TCGv t0;
23122    TCGv val_t;
23123
23124    if (ret == 0) {
23125        /* Treat as NOP. */
23126        return;
23127    }
23128
23129    t0 = tcg_temp_new();
23130    val_t = tcg_temp_new();
23131    gen_load_gpr(val_t, val);
23132
23133    switch (op1) {
23134    case OPC_ABSQ_S_PH_DSP:
23135        switch (op2) {
23136        case OPC_BITREV:
23137            check_dsp(ctx);
23138            gen_helper_bitrev(cpu_gpr[ret], val_t);
23139            break;
23140        case OPC_REPL_QB:
23141            check_dsp(ctx);
23142            {
23143                target_long result;
23144                imm = (ctx->opcode >> 16) & 0xFF;
23145                result = (uint32_t)imm << 24 |
23146                         (uint32_t)imm << 16 |
23147                         (uint32_t)imm << 8  |
23148                         (uint32_t)imm;
23149                result = (int32_t)result;
23150                tcg_gen_movi_tl(cpu_gpr[ret], result);
23151            }
23152            break;
23153        case OPC_REPLV_QB:
23154            check_dsp(ctx);
23155            tcg_gen_ext8u_tl(cpu_gpr[ret], val_t);
23156            tcg_gen_shli_tl(t0, cpu_gpr[ret], 8);
23157            tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
23158            tcg_gen_shli_tl(t0, cpu_gpr[ret], 16);
23159            tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
23160            tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]);
23161            break;
23162        case OPC_REPL_PH:
23163            check_dsp(ctx);
23164            {
23165                imm = (ctx->opcode >> 16) & 0x03FF;
23166                imm = (int16_t)(imm << 6) >> 6;
23167                tcg_gen_movi_tl(cpu_gpr[ret], \
23168                                (target_long)((int32_t)imm << 16 | \
23169                                (uint16_t)imm));
23170            }
23171            break;
23172        case OPC_REPLV_PH:
23173            check_dsp(ctx);
23174            tcg_gen_ext16u_tl(cpu_gpr[ret], val_t);
23175            tcg_gen_shli_tl(t0, cpu_gpr[ret], 16);
23176            tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
23177            tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]);
23178            break;
23179        }
23180        break;
23181#ifdef TARGET_MIPS64
23182    case OPC_ABSQ_S_QH_DSP:
23183        switch (op2) {
23184        case OPC_REPL_OB:
23185            check_dsp(ctx);
23186            {
23187                target_long temp;
23188
23189                imm = (ctx->opcode >> 16) & 0xFF;
23190                temp = ((uint64_t)imm << 8) | (uint64_t)imm;
23191                temp = (temp << 16) | temp;
23192                temp = (temp << 32) | temp;
23193                tcg_gen_movi_tl(cpu_gpr[ret], temp);
23194                break;
23195            }
23196        case OPC_REPL_PW:
23197            check_dsp(ctx);
23198            {
23199                target_long temp;
23200
23201                imm = (ctx->opcode >> 16) & 0x03FF;
23202                imm = (int16_t)(imm << 6) >> 6;
23203                temp = ((target_long)imm << 32) \
23204                       | ((target_long)imm & 0xFFFFFFFF);
23205                tcg_gen_movi_tl(cpu_gpr[ret], temp);
23206                break;
23207            }
23208        case OPC_REPL_QH:
23209            check_dsp(ctx);
23210            {
23211                target_long temp;
23212
23213                imm = (ctx->opcode >> 16) & 0x03FF;
23214                imm = (int16_t)(imm << 6) >> 6;
23215
23216                temp = ((uint64_t)(uint16_t)imm << 48) |
23217                       ((uint64_t)(uint16_t)imm << 32) |
23218                       ((uint64_t)(uint16_t)imm << 16) |
23219                       (uint64_t)(uint16_t)imm;
23220                tcg_gen_movi_tl(cpu_gpr[ret], temp);
23221                break;
23222            }
23223        case OPC_REPLV_OB:
23224            check_dsp(ctx);
23225            tcg_gen_ext8u_tl(cpu_gpr[ret], val_t);
23226            tcg_gen_shli_tl(t0, cpu_gpr[ret], 8);
23227            tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
23228            tcg_gen_shli_tl(t0, cpu_gpr[ret], 16);
23229            tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
23230            tcg_gen_shli_tl(t0, cpu_gpr[ret], 32);
23231            tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
23232            break;
23233        case OPC_REPLV_PW:
23234            check_dsp(ctx);
23235            tcg_gen_ext32u_i64(cpu_gpr[ret], val_t);
23236            tcg_gen_shli_tl(t0, cpu_gpr[ret], 32);
23237            tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
23238            break;
23239        case OPC_REPLV_QH:
23240            check_dsp(ctx);
23241            tcg_gen_ext16u_tl(cpu_gpr[ret], val_t);
23242            tcg_gen_shli_tl(t0, cpu_gpr[ret], 16);
23243            tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
23244            tcg_gen_shli_tl(t0, cpu_gpr[ret], 32);
23245            tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
23246            break;
23247        }
23248        break;
23249#endif
23250    }
23251    tcg_temp_free(t0);
23252    tcg_temp_free(val_t);
23253}
23254
23255static void gen_mipsdsp_add_cmp_pick(DisasContext *ctx,
23256                                     uint32_t op1, uint32_t op2,
23257                                     int ret, int v1, int v2, int check_ret)
23258{
23259    TCGv t1;
23260    TCGv v1_t;
23261    TCGv v2_t;
23262
23263    if ((ret == 0) && (check_ret == 1)) {
23264        /* Treat as NOP. */
23265        return;
23266    }
23267
23268    t1 = tcg_temp_new();
23269    v1_t = tcg_temp_new();
23270    v2_t = tcg_temp_new();
23271
23272    gen_load_gpr(v1_t, v1);
23273    gen_load_gpr(v2_t, v2);
23274
23275    switch (op1) {
23276    case OPC_CMPU_EQ_QB_DSP:
23277        switch (op2) {
23278        case OPC_CMPU_EQ_QB:
23279            check_dsp(ctx);
23280            gen_helper_cmpu_eq_qb(v1_t, v2_t, cpu_env);
23281            break;
23282        case OPC_CMPU_LT_QB:
23283            check_dsp(ctx);
23284            gen_helper_cmpu_lt_qb(v1_t, v2_t, cpu_env);
23285            break;
23286        case OPC_CMPU_LE_QB:
23287            check_dsp(ctx);
23288            gen_helper_cmpu_le_qb(v1_t, v2_t, cpu_env);
23289            break;
23290        case OPC_CMPGU_EQ_QB:
23291            check_dsp(ctx);
23292            gen_helper_cmpgu_eq_qb(cpu_gpr[ret], v1_t, v2_t);
23293            break;
23294        case OPC_CMPGU_LT_QB:
23295            check_dsp(ctx);
23296            gen_helper_cmpgu_lt_qb(cpu_gpr[ret], v1_t, v2_t);
23297            break;
23298        case OPC_CMPGU_LE_QB:
23299            check_dsp(ctx);
23300            gen_helper_cmpgu_le_qb(cpu_gpr[ret], v1_t, v2_t);
23301            break;
23302        case OPC_CMPGDU_EQ_QB:
23303            check_dsp_r2(ctx);
23304            gen_helper_cmpgu_eq_qb(t1, v1_t, v2_t);
23305            tcg_gen_mov_tl(cpu_gpr[ret], t1);
23306            tcg_gen_andi_tl(cpu_dspctrl, cpu_dspctrl, 0xF0FFFFFF);
23307            tcg_gen_shli_tl(t1, t1, 24);
23308            tcg_gen_or_tl(cpu_dspctrl, cpu_dspctrl, t1);
23309            break;
23310        case OPC_CMPGDU_LT_QB:
23311            check_dsp_r2(ctx);
23312            gen_helper_cmpgu_lt_qb(t1, v1_t, v2_t);
23313            tcg_gen_mov_tl(cpu_gpr[ret], t1);
23314            tcg_gen_andi_tl(cpu_dspctrl, cpu_dspctrl, 0xF0FFFFFF);
23315            tcg_gen_shli_tl(t1, t1, 24);
23316            tcg_gen_or_tl(cpu_dspctrl, cpu_dspctrl, t1);
23317            break;
23318        case OPC_CMPGDU_LE_QB:
23319            check_dsp_r2(ctx);
23320            gen_helper_cmpgu_le_qb(t1, v1_t, v2_t);
23321            tcg_gen_mov_tl(cpu_gpr[ret], t1);
23322            tcg_gen_andi_tl(cpu_dspctrl, cpu_dspctrl, 0xF0FFFFFF);
23323            tcg_gen_shli_tl(t1, t1, 24);
23324            tcg_gen_or_tl(cpu_dspctrl, cpu_dspctrl, t1);
23325            break;
23326        case OPC_CMP_EQ_PH:
23327            check_dsp(ctx);
23328            gen_helper_cmp_eq_ph(v1_t, v2_t, cpu_env);
23329            break;
23330        case OPC_CMP_LT_PH:
23331            check_dsp(ctx);
23332            gen_helper_cmp_lt_ph(v1_t, v2_t, cpu_env);
23333            break;
23334        case OPC_CMP_LE_PH:
23335            check_dsp(ctx);
23336            gen_helper_cmp_le_ph(v1_t, v2_t, cpu_env);
23337            break;
23338        case OPC_PICK_QB:
23339            check_dsp(ctx);
23340            gen_helper_pick_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
23341            break;
23342        case OPC_PICK_PH:
23343            check_dsp(ctx);
23344            gen_helper_pick_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
23345            break;
23346        case OPC_PACKRL_PH:
23347            check_dsp(ctx);
23348            gen_helper_packrl_ph(cpu_gpr[ret], v1_t, v2_t);
23349            break;
23350        }
23351        break;
23352#ifdef TARGET_MIPS64
23353    case OPC_CMPU_EQ_OB_DSP:
23354        switch (op2) {
23355        case OPC_CMP_EQ_PW:
23356            check_dsp(ctx);
23357            gen_helper_cmp_eq_pw(v1_t, v2_t, cpu_env);
23358            break;
23359        case OPC_CMP_LT_PW:
23360            check_dsp(ctx);
23361            gen_helper_cmp_lt_pw(v1_t, v2_t, cpu_env);
23362            break;
23363        case OPC_CMP_LE_PW:
23364            check_dsp(ctx);
23365            gen_helper_cmp_le_pw(v1_t, v2_t, cpu_env);
23366            break;
23367        case OPC_CMP_EQ_QH:
23368            check_dsp(ctx);
23369            gen_helper_cmp_eq_qh(v1_t, v2_t, cpu_env);
23370            break;
23371        case OPC_CMP_LT_QH:
23372            check_dsp(ctx);
23373            gen_helper_cmp_lt_qh(v1_t, v2_t, cpu_env);
23374            break;
23375        case OPC_CMP_LE_QH:
23376            check_dsp(ctx);
23377            gen_helper_cmp_le_qh(v1_t, v2_t, cpu_env);
23378            break;
23379        case OPC_CMPGDU_EQ_OB:
23380            check_dsp_r2(ctx);
23381            gen_helper_cmpgdu_eq_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
23382            break;
23383        case OPC_CMPGDU_LT_OB:
23384            check_dsp_r2(ctx);
23385            gen_helper_cmpgdu_lt_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
23386            break;
23387        case OPC_CMPGDU_LE_OB:
23388            check_dsp_r2(ctx);
23389            gen_helper_cmpgdu_le_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
23390            break;
23391        case OPC_CMPGU_EQ_OB:
23392            check_dsp(ctx);
23393            gen_helper_cmpgu_eq_ob(cpu_gpr[ret], v1_t, v2_t);
23394            break;
23395        case OPC_CMPGU_LT_OB:
23396            check_dsp(ctx);
23397            gen_helper_cmpgu_lt_ob(cpu_gpr[ret], v1_t, v2_t);
23398            break;
23399        case OPC_CMPGU_LE_OB:
23400            check_dsp(ctx);
23401            gen_helper_cmpgu_le_ob(cpu_gpr[ret], v1_t, v2_t);
23402            break;
23403        case OPC_CMPU_EQ_OB:
23404            check_dsp(ctx);
23405            gen_helper_cmpu_eq_ob(v1_t, v2_t, cpu_env);
23406            break;
23407        case OPC_CMPU_LT_OB:
23408            check_dsp(ctx);
23409            gen_helper_cmpu_lt_ob(v1_t, v2_t, cpu_env);
23410            break;
23411        case OPC_CMPU_LE_OB:
23412            check_dsp(ctx);
23413            gen_helper_cmpu_le_ob(v1_t, v2_t, cpu_env);
23414            break;
23415        case OPC_PACKRL_PW:
23416            check_dsp(ctx);
23417            gen_helper_packrl_pw(cpu_gpr[ret], v1_t, v2_t);
23418            break;
23419        case OPC_PICK_OB:
23420            check_dsp(ctx);
23421            gen_helper_pick_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
23422            break;
23423        case OPC_PICK_PW:
23424            check_dsp(ctx);
23425            gen_helper_pick_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
23426            break;
23427        case OPC_PICK_QH:
23428            check_dsp(ctx);
23429            gen_helper_pick_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
23430            break;
23431        }
23432        break;
23433#endif
23434    }
23435
23436    tcg_temp_free(t1);
23437    tcg_temp_free(v1_t);
23438    tcg_temp_free(v2_t);
23439}
23440
23441static void gen_mipsdsp_append(CPUMIPSState *env, DisasContext *ctx,
23442                               uint32_t op1, int rt, int rs, int sa)
23443{
23444    TCGv t0;
23445
23446    check_dsp_r2(ctx);
23447
23448    if (rt == 0) {
23449        /* Treat as NOP. */
23450        return;
23451    }
23452
23453    t0 = tcg_temp_new();
23454    gen_load_gpr(t0, rs);
23455
23456    switch (op1) {
23457    case OPC_APPEND_DSP:
23458        switch (MASK_APPEND(ctx->opcode)) {
23459        case OPC_APPEND:
23460            if (sa != 0) {
23461                tcg_gen_deposit_tl(cpu_gpr[rt], t0, cpu_gpr[rt], sa, 32 - sa);
23462            }
23463            tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
23464            break;
23465        case OPC_PREPEND:
23466            if (sa != 0) {
23467                tcg_gen_ext32u_tl(cpu_gpr[rt], cpu_gpr[rt]);
23468                tcg_gen_shri_tl(cpu_gpr[rt], cpu_gpr[rt], sa);
23469                tcg_gen_shli_tl(t0, t0, 32 - sa);
23470                tcg_gen_or_tl(cpu_gpr[rt], cpu_gpr[rt], t0);
23471            }
23472            tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
23473            break;
23474        case OPC_BALIGN:
23475            sa &= 3;
23476            if (sa != 0 && sa != 2) {
23477                tcg_gen_shli_tl(cpu_gpr[rt], cpu_gpr[rt], 8 * sa);
23478                tcg_gen_ext32u_tl(t0, t0);
23479                tcg_gen_shri_tl(t0, t0, 8 * (4 - sa));
23480                tcg_gen_or_tl(cpu_gpr[rt], cpu_gpr[rt], t0);
23481            }
23482            tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
23483            break;
23484        default:            /* Invalid */
23485            MIPS_INVAL("MASK APPEND");
23486            generate_exception_end(ctx, EXCP_RI);
23487            break;
23488        }
23489        break;
23490#ifdef TARGET_MIPS64
23491    case OPC_DAPPEND_DSP:
23492        switch (MASK_DAPPEND(ctx->opcode)) {
23493        case OPC_DAPPEND:
23494            if (sa != 0) {
23495                tcg_gen_deposit_tl(cpu_gpr[rt], t0, cpu_gpr[rt], sa, 64 - sa);
23496            }
23497            break;
23498        case OPC_PREPENDD:
23499            tcg_gen_shri_tl(cpu_gpr[rt], cpu_gpr[rt], 0x20 | sa);
23500            tcg_gen_shli_tl(t0, t0, 64 - (0x20 | sa));
23501            tcg_gen_or_tl(cpu_gpr[rt], t0, t0);
23502            break;
23503        case OPC_PREPENDW:
23504            if (sa != 0) {
23505                tcg_gen_shri_tl(cpu_gpr[rt], cpu_gpr[rt], sa);
23506                tcg_gen_shli_tl(t0, t0, 64 - sa);
23507                tcg_gen_or_tl(cpu_gpr[rt], cpu_gpr[rt], t0);
23508            }
23509            break;
23510        case OPC_DBALIGN:
23511            sa &= 7;
23512            if (sa != 0 && sa != 2 && sa != 4) {
23513                tcg_gen_shli_tl(cpu_gpr[rt], cpu_gpr[rt], 8 * sa);
23514                tcg_gen_shri_tl(t0, t0, 8 * (8 - sa));
23515                tcg_gen_or_tl(cpu_gpr[rt], cpu_gpr[rt], t0);
23516            }
23517            break;
23518        default:            /* Invalid */
23519            MIPS_INVAL("MASK DAPPEND");
23520            generate_exception_end(ctx, EXCP_RI);
23521            break;
23522        }
23523        break;
23524#endif
23525    }
23526    tcg_temp_free(t0);
23527}
23528
23529static void gen_mipsdsp_accinsn(DisasContext *ctx, uint32_t op1, uint32_t op2,
23530                                int ret, int v1, int v2, int check_ret)
23531
23532{
23533    TCGv t0;
23534    TCGv t1;
23535    TCGv v1_t;
23536    TCGv v2_t;
23537    int16_t imm;
23538
23539    if ((ret == 0) && (check_ret == 1)) {
23540        /* Treat as NOP. */
23541        return;
23542    }
23543
23544    t0 = tcg_temp_new();
23545    t1 = tcg_temp_new();
23546    v1_t = tcg_temp_new();
23547    v2_t = tcg_temp_new();
23548
23549    gen_load_gpr(v1_t, v1);
23550    gen_load_gpr(v2_t, v2);
23551
23552    switch (op1) {
23553    case OPC_EXTR_W_DSP:
23554        check_dsp(ctx);
23555        switch (op2) {
23556        case OPC_EXTR_W:
23557            tcg_gen_movi_tl(t0, v2);
23558            tcg_gen_movi_tl(t1, v1);
23559            gen_helper_extr_w(cpu_gpr[ret], t0, t1, cpu_env);
23560            break;
23561        case OPC_EXTR_R_W:
23562            tcg_gen_movi_tl(t0, v2);
23563            tcg_gen_movi_tl(t1, v1);
23564            gen_helper_extr_r_w(cpu_gpr[ret], t0, t1, cpu_env);
23565            break;
23566        case OPC_EXTR_RS_W:
23567            tcg_gen_movi_tl(t0, v2);
23568            tcg_gen_movi_tl(t1, v1);
23569            gen_helper_extr_rs_w(cpu_gpr[ret], t0, t1, cpu_env);
23570            break;
23571        case OPC_EXTR_S_H:
23572            tcg_gen_movi_tl(t0, v2);
23573            tcg_gen_movi_tl(t1, v1);
23574            gen_helper_extr_s_h(cpu_gpr[ret], t0, t1, cpu_env);
23575            break;
23576        case OPC_EXTRV_S_H:
23577            tcg_gen_movi_tl(t0, v2);
23578            gen_helper_extr_s_h(cpu_gpr[ret], t0, v1_t, cpu_env);
23579            break;
23580        case OPC_EXTRV_W:
23581            tcg_gen_movi_tl(t0, v2);
23582            gen_helper_extr_w(cpu_gpr[ret], t0, v1_t, cpu_env);
23583            break;
23584        case OPC_EXTRV_R_W:
23585            tcg_gen_movi_tl(t0, v2);
23586            gen_helper_extr_r_w(cpu_gpr[ret], t0, v1_t, cpu_env);
23587            break;
23588        case OPC_EXTRV_RS_W:
23589            tcg_gen_movi_tl(t0, v2);
23590            gen_helper_extr_rs_w(cpu_gpr[ret], t0, v1_t, cpu_env);
23591            break;
23592        case OPC_EXTP:
23593            tcg_gen_movi_tl(t0, v2);
23594            tcg_gen_movi_tl(t1, v1);
23595            gen_helper_extp(cpu_gpr[ret], t0, t1, cpu_env);
23596            break;
23597        case OPC_EXTPV:
23598            tcg_gen_movi_tl(t0, v2);
23599            gen_helper_extp(cpu_gpr[ret], t0, v1_t, cpu_env);
23600            break;
23601        case OPC_EXTPDP:
23602            tcg_gen_movi_tl(t0, v2);
23603            tcg_gen_movi_tl(t1, v1);
23604            gen_helper_extpdp(cpu_gpr[ret], t0, t1, cpu_env);
23605            break;
23606        case OPC_EXTPDPV:
23607            tcg_gen_movi_tl(t0, v2);
23608            gen_helper_extpdp(cpu_gpr[ret], t0, v1_t, cpu_env);
23609            break;
23610        case OPC_SHILO:
23611            imm = (ctx->opcode >> 20) & 0x3F;
23612            tcg_gen_movi_tl(t0, ret);
23613            tcg_gen_movi_tl(t1, imm);
23614            gen_helper_shilo(t0, t1, cpu_env);
23615            break;
23616        case OPC_SHILOV:
23617            tcg_gen_movi_tl(t0, ret);
23618            gen_helper_shilo(t0, v1_t, cpu_env);
23619            break;
23620        case OPC_MTHLIP:
23621            tcg_gen_movi_tl(t0, ret);
23622            gen_helper_mthlip(t0, v1_t, cpu_env);
23623            break;
23624        case OPC_WRDSP:
23625            imm = (ctx->opcode >> 11) & 0x3FF;
23626            tcg_gen_movi_tl(t0, imm);
23627            gen_helper_wrdsp(v1_t, t0, cpu_env);
23628            break;
23629        case OPC_RDDSP:
23630            imm = (ctx->opcode >> 16) & 0x03FF;
23631            tcg_gen_movi_tl(t0, imm);
23632            gen_helper_rddsp(cpu_gpr[ret], t0, cpu_env);
23633            break;
23634        }
23635        break;
23636#ifdef TARGET_MIPS64
23637    case OPC_DEXTR_W_DSP:
23638        check_dsp(ctx);
23639        switch (op2) {
23640        case OPC_DMTHLIP:
23641            tcg_gen_movi_tl(t0, ret);
23642            gen_helper_dmthlip(v1_t, t0, cpu_env);
23643            break;
23644        case OPC_DSHILO:
23645            {
23646                int shift = (ctx->opcode >> 19) & 0x7F;
23647                int ac = (ctx->opcode >> 11) & 0x03;
23648                tcg_gen_movi_tl(t0, shift);
23649                tcg_gen_movi_tl(t1, ac);
23650                gen_helper_dshilo(t0, t1, cpu_env);
23651                break;
23652            }
23653        case OPC_DSHILOV:
23654            {
23655                int ac = (ctx->opcode >> 11) & 0x03;
23656                tcg_gen_movi_tl(t0, ac);
23657                gen_helper_dshilo(v1_t, t0, cpu_env);
23658                break;
23659            }
23660        case OPC_DEXTP:
23661            tcg_gen_movi_tl(t0, v2);
23662            tcg_gen_movi_tl(t1, v1);
23663
23664            gen_helper_dextp(cpu_gpr[ret], t0, t1, cpu_env);
23665            break;
23666        case OPC_DEXTPV:
23667            tcg_gen_movi_tl(t0, v2);
23668            gen_helper_dextp(cpu_gpr[ret], t0, v1_t, cpu_env);
23669            break;
23670        case OPC_DEXTPDP:
23671            tcg_gen_movi_tl(t0, v2);
23672            tcg_gen_movi_tl(t1, v1);
23673            gen_helper_dextpdp(cpu_gpr[ret], t0, t1, cpu_env);
23674            break;
23675        case OPC_DEXTPDPV:
23676            tcg_gen_movi_tl(t0, v2);
23677            gen_helper_dextpdp(cpu_gpr[ret], t0, v1_t, cpu_env);
23678            break;
23679        case OPC_DEXTR_L:
23680            tcg_gen_movi_tl(t0, v2);
23681            tcg_gen_movi_tl(t1, v1);
23682            gen_helper_dextr_l(cpu_gpr[ret], t0, t1, cpu_env);
23683            break;
23684        case OPC_DEXTR_R_L:
23685            tcg_gen_movi_tl(t0, v2);
23686            tcg_gen_movi_tl(t1, v1);
23687            gen_helper_dextr_r_l(cpu_gpr[ret], t0, t1, cpu_env);
23688            break;
23689        case OPC_DEXTR_RS_L:
23690            tcg_gen_movi_tl(t0, v2);
23691            tcg_gen_movi_tl(t1, v1);
23692            gen_helper_dextr_rs_l(cpu_gpr[ret], t0, t1, cpu_env);
23693            break;
23694        case OPC_DEXTR_W:
23695            tcg_gen_movi_tl(t0, v2);
23696            tcg_gen_movi_tl(t1, v1);
23697            gen_helper_dextr_w(cpu_gpr[ret], t0, t1, cpu_env);
23698            break;
23699        case OPC_DEXTR_R_W:
23700            tcg_gen_movi_tl(t0, v2);
23701            tcg_gen_movi_tl(t1, v1);
23702            gen_helper_dextr_r_w(cpu_gpr[ret], t0, t1, cpu_env);
23703            break;
23704        case OPC_DEXTR_RS_W:
23705            tcg_gen_movi_tl(t0, v2);
23706            tcg_gen_movi_tl(t1, v1);
23707            gen_helper_dextr_rs_w(cpu_gpr[ret], t0, t1, cpu_env);
23708            break;
23709        case OPC_DEXTR_S_H:
23710            tcg_gen_movi_tl(t0, v2);
23711            tcg_gen_movi_tl(t1, v1);
23712            gen_helper_dextr_s_h(cpu_gpr[ret], t0, t1, cpu_env);
23713            break;
23714        case OPC_DEXTRV_S_H:
23715            tcg_gen_movi_tl(t0, v2);
23716            tcg_gen_movi_tl(t1, v1);
23717            gen_helper_dextr_s_h(cpu_gpr[ret], t0, t1, cpu_env);
23718            break;
23719        case OPC_DEXTRV_L:
23720            tcg_gen_movi_tl(t0, v2);
23721            gen_helper_dextr_l(cpu_gpr[ret], t0, v1_t, cpu_env);
23722            break;
23723        case OPC_DEXTRV_R_L:
23724            tcg_gen_movi_tl(t0, v2);
23725            gen_helper_dextr_r_l(cpu_gpr[ret], t0, v1_t, cpu_env);
23726            break;
23727        case OPC_DEXTRV_RS_L:
23728            tcg_gen_movi_tl(t0, v2);
23729            gen_helper_dextr_rs_l(cpu_gpr[ret], t0, v1_t, cpu_env);
23730            break;
23731        case OPC_DEXTRV_W:
23732            tcg_gen_movi_tl(t0, v2);
23733            gen_helper_dextr_w(cpu_gpr[ret], t0, v1_t, cpu_env);
23734            break;
23735        case OPC_DEXTRV_R_W:
23736            tcg_gen_movi_tl(t0, v2);
23737            gen_helper_dextr_r_w(cpu_gpr[ret], t0, v1_t, cpu_env);
23738            break;
23739        case OPC_DEXTRV_RS_W:
23740            tcg_gen_movi_tl(t0, v2);
23741            gen_helper_dextr_rs_w(cpu_gpr[ret], t0, v1_t, cpu_env);
23742            break;
23743        }
23744        break;
23745#endif
23746    }
23747
23748    tcg_temp_free(t0);
23749    tcg_temp_free(t1);
23750    tcg_temp_free(v1_t);
23751    tcg_temp_free(v2_t);
23752}
23753
23754/* End MIPSDSP functions. */
23755
23756static void decode_opc_special_r6(CPUMIPSState *env, DisasContext *ctx)
23757{
23758    int rs, rt, rd, sa;
23759    uint32_t op1, op2;
23760
23761    rs = (ctx->opcode >> 21) & 0x1f;
23762    rt = (ctx->opcode >> 16) & 0x1f;
23763    rd = (ctx->opcode >> 11) & 0x1f;
23764    sa = (ctx->opcode >> 6) & 0x1f;
23765
23766    op1 = MASK_SPECIAL(ctx->opcode);
23767    switch (op1) {
23768    case OPC_LSA:
23769        gen_lsa(ctx, op1, rd, rs, rt, extract32(ctx->opcode, 6, 2));
23770        break;
23771    case OPC_MULT:
23772    case OPC_MULTU:
23773    case OPC_DIV:
23774    case OPC_DIVU:
23775        op2 = MASK_R6_MULDIV(ctx->opcode);
23776        switch (op2) {
23777        case R6_OPC_MUL:
23778        case R6_OPC_MUH:
23779        case R6_OPC_MULU:
23780        case R6_OPC_MUHU:
23781        case R6_OPC_DIV:
23782        case R6_OPC_MOD:
23783        case R6_OPC_DIVU:
23784        case R6_OPC_MODU:
23785            gen_r6_muldiv(ctx, op2, rd, rs, rt);
23786            break;
23787        default:
23788            MIPS_INVAL("special_r6 muldiv");
23789            generate_exception_end(ctx, EXCP_RI);
23790            break;
23791        }
23792        break;
23793    case OPC_SELEQZ:
23794    case OPC_SELNEZ:
23795        gen_cond_move(ctx, op1, rd, rs, rt);
23796        break;
23797    case R6_OPC_CLO:
23798    case R6_OPC_CLZ:
23799        if (rt == 0 && sa == 1) {
23800            /* Major opcode and function field is shared with preR6 MFHI/MTHI.
23801               We need additionally to check other fields */
23802            gen_cl(ctx, op1, rd, rs);
23803        } else {
23804            generate_exception_end(ctx, EXCP_RI);
23805        }
23806        break;
23807    case R6_OPC_SDBBP:
23808        if (is_uhi(extract32(ctx->opcode, 6, 20))) {
23809            gen_helper_do_semihosting(cpu_env);
23810        } else {
23811            if (ctx->hflags & MIPS_HFLAG_SBRI) {
23812                generate_exception_end(ctx, EXCP_RI);
23813            } else {
23814                generate_exception_end(ctx, EXCP_DBp);
23815            }
23816        }
23817        break;
23818#if defined(TARGET_MIPS64)
23819    case OPC_DLSA:
23820        check_mips_64(ctx);
23821        gen_lsa(ctx, op1, rd, rs, rt, extract32(ctx->opcode, 6, 2));
23822        break;
23823    case R6_OPC_DCLO:
23824    case R6_OPC_DCLZ:
23825        if (rt == 0 && sa == 1) {
23826            /* Major opcode and function field is shared with preR6 MFHI/MTHI.
23827               We need additionally to check other fields */
23828            check_mips_64(ctx);
23829            gen_cl(ctx, op1, rd, rs);
23830        } else {
23831            generate_exception_end(ctx, EXCP_RI);
23832        }
23833        break;
23834    case OPC_DMULT:
23835    case OPC_DMULTU:
23836    case OPC_DDIV:
23837    case OPC_DDIVU:
23838
23839        op2 = MASK_R6_MULDIV(ctx->opcode);
23840        switch (op2) {
23841        case R6_OPC_DMUL:
23842        case R6_OPC_DMUH:
23843        case R6_OPC_DMULU:
23844        case R6_OPC_DMUHU:
23845        case R6_OPC_DDIV:
23846        case R6_OPC_DMOD:
23847        case R6_OPC_DDIVU:
23848        case R6_OPC_DMODU:
23849            check_mips_64(ctx);
23850            gen_r6_muldiv(ctx, op2, rd, rs, rt);
23851            break;
23852        default:
23853            MIPS_INVAL("special_r6 muldiv");
23854            generate_exception_end(ctx, EXCP_RI);
23855            break;
23856        }
23857        break;
23858#endif
23859    default:            /* Invalid */
23860        MIPS_INVAL("special_r6");
23861        generate_exception_end(ctx, EXCP_RI);
23862        break;
23863    }
23864}
23865
23866static void decode_opc_special_tx79(CPUMIPSState *env, DisasContext *ctx)
23867{
23868    int rs = extract32(ctx->opcode, 21, 5);
23869    int rt = extract32(ctx->opcode, 16, 5);
23870    int rd = extract32(ctx->opcode, 11, 5);
23871    uint32_t op1 = MASK_SPECIAL(ctx->opcode);
23872
23873    switch (op1) {
23874    case OPC_MOVN:         /* Conditional move */
23875    case OPC_MOVZ:
23876        gen_cond_move(ctx, op1, rd, rs, rt);
23877        break;
23878    case OPC_MFHI:          /* Move from HI/LO */
23879    case OPC_MFLO:
23880        gen_HILO(ctx, op1, 0, rd);
23881        break;
23882    case OPC_MTHI:
23883    case OPC_MTLO:          /* Move to HI/LO */
23884        gen_HILO(ctx, op1, 0, rs);
23885        break;
23886    case OPC_MULT:
23887    case OPC_MULTU:
23888        gen_mul_txx9(ctx, op1, rd, rs, rt);
23889        break;
23890    case OPC_DIV:
23891    case OPC_DIVU:
23892        gen_muldiv(ctx, op1, 0, rs, rt);
23893        break;
23894#if defined(TARGET_MIPS64)
23895    case OPC_DMULT:
23896    case OPC_DMULTU:
23897    case OPC_DDIV:
23898    case OPC_DDIVU:
23899        check_insn_opc_user_only(ctx, INSN_R5900);
23900        gen_muldiv(ctx, op1, 0, rs, rt);
23901        break;
23902#endif
23903    case OPC_JR:
23904        gen_compute_branch(ctx, op1, 4, rs, 0, 0, 4);
23905        break;
23906    default:            /* Invalid */
23907        MIPS_INVAL("special_tx79");
23908        generate_exception_end(ctx, EXCP_RI);
23909        break;
23910    }
23911}
23912
23913static void decode_opc_special_legacy(CPUMIPSState *env, DisasContext *ctx)
23914{
23915    int rs, rt, rd, sa;
23916    uint32_t op1;
23917
23918    rs = (ctx->opcode >> 21) & 0x1f;
23919    rt = (ctx->opcode >> 16) & 0x1f;
23920    rd = (ctx->opcode >> 11) & 0x1f;
23921    sa = (ctx->opcode >> 6) & 0x1f;
23922
23923    op1 = MASK_SPECIAL(ctx->opcode);
23924    switch (op1) {
23925    case OPC_MOVN:         /* Conditional move */
23926    case OPC_MOVZ:
23927        check_insn(ctx, ISA_MIPS4 | ISA_MIPS32 |
23928                   INSN_LOONGSON2E | INSN_LOONGSON2F);
23929        gen_cond_move(ctx, op1, rd, rs, rt);
23930        break;
23931    case OPC_MFHI:          /* Move from HI/LO */
23932    case OPC_MFLO:
23933        gen_HILO(ctx, op1, rs & 3, rd);
23934        break;
23935    case OPC_MTHI:
23936    case OPC_MTLO:          /* Move to HI/LO */
23937        gen_HILO(ctx, op1, rd & 3, rs);
23938        break;
23939    case OPC_MOVCI:
23940        check_insn(ctx, ISA_MIPS4 | ISA_MIPS32);
23941        if (env->CP0_Config1 & (1 << CP0C1_FP)) {
23942            check_cp1_enabled(ctx);
23943            gen_movci(ctx, rd, rs, (ctx->opcode >> 18) & 0x7,
23944                      (ctx->opcode >> 16) & 1);
23945        } else {
23946            generate_exception_err(ctx, EXCP_CpU, 1);
23947        }
23948        break;
23949    case OPC_MULT:
23950    case OPC_MULTU:
23951        if (sa) {
23952            check_insn(ctx, INSN_VR54XX);
23953            op1 = MASK_MUL_VR54XX(ctx->opcode);
23954            gen_mul_vr54xx(ctx, op1, rd, rs, rt);
23955        } else {
23956            gen_muldiv(ctx, op1, rd & 3, rs, rt);
23957        }
23958        break;
23959    case OPC_DIV:
23960    case OPC_DIVU:
23961        gen_muldiv(ctx, op1, 0, rs, rt);
23962        break;
23963#if defined(TARGET_MIPS64)
23964    case OPC_DMULT:
23965    case OPC_DMULTU:
23966    case OPC_DDIV:
23967    case OPC_DDIVU:
23968        check_insn(ctx, ISA_MIPS3);
23969        check_mips_64(ctx);
23970        gen_muldiv(ctx, op1, 0, rs, rt);
23971        break;
23972#endif
23973    case OPC_JR:
23974        gen_compute_branch(ctx, op1, 4, rs, rd, sa, 4);
23975        break;
23976    case OPC_SPIM:
23977#ifdef MIPS_STRICT_STANDARD
23978        MIPS_INVAL("SPIM");
23979        generate_exception_end(ctx, EXCP_RI);
23980#else
23981        /* Implemented as RI exception for now. */
23982        MIPS_INVAL("spim (unofficial)");
23983        generate_exception_end(ctx, EXCP_RI);
23984#endif
23985        break;
23986    default:            /* Invalid */
23987        MIPS_INVAL("special_legacy");
23988        generate_exception_end(ctx, EXCP_RI);
23989        break;
23990    }
23991}
23992
23993static void decode_opc_special(CPUMIPSState *env, DisasContext *ctx)
23994{
23995    int rs, rt, rd, sa;
23996    uint32_t op1;
23997
23998    rs = (ctx->opcode >> 21) & 0x1f;
23999    rt = (ctx->opcode >> 16) & 0x1f;
24000    rd = (ctx->opcode >> 11) & 0x1f;
24001    sa = (ctx->opcode >> 6) & 0x1f;
24002
24003    op1 = MASK_SPECIAL(ctx->opcode);
24004    switch (op1) {
24005    case OPC_SLL:          /* Shift with immediate */
24006        if (sa == 5 && rd == 0 &&
24007            rs == 0 && rt == 0) { /* PAUSE */
24008            if ((ctx->insn_flags & ISA_MIPS32R6) &&
24009                (ctx->hflags & MIPS_HFLAG_BMASK)) {
24010                generate_exception_end(ctx, EXCP_RI);
24011                break;
24012            }
24013        }
24014        /* Fallthrough */
24015    case OPC_SRA:
24016        gen_shift_imm(ctx, op1, rd, rt, sa);
24017        break;
24018    case OPC_SRL:
24019        switch ((ctx->opcode >> 21) & 0x1f) {
24020        case 1:
24021            /* rotr is decoded as srl on non-R2 CPUs */
24022            if (ctx->insn_flags & ISA_MIPS32R2) {
24023                op1 = OPC_ROTR;
24024            }
24025            /* Fallthrough */
24026        case 0:
24027            gen_shift_imm(ctx, op1, rd, rt, sa);
24028            break;
24029        default:
24030            generate_exception_end(ctx, EXCP_RI);
24031            break;
24032        }
24033        break;
24034    case OPC_ADD:
24035    case OPC_ADDU:
24036    case OPC_SUB:
24037    case OPC_SUBU:
24038        gen_arith(ctx, op1, rd, rs, rt);
24039        break;
24040    case OPC_SLLV:         /* Shifts */
24041    case OPC_SRAV:
24042        gen_shift(ctx, op1, rd, rs, rt);
24043        break;
24044    case OPC_SRLV:
24045        switch ((ctx->opcode >> 6) & 0x1f) {
24046        case 1:
24047            /* rotrv is decoded as srlv on non-R2 CPUs */
24048            if (ctx->insn_flags & ISA_MIPS32R2) {
24049                op1 = OPC_ROTRV;
24050            }
24051            /* Fallthrough */
24052        case 0:
24053            gen_shift(ctx, op1, rd, rs, rt);
24054            break;
24055        default:
24056            generate_exception_end(ctx, EXCP_RI);
24057            break;
24058        }
24059        break;
24060    case OPC_SLT:          /* Set on less than */
24061    case OPC_SLTU:
24062        gen_slt(ctx, op1, rd, rs, rt);
24063        break;
24064    case OPC_AND:          /* Logic*/
24065    case OPC_OR:
24066    case OPC_NOR:
24067    case OPC_XOR:
24068        gen_logic(ctx, op1, rd, rs, rt);
24069        break;
24070    case OPC_JALR:
24071        gen_compute_branch(ctx, op1, 4, rs, rd, sa, 4);
24072        break;
24073    case OPC_TGE: /* Traps */
24074    case OPC_TGEU:
24075    case OPC_TLT:
24076    case OPC_TLTU:
24077    case OPC_TEQ:
24078    case OPC_TNE:
24079        check_insn(ctx, ISA_MIPS2);
24080        gen_trap(ctx, op1, rs, rt, -1);
24081        break;
24082    case OPC_LSA: /* OPC_PMON */
24083        if ((ctx->insn_flags & ISA_MIPS32R6) ||
24084            (env->CP0_Config3 & (1 << CP0C3_MSAP))) {
24085            decode_opc_special_r6(env, ctx);
24086        } else {
24087            /* Pmon entry point, also R4010 selsl */
24088#ifdef MIPS_STRICT_STANDARD
24089            MIPS_INVAL("PMON / selsl");
24090            generate_exception_end(ctx, EXCP_RI);
24091#else
24092            gen_helper_0e0i(pmon, sa);
24093#endif
24094        }
24095        break;
24096    case OPC_SYSCALL:
24097        generate_exception_end(ctx, EXCP_SYSCALL);
24098        break;
24099    case OPC_BREAK:
24100        generate_exception_end(ctx, EXCP_BREAK);
24101        break;
24102    case OPC_SYNC:
24103        check_insn(ctx, ISA_MIPS2);
24104        gen_sync(extract32(ctx->opcode, 6, 5));
24105        break;
24106
24107#if defined(TARGET_MIPS64)
24108        /* MIPS64 specific opcodes */
24109    case OPC_DSLL:
24110    case OPC_DSRA:
24111    case OPC_DSLL32:
24112    case OPC_DSRA32:
24113        check_insn(ctx, ISA_MIPS3);
24114        check_mips_64(ctx);
24115        gen_shift_imm(ctx, op1, rd, rt, sa);
24116        break;
24117    case OPC_DSRL:
24118        switch ((ctx->opcode >> 21) & 0x1f) {
24119        case 1:
24120            /* drotr is decoded as dsrl on non-R2 CPUs */
24121            if (ctx->insn_flags & ISA_MIPS32R2) {
24122                op1 = OPC_DROTR;
24123            }
24124            /* Fallthrough */
24125        case 0:
24126            check_insn(ctx, ISA_MIPS3);
24127            check_mips_64(ctx);
24128            gen_shift_imm(ctx, op1, rd, rt, sa);
24129            break;
24130        default:
24131            generate_exception_end(ctx, EXCP_RI);
24132            break;
24133        }
24134        break;
24135    case OPC_DSRL32:
24136        switch ((ctx->opcode >> 21) & 0x1f) {
24137        case 1:
24138            /* drotr32 is decoded as dsrl32 on non-R2 CPUs */
24139            if (ctx->insn_flags & ISA_MIPS32R2) {
24140                op1 = OPC_DROTR32;
24141            }
24142            /* Fallthrough */
24143        case 0:
24144            check_insn(ctx, ISA_MIPS3);
24145            check_mips_64(ctx);
24146            gen_shift_imm(ctx, op1, rd, rt, sa);
24147            break;
24148        default:
24149            generate_exception_end(ctx, EXCP_RI);
24150            break;
24151        }
24152        break;
24153    case OPC_DADD:
24154    case OPC_DADDU:
24155    case OPC_DSUB:
24156    case OPC_DSUBU:
24157        check_insn(ctx, ISA_MIPS3);
24158        check_mips_64(ctx);
24159        gen_arith(ctx, op1, rd, rs, rt);
24160        break;
24161    case OPC_DSLLV:
24162    case OPC_DSRAV:
24163        check_insn(ctx, ISA_MIPS3);
24164        check_mips_64(ctx);
24165        gen_shift(ctx, op1, rd, rs, rt);
24166        break;
24167    case OPC_DSRLV:
24168        switch ((ctx->opcode >> 6) & 0x1f) {
24169        case 1:
24170            /* drotrv is decoded as dsrlv on non-R2 CPUs */
24171            if (ctx->insn_flags & ISA_MIPS32R2) {
24172                op1 = OPC_DROTRV;
24173            }
24174            /* Fallthrough */
24175        case 0:
24176            check_insn(ctx, ISA_MIPS3);
24177            check_mips_64(ctx);
24178            gen_shift(ctx, op1, rd, rs, rt);
24179            break;
24180        default:
24181            generate_exception_end(ctx, EXCP_RI);
24182            break;
24183        }
24184        break;
24185    case OPC_DLSA:
24186        if ((ctx->insn_flags & ISA_MIPS32R6) ||
24187            (env->CP0_Config3 & (1 << CP0C3_MSAP))) {
24188            decode_opc_special_r6(env, ctx);
24189        }
24190        break;
24191#endif
24192    default:
24193        if (ctx->insn_flags & ISA_MIPS32R6) {
24194            decode_opc_special_r6(env, ctx);
24195        } else if (ctx->insn_flags & INSN_R5900) {
24196            decode_opc_special_tx79(env, ctx);
24197        } else {
24198            decode_opc_special_legacy(env, ctx);
24199        }
24200    }
24201}
24202
24203
24204/* MXU accumulate add/subtract 1-bit pattern 'aptn1' */
24205#define MXU_APTN1_A    0
24206#define MXU_APTN1_S    1
24207
24208/* MXU accumulate add/subtract 2-bit pattern 'aptn2' */
24209#define MXU_APTN2_AA    0
24210#define MXU_APTN2_AS    1
24211#define MXU_APTN2_SA    2
24212#define MXU_APTN2_SS    3
24213
24214/* MXU execute add/subtract 2-bit pattern 'eptn2' */
24215#define MXU_EPTN2_AA    0
24216#define MXU_EPTN2_AS    1
24217#define MXU_EPTN2_SA    2
24218#define MXU_EPTN2_SS    3
24219
24220/* MXU operand getting pattern 'optn2' */
24221#define MXU_OPTN2_WW    0
24222#define MXU_OPTN2_LW    1
24223#define MXU_OPTN2_HW    2
24224#define MXU_OPTN2_XW    3
24225
24226/* MXU operand getting pattern 'optn3' */
24227#define MXU_OPTN3_PTN0  0
24228#define MXU_OPTN3_PTN1  1
24229#define MXU_OPTN3_PTN2  2
24230#define MXU_OPTN3_PTN3  3
24231#define MXU_OPTN3_PTN4  4
24232#define MXU_OPTN3_PTN5  5
24233#define MXU_OPTN3_PTN6  6
24234#define MXU_OPTN3_PTN7  7
24235
24236
24237/*
24238 * S32I2M XRa, rb - Register move from GRF to XRF
24239 */
24240static void gen_mxu_s32i2m(DisasContext *ctx)
24241{
24242    TCGv t0;
24243    uint32_t XRa, Rb;
24244
24245    t0 = tcg_temp_new();
24246
24247    XRa = extract32(ctx->opcode, 6, 5);
24248    Rb = extract32(ctx->opcode, 16, 5);
24249
24250    gen_load_gpr(t0, Rb);
24251    if (XRa <= 15) {
24252        gen_store_mxu_gpr(t0, XRa);
24253    } else if (XRa == 16) {
24254        gen_store_mxu_cr(t0);
24255    }
24256
24257    tcg_temp_free(t0);
24258}
24259
24260/*
24261 * S32M2I XRa, rb - Register move from XRF to GRF
24262 */
24263static void gen_mxu_s32m2i(DisasContext *ctx)
24264{
24265    TCGv t0;
24266    uint32_t XRa, Rb;
24267
24268    t0 = tcg_temp_new();
24269
24270    XRa = extract32(ctx->opcode, 6, 5);
24271    Rb = extract32(ctx->opcode, 16, 5);
24272
24273    if (XRa <= 15) {
24274        gen_load_mxu_gpr(t0, XRa);
24275    } else if (XRa == 16) {
24276        gen_load_mxu_cr(t0);
24277    }
24278
24279    gen_store_gpr(t0, Rb);
24280
24281    tcg_temp_free(t0);
24282}
24283
24284/*
24285 * S8LDD XRa, Rb, s8, optn3 - Load a byte from memory to XRF
24286 */
24287static void gen_mxu_s8ldd(DisasContext *ctx)
24288{
24289    TCGv t0, t1;
24290    uint32_t XRa, Rb, s8, optn3;
24291
24292    t0 = tcg_temp_new();
24293    t1 = tcg_temp_new();
24294
24295    XRa = extract32(ctx->opcode, 6, 4);
24296    s8 = extract32(ctx->opcode, 10, 8);
24297    optn3 = extract32(ctx->opcode, 18, 3);
24298    Rb = extract32(ctx->opcode, 21, 5);
24299
24300    gen_load_gpr(t0, Rb);
24301    tcg_gen_addi_tl(t0, t0, (int8_t)s8);
24302
24303    switch (optn3) {
24304    /* XRa[7:0] = tmp8 */
24305    case MXU_OPTN3_PTN0:
24306        tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_UB);
24307        gen_load_mxu_gpr(t0, XRa);
24308        tcg_gen_deposit_tl(t0, t0, t1, 0, 8);
24309        break;
24310    /* XRa[15:8] = tmp8 */
24311    case MXU_OPTN3_PTN1:
24312        tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_UB);
24313        gen_load_mxu_gpr(t0, XRa);
24314        tcg_gen_deposit_tl(t0, t0, t1, 8, 8);
24315        break;
24316    /* XRa[23:16] = tmp8 */
24317    case MXU_OPTN3_PTN2:
24318        tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_UB);
24319        gen_load_mxu_gpr(t0, XRa);
24320        tcg_gen_deposit_tl(t0, t0, t1, 16, 8);
24321        break;
24322    /* XRa[31:24] = tmp8 */
24323    case MXU_OPTN3_PTN3:
24324        tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_UB);
24325        gen_load_mxu_gpr(t0, XRa);
24326        tcg_gen_deposit_tl(t0, t0, t1, 24, 8);
24327        break;
24328    /* XRa = {8'b0, tmp8, 8'b0, tmp8} */
24329    case MXU_OPTN3_PTN4:
24330        tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_UB);
24331        tcg_gen_deposit_tl(t0, t1, t1, 16, 16);
24332        break;
24333    /* XRa = {tmp8, 8'b0, tmp8, 8'b0} */
24334    case MXU_OPTN3_PTN5:
24335        tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_UB);
24336        tcg_gen_shli_tl(t1, t1, 8);
24337        tcg_gen_deposit_tl(t0, t1, t1, 16, 16);
24338        break;
24339    /* XRa = {{8{sign of tmp8}}, tmp8, {8{sign of tmp8}}, tmp8} */
24340    case MXU_OPTN3_PTN6:
24341        tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_SB);
24342        tcg_gen_mov_tl(t0, t1);
24343        tcg_gen_andi_tl(t0, t0, 0xFF00FFFF);
24344        tcg_gen_shli_tl(t1, t1, 16);
24345        tcg_gen_or_tl(t0, t0, t1);
24346        break;
24347    /* XRa = {tmp8, tmp8, tmp8, tmp8} */
24348    case MXU_OPTN3_PTN7:
24349        tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_UB);
24350        tcg_gen_deposit_tl(t1, t1, t1, 8, 8);
24351        tcg_gen_deposit_tl(t0, t1, t1, 16, 16);
24352        break;
24353    }
24354
24355    gen_store_mxu_gpr(t0, XRa);
24356
24357    tcg_temp_free(t0);
24358    tcg_temp_free(t1);
24359}
24360
24361/*
24362 * D16MUL XRa, XRb, XRc, XRd, optn2 - Signed 16 bit pattern multiplication
24363 */
24364static void gen_mxu_d16mul(DisasContext *ctx)
24365{
24366    TCGv t0, t1, t2, t3;
24367    uint32_t XRa, XRb, XRc, XRd, optn2;
24368
24369    t0 = tcg_temp_new();
24370    t1 = tcg_temp_new();
24371    t2 = tcg_temp_new();
24372    t3 = tcg_temp_new();
24373
24374    XRa = extract32(ctx->opcode, 6, 4);
24375    XRb = extract32(ctx->opcode, 10, 4);
24376    XRc = extract32(ctx->opcode, 14, 4);
24377    XRd = extract32(ctx->opcode, 18, 4);
24378    optn2 = extract32(ctx->opcode, 22, 2);
24379
24380    gen_load_mxu_gpr(t1, XRb);
24381    tcg_gen_sextract_tl(t0, t1, 0, 16);
24382    tcg_gen_sextract_tl(t1, t1, 16, 16);
24383    gen_load_mxu_gpr(t3, XRc);
24384    tcg_gen_sextract_tl(t2, t3, 0, 16);
24385    tcg_gen_sextract_tl(t3, t3, 16, 16);
24386
24387    switch (optn2) {
24388    case MXU_OPTN2_WW: /* XRB.H*XRC.H == lop, XRB.L*XRC.L == rop */
24389        tcg_gen_mul_tl(t3, t1, t3);
24390        tcg_gen_mul_tl(t2, t0, t2);
24391        break;
24392    case MXU_OPTN2_LW: /* XRB.L*XRC.H == lop, XRB.L*XRC.L == rop */
24393        tcg_gen_mul_tl(t3, t0, t3);
24394        tcg_gen_mul_tl(t2, t0, t2);
24395        break;
24396    case MXU_OPTN2_HW: /* XRB.H*XRC.H == lop, XRB.H*XRC.L == rop */
24397        tcg_gen_mul_tl(t3, t1, t3);
24398        tcg_gen_mul_tl(t2, t1, t2);
24399        break;
24400    case MXU_OPTN2_XW: /* XRB.L*XRC.H == lop, XRB.H*XRC.L == rop */
24401        tcg_gen_mul_tl(t3, t0, t3);
24402        tcg_gen_mul_tl(t2, t1, t2);
24403        break;
24404    }
24405    gen_store_mxu_gpr(t3, XRa);
24406    gen_store_mxu_gpr(t2, XRd);
24407
24408    tcg_temp_free(t0);
24409    tcg_temp_free(t1);
24410    tcg_temp_free(t2);
24411    tcg_temp_free(t3);
24412}
24413
24414/*
24415 * D16MAC XRa, XRb, XRc, XRd, aptn2, optn2 - Signed 16 bit pattern multiply
24416 *                                           and accumulate
24417 */
24418static void gen_mxu_d16mac(DisasContext *ctx)
24419{
24420    TCGv t0, t1, t2, t3;
24421    uint32_t XRa, XRb, XRc, XRd, optn2, aptn2;
24422
24423    t0 = tcg_temp_new();
24424    t1 = tcg_temp_new();
24425    t2 = tcg_temp_new();
24426    t3 = tcg_temp_new();
24427
24428    XRa = extract32(ctx->opcode, 6, 4);
24429    XRb = extract32(ctx->opcode, 10, 4);
24430    XRc = extract32(ctx->opcode, 14, 4);
24431    XRd = extract32(ctx->opcode, 18, 4);
24432    optn2 = extract32(ctx->opcode, 22, 2);
24433    aptn2 = extract32(ctx->opcode, 24, 2);
24434
24435    gen_load_mxu_gpr(t1, XRb);
24436    tcg_gen_sextract_tl(t0, t1, 0, 16);
24437    tcg_gen_sextract_tl(t1, t1, 16, 16);
24438
24439    gen_load_mxu_gpr(t3, XRc);
24440    tcg_gen_sextract_tl(t2, t3, 0, 16);
24441    tcg_gen_sextract_tl(t3, t3, 16, 16);
24442
24443    switch (optn2) {
24444    case MXU_OPTN2_WW: /* XRB.H*XRC.H == lop, XRB.L*XRC.L == rop */
24445        tcg_gen_mul_tl(t3, t1, t3);
24446        tcg_gen_mul_tl(t2, t0, t2);
24447        break;
24448    case MXU_OPTN2_LW: /* XRB.L*XRC.H == lop, XRB.L*XRC.L == rop */
24449        tcg_gen_mul_tl(t3, t0, t3);
24450        tcg_gen_mul_tl(t2, t0, t2);
24451        break;
24452    case MXU_OPTN2_HW: /* XRB.H*XRC.H == lop, XRB.H*XRC.L == rop */
24453        tcg_gen_mul_tl(t3, t1, t3);
24454        tcg_gen_mul_tl(t2, t1, t2);
24455        break;
24456    case MXU_OPTN2_XW: /* XRB.L*XRC.H == lop, XRB.H*XRC.L == rop */
24457        tcg_gen_mul_tl(t3, t0, t3);
24458        tcg_gen_mul_tl(t2, t1, t2);
24459        break;
24460    }
24461    gen_load_mxu_gpr(t0, XRa);
24462    gen_load_mxu_gpr(t1, XRd);
24463
24464    switch (aptn2) {
24465    case MXU_APTN2_AA:
24466        tcg_gen_add_tl(t3, t0, t3);
24467        tcg_gen_add_tl(t2, t1, t2);
24468        break;
24469    case MXU_APTN2_AS:
24470        tcg_gen_add_tl(t3, t0, t3);
24471        tcg_gen_sub_tl(t2, t1, t2);
24472        break;
24473    case MXU_APTN2_SA:
24474        tcg_gen_sub_tl(t3, t0, t3);
24475        tcg_gen_add_tl(t2, t1, t2);
24476        break;
24477    case MXU_APTN2_SS:
24478        tcg_gen_sub_tl(t3, t0, t3);
24479        tcg_gen_sub_tl(t2, t1, t2);
24480        break;
24481    }
24482    gen_store_mxu_gpr(t3, XRa);
24483    gen_store_mxu_gpr(t2, XRd);
24484
24485    tcg_temp_free(t0);
24486    tcg_temp_free(t1);
24487    tcg_temp_free(t2);
24488    tcg_temp_free(t3);
24489}
24490
24491/*
24492 * Q8MUL   XRa, XRb, XRc, XRd - Parallel unsigned 8 bit pattern multiply
24493 * Q8MULSU XRa, XRb, XRc, XRd - Parallel signed 8 bit pattern multiply
24494 */
24495static void gen_mxu_q8mul_q8mulsu(DisasContext *ctx)
24496{
24497    TCGv t0, t1, t2, t3, t4, t5, t6, t7;
24498    uint32_t XRa, XRb, XRc, XRd, sel;
24499
24500    t0 = tcg_temp_new();
24501    t1 = tcg_temp_new();
24502    t2 = tcg_temp_new();
24503    t3 = tcg_temp_new();
24504    t4 = tcg_temp_new();
24505    t5 = tcg_temp_new();
24506    t6 = tcg_temp_new();
24507    t7 = tcg_temp_new();
24508
24509    XRa = extract32(ctx->opcode, 6, 4);
24510    XRb = extract32(ctx->opcode, 10, 4);
24511    XRc = extract32(ctx->opcode, 14, 4);
24512    XRd = extract32(ctx->opcode, 18, 4);
24513    sel = extract32(ctx->opcode, 22, 2);
24514
24515    gen_load_mxu_gpr(t3, XRb);
24516    gen_load_mxu_gpr(t7, XRc);
24517
24518    if (sel == 0x2) {
24519        /* Q8MULSU */
24520        tcg_gen_ext8s_tl(t0, t3);
24521        tcg_gen_shri_tl(t3, t3, 8);
24522        tcg_gen_ext8s_tl(t1, t3);
24523        tcg_gen_shri_tl(t3, t3, 8);
24524        tcg_gen_ext8s_tl(t2, t3);
24525        tcg_gen_shri_tl(t3, t3, 8);
24526        tcg_gen_ext8s_tl(t3, t3);
24527    } else {
24528        /* Q8MUL */
24529        tcg_gen_ext8u_tl(t0, t3);
24530        tcg_gen_shri_tl(t3, t3, 8);
24531        tcg_gen_ext8u_tl(t1, t3);
24532        tcg_gen_shri_tl(t3, t3, 8);
24533        tcg_gen_ext8u_tl(t2, t3);
24534        tcg_gen_shri_tl(t3, t3, 8);
24535        tcg_gen_ext8u_tl(t3, t3);
24536    }
24537
24538    tcg_gen_ext8u_tl(t4, t7);
24539    tcg_gen_shri_tl(t7, t7, 8);
24540    tcg_gen_ext8u_tl(t5, t7);
24541    tcg_gen_shri_tl(t7, t7, 8);
24542    tcg_gen_ext8u_tl(t6, t7);
24543    tcg_gen_shri_tl(t7, t7, 8);
24544    tcg_gen_ext8u_tl(t7, t7);
24545
24546    tcg_gen_mul_tl(t0, t0, t4);
24547    tcg_gen_mul_tl(t1, t1, t5);
24548    tcg_gen_mul_tl(t2, t2, t6);
24549    tcg_gen_mul_tl(t3, t3, t7);
24550
24551    tcg_gen_andi_tl(t0, t0, 0xFFFF);
24552    tcg_gen_andi_tl(t1, t1, 0xFFFF);
24553    tcg_gen_andi_tl(t2, t2, 0xFFFF);
24554    tcg_gen_andi_tl(t3, t3, 0xFFFF);
24555
24556    tcg_gen_shli_tl(t1, t1, 16);
24557    tcg_gen_shli_tl(t3, t3, 16);
24558
24559    tcg_gen_or_tl(t0, t0, t1);
24560    tcg_gen_or_tl(t1, t2, t3);
24561
24562    gen_store_mxu_gpr(t0, XRd);
24563    gen_store_mxu_gpr(t1, XRa);
24564
24565    tcg_temp_free(t0);
24566    tcg_temp_free(t1);
24567    tcg_temp_free(t2);
24568    tcg_temp_free(t3);
24569    tcg_temp_free(t4);
24570    tcg_temp_free(t5);
24571    tcg_temp_free(t6);
24572    tcg_temp_free(t7);
24573}
24574
24575/*
24576 * S32LDD  XRa, Rb, S12 - Load a word from memory to XRF
24577 * S32LDDR XRa, Rb, S12 - Load a word from memory to XRF, reversed byte seq.
24578 */
24579static void gen_mxu_s32ldd_s32lddr(DisasContext *ctx)
24580{
24581    TCGv t0, t1;
24582    uint32_t XRa, Rb, s12, sel;
24583
24584    t0 = tcg_temp_new();
24585    t1 = tcg_temp_new();
24586
24587    XRa = extract32(ctx->opcode, 6, 4);
24588    s12 = extract32(ctx->opcode, 10, 10);
24589    sel = extract32(ctx->opcode, 20, 1);
24590    Rb = extract32(ctx->opcode, 21, 5);
24591
24592    gen_load_gpr(t0, Rb);
24593
24594    tcg_gen_movi_tl(t1, s12);
24595    tcg_gen_shli_tl(t1, t1, 2);
24596    if (s12 & 0x200) {
24597        tcg_gen_ori_tl(t1, t1, 0xFFFFF000);
24598    }
24599    tcg_gen_add_tl(t1, t0, t1);
24600    tcg_gen_qemu_ld_tl(t1, t1, ctx->mem_idx, MO_SL);
24601
24602    if (sel == 1) {
24603        /* S32LDDR */
24604        tcg_gen_bswap32_tl(t1, t1);
24605    }
24606    gen_store_mxu_gpr(t1, XRa);
24607
24608    tcg_temp_free(t0);
24609    tcg_temp_free(t1);
24610}
24611
24612
24613/*
24614 * Decoding engine for MXU
24615 * =======================
24616 */
24617
24618/*
24619 *
24620 * Decode MXU pool00
24621 *
24622 *   1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
24623 *  +-----------+---------+-----+-------+-------+-------+-----------+
24624 *  |  SPECIAL2 |0 0 0 0 0|x x x|  XRc  |  XRb  |  XRa  |MXU__POOL00|
24625 *  +-----------+---------+-----+-------+-------+-------+-----------+
24626 *
24627 */
24628static void decode_opc_mxu__pool00(CPUMIPSState *env, DisasContext *ctx)
24629{
24630    uint32_t opcode = extract32(ctx->opcode, 18, 3);
24631
24632    switch (opcode) {
24633    case OPC_MXU_S32MAX:
24634        /* TODO: Implement emulation of S32MAX instruction. */
24635        MIPS_INVAL("OPC_MXU_S32MAX");
24636        generate_exception_end(ctx, EXCP_RI);
24637        break;
24638    case OPC_MXU_S32MIN:
24639        /* TODO: Implement emulation of S32MIN instruction. */
24640        MIPS_INVAL("OPC_MXU_S32MIN");
24641        generate_exception_end(ctx, EXCP_RI);
24642        break;
24643    case OPC_MXU_D16MAX:
24644        /* TODO: Implement emulation of D16MAX instruction. */
24645        MIPS_INVAL("OPC_MXU_D16MAX");
24646        generate_exception_end(ctx, EXCP_RI);
24647        break;
24648    case OPC_MXU_D16MIN:
24649        /* TODO: Implement emulation of D16MIN instruction. */
24650        MIPS_INVAL("OPC_MXU_D16MIN");
24651        generate_exception_end(ctx, EXCP_RI);
24652        break;
24653    case OPC_MXU_Q8MAX:
24654        /* TODO: Implement emulation of Q8MAX instruction. */
24655        MIPS_INVAL("OPC_MXU_Q8MAX");
24656        generate_exception_end(ctx, EXCP_RI);
24657        break;
24658    case OPC_MXU_Q8MIN:
24659        /* TODO: Implement emulation of Q8MIN instruction. */
24660        MIPS_INVAL("OPC_MXU_Q8MIN");
24661        generate_exception_end(ctx, EXCP_RI);
24662        break;
24663    case OPC_MXU_Q8SLT:
24664        /* TODO: Implement emulation of Q8SLT instruction. */
24665        MIPS_INVAL("OPC_MXU_Q8SLT");
24666        generate_exception_end(ctx, EXCP_RI);
24667        break;
24668    case OPC_MXU_Q8SLTU:
24669        /* TODO: Implement emulation of Q8SLTU instruction. */
24670        MIPS_INVAL("OPC_MXU_Q8SLTU");
24671        generate_exception_end(ctx, EXCP_RI);
24672        break;
24673    default:
24674        MIPS_INVAL("decode_opc_mxu");
24675        generate_exception_end(ctx, EXCP_RI);
24676        break;
24677    }
24678}
24679
24680/*
24681 *
24682 * Decode MXU pool01
24683 *
24684 *  S32SLT, D16SLT, D16AVG, D16AVGR, Q8AVG, Q8AVGR:
24685 *   1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
24686 *  +-----------+---------+-----+-------+-------+-------+-----------+
24687 *  |  SPECIAL2 |0 0 0 0 0|x x x|  XRc  |  XRb  |  XRa  |MXU__POOL01|
24688 *  +-----------+---------+-----+-------+-------+-------+-----------+
24689 *
24690 *  Q8ADD:
24691 *   1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
24692 *  +-----------+---+-----+-----+-------+-------+-------+-----------+
24693 *  |  SPECIAL2 |en2|0 0 0|x x x|  XRc  |  XRb  |  XRa  |MXU__POOL01|
24694 *  +-----------+---+-----+-----+-------+-------+-------+-----------+
24695 *
24696 */
24697static void decode_opc_mxu__pool01(CPUMIPSState *env, DisasContext *ctx)
24698{
24699    uint32_t opcode = extract32(ctx->opcode, 18, 3);
24700
24701    switch (opcode) {
24702    case OPC_MXU_S32SLT:
24703        /* TODO: Implement emulation of S32SLT instruction. */
24704        MIPS_INVAL("OPC_MXU_S32SLT");
24705        generate_exception_end(ctx, EXCP_RI);
24706        break;
24707    case OPC_MXU_D16SLT:
24708        /* TODO: Implement emulation of D16SLT instruction. */
24709        MIPS_INVAL("OPC_MXU_D16SLT");
24710        generate_exception_end(ctx, EXCP_RI);
24711        break;
24712    case OPC_MXU_D16AVG:
24713        /* TODO: Implement emulation of D16AVG instruction. */
24714        MIPS_INVAL("OPC_MXU_D16AVG");
24715        generate_exception_end(ctx, EXCP_RI);
24716        break;
24717    case OPC_MXU_D16AVGR:
24718        /* TODO: Implement emulation of D16AVGR instruction. */
24719        MIPS_INVAL("OPC_MXU_D16AVGR");
24720        generate_exception_end(ctx, EXCP_RI);
24721        break;
24722    case OPC_MXU_Q8AVG:
24723        /* TODO: Implement emulation of Q8AVG instruction. */
24724        MIPS_INVAL("OPC_MXU_Q8AVG");
24725        generate_exception_end(ctx, EXCP_RI);
24726        break;
24727    case OPC_MXU_Q8AVGR:
24728        /* TODO: Implement emulation of Q8AVGR instruction. */
24729        MIPS_INVAL("OPC_MXU_Q8AVGR");
24730        generate_exception_end(ctx, EXCP_RI);
24731        break;
24732    case OPC_MXU_Q8ADD:
24733        /* TODO: Implement emulation of Q8ADD instruction. */
24734        MIPS_INVAL("OPC_MXU_Q8ADD");
24735        generate_exception_end(ctx, EXCP_RI);
24736        break;
24737    default:
24738        MIPS_INVAL("decode_opc_mxu");
24739        generate_exception_end(ctx, EXCP_RI);
24740        break;
24741    }
24742}
24743
24744/*
24745 *
24746 * Decode MXU pool02
24747 *
24748 *   1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
24749 *  +-----------+---------+-----+-------+-------+-------+-----------+
24750 *  |  SPECIAL2 |0 0 0 0 0|x x x|  XRc  |  XRb  |  XRa  |MXU__POOL02|
24751 *  +-----------+---------+-----+-------+-------+-------+-----------+
24752 *
24753 */
24754static void decode_opc_mxu__pool02(CPUMIPSState *env, DisasContext *ctx)
24755{
24756    uint32_t opcode = extract32(ctx->opcode, 18, 3);
24757
24758    switch (opcode) {
24759    case OPC_MXU_S32CPS:
24760        /* TODO: Implement emulation of S32CPS instruction. */
24761        MIPS_INVAL("OPC_MXU_S32CPS");
24762        generate_exception_end(ctx, EXCP_RI);
24763        break;
24764    case OPC_MXU_D16CPS:
24765        /* TODO: Implement emulation of D16CPS instruction. */
24766        MIPS_INVAL("OPC_MXU_D16CPS");
24767        generate_exception_end(ctx, EXCP_RI);
24768        break;
24769    case OPC_MXU_Q8ABD:
24770        /* TODO: Implement emulation of Q8ABD instruction. */
24771        MIPS_INVAL("OPC_MXU_Q8ABD");
24772        generate_exception_end(ctx, EXCP_RI);
24773        break;
24774    case OPC_MXU_Q16SAT:
24775        /* TODO: Implement emulation of Q16SAT instruction. */
24776        MIPS_INVAL("OPC_MXU_Q16SAT");
24777        generate_exception_end(ctx, EXCP_RI);
24778        break;
24779    default:
24780        MIPS_INVAL("decode_opc_mxu");
24781        generate_exception_end(ctx, EXCP_RI);
24782        break;
24783    }
24784}
24785
24786/*
24787 *
24788 * Decode MXU pool03
24789 *
24790 *  D16MULF:
24791 *   1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
24792 *  +-----------+---+---+-------+-------+-------+-------+-----------+
24793 *  |  SPECIAL2 |x x|on2|0 0 0 0|  XRc  |  XRb  |  XRa  |MXU__POOL03|
24794 *  +-----------+---+---+-------+-------+-------+-------+-----------+
24795 *
24796 *  D16MULE:
24797 *   1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
24798 *  +-----------+---+---+-------+-------+-------+-------+-----------+
24799 *  |  SPECIAL2 |x x|on2|   Xd  |  XRc  |  XRb  |  XRa  |MXU__POOL03|
24800 *  +-----------+---+---+-------+-------+-------+-------+-----------+
24801 *
24802 */
24803static void decode_opc_mxu__pool03(CPUMIPSState *env, DisasContext *ctx)
24804{
24805    uint32_t opcode = extract32(ctx->opcode, 24, 2);
24806
24807    switch (opcode) {
24808    case OPC_MXU_D16MULF:
24809        /* TODO: Implement emulation of D16MULF instruction. */
24810        MIPS_INVAL("OPC_MXU_D16MULF");
24811        generate_exception_end(ctx, EXCP_RI);
24812        break;
24813    case OPC_MXU_D16MULE:
24814        /* TODO: Implement emulation of D16MULE instruction. */
24815        MIPS_INVAL("OPC_MXU_D16MULE");
24816        generate_exception_end(ctx, EXCP_RI);
24817        break;
24818    default:
24819        MIPS_INVAL("decode_opc_mxu");
24820        generate_exception_end(ctx, EXCP_RI);
24821        break;
24822    }
24823}
24824
24825/*
24826 *
24827 * Decode MXU pool04
24828 *
24829 *   1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
24830 *  +-----------+---------+-+-------------------+-------+-----------+
24831 *  |  SPECIAL2 |    rb   |x|        s12        |  XRa  |MXU__POOL04|
24832 *  +-----------+---------+-+-------------------+-------+-----------+
24833 *
24834 */
24835static void decode_opc_mxu__pool04(CPUMIPSState *env, DisasContext *ctx)
24836{
24837    uint32_t opcode = extract32(ctx->opcode, 20, 1);
24838
24839    switch (opcode) {
24840    case OPC_MXU_S32LDD:
24841    case OPC_MXU_S32LDDR:
24842        gen_mxu_s32ldd_s32lddr(ctx);
24843        break;
24844    default:
24845        MIPS_INVAL("decode_opc_mxu");
24846        generate_exception_end(ctx, EXCP_RI);
24847        break;
24848    }
24849}
24850
24851/*
24852 *
24853 * Decode MXU pool05
24854 *
24855 *   1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
24856 *  +-----------+---------+-+-------------------+-------+-----------+
24857 *  |  SPECIAL2 |    rb   |x|        s12        |  XRa  |MXU__POOL05|
24858 *  +-----------+---------+-+-------------------+-------+-----------+
24859 *
24860 */
24861static void decode_opc_mxu__pool05(CPUMIPSState *env, DisasContext *ctx)
24862{
24863    uint32_t opcode = extract32(ctx->opcode, 20, 1);
24864
24865    switch (opcode) {
24866    case OPC_MXU_S32STD:
24867        /* TODO: Implement emulation of S32STD instruction. */
24868        MIPS_INVAL("OPC_MXU_S32STD");
24869        generate_exception_end(ctx, EXCP_RI);
24870        break;
24871    case OPC_MXU_S32STDR:
24872        /* TODO: Implement emulation of S32STDR instruction. */
24873        MIPS_INVAL("OPC_MXU_S32STDR");
24874        generate_exception_end(ctx, EXCP_RI);
24875        break;
24876    default:
24877        MIPS_INVAL("decode_opc_mxu");
24878        generate_exception_end(ctx, EXCP_RI);
24879        break;
24880    }
24881}
24882
24883/*
24884 *
24885 * Decode MXU pool06
24886 *
24887 *   1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
24888 *  +-----------+---------+---------+---+-------+-------+-----------+
24889 *  |  SPECIAL2 |    rb   |    rc   |st2|x x x x|  XRa  |MXU__POOL06|
24890 *  +-----------+---------+---------+---+-------+-------+-----------+
24891 *
24892 */
24893static void decode_opc_mxu__pool06(CPUMIPSState *env, DisasContext *ctx)
24894{
24895    uint32_t opcode = extract32(ctx->opcode, 10, 4);
24896
24897    switch (opcode) {
24898    case OPC_MXU_S32LDDV:
24899        /* TODO: Implement emulation of S32LDDV instruction. */
24900        MIPS_INVAL("OPC_MXU_S32LDDV");
24901        generate_exception_end(ctx, EXCP_RI);
24902        break;
24903    case OPC_MXU_S32LDDVR:
24904        /* TODO: Implement emulation of S32LDDVR instruction. */
24905        MIPS_INVAL("OPC_MXU_S32LDDVR");
24906        generate_exception_end(ctx, EXCP_RI);
24907        break;
24908    default:
24909        MIPS_INVAL("decode_opc_mxu");
24910        generate_exception_end(ctx, EXCP_RI);
24911        break;
24912    }
24913}
24914
24915/*
24916 *
24917 * Decode MXU pool07
24918 *
24919 *   1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
24920 *  +-----------+---------+---------+---+-------+-------+-----------+
24921 *  |  SPECIAL2 |    rb   |    rc   |st2|x x x x|  XRa  |MXU__POOL07|
24922 *  +-----------+---------+---------+---+-------+-------+-----------+
24923 *
24924 */
24925static void decode_opc_mxu__pool07(CPUMIPSState *env, DisasContext *ctx)
24926{
24927    uint32_t opcode = extract32(ctx->opcode, 10, 4);
24928
24929    switch (opcode) {
24930    case OPC_MXU_S32STDV:
24931        /* TODO: Implement emulation of S32TDV instruction. */
24932        MIPS_INVAL("OPC_MXU_S32TDV");
24933        generate_exception_end(ctx, EXCP_RI);
24934        break;
24935    case OPC_MXU_S32STDVR:
24936        /* TODO: Implement emulation of S32TDVR instruction. */
24937        MIPS_INVAL("OPC_MXU_S32TDVR");
24938        generate_exception_end(ctx, EXCP_RI);
24939        break;
24940    default:
24941        MIPS_INVAL("decode_opc_mxu");
24942        generate_exception_end(ctx, EXCP_RI);
24943        break;
24944    }
24945}
24946
24947/*
24948 *
24949 * Decode MXU pool08
24950 *
24951 *   1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
24952 *  +-----------+---------+-+-------------------+-------+-----------+
24953 *  |  SPECIAL2 |    rb   |x|        s12        |  XRa  |MXU__POOL08|
24954 *  +-----------+---------+-+-------------------+-------+-----------+
24955 *
24956*/
24957static void decode_opc_mxu__pool08(CPUMIPSState *env, DisasContext *ctx)
24958{
24959    uint32_t opcode = extract32(ctx->opcode, 20, 1);
24960
24961    switch (opcode) {
24962    case OPC_MXU_S32LDI:
24963        /* TODO: Implement emulation of S32LDI instruction. */
24964        MIPS_INVAL("OPC_MXU_S32LDI");
24965        generate_exception_end(ctx, EXCP_RI);
24966        break;
24967    case OPC_MXU_S32LDIR:
24968        /* TODO: Implement emulation of S32LDIR instruction. */
24969        MIPS_INVAL("OPC_MXU_S32LDIR");
24970        generate_exception_end(ctx, EXCP_RI);
24971        break;
24972    default:
24973        MIPS_INVAL("decode_opc_mxu");
24974        generate_exception_end(ctx, EXCP_RI);
24975        break;
24976    }
24977}
24978
24979/*
24980 *
24981 * Decode MXU pool09
24982 *
24983 *   1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
24984 *  +-----------+---------+-+-------------------+-------+-----------+
24985 *  |  SPECIAL2 |    rb   |x|        s12        |  XRa  |MXU__POOL09|
24986 *  +-----------+---------+-+-------------------+-------+-----------+
24987 *
24988 */
24989static void decode_opc_mxu__pool09(CPUMIPSState *env, DisasContext *ctx)
24990{
24991    uint32_t opcode = extract32(ctx->opcode, 5, 0);
24992
24993    switch (opcode) {
24994    case OPC_MXU_S32SDI:
24995        /* TODO: Implement emulation of S32SDI instruction. */
24996        MIPS_INVAL("OPC_MXU_S32SDI");
24997        generate_exception_end(ctx, EXCP_RI);
24998        break;
24999    case OPC_MXU_S32SDIR:
25000        /* TODO: Implement emulation of S32SDIR instruction. */
25001        MIPS_INVAL("OPC_MXU_S32SDIR");
25002        generate_exception_end(ctx, EXCP_RI);
25003        break;
25004    default:
25005        MIPS_INVAL("decode_opc_mxu");
25006        generate_exception_end(ctx, EXCP_RI);
25007        break;
25008    }
25009}
25010
25011/*
25012 *
25013 * Decode MXU pool10
25014 *
25015 *   1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
25016 *  +-----------+---------+---------+---+-------+-------+-----------+
25017 *  |  SPECIAL2 |    rb   |    rc   |st2|x x x x|  XRa  |MXU__POOL10|
25018 *  +-----------+---------+---------+---+-------+-------+-----------+
25019 *
25020 */
25021static void decode_opc_mxu__pool10(CPUMIPSState *env, DisasContext *ctx)
25022{
25023    uint32_t opcode = extract32(ctx->opcode, 5, 0);
25024
25025    switch (opcode) {
25026    case OPC_MXU_S32LDIV:
25027        /* TODO: Implement emulation of S32LDIV instruction. */
25028        MIPS_INVAL("OPC_MXU_S32LDIV");
25029        generate_exception_end(ctx, EXCP_RI);
25030        break;
25031    case OPC_MXU_S32LDIVR:
25032        /* TODO: Implement emulation of S32LDIVR instruction. */
25033        MIPS_INVAL("OPC_MXU_S32LDIVR");
25034        generate_exception_end(ctx, EXCP_RI);
25035        break;
25036    default:
25037        MIPS_INVAL("decode_opc_mxu");
25038        generate_exception_end(ctx, EXCP_RI);
25039        break;
25040    }
25041}
25042
25043/*
25044 *
25045 * Decode MXU pool11
25046 *
25047 *   1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
25048 *  +-----------+---------+---------+---+-------+-------+-----------+
25049 *  |  SPECIAL2 |    rb   |    rc   |st2|x x x x|  XRa  |MXU__POOL11|
25050 *  +-----------+---------+---------+---+-------+-------+-----------+
25051 *
25052 */
25053static void decode_opc_mxu__pool11(CPUMIPSState *env, DisasContext *ctx)
25054{
25055    uint32_t opcode = extract32(ctx->opcode, 10, 4);
25056
25057    switch (opcode) {
25058    case OPC_MXU_S32SDIV:
25059        /* TODO: Implement emulation of S32SDIV instruction. */
25060        MIPS_INVAL("OPC_MXU_S32SDIV");
25061        generate_exception_end(ctx, EXCP_RI);
25062        break;
25063    case OPC_MXU_S32SDIVR:
25064        /* TODO: Implement emulation of S32SDIVR instruction. */
25065        MIPS_INVAL("OPC_MXU_S32SDIVR");
25066        generate_exception_end(ctx, EXCP_RI);
25067        break;
25068    default:
25069        MIPS_INVAL("decode_opc_mxu");
25070        generate_exception_end(ctx, EXCP_RI);
25071        break;
25072    }
25073}
25074
25075/*
25076 *
25077 * Decode MXU pool12
25078 *
25079 *   1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
25080 *  +-----------+---+---+-------+-------+-------+-------+-----------+
25081 *  |  SPECIAL2 |an2|x x|   Xd  |  XRc  |  XRb  |  XRa  |MXU__POOL12|
25082 *  +-----------+---+---+-------+-------+-------+-------+-----------+
25083 *
25084 */
25085static void decode_opc_mxu__pool12(CPUMIPSState *env, DisasContext *ctx)
25086{
25087    uint32_t opcode = extract32(ctx->opcode, 22, 2);
25088
25089    switch (opcode) {
25090    case OPC_MXU_D32ACC:
25091        /* TODO: Implement emulation of D32ACC instruction. */
25092        MIPS_INVAL("OPC_MXU_D32ACC");
25093        generate_exception_end(ctx, EXCP_RI);
25094        break;
25095    case OPC_MXU_D32ACCM:
25096        /* TODO: Implement emulation of D32ACCM instruction. */
25097        MIPS_INVAL("OPC_MXU_D32ACCM");
25098        generate_exception_end(ctx, EXCP_RI);
25099        break;
25100    case OPC_MXU_D32ASUM:
25101        /* TODO: Implement emulation of D32ASUM instruction. */
25102        MIPS_INVAL("OPC_MXU_D32ASUM");
25103        generate_exception_end(ctx, EXCP_RI);
25104        break;
25105    default:
25106        MIPS_INVAL("decode_opc_mxu");
25107        generate_exception_end(ctx, EXCP_RI);
25108        break;
25109    }
25110}
25111
25112/*
25113 *
25114 * Decode MXU pool13
25115 *
25116 *   1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
25117 *  +-----------+---+---+-------+-------+-------+-------+-----------+
25118 *  |  SPECIAL2 |en2|x x|0 0 0 0|  XRc  |  XRb  |  XRa  |MXU__POOL13|
25119 *  +-----------+---+---+-------+-------+-------+-------+-----------+
25120 *
25121 */
25122static void decode_opc_mxu__pool13(CPUMIPSState *env, DisasContext *ctx)
25123{
25124    uint32_t opcode = extract32(ctx->opcode, 22, 2);
25125
25126    switch (opcode) {
25127    case OPC_MXU_Q16ACC:
25128        /* TODO: Implement emulation of Q16ACC instruction. */
25129        MIPS_INVAL("OPC_MXU_Q16ACC");
25130        generate_exception_end(ctx, EXCP_RI);
25131        break;
25132    case OPC_MXU_Q16ACCM:
25133        /* TODO: Implement emulation of Q16ACCM instruction. */
25134        MIPS_INVAL("OPC_MXU_Q16ACCM");
25135        generate_exception_end(ctx, EXCP_RI);
25136        break;
25137    case OPC_MXU_Q16ASUM:
25138        /* TODO: Implement emulation of Q16ASUM instruction. */
25139        MIPS_INVAL("OPC_MXU_Q16ASUM");
25140        generate_exception_end(ctx, EXCP_RI);
25141        break;
25142    default:
25143        MIPS_INVAL("decode_opc_mxu");
25144        generate_exception_end(ctx, EXCP_RI);
25145        break;
25146    }
25147}
25148
25149/*
25150 *
25151 * Decode MXU pool14
25152 *
25153 *  Q8ADDE, Q8ACCE:
25154 *   1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
25155 *  +-----------+---+---+-------+-------+-------+-------+-----------+
25156 *  |  SPECIAL2 |0 0|x x|  XRd  |  XRc  |  XRb  |  XRa  |MXU__POOL14|
25157 *  +-----------+---+---+-------+-------+-------+-------+-----------+
25158 *
25159 *  D8SUM, D8SUMC:
25160 *   1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
25161 *  +-----------+---+---+-------+-------+-------+-------+-----------+
25162 *  |  SPECIAL2 |en2|x x|0 0 0 0|  XRc  |  XRb  |  XRa  |MXU__POOL14|
25163 *  +-----------+---+---+-------+-------+-------+-------+-----------+
25164 *
25165 */
25166static void decode_opc_mxu__pool14(CPUMIPSState *env, DisasContext *ctx)
25167{
25168    uint32_t opcode = extract32(ctx->opcode, 22, 2);
25169
25170    switch (opcode) {
25171    case OPC_MXU_Q8ADDE:
25172        /* TODO: Implement emulation of Q8ADDE instruction. */
25173        MIPS_INVAL("OPC_MXU_Q8ADDE");
25174        generate_exception_end(ctx, EXCP_RI);
25175        break;
25176    case OPC_MXU_D8SUM:
25177        /* TODO: Implement emulation of D8SUM instruction. */
25178        MIPS_INVAL("OPC_MXU_D8SUM");
25179        generate_exception_end(ctx, EXCP_RI);
25180        break;
25181    case OPC_MXU_D8SUMC:
25182        /* TODO: Implement emulation of D8SUMC instruction. */
25183        MIPS_INVAL("OPC_MXU_D8SUMC");
25184        generate_exception_end(ctx, EXCP_RI);
25185        break;
25186    default:
25187        MIPS_INVAL("decode_opc_mxu");
25188        generate_exception_end(ctx, EXCP_RI);
25189        break;
25190    }
25191}
25192
25193/*
25194 *
25195 * Decode MXU pool15
25196 *
25197 *  S32MUL, S32MULU, S32EXTRV:
25198 *   1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
25199 *  +-----------+---------+---------+---+-------+-------+-----------+
25200 *  |  SPECIAL2 |    rs   |    rt   |x x|  XRd  |  XRa  |MXU__POOL15|
25201 *  +-----------+---------+---------+---+-------+-------+-----------+
25202 *
25203 *  S32EXTR:
25204 *   1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
25205 *  +-----------+---------+---------+---+-------+-------+-----------+
25206 *  |  SPECIAL2 |    rb   |   sft5  |x x|  XRd  |  XRa  |MXU__POOL15|
25207 *  +-----------+---------+---------+---+-------+-------+-----------+
25208 *
25209 */
25210static void decode_opc_mxu__pool15(CPUMIPSState *env, DisasContext *ctx)
25211{
25212    uint32_t opcode = extract32(ctx->opcode, 14, 2);
25213
25214    switch (opcode) {
25215    case OPC_MXU_S32MUL:
25216        /* TODO: Implement emulation of S32MUL instruction. */
25217        MIPS_INVAL("OPC_MXU_S32MUL");
25218        generate_exception_end(ctx, EXCP_RI);
25219        break;
25220    case OPC_MXU_S32MULU:
25221        /* TODO: Implement emulation of S32MULU instruction. */
25222        MIPS_INVAL("OPC_MXU_S32MULU");
25223        generate_exception_end(ctx, EXCP_RI);
25224        break;
25225    case OPC_MXU_S32EXTR:
25226        /* TODO: Implement emulation of S32EXTR instruction. */
25227        MIPS_INVAL("OPC_MXU_S32EXTR");
25228        generate_exception_end(ctx, EXCP_RI);
25229        break;
25230    case OPC_MXU_S32EXTRV:
25231        /* TODO: Implement emulation of S32EXTRV instruction. */
25232        MIPS_INVAL("OPC_MXU_S32EXTRV");
25233        generate_exception_end(ctx, EXCP_RI);
25234        break;
25235    default:
25236        MIPS_INVAL("decode_opc_mxu");
25237        generate_exception_end(ctx, EXCP_RI);
25238        break;
25239    }
25240}
25241
25242/*
25243 *
25244 * Decode MXU pool16
25245 *
25246 *  D32SARW:
25247 *   1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
25248 *  +-----------+---------+-----+-------+-------+-------+-----------+
25249 *  |  SPECIAL2 |    rb   |x x x|  XRc  |  XRb  |  XRa  |MXU__POOL16|
25250 *  +-----------+---------+-----+-------+-------+-------+-----------+
25251 *
25252 *  S32ALN:
25253 *   1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
25254 *  +-----------+---------+-----+-------+-------+-------+-----------+
25255 *  |  SPECIAL2 |    rs   |x x x|  XRc  |  XRb  |  XRa  |MXU__POOL16|
25256 *  +-----------+---------+-----+-------+-------+-------+-----------+
25257 *
25258 *  S32ALNI:
25259 *   1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
25260 *  +-----------+-----+---+-----+-------+-------+-------+-----------+
25261 *  |  SPECIAL2 |  s3 |0 0|x x x|  XRc  |  XRb  |  XRa  |MXU__POOL16|
25262 *  +-----------+-----+---+-----+-------+-------+-------+-----------+
25263 *
25264 *  S32NOR, S32AND, S32OR, S32XOR:
25265 *   1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
25266 *  +-----------+---------+-----+-------+-------+-------+-----------+
25267 *  |  SPECIAL2 |0 0 0 0 0|x x x|  XRc  |  XRb  |  XRa  |MXU__POOL16|
25268 *  +-----------+---------+-----+-------+-------+-------+-----------+
25269 *
25270 *  S32LUI:
25271 *   1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
25272 *  +-----------+-----+---+-----+-------+---------------+-----------+
25273 *  |  SPECIAL2 |optn3|0 0|x x x|  XRc  |       s8      |MXU__POOL16|
25274 *  +-----------+-----+---+-----+-------+---------------+-----------+
25275 *
25276 */
25277static void decode_opc_mxu__pool16(CPUMIPSState *env, DisasContext *ctx)
25278{
25279    uint32_t opcode = extract32(ctx->opcode, 18, 3);
25280
25281    switch (opcode) {
25282    case OPC_MXU_D32SARW:
25283        /* TODO: Implement emulation of D32SARW instruction. */
25284        MIPS_INVAL("OPC_MXU_D32SARW");
25285        generate_exception_end(ctx, EXCP_RI);
25286        break;
25287    case OPC_MXU_S32ALN:
25288        /* TODO: Implement emulation of S32ALN instruction. */
25289        MIPS_INVAL("OPC_MXU_S32ALN");
25290        generate_exception_end(ctx, EXCP_RI);
25291        break;
25292    case OPC_MXU_S32ALNI:
25293        /* TODO: Implement emulation of S32ALNI instruction. */
25294        MIPS_INVAL("OPC_MXU_S32ALNI");
25295        generate_exception_end(ctx, EXCP_RI);
25296        break;
25297    case OPC_MXU_S32NOR:
25298        /* TODO: Implement emulation of S32NOR instruction. */
25299        MIPS_INVAL("OPC_MXU_S32NOR");
25300        generate_exception_end(ctx, EXCP_RI);
25301        break;
25302    case OPC_MXU_S32AND:
25303        /* TODO: Implement emulation of S32AND instruction. */
25304        MIPS_INVAL("OPC_MXU_S32AND");
25305        generate_exception_end(ctx, EXCP_RI);
25306        break;
25307    case OPC_MXU_S32OR:
25308        /* TODO: Implement emulation of S32OR instruction. */
25309        MIPS_INVAL("OPC_MXU_S32OR");
25310        generate_exception_end(ctx, EXCP_RI);
25311        break;
25312    case OPC_MXU_S32XOR:
25313        /* TODO: Implement emulation of S32XOR instruction. */
25314        MIPS_INVAL("OPC_MXU_S32XOR");
25315        generate_exception_end(ctx, EXCP_RI);
25316        break;
25317    case OPC_MXU_S32LUI:
25318        /* TODO: Implement emulation of S32LUI instruction. */
25319        MIPS_INVAL("OPC_MXU_S32LUI");
25320        generate_exception_end(ctx, EXCP_RI);
25321        break;
25322    default:
25323        MIPS_INVAL("decode_opc_mxu");
25324        generate_exception_end(ctx, EXCP_RI);
25325        break;
25326    }
25327}
25328
25329/*
25330 *
25331 * Decode MXU pool17
25332 *
25333 *   1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
25334 *  +-----------+---------+-----+-------+-------+-------+-----------+
25335 *  |  SPECIAL2 |    rb   |x x x|  XRd  |  XRa  |0 0 0 0|MXU__POOL17|
25336 *  +-----------+---------+-----+-------+-------+-------+-----------+
25337 *
25338 */
25339static void decode_opc_mxu__pool17(CPUMIPSState *env, DisasContext *ctx)
25340{
25341    uint32_t opcode = extract32(ctx->opcode, 18, 3);
25342
25343    switch (opcode) {
25344    case OPC_MXU_D32SLLV:
25345        /* TODO: Implement emulation of D32SLLV instruction. */
25346        MIPS_INVAL("OPC_MXU_D32SLLV");
25347        generate_exception_end(ctx, EXCP_RI);
25348        break;
25349    case OPC_MXU_D32SLRV:
25350        /* TODO: Implement emulation of D32SLRV instruction. */
25351        MIPS_INVAL("OPC_MXU_D32SLRV");
25352        generate_exception_end(ctx, EXCP_RI);
25353        break;
25354    case OPC_MXU_D32SARV:
25355        /* TODO: Implement emulation of D32SARV instruction. */
25356        MIPS_INVAL("OPC_MXU_D32SARV");
25357        generate_exception_end(ctx, EXCP_RI);
25358        break;
25359    case OPC_MXU_Q16SLLV:
25360        /* TODO: Implement emulation of Q16SLLV instruction. */
25361        MIPS_INVAL("OPC_MXU_Q16SLLV");
25362        generate_exception_end(ctx, EXCP_RI);
25363        break;
25364    case OPC_MXU_Q16SLRV:
25365        /* TODO: Implement emulation of Q16SLRV instruction. */
25366        MIPS_INVAL("OPC_MXU_Q16SLRV");
25367        generate_exception_end(ctx, EXCP_RI);
25368        break;
25369    case OPC_MXU_Q16SARV:
25370        /* TODO: Implement emulation of Q16SARV instruction. */
25371        MIPS_INVAL("OPC_MXU_Q16SARV");
25372        generate_exception_end(ctx, EXCP_RI);
25373        break;
25374    default:
25375        MIPS_INVAL("decode_opc_mxu");
25376        generate_exception_end(ctx, EXCP_RI);
25377        break;
25378    }
25379}
25380
25381/*
25382 *
25383 * Decode MXU pool18
25384 *
25385 *   1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
25386 *  +-----------+---+---+-------+-------+-------+-------+-----------+
25387 *  |  SPECIAL2 |0 0|x x|  XRd  |  XRc  |  XRb  |  XRa  |MXU__POOL18|
25388 *  +-----------+---+---+-------+-------+-------+-------+-----------+
25389 *
25390 */
25391static void decode_opc_mxu__pool18(CPUMIPSState *env, DisasContext *ctx)
25392{
25393    uint32_t opcode = extract32(ctx->opcode, 22, 2);
25394
25395    switch (opcode) {
25396    case OPC_MXU_Q8MUL:
25397    case OPC_MXU_Q8MULSU:
25398        gen_mxu_q8mul_q8mulsu(ctx);
25399        break;
25400    default:
25401        MIPS_INVAL("decode_opc_mxu");
25402        generate_exception_end(ctx, EXCP_RI);
25403        break;
25404    }
25405}
25406
25407/*
25408 *
25409 * Decode MXU pool19
25410 *
25411 *   1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
25412 *  +-----------+---------+-----+-------+-------+-------+-----------+
25413 *  |  SPECIAL2 |0 0 0 0 0|x x x|  XRc  |  XRb  |  XRa  |MXU__POOL19|
25414 *  +-----------+---------+-----+-------+-------+-------+-----------+
25415 *
25416 */
25417static void decode_opc_mxu__pool19(CPUMIPSState *env, DisasContext *ctx)
25418{
25419    uint32_t opcode = extract32(ctx->opcode, 18, 3);
25420
25421    switch (opcode) {
25422    case OPC_MXU_Q8MOVZ:
25423        /* TODO: Implement emulation of Q8MOVZ instruction. */
25424        MIPS_INVAL("OPC_MXU_Q8MOVZ");
25425        generate_exception_end(ctx, EXCP_RI);
25426        break;
25427    case OPC_MXU_Q8MOVN:
25428        /* TODO: Implement emulation of Q8MOVN instruction. */
25429        MIPS_INVAL("OPC_MXU_Q8MOVN");
25430        generate_exception_end(ctx, EXCP_RI);
25431        break;
25432    case OPC_MXU_D16MOVZ:
25433        /* TODO: Implement emulation of D16MOVZ instruction. */
25434        MIPS_INVAL("OPC_MXU_D16MOVZ");
25435        generate_exception_end(ctx, EXCP_RI);
25436        break;
25437    case OPC_MXU_D16MOVN:
25438        /* TODO: Implement emulation of D16MOVN instruction. */
25439        MIPS_INVAL("OPC_MXU_D16MOVN");
25440        generate_exception_end(ctx, EXCP_RI);
25441        break;
25442    case OPC_MXU_S32MOVZ:
25443        /* TODO: Implement emulation of S32MOVZ instruction. */
25444        MIPS_INVAL("OPC_MXU_S32MOVZ");
25445        generate_exception_end(ctx, EXCP_RI);
25446        break;
25447    case OPC_MXU_S32MOVN:
25448        /* TODO: Implement emulation of S32MOVN instruction. */
25449        MIPS_INVAL("OPC_MXU_S32MOVN");
25450        generate_exception_end(ctx, EXCP_RI);
25451        break;
25452    default:
25453        MIPS_INVAL("decode_opc_mxu");
25454        generate_exception_end(ctx, EXCP_RI);
25455        break;
25456    }
25457}
25458
25459/*
25460 *
25461 * Decode MXU pool20
25462 *
25463 *   1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
25464 *  +-----------+---+---+-------+-------+-------+-------+-----------+
25465 *  |  SPECIAL2 |an2|x x|  XRd  |  XRc  |  XRb  |  XRa  |MXU__POOL20|
25466 *  +-----------+---+---+-------+-------+-------+-------+-----------+
25467 *
25468 */
25469static void decode_opc_mxu__pool20(CPUMIPSState *env, DisasContext *ctx)
25470{
25471    uint32_t opcode = extract32(ctx->opcode, 22, 2);
25472
25473    switch (opcode) {
25474    case OPC_MXU_Q8MAC:
25475        /* TODO: Implement emulation of Q8MAC instruction. */
25476        MIPS_INVAL("OPC_MXU_Q8MAC");
25477        generate_exception_end(ctx, EXCP_RI);
25478        break;
25479    case OPC_MXU_Q8MACSU:
25480        /* TODO: Implement emulation of Q8MACSU instruction. */
25481        MIPS_INVAL("OPC_MXU_Q8MACSU");
25482        generate_exception_end(ctx, EXCP_RI);
25483        break;
25484    default:
25485        MIPS_INVAL("decode_opc_mxu");
25486        generate_exception_end(ctx, EXCP_RI);
25487        break;
25488    }
25489}
25490
25491
25492/*
25493 * Main MXU decoding function
25494 *
25495 *   1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
25496 *  +-----------+---------------------------------------+-----------+
25497 *  |  SPECIAL2 |                                       |x x x x x x|
25498 *  +-----------+---------------------------------------+-----------+
25499 *
25500 */
25501static void decode_opc_mxu(CPUMIPSState *env, DisasContext *ctx)
25502{
25503    /*
25504     * TODO: Investigate necessity of including handling of
25505     * CLZ, CLO, SDBB in this function, as they belong to
25506     * SPECIAL2 opcode space for regular pre-R6 MIPS ISAs.
25507     */
25508    uint32_t opcode = extract32(ctx->opcode, 0, 6);
25509
25510    if (opcode == OPC__MXU_MUL) {
25511        uint32_t  rs, rt, rd, op1;
25512
25513        rs = extract32(ctx->opcode, 21, 5);
25514        rt = extract32(ctx->opcode, 16, 5);
25515        rd = extract32(ctx->opcode, 11, 5);
25516        op1 = MASK_SPECIAL2(ctx->opcode);
25517
25518        gen_arith(ctx, op1, rd, rs, rt);
25519
25520        return;
25521    }
25522
25523    if (opcode == OPC_MXU_S32M2I) {
25524        gen_mxu_s32m2i(ctx);
25525        return;
25526    }
25527
25528    if (opcode == OPC_MXU_S32I2M) {
25529        gen_mxu_s32i2m(ctx);
25530        return;
25531    }
25532
25533    {
25534        TCGv t_mxu_cr = tcg_temp_new();
25535        TCGLabel *l_exit = gen_new_label();
25536
25537        gen_load_mxu_cr(t_mxu_cr);
25538        tcg_gen_andi_tl(t_mxu_cr, t_mxu_cr, MXU_CR_MXU_EN);
25539        tcg_gen_brcondi_tl(TCG_COND_NE, t_mxu_cr, MXU_CR_MXU_EN, l_exit);
25540
25541        switch (opcode) {
25542        case OPC_MXU_S32MADD:
25543            /* TODO: Implement emulation of S32MADD instruction. */
25544            MIPS_INVAL("OPC_MXU_S32MADD");
25545            generate_exception_end(ctx, EXCP_RI);
25546            break;
25547        case OPC_MXU_S32MADDU:
25548            /* TODO: Implement emulation of S32MADDU instruction. */
25549            MIPS_INVAL("OPC_MXU_S32MADDU");
25550            generate_exception_end(ctx, EXCP_RI);
25551            break;
25552        case OPC_MXU__POOL00:
25553            decode_opc_mxu__pool00(env, ctx);
25554            break;
25555        case OPC_MXU_S32MSUB:
25556            /* TODO: Implement emulation of S32MSUB instruction. */
25557            MIPS_INVAL("OPC_MXU_S32MSUB");
25558            generate_exception_end(ctx, EXCP_RI);
25559            break;
25560        case OPC_MXU_S32MSUBU:
25561            /* TODO: Implement emulation of S32MSUBU instruction. */
25562            MIPS_INVAL("OPC_MXU_S32MSUBU");
25563            generate_exception_end(ctx, EXCP_RI);
25564            break;
25565        case OPC_MXU__POOL01:
25566            decode_opc_mxu__pool01(env, ctx);
25567            break;
25568        case OPC_MXU__POOL02:
25569            decode_opc_mxu__pool02(env, ctx);
25570            break;
25571        case OPC_MXU_D16MUL:
25572            gen_mxu_d16mul(ctx);
25573            break;
25574        case OPC_MXU__POOL03:
25575            decode_opc_mxu__pool03(env, ctx);
25576            break;
25577        case OPC_MXU_D16MAC:
25578            gen_mxu_d16mac(ctx);
25579            break;
25580        case OPC_MXU_D16MACF:
25581            /* TODO: Implement emulation of D16MACF instruction. */
25582            MIPS_INVAL("OPC_MXU_D16MACF");
25583            generate_exception_end(ctx, EXCP_RI);
25584            break;
25585        case OPC_MXU_D16MADL:
25586            /* TODO: Implement emulation of D16MADL instruction. */
25587            MIPS_INVAL("OPC_MXU_D16MADL");
25588            generate_exception_end(ctx, EXCP_RI);
25589            break;
25590        case OPC_MXU_S16MAD:
25591            /* TODO: Implement emulation of S16MAD instruction. */
25592            MIPS_INVAL("OPC_MXU_S16MAD");
25593            generate_exception_end(ctx, EXCP_RI);
25594            break;
25595        case OPC_MXU_Q16ADD:
25596            /* TODO: Implement emulation of Q16ADD instruction. */
25597            MIPS_INVAL("OPC_MXU_Q16ADD");
25598            generate_exception_end(ctx, EXCP_RI);
25599            break;
25600        case OPC_MXU_D16MACE:
25601            /* TODO: Implement emulation of D16MACE instruction. */
25602            MIPS_INVAL("OPC_MXU_D16MACE");
25603            generate_exception_end(ctx, EXCP_RI);
25604            break;
25605        case OPC_MXU__POOL04:
25606            decode_opc_mxu__pool04(env, ctx);
25607            break;
25608        case OPC_MXU__POOL05:
25609            decode_opc_mxu__pool05(env, ctx);
25610            break;
25611        case OPC_MXU__POOL06:
25612            decode_opc_mxu__pool06(env, ctx);
25613            break;
25614        case OPC_MXU__POOL07:
25615            decode_opc_mxu__pool07(env, ctx);
25616            break;
25617        case OPC_MXU__POOL08:
25618            decode_opc_mxu__pool08(env, ctx);
25619            break;
25620        case OPC_MXU__POOL09:
25621            decode_opc_mxu__pool09(env, ctx);
25622            break;
25623        case OPC_MXU__POOL10:
25624            decode_opc_mxu__pool10(env, ctx);
25625            break;
25626        case OPC_MXU__POOL11:
25627            decode_opc_mxu__pool11(env, ctx);
25628            break;
25629        case OPC_MXU_D32ADD:
25630            /* TODO: Implement emulation of D32ADD instruction. */
25631            MIPS_INVAL("OPC_MXU_D32ADD");
25632            generate_exception_end(ctx, EXCP_RI);
25633            break;
25634        case OPC_MXU__POOL12:
25635            decode_opc_mxu__pool12(env, ctx);
25636            break;
25637        case OPC_MXU__POOL13:
25638            decode_opc_mxu__pool13(env, ctx);
25639            break;
25640        case OPC_MXU__POOL14:
25641            decode_opc_mxu__pool14(env, ctx);
25642            break;
25643        case OPC_MXU_Q8ACCE:
25644            /* TODO: Implement emulation of Q8ACCE instruction. */
25645            MIPS_INVAL("OPC_MXU_Q8ACCE");
25646            generate_exception_end(ctx, EXCP_RI);
25647            break;
25648        case OPC_MXU_S8LDD:
25649            gen_mxu_s8ldd(ctx);
25650            break;
25651        case OPC_MXU_S8STD:
25652            /* TODO: Implement emulation of S8STD instruction. */
25653            MIPS_INVAL("OPC_MXU_S8STD");
25654            generate_exception_end(ctx, EXCP_RI);
25655            break;
25656        case OPC_MXU_S8LDI:
25657            /* TODO: Implement emulation of S8LDI instruction. */
25658            MIPS_INVAL("OPC_MXU_S8LDI");
25659            generate_exception_end(ctx, EXCP_RI);
25660            break;
25661        case OPC_MXU_S8SDI:
25662            /* TODO: Implement emulation of S8SDI instruction. */
25663            MIPS_INVAL("OPC_MXU_S8SDI");
25664            generate_exception_end(ctx, EXCP_RI);
25665            break;
25666        case OPC_MXU__POOL15:
25667            decode_opc_mxu__pool15(env, ctx);
25668            break;
25669        case OPC_MXU__POOL16:
25670            decode_opc_mxu__pool16(env, ctx);
25671            break;
25672        case OPC_MXU_LXB:
25673            /* TODO: Implement emulation of LXB instruction. */
25674            MIPS_INVAL("OPC_MXU_LXB");
25675            generate_exception_end(ctx, EXCP_RI);
25676            break;
25677        case OPC_MXU_S16LDD:
25678            /* TODO: Implement emulation of S16LDD instruction. */
25679            MIPS_INVAL("OPC_MXU_S16LDD");
25680            generate_exception_end(ctx, EXCP_RI);
25681            break;
25682        case OPC_MXU_S16STD:
25683            /* TODO: Implement emulation of S16STD instruction. */
25684            MIPS_INVAL("OPC_MXU_S16STD");
25685            generate_exception_end(ctx, EXCP_RI);
25686            break;
25687        case OPC_MXU_S16LDI:
25688            /* TODO: Implement emulation of S16LDI instruction. */
25689            MIPS_INVAL("OPC_MXU_S16LDI");
25690            generate_exception_end(ctx, EXCP_RI);
25691            break;
25692        case OPC_MXU_S16SDI:
25693            /* TODO: Implement emulation of S16SDI instruction. */
25694            MIPS_INVAL("OPC_MXU_S16SDI");
25695            generate_exception_end(ctx, EXCP_RI);
25696            break;
25697        case OPC_MXU_D32SLL:
25698            /* TODO: Implement emulation of D32SLL instruction. */
25699            MIPS_INVAL("OPC_MXU_D32SLL");
25700            generate_exception_end(ctx, EXCP_RI);
25701            break;
25702        case OPC_MXU_D32SLR:
25703            /* TODO: Implement emulation of D32SLR instruction. */
25704            MIPS_INVAL("OPC_MXU_D32SLR");
25705            generate_exception_end(ctx, EXCP_RI);
25706            break;
25707        case OPC_MXU_D32SARL:
25708            /* TODO: Implement emulation of D32SARL instruction. */
25709            MIPS_INVAL("OPC_MXU_D32SARL");
25710            generate_exception_end(ctx, EXCP_RI);
25711            break;
25712        case OPC_MXU_D32SAR:
25713            /* TODO: Implement emulation of D32SAR instruction. */
25714            MIPS_INVAL("OPC_MXU_D32SAR");
25715            generate_exception_end(ctx, EXCP_RI);
25716            break;
25717        case OPC_MXU_Q16SLL:
25718            /* TODO: Implement emulation of Q16SLL instruction. */
25719            MIPS_INVAL("OPC_MXU_Q16SLL");
25720            generate_exception_end(ctx, EXCP_RI);
25721            break;
25722        case OPC_MXU_Q16SLR:
25723            /* TODO: Implement emulation of Q16SLR instruction. */
25724            MIPS_INVAL("OPC_MXU_Q16SLR");
25725            generate_exception_end(ctx, EXCP_RI);
25726            break;
25727        case OPC_MXU__POOL17:
25728            decode_opc_mxu__pool17(env, ctx);
25729            break;
25730        case OPC_MXU_Q16SAR:
25731            /* TODO: Implement emulation of Q16SAR instruction. */
25732            MIPS_INVAL("OPC_MXU_Q16SAR");
25733            generate_exception_end(ctx, EXCP_RI);
25734            break;
25735        case OPC_MXU__POOL18:
25736            decode_opc_mxu__pool18(env, ctx);
25737            break;
25738        case OPC_MXU__POOL19:
25739            decode_opc_mxu__pool19(env, ctx);
25740            break;
25741        case OPC_MXU__POOL20:
25742            decode_opc_mxu__pool20(env, ctx);
25743            break;
25744        case OPC_MXU_Q16SCOP:
25745            /* TODO: Implement emulation of Q16SCOP instruction. */
25746            MIPS_INVAL("OPC_MXU_Q16SCOP");
25747            generate_exception_end(ctx, EXCP_RI);
25748            break;
25749        case OPC_MXU_Q8MADL:
25750            /* TODO: Implement emulation of Q8MADL instruction. */
25751            MIPS_INVAL("OPC_MXU_Q8MADL");
25752            generate_exception_end(ctx, EXCP_RI);
25753            break;
25754        case OPC_MXU_S32SFL:
25755            /* TODO: Implement emulation of S32SFL instruction. */
25756            MIPS_INVAL("OPC_MXU_S32SFL");
25757            generate_exception_end(ctx, EXCP_RI);
25758            break;
25759        case OPC_MXU_Q8SAD:
25760            /* TODO: Implement emulation of Q8SAD instruction. */
25761            MIPS_INVAL("OPC_MXU_Q8SAD");
25762            generate_exception_end(ctx, EXCP_RI);
25763            break;
25764        default:
25765            MIPS_INVAL("decode_opc_mxu");
25766            generate_exception_end(ctx, EXCP_RI);
25767        }
25768
25769        gen_set_label(l_exit);
25770        tcg_temp_free(t_mxu_cr);
25771    }
25772}
25773
25774
25775static void decode_opc_special2_legacy(CPUMIPSState *env, DisasContext *ctx)
25776{
25777    int rs, rt, rd;
25778    uint32_t op1;
25779
25780    check_insn_opc_removed(ctx, ISA_MIPS32R6);
25781
25782    rs = (ctx->opcode >> 21) & 0x1f;
25783    rt = (ctx->opcode >> 16) & 0x1f;
25784    rd = (ctx->opcode >> 11) & 0x1f;
25785
25786    op1 = MASK_SPECIAL2(ctx->opcode);
25787    switch (op1) {
25788    case OPC_MADD: /* Multiply and add/sub */
25789    case OPC_MADDU:
25790    case OPC_MSUB:
25791    case OPC_MSUBU:
25792        check_insn(ctx, ISA_MIPS32);
25793        gen_muldiv(ctx, op1, rd & 3, rs, rt);
25794        break;
25795    case OPC_MUL:
25796        gen_arith(ctx, op1, rd, rs, rt);
25797        break;
25798    case OPC_DIV_G_2F:
25799    case OPC_DIVU_G_2F:
25800    case OPC_MULT_G_2F:
25801    case OPC_MULTU_G_2F:
25802    case OPC_MOD_G_2F:
25803    case OPC_MODU_G_2F:
25804        check_insn(ctx, INSN_LOONGSON2F);
25805        gen_loongson_integer(ctx, op1, rd, rs, rt);
25806        break;
25807    case OPC_CLO:
25808    case OPC_CLZ:
25809        check_insn(ctx, ISA_MIPS32);
25810        gen_cl(ctx, op1, rd, rs);
25811        break;
25812    case OPC_SDBBP:
25813        if (is_uhi(extract32(ctx->opcode, 6, 20))) {
25814            gen_helper_do_semihosting(cpu_env);
25815        } else {
25816            /* XXX: not clear which exception should be raised
25817             *      when in debug mode...
25818             */
25819            check_insn(ctx, ISA_MIPS32);
25820            generate_exception_end(ctx, EXCP_DBp);
25821        }
25822        break;
25823#if defined(TARGET_MIPS64)
25824    case OPC_DCLO:
25825    case OPC_DCLZ:
25826        check_insn(ctx, ISA_MIPS64);
25827        check_mips_64(ctx);
25828        gen_cl(ctx, op1, rd, rs);
25829        break;
25830    case OPC_DMULT_G_2F:
25831    case OPC_DMULTU_G_2F:
25832    case OPC_DDIV_G_2F:
25833    case OPC_DDIVU_G_2F:
25834    case OPC_DMOD_G_2F:
25835    case OPC_DMODU_G_2F:
25836        check_insn(ctx, INSN_LOONGSON2F);
25837        gen_loongson_integer(ctx, op1, rd, rs, rt);
25838        break;
25839#endif
25840    default:            /* Invalid */
25841        MIPS_INVAL("special2_legacy");
25842        generate_exception_end(ctx, EXCP_RI);
25843        break;
25844    }
25845}
25846
25847static void decode_opc_special3_r6(CPUMIPSState *env, DisasContext *ctx)
25848{
25849    int rs, rt, rd, sa;
25850    uint32_t op1, op2;
25851    int16_t imm;
25852
25853    rs = (ctx->opcode >> 21) & 0x1f;
25854    rt = (ctx->opcode >> 16) & 0x1f;
25855    rd = (ctx->opcode >> 11) & 0x1f;
25856    sa = (ctx->opcode >> 6) & 0x1f;
25857    imm = (int16_t)ctx->opcode >> 7;
25858
25859    op1 = MASK_SPECIAL3(ctx->opcode);
25860    switch (op1) {
25861    case R6_OPC_PREF:
25862        if (rt >= 24) {
25863            /* hint codes 24-31 are reserved and signal RI */
25864            generate_exception_end(ctx, EXCP_RI);
25865        }
25866        /* Treat as NOP. */
25867        break;
25868    case R6_OPC_CACHE:
25869        check_cp0_enabled(ctx);
25870        if (ctx->hflags & MIPS_HFLAG_ITC_CACHE) {
25871            gen_cache_operation(ctx, rt, rs, imm);
25872        }
25873        break;
25874    case R6_OPC_SC:
25875        gen_st_cond(ctx, op1, rt, rs, imm);
25876        break;
25877    case R6_OPC_LL:
25878        gen_ld(ctx, op1, rt, rs, imm);
25879        break;
25880    case OPC_BSHFL:
25881        {
25882            if (rd == 0) {
25883                /* Treat as NOP. */
25884                break;
25885            }
25886            op2 = MASK_BSHFL(ctx->opcode);
25887            switch (op2) {
25888            case OPC_ALIGN:
25889            case OPC_ALIGN_1:
25890            case OPC_ALIGN_2:
25891            case OPC_ALIGN_3:
25892                gen_align(ctx, 32, rd, rs, rt, sa & 3);
25893                break;
25894            case OPC_BITSWAP:
25895                gen_bitswap(ctx, op2, rd, rt);
25896                break;
25897            }
25898        }
25899        break;
25900#if defined(TARGET_MIPS64)
25901    case R6_OPC_SCD:
25902        gen_st_cond(ctx, op1, rt, rs, imm);
25903        break;
25904    case R6_OPC_LLD:
25905        gen_ld(ctx, op1, rt, rs, imm);
25906        break;
25907    case OPC_DBSHFL:
25908        check_mips_64(ctx);
25909        {
25910            if (rd == 0) {
25911                /* Treat as NOP. */
25912                break;
25913            }
25914            op2 = MASK_DBSHFL(ctx->opcode);
25915            switch (op2) {
25916            case OPC_DALIGN:
25917            case OPC_DALIGN_1:
25918            case OPC_DALIGN_2:
25919            case OPC_DALIGN_3:
25920            case OPC_DALIGN_4:
25921            case OPC_DALIGN_5:
25922            case OPC_DALIGN_6:
25923            case OPC_DALIGN_7:
25924                gen_align(ctx, 64, rd, rs, rt, sa & 7);
25925                break;
25926            case OPC_DBITSWAP:
25927                gen_bitswap(ctx, op2, rd, rt);
25928                break;
25929            }
25930
25931        }
25932        break;
25933#endif
25934    default:            /* Invalid */
25935        MIPS_INVAL("special3_r6");
25936        generate_exception_end(ctx, EXCP_RI);
25937        break;
25938    }
25939}
25940
25941static void decode_opc_special3_legacy(CPUMIPSState *env, DisasContext *ctx)
25942{
25943    int rs, rt, rd;
25944    uint32_t op1, op2;
25945
25946    rs = (ctx->opcode >> 21) & 0x1f;
25947    rt = (ctx->opcode >> 16) & 0x1f;
25948    rd = (ctx->opcode >> 11) & 0x1f;
25949
25950    op1 = MASK_SPECIAL3(ctx->opcode);
25951    switch (op1) {
25952    case OPC_DIV_G_2E:
25953    case OPC_DIVU_G_2E:
25954    case OPC_MOD_G_2E:
25955    case OPC_MODU_G_2E:
25956    case OPC_MULT_G_2E:
25957    case OPC_MULTU_G_2E:
25958        /* OPC_MULT_G_2E, OPC_ADDUH_QB_DSP, OPC_MUL_PH_DSP have
25959         * the same mask and op1. */
25960        if ((ctx->insn_flags & ASE_DSP_R2) && (op1 == OPC_MULT_G_2E)) {
25961            op2 = MASK_ADDUH_QB(ctx->opcode);
25962            switch (op2) {
25963            case OPC_ADDUH_QB:
25964            case OPC_ADDUH_R_QB:
25965            case OPC_ADDQH_PH:
25966            case OPC_ADDQH_R_PH:
25967            case OPC_ADDQH_W:
25968            case OPC_ADDQH_R_W:
25969            case OPC_SUBUH_QB:
25970            case OPC_SUBUH_R_QB:
25971            case OPC_SUBQH_PH:
25972            case OPC_SUBQH_R_PH:
25973            case OPC_SUBQH_W:
25974            case OPC_SUBQH_R_W:
25975                gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
25976                break;
25977            case OPC_MUL_PH:
25978            case OPC_MUL_S_PH:
25979            case OPC_MULQ_S_W:
25980            case OPC_MULQ_RS_W:
25981                gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 1);
25982                break;
25983            default:
25984                MIPS_INVAL("MASK ADDUH.QB");
25985                generate_exception_end(ctx, EXCP_RI);
25986                break;
25987            }
25988        } else if (ctx->insn_flags & INSN_LOONGSON2E) {
25989            gen_loongson_integer(ctx, op1, rd, rs, rt);
25990        } else {
25991            generate_exception_end(ctx, EXCP_RI);
25992        }
25993        break;
25994    case OPC_LX_DSP:
25995        op2 = MASK_LX(ctx->opcode);
25996        switch (op2) {
25997#if defined(TARGET_MIPS64)
25998        case OPC_LDX:
25999#endif
26000        case OPC_LBUX:
26001        case OPC_LHX:
26002        case OPC_LWX:
26003            gen_mipsdsp_ld(ctx, op2, rd, rs, rt);
26004            break;
26005        default:            /* Invalid */
26006            MIPS_INVAL("MASK LX");
26007            generate_exception_end(ctx, EXCP_RI);
26008            break;
26009        }
26010        break;
26011    case OPC_ABSQ_S_PH_DSP:
26012        op2 = MASK_ABSQ_S_PH(ctx->opcode);
26013        switch (op2) {
26014        case OPC_ABSQ_S_QB:
26015        case OPC_ABSQ_S_PH:
26016        case OPC_ABSQ_S_W:
26017        case OPC_PRECEQ_W_PHL:
26018        case OPC_PRECEQ_W_PHR:
26019        case OPC_PRECEQU_PH_QBL:
26020        case OPC_PRECEQU_PH_QBR:
26021        case OPC_PRECEQU_PH_QBLA:
26022        case OPC_PRECEQU_PH_QBRA:
26023        case OPC_PRECEU_PH_QBL:
26024        case OPC_PRECEU_PH_QBR:
26025        case OPC_PRECEU_PH_QBLA:
26026        case OPC_PRECEU_PH_QBRA:
26027            gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
26028            break;
26029        case OPC_BITREV:
26030        case OPC_REPL_QB:
26031        case OPC_REPLV_QB:
26032        case OPC_REPL_PH:
26033        case OPC_REPLV_PH:
26034            gen_mipsdsp_bitinsn(ctx, op1, op2, rd, rt);
26035            break;
26036        default:
26037            MIPS_INVAL("MASK ABSQ_S.PH");
26038            generate_exception_end(ctx, EXCP_RI);
26039            break;
26040        }
26041        break;
26042    case OPC_ADDU_QB_DSP:
26043        op2 = MASK_ADDU_QB(ctx->opcode);
26044        switch (op2) {
26045        case OPC_ADDQ_PH:
26046        case OPC_ADDQ_S_PH:
26047        case OPC_ADDQ_S_W:
26048        case OPC_ADDU_QB:
26049        case OPC_ADDU_S_QB:
26050        case OPC_ADDU_PH:
26051        case OPC_ADDU_S_PH:
26052        case OPC_SUBQ_PH:
26053        case OPC_SUBQ_S_PH:
26054        case OPC_SUBQ_S_W:
26055        case OPC_SUBU_QB:
26056        case OPC_SUBU_S_QB:
26057        case OPC_SUBU_PH:
26058        case OPC_SUBU_S_PH:
26059        case OPC_ADDSC:
26060        case OPC_ADDWC:
26061        case OPC_MODSUB:
26062        case OPC_RADDU_W_QB:
26063            gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
26064            break;
26065        case OPC_MULEU_S_PH_QBL:
26066        case OPC_MULEU_S_PH_QBR:
26067        case OPC_MULQ_RS_PH:
26068        case OPC_MULEQ_S_W_PHL:
26069        case OPC_MULEQ_S_W_PHR:
26070        case OPC_MULQ_S_PH:
26071            gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 1);
26072            break;
26073        default:            /* Invalid */
26074            MIPS_INVAL("MASK ADDU.QB");
26075            generate_exception_end(ctx, EXCP_RI);
26076            break;
26077
26078        }
26079        break;
26080    case OPC_CMPU_EQ_QB_DSP:
26081        op2 = MASK_CMPU_EQ_QB(ctx->opcode);
26082        switch (op2) {
26083        case OPC_PRECR_SRA_PH_W:
26084        case OPC_PRECR_SRA_R_PH_W:
26085            gen_mipsdsp_arith(ctx, op1, op2, rt, rs, rd);
26086            break;
26087        case OPC_PRECR_QB_PH:
26088        case OPC_PRECRQ_QB_PH:
26089        case OPC_PRECRQ_PH_W:
26090        case OPC_PRECRQ_RS_PH_W:
26091        case OPC_PRECRQU_S_QB_PH:
26092            gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
26093            break;
26094        case OPC_CMPU_EQ_QB:
26095        case OPC_CMPU_LT_QB:
26096        case OPC_CMPU_LE_QB:
26097        case OPC_CMP_EQ_PH:
26098        case OPC_CMP_LT_PH:
26099        case OPC_CMP_LE_PH:
26100            gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 0);
26101            break;
26102        case OPC_CMPGU_EQ_QB:
26103        case OPC_CMPGU_LT_QB:
26104        case OPC_CMPGU_LE_QB:
26105        case OPC_CMPGDU_EQ_QB:
26106        case OPC_CMPGDU_LT_QB:
26107        case OPC_CMPGDU_LE_QB:
26108        case OPC_PICK_QB:
26109        case OPC_PICK_PH:
26110        case OPC_PACKRL_PH:
26111            gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 1);
26112            break;
26113        default:            /* Invalid */
26114            MIPS_INVAL("MASK CMPU.EQ.QB");
26115            generate_exception_end(ctx, EXCP_RI);
26116            break;
26117        }
26118        break;
26119    case OPC_SHLL_QB_DSP:
26120        gen_mipsdsp_shift(ctx, op1, rd, rs, rt);
26121        break;
26122    case OPC_DPA_W_PH_DSP:
26123        op2 = MASK_DPA_W_PH(ctx->opcode);
26124        switch (op2) {
26125        case OPC_DPAU_H_QBL:
26126        case OPC_DPAU_H_QBR:
26127        case OPC_DPSU_H_QBL:
26128        case OPC_DPSU_H_QBR:
26129        case OPC_DPA_W_PH:
26130        case OPC_DPAX_W_PH:
26131        case OPC_DPAQ_S_W_PH:
26132        case OPC_DPAQX_S_W_PH:
26133        case OPC_DPAQX_SA_W_PH:
26134        case OPC_DPS_W_PH:
26135        case OPC_DPSX_W_PH:
26136        case OPC_DPSQ_S_W_PH:
26137        case OPC_DPSQX_S_W_PH:
26138        case OPC_DPSQX_SA_W_PH:
26139        case OPC_MULSAQ_S_W_PH:
26140        case OPC_DPAQ_SA_L_W:
26141        case OPC_DPSQ_SA_L_W:
26142        case OPC_MAQ_S_W_PHL:
26143        case OPC_MAQ_S_W_PHR:
26144        case OPC_MAQ_SA_W_PHL:
26145        case OPC_MAQ_SA_W_PHR:
26146        case OPC_MULSA_W_PH:
26147            gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 0);
26148            break;
26149        default:            /* Invalid */
26150            MIPS_INVAL("MASK DPAW.PH");
26151            generate_exception_end(ctx, EXCP_RI);
26152            break;
26153        }
26154        break;
26155    case OPC_INSV_DSP:
26156        op2 = MASK_INSV(ctx->opcode);
26157        switch (op2) {
26158        case OPC_INSV:
26159            check_dsp(ctx);
26160            {
26161                TCGv t0, t1;
26162
26163                if (rt == 0) {
26164                    break;
26165                }
26166
26167                t0 = tcg_temp_new();
26168                t1 = tcg_temp_new();
26169
26170                gen_load_gpr(t0, rt);
26171                gen_load_gpr(t1, rs);
26172
26173                gen_helper_insv(cpu_gpr[rt], cpu_env, t1, t0);
26174
26175                tcg_temp_free(t0);
26176                tcg_temp_free(t1);
26177                break;
26178            }
26179        default:            /* Invalid */
26180            MIPS_INVAL("MASK INSV");
26181            generate_exception_end(ctx, EXCP_RI);
26182            break;
26183        }
26184        break;
26185    case OPC_APPEND_DSP:
26186        gen_mipsdsp_append(env, ctx, op1, rt, rs, rd);
26187        break;
26188    case OPC_EXTR_W_DSP:
26189        op2 = MASK_EXTR_W(ctx->opcode);
26190        switch (op2) {
26191        case OPC_EXTR_W:
26192        case OPC_EXTR_R_W:
26193        case OPC_EXTR_RS_W:
26194        case OPC_EXTR_S_H:
26195        case OPC_EXTRV_S_H:
26196        case OPC_EXTRV_W:
26197        case OPC_EXTRV_R_W:
26198        case OPC_EXTRV_RS_W:
26199        case OPC_EXTP:
26200        case OPC_EXTPV:
26201        case OPC_EXTPDP:
26202        case OPC_EXTPDPV:
26203            gen_mipsdsp_accinsn(ctx, op1, op2, rt, rs, rd, 1);
26204            break;
26205        case OPC_RDDSP:
26206            gen_mipsdsp_accinsn(ctx, op1, op2, rd, rs, rt, 1);
26207            break;
26208        case OPC_SHILO:
26209        case OPC_SHILOV:
26210        case OPC_MTHLIP:
26211        case OPC_WRDSP:
26212            gen_mipsdsp_accinsn(ctx, op1, op2, rd, rs, rt, 0);
26213            break;
26214        default:            /* Invalid */
26215            MIPS_INVAL("MASK EXTR.W");
26216            generate_exception_end(ctx, EXCP_RI);
26217            break;
26218        }
26219        break;
26220#if defined(TARGET_MIPS64)
26221    case OPC_DDIV_G_2E:
26222    case OPC_DDIVU_G_2E:
26223    case OPC_DMULT_G_2E:
26224    case OPC_DMULTU_G_2E:
26225    case OPC_DMOD_G_2E:
26226    case OPC_DMODU_G_2E:
26227        check_insn(ctx, INSN_LOONGSON2E);
26228        gen_loongson_integer(ctx, op1, rd, rs, rt);
26229        break;
26230    case OPC_ABSQ_S_QH_DSP:
26231        op2 = MASK_ABSQ_S_QH(ctx->opcode);
26232        switch (op2) {
26233        case OPC_PRECEQ_L_PWL:
26234        case OPC_PRECEQ_L_PWR:
26235        case OPC_PRECEQ_PW_QHL:
26236        case OPC_PRECEQ_PW_QHR:
26237        case OPC_PRECEQ_PW_QHLA:
26238        case OPC_PRECEQ_PW_QHRA:
26239        case OPC_PRECEQU_QH_OBL:
26240        case OPC_PRECEQU_QH_OBR:
26241        case OPC_PRECEQU_QH_OBLA:
26242        case OPC_PRECEQU_QH_OBRA:
26243        case OPC_PRECEU_QH_OBL:
26244        case OPC_PRECEU_QH_OBR:
26245        case OPC_PRECEU_QH_OBLA:
26246        case OPC_PRECEU_QH_OBRA:
26247        case OPC_ABSQ_S_OB:
26248        case OPC_ABSQ_S_PW:
26249        case OPC_ABSQ_S_QH:
26250            gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
26251            break;
26252        case OPC_REPL_OB:
26253        case OPC_REPL_PW:
26254        case OPC_REPL_QH:
26255        case OPC_REPLV_OB:
26256        case OPC_REPLV_PW:
26257        case OPC_REPLV_QH:
26258            gen_mipsdsp_bitinsn(ctx, op1, op2, rd, rt);
26259            break;
26260        default:            /* Invalid */
26261            MIPS_INVAL("MASK ABSQ_S.QH");
26262            generate_exception_end(ctx, EXCP_RI);
26263            break;
26264        }
26265        break;
26266    case OPC_ADDU_OB_DSP:
26267        op2 = MASK_ADDU_OB(ctx->opcode);
26268        switch (op2) {
26269        case OPC_RADDU_L_OB:
26270        case OPC_SUBQ_PW:
26271        case OPC_SUBQ_S_PW:
26272        case OPC_SUBQ_QH:
26273        case OPC_SUBQ_S_QH:
26274        case OPC_SUBU_OB:
26275        case OPC_SUBU_S_OB:
26276        case OPC_SUBU_QH:
26277        case OPC_SUBU_S_QH:
26278        case OPC_SUBUH_OB:
26279        case OPC_SUBUH_R_OB:
26280        case OPC_ADDQ_PW:
26281        case OPC_ADDQ_S_PW:
26282        case OPC_ADDQ_QH:
26283        case OPC_ADDQ_S_QH:
26284        case OPC_ADDU_OB:
26285        case OPC_ADDU_S_OB:
26286        case OPC_ADDU_QH:
26287        case OPC_ADDU_S_QH:
26288        case OPC_ADDUH_OB:
26289        case OPC_ADDUH_R_OB:
26290            gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
26291            break;
26292        case OPC_MULEQ_S_PW_QHL:
26293        case OPC_MULEQ_S_PW_QHR:
26294        case OPC_MULEU_S_QH_OBL:
26295        case OPC_MULEU_S_QH_OBR:
26296        case OPC_MULQ_RS_QH:
26297            gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 1);
26298            break;
26299        default:            /* Invalid */
26300            MIPS_INVAL("MASK ADDU.OB");
26301            generate_exception_end(ctx, EXCP_RI);
26302            break;
26303        }
26304        break;
26305    case OPC_CMPU_EQ_OB_DSP:
26306        op2 = MASK_CMPU_EQ_OB(ctx->opcode);
26307        switch (op2) {
26308        case OPC_PRECR_SRA_QH_PW:
26309        case OPC_PRECR_SRA_R_QH_PW:
26310            /* Return value is rt. */
26311            gen_mipsdsp_arith(ctx, op1, op2, rt, rs, rd);
26312            break;
26313        case OPC_PRECR_OB_QH:
26314        case OPC_PRECRQ_OB_QH:
26315        case OPC_PRECRQ_PW_L:
26316        case OPC_PRECRQ_QH_PW:
26317        case OPC_PRECRQ_RS_QH_PW:
26318        case OPC_PRECRQU_S_OB_QH:
26319            gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
26320            break;
26321        case OPC_CMPU_EQ_OB:
26322        case OPC_CMPU_LT_OB:
26323        case OPC_CMPU_LE_OB:
26324        case OPC_CMP_EQ_QH:
26325        case OPC_CMP_LT_QH:
26326        case OPC_CMP_LE_QH:
26327        case OPC_CMP_EQ_PW:
26328        case OPC_CMP_LT_PW:
26329        case OPC_CMP_LE_PW:
26330            gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 0);
26331            break;
26332        case OPC_CMPGDU_EQ_OB:
26333        case OPC_CMPGDU_LT_OB:
26334        case OPC_CMPGDU_LE_OB:
26335        case OPC_CMPGU_EQ_OB:
26336        case OPC_CMPGU_LT_OB:
26337        case OPC_CMPGU_LE_OB:
26338        case OPC_PACKRL_PW:
26339        case OPC_PICK_OB:
26340        case OPC_PICK_PW:
26341        case OPC_PICK_QH:
26342            gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 1);
26343            break;
26344        default:            /* Invalid */
26345            MIPS_INVAL("MASK CMPU_EQ.OB");
26346            generate_exception_end(ctx, EXCP_RI);
26347            break;
26348        }
26349        break;
26350    case OPC_DAPPEND_DSP:
26351        gen_mipsdsp_append(env, ctx, op1, rt, rs, rd);
26352        break;
26353    case OPC_DEXTR_W_DSP:
26354        op2 = MASK_DEXTR_W(ctx->opcode);
26355        switch (op2) {
26356        case OPC_DEXTP:
26357        case OPC_DEXTPDP:
26358        case OPC_DEXTPDPV:
26359        case OPC_DEXTPV:
26360        case OPC_DEXTR_L:
26361        case OPC_DEXTR_R_L:
26362        case OPC_DEXTR_RS_L:
26363        case OPC_DEXTR_W:
26364        case OPC_DEXTR_R_W:
26365        case OPC_DEXTR_RS_W:
26366        case OPC_DEXTR_S_H:
26367        case OPC_DEXTRV_L:
26368        case OPC_DEXTRV_R_L:
26369        case OPC_DEXTRV_RS_L:
26370        case OPC_DEXTRV_S_H:
26371        case OPC_DEXTRV_W:
26372        case OPC_DEXTRV_R_W:
26373        case OPC_DEXTRV_RS_W:
26374            gen_mipsdsp_accinsn(ctx, op1, op2, rt, rs, rd, 1);
26375            break;
26376        case OPC_DMTHLIP:
26377        case OPC_DSHILO:
26378        case OPC_DSHILOV:
26379            gen_mipsdsp_accinsn(ctx, op1, op2, rd, rs, rt, 0);
26380            break;
26381        default:            /* Invalid */
26382            MIPS_INVAL("MASK EXTR.W");
26383            generate_exception_end(ctx, EXCP_RI);
26384            break;
26385        }
26386        break;
26387    case OPC_DPAQ_W_QH_DSP:
26388        op2 = MASK_DPAQ_W_QH(ctx->opcode);
26389        switch (op2) {
26390        case OPC_DPAU_H_OBL:
26391        case OPC_DPAU_H_OBR:
26392        case OPC_DPSU_H_OBL:
26393        case OPC_DPSU_H_OBR:
26394        case OPC_DPA_W_QH:
26395        case OPC_DPAQ_S_W_QH:
26396        case OPC_DPS_W_QH:
26397        case OPC_DPSQ_S_W_QH:
26398        case OPC_MULSAQ_S_W_QH:
26399        case OPC_DPAQ_SA_L_PW:
26400        case OPC_DPSQ_SA_L_PW:
26401        case OPC_MULSAQ_S_L_PW:
26402            gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 0);
26403            break;
26404        case OPC_MAQ_S_W_QHLL:
26405        case OPC_MAQ_S_W_QHLR:
26406        case OPC_MAQ_S_W_QHRL:
26407        case OPC_MAQ_S_W_QHRR:
26408        case OPC_MAQ_SA_W_QHLL:
26409        case OPC_MAQ_SA_W_QHLR:
26410        case OPC_MAQ_SA_W_QHRL:
26411        case OPC_MAQ_SA_W_QHRR:
26412        case OPC_MAQ_S_L_PWL:
26413        case OPC_MAQ_S_L_PWR:
26414        case OPC_DMADD:
26415        case OPC_DMADDU:
26416        case OPC_DMSUB:
26417        case OPC_DMSUBU:
26418            gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 0);
26419            break;
26420        default:            /* Invalid */
26421            MIPS_INVAL("MASK DPAQ.W.QH");
26422            generate_exception_end(ctx, EXCP_RI);
26423            break;
26424        }
26425        break;
26426    case OPC_DINSV_DSP:
26427        op2 = MASK_INSV(ctx->opcode);
26428        switch (op2) {
26429        case OPC_DINSV:
26430        {
26431            TCGv t0, t1;
26432
26433            if (rt == 0) {
26434                break;
26435            }
26436            check_dsp(ctx);
26437
26438            t0 = tcg_temp_new();
26439            t1 = tcg_temp_new();
26440
26441            gen_load_gpr(t0, rt);
26442            gen_load_gpr(t1, rs);
26443
26444            gen_helper_dinsv(cpu_gpr[rt], cpu_env, t1, t0);
26445
26446            tcg_temp_free(t0);
26447            tcg_temp_free(t1);
26448            break;
26449        }
26450        default:            /* Invalid */
26451            MIPS_INVAL("MASK DINSV");
26452            generate_exception_end(ctx, EXCP_RI);
26453            break;
26454        }
26455        break;
26456    case OPC_SHLL_OB_DSP:
26457        gen_mipsdsp_shift(ctx, op1, rd, rs, rt);
26458        break;
26459#endif
26460    default:            /* Invalid */
26461        MIPS_INVAL("special3_legacy");
26462        generate_exception_end(ctx, EXCP_RI);
26463        break;
26464    }
26465}
26466
26467static void decode_mmi0(CPUMIPSState *env, DisasContext *ctx)
26468{
26469    uint32_t opc = MASK_MMI0(ctx->opcode);
26470
26471    switch (opc) {
26472    case MMI_OPC_0_PADDW:     /* TODO: MMI_OPC_0_PADDW */
26473    case MMI_OPC_0_PSUBW:     /* TODO: MMI_OPC_0_PSUBW */
26474    case MMI_OPC_0_PCGTW:     /* TODO: MMI_OPC_0_PCGTW */
26475    case MMI_OPC_0_PMAXW:     /* TODO: MMI_OPC_0_PMAXW */
26476    case MMI_OPC_0_PADDH:     /* TODO: MMI_OPC_0_PADDH */
26477    case MMI_OPC_0_PSUBH:     /* TODO: MMI_OPC_0_PSUBH */
26478    case MMI_OPC_0_PCGTH:     /* TODO: MMI_OPC_0_PCGTH */
26479    case MMI_OPC_0_PMAXH:     /* TODO: MMI_OPC_0_PMAXH */
26480    case MMI_OPC_0_PADDB:     /* TODO: MMI_OPC_0_PADDB */
26481    case MMI_OPC_0_PSUBB:     /* TODO: MMI_OPC_0_PSUBB */
26482    case MMI_OPC_0_PCGTB:     /* TODO: MMI_OPC_0_PCGTB */
26483    case MMI_OPC_0_PADDSW:    /* TODO: MMI_OPC_0_PADDSW */
26484    case MMI_OPC_0_PSUBSW:    /* TODO: MMI_OPC_0_PSUBSW */
26485    case MMI_OPC_0_PEXTLW:    /* TODO: MMI_OPC_0_PEXTLW */
26486    case MMI_OPC_0_PPACW:     /* TODO: MMI_OPC_0_PPACW */
26487    case MMI_OPC_0_PADDSH:    /* TODO: MMI_OPC_0_PADDSH */
26488    case MMI_OPC_0_PSUBSH:    /* TODO: MMI_OPC_0_PSUBSH */
26489    case MMI_OPC_0_PEXTLH:    /* TODO: MMI_OPC_0_PEXTLH */
26490    case MMI_OPC_0_PPACH:     /* TODO: MMI_OPC_0_PPACH */
26491    case MMI_OPC_0_PADDSB:    /* TODO: MMI_OPC_0_PADDSB */
26492    case MMI_OPC_0_PSUBSB:    /* TODO: MMI_OPC_0_PSUBSB */
26493    case MMI_OPC_0_PEXTLB:    /* TODO: MMI_OPC_0_PEXTLB */
26494    case MMI_OPC_0_PPACB:     /* TODO: MMI_OPC_0_PPACB */
26495    case MMI_OPC_0_PEXT5:     /* TODO: MMI_OPC_0_PEXT5 */
26496    case MMI_OPC_0_PPAC5:     /* TODO: MMI_OPC_0_PPAC5 */
26497        generate_exception_end(ctx, EXCP_RI); /* TODO: MMI_OPC_CLASS_MMI0 */
26498        break;
26499    default:
26500        MIPS_INVAL("TX79 MMI class MMI0");
26501        generate_exception_end(ctx, EXCP_RI);
26502        break;
26503    }
26504}
26505
26506static void decode_mmi1(CPUMIPSState *env, DisasContext *ctx)
26507{
26508    uint32_t opc = MASK_MMI1(ctx->opcode);
26509
26510    switch (opc) {
26511    case MMI_OPC_1_PABSW:     /* TODO: MMI_OPC_1_PABSW */
26512    case MMI_OPC_1_PCEQW:     /* TODO: MMI_OPC_1_PCEQW */
26513    case MMI_OPC_1_PMINW:     /* TODO: MMI_OPC_1_PMINW */
26514    case MMI_OPC_1_PADSBH:    /* TODO: MMI_OPC_1_PADSBH */
26515    case MMI_OPC_1_PABSH:     /* TODO: MMI_OPC_1_PABSH */
26516    case MMI_OPC_1_PCEQH:     /* TODO: MMI_OPC_1_PCEQH */
26517    case MMI_OPC_1_PMINH:     /* TODO: MMI_OPC_1_PMINH */
26518    case MMI_OPC_1_PCEQB:     /* TODO: MMI_OPC_1_PCEQB */
26519    case MMI_OPC_1_PADDUW:    /* TODO: MMI_OPC_1_PADDUW */
26520    case MMI_OPC_1_PSUBUW:    /* TODO: MMI_OPC_1_PSUBUW */
26521    case MMI_OPC_1_PEXTUW:    /* TODO: MMI_OPC_1_PEXTUW */
26522    case MMI_OPC_1_PADDUH:    /* TODO: MMI_OPC_1_PADDUH */
26523    case MMI_OPC_1_PSUBUH:    /* TODO: MMI_OPC_1_PSUBUH */
26524    case MMI_OPC_1_PEXTUH:    /* TODO: MMI_OPC_1_PEXTUH */
26525    case MMI_OPC_1_PADDUB:    /* TODO: MMI_OPC_1_PADDUB */
26526    case MMI_OPC_1_PSUBUB:    /* TODO: MMI_OPC_1_PSUBUB */
26527    case MMI_OPC_1_PEXTUB:    /* TODO: MMI_OPC_1_PEXTUB */
26528    case MMI_OPC_1_QFSRV:     /* TODO: MMI_OPC_1_QFSRV */
26529        generate_exception_end(ctx, EXCP_RI); /* TODO: MMI_OPC_CLASS_MMI1 */
26530        break;
26531    default:
26532        MIPS_INVAL("TX79 MMI class MMI1");
26533        generate_exception_end(ctx, EXCP_RI);
26534        break;
26535    }
26536}
26537
26538static void decode_mmi2(CPUMIPSState *env, DisasContext *ctx)
26539{
26540    uint32_t opc = MASK_MMI2(ctx->opcode);
26541
26542    switch (opc) {
26543    case MMI_OPC_2_PMADDW:    /* TODO: MMI_OPC_2_PMADDW */
26544    case MMI_OPC_2_PSLLVW:    /* TODO: MMI_OPC_2_PSLLVW */
26545    case MMI_OPC_2_PSRLVW:    /* TODO: MMI_OPC_2_PSRLVW */
26546    case MMI_OPC_2_PMSUBW:    /* TODO: MMI_OPC_2_PMSUBW */
26547    case MMI_OPC_2_PMFHI:     /* TODO: MMI_OPC_2_PMFHI */
26548    case MMI_OPC_2_PMFLO:     /* TODO: MMI_OPC_2_PMFLO */
26549    case MMI_OPC_2_PINTH:     /* TODO: MMI_OPC_2_PINTH */
26550    case MMI_OPC_2_PMULTW:    /* TODO: MMI_OPC_2_PMULTW */
26551    case MMI_OPC_2_PDIVW:     /* TODO: MMI_OPC_2_PDIVW */
26552    case MMI_OPC_2_PCPYLD:    /* TODO: MMI_OPC_2_PCPYLD */
26553    case MMI_OPC_2_PMADDH:    /* TODO: MMI_OPC_2_PMADDH */
26554    case MMI_OPC_2_PHMADH:    /* TODO: MMI_OPC_2_PHMADH */
26555    case MMI_OPC_2_PAND:      /* TODO: MMI_OPC_2_PAND */
26556    case MMI_OPC_2_PXOR:      /* TODO: MMI_OPC_2_PXOR */
26557    case MMI_OPC_2_PMSUBH:    /* TODO: MMI_OPC_2_PMSUBH */
26558    case MMI_OPC_2_PHMSBH:    /* TODO: MMI_OPC_2_PHMSBH */
26559    case MMI_OPC_2_PEXEH:     /* TODO: MMI_OPC_2_PEXEH */
26560    case MMI_OPC_2_PREVH:     /* TODO: MMI_OPC_2_PREVH */
26561    case MMI_OPC_2_PMULTH:    /* TODO: MMI_OPC_2_PMULTH */
26562    case MMI_OPC_2_PDIVBW:    /* TODO: MMI_OPC_2_PDIVBW */
26563    case MMI_OPC_2_PEXEW:     /* TODO: MMI_OPC_2_PEXEW */
26564    case MMI_OPC_2_PROT3W:    /* TODO: MMI_OPC_2_PROT3W */
26565        generate_exception_end(ctx, EXCP_RI); /* TODO: MMI_OPC_CLASS_MMI2 */
26566        break;
26567    default:
26568        MIPS_INVAL("TX79 MMI class MMI2");
26569        generate_exception_end(ctx, EXCP_RI);
26570        break;
26571    }
26572}
26573
26574static void decode_mmi3(CPUMIPSState *env, DisasContext *ctx)
26575{
26576    uint32_t opc = MASK_MMI3(ctx->opcode);
26577
26578    switch (opc) {
26579    case MMI_OPC_3_PMADDUW:    /* TODO: MMI_OPC_3_PMADDUW */
26580    case MMI_OPC_3_PSRAVW:     /* TODO: MMI_OPC_3_PSRAVW */
26581    case MMI_OPC_3_PMTHI:      /* TODO: MMI_OPC_3_PMTHI */
26582    case MMI_OPC_3_PMTLO:      /* TODO: MMI_OPC_3_PMTLO */
26583    case MMI_OPC_3_PINTEH:     /* TODO: MMI_OPC_3_PINTEH */
26584    case MMI_OPC_3_PMULTUW:    /* TODO: MMI_OPC_3_PMULTUW */
26585    case MMI_OPC_3_PDIVUW:     /* TODO: MMI_OPC_3_PDIVUW */
26586    case MMI_OPC_3_PCPYUD:     /* TODO: MMI_OPC_3_PCPYUD */
26587    case MMI_OPC_3_POR:        /* TODO: MMI_OPC_3_POR */
26588    case MMI_OPC_3_PNOR:       /* TODO: MMI_OPC_3_PNOR */
26589    case MMI_OPC_3_PEXCH:      /* TODO: MMI_OPC_3_PEXCH */
26590    case MMI_OPC_3_PCPYH:      /* TODO: MMI_OPC_3_PCPYH */
26591    case MMI_OPC_3_PEXCW:      /* TODO: MMI_OPC_3_PEXCW */
26592        generate_exception_end(ctx, EXCP_RI); /* TODO: MMI_OPC_CLASS_MMI3 */
26593        break;
26594    default:
26595        MIPS_INVAL("TX79 MMI class MMI3");
26596        generate_exception_end(ctx, EXCP_RI);
26597        break;
26598    }
26599}
26600
26601static void decode_mmi(CPUMIPSState *env, DisasContext *ctx)
26602{
26603    uint32_t opc = MASK_MMI(ctx->opcode);
26604    int rs = extract32(ctx->opcode, 21, 5);
26605    int rt = extract32(ctx->opcode, 16, 5);
26606    int rd = extract32(ctx->opcode, 11, 5);
26607
26608    switch (opc) {
26609    case MMI_OPC_CLASS_MMI0:
26610        decode_mmi0(env, ctx);
26611        break;
26612    case MMI_OPC_CLASS_MMI1:
26613        decode_mmi1(env, ctx);
26614        break;
26615    case MMI_OPC_CLASS_MMI2:
26616        decode_mmi2(env, ctx);
26617        break;
26618    case MMI_OPC_CLASS_MMI3:
26619        decode_mmi3(env, ctx);
26620        break;
26621    case MMI_OPC_MULT1:
26622    case MMI_OPC_MULTU1:
26623        gen_mul_txx9(ctx, opc, rd, rs, rt);
26624        break;
26625    case MMI_OPC_DIV1:
26626    case MMI_OPC_DIVU1:
26627        gen_div1_tx79(ctx, opc, rs, rt);
26628        break;
26629    case MMI_OPC_MTLO1:
26630    case MMI_OPC_MTHI1:
26631        gen_HILO1_tx79(ctx, opc, rs);
26632        break;
26633    case MMI_OPC_MFLO1:
26634    case MMI_OPC_MFHI1:
26635        gen_HILO1_tx79(ctx, opc, rd);
26636        break;
26637    case MMI_OPC_MADD:          /* TODO: MMI_OPC_MADD */
26638    case MMI_OPC_MADDU:         /* TODO: MMI_OPC_MADDU */
26639    case MMI_OPC_PLZCW:         /* TODO: MMI_OPC_PLZCW */
26640    case MMI_OPC_MADD1:         /* TODO: MMI_OPC_MADD1 */
26641    case MMI_OPC_MADDU1:        /* TODO: MMI_OPC_MADDU1 */
26642    case MMI_OPC_PMFHL:         /* TODO: MMI_OPC_PMFHL */
26643    case MMI_OPC_PMTHL:         /* TODO: MMI_OPC_PMTHL */
26644    case MMI_OPC_PSLLH:         /* TODO: MMI_OPC_PSLLH */
26645    case MMI_OPC_PSRLH:         /* TODO: MMI_OPC_PSRLH */
26646    case MMI_OPC_PSRAH:         /* TODO: MMI_OPC_PSRAH */
26647    case MMI_OPC_PSLLW:         /* TODO: MMI_OPC_PSLLW */
26648    case MMI_OPC_PSRLW:         /* TODO: MMI_OPC_PSRLW */
26649    case MMI_OPC_PSRAW:         /* TODO: MMI_OPC_PSRAW */
26650        generate_exception_end(ctx, EXCP_RI);    /* TODO: MMI_OPC_CLASS_MMI */
26651        break;
26652    default:
26653        MIPS_INVAL("TX79 MMI class");
26654        generate_exception_end(ctx, EXCP_RI);
26655        break;
26656    }
26657}
26658
26659static void gen_mmi_lq(CPUMIPSState *env, DisasContext *ctx)
26660{
26661    generate_exception_end(ctx, EXCP_RI);    /* TODO: MMI_OPC_LQ */
26662}
26663
26664static void gen_mmi_sq(DisasContext *ctx, int base, int rt, int offset)
26665{
26666    generate_exception_end(ctx, EXCP_RI);    /* TODO: MMI_OPC_SQ */
26667}
26668
26669/*
26670 * The TX79-specific instruction Store Quadword
26671 *
26672 * +--------+-------+-------+------------------------+
26673 * | 011111 |  base |   rt  |           offset       | SQ
26674 * +--------+-------+-------+------------------------+
26675 *      6       5       5                 16
26676 *
26677 * has the same opcode as the Read Hardware Register instruction
26678 *
26679 * +--------+-------+-------+-------+-------+--------+
26680 * | 011111 | 00000 |   rt  |   rd  | 00000 | 111011 | RDHWR
26681 * +--------+-------+-------+-------+-------+--------+
26682 *      6       5       5       5       5        6
26683 *
26684 * that is required, trapped and emulated by the Linux kernel. However, all
26685 * RDHWR encodings yield address error exceptions on the TX79 since the SQ
26686 * offset is odd. Therefore all valid SQ instructions can execute normally.
26687 * In user mode, QEMU must verify the upper and lower 11 bits to distinguish
26688 * between SQ and RDHWR, as the Linux kernel does.
26689 */
26690static void decode_mmi_sq(CPUMIPSState *env, DisasContext *ctx)
26691{
26692    int base = extract32(ctx->opcode, 21, 5);
26693    int rt = extract32(ctx->opcode, 16, 5);
26694    int offset = extract32(ctx->opcode, 0, 16);
26695
26696#ifdef CONFIG_USER_ONLY
26697    uint32_t op1 = MASK_SPECIAL3(ctx->opcode);
26698    uint32_t op2 = extract32(ctx->opcode, 6, 5);
26699
26700    if (base == 0 && op2 == 0 && op1 == OPC_RDHWR) {
26701        int rd = extract32(ctx->opcode, 11, 5);
26702
26703        gen_rdhwr(ctx, rt, rd, 0);
26704        return;
26705    }
26706#endif
26707
26708    gen_mmi_sq(ctx, base, rt, offset);
26709}
26710
26711static void decode_opc_special3(CPUMIPSState *env, DisasContext *ctx)
26712{
26713    int rs, rt, rd, sa;
26714    uint32_t op1, op2;
26715    int16_t imm;
26716
26717    rs = (ctx->opcode >> 21) & 0x1f;
26718    rt = (ctx->opcode >> 16) & 0x1f;
26719    rd = (ctx->opcode >> 11) & 0x1f;
26720    sa = (ctx->opcode >> 6) & 0x1f;
26721    imm = sextract32(ctx->opcode, 7, 9);
26722
26723    op1 = MASK_SPECIAL3(ctx->opcode);
26724
26725    /*
26726     * EVA loads and stores overlap Loongson 2E instructions decoded by
26727     * decode_opc_special3_legacy(), so be careful to allow their decoding when
26728     * EVA is absent.
26729     */
26730    if (ctx->eva) {
26731        switch (op1) {
26732        case OPC_LWLE:
26733        case OPC_LWRE:
26734            check_insn_opc_removed(ctx, ISA_MIPS32R6);
26735            /* fall through */
26736        case OPC_LBUE:
26737        case OPC_LHUE:
26738        case OPC_LBE:
26739        case OPC_LHE:
26740        case OPC_LLE:
26741        case OPC_LWE:
26742            check_cp0_enabled(ctx);
26743            gen_ld(ctx, op1, rt, rs, imm);
26744            return;
26745        case OPC_SWLE:
26746        case OPC_SWRE:
26747            check_insn_opc_removed(ctx, ISA_MIPS32R6);
26748            /* fall through */
26749        case OPC_SBE:
26750        case OPC_SHE:
26751        case OPC_SWE:
26752            check_cp0_enabled(ctx);
26753            gen_st(ctx, op1, rt, rs, imm);
26754            return;
26755        case OPC_SCE:
26756            check_cp0_enabled(ctx);
26757            gen_st_cond(ctx, op1, rt, rs, imm);
26758            return;
26759        case OPC_CACHEE:
26760            check_cp0_enabled(ctx);
26761            if (ctx->hflags & MIPS_HFLAG_ITC_CACHE) {
26762                gen_cache_operation(ctx, rt, rs, imm);
26763            }
26764            /* Treat as NOP. */
26765            return;
26766        case OPC_PREFE:
26767            check_cp0_enabled(ctx);
26768            /* Treat as NOP. */
26769            return;
26770        }
26771    }
26772
26773    switch (op1) {
26774    case OPC_EXT:
26775    case OPC_INS:
26776        check_insn(ctx, ISA_MIPS32R2);
26777        gen_bitops(ctx, op1, rt, rs, sa, rd);
26778        break;
26779    case OPC_BSHFL:
26780        op2 = MASK_BSHFL(ctx->opcode);
26781        switch (op2) {
26782        case OPC_ALIGN:
26783        case OPC_ALIGN_1:
26784        case OPC_ALIGN_2:
26785        case OPC_ALIGN_3:
26786        case OPC_BITSWAP:
26787            check_insn(ctx, ISA_MIPS32R6);
26788            decode_opc_special3_r6(env, ctx);
26789            break;
26790        default:
26791            check_insn(ctx, ISA_MIPS32R2);
26792            gen_bshfl(ctx, op2, rt, rd);
26793            break;
26794        }
26795        break;
26796#if defined(TARGET_MIPS64)
26797    case OPC_DEXTM:
26798    case OPC_DEXTU:
26799    case OPC_DEXT:
26800    case OPC_DINSM:
26801    case OPC_DINSU:
26802    case OPC_DINS:
26803        check_insn(ctx, ISA_MIPS64R2);
26804        check_mips_64(ctx);
26805        gen_bitops(ctx, op1, rt, rs, sa, rd);
26806        break;
26807    case OPC_DBSHFL:
26808        op2 = MASK_DBSHFL(ctx->opcode);
26809        switch (op2) {
26810        case OPC_DALIGN:
26811        case OPC_DALIGN_1:
26812        case OPC_DALIGN_2:
26813        case OPC_DALIGN_3:
26814        case OPC_DALIGN_4:
26815        case OPC_DALIGN_5:
26816        case OPC_DALIGN_6:
26817        case OPC_DALIGN_7:
26818        case OPC_DBITSWAP:
26819            check_insn(ctx, ISA_MIPS32R6);
26820            decode_opc_special3_r6(env, ctx);
26821            break;
26822        default:
26823            check_insn(ctx, ISA_MIPS64R2);
26824            check_mips_64(ctx);
26825            op2 = MASK_DBSHFL(ctx->opcode);
26826            gen_bshfl(ctx, op2, rt, rd);
26827            break;
26828        }
26829        break;
26830#endif
26831    case OPC_RDHWR:
26832        gen_rdhwr(ctx, rt, rd, extract32(ctx->opcode, 6, 3));
26833        break;
26834    case OPC_FORK:
26835        check_mt(ctx);
26836        {
26837            TCGv t0 = tcg_temp_new();
26838            TCGv t1 = tcg_temp_new();
26839
26840            gen_load_gpr(t0, rt);
26841            gen_load_gpr(t1, rs);
26842            gen_helper_fork(t0, t1);
26843            tcg_temp_free(t0);
26844            tcg_temp_free(t1);
26845        }
26846        break;
26847    case OPC_YIELD:
26848        check_mt(ctx);
26849        {
26850            TCGv t0 = tcg_temp_new();
26851
26852            gen_load_gpr(t0, rs);
26853            gen_helper_yield(t0, cpu_env, t0);
26854            gen_store_gpr(t0, rd);
26855            tcg_temp_free(t0);
26856        }
26857        break;
26858    default:
26859        if (ctx->insn_flags & ISA_MIPS32R6) {
26860            decode_opc_special3_r6(env, ctx);
26861        } else {
26862            decode_opc_special3_legacy(env, ctx);
26863        }
26864    }
26865}
26866
26867/* MIPS SIMD Architecture (MSA)  */
26868static inline int check_msa_access(DisasContext *ctx)
26869{
26870    if (unlikely((ctx->hflags & MIPS_HFLAG_FPU) &&
26871                 !(ctx->hflags & MIPS_HFLAG_F64))) {
26872        generate_exception_end(ctx, EXCP_RI);
26873        return 0;
26874    }
26875
26876    if (unlikely(!(ctx->hflags & MIPS_HFLAG_MSA))) {
26877        if (ctx->insn_flags & ASE_MSA) {
26878            generate_exception_end(ctx, EXCP_MSADIS);
26879            return 0;
26880        } else {
26881            generate_exception_end(ctx, EXCP_RI);
26882            return 0;
26883        }
26884    }
26885    return 1;
26886}
26887
26888static void gen_check_zero_element(TCGv tresult, uint8_t df, uint8_t wt)
26889{
26890    /* generates tcg ops to check if any element is 0 */
26891    /* Note this function only works with MSA_WRLEN = 128 */
26892    uint64_t eval_zero_or_big = 0;
26893    uint64_t eval_big = 0;
26894    TCGv_i64 t0 = tcg_temp_new_i64();
26895    TCGv_i64 t1 = tcg_temp_new_i64();
26896    switch (df) {
26897    case DF_BYTE:
26898        eval_zero_or_big = 0x0101010101010101ULL;
26899        eval_big = 0x8080808080808080ULL;
26900        break;
26901    case DF_HALF:
26902        eval_zero_or_big = 0x0001000100010001ULL;
26903        eval_big = 0x8000800080008000ULL;
26904        break;
26905    case DF_WORD:
26906        eval_zero_or_big = 0x0000000100000001ULL;
26907        eval_big = 0x8000000080000000ULL;
26908        break;
26909    case DF_DOUBLE:
26910        eval_zero_or_big = 0x0000000000000001ULL;
26911        eval_big = 0x8000000000000000ULL;
26912        break;
26913    }
26914    tcg_gen_subi_i64(t0, msa_wr_d[wt<<1], eval_zero_or_big);
26915    tcg_gen_andc_i64(t0, t0, msa_wr_d[wt<<1]);
26916    tcg_gen_andi_i64(t0, t0, eval_big);
26917    tcg_gen_subi_i64(t1, msa_wr_d[(wt<<1)+1], eval_zero_or_big);
26918    tcg_gen_andc_i64(t1, t1, msa_wr_d[(wt<<1)+1]);
26919    tcg_gen_andi_i64(t1, t1, eval_big);
26920    tcg_gen_or_i64(t0, t0, t1);
26921    /* if all bits are zero then all elements are not zero */
26922    /* if some bit is non-zero then some element is zero */
26923    tcg_gen_setcondi_i64(TCG_COND_NE, t0, t0, 0);
26924    tcg_gen_trunc_i64_tl(tresult, t0);
26925    tcg_temp_free_i64(t0);
26926    tcg_temp_free_i64(t1);
26927}
26928
26929static void gen_msa_branch(CPUMIPSState *env, DisasContext *ctx, uint32_t op1)
26930{
26931    uint8_t df = (ctx->opcode >> 21) & 0x3;
26932    uint8_t wt = (ctx->opcode >> 16) & 0x1f;
26933    int64_t s16 = (int16_t)ctx->opcode;
26934
26935    check_msa_access(ctx);
26936
26937    if (ctx->hflags & MIPS_HFLAG_BMASK) {
26938        generate_exception_end(ctx, EXCP_RI);
26939        return;
26940    }
26941    switch (op1) {
26942    case OPC_BZ_V:
26943    case OPC_BNZ_V:
26944        {
26945            TCGv_i64 t0 = tcg_temp_new_i64();
26946            tcg_gen_or_i64(t0, msa_wr_d[wt<<1], msa_wr_d[(wt<<1)+1]);
26947            tcg_gen_setcondi_i64((op1 == OPC_BZ_V) ?
26948                    TCG_COND_EQ : TCG_COND_NE, t0, t0, 0);
26949            tcg_gen_trunc_i64_tl(bcond, t0);
26950            tcg_temp_free_i64(t0);
26951        }
26952        break;
26953    case OPC_BZ_B:
26954    case OPC_BZ_H:
26955    case OPC_BZ_W:
26956    case OPC_BZ_D:
26957        gen_check_zero_element(bcond, df, wt);
26958        break;
26959    case OPC_BNZ_B:
26960    case OPC_BNZ_H:
26961    case OPC_BNZ_W:
26962    case OPC_BNZ_D:
26963        gen_check_zero_element(bcond, df, wt);
26964        tcg_gen_setcondi_tl(TCG_COND_EQ, bcond, bcond, 0);
26965        break;
26966    }
26967
26968    ctx->btarget = ctx->base.pc_next + (s16 << 2) + 4;
26969
26970    ctx->hflags |= MIPS_HFLAG_BC;
26971    ctx->hflags |= MIPS_HFLAG_BDS32;
26972}
26973
26974static void gen_msa_i8(CPUMIPSState *env, DisasContext *ctx)
26975{
26976#define MASK_MSA_I8(op)    (MASK_MSA_MINOR(op) | (op & (0x03 << 24)))
26977    uint8_t i8 = (ctx->opcode >> 16) & 0xff;
26978    uint8_t ws = (ctx->opcode >> 11) & 0x1f;
26979    uint8_t wd = (ctx->opcode >> 6) & 0x1f;
26980
26981    TCGv_i32 twd = tcg_const_i32(wd);
26982    TCGv_i32 tws = tcg_const_i32(ws);
26983    TCGv_i32 ti8 = tcg_const_i32(i8);
26984
26985    switch (MASK_MSA_I8(ctx->opcode)) {
26986    case OPC_ANDI_B:
26987        gen_helper_msa_andi_b(cpu_env, twd, tws, ti8);
26988        break;
26989    case OPC_ORI_B:
26990        gen_helper_msa_ori_b(cpu_env, twd, tws, ti8);
26991        break;
26992    case OPC_NORI_B:
26993        gen_helper_msa_nori_b(cpu_env, twd, tws, ti8);
26994        break;
26995    case OPC_XORI_B:
26996        gen_helper_msa_xori_b(cpu_env, twd, tws, ti8);
26997        break;
26998    case OPC_BMNZI_B:
26999        gen_helper_msa_bmnzi_b(cpu_env, twd, tws, ti8);
27000        break;
27001    case OPC_BMZI_B:
27002        gen_helper_msa_bmzi_b(cpu_env, twd, tws, ti8);
27003        break;
27004    case OPC_BSELI_B:
27005        gen_helper_msa_bseli_b(cpu_env, twd, tws, ti8);
27006        break;
27007    case OPC_SHF_B:
27008    case OPC_SHF_H:
27009    case OPC_SHF_W:
27010        {
27011            uint8_t df = (ctx->opcode >> 24) & 0x3;
27012            if (df == DF_DOUBLE) {
27013                generate_exception_end(ctx, EXCP_RI);
27014            } else {
27015                TCGv_i32 tdf = tcg_const_i32(df);
27016                gen_helper_msa_shf_df(cpu_env, tdf, twd, tws, ti8);
27017                tcg_temp_free_i32(tdf);
27018            }
27019        }
27020        break;
27021    default:
27022        MIPS_INVAL("MSA instruction");
27023        generate_exception_end(ctx, EXCP_RI);
27024        break;
27025    }
27026
27027    tcg_temp_free_i32(twd);
27028    tcg_temp_free_i32(tws);
27029    tcg_temp_free_i32(ti8);
27030}
27031
27032static void gen_msa_i5(CPUMIPSState *env, DisasContext *ctx)
27033{
27034#define MASK_MSA_I5(op)    (MASK_MSA_MINOR(op) | (op & (0x7 << 23)))
27035    uint8_t df = (ctx->opcode >> 21) & 0x3;
27036    int8_t s5 = (int8_t) sextract32(ctx->opcode, 16, 5);
27037    uint8_t u5 = (ctx->opcode >> 16) & 0x1f;
27038    uint8_t ws = (ctx->opcode >> 11) & 0x1f;
27039    uint8_t wd = (ctx->opcode >> 6) & 0x1f;
27040
27041    TCGv_i32 tdf = tcg_const_i32(df);
27042    TCGv_i32 twd = tcg_const_i32(wd);
27043    TCGv_i32 tws = tcg_const_i32(ws);
27044    TCGv_i32 timm = tcg_temp_new_i32();
27045    tcg_gen_movi_i32(timm, u5);
27046
27047    switch (MASK_MSA_I5(ctx->opcode)) {
27048    case OPC_ADDVI_df:
27049        gen_helper_msa_addvi_df(cpu_env, tdf, twd, tws, timm);
27050        break;
27051    case OPC_SUBVI_df:
27052        gen_helper_msa_subvi_df(cpu_env, tdf, twd, tws, timm);
27053        break;
27054    case OPC_MAXI_S_df:
27055        tcg_gen_movi_i32(timm, s5);
27056        gen_helper_msa_maxi_s_df(cpu_env, tdf, twd, tws, timm);
27057        break;
27058    case OPC_MAXI_U_df:
27059        gen_helper_msa_maxi_u_df(cpu_env, tdf, twd, tws, timm);
27060        break;
27061    case OPC_MINI_S_df:
27062        tcg_gen_movi_i32(timm, s5);
27063        gen_helper_msa_mini_s_df(cpu_env, tdf, twd, tws, timm);
27064        break;
27065    case OPC_MINI_U_df:
27066        gen_helper_msa_mini_u_df(cpu_env, tdf, twd, tws, timm);
27067        break;
27068    case OPC_CEQI_df:
27069        tcg_gen_movi_i32(timm, s5);
27070        gen_helper_msa_ceqi_df(cpu_env, tdf, twd, tws, timm);
27071        break;
27072    case OPC_CLTI_S_df:
27073        tcg_gen_movi_i32(timm, s5);
27074        gen_helper_msa_clti_s_df(cpu_env, tdf, twd, tws, timm);
27075        break;
27076    case OPC_CLTI_U_df:
27077        gen_helper_msa_clti_u_df(cpu_env, tdf, twd, tws, timm);
27078        break;
27079    case OPC_CLEI_S_df:
27080        tcg_gen_movi_i32(timm, s5);
27081        gen_helper_msa_clei_s_df(cpu_env, tdf, twd, tws, timm);
27082        break;
27083    case OPC_CLEI_U_df:
27084        gen_helper_msa_clei_u_df(cpu_env, tdf, twd, tws, timm);
27085        break;
27086    case OPC_LDI_df:
27087        {
27088            int32_t s10 = sextract32(ctx->opcode, 11, 10);
27089            tcg_gen_movi_i32(timm, s10);
27090            gen_helper_msa_ldi_df(cpu_env, tdf, twd, timm);
27091        }
27092        break;
27093    default:
27094        MIPS_INVAL("MSA instruction");
27095        generate_exception_end(ctx, EXCP_RI);
27096        break;
27097    }
27098
27099    tcg_temp_free_i32(tdf);
27100    tcg_temp_free_i32(twd);
27101    tcg_temp_free_i32(tws);
27102    tcg_temp_free_i32(timm);
27103}
27104
27105static void gen_msa_bit(CPUMIPSState *env, DisasContext *ctx)
27106{
27107#define MASK_MSA_BIT(op)    (MASK_MSA_MINOR(op) | (op & (0x7 << 23)))
27108    uint8_t dfm = (ctx->opcode >> 16) & 0x7f;
27109    uint32_t df = 0, m = 0;
27110    uint8_t ws = (ctx->opcode >> 11) & 0x1f;
27111    uint8_t wd = (ctx->opcode >> 6) & 0x1f;
27112
27113    TCGv_i32 tdf;
27114    TCGv_i32 tm;
27115    TCGv_i32 twd;
27116    TCGv_i32 tws;
27117
27118    if ((dfm & 0x40) == 0x00) {
27119        m = dfm & 0x3f;
27120        df = DF_DOUBLE;
27121    } else if ((dfm & 0x60) == 0x40) {
27122        m = dfm & 0x1f;
27123        df = DF_WORD;
27124    } else if ((dfm & 0x70) == 0x60) {
27125        m = dfm & 0x0f;
27126        df = DF_HALF;
27127    } else if ((dfm & 0x78) == 0x70) {
27128        m = dfm & 0x7;
27129        df = DF_BYTE;
27130    } else {
27131        generate_exception_end(ctx, EXCP_RI);
27132        return;
27133    }
27134
27135    tdf = tcg_const_i32(df);
27136    tm  = tcg_const_i32(m);
27137    twd = tcg_const_i32(wd);
27138    tws = tcg_const_i32(ws);
27139
27140    switch (MASK_MSA_BIT(ctx->opcode)) {
27141    case OPC_SLLI_df:
27142        gen_helper_msa_slli_df(cpu_env, tdf, twd, tws, tm);
27143        break;
27144    case OPC_SRAI_df:
27145        gen_helper_msa_srai_df(cpu_env, tdf, twd, tws, tm);
27146        break;
27147    case OPC_SRLI_df:
27148        gen_helper_msa_srli_df(cpu_env, tdf, twd, tws, tm);
27149        break;
27150    case OPC_BCLRI_df:
27151        gen_helper_msa_bclri_df(cpu_env, tdf, twd, tws, tm);
27152        break;
27153    case OPC_BSETI_df:
27154        gen_helper_msa_bseti_df(cpu_env, tdf, twd, tws, tm);
27155        break;
27156    case OPC_BNEGI_df:
27157        gen_helper_msa_bnegi_df(cpu_env, tdf, twd, tws, tm);
27158        break;
27159    case OPC_BINSLI_df:
27160        gen_helper_msa_binsli_df(cpu_env, tdf, twd, tws, tm);
27161        break;
27162    case OPC_BINSRI_df:
27163        gen_helper_msa_binsri_df(cpu_env, tdf, twd, tws, tm);
27164        break;
27165    case OPC_SAT_S_df:
27166        gen_helper_msa_sat_s_df(cpu_env, tdf, twd, tws, tm);
27167        break;
27168    case OPC_SAT_U_df:
27169        gen_helper_msa_sat_u_df(cpu_env, tdf, twd, tws, tm);
27170        break;
27171    case OPC_SRARI_df:
27172        gen_helper_msa_srari_df(cpu_env, tdf, twd, tws, tm);
27173        break;
27174    case OPC_SRLRI_df:
27175        gen_helper_msa_srlri_df(cpu_env, tdf, twd, tws, tm);
27176        break;
27177    default:
27178        MIPS_INVAL("MSA instruction");
27179        generate_exception_end(ctx, EXCP_RI);
27180        break;
27181    }
27182
27183    tcg_temp_free_i32(tdf);
27184    tcg_temp_free_i32(tm);
27185    tcg_temp_free_i32(twd);
27186    tcg_temp_free_i32(tws);
27187}
27188
27189static void gen_msa_3r(CPUMIPSState *env, DisasContext *ctx)
27190{
27191#define MASK_MSA_3R(op)    (MASK_MSA_MINOR(op) | (op & (0x7 << 23)))
27192    uint8_t df = (ctx->opcode >> 21) & 0x3;
27193    uint8_t wt = (ctx->opcode >> 16) & 0x1f;
27194    uint8_t ws = (ctx->opcode >> 11) & 0x1f;
27195    uint8_t wd = (ctx->opcode >> 6) & 0x1f;
27196
27197    TCGv_i32 tdf = tcg_const_i32(df);
27198    TCGv_i32 twd = tcg_const_i32(wd);
27199    TCGv_i32 tws = tcg_const_i32(ws);
27200    TCGv_i32 twt = tcg_const_i32(wt);
27201
27202    switch (MASK_MSA_3R(ctx->opcode)) {
27203    case OPC_SLL_df:
27204        gen_helper_msa_sll_df(cpu_env, tdf, twd, tws, twt);
27205        break;
27206    case OPC_ADDV_df:
27207        gen_helper_msa_addv_df(cpu_env, tdf, twd, tws, twt);
27208        break;
27209    case OPC_CEQ_df:
27210        gen_helper_msa_ceq_df(cpu_env, tdf, twd, tws, twt);
27211        break;
27212    case OPC_ADD_A_df:
27213        gen_helper_msa_add_a_df(cpu_env, tdf, twd, tws, twt);
27214        break;
27215    case OPC_SUBS_S_df:
27216        gen_helper_msa_subs_s_df(cpu_env, tdf, twd, tws, twt);
27217        break;
27218    case OPC_MULV_df:
27219        gen_helper_msa_mulv_df(cpu_env, tdf, twd, tws, twt);
27220        break;
27221    case OPC_SLD_df:
27222        gen_helper_msa_sld_df(cpu_env, tdf, twd, tws, twt);
27223        break;
27224    case OPC_VSHF_df:
27225        gen_helper_msa_vshf_df(cpu_env, tdf, twd, tws, twt);
27226        break;
27227    case OPC_SRA_df:
27228        gen_helper_msa_sra_df(cpu_env, tdf, twd, tws, twt);
27229        break;
27230    case OPC_SUBV_df:
27231        gen_helper_msa_subv_df(cpu_env, tdf, twd, tws, twt);
27232        break;
27233    case OPC_ADDS_A_df:
27234        gen_helper_msa_adds_a_df(cpu_env, tdf, twd, tws, twt);
27235        break;
27236    case OPC_SUBS_U_df:
27237        gen_helper_msa_subs_u_df(cpu_env, tdf, twd, tws, twt);
27238        break;
27239    case OPC_MADDV_df:
27240        gen_helper_msa_maddv_df(cpu_env, tdf, twd, tws, twt);
27241        break;
27242    case OPC_SPLAT_df:
27243        gen_helper_msa_splat_df(cpu_env, tdf, twd, tws, twt);
27244        break;
27245    case OPC_SRAR_df:
27246        gen_helper_msa_srar_df(cpu_env, tdf, twd, tws, twt);
27247        break;
27248    case OPC_SRL_df:
27249        gen_helper_msa_srl_df(cpu_env, tdf, twd, tws, twt);
27250        break;
27251    case OPC_MAX_S_df:
27252        gen_helper_msa_max_s_df(cpu_env, tdf, twd, tws, twt);
27253        break;
27254    case OPC_CLT_S_df:
27255        gen_helper_msa_clt_s_df(cpu_env, tdf, twd, tws, twt);
27256        break;
27257    case OPC_ADDS_S_df:
27258        gen_helper_msa_adds_s_df(cpu_env, tdf, twd, tws, twt);
27259        break;
27260    case OPC_SUBSUS_U_df:
27261        gen_helper_msa_subsus_u_df(cpu_env, tdf, twd, tws, twt);
27262        break;
27263    case OPC_MSUBV_df:
27264        gen_helper_msa_msubv_df(cpu_env, tdf, twd, tws, twt);
27265        break;
27266    case OPC_PCKEV_df:
27267        gen_helper_msa_pckev_df(cpu_env, tdf, twd, tws, twt);
27268        break;
27269    case OPC_SRLR_df:
27270        gen_helper_msa_srlr_df(cpu_env, tdf, twd, tws, twt);
27271        break;
27272    case OPC_BCLR_df:
27273        gen_helper_msa_bclr_df(cpu_env, tdf, twd, tws, twt);
27274        break;
27275    case OPC_MAX_U_df:
27276        gen_helper_msa_max_u_df(cpu_env, tdf, twd, tws, twt);
27277        break;
27278    case OPC_CLT_U_df:
27279        gen_helper_msa_clt_u_df(cpu_env, tdf, twd, tws, twt);
27280        break;
27281    case OPC_ADDS_U_df:
27282        gen_helper_msa_adds_u_df(cpu_env, tdf, twd, tws, twt);
27283        break;
27284    case OPC_SUBSUU_S_df:
27285        gen_helper_msa_subsuu_s_df(cpu_env, tdf, twd, tws, twt);
27286        break;
27287    case OPC_PCKOD_df:
27288        gen_helper_msa_pckod_df(cpu_env, tdf, twd, tws, twt);
27289        break;
27290    case OPC_BSET_df:
27291        gen_helper_msa_bset_df(cpu_env, tdf, twd, tws, twt);
27292        break;
27293    case OPC_MIN_S_df:
27294        gen_helper_msa_min_s_df(cpu_env, tdf, twd, tws, twt);
27295        break;
27296    case OPC_CLE_S_df:
27297        gen_helper_msa_cle_s_df(cpu_env, tdf, twd, tws, twt);
27298        break;
27299    case OPC_AVE_S_df:
27300        gen_helper_msa_ave_s_df(cpu_env, tdf, twd, tws, twt);
27301        break;
27302    case OPC_ASUB_S_df:
27303        gen_helper_msa_asub_s_df(cpu_env, tdf, twd, tws, twt);
27304        break;
27305    case OPC_DIV_S_df:
27306        gen_helper_msa_div_s_df(cpu_env, tdf, twd, tws, twt);
27307        break;
27308    case OPC_ILVL_df:
27309        gen_helper_msa_ilvl_df(cpu_env, tdf, twd, tws, twt);
27310        break;
27311    case OPC_BNEG_df:
27312        gen_helper_msa_bneg_df(cpu_env, tdf, twd, tws, twt);
27313        break;
27314    case OPC_MIN_U_df:
27315        gen_helper_msa_min_u_df(cpu_env, tdf, twd, tws, twt);
27316        break;
27317    case OPC_CLE_U_df:
27318        gen_helper_msa_cle_u_df(cpu_env, tdf, twd, tws, twt);
27319        break;
27320    case OPC_AVE_U_df:
27321        gen_helper_msa_ave_u_df(cpu_env, tdf, twd, tws, twt);
27322        break;
27323    case OPC_ASUB_U_df:
27324        gen_helper_msa_asub_u_df(cpu_env, tdf, twd, tws, twt);
27325        break;
27326    case OPC_DIV_U_df:
27327        gen_helper_msa_div_u_df(cpu_env, tdf, twd, tws, twt);
27328        break;
27329    case OPC_ILVR_df:
27330        gen_helper_msa_ilvr_df(cpu_env, tdf, twd, tws, twt);
27331        break;
27332    case OPC_BINSL_df:
27333        gen_helper_msa_binsl_df(cpu_env, tdf, twd, tws, twt);
27334        break;
27335    case OPC_MAX_A_df:
27336        gen_helper_msa_max_a_df(cpu_env, tdf, twd, tws, twt);
27337        break;
27338    case OPC_AVER_S_df:
27339        gen_helper_msa_aver_s_df(cpu_env, tdf, twd, tws, twt);
27340        break;
27341    case OPC_MOD_S_df:
27342        gen_helper_msa_mod_s_df(cpu_env, tdf, twd, tws, twt);
27343        break;
27344    case OPC_ILVEV_df:
27345        gen_helper_msa_ilvev_df(cpu_env, tdf, twd, tws, twt);
27346        break;
27347    case OPC_BINSR_df:
27348        gen_helper_msa_binsr_df(cpu_env, tdf, twd, tws, twt);
27349        break;
27350    case OPC_MIN_A_df:
27351        gen_helper_msa_min_a_df(cpu_env, tdf, twd, tws, twt);
27352        break;
27353    case OPC_AVER_U_df:
27354        gen_helper_msa_aver_u_df(cpu_env, tdf, twd, tws, twt);
27355        break;
27356    case OPC_MOD_U_df:
27357        gen_helper_msa_mod_u_df(cpu_env, tdf, twd, tws, twt);
27358        break;
27359    case OPC_ILVOD_df:
27360        gen_helper_msa_ilvod_df(cpu_env, tdf, twd, tws, twt);
27361        break;
27362
27363    case OPC_DOTP_S_df:
27364    case OPC_DOTP_U_df:
27365    case OPC_DPADD_S_df:
27366    case OPC_DPADD_U_df:
27367    case OPC_DPSUB_S_df:
27368    case OPC_HADD_S_df:
27369    case OPC_DPSUB_U_df:
27370    case OPC_HADD_U_df:
27371    case OPC_HSUB_S_df:
27372    case OPC_HSUB_U_df:
27373        if (df == DF_BYTE) {
27374            generate_exception_end(ctx, EXCP_RI);
27375            break;
27376        }
27377        switch (MASK_MSA_3R(ctx->opcode)) {
27378        case OPC_DOTP_S_df:
27379            gen_helper_msa_dotp_s_df(cpu_env, tdf, twd, tws, twt);
27380            break;
27381        case OPC_DOTP_U_df:
27382            gen_helper_msa_dotp_u_df(cpu_env, tdf, twd, tws, twt);
27383            break;
27384        case OPC_DPADD_S_df:
27385            gen_helper_msa_dpadd_s_df(cpu_env, tdf, twd, tws, twt);
27386            break;
27387        case OPC_DPADD_U_df:
27388            gen_helper_msa_dpadd_u_df(cpu_env, tdf, twd, tws, twt);
27389            break;
27390        case OPC_DPSUB_S_df:
27391            gen_helper_msa_dpsub_s_df(cpu_env, tdf, twd, tws, twt);
27392            break;
27393        case OPC_HADD_S_df:
27394            gen_helper_msa_hadd_s_df(cpu_env, tdf, twd, tws, twt);
27395            break;
27396        case OPC_DPSUB_U_df:
27397            gen_helper_msa_dpsub_u_df(cpu_env, tdf, twd, tws, twt);
27398            break;
27399        case OPC_HADD_U_df:
27400            gen_helper_msa_hadd_u_df(cpu_env, tdf, twd, tws, twt);
27401            break;
27402        case OPC_HSUB_S_df:
27403            gen_helper_msa_hsub_s_df(cpu_env, tdf, twd, tws, twt);
27404            break;
27405        case OPC_HSUB_U_df:
27406            gen_helper_msa_hsub_u_df(cpu_env, tdf, twd, tws, twt);
27407            break;
27408        }
27409        break;
27410    default:
27411        MIPS_INVAL("MSA instruction");
27412        generate_exception_end(ctx, EXCP_RI);
27413        break;
27414    }
27415    tcg_temp_free_i32(twd);
27416    tcg_temp_free_i32(tws);
27417    tcg_temp_free_i32(twt);
27418    tcg_temp_free_i32(tdf);
27419}
27420
27421static void gen_msa_elm_3e(CPUMIPSState *env, DisasContext *ctx)
27422{
27423#define MASK_MSA_ELM_DF3E(op)   (MASK_MSA_MINOR(op) | (op & (0x3FF << 16)))
27424    uint8_t source = (ctx->opcode >> 11) & 0x1f;
27425    uint8_t dest = (ctx->opcode >> 6) & 0x1f;
27426    TCGv telm = tcg_temp_new();
27427    TCGv_i32 tsr = tcg_const_i32(source);
27428    TCGv_i32 tdt = tcg_const_i32(dest);
27429
27430    switch (MASK_MSA_ELM_DF3E(ctx->opcode)) {
27431    case OPC_CTCMSA:
27432        gen_load_gpr(telm, source);
27433        gen_helper_msa_ctcmsa(cpu_env, telm, tdt);
27434        break;
27435    case OPC_CFCMSA:
27436        gen_helper_msa_cfcmsa(telm, cpu_env, tsr);
27437        gen_store_gpr(telm, dest);
27438        break;
27439    case OPC_MOVE_V:
27440        gen_helper_msa_move_v(cpu_env, tdt, tsr);
27441        break;
27442    default:
27443        MIPS_INVAL("MSA instruction");
27444        generate_exception_end(ctx, EXCP_RI);
27445        break;
27446    }
27447
27448    tcg_temp_free(telm);
27449    tcg_temp_free_i32(tdt);
27450    tcg_temp_free_i32(tsr);
27451}
27452
27453static void gen_msa_elm_df(CPUMIPSState *env, DisasContext *ctx, uint32_t df,
27454        uint32_t n)
27455{
27456#define MASK_MSA_ELM(op)    (MASK_MSA_MINOR(op) | (op & (0xf << 22)))
27457    uint8_t ws = (ctx->opcode >> 11) & 0x1f;
27458    uint8_t wd = (ctx->opcode >> 6) & 0x1f;
27459
27460    TCGv_i32 tws = tcg_const_i32(ws);
27461    TCGv_i32 twd = tcg_const_i32(wd);
27462    TCGv_i32 tn  = tcg_const_i32(n);
27463    TCGv_i32 tdf = tcg_const_i32(df);
27464
27465    switch (MASK_MSA_ELM(ctx->opcode)) {
27466    case OPC_SLDI_df:
27467        gen_helper_msa_sldi_df(cpu_env, tdf, twd, tws, tn);
27468        break;
27469    case OPC_SPLATI_df:
27470        gen_helper_msa_splati_df(cpu_env, tdf, twd, tws, tn);
27471        break;
27472    case OPC_INSVE_df:
27473        gen_helper_msa_insve_df(cpu_env, tdf, twd, tws, tn);
27474        break;
27475    case OPC_COPY_S_df:
27476    case OPC_COPY_U_df:
27477    case OPC_INSERT_df:
27478#if !defined(TARGET_MIPS64)
27479        /* Double format valid only for MIPS64 */
27480        if (df == DF_DOUBLE) {
27481            generate_exception_end(ctx, EXCP_RI);
27482            break;
27483        }
27484#endif
27485        switch (MASK_MSA_ELM(ctx->opcode)) {
27486        case OPC_COPY_S_df:
27487            if (likely(wd != 0)) {
27488                gen_helper_msa_copy_s_df(cpu_env, tdf, twd, tws, tn);
27489            }
27490            break;
27491        case OPC_COPY_U_df:
27492            if (likely(wd != 0)) {
27493                gen_helper_msa_copy_u_df(cpu_env, tdf, twd, tws, tn);
27494            }
27495            break;
27496        case OPC_INSERT_df:
27497            gen_helper_msa_insert_df(cpu_env, tdf, twd, tws, tn);
27498            break;
27499        }
27500        break;
27501    default:
27502        MIPS_INVAL("MSA instruction");
27503        generate_exception_end(ctx, EXCP_RI);
27504    }
27505    tcg_temp_free_i32(twd);
27506    tcg_temp_free_i32(tws);
27507    tcg_temp_free_i32(tn);
27508    tcg_temp_free_i32(tdf);
27509}
27510
27511static void gen_msa_elm(CPUMIPSState *env, DisasContext *ctx)
27512{
27513    uint8_t dfn = (ctx->opcode >> 16) & 0x3f;
27514    uint32_t df = 0, n = 0;
27515
27516    if ((dfn & 0x30) == 0x00) {
27517        n = dfn & 0x0f;
27518        df = DF_BYTE;
27519    } else if ((dfn & 0x38) == 0x20) {
27520        n = dfn & 0x07;
27521        df = DF_HALF;
27522    } else if ((dfn & 0x3c) == 0x30) {
27523        n = dfn & 0x03;
27524        df = DF_WORD;
27525    } else if ((dfn & 0x3e) == 0x38) {
27526        n = dfn & 0x01;
27527        df = DF_DOUBLE;
27528    } else if (dfn == 0x3E) {
27529        /* CTCMSA, CFCMSA, MOVE.V */
27530        gen_msa_elm_3e(env, ctx);
27531        return;
27532    } else {
27533        generate_exception_end(ctx, EXCP_RI);
27534        return;
27535    }
27536
27537    gen_msa_elm_df(env, ctx, df, n);
27538}
27539
27540static void gen_msa_3rf(CPUMIPSState *env, DisasContext *ctx)
27541{
27542#define MASK_MSA_3RF(op)    (MASK_MSA_MINOR(op) | (op & (0xf << 22)))
27543    uint8_t df = (ctx->opcode >> 21) & 0x1;
27544    uint8_t wt = (ctx->opcode >> 16) & 0x1f;
27545    uint8_t ws = (ctx->opcode >> 11) & 0x1f;
27546    uint8_t wd = (ctx->opcode >> 6) & 0x1f;
27547
27548    TCGv_i32 twd = tcg_const_i32(wd);
27549    TCGv_i32 tws = tcg_const_i32(ws);
27550    TCGv_i32 twt = tcg_const_i32(wt);
27551    TCGv_i32 tdf = tcg_temp_new_i32();
27552
27553    /* adjust df value for floating-point instruction */
27554    tcg_gen_movi_i32(tdf, df + 2);
27555
27556    switch (MASK_MSA_3RF(ctx->opcode)) {
27557    case OPC_FCAF_df:
27558        gen_helper_msa_fcaf_df(cpu_env, tdf, twd, tws, twt);
27559        break;
27560    case OPC_FADD_df:
27561        gen_helper_msa_fadd_df(cpu_env, tdf, twd, tws, twt);
27562        break;
27563    case OPC_FCUN_df:
27564        gen_helper_msa_fcun_df(cpu_env, tdf, twd, tws, twt);
27565        break;
27566    case OPC_FSUB_df:
27567        gen_helper_msa_fsub_df(cpu_env, tdf, twd, tws, twt);
27568        break;
27569    case OPC_FCOR_df:
27570        gen_helper_msa_fcor_df(cpu_env, tdf, twd, tws, twt);
27571        break;
27572    case OPC_FCEQ_df:
27573        gen_helper_msa_fceq_df(cpu_env, tdf, twd, tws, twt);
27574        break;
27575    case OPC_FMUL_df:
27576        gen_helper_msa_fmul_df(cpu_env, tdf, twd, tws, twt);
27577        break;
27578    case OPC_FCUNE_df:
27579        gen_helper_msa_fcune_df(cpu_env, tdf, twd, tws, twt);
27580        break;
27581    case OPC_FCUEQ_df:
27582        gen_helper_msa_fcueq_df(cpu_env, tdf, twd, tws, twt);
27583        break;
27584    case OPC_FDIV_df:
27585        gen_helper_msa_fdiv_df(cpu_env, tdf, twd, tws, twt);
27586        break;
27587    case OPC_FCNE_df:
27588        gen_helper_msa_fcne_df(cpu_env, tdf, twd, tws, twt);
27589        break;
27590    case OPC_FCLT_df:
27591        gen_helper_msa_fclt_df(cpu_env, tdf, twd, tws, twt);
27592        break;
27593    case OPC_FMADD_df:
27594        gen_helper_msa_fmadd_df(cpu_env, tdf, twd, tws, twt);
27595        break;
27596    case OPC_MUL_Q_df:
27597        tcg_gen_movi_i32(tdf, df + 1);
27598        gen_helper_msa_mul_q_df(cpu_env, tdf, twd, tws, twt);
27599        break;
27600    case OPC_FCULT_df:
27601        gen_helper_msa_fcult_df(cpu_env, tdf, twd, tws, twt);
27602        break;
27603    case OPC_FMSUB_df:
27604        gen_helper_msa_fmsub_df(cpu_env, tdf, twd, tws, twt);
27605        break;
27606    case OPC_MADD_Q_df:
27607        tcg_gen_movi_i32(tdf, df + 1);
27608        gen_helper_msa_madd_q_df(cpu_env, tdf, twd, tws, twt);
27609        break;
27610    case OPC_FCLE_df:
27611        gen_helper_msa_fcle_df(cpu_env, tdf, twd, tws, twt);
27612        break;
27613    case OPC_MSUB_Q_df:
27614        tcg_gen_movi_i32(tdf, df + 1);
27615        gen_helper_msa_msub_q_df(cpu_env, tdf, twd, tws, twt);
27616        break;
27617    case OPC_FCULE_df:
27618        gen_helper_msa_fcule_df(cpu_env, tdf, twd, tws, twt);
27619        break;
27620    case OPC_FEXP2_df:
27621        gen_helper_msa_fexp2_df(cpu_env, tdf, twd, tws, twt);
27622        break;
27623    case OPC_FSAF_df:
27624        gen_helper_msa_fsaf_df(cpu_env, tdf, twd, tws, twt);
27625        break;
27626    case OPC_FEXDO_df:
27627        gen_helper_msa_fexdo_df(cpu_env, tdf, twd, tws, twt);
27628        break;
27629    case OPC_FSUN_df:
27630        gen_helper_msa_fsun_df(cpu_env, tdf, twd, tws, twt);
27631        break;
27632    case OPC_FSOR_df:
27633        gen_helper_msa_fsor_df(cpu_env, tdf, twd, tws, twt);
27634        break;
27635    case OPC_FSEQ_df:
27636        gen_helper_msa_fseq_df(cpu_env, tdf, twd, tws, twt);
27637        break;
27638    case OPC_FTQ_df:
27639        gen_helper_msa_ftq_df(cpu_env, tdf, twd, tws, twt);
27640        break;
27641    case OPC_FSUNE_df:
27642        gen_helper_msa_fsune_df(cpu_env, tdf, twd, tws, twt);
27643        break;
27644    case OPC_FSUEQ_df:
27645        gen_helper_msa_fsueq_df(cpu_env, tdf, twd, tws, twt);
27646        break;
27647    case OPC_FSNE_df:
27648        gen_helper_msa_fsne_df(cpu_env, tdf, twd, tws, twt);
27649        break;
27650    case OPC_FSLT_df:
27651        gen_helper_msa_fslt_df(cpu_env, tdf, twd, tws, twt);
27652        break;
27653    case OPC_FMIN_df:
27654        gen_helper_msa_fmin_df(cpu_env, tdf, twd, tws, twt);
27655        break;
27656    case OPC_MULR_Q_df:
27657        tcg_gen_movi_i32(tdf, df + 1);
27658        gen_helper_msa_mulr_q_df(cpu_env, tdf, twd, tws, twt);
27659        break;
27660    case OPC_FSULT_df:
27661        gen_helper_msa_fsult_df(cpu_env, tdf, twd, tws, twt);
27662        break;
27663    case OPC_FMIN_A_df:
27664        gen_helper_msa_fmin_a_df(cpu_env, tdf, twd, tws, twt);
27665        break;
27666    case OPC_MADDR_Q_df:
27667        tcg_gen_movi_i32(tdf, df + 1);
27668        gen_helper_msa_maddr_q_df(cpu_env, tdf, twd, tws, twt);
27669        break;
27670    case OPC_FSLE_df:
27671        gen_helper_msa_fsle_df(cpu_env, tdf, twd, tws, twt);
27672        break;
27673    case OPC_FMAX_df:
27674        gen_helper_msa_fmax_df(cpu_env, tdf, twd, tws, twt);
27675        break;
27676    case OPC_MSUBR_Q_df:
27677        tcg_gen_movi_i32(tdf, df + 1);
27678        gen_helper_msa_msubr_q_df(cpu_env, tdf, twd, tws, twt);
27679        break;
27680    case OPC_FSULE_df:
27681        gen_helper_msa_fsule_df(cpu_env, tdf, twd, tws, twt);
27682        break;
27683    case OPC_FMAX_A_df:
27684        gen_helper_msa_fmax_a_df(cpu_env, tdf, twd, tws, twt);
27685        break;
27686    default:
27687        MIPS_INVAL("MSA instruction");
27688        generate_exception_end(ctx, EXCP_RI);
27689        break;
27690    }
27691
27692    tcg_temp_free_i32(twd);
27693    tcg_temp_free_i32(tws);
27694    tcg_temp_free_i32(twt);
27695    tcg_temp_free_i32(tdf);
27696}
27697
27698static void gen_msa_2r(CPUMIPSState *env, DisasContext *ctx)
27699{
27700#define MASK_MSA_2R(op)     (MASK_MSA_MINOR(op) | (op & (0x1f << 21)) | \
27701                            (op & (0x7 << 18)))
27702    uint8_t wt = (ctx->opcode >> 16) & 0x1f;
27703    uint8_t ws = (ctx->opcode >> 11) & 0x1f;
27704    uint8_t wd = (ctx->opcode >> 6) & 0x1f;
27705    uint8_t df = (ctx->opcode >> 16) & 0x3;
27706    TCGv_i32 twd = tcg_const_i32(wd);
27707    TCGv_i32 tws = tcg_const_i32(ws);
27708    TCGv_i32 twt = tcg_const_i32(wt);
27709    TCGv_i32 tdf = tcg_const_i32(df);
27710
27711    switch (MASK_MSA_2R(ctx->opcode)) {
27712    case OPC_FILL_df:
27713#if !defined(TARGET_MIPS64)
27714        /* Double format valid only for MIPS64 */
27715        if (df == DF_DOUBLE) {
27716            generate_exception_end(ctx, EXCP_RI);
27717            break;
27718        }
27719#endif
27720        gen_helper_msa_fill_df(cpu_env, tdf, twd, tws); /* trs */
27721        break;
27722    case OPC_PCNT_df:
27723        gen_helper_msa_pcnt_df(cpu_env, tdf, twd, tws);
27724        break;
27725    case OPC_NLOC_df:
27726        gen_helper_msa_nloc_df(cpu_env, tdf, twd, tws);
27727        break;
27728    case OPC_NLZC_df:
27729        gen_helper_msa_nlzc_df(cpu_env, tdf, twd, tws);
27730        break;
27731    default:
27732        MIPS_INVAL("MSA instruction");
27733        generate_exception_end(ctx, EXCP_RI);
27734        break;
27735    }
27736
27737    tcg_temp_free_i32(twd);
27738    tcg_temp_free_i32(tws);
27739    tcg_temp_free_i32(twt);
27740    tcg_temp_free_i32(tdf);
27741}
27742
27743static void gen_msa_2rf(CPUMIPSState *env, DisasContext *ctx)
27744{
27745#define MASK_MSA_2RF(op)    (MASK_MSA_MINOR(op) | (op & (0x1f << 21)) | \
27746                            (op & (0xf << 17)))
27747    uint8_t wt = (ctx->opcode >> 16) & 0x1f;
27748    uint8_t ws = (ctx->opcode >> 11) & 0x1f;
27749    uint8_t wd = (ctx->opcode >> 6) & 0x1f;
27750    uint8_t df = (ctx->opcode >> 16) & 0x1;
27751    TCGv_i32 twd = tcg_const_i32(wd);
27752    TCGv_i32 tws = tcg_const_i32(ws);
27753    TCGv_i32 twt = tcg_const_i32(wt);
27754    /* adjust df value for floating-point instruction */
27755    TCGv_i32 tdf = tcg_const_i32(df + 2);
27756
27757    switch (MASK_MSA_2RF(ctx->opcode)) {
27758    case OPC_FCLASS_df:
27759        gen_helper_msa_fclass_df(cpu_env, tdf, twd, tws);
27760        break;
27761    case OPC_FTRUNC_S_df:
27762        gen_helper_msa_ftrunc_s_df(cpu_env, tdf, twd, tws);
27763        break;
27764    case OPC_FTRUNC_U_df:
27765        gen_helper_msa_ftrunc_u_df(cpu_env, tdf, twd, tws);
27766        break;
27767    case OPC_FSQRT_df:
27768        gen_helper_msa_fsqrt_df(cpu_env, tdf, twd, tws);
27769        break;
27770    case OPC_FRSQRT_df:
27771        gen_helper_msa_frsqrt_df(cpu_env, tdf, twd, tws);
27772        break;
27773    case OPC_FRCP_df:
27774        gen_helper_msa_frcp_df(cpu_env, tdf, twd, tws);
27775        break;
27776    case OPC_FRINT_df:
27777        gen_helper_msa_frint_df(cpu_env, tdf, twd, tws);
27778        break;
27779    case OPC_FLOG2_df:
27780        gen_helper_msa_flog2_df(cpu_env, tdf, twd, tws);
27781        break;
27782    case OPC_FEXUPL_df:
27783        gen_helper_msa_fexupl_df(cpu_env, tdf, twd, tws);
27784        break;
27785    case OPC_FEXUPR_df:
27786        gen_helper_msa_fexupr_df(cpu_env, tdf, twd, tws);
27787        break;
27788    case OPC_FFQL_df:
27789        gen_helper_msa_ffql_df(cpu_env, tdf, twd, tws);
27790        break;
27791    case OPC_FFQR_df:
27792        gen_helper_msa_ffqr_df(cpu_env, tdf, twd, tws);
27793        break;
27794    case OPC_FTINT_S_df:
27795        gen_helper_msa_ftint_s_df(cpu_env, tdf, twd, tws);
27796        break;
27797    case OPC_FTINT_U_df:
27798        gen_helper_msa_ftint_u_df(cpu_env, tdf, twd, tws);
27799        break;
27800    case OPC_FFINT_S_df:
27801        gen_helper_msa_ffint_s_df(cpu_env, tdf, twd, tws);
27802        break;
27803    case OPC_FFINT_U_df:
27804        gen_helper_msa_ffint_u_df(cpu_env, tdf, twd, tws);
27805        break;
27806    }
27807
27808    tcg_temp_free_i32(twd);
27809    tcg_temp_free_i32(tws);
27810    tcg_temp_free_i32(twt);
27811    tcg_temp_free_i32(tdf);
27812}
27813
27814static void gen_msa_vec_v(CPUMIPSState *env, DisasContext *ctx)
27815{
27816#define MASK_MSA_VEC(op)    (MASK_MSA_MINOR(op) | (op & (0x1f << 21)))
27817    uint8_t wt = (ctx->opcode >> 16) & 0x1f;
27818    uint8_t ws = (ctx->opcode >> 11) & 0x1f;
27819    uint8_t wd = (ctx->opcode >> 6) & 0x1f;
27820    TCGv_i32 twd = tcg_const_i32(wd);
27821    TCGv_i32 tws = tcg_const_i32(ws);
27822    TCGv_i32 twt = tcg_const_i32(wt);
27823
27824    switch (MASK_MSA_VEC(ctx->opcode)) {
27825    case OPC_AND_V:
27826        gen_helper_msa_and_v(cpu_env, twd, tws, twt);
27827        break;
27828    case OPC_OR_V:
27829        gen_helper_msa_or_v(cpu_env, twd, tws, twt);
27830        break;
27831    case OPC_NOR_V:
27832        gen_helper_msa_nor_v(cpu_env, twd, tws, twt);
27833        break;
27834    case OPC_XOR_V:
27835        gen_helper_msa_xor_v(cpu_env, twd, tws, twt);
27836        break;
27837    case OPC_BMNZ_V:
27838        gen_helper_msa_bmnz_v(cpu_env, twd, tws, twt);
27839        break;
27840    case OPC_BMZ_V:
27841        gen_helper_msa_bmz_v(cpu_env, twd, tws, twt);
27842        break;
27843    case OPC_BSEL_V:
27844        gen_helper_msa_bsel_v(cpu_env, twd, tws, twt);
27845        break;
27846    default:
27847        MIPS_INVAL("MSA instruction");
27848        generate_exception_end(ctx, EXCP_RI);
27849        break;
27850    }
27851
27852    tcg_temp_free_i32(twd);
27853    tcg_temp_free_i32(tws);
27854    tcg_temp_free_i32(twt);
27855}
27856
27857static void gen_msa_vec(CPUMIPSState *env, DisasContext *ctx)
27858{
27859    switch (MASK_MSA_VEC(ctx->opcode)) {
27860    case OPC_AND_V:
27861    case OPC_OR_V:
27862    case OPC_NOR_V:
27863    case OPC_XOR_V:
27864    case OPC_BMNZ_V:
27865    case OPC_BMZ_V:
27866    case OPC_BSEL_V:
27867        gen_msa_vec_v(env, ctx);
27868        break;
27869    case OPC_MSA_2R:
27870        gen_msa_2r(env, ctx);
27871        break;
27872    case OPC_MSA_2RF:
27873        gen_msa_2rf(env, ctx);
27874        break;
27875    default:
27876        MIPS_INVAL("MSA instruction");
27877        generate_exception_end(ctx, EXCP_RI);
27878        break;
27879    }
27880}
27881
27882static void gen_msa(CPUMIPSState *env, DisasContext *ctx)
27883{
27884    uint32_t opcode = ctx->opcode;
27885    check_insn(ctx, ASE_MSA);
27886    check_msa_access(ctx);
27887
27888    switch (MASK_MSA_MINOR(opcode)) {
27889    case OPC_MSA_I8_00:
27890    case OPC_MSA_I8_01:
27891    case OPC_MSA_I8_02:
27892        gen_msa_i8(env, ctx);
27893        break;
27894    case OPC_MSA_I5_06:
27895    case OPC_MSA_I5_07:
27896        gen_msa_i5(env, ctx);
27897        break;
27898    case OPC_MSA_BIT_09:
27899    case OPC_MSA_BIT_0A:
27900        gen_msa_bit(env, ctx);
27901        break;
27902    case OPC_MSA_3R_0D:
27903    case OPC_MSA_3R_0E:
27904    case OPC_MSA_3R_0F:
27905    case OPC_MSA_3R_10:
27906    case OPC_MSA_3R_11:
27907    case OPC_MSA_3R_12:
27908    case OPC_MSA_3R_13:
27909    case OPC_MSA_3R_14:
27910    case OPC_MSA_3R_15:
27911        gen_msa_3r(env, ctx);
27912        break;
27913    case OPC_MSA_ELM:
27914        gen_msa_elm(env, ctx);
27915        break;
27916    case OPC_MSA_3RF_1A:
27917    case OPC_MSA_3RF_1B:
27918    case OPC_MSA_3RF_1C:
27919        gen_msa_3rf(env, ctx);
27920        break;
27921    case OPC_MSA_VEC:
27922        gen_msa_vec(env, ctx);
27923        break;
27924    case OPC_LD_B:
27925    case OPC_LD_H:
27926    case OPC_LD_W:
27927    case OPC_LD_D:
27928    case OPC_ST_B:
27929    case OPC_ST_H:
27930    case OPC_ST_W:
27931    case OPC_ST_D:
27932        {
27933            int32_t s10 = sextract32(ctx->opcode, 16, 10);
27934            uint8_t rs = (ctx->opcode >> 11) & 0x1f;
27935            uint8_t wd = (ctx->opcode >> 6) & 0x1f;
27936            uint8_t df = (ctx->opcode >> 0) & 0x3;
27937
27938            TCGv_i32 twd = tcg_const_i32(wd);
27939            TCGv taddr = tcg_temp_new();
27940            gen_base_offset_addr(ctx, taddr, rs, s10 << df);
27941
27942            switch (MASK_MSA_MINOR(opcode)) {
27943            case OPC_LD_B:
27944                gen_helper_msa_ld_b(cpu_env, twd, taddr);
27945                break;
27946            case OPC_LD_H:
27947                gen_helper_msa_ld_h(cpu_env, twd, taddr);
27948                break;
27949            case OPC_LD_W:
27950                gen_helper_msa_ld_w(cpu_env, twd, taddr);
27951                break;
27952            case OPC_LD_D:
27953                gen_helper_msa_ld_d(cpu_env, twd, taddr);
27954                break;
27955            case OPC_ST_B:
27956                gen_helper_msa_st_b(cpu_env, twd, taddr);
27957                break;
27958            case OPC_ST_H:
27959                gen_helper_msa_st_h(cpu_env, twd, taddr);
27960                break;
27961            case OPC_ST_W:
27962                gen_helper_msa_st_w(cpu_env, twd, taddr);
27963                break;
27964            case OPC_ST_D:
27965                gen_helper_msa_st_d(cpu_env, twd, taddr);
27966                break;
27967            }
27968
27969            tcg_temp_free_i32(twd);
27970            tcg_temp_free(taddr);
27971        }
27972        break;
27973    default:
27974        MIPS_INVAL("MSA instruction");
27975        generate_exception_end(ctx, EXCP_RI);
27976        break;
27977    }
27978
27979}
27980
27981static void decode_opc(CPUMIPSState *env, DisasContext *ctx)
27982{
27983    int32_t offset;
27984    int rs, rt, rd, sa;
27985    uint32_t op, op1;
27986    int16_t imm;
27987
27988    /* make sure instructions are on a word boundary */
27989    if (ctx->base.pc_next & 0x3) {
27990        env->CP0_BadVAddr = ctx->base.pc_next;
27991        generate_exception_err(ctx, EXCP_AdEL, EXCP_INST_NOTAVAIL);
27992        return;
27993    }
27994
27995    /* Handle blikely not taken case */
27996    if ((ctx->hflags & MIPS_HFLAG_BMASK_BASE) == MIPS_HFLAG_BL) {
27997        TCGLabel *l1 = gen_new_label();
27998
27999        tcg_gen_brcondi_tl(TCG_COND_NE, bcond, 0, l1);
28000        tcg_gen_movi_i32(hflags, ctx->hflags & ~MIPS_HFLAG_BMASK);
28001        gen_goto_tb(ctx, 1, ctx->base.pc_next + 4);
28002        gen_set_label(l1);
28003    }
28004
28005    op = MASK_OP_MAJOR(ctx->opcode);
28006    rs = (ctx->opcode >> 21) & 0x1f;
28007    rt = (ctx->opcode >> 16) & 0x1f;
28008    rd = (ctx->opcode >> 11) & 0x1f;
28009    sa = (ctx->opcode >> 6) & 0x1f;
28010    imm = (int16_t)ctx->opcode;
28011    switch (op) {
28012    case OPC_SPECIAL:
28013        decode_opc_special(env, ctx);
28014        break;
28015    case OPC_SPECIAL2:
28016        if ((ctx->insn_flags & INSN_R5900) && (ctx->insn_flags & ASE_MMI)) {
28017            decode_mmi(env, ctx);
28018        } else if (ctx->insn_flags & ASE_MXU) {
28019            decode_opc_mxu(env, ctx);
28020        } else {
28021            decode_opc_special2_legacy(env, ctx);
28022        }
28023        break;
28024    case OPC_SPECIAL3:
28025        if (ctx->insn_flags & INSN_R5900) {
28026            decode_mmi_sq(env, ctx);    /* MMI_OPC_SQ */
28027        } else {
28028            decode_opc_special3(env, ctx);
28029        }
28030        break;
28031    case OPC_REGIMM:
28032        op1 = MASK_REGIMM(ctx->opcode);
28033        switch (op1) {
28034        case OPC_BLTZL: /* REGIMM branches */
28035        case OPC_BGEZL:
28036        case OPC_BLTZALL:
28037        case OPC_BGEZALL:
28038            check_insn(ctx, ISA_MIPS2);
28039            check_insn_opc_removed(ctx, ISA_MIPS32R6);
28040            /* Fallthrough */
28041        case OPC_BLTZ:
28042        case OPC_BGEZ:
28043            gen_compute_branch(ctx, op1, 4, rs, -1, imm << 2, 4);
28044            break;
28045        case OPC_BLTZAL:
28046        case OPC_BGEZAL:
28047            if (ctx->insn_flags & ISA_MIPS32R6) {
28048                if (rs == 0) {
28049                    /* OPC_NAL, OPC_BAL */
28050                    gen_compute_branch(ctx, op1, 4, 0, -1, imm << 2, 4);
28051                } else {
28052                    generate_exception_end(ctx, EXCP_RI);
28053                }
28054            } else {
28055                gen_compute_branch(ctx, op1, 4, rs, -1, imm << 2, 4);
28056            }
28057            break;
28058        case OPC_TGEI: /* REGIMM traps */
28059        case OPC_TGEIU:
28060        case OPC_TLTI:
28061        case OPC_TLTIU:
28062        case OPC_TEQI:
28063
28064        case OPC_TNEI:
28065            check_insn(ctx, ISA_MIPS2);
28066            check_insn_opc_removed(ctx, ISA_MIPS32R6);
28067            gen_trap(ctx, op1, rs, -1, imm);
28068            break;
28069        case OPC_SIGRIE:
28070            check_insn(ctx, ISA_MIPS32R6);
28071            generate_exception_end(ctx, EXCP_RI);
28072            break;
28073        case OPC_SYNCI:
28074            check_insn(ctx, ISA_MIPS32R2);
28075            /* Break the TB to be able to sync copied instructions
28076               immediately */
28077            ctx->base.is_jmp = DISAS_STOP;
28078            break;
28079        case OPC_BPOSGE32:    /* MIPS DSP branch */
28080#if defined(TARGET_MIPS64)
28081        case OPC_BPOSGE64:
28082#endif
28083            check_dsp(ctx);
28084            gen_compute_branch(ctx, op1, 4, -1, -2, (int32_t)imm << 2, 4);
28085            break;
28086#if defined(TARGET_MIPS64)
28087        case OPC_DAHI:
28088            check_insn(ctx, ISA_MIPS32R6);
28089            check_mips_64(ctx);
28090            if (rs != 0) {
28091                tcg_gen_addi_tl(cpu_gpr[rs], cpu_gpr[rs], (int64_t)imm << 32);
28092            }
28093            break;
28094        case OPC_DATI:
28095            check_insn(ctx, ISA_MIPS32R6);
28096            check_mips_64(ctx);
28097            if (rs != 0) {
28098                tcg_gen_addi_tl(cpu_gpr[rs], cpu_gpr[rs], (int64_t)imm << 48);
28099            }
28100            break;
28101#endif
28102        default:            /* Invalid */
28103            MIPS_INVAL("regimm");
28104            generate_exception_end(ctx, EXCP_RI);
28105            break;
28106        }
28107        break;
28108    case OPC_CP0:
28109        check_cp0_enabled(ctx);
28110        op1 = MASK_CP0(ctx->opcode);
28111        switch (op1) {
28112        case OPC_MFC0:
28113        case OPC_MTC0:
28114        case OPC_MFTR:
28115        case OPC_MTTR:
28116        case OPC_MFHC0:
28117        case OPC_MTHC0:
28118#if defined(TARGET_MIPS64)
28119        case OPC_DMFC0:
28120        case OPC_DMTC0:
28121#endif
28122#ifndef CONFIG_USER_ONLY
28123            gen_cp0(env, ctx, op1, rt, rd);
28124#endif /* !CONFIG_USER_ONLY */
28125            break;
28126        case OPC_C0:
28127        case OPC_C0_1:
28128        case OPC_C0_2:
28129        case OPC_C0_3:
28130        case OPC_C0_4:
28131        case OPC_C0_5:
28132        case OPC_C0_6:
28133        case OPC_C0_7:
28134        case OPC_C0_8:
28135        case OPC_C0_9:
28136        case OPC_C0_A:
28137        case OPC_C0_B:
28138        case OPC_C0_C:
28139        case OPC_C0_D:
28140        case OPC_C0_E:
28141        case OPC_C0_F:
28142#ifndef CONFIG_USER_ONLY
28143            gen_cp0(env, ctx, MASK_C0(ctx->opcode), rt, rd);
28144#endif /* !CONFIG_USER_ONLY */
28145            break;
28146        case OPC_MFMC0:
28147#ifndef CONFIG_USER_ONLY
28148            {
28149                uint32_t op2;
28150                TCGv t0 = tcg_temp_new();
28151
28152                op2 = MASK_MFMC0(ctx->opcode);
28153                switch (op2) {
28154                case OPC_DMT:
28155                    check_cp0_mt(ctx);
28156                    gen_helper_dmt(t0);
28157                    gen_store_gpr(t0, rt);
28158                    break;
28159                case OPC_EMT:
28160                    check_cp0_mt(ctx);
28161                    gen_helper_emt(t0);
28162                    gen_store_gpr(t0, rt);
28163                    break;
28164                case OPC_DVPE:
28165                    check_cp0_mt(ctx);
28166                    gen_helper_dvpe(t0, cpu_env);
28167                    gen_store_gpr(t0, rt);
28168                    break;
28169                case OPC_EVPE:
28170                    check_cp0_mt(ctx);
28171                    gen_helper_evpe(t0, cpu_env);
28172                    gen_store_gpr(t0, rt);
28173                    break;
28174                case OPC_DVP:
28175                    check_insn(ctx, ISA_MIPS32R6);
28176                    if (ctx->vp) {
28177                        gen_helper_dvp(t0, cpu_env);
28178                        gen_store_gpr(t0, rt);
28179                    }
28180                    break;
28181                case OPC_EVP:
28182                    check_insn(ctx, ISA_MIPS32R6);
28183                    if (ctx->vp) {
28184                        gen_helper_evp(t0, cpu_env);
28185                        gen_store_gpr(t0, rt);
28186                    }
28187                    break;
28188                case OPC_DI:
28189                    check_insn(ctx, ISA_MIPS32R2);
28190                    save_cpu_state(ctx, 1);
28191                    gen_helper_di(t0, cpu_env);
28192                    gen_store_gpr(t0, rt);
28193                    /* Stop translation as we may have switched
28194                       the execution mode.  */
28195                    ctx->base.is_jmp = DISAS_STOP;
28196                    break;
28197                case OPC_EI:
28198                    check_insn(ctx, ISA_MIPS32R2);
28199                    save_cpu_state(ctx, 1);
28200                    gen_helper_ei(t0, cpu_env);
28201                    gen_store_gpr(t0, rt);
28202                    /* DISAS_STOP isn't sufficient, we need to ensure we break
28203                       out of translated code to check for pending interrupts */
28204                    gen_save_pc(ctx->base.pc_next + 4);
28205                    ctx->base.is_jmp = DISAS_EXIT;
28206                    break;
28207                default:            /* Invalid */
28208                    MIPS_INVAL("mfmc0");
28209                    generate_exception_end(ctx, EXCP_RI);
28210                    break;
28211                }
28212                tcg_temp_free(t0);
28213            }
28214#endif /* !CONFIG_USER_ONLY */
28215            break;
28216        case OPC_RDPGPR:
28217            check_insn(ctx, ISA_MIPS32R2);
28218            gen_load_srsgpr(rt, rd);
28219            break;
28220        case OPC_WRPGPR:
28221            check_insn(ctx, ISA_MIPS32R2);
28222            gen_store_srsgpr(rt, rd);
28223            break;
28224        default:
28225            MIPS_INVAL("cp0");
28226            generate_exception_end(ctx, EXCP_RI);
28227            break;
28228        }
28229        break;
28230    case OPC_BOVC: /* OPC_BEQZALC, OPC_BEQC, OPC_ADDI */
28231        if (ctx->insn_flags & ISA_MIPS32R6) {
28232            /* OPC_BOVC, OPC_BEQZALC, OPC_BEQC */
28233            gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
28234        } else {
28235            /* OPC_ADDI */
28236            /* Arithmetic with immediate opcode */
28237            gen_arith_imm(ctx, op, rt, rs, imm);
28238        }
28239        break;
28240    case OPC_ADDIU:
28241         gen_arith_imm(ctx, op, rt, rs, imm);
28242         break;
28243    case OPC_SLTI: /* Set on less than with immediate opcode */
28244    case OPC_SLTIU:
28245         gen_slt_imm(ctx, op, rt, rs, imm);
28246         break;
28247    case OPC_ANDI: /* Arithmetic with immediate opcode */
28248    case OPC_LUI: /* OPC_AUI */
28249    case OPC_ORI:
28250    case OPC_XORI:
28251         gen_logic_imm(ctx, op, rt, rs, imm);
28252         break;
28253    case OPC_J: /* Jump */
28254    case OPC_JAL:
28255         offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 2;
28256         gen_compute_branch(ctx, op, 4, rs, rt, offset, 4);
28257         break;
28258    /* Branch */
28259    case OPC_BLEZC: /* OPC_BGEZC, OPC_BGEC, OPC_BLEZL */
28260        if (ctx->insn_flags & ISA_MIPS32R6) {
28261            if (rt == 0) {
28262                generate_exception_end(ctx, EXCP_RI);
28263                break;
28264            }
28265            /* OPC_BLEZC, OPC_BGEZC, OPC_BGEC */
28266            gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
28267        } else {
28268            /* OPC_BLEZL */
28269            gen_compute_branch(ctx, op, 4, rs, rt, imm << 2, 4);
28270        }
28271        break;
28272    case OPC_BGTZC: /* OPC_BLTZC, OPC_BLTC, OPC_BGTZL */
28273        if (ctx->insn_flags & ISA_MIPS32R6) {
28274            if (rt == 0) {
28275                generate_exception_end(ctx, EXCP_RI);
28276                break;
28277            }
28278            /* OPC_BGTZC, OPC_BLTZC, OPC_BLTC */
28279            gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
28280        } else {
28281            /* OPC_BGTZL */
28282            gen_compute_branch(ctx, op, 4, rs, rt, imm << 2, 4);
28283        }
28284        break;
28285    case OPC_BLEZALC: /* OPC_BGEZALC, OPC_BGEUC, OPC_BLEZ */
28286        if (rt == 0) {
28287            /* OPC_BLEZ */
28288            gen_compute_branch(ctx, op, 4, rs, rt, imm << 2, 4);
28289        } else {
28290            check_insn(ctx, ISA_MIPS32R6);
28291            /* OPC_BLEZALC, OPC_BGEZALC, OPC_BGEUC */
28292            gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
28293        }
28294        break;
28295    case OPC_BGTZALC: /* OPC_BLTZALC, OPC_BLTUC, OPC_BGTZ */
28296        if (rt == 0) {
28297            /* OPC_BGTZ */
28298            gen_compute_branch(ctx, op, 4, rs, rt, imm << 2, 4);
28299        } else {
28300            check_insn(ctx, ISA_MIPS32R6);
28301            /* OPC_BGTZALC, OPC_BLTZALC, OPC_BLTUC */
28302            gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
28303        }
28304        break;
28305    case OPC_BEQL:
28306    case OPC_BNEL:
28307        check_insn(ctx, ISA_MIPS2);
28308         check_insn_opc_removed(ctx, ISA_MIPS32R6);
28309        /* Fallthrough */
28310    case OPC_BEQ:
28311    case OPC_BNE:
28312         gen_compute_branch(ctx, op, 4, rs, rt, imm << 2, 4);
28313         break;
28314    case OPC_LL: /* Load and stores */
28315        check_insn(ctx, ISA_MIPS2);
28316        if (ctx->insn_flags & INSN_R5900) {
28317            check_insn_opc_user_only(ctx, INSN_R5900);
28318        }
28319        /* Fallthrough */
28320    case OPC_LWL:
28321    case OPC_LWR:
28322        check_insn_opc_removed(ctx, ISA_MIPS32R6);
28323         /* Fallthrough */
28324    case OPC_LB:
28325    case OPC_LH:
28326    case OPC_LW:
28327    case OPC_LWPC:
28328    case OPC_LBU:
28329    case OPC_LHU:
28330         gen_ld(ctx, op, rt, rs, imm);
28331         break;
28332    case OPC_SWL:
28333    case OPC_SWR:
28334        check_insn_opc_removed(ctx, ISA_MIPS32R6);
28335        /* fall through */
28336    case OPC_SB:
28337    case OPC_SH:
28338    case OPC_SW:
28339         gen_st(ctx, op, rt, rs, imm);
28340         break;
28341    case OPC_SC:
28342        check_insn(ctx, ISA_MIPS2);
28343         check_insn_opc_removed(ctx, ISA_MIPS32R6);
28344        if (ctx->insn_flags & INSN_R5900) {
28345            check_insn_opc_user_only(ctx, INSN_R5900);
28346        }
28347         gen_st_cond(ctx, op, rt, rs, imm);
28348         break;
28349    case OPC_CACHE:
28350        check_insn_opc_removed(ctx, ISA_MIPS32R6);
28351        check_cp0_enabled(ctx);
28352        check_insn(ctx, ISA_MIPS3 | ISA_MIPS32);
28353        if (ctx->hflags & MIPS_HFLAG_ITC_CACHE) {
28354            gen_cache_operation(ctx, rt, rs, imm);
28355        }
28356        /* Treat as NOP. */
28357        break;
28358    case OPC_PREF:
28359        check_insn_opc_removed(ctx, ISA_MIPS32R6);
28360        if (ctx->insn_flags & INSN_R5900) {
28361            /* Treat as NOP. */
28362        } else {
28363            check_insn(ctx, ISA_MIPS4 | ISA_MIPS32);
28364            /* Treat as NOP. */
28365        }
28366        break;
28367
28368    /* Floating point (COP1). */
28369    case OPC_LWC1:
28370    case OPC_LDC1:
28371    case OPC_SWC1:
28372    case OPC_SDC1:
28373        gen_cop1_ldst(ctx, op, rt, rs, imm);
28374        break;
28375
28376    case OPC_CP1:
28377        op1 = MASK_CP1(ctx->opcode);
28378
28379        switch (op1) {
28380        case OPC_MFHC1:
28381        case OPC_MTHC1:
28382            check_cp1_enabled(ctx);
28383            check_insn(ctx, ISA_MIPS32R2);
28384            /* fall through */
28385        case OPC_MFC1:
28386        case OPC_CFC1:
28387        case OPC_MTC1:
28388        case OPC_CTC1:
28389            check_cp1_enabled(ctx);
28390            gen_cp1(ctx, op1, rt, rd);
28391            break;
28392#if defined(TARGET_MIPS64)
28393        case OPC_DMFC1:
28394        case OPC_DMTC1:
28395            check_cp1_enabled(ctx);
28396            check_insn(ctx, ISA_MIPS3);
28397            check_mips_64(ctx);
28398            gen_cp1(ctx, op1, rt, rd);
28399            break;
28400#endif
28401        case OPC_BC1EQZ: /* OPC_BC1ANY2 */
28402            check_cp1_enabled(ctx);
28403            if (ctx->insn_flags & ISA_MIPS32R6) {
28404                /* OPC_BC1EQZ */
28405                gen_compute_branch1_r6(ctx, MASK_CP1(ctx->opcode),
28406                                       rt, imm << 2, 4);
28407            } else {
28408                /* OPC_BC1ANY2 */
28409                check_cop1x(ctx);
28410                check_insn(ctx, ASE_MIPS3D);
28411                gen_compute_branch1(ctx, MASK_BC1(ctx->opcode),
28412                                    (rt >> 2) & 0x7, imm << 2);
28413            }
28414            break;
28415        case OPC_BC1NEZ:
28416            check_cp1_enabled(ctx);
28417            check_insn(ctx, ISA_MIPS32R6);
28418            gen_compute_branch1_r6(ctx, MASK_CP1(ctx->opcode),
28419                                   rt, imm << 2, 4);
28420            break;
28421        case OPC_BC1ANY4:
28422            check_cp1_enabled(ctx);
28423            check_insn_opc_removed(ctx, ISA_MIPS32R6);
28424            check_cop1x(ctx);
28425            check_insn(ctx, ASE_MIPS3D);
28426            /* fall through */
28427        case OPC_BC1:
28428            check_cp1_enabled(ctx);
28429            check_insn_opc_removed(ctx, ISA_MIPS32R6);
28430            gen_compute_branch1(ctx, MASK_BC1(ctx->opcode),
28431                                (rt >> 2) & 0x7, imm << 2);
28432            break;
28433        case OPC_PS_FMT:
28434            check_ps(ctx);
28435            /* fall through */
28436        case OPC_S_FMT:
28437        case OPC_D_FMT:
28438            check_cp1_enabled(ctx);
28439            gen_farith(ctx, ctx->opcode & FOP(0x3f, 0x1f), rt, rd, sa,
28440                       (imm >> 8) & 0x7);
28441            break;
28442        case OPC_W_FMT:
28443        case OPC_L_FMT:
28444        {
28445            int r6_op = ctx->opcode & FOP(0x3f, 0x1f);
28446            check_cp1_enabled(ctx);
28447            if (ctx->insn_flags & ISA_MIPS32R6) {
28448                switch (r6_op) {
28449                case R6_OPC_CMP_AF_S:
28450                case R6_OPC_CMP_UN_S:
28451                case R6_OPC_CMP_EQ_S:
28452                case R6_OPC_CMP_UEQ_S:
28453                case R6_OPC_CMP_LT_S:
28454                case R6_OPC_CMP_ULT_S:
28455                case R6_OPC_CMP_LE_S:
28456                case R6_OPC_CMP_ULE_S:
28457                case R6_OPC_CMP_SAF_S:
28458                case R6_OPC_CMP_SUN_S:
28459                case R6_OPC_CMP_SEQ_S:
28460                case R6_OPC_CMP_SEUQ_S:
28461                case R6_OPC_CMP_SLT_S:
28462                case R6_OPC_CMP_SULT_S:
28463                case R6_OPC_CMP_SLE_S:
28464                case R6_OPC_CMP_SULE_S:
28465                case R6_OPC_CMP_OR_S:
28466                case R6_OPC_CMP_UNE_S:
28467                case R6_OPC_CMP_NE_S:
28468                case R6_OPC_CMP_SOR_S:
28469                case R6_OPC_CMP_SUNE_S:
28470                case R6_OPC_CMP_SNE_S:
28471                    gen_r6_cmp_s(ctx, ctx->opcode & 0x1f, rt, rd, sa);
28472                    break;
28473                case R6_OPC_CMP_AF_D:
28474                case R6_OPC_CMP_UN_D:
28475                case R6_OPC_CMP_EQ_D:
28476                case R6_OPC_CMP_UEQ_D:
28477                case R6_OPC_CMP_LT_D:
28478                case R6_OPC_CMP_ULT_D:
28479                case R6_OPC_CMP_LE_D:
28480                case R6_OPC_CMP_ULE_D:
28481                case R6_OPC_CMP_SAF_D:
28482                case R6_OPC_CMP_SUN_D:
28483                case R6_OPC_CMP_SEQ_D:
28484                case R6_OPC_CMP_SEUQ_D:
28485                case R6_OPC_CMP_SLT_D:
28486                case R6_OPC_CMP_SULT_D:
28487                case R6_OPC_CMP_SLE_D:
28488                case R6_OPC_CMP_SULE_D:
28489                case R6_OPC_CMP_OR_D:
28490                case R6_OPC_CMP_UNE_D:
28491                case R6_OPC_CMP_NE_D:
28492                case R6_OPC_CMP_SOR_D:
28493                case R6_OPC_CMP_SUNE_D:
28494                case R6_OPC_CMP_SNE_D:
28495                    gen_r6_cmp_d(ctx, ctx->opcode & 0x1f, rt, rd, sa);
28496                    break;
28497                default:
28498                    gen_farith(ctx, ctx->opcode & FOP(0x3f, 0x1f),
28499                               rt, rd, sa, (imm >> 8) & 0x7);
28500
28501                    break;
28502                }
28503            } else {
28504                gen_farith(ctx, ctx->opcode & FOP(0x3f, 0x1f), rt, rd, sa,
28505                           (imm >> 8) & 0x7);
28506            }
28507            break;
28508        }
28509        case OPC_BZ_V:
28510        case OPC_BNZ_V:
28511        case OPC_BZ_B:
28512        case OPC_BZ_H:
28513        case OPC_BZ_W:
28514        case OPC_BZ_D:
28515        case OPC_BNZ_B:
28516        case OPC_BNZ_H:
28517        case OPC_BNZ_W:
28518        case OPC_BNZ_D:
28519            check_insn(ctx, ASE_MSA);
28520            gen_msa_branch(env, ctx, op1);
28521            break;
28522        default:
28523            MIPS_INVAL("cp1");
28524            generate_exception_end(ctx, EXCP_RI);
28525            break;
28526        }
28527        break;
28528
28529    /* Compact branches [R6] and COP2 [non-R6] */
28530    case OPC_BC: /* OPC_LWC2 */
28531    case OPC_BALC: /* OPC_SWC2 */
28532        if (ctx->insn_flags & ISA_MIPS32R6) {
28533            /* OPC_BC, OPC_BALC */
28534            gen_compute_compact_branch(ctx, op, 0, 0,
28535                                       sextract32(ctx->opcode << 2, 0, 28));
28536        } else {
28537            /* OPC_LWC2, OPC_SWC2 */
28538            /* COP2: Not implemented. */
28539            generate_exception_err(ctx, EXCP_CpU, 2);
28540        }
28541        break;
28542    case OPC_BEQZC: /* OPC_JIC, OPC_LDC2 */
28543    case OPC_BNEZC: /* OPC_JIALC, OPC_SDC2 */
28544        if (ctx->insn_flags & ISA_MIPS32R6) {
28545            if (rs != 0) {
28546                /* OPC_BEQZC, OPC_BNEZC */
28547                gen_compute_compact_branch(ctx, op, rs, 0,
28548                                           sextract32(ctx->opcode << 2, 0, 23));
28549            } else {
28550                /* OPC_JIC, OPC_JIALC */
28551                gen_compute_compact_branch(ctx, op, 0, rt, imm);
28552            }
28553        } else {
28554            /* OPC_LWC2, OPC_SWC2 */
28555            /* COP2: Not implemented. */
28556            generate_exception_err(ctx, EXCP_CpU, 2);
28557        }
28558        break;
28559    case OPC_CP2:
28560        check_insn(ctx, INSN_LOONGSON2F);
28561        /* Note that these instructions use different fields.  */
28562        gen_loongson_multimedia(ctx, sa, rd, rt);
28563        break;
28564
28565    case OPC_CP3:
28566        check_insn_opc_removed(ctx, ISA_MIPS32R6);
28567        if (ctx->CP0_Config1 & (1 << CP0C1_FP)) {
28568            check_cp1_enabled(ctx);
28569            op1 = MASK_CP3(ctx->opcode);
28570            switch (op1) {
28571            case OPC_LUXC1:
28572            case OPC_SUXC1:
28573                check_insn(ctx, ISA_MIPS5 | ISA_MIPS32R2);
28574                /* Fallthrough */
28575            case OPC_LWXC1:
28576            case OPC_LDXC1:
28577            case OPC_SWXC1:
28578            case OPC_SDXC1:
28579                check_insn(ctx, ISA_MIPS4 | ISA_MIPS32R2);
28580                gen_flt3_ldst(ctx, op1, sa, rd, rs, rt);
28581                break;
28582            case OPC_PREFX:
28583                check_insn(ctx, ISA_MIPS4 | ISA_MIPS32R2);
28584                /* Treat as NOP. */
28585                break;
28586            case OPC_ALNV_PS:
28587                check_insn(ctx, ISA_MIPS5 | ISA_MIPS32R2);
28588                /* Fallthrough */
28589            case OPC_MADD_S:
28590            case OPC_MADD_D:
28591            case OPC_MADD_PS:
28592            case OPC_MSUB_S:
28593            case OPC_MSUB_D:
28594            case OPC_MSUB_PS:
28595            case OPC_NMADD_S:
28596            case OPC_NMADD_D:
28597            case OPC_NMADD_PS:
28598            case OPC_NMSUB_S:
28599            case OPC_NMSUB_D:
28600            case OPC_NMSUB_PS:
28601                check_insn(ctx, ISA_MIPS4 | ISA_MIPS32R2);
28602                gen_flt3_arith(ctx, op1, sa, rs, rd, rt);
28603                break;
28604            default:
28605                MIPS_INVAL("cp3");
28606                generate_exception_end(ctx, EXCP_RI);
28607                break;
28608            }
28609        } else {
28610            generate_exception_err(ctx, EXCP_CpU, 1);
28611        }
28612        break;
28613
28614#if defined(TARGET_MIPS64)
28615    /* MIPS64 opcodes */
28616    case OPC_LLD:
28617        if (ctx->insn_flags & INSN_R5900) {
28618            check_insn_opc_user_only(ctx, INSN_R5900);
28619        }
28620        /* fall through */
28621    case OPC_LDL:
28622    case OPC_LDR:
28623        check_insn_opc_removed(ctx, ISA_MIPS32R6);
28624        /* fall through */
28625    case OPC_LWU:
28626    case OPC_LD:
28627        check_insn(ctx, ISA_MIPS3);
28628        check_mips_64(ctx);
28629        gen_ld(ctx, op, rt, rs, imm);
28630        break;
28631    case OPC_SDL:
28632    case OPC_SDR:
28633        check_insn_opc_removed(ctx, ISA_MIPS32R6);
28634        /* fall through */
28635    case OPC_SD:
28636        check_insn(ctx, ISA_MIPS3);
28637        check_mips_64(ctx);
28638        gen_st(ctx, op, rt, rs, imm);
28639        break;
28640    case OPC_SCD:
28641        check_insn_opc_removed(ctx, ISA_MIPS32R6);
28642        check_insn(ctx, ISA_MIPS3);
28643        if (ctx->insn_flags & INSN_R5900) {
28644            check_insn_opc_user_only(ctx, INSN_R5900);
28645        }
28646        check_mips_64(ctx);
28647        gen_st_cond(ctx, op, rt, rs, imm);
28648        break;
28649    case OPC_BNVC: /* OPC_BNEZALC, OPC_BNEC, OPC_DADDI */
28650        if (ctx->insn_flags & ISA_MIPS32R6) {
28651            /* OPC_BNVC, OPC_BNEZALC, OPC_BNEC */
28652            gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
28653        } else {
28654            /* OPC_DADDI */
28655            check_insn(ctx, ISA_MIPS3);
28656            check_mips_64(ctx);
28657            gen_arith_imm(ctx, op, rt, rs, imm);
28658        }
28659        break;
28660    case OPC_DADDIU:
28661        check_insn(ctx, ISA_MIPS3);
28662        check_mips_64(ctx);
28663        gen_arith_imm(ctx, op, rt, rs, imm);
28664        break;
28665#else
28666    case OPC_BNVC: /* OPC_BNEZALC, OPC_BNEC */
28667        if (ctx->insn_flags & ISA_MIPS32R6) {
28668            gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
28669        } else {
28670            MIPS_INVAL("major opcode");
28671            generate_exception_end(ctx, EXCP_RI);
28672        }
28673        break;
28674#endif
28675    case OPC_DAUI: /* OPC_JALX */
28676        if (ctx->insn_flags & ISA_MIPS32R6) {
28677#if defined(TARGET_MIPS64)
28678            /* OPC_DAUI */
28679            check_mips_64(ctx);
28680            if (rs == 0) {
28681                generate_exception(ctx, EXCP_RI);
28682            } else if (rt != 0) {
28683                TCGv t0 = tcg_temp_new();
28684                gen_load_gpr(t0, rs);
28685                tcg_gen_addi_tl(cpu_gpr[rt], t0, imm << 16);
28686                tcg_temp_free(t0);
28687            }
28688#else
28689            generate_exception_end(ctx, EXCP_RI);
28690            MIPS_INVAL("major opcode");
28691#endif
28692        } else {
28693            /* OPC_JALX */
28694            check_insn(ctx, ASE_MIPS16 | ASE_MICROMIPS);
28695            offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 2;
28696            gen_compute_branch(ctx, op, 4, rs, rt, offset, 4);
28697        }
28698        break;
28699    case OPC_MSA: /* OPC_MDMX */
28700        if (ctx->insn_flags & INSN_R5900) {
28701            gen_mmi_lq(env, ctx);    /* MMI_OPC_LQ */
28702        } else {
28703            /* MDMX: Not implemented. */
28704            gen_msa(env, ctx);
28705        }
28706        break;
28707    case OPC_PCREL:
28708        check_insn(ctx, ISA_MIPS32R6);
28709        gen_pcrel(ctx, ctx->opcode, ctx->base.pc_next, rs);
28710        break;
28711    default:            /* Invalid */
28712        MIPS_INVAL("major opcode");
28713        generate_exception_end(ctx, EXCP_RI);
28714        break;
28715    }
28716}
28717
28718static void mips_tr_init_disas_context(DisasContextBase *dcbase, CPUState *cs)
28719{
28720    DisasContext *ctx = container_of(dcbase, DisasContext, base);
28721    CPUMIPSState *env = cs->env_ptr;
28722
28723    ctx->page_start = ctx->base.pc_first & TARGET_PAGE_MASK;
28724    ctx->saved_pc = -1;
28725    ctx->insn_flags = env->insn_flags;
28726    ctx->CP0_Config1 = env->CP0_Config1;
28727    ctx->CP0_Config2 = env->CP0_Config2;
28728    ctx->CP0_Config3 = env->CP0_Config3;
28729    ctx->CP0_Config5 = env->CP0_Config5;
28730    ctx->btarget = 0;
28731    ctx->kscrexist = (env->CP0_Config4 >> CP0C4_KScrExist) & 0xff;
28732    ctx->rxi = (env->CP0_Config3 >> CP0C3_RXI) & 1;
28733    ctx->ie = (env->CP0_Config4 >> CP0C4_IE) & 3;
28734    ctx->bi = (env->CP0_Config3 >> CP0C3_BI) & 1;
28735    ctx->bp = (env->CP0_Config3 >> CP0C3_BP) & 1;
28736    ctx->PAMask = env->PAMask;
28737    ctx->mvh = (env->CP0_Config5 >> CP0C5_MVH) & 1;
28738    ctx->eva = (env->CP0_Config5 >> CP0C5_EVA) & 1;
28739    ctx->sc = (env->CP0_Config3 >> CP0C3_SC) & 1;
28740    ctx->CP0_LLAddr_shift = env->CP0_LLAddr_shift;
28741    ctx->cmgcr = (env->CP0_Config3 >> CP0C3_CMGCR) & 1;
28742    /* Restore delay slot state from the tb context.  */
28743    ctx->hflags = (uint32_t)ctx->base.tb->flags; /* FIXME: maybe use 64 bits? */
28744    ctx->ulri = (env->CP0_Config3 >> CP0C3_ULRI) & 1;
28745    ctx->ps = ((env->active_fpu.fcr0 >> FCR0_PS) & 1) ||
28746             (env->insn_flags & (INSN_LOONGSON2E | INSN_LOONGSON2F));
28747    ctx->vp = (env->CP0_Config5 >> CP0C5_VP) & 1;
28748    ctx->mrp = (env->CP0_Config5 >> CP0C5_MRP) & 1;
28749    ctx->nan2008 = (env->active_fpu.fcr31 >> FCR31_NAN2008) & 1;
28750    ctx->abs2008 = (env->active_fpu.fcr31 >> FCR31_ABS2008) & 1;
28751    restore_cpu_state(env, ctx);
28752#ifdef CONFIG_USER_ONLY
28753        ctx->mem_idx = MIPS_HFLAG_UM;
28754#else
28755        ctx->mem_idx = hflags_mmu_index(ctx->hflags);
28756#endif
28757    ctx->default_tcg_memop_mask = (ctx->insn_flags & ISA_MIPS32R6) ?
28758                                  MO_UNALN : MO_ALIGN;
28759
28760    LOG_DISAS("\ntb %p idx %d hflags %04x\n", ctx->base.tb, ctx->mem_idx,
28761              ctx->hflags);
28762}
28763
28764static void mips_tr_tb_start(DisasContextBase *dcbase, CPUState *cs)
28765{
28766}
28767
28768static void mips_tr_insn_start(DisasContextBase *dcbase, CPUState *cs)
28769{
28770    DisasContext *ctx = container_of(dcbase, DisasContext, base);
28771
28772    tcg_gen_insn_start(ctx->base.pc_next, ctx->hflags & MIPS_HFLAG_BMASK,
28773                       ctx->btarget);
28774}
28775
28776static bool mips_tr_breakpoint_check(DisasContextBase *dcbase, CPUState *cs,
28777                                     const CPUBreakpoint *bp)
28778{
28779    DisasContext *ctx = container_of(dcbase, DisasContext, base);
28780
28781    save_cpu_state(ctx, 1);
28782    ctx->base.is_jmp = DISAS_NORETURN;
28783    gen_helper_raise_exception_debug(cpu_env);
28784    /* The address covered by the breakpoint must be included in
28785       [tb->pc, tb->pc + tb->size) in order to for it to be
28786       properly cleared -- thus we increment the PC here so that
28787       the logic setting tb->size below does the right thing.  */
28788    ctx->base.pc_next += 4;
28789    return true;
28790}
28791
28792static void mips_tr_translate_insn(DisasContextBase *dcbase, CPUState *cs)
28793{
28794    CPUMIPSState *env = cs->env_ptr;
28795    DisasContext *ctx = container_of(dcbase, DisasContext, base);
28796    int insn_bytes;
28797    int is_slot;
28798
28799    is_slot = ctx->hflags & MIPS_HFLAG_BMASK;
28800    if (ctx->insn_flags & ISA_NANOMIPS32) {
28801        ctx->opcode = cpu_lduw_code(env, ctx->base.pc_next);
28802        insn_bytes = decode_nanomips_opc(env, ctx);
28803    } else if (!(ctx->hflags & MIPS_HFLAG_M16)) {
28804        ctx->opcode = cpu_ldl_code(env, ctx->base.pc_next);
28805        insn_bytes = 4;
28806        decode_opc(env, ctx);
28807    } else if (ctx->insn_flags & ASE_MICROMIPS) {
28808        ctx->opcode = cpu_lduw_code(env, ctx->base.pc_next);
28809        insn_bytes = decode_micromips_opc(env, ctx);
28810    } else if (ctx->insn_flags & ASE_MIPS16) {
28811        ctx->opcode = cpu_lduw_code(env, ctx->base.pc_next);
28812        insn_bytes = decode_mips16_opc(env, ctx);
28813    } else {
28814        generate_exception_end(ctx, EXCP_RI);
28815        g_assert(ctx->base.is_jmp == DISAS_NORETURN);
28816        return;
28817    }
28818
28819    if (ctx->hflags & MIPS_HFLAG_BMASK) {
28820        if (!(ctx->hflags & (MIPS_HFLAG_BDS16 | MIPS_HFLAG_BDS32 |
28821                             MIPS_HFLAG_FBNSLOT))) {
28822            /* force to generate branch as there is neither delay nor
28823               forbidden slot */
28824            is_slot = 1;
28825        }
28826        if ((ctx->hflags & MIPS_HFLAG_M16) &&
28827            (ctx->hflags & MIPS_HFLAG_FBNSLOT)) {
28828            /* Force to generate branch as microMIPS R6 doesn't restrict
28829               branches in the forbidden slot. */
28830            is_slot = 1;
28831        }
28832    }
28833    if (is_slot) {
28834        gen_branch(ctx, insn_bytes);
28835    }
28836    ctx->base.pc_next += insn_bytes;
28837
28838    if (ctx->base.is_jmp != DISAS_NEXT) {
28839        return;
28840    }
28841    /* Execute a branch and its delay slot as a single instruction.
28842       This is what GDB expects and is consistent with what the
28843       hardware does (e.g. if a delay slot instruction faults, the
28844       reported PC is the PC of the branch).  */
28845    if (ctx->base.singlestep_enabled &&
28846        (ctx->hflags & MIPS_HFLAG_BMASK) == 0) {
28847        ctx->base.is_jmp = DISAS_TOO_MANY;
28848    }
28849    if (ctx->base.pc_next - ctx->page_start >= TARGET_PAGE_SIZE) {
28850        ctx->base.is_jmp = DISAS_TOO_MANY;
28851    }
28852}
28853
28854static void mips_tr_tb_stop(DisasContextBase *dcbase, CPUState *cs)
28855{
28856    DisasContext *ctx = container_of(dcbase, DisasContext, base);
28857
28858    if (ctx->base.singlestep_enabled && ctx->base.is_jmp != DISAS_NORETURN) {
28859        save_cpu_state(ctx, ctx->base.is_jmp != DISAS_EXIT);
28860        gen_helper_raise_exception_debug(cpu_env);
28861    } else {
28862        switch (ctx->base.is_jmp) {
28863        case DISAS_STOP:
28864            gen_save_pc(ctx->base.pc_next);
28865            tcg_gen_lookup_and_goto_ptr();
28866            break;
28867        case DISAS_NEXT:
28868        case DISAS_TOO_MANY:
28869            save_cpu_state(ctx, 0);
28870            gen_goto_tb(ctx, 0, ctx->base.pc_next);
28871            break;
28872        case DISAS_EXIT:
28873            tcg_gen_exit_tb(NULL, 0);
28874            break;
28875        case DISAS_NORETURN:
28876            break;
28877        default:
28878            g_assert_not_reached();
28879        }
28880    }
28881}
28882
28883static void mips_tr_disas_log(const DisasContextBase *dcbase, CPUState *cs)
28884{
28885    qemu_log("IN: %s\n", lookup_symbol(dcbase->pc_first));
28886    log_target_disas(cs, dcbase->pc_first, dcbase->tb->size);
28887}
28888
28889static const TranslatorOps mips_tr_ops = {
28890    .init_disas_context = mips_tr_init_disas_context,
28891    .tb_start           = mips_tr_tb_start,
28892    .insn_start         = mips_tr_insn_start,
28893    .breakpoint_check   = mips_tr_breakpoint_check,
28894    .translate_insn     = mips_tr_translate_insn,
28895    .tb_stop            = mips_tr_tb_stop,
28896    .disas_log          = mips_tr_disas_log,
28897};
28898
28899void gen_intermediate_code(CPUState *cs, struct TranslationBlock *tb)
28900{
28901    DisasContext ctx;
28902
28903    translator_loop(&mips_tr_ops, &ctx.base, cs, tb);
28904}
28905
28906static void fpu_dump_state(CPUMIPSState *env, FILE *f, fprintf_function fpu_fprintf,
28907                           int flags)
28908{
28909    int i;
28910    int is_fpu64 = !!(env->hflags & MIPS_HFLAG_F64);
28911
28912#define printfpr(fp)                                                    \
28913    do {                                                                \
28914        if (is_fpu64)                                                   \
28915            fpu_fprintf(f, "w:%08x d:%016" PRIx64                       \
28916                        " fd:%13g fs:%13g psu: %13g\n",                 \
28917                        (fp)->w[FP_ENDIAN_IDX], (fp)->d,                \
28918                        (double)(fp)->fd,                               \
28919                        (double)(fp)->fs[FP_ENDIAN_IDX],                \
28920                        (double)(fp)->fs[!FP_ENDIAN_IDX]);              \
28921        else {                                                          \
28922            fpr_t tmp;                                                  \
28923            tmp.w[FP_ENDIAN_IDX] = (fp)->w[FP_ENDIAN_IDX];              \
28924            tmp.w[!FP_ENDIAN_IDX] = ((fp) + 1)->w[FP_ENDIAN_IDX];       \
28925            fpu_fprintf(f, "w:%08x d:%016" PRIx64                       \
28926                        " fd:%13g fs:%13g psu:%13g\n",                  \
28927                        tmp.w[FP_ENDIAN_IDX], tmp.d,                    \
28928                        (double)tmp.fd,                                 \
28929                        (double)tmp.fs[FP_ENDIAN_IDX],                  \
28930                        (double)tmp.fs[!FP_ENDIAN_IDX]);                \
28931        }                                                               \
28932    } while(0)
28933
28934
28935    fpu_fprintf(f, "CP1 FCR0 0x%08x  FCR31 0x%08x  SR.FR %d  fp_status 0x%02x\n",
28936                env->active_fpu.fcr0, env->active_fpu.fcr31, is_fpu64,
28937                get_float_exception_flags(&env->active_fpu.fp_status));
28938    for (i = 0; i < 32; (is_fpu64) ? i++ : (i += 2)) {
28939        fpu_fprintf(f, "%3s: ", fregnames[i]);
28940        printfpr(&env->active_fpu.fpr[i]);
28941    }
28942
28943#undef printfpr
28944}
28945
28946void mips_cpu_dump_state(CPUState *cs, FILE *f, fprintf_function cpu_fprintf,
28947                         int flags)
28948{
28949    MIPSCPU *cpu = MIPS_CPU(cs);
28950    CPUMIPSState *env = &cpu->env;
28951    int i;
28952
28953    cpu_fprintf(f, "pc=0x" TARGET_FMT_lx " HI=0x" TARGET_FMT_lx
28954                " LO=0x" TARGET_FMT_lx " ds %04x "
28955                TARGET_FMT_lx " " TARGET_FMT_ld "\n",
28956                env->active_tc.PC, env->active_tc.HI[0], env->active_tc.LO[0],
28957                env->hflags, env->btarget, env->bcond);
28958    for (i = 0; i < 32; i++) {
28959        if ((i & 3) == 0)
28960            cpu_fprintf(f, "GPR%02d:", i);
28961        cpu_fprintf(f, " %s " TARGET_FMT_lx, regnames[i], env->active_tc.gpr[i]);
28962        if ((i & 3) == 3)
28963            cpu_fprintf(f, "\n");
28964    }
28965
28966    cpu_fprintf(f, "CP0 Status  0x%08x Cause   0x%08x EPC    0x" TARGET_FMT_lx "\n",
28967                env->CP0_Status, env->CP0_Cause, env->CP0_EPC);
28968    cpu_fprintf(f, "    Config0 0x%08x Config1 0x%08x LLAddr 0x%016"
28969                PRIx64 "\n",
28970                env->CP0_Config0, env->CP0_Config1, env->lladdr);
28971    cpu_fprintf(f, "    Config2 0x%08x Config3 0x%08x\n",
28972                env->CP0_Config2, env->CP0_Config3);
28973    cpu_fprintf(f, "    Config4 0x%08x Config5 0x%08x\n",
28974                env->CP0_Config4, env->CP0_Config5);
28975    if ((flags & CPU_DUMP_FPU) && (env->hflags & MIPS_HFLAG_FPU)) {
28976        fpu_dump_state(env, f, cpu_fprintf, flags);
28977    }
28978}
28979
28980void mips_tcg_init(void)
28981{
28982    int i;
28983
28984    cpu_gpr[0] = NULL;
28985    for (i = 1; i < 32; i++)
28986        cpu_gpr[i] = tcg_global_mem_new(cpu_env,
28987                                        offsetof(CPUMIPSState, active_tc.gpr[i]),
28988                                        regnames[i]);
28989
28990    for (i = 0; i < 32; i++) {
28991        int off = offsetof(CPUMIPSState, active_fpu.fpr[i].wr.d[0]);
28992        msa_wr_d[i * 2] =
28993                tcg_global_mem_new_i64(cpu_env, off, msaregnames[i * 2]);
28994        /* The scalar floating-point unit (FPU) registers are mapped on
28995         * the MSA vector registers. */
28996        fpu_f64[i] = msa_wr_d[i * 2];
28997        off = offsetof(CPUMIPSState, active_fpu.fpr[i].wr.d[1]);
28998        msa_wr_d[i * 2 + 1] =
28999                tcg_global_mem_new_i64(cpu_env, off, msaregnames[i * 2 + 1]);
29000    }
29001
29002    cpu_PC = tcg_global_mem_new(cpu_env,
29003                                offsetof(CPUMIPSState, active_tc.PC), "PC");
29004    for (i = 0; i < MIPS_DSP_ACC; i++) {
29005        cpu_HI[i] = tcg_global_mem_new(cpu_env,
29006                                       offsetof(CPUMIPSState, active_tc.HI[i]),
29007                                       regnames_HI[i]);
29008        cpu_LO[i] = tcg_global_mem_new(cpu_env,
29009                                       offsetof(CPUMIPSState, active_tc.LO[i]),
29010                                       regnames_LO[i]);
29011    }
29012    cpu_dspctrl = tcg_global_mem_new(cpu_env,
29013                                     offsetof(CPUMIPSState, active_tc.DSPControl),
29014                                     "DSPControl");
29015    bcond = tcg_global_mem_new(cpu_env,
29016                               offsetof(CPUMIPSState, bcond), "bcond");
29017    btarget = tcg_global_mem_new(cpu_env,
29018                                 offsetof(CPUMIPSState, btarget), "btarget");
29019    hflags = tcg_global_mem_new_i32(cpu_env,
29020                                    offsetof(CPUMIPSState, hflags), "hflags");
29021
29022    fpu_fcr0 = tcg_global_mem_new_i32(cpu_env,
29023                                      offsetof(CPUMIPSState, active_fpu.fcr0),
29024                                      "fcr0");
29025    fpu_fcr31 = tcg_global_mem_new_i32(cpu_env,
29026                                       offsetof(CPUMIPSState, active_fpu.fcr31),
29027                                       "fcr31");
29028
29029    for (i = 0; i < NUMBER_OF_MXU_REGISTERS - 1; i++) {
29030        mxu_gpr[i] = tcg_global_mem_new(cpu_env,
29031                                        offsetof(CPUMIPSState,
29032                                                 active_tc.mxu_gpr[i]),
29033                                        mxuregnames[i]);
29034    }
29035
29036    mxu_CR = tcg_global_mem_new(cpu_env,
29037                                offsetof(CPUMIPSState, active_tc.mxu_cr),
29038                                mxuregnames[NUMBER_OF_MXU_REGISTERS - 1]);
29039}
29040
29041#include "translate_init.inc.c"
29042
29043void cpu_mips_realize_env(CPUMIPSState *env)
29044{
29045    env->exception_base = (int32_t)0xBFC00000;
29046
29047#ifndef CONFIG_USER_ONLY
29048    mmu_init(env, env->cpu_model);
29049#endif
29050    fpu_init(env, env->cpu_model);
29051    mvp_init(env, env->cpu_model);
29052}
29053
29054bool cpu_supports_cps_smp(const char *cpu_type)
29055{
29056    const MIPSCPUClass *mcc = MIPS_CPU_CLASS(object_class_by_name(cpu_type));
29057    return (mcc->cpu_def->CP0_Config3 & (1 << CP0C3_CMGCR)) != 0;
29058}
29059
29060bool cpu_supports_isa(const char *cpu_type, unsigned int isa)
29061{
29062    const MIPSCPUClass *mcc = MIPS_CPU_CLASS(object_class_by_name(cpu_type));
29063    return (mcc->cpu_def->insn_flags & isa) != 0;
29064}
29065
29066void cpu_set_exception_base(int vp_index, target_ulong address)
29067{
29068    MIPSCPU *vp = MIPS_CPU(qemu_get_cpu(vp_index));
29069    vp->env.exception_base = address;
29070}
29071
29072void cpu_state_reset(CPUMIPSState *env)
29073{
29074    MIPSCPU *cpu = mips_env_get_cpu(env);
29075    CPUState *cs = CPU(cpu);
29076
29077    /* Reset registers to their default values */
29078    env->CP0_PRid = env->cpu_model->CP0_PRid;
29079    env->CP0_Config0 = env->cpu_model->CP0_Config0;
29080#ifdef TARGET_WORDS_BIGENDIAN
29081    env->CP0_Config0 |= (1 << CP0C0_BE);
29082#endif
29083    env->CP0_Config1 = env->cpu_model->CP0_Config1;
29084    env->CP0_Config2 = env->cpu_model->CP0_Config2;
29085    env->CP0_Config3 = env->cpu_model->CP0_Config3;
29086    env->CP0_Config4 = env->cpu_model->CP0_Config4;
29087    env->CP0_Config4_rw_bitmask = env->cpu_model->CP0_Config4_rw_bitmask;
29088    env->CP0_Config5 = env->cpu_model->CP0_Config5;
29089    env->CP0_Config5_rw_bitmask = env->cpu_model->CP0_Config5_rw_bitmask;
29090    env->CP0_Config6 = env->cpu_model->CP0_Config6;
29091    env->CP0_Config7 = env->cpu_model->CP0_Config7;
29092    env->CP0_LLAddr_rw_bitmask = env->cpu_model->CP0_LLAddr_rw_bitmask
29093                                 << env->cpu_model->CP0_LLAddr_shift;
29094    env->CP0_LLAddr_shift = env->cpu_model->CP0_LLAddr_shift;
29095    env->SYNCI_Step = env->cpu_model->SYNCI_Step;
29096    env->CCRes = env->cpu_model->CCRes;
29097    env->CP0_Status_rw_bitmask = env->cpu_model->CP0_Status_rw_bitmask;
29098    env->CP0_TCStatus_rw_bitmask = env->cpu_model->CP0_TCStatus_rw_bitmask;
29099    env->CP0_SRSCtl = env->cpu_model->CP0_SRSCtl;
29100    env->current_tc = 0;
29101    env->SEGBITS = env->cpu_model->SEGBITS;
29102    env->SEGMask = (target_ulong)((1ULL << env->cpu_model->SEGBITS) - 1);
29103#if defined(TARGET_MIPS64)
29104    if (env->cpu_model->insn_flags & ISA_MIPS3) {
29105        env->SEGMask |= 3ULL << 62;
29106    }
29107#endif
29108    env->PABITS = env->cpu_model->PABITS;
29109    env->CP0_SRSConf0_rw_bitmask = env->cpu_model->CP0_SRSConf0_rw_bitmask;
29110    env->CP0_SRSConf0 = env->cpu_model->CP0_SRSConf0;
29111    env->CP0_SRSConf1_rw_bitmask = env->cpu_model->CP0_SRSConf1_rw_bitmask;
29112    env->CP0_SRSConf1 = env->cpu_model->CP0_SRSConf1;
29113    env->CP0_SRSConf2_rw_bitmask = env->cpu_model->CP0_SRSConf2_rw_bitmask;
29114    env->CP0_SRSConf2 = env->cpu_model->CP0_SRSConf2;
29115    env->CP0_SRSConf3_rw_bitmask = env->cpu_model->CP0_SRSConf3_rw_bitmask;
29116    env->CP0_SRSConf3 = env->cpu_model->CP0_SRSConf3;
29117    env->CP0_SRSConf4_rw_bitmask = env->cpu_model->CP0_SRSConf4_rw_bitmask;
29118    env->CP0_SRSConf4 = env->cpu_model->CP0_SRSConf4;
29119    env->CP0_PageGrain_rw_bitmask = env->cpu_model->CP0_PageGrain_rw_bitmask;
29120    env->CP0_PageGrain = env->cpu_model->CP0_PageGrain;
29121    env->CP0_EBaseWG_rw_bitmask = env->cpu_model->CP0_EBaseWG_rw_bitmask;
29122    env->active_fpu.fcr0 = env->cpu_model->CP1_fcr0;
29123    env->active_fpu.fcr31_rw_bitmask = env->cpu_model->CP1_fcr31_rw_bitmask;
29124    env->active_fpu.fcr31 = env->cpu_model->CP1_fcr31;
29125    env->msair = env->cpu_model->MSAIR;
29126    env->insn_flags = env->cpu_model->insn_flags;
29127
29128#if defined(CONFIG_USER_ONLY)
29129    env->CP0_Status = (MIPS_HFLAG_UM << CP0St_KSU);
29130# ifdef TARGET_MIPS64
29131    /* Enable 64-bit register mode.  */
29132    env->CP0_Status |= (1 << CP0St_PX);
29133# endif
29134# ifdef TARGET_ABI_MIPSN64
29135    /* Enable 64-bit address mode.  */
29136    env->CP0_Status |= (1 << CP0St_UX);
29137# endif
29138    /* Enable access to the CPUNum, SYNCI_Step, CC, and CCRes RDHWR
29139       hardware registers.  */
29140    env->CP0_HWREna |= 0x0000000F;
29141    if (env->CP0_Config1 & (1 << CP0C1_FP)) {
29142        env->CP0_Status |= (1 << CP0St_CU1);
29143    }
29144    if (env->CP0_Config3 & (1 << CP0C3_DSPP)) {
29145        env->CP0_Status |= (1 << CP0St_MX);
29146    }
29147# if defined(TARGET_MIPS64)
29148    /* For MIPS64, init FR bit to 1 if FPU unit is there and bit is writable. */
29149    if ((env->CP0_Config1 & (1 << CP0C1_FP)) &&
29150        (env->CP0_Status_rw_bitmask & (1 << CP0St_FR))) {
29151        env->CP0_Status |= (1 << CP0St_FR);
29152    }
29153# endif
29154#else
29155    if (env->hflags & MIPS_HFLAG_BMASK) {
29156        /* If the exception was raised from a delay slot,
29157           come back to the jump.  */
29158        env->CP0_ErrorEPC = (env->active_tc.PC
29159                             - (env->hflags & MIPS_HFLAG_B16 ? 2 : 4));
29160    } else {
29161        env->CP0_ErrorEPC = env->active_tc.PC;
29162    }
29163    env->active_tc.PC = env->exception_base;
29164    env->CP0_Random = env->tlb->nb_tlb - 1;
29165    env->tlb->tlb_in_use = env->tlb->nb_tlb;
29166    env->CP0_Wired = 0;
29167    env->CP0_GlobalNumber = (cs->cpu_index & 0xFF) << CP0GN_VPId;
29168    env->CP0_EBase = (cs->cpu_index & 0x3FF);
29169    if (mips_um_ksegs_enabled()) {
29170        env->CP0_EBase |= 0x40000000;
29171    } else {
29172        env->CP0_EBase |= (int32_t)0x80000000;
29173    }
29174    if (env->CP0_Config3 & (1 << CP0C3_CMGCR)) {
29175        env->CP0_CMGCRBase = 0x1fbf8000 >> 4;
29176    }
29177    env->CP0_EntryHi_ASID_mask = (env->CP0_Config4 & (1 << CP0C4_AE)) ?
29178                                 0x3ff : 0xff;
29179    env->CP0_Status = (1 << CP0St_BEV) | (1 << CP0St_ERL);
29180    /* vectored interrupts not implemented, timer on int 7,
29181       no performance counters. */
29182    env->CP0_IntCtl = 0xe0000000;
29183    {
29184        int i;
29185
29186        for (i = 0; i < 7; i++) {
29187            env->CP0_WatchLo[i] = 0;
29188            env->CP0_WatchHi[i] = 0x80000000;
29189        }
29190        env->CP0_WatchLo[7] = 0;
29191        env->CP0_WatchHi[7] = 0;
29192    }
29193    /* Count register increments in debug mode, EJTAG version 1 */
29194    env->CP0_Debug = (1 << CP0DB_CNT) | (0x1 << CP0DB_VER);
29195
29196    cpu_mips_store_count(env, 1);
29197
29198    if (env->CP0_Config3 & (1 << CP0C3_MT)) {
29199        int i;
29200
29201        /* Only TC0 on VPE 0 starts as active.  */
29202        for (i = 0; i < ARRAY_SIZE(env->tcs); i++) {
29203            env->tcs[i].CP0_TCBind = cs->cpu_index << CP0TCBd_CurVPE;
29204            env->tcs[i].CP0_TCHalt = 1;
29205        }
29206        env->active_tc.CP0_TCHalt = 1;
29207        cs->halted = 1;
29208
29209        if (cs->cpu_index == 0) {
29210            /* VPE0 starts up enabled.  */
29211            env->mvp->CP0_MVPControl |= (1 << CP0MVPCo_EVP);
29212            env->CP0_VPEConf0 |= (1 << CP0VPEC0_MVP) | (1 << CP0VPEC0_VPA);
29213
29214            /* TC0 starts up unhalted.  */
29215            cs->halted = 0;
29216            env->active_tc.CP0_TCHalt = 0;
29217            env->tcs[0].CP0_TCHalt = 0;
29218            /* With thread 0 active.  */
29219            env->active_tc.CP0_TCStatus = (1 << CP0TCSt_A);
29220            env->tcs[0].CP0_TCStatus = (1 << CP0TCSt_A);
29221        }
29222    }
29223
29224    /*
29225     * Configure default legacy segmentation control. We use this regardless of
29226     * whether segmentation control is presented to the guest.
29227     */
29228    /* KSeg3 (seg0 0xE0000000..0xFFFFFFFF) */
29229    env->CP0_SegCtl0 =   (CP0SC_AM_MK << CP0SC_AM);
29230    /* KSeg2 (seg1 0xC0000000..0xDFFFFFFF) */
29231    env->CP0_SegCtl0 |= ((CP0SC_AM_MSK << CP0SC_AM)) << 16;
29232    /* KSeg1 (seg2 0xA0000000..0x9FFFFFFF) */
29233    env->CP0_SegCtl1 =   (0 << CP0SC_PA) | (CP0SC_AM_UK << CP0SC_AM) |
29234                         (2 << CP0SC_C);
29235    /* KSeg0 (seg3 0x80000000..0x9FFFFFFF) */
29236    env->CP0_SegCtl1 |= ((0 << CP0SC_PA) | (CP0SC_AM_UK << CP0SC_AM) |
29237                         (3 << CP0SC_C)) << 16;
29238    /* USeg (seg4 0x40000000..0x7FFFFFFF) */
29239    env->CP0_SegCtl2 =   (2 << CP0SC_PA) | (CP0SC_AM_MUSK << CP0SC_AM) |
29240                         (1 << CP0SC_EU) | (2 << CP0SC_C);
29241    /* USeg (seg5 0x00000000..0x3FFFFFFF) */
29242    env->CP0_SegCtl2 |= ((0 << CP0SC_PA) | (CP0SC_AM_MUSK << CP0SC_AM) |
29243                         (1 << CP0SC_EU) | (2 << CP0SC_C)) << 16;
29244    /* XKPhys (note, SegCtl2.XR = 0, so XAM won't be used) */
29245    env->CP0_SegCtl1 |= (CP0SC_AM_UK << CP0SC1_XAM);
29246#endif
29247    if ((env->insn_flags & ISA_MIPS32R6) &&
29248        (env->active_fpu.fcr0 & (1 << FCR0_F64))) {
29249        /* Status.FR = 0 mode in 64-bit FPU not allowed in R6 */
29250        env->CP0_Status |= (1 << CP0St_FR);
29251    }
29252
29253    if (env->insn_flags & ISA_MIPS32R6) {
29254        /* PTW  =  1 */
29255        env->CP0_PWSize = 0x40;
29256        /* GDI  = 12 */
29257        /* UDI  = 12 */
29258        /* MDI  = 12 */
29259        /* PRI  = 12 */
29260        /* PTEI =  2 */
29261        env->CP0_PWField = 0x0C30C302;
29262    } else {
29263        /* GDI  =  0 */
29264        /* UDI  =  0 */
29265        /* MDI  =  0 */
29266        /* PRI  =  0 */
29267        /* PTEI =  2 */
29268        env->CP0_PWField = 0x02;
29269    }
29270
29271    if (env->CP0_Config3 & (1 << CP0C3_ISA) & (1 << (CP0C3_ISA + 1))) {
29272        /*  microMIPS on reset when Config3.ISA is 3 */
29273        env->hflags |= MIPS_HFLAG_M16;
29274    }
29275
29276    /* MSA */
29277    if (env->CP0_Config3 & (1 << CP0C3_MSAP)) {
29278        msa_reset(env);
29279    }
29280
29281    compute_hflags(env);
29282    restore_fp_status(env);
29283    restore_pamask(env);
29284    cs->exception_index = EXCP_NONE;
29285
29286    if (semihosting_get_argc()) {
29287        /* UHI interface can be used to obtain argc and argv */
29288        env->active_tc.gpr[4] = -1;
29289    }
29290}
29291
29292void restore_state_to_opc(CPUMIPSState *env, TranslationBlock *tb,
29293                          target_ulong *data)
29294{
29295    env->active_tc.PC = data[0];
29296    env->hflags &= ~MIPS_HFLAG_BMASK;
29297    env->hflags |= data[1];
29298    switch (env->hflags & MIPS_HFLAG_BMASK_BASE) {
29299    case MIPS_HFLAG_BR:
29300        break;
29301    case MIPS_HFLAG_BC:
29302    case MIPS_HFLAG_BL:
29303    case MIPS_HFLAG_B:
29304        env->btarget = data[2];
29305        break;
29306    }
29307}
29308