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/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 "hw/semihosting/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#include "qemu/qemu-print.h"
  42
  43#define MIPS_DEBUG_DISAS 0
  44
  45/* MIPS major opcodes */
  46#define MASK_OP_MAJOR(op)       (op & (0x3F << 26))
  47
  48enum {
  49    /* indirect opcode tables */
  50    OPC_SPECIAL  = (0x00 << 26),
  51    OPC_REGIMM   = (0x01 << 26),
  52    OPC_CP0      = (0x10 << 26),
  53    OPC_CP1      = (0x11 << 26),
  54    OPC_CP2      = (0x12 << 26),
  55    OPC_CP3      = (0x13 << 26),
  56    OPC_SPECIAL2 = (0x1C << 26),
  57    OPC_SPECIAL3 = (0x1F << 26),
  58    /* arithmetic with immediate */
  59    OPC_ADDI     = (0x08 << 26),
  60    OPC_ADDIU    = (0x09 << 26),
  61    OPC_SLTI     = (0x0A << 26),
  62    OPC_SLTIU    = (0x0B << 26),
  63    /* logic with immediate */
  64    OPC_ANDI     = (0x0C << 26),
  65    OPC_ORI      = (0x0D << 26),
  66    OPC_XORI     = (0x0E << 26),
  67    OPC_LUI      = (0x0F << 26),
  68    /* arithmetic with immediate */
  69    OPC_DADDI    = (0x18 << 26),
  70    OPC_DADDIU   = (0x19 << 26),
  71    /* Jump and branches */
  72    OPC_J        = (0x02 << 26),
  73    OPC_JAL      = (0x03 << 26),
  74    OPC_BEQ      = (0x04 << 26),  /* Unconditional if rs = rt = 0 (B) */
  75    OPC_BEQL     = (0x14 << 26),
  76    OPC_BNE      = (0x05 << 26),
  77    OPC_BNEL     = (0x15 << 26),
  78    OPC_BLEZ     = (0x06 << 26),
  79    OPC_BLEZL    = (0x16 << 26),
  80    OPC_BGTZ     = (0x07 << 26),
  81    OPC_BGTZL    = (0x17 << 26),
  82    OPC_JALX     = (0x1D << 26),
  83    OPC_DAUI     = (0x1D << 26),
  84    /* Load and stores */
  85    OPC_LDL      = (0x1A << 26),
  86    OPC_LDR      = (0x1B << 26),
  87    OPC_LB       = (0x20 << 26),
  88    OPC_LH       = (0x21 << 26),
  89    OPC_LWL      = (0x22 << 26),
  90    OPC_LW       = (0x23 << 26),
  91    OPC_LWPC     = OPC_LW | 0x5,
  92    OPC_LBU      = (0x24 << 26),
  93    OPC_LHU      = (0x25 << 26),
  94    OPC_LWR      = (0x26 << 26),
  95    OPC_LWU      = (0x27 << 26),
  96    OPC_SB       = (0x28 << 26),
  97    OPC_SH       = (0x29 << 26),
  98    OPC_SWL      = (0x2A << 26),
  99    OPC_SW       = (0x2B << 26),
 100    OPC_SDL      = (0x2C << 26),
 101    OPC_SDR      = (0x2D << 26),
 102    OPC_SWR      = (0x2E << 26),
 103    OPC_LL       = (0x30 << 26),
 104    OPC_LLD      = (0x34 << 26),
 105    OPC_LD       = (0x37 << 26),
 106    OPC_LDPC     = OPC_LD | 0x5,
 107    OPC_SC       = (0x38 << 26),
 108    OPC_SCD      = (0x3C << 26),
 109    OPC_SD       = (0x3F << 26),
 110    /* Floating point load/store */
 111    OPC_LWC1     = (0x31 << 26),
 112    OPC_LWC2     = (0x32 << 26),
 113    OPC_LDC1     = (0x35 << 26),
 114    OPC_LDC2     = (0x36 << 26),
 115    OPC_SWC1     = (0x39 << 26),
 116    OPC_SWC2     = (0x3A << 26),
 117    OPC_SDC1     = (0x3D << 26),
 118    OPC_SDC2     = (0x3E << 26),
 119    /* Compact Branches */
 120    OPC_BLEZALC  = (0x06 << 26),
 121    OPC_BGEZALC  = (0x06 << 26),
 122    OPC_BGEUC    = (0x06 << 26),
 123    OPC_BGTZALC  = (0x07 << 26),
 124    OPC_BLTZALC  = (0x07 << 26),
 125    OPC_BLTUC    = (0x07 << 26),
 126    OPC_BOVC     = (0x08 << 26),
 127    OPC_BEQZALC  = (0x08 << 26),
 128    OPC_BEQC     = (0x08 << 26),
 129    OPC_BLEZC    = (0x16 << 26),
 130    OPC_BGEZC    = (0x16 << 26),
 131    OPC_BGEC     = (0x16 << 26),
 132    OPC_BGTZC    = (0x17 << 26),
 133    OPC_BLTZC    = (0x17 << 26),
 134    OPC_BLTC     = (0x17 << 26),
 135    OPC_BNVC     = (0x18 << 26),
 136    OPC_BNEZALC  = (0x18 << 26),
 137    OPC_BNEC     = (0x18 << 26),
 138    OPC_BC       = (0x32 << 26),
 139    OPC_BEQZC    = (0x36 << 26),
 140    OPC_JIC      = (0x36 << 26),
 141    OPC_BALC     = (0x3A << 26),
 142    OPC_BNEZC    = (0x3E << 26),
 143    OPC_JIALC    = (0x3E << 26),
 144    /* MDMX ASE specific */
 145    OPC_MDMX     = (0x1E << 26),
 146    /* MSA ASE, same as MDMX */
 147    OPC_MSA      = OPC_MDMX,
 148    /* Cache and prefetch */
 149    OPC_CACHE    = (0x2F << 26),
 150    OPC_PREF     = (0x33 << 26),
 151    /* PC-relative address computation / loads */
 152    OPC_PCREL    = (0x3B << 26),
 153};
 154
 155/* PC-relative address computation / loads  */
 156#define MASK_OPC_PCREL_TOP2BITS(op) (MASK_OP_MAJOR(op) | (op & (3 << 19)))
 157#define MASK_OPC_PCREL_TOP5BITS(op) (MASK_OP_MAJOR(op) | (op & (0x1f << 16)))
 158enum {
 159    /* Instructions determined by bits 19 and 20 */
 160    OPC_ADDIUPC = OPC_PCREL | (0 << 19),
 161    R6_OPC_LWPC = OPC_PCREL | (1 << 19),
 162    OPC_LWUPC   = OPC_PCREL | (2 << 19),
 163
 164    /* Instructions determined by bits 16 ... 20 */
 165    OPC_AUIPC   = OPC_PCREL | (0x1e << 16),
 166    OPC_ALUIPC  = OPC_PCREL | (0x1f << 16),
 167
 168    /* Other */
 169    R6_OPC_LDPC = OPC_PCREL | (6 << 18),
 170};
 171
 172/* MIPS special opcodes */
 173#define MASK_SPECIAL(op)            (MASK_OP_MAJOR(op) | (op & 0x3F))
 174
 175enum {
 176    /* Shifts */
 177    OPC_SLL      = 0x00 | OPC_SPECIAL,
 178    /* NOP is SLL r0, r0, 0   */
 179    /* SSNOP is SLL r0, r0, 1 */
 180    /* EHB is SLL r0, r0, 3 */
 181    OPC_SRL      = 0x02 | OPC_SPECIAL, /* also ROTR */
 182    OPC_ROTR     = OPC_SRL | (1 << 21),
 183    OPC_SRA      = 0x03 | OPC_SPECIAL,
 184    OPC_SLLV     = 0x04 | OPC_SPECIAL,
 185    OPC_SRLV     = 0x06 | OPC_SPECIAL, /* also ROTRV */
 186    OPC_ROTRV    = OPC_SRLV | (1 << 6),
 187    OPC_SRAV     = 0x07 | OPC_SPECIAL,
 188    OPC_DSLLV    = 0x14 | OPC_SPECIAL,
 189    OPC_DSRLV    = 0x16 | OPC_SPECIAL, /* also DROTRV */
 190    OPC_DROTRV   = OPC_DSRLV | (1 << 6),
 191    OPC_DSRAV    = 0x17 | OPC_SPECIAL,
 192    OPC_DSLL     = 0x38 | OPC_SPECIAL,
 193    OPC_DSRL     = 0x3A | OPC_SPECIAL, /* also DROTR */
 194    OPC_DROTR    = OPC_DSRL | (1 << 21),
 195    OPC_DSRA     = 0x3B | OPC_SPECIAL,
 196    OPC_DSLL32   = 0x3C | OPC_SPECIAL,
 197    OPC_DSRL32   = 0x3E | OPC_SPECIAL, /* also DROTR32 */
 198    OPC_DROTR32  = OPC_DSRL32 | (1 << 21),
 199    OPC_DSRA32   = 0x3F | OPC_SPECIAL,
 200    /* Multiplication / division */
 201    OPC_MULT     = 0x18 | OPC_SPECIAL,
 202    OPC_MULTU    = 0x19 | OPC_SPECIAL,
 203    OPC_DIV      = 0x1A | OPC_SPECIAL,
 204    OPC_DIVU     = 0x1B | OPC_SPECIAL,
 205    OPC_DMULT    = 0x1C | OPC_SPECIAL,
 206    OPC_DMULTU   = 0x1D | OPC_SPECIAL,
 207    OPC_DDIV     = 0x1E | OPC_SPECIAL,
 208    OPC_DDIVU    = 0x1F | OPC_SPECIAL,
 209
 210    /* 2 registers arithmetic / logic */
 211    OPC_ADD      = 0x20 | OPC_SPECIAL,
 212    OPC_ADDU     = 0x21 | OPC_SPECIAL,
 213    OPC_SUB      = 0x22 | OPC_SPECIAL,
 214    OPC_SUBU     = 0x23 | OPC_SPECIAL,
 215    OPC_AND      = 0x24 | OPC_SPECIAL,
 216    OPC_OR       = 0x25 | OPC_SPECIAL,
 217    OPC_XOR      = 0x26 | OPC_SPECIAL,
 218    OPC_NOR      = 0x27 | OPC_SPECIAL,
 219    OPC_SLT      = 0x2A | OPC_SPECIAL,
 220    OPC_SLTU     = 0x2B | OPC_SPECIAL,
 221    OPC_DADD     = 0x2C | OPC_SPECIAL,
 222    OPC_DADDU    = 0x2D | OPC_SPECIAL,
 223    OPC_DSUB     = 0x2E | OPC_SPECIAL,
 224    OPC_DSUBU    = 0x2F | OPC_SPECIAL,
 225    /* Jumps */
 226    OPC_JR       = 0x08 | OPC_SPECIAL, /* Also JR.HB */
 227    OPC_JALR     = 0x09 | OPC_SPECIAL, /* Also JALR.HB */
 228    /* Traps */
 229    OPC_TGE      = 0x30 | OPC_SPECIAL,
 230    OPC_TGEU     = 0x31 | OPC_SPECIAL,
 231    OPC_TLT      = 0x32 | OPC_SPECIAL,
 232    OPC_TLTU     = 0x33 | OPC_SPECIAL,
 233    OPC_TEQ      = 0x34 | OPC_SPECIAL,
 234    OPC_TNE      = 0x36 | OPC_SPECIAL,
 235    /* HI / LO registers load & stores */
 236    OPC_MFHI     = 0x10 | OPC_SPECIAL,
 237    OPC_MTHI     = 0x11 | OPC_SPECIAL,
 238    OPC_MFLO     = 0x12 | OPC_SPECIAL,
 239    OPC_MTLO     = 0x13 | OPC_SPECIAL,
 240    /* Conditional moves */
 241    OPC_MOVZ     = 0x0A | OPC_SPECIAL,
 242    OPC_MOVN     = 0x0B | OPC_SPECIAL,
 243
 244    OPC_SELEQZ   = 0x35 | OPC_SPECIAL,
 245    OPC_SELNEZ   = 0x37 | OPC_SPECIAL,
 246
 247    OPC_MOVCI    = 0x01 | OPC_SPECIAL,
 248
 249    /* Special */
 250    OPC_PMON     = 0x05 | OPC_SPECIAL, /* unofficial */
 251    OPC_SYSCALL  = 0x0C | OPC_SPECIAL,
 252    OPC_BREAK    = 0x0D | OPC_SPECIAL,
 253    OPC_SPIM     = 0x0E | OPC_SPECIAL, /* unofficial */
 254    OPC_SYNC     = 0x0F | OPC_SPECIAL,
 255
 256    OPC_SPECIAL28_RESERVED = 0x28 | OPC_SPECIAL,
 257    OPC_SPECIAL29_RESERVED = 0x29 | OPC_SPECIAL,
 258    OPC_SPECIAL39_RESERVED = 0x39 | OPC_SPECIAL,
 259    OPC_SPECIAL3D_RESERVED = 0x3D | OPC_SPECIAL,
 260};
 261
 262/*
 263 * R6 Multiply and Divide instructions have the same opcode
 264 * and function field as legacy OPC_MULT[U]/OPC_DIV[U]
 265 */
 266#define MASK_R6_MULDIV(op)          (MASK_SPECIAL(op) | (op & (0x7ff)))
 267
 268enum {
 269    R6_OPC_MUL   = OPC_MULT  | (2 << 6),
 270    R6_OPC_MUH   = OPC_MULT  | (3 << 6),
 271    R6_OPC_MULU  = OPC_MULTU | (2 << 6),
 272    R6_OPC_MUHU  = OPC_MULTU | (3 << 6),
 273    R6_OPC_DIV   = OPC_DIV   | (2 << 6),
 274    R6_OPC_MOD   = OPC_DIV   | (3 << 6),
 275    R6_OPC_DIVU  = OPC_DIVU  | (2 << 6),
 276    R6_OPC_MODU  = OPC_DIVU  | (3 << 6),
 277
 278    R6_OPC_DMUL   = OPC_DMULT  | (2 << 6),
 279    R6_OPC_DMUH   = OPC_DMULT  | (3 << 6),
 280    R6_OPC_DMULU  = OPC_DMULTU | (2 << 6),
 281    R6_OPC_DMUHU  = OPC_DMULTU | (3 << 6),
 282    R6_OPC_DDIV   = OPC_DDIV   | (2 << 6),
 283    R6_OPC_DMOD   = OPC_DDIV   | (3 << 6),
 284    R6_OPC_DDIVU  = OPC_DDIVU  | (2 << 6),
 285    R6_OPC_DMODU  = OPC_DDIVU  | (3 << 6),
 286
 287    R6_OPC_CLZ      = 0x10 | OPC_SPECIAL,
 288    R6_OPC_CLO      = 0x11 | OPC_SPECIAL,
 289    R6_OPC_DCLZ     = 0x12 | OPC_SPECIAL,
 290    R6_OPC_DCLO     = 0x13 | OPC_SPECIAL,
 291    R6_OPC_SDBBP    = 0x0e | OPC_SPECIAL,
 292
 293    OPC_LSA  = 0x05 | OPC_SPECIAL,
 294    OPC_DLSA = 0x15 | OPC_SPECIAL,
 295};
 296
 297/* Multiplication variants of the vr54xx. */
 298#define MASK_MUL_VR54XX(op)         (MASK_SPECIAL(op) | (op & (0x1F << 6)))
 299
 300enum {
 301    OPC_VR54XX_MULS    = (0x03 << 6) | OPC_MULT,
 302    OPC_VR54XX_MULSU   = (0x03 << 6) | OPC_MULTU,
 303    OPC_VR54XX_MACC    = (0x05 << 6) | OPC_MULT,
 304    OPC_VR54XX_MACCU   = (0x05 << 6) | OPC_MULTU,
 305    OPC_VR54XX_MSAC    = (0x07 << 6) | OPC_MULT,
 306    OPC_VR54XX_MSACU   = (0x07 << 6) | OPC_MULTU,
 307    OPC_VR54XX_MULHI   = (0x09 << 6) | OPC_MULT,
 308    OPC_VR54XX_MULHIU  = (0x09 << 6) | OPC_MULTU,
 309    OPC_VR54XX_MULSHI  = (0x0B << 6) | OPC_MULT,
 310    OPC_VR54XX_MULSHIU = (0x0B << 6) | OPC_MULTU,
 311    OPC_VR54XX_MACCHI  = (0x0D << 6) | OPC_MULT,
 312    OPC_VR54XX_MACCHIU = (0x0D << 6) | OPC_MULTU,
 313    OPC_VR54XX_MSACHI  = (0x0F << 6) | OPC_MULT,
 314    OPC_VR54XX_MSACHIU = (0x0F << 6) | OPC_MULTU,
 315};
 316
 317/* REGIMM (rt field) opcodes */
 318#define MASK_REGIMM(op)             (MASK_OP_MAJOR(op) | (op & (0x1F << 16)))
 319
 320enum {
 321    OPC_BLTZ     = (0x00 << 16) | OPC_REGIMM,
 322    OPC_BLTZL    = (0x02 << 16) | OPC_REGIMM,
 323    OPC_BGEZ     = (0x01 << 16) | OPC_REGIMM,
 324    OPC_BGEZL    = (0x03 << 16) | OPC_REGIMM,
 325    OPC_BLTZAL   = (0x10 << 16) | OPC_REGIMM,
 326    OPC_BLTZALL  = (0x12 << 16) | OPC_REGIMM,
 327    OPC_BGEZAL   = (0x11 << 16) | OPC_REGIMM,
 328    OPC_BGEZALL  = (0x13 << 16) | OPC_REGIMM,
 329    OPC_TGEI     = (0x08 << 16) | OPC_REGIMM,
 330    OPC_TGEIU    = (0x09 << 16) | OPC_REGIMM,
 331    OPC_TLTI     = (0x0A << 16) | OPC_REGIMM,
 332    OPC_TLTIU    = (0x0B << 16) | OPC_REGIMM,
 333    OPC_TEQI     = (0x0C << 16) | OPC_REGIMM,
 334    OPC_TNEI     = (0x0E << 16) | OPC_REGIMM,
 335    OPC_SIGRIE   = (0x17 << 16) | OPC_REGIMM,
 336    OPC_SYNCI    = (0x1F << 16) | OPC_REGIMM,
 337
 338    OPC_DAHI     = (0x06 << 16) | OPC_REGIMM,
 339    OPC_DATI     = (0x1e << 16) | OPC_REGIMM,
 340};
 341
 342/* Special2 opcodes */
 343#define MASK_SPECIAL2(op)           (MASK_OP_MAJOR(op) | (op & 0x3F))
 344
 345enum {
 346    /* Multiply & xxx operations */
 347    OPC_MADD     = 0x00 | OPC_SPECIAL2,
 348    OPC_MADDU    = 0x01 | OPC_SPECIAL2,
 349    OPC_MUL      = 0x02 | OPC_SPECIAL2,
 350    OPC_MSUB     = 0x04 | OPC_SPECIAL2,
 351    OPC_MSUBU    = 0x05 | OPC_SPECIAL2,
 352    /* Loongson 2F */
 353    OPC_MULT_G_2F   = 0x10 | OPC_SPECIAL2,
 354    OPC_DMULT_G_2F  = 0x11 | OPC_SPECIAL2,
 355    OPC_MULTU_G_2F  = 0x12 | OPC_SPECIAL2,
 356    OPC_DMULTU_G_2F = 0x13 | OPC_SPECIAL2,
 357    OPC_DIV_G_2F    = 0x14 | OPC_SPECIAL2,
 358    OPC_DDIV_G_2F   = 0x15 | OPC_SPECIAL2,
 359    OPC_DIVU_G_2F   = 0x16 | OPC_SPECIAL2,
 360    OPC_DDIVU_G_2F  = 0x17 | OPC_SPECIAL2,
 361    OPC_MOD_G_2F    = 0x1c | OPC_SPECIAL2,
 362    OPC_DMOD_G_2F   = 0x1d | OPC_SPECIAL2,
 363    OPC_MODU_G_2F   = 0x1e | OPC_SPECIAL2,
 364    OPC_DMODU_G_2F  = 0x1f | OPC_SPECIAL2,
 365    /* Misc */
 366    OPC_CLZ      = 0x20 | OPC_SPECIAL2,
 367    OPC_CLO      = 0x21 | OPC_SPECIAL2,
 368    OPC_DCLZ     = 0x24 | OPC_SPECIAL2,
 369    OPC_DCLO     = 0x25 | OPC_SPECIAL2,
 370    /* Special */
 371    OPC_SDBBP    = 0x3F | OPC_SPECIAL2,
 372};
 373
 374/* Special3 opcodes */
 375#define MASK_SPECIAL3(op)           (MASK_OP_MAJOR(op) | (op & 0x3F))
 376
 377enum {
 378    OPC_EXT      = 0x00 | OPC_SPECIAL3,
 379    OPC_DEXTM    = 0x01 | OPC_SPECIAL3,
 380    OPC_DEXTU    = 0x02 | OPC_SPECIAL3,
 381    OPC_DEXT     = 0x03 | OPC_SPECIAL3,
 382    OPC_INS      = 0x04 | OPC_SPECIAL3,
 383    OPC_DINSM    = 0x05 | OPC_SPECIAL3,
 384    OPC_DINSU    = 0x06 | OPC_SPECIAL3,
 385    OPC_DINS     = 0x07 | OPC_SPECIAL3,
 386    OPC_FORK     = 0x08 | OPC_SPECIAL3,
 387    OPC_YIELD    = 0x09 | OPC_SPECIAL3,
 388    OPC_BSHFL    = 0x20 | OPC_SPECIAL3,
 389    OPC_DBSHFL   = 0x24 | OPC_SPECIAL3,
 390    OPC_RDHWR    = 0x3B | OPC_SPECIAL3,
 391    OPC_GINV     = 0x3D | OPC_SPECIAL3,
 392
 393    /* Loongson 2E */
 394    OPC_MULT_G_2E   = 0x18 | OPC_SPECIAL3,
 395    OPC_MULTU_G_2E  = 0x19 | OPC_SPECIAL3,
 396    OPC_DIV_G_2E    = 0x1A | OPC_SPECIAL3,
 397    OPC_DIVU_G_2E   = 0x1B | OPC_SPECIAL3,
 398    OPC_DMULT_G_2E  = 0x1C | OPC_SPECIAL3,
 399    OPC_DMULTU_G_2E = 0x1D | OPC_SPECIAL3,
 400    OPC_DDIV_G_2E   = 0x1E | OPC_SPECIAL3,
 401    OPC_DDIVU_G_2E  = 0x1F | OPC_SPECIAL3,
 402    OPC_MOD_G_2E    = 0x22 | OPC_SPECIAL3,
 403    OPC_MODU_G_2E   = 0x23 | OPC_SPECIAL3,
 404    OPC_DMOD_G_2E   = 0x26 | OPC_SPECIAL3,
 405    OPC_DMODU_G_2E  = 0x27 | OPC_SPECIAL3,
 406
 407    /* MIPS DSP Load */
 408    OPC_LX_DSP         = 0x0A | OPC_SPECIAL3,
 409    /* MIPS DSP Arithmetic */
 410    OPC_ADDU_QB_DSP    = 0x10 | OPC_SPECIAL3,
 411    OPC_ADDU_OB_DSP    = 0x14 | OPC_SPECIAL3,
 412    OPC_ABSQ_S_PH_DSP  = 0x12 | OPC_SPECIAL3,
 413    OPC_ABSQ_S_QH_DSP  = 0x16 | OPC_SPECIAL3,
 414    /* OPC_ADDUH_QB_DSP is same as OPC_MULT_G_2E.  */
 415    /* OPC_ADDUH_QB_DSP   = 0x18 | OPC_SPECIAL3,  */
 416    OPC_CMPU_EQ_QB_DSP = 0x11 | OPC_SPECIAL3,
 417    OPC_CMPU_EQ_OB_DSP = 0x15 | OPC_SPECIAL3,
 418    /* MIPS DSP GPR-Based Shift Sub-class */
 419    OPC_SHLL_QB_DSP    = 0x13 | OPC_SPECIAL3,
 420    OPC_SHLL_OB_DSP    = 0x17 | OPC_SPECIAL3,
 421    /* MIPS DSP Multiply Sub-class insns */
 422    /* OPC_MUL_PH_DSP is same as OPC_ADDUH_QB_DSP.  */
 423    /* OPC_MUL_PH_DSP     = 0x18 | OPC_SPECIAL3,  */
 424    OPC_DPA_W_PH_DSP   = 0x30 | OPC_SPECIAL3,
 425    OPC_DPAQ_W_QH_DSP  = 0x34 | OPC_SPECIAL3,
 426    /* DSP Bit/Manipulation Sub-class */
 427    OPC_INSV_DSP       = 0x0C | OPC_SPECIAL3,
 428    OPC_DINSV_DSP      = 0x0D | OPC_SPECIAL3,
 429    /* MIPS DSP Append Sub-class */
 430    OPC_APPEND_DSP     = 0x31 | OPC_SPECIAL3,
 431    OPC_DAPPEND_DSP    = 0x35 | OPC_SPECIAL3,
 432    /* MIPS DSP Accumulator and DSPControl Access Sub-class */
 433    OPC_EXTR_W_DSP     = 0x38 | OPC_SPECIAL3,
 434    OPC_DEXTR_W_DSP    = 0x3C | OPC_SPECIAL3,
 435
 436    /* EVA */
 437    OPC_LWLE           = 0x19 | OPC_SPECIAL3,
 438    OPC_LWRE           = 0x1A | OPC_SPECIAL3,
 439    OPC_CACHEE         = 0x1B | OPC_SPECIAL3,
 440    OPC_SBE            = 0x1C | OPC_SPECIAL3,
 441    OPC_SHE            = 0x1D | OPC_SPECIAL3,
 442    OPC_SCE            = 0x1E | OPC_SPECIAL3,
 443    OPC_SWE            = 0x1F | OPC_SPECIAL3,
 444    OPC_SWLE           = 0x21 | OPC_SPECIAL3,
 445    OPC_SWRE           = 0x22 | OPC_SPECIAL3,
 446    OPC_PREFE          = 0x23 | OPC_SPECIAL3,
 447    OPC_LBUE           = 0x28 | OPC_SPECIAL3,
 448    OPC_LHUE           = 0x29 | OPC_SPECIAL3,
 449    OPC_LBE            = 0x2C | OPC_SPECIAL3,
 450    OPC_LHE            = 0x2D | OPC_SPECIAL3,
 451    OPC_LLE            = 0x2E | OPC_SPECIAL3,
 452    OPC_LWE            = 0x2F | OPC_SPECIAL3,
 453
 454    /* R6 */
 455    R6_OPC_PREF        = 0x35 | OPC_SPECIAL3,
 456    R6_OPC_CACHE       = 0x25 | OPC_SPECIAL3,
 457    R6_OPC_LL          = 0x36 | OPC_SPECIAL3,
 458    R6_OPC_SC          = 0x26 | OPC_SPECIAL3,
 459    R6_OPC_LLD         = 0x37 | OPC_SPECIAL3,
 460    R6_OPC_SCD         = 0x27 | OPC_SPECIAL3,
 461};
 462
 463/* BSHFL opcodes */
 464#define MASK_BSHFL(op)              (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
 465
 466enum {
 467    OPC_WSBH      = (0x02 << 6) | OPC_BSHFL,
 468    OPC_SEB       = (0x10 << 6) | OPC_BSHFL,
 469    OPC_SEH       = (0x18 << 6) | OPC_BSHFL,
 470    OPC_ALIGN     = (0x08 << 6) | OPC_BSHFL, /* 010.bp (010.00 to 010.11) */
 471    OPC_ALIGN_1   = (0x09 << 6) | OPC_BSHFL,
 472    OPC_ALIGN_2   = (0x0A << 6) | OPC_BSHFL,
 473    OPC_ALIGN_3   = (0x0B << 6) | OPC_BSHFL,
 474    OPC_BITSWAP   = (0x00 << 6) | OPC_BSHFL  /* 00000 */
 475};
 476
 477/* DBSHFL opcodes */
 478#define MASK_DBSHFL(op)             (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
 479
 480enum {
 481    OPC_DSBH       = (0x02 << 6) | OPC_DBSHFL,
 482    OPC_DSHD       = (0x05 << 6) | OPC_DBSHFL,
 483    OPC_DALIGN     = (0x08 << 6) | OPC_DBSHFL, /* 01.bp (01.000 to 01.111) */
 484    OPC_DALIGN_1   = (0x09 << 6) | OPC_DBSHFL,
 485    OPC_DALIGN_2   = (0x0A << 6) | OPC_DBSHFL,
 486    OPC_DALIGN_3   = (0x0B << 6) | OPC_DBSHFL,
 487    OPC_DALIGN_4   = (0x0C << 6) | OPC_DBSHFL,
 488    OPC_DALIGN_5   = (0x0D << 6) | OPC_DBSHFL,
 489    OPC_DALIGN_6   = (0x0E << 6) | OPC_DBSHFL,
 490    OPC_DALIGN_7   = (0x0F << 6) | OPC_DBSHFL,
 491    OPC_DBITSWAP   = (0x00 << 6) | OPC_DBSHFL, /* 00000 */
 492};
 493
 494/* MIPS DSP REGIMM opcodes */
 495enum {
 496    OPC_BPOSGE32 = (0x1C << 16) | OPC_REGIMM,
 497    OPC_BPOSGE64 = (0x1D << 16) | OPC_REGIMM,
 498};
 499
 500#define MASK_LX(op)                 (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
 501/* MIPS DSP Load */
 502enum {
 503    OPC_LBUX = (0x06 << 6) | OPC_LX_DSP,
 504    OPC_LHX  = (0x04 << 6) | OPC_LX_DSP,
 505    OPC_LWX  = (0x00 << 6) | OPC_LX_DSP,
 506    OPC_LDX = (0x08 << 6) | OPC_LX_DSP,
 507};
 508
 509#define MASK_ADDU_QB(op)            (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
 510enum {
 511    /* MIPS DSP Arithmetic Sub-class */
 512    OPC_ADDQ_PH        = (0x0A << 6) | OPC_ADDU_QB_DSP,
 513    OPC_ADDQ_S_PH      = (0x0E << 6) | OPC_ADDU_QB_DSP,
 514    OPC_ADDQ_S_W       = (0x16 << 6) | OPC_ADDU_QB_DSP,
 515    OPC_ADDU_QB        = (0x00 << 6) | OPC_ADDU_QB_DSP,
 516    OPC_ADDU_S_QB      = (0x04 << 6) | OPC_ADDU_QB_DSP,
 517    OPC_ADDU_PH        = (0x08 << 6) | OPC_ADDU_QB_DSP,
 518    OPC_ADDU_S_PH      = (0x0C << 6) | OPC_ADDU_QB_DSP,
 519    OPC_SUBQ_PH        = (0x0B << 6) | OPC_ADDU_QB_DSP,
 520    OPC_SUBQ_S_PH      = (0x0F << 6) | OPC_ADDU_QB_DSP,
 521    OPC_SUBQ_S_W       = (0x17 << 6) | OPC_ADDU_QB_DSP,
 522    OPC_SUBU_QB        = (0x01 << 6) | OPC_ADDU_QB_DSP,
 523    OPC_SUBU_S_QB      = (0x05 << 6) | OPC_ADDU_QB_DSP,
 524    OPC_SUBU_PH        = (0x09 << 6) | OPC_ADDU_QB_DSP,
 525    OPC_SUBU_S_PH      = (0x0D << 6) | OPC_ADDU_QB_DSP,
 526    OPC_ADDSC          = (0x10 << 6) | OPC_ADDU_QB_DSP,
 527    OPC_ADDWC          = (0x11 << 6) | OPC_ADDU_QB_DSP,
 528    OPC_MODSUB         = (0x12 << 6) | OPC_ADDU_QB_DSP,
 529    OPC_RADDU_W_QB     = (0x14 << 6) | OPC_ADDU_QB_DSP,
 530    /* MIPS DSP Multiply Sub-class insns */
 531    OPC_MULEU_S_PH_QBL = (0x06 << 6) | OPC_ADDU_QB_DSP,
 532    OPC_MULEU_S_PH_QBR = (0x07 << 6) | OPC_ADDU_QB_DSP,
 533    OPC_MULQ_RS_PH     = (0x1F << 6) | OPC_ADDU_QB_DSP,
 534    OPC_MULEQ_S_W_PHL  = (0x1C << 6) | OPC_ADDU_QB_DSP,
 535    OPC_MULEQ_S_W_PHR  = (0x1D << 6) | OPC_ADDU_QB_DSP,
 536    OPC_MULQ_S_PH      = (0x1E << 6) | OPC_ADDU_QB_DSP,
 537};
 538
 539#define OPC_ADDUH_QB_DSP OPC_MULT_G_2E
 540#define MASK_ADDUH_QB(op)           (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
 541enum {
 542    /* MIPS DSP Arithmetic Sub-class */
 543    OPC_ADDUH_QB   = (0x00 << 6) | OPC_ADDUH_QB_DSP,
 544    OPC_ADDUH_R_QB = (0x02 << 6) | OPC_ADDUH_QB_DSP,
 545    OPC_ADDQH_PH   = (0x08 << 6) | OPC_ADDUH_QB_DSP,
 546    OPC_ADDQH_R_PH = (0x0A << 6) | OPC_ADDUH_QB_DSP,
 547    OPC_ADDQH_W    = (0x10 << 6) | OPC_ADDUH_QB_DSP,
 548    OPC_ADDQH_R_W  = (0x12 << 6) | OPC_ADDUH_QB_DSP,
 549    OPC_SUBUH_QB   = (0x01 << 6) | OPC_ADDUH_QB_DSP,
 550    OPC_SUBUH_R_QB = (0x03 << 6) | OPC_ADDUH_QB_DSP,
 551    OPC_SUBQH_PH   = (0x09 << 6) | OPC_ADDUH_QB_DSP,
 552    OPC_SUBQH_R_PH = (0x0B << 6) | OPC_ADDUH_QB_DSP,
 553    OPC_SUBQH_W    = (0x11 << 6) | OPC_ADDUH_QB_DSP,
 554    OPC_SUBQH_R_W  = (0x13 << 6) | OPC_ADDUH_QB_DSP,
 555    /* MIPS DSP Multiply Sub-class insns */
 556    OPC_MUL_PH     = (0x0C << 6) | OPC_ADDUH_QB_DSP,
 557    OPC_MUL_S_PH   = (0x0E << 6) | OPC_ADDUH_QB_DSP,
 558    OPC_MULQ_S_W   = (0x16 << 6) | OPC_ADDUH_QB_DSP,
 559    OPC_MULQ_RS_W  = (0x17 << 6) | OPC_ADDUH_QB_DSP,
 560};
 561
 562#define MASK_ABSQ_S_PH(op)          (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
 563enum {
 564    /* MIPS DSP Arithmetic Sub-class */
 565    OPC_ABSQ_S_QB       = (0x01 << 6) | OPC_ABSQ_S_PH_DSP,
 566    OPC_ABSQ_S_PH       = (0x09 << 6) | OPC_ABSQ_S_PH_DSP,
 567    OPC_ABSQ_S_W        = (0x11 << 6) | OPC_ABSQ_S_PH_DSP,
 568    OPC_PRECEQ_W_PHL    = (0x0C << 6) | OPC_ABSQ_S_PH_DSP,
 569    OPC_PRECEQ_W_PHR    = (0x0D << 6) | OPC_ABSQ_S_PH_DSP,
 570    OPC_PRECEQU_PH_QBL  = (0x04 << 6) | OPC_ABSQ_S_PH_DSP,
 571    OPC_PRECEQU_PH_QBR  = (0x05 << 6) | OPC_ABSQ_S_PH_DSP,
 572    OPC_PRECEQU_PH_QBLA = (0x06 << 6) | OPC_ABSQ_S_PH_DSP,
 573    OPC_PRECEQU_PH_QBRA = (0x07 << 6) | OPC_ABSQ_S_PH_DSP,
 574    OPC_PRECEU_PH_QBL   = (0x1C << 6) | OPC_ABSQ_S_PH_DSP,
 575    OPC_PRECEU_PH_QBR   = (0x1D << 6) | OPC_ABSQ_S_PH_DSP,
 576    OPC_PRECEU_PH_QBLA  = (0x1E << 6) | OPC_ABSQ_S_PH_DSP,
 577    OPC_PRECEU_PH_QBRA  = (0x1F << 6) | OPC_ABSQ_S_PH_DSP,
 578    /* DSP Bit/Manipulation Sub-class */
 579    OPC_BITREV          = (0x1B << 6) | OPC_ABSQ_S_PH_DSP,
 580    OPC_REPL_QB         = (0x02 << 6) | OPC_ABSQ_S_PH_DSP,
 581    OPC_REPLV_QB        = (0x03 << 6) | OPC_ABSQ_S_PH_DSP,
 582    OPC_REPL_PH         = (0x0A << 6) | OPC_ABSQ_S_PH_DSP,
 583    OPC_REPLV_PH        = (0x0B << 6) | OPC_ABSQ_S_PH_DSP,
 584};
 585
 586#define MASK_CMPU_EQ_QB(op)         (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
 587enum {
 588    /* MIPS DSP Arithmetic Sub-class */
 589    OPC_PRECR_QB_PH      = (0x0D << 6) | OPC_CMPU_EQ_QB_DSP,
 590    OPC_PRECRQ_QB_PH     = (0x0C << 6) | OPC_CMPU_EQ_QB_DSP,
 591    OPC_PRECR_SRA_PH_W   = (0x1E << 6) | OPC_CMPU_EQ_QB_DSP,
 592    OPC_PRECR_SRA_R_PH_W = (0x1F << 6) | OPC_CMPU_EQ_QB_DSP,
 593    OPC_PRECRQ_PH_W      = (0x14 << 6) | OPC_CMPU_EQ_QB_DSP,
 594    OPC_PRECRQ_RS_PH_W   = (0x15 << 6) | OPC_CMPU_EQ_QB_DSP,
 595    OPC_PRECRQU_S_QB_PH  = (0x0F << 6) | OPC_CMPU_EQ_QB_DSP,
 596    /* DSP Compare-Pick Sub-class */
 597    OPC_CMPU_EQ_QB       = (0x00 << 6) | OPC_CMPU_EQ_QB_DSP,
 598    OPC_CMPU_LT_QB       = (0x01 << 6) | OPC_CMPU_EQ_QB_DSP,
 599    OPC_CMPU_LE_QB       = (0x02 << 6) | OPC_CMPU_EQ_QB_DSP,
 600    OPC_CMPGU_EQ_QB      = (0x04 << 6) | OPC_CMPU_EQ_QB_DSP,
 601    OPC_CMPGU_LT_QB      = (0x05 << 6) | OPC_CMPU_EQ_QB_DSP,
 602    OPC_CMPGU_LE_QB      = (0x06 << 6) | OPC_CMPU_EQ_QB_DSP,
 603    OPC_CMPGDU_EQ_QB     = (0x18 << 6) | OPC_CMPU_EQ_QB_DSP,
 604    OPC_CMPGDU_LT_QB     = (0x19 << 6) | OPC_CMPU_EQ_QB_DSP,
 605    OPC_CMPGDU_LE_QB     = (0x1A << 6) | OPC_CMPU_EQ_QB_DSP,
 606    OPC_CMP_EQ_PH        = (0x08 << 6) | OPC_CMPU_EQ_QB_DSP,
 607    OPC_CMP_LT_PH        = (0x09 << 6) | OPC_CMPU_EQ_QB_DSP,
 608    OPC_CMP_LE_PH        = (0x0A << 6) | OPC_CMPU_EQ_QB_DSP,
 609    OPC_PICK_QB          = (0x03 << 6) | OPC_CMPU_EQ_QB_DSP,
 610    OPC_PICK_PH          = (0x0B << 6) | OPC_CMPU_EQ_QB_DSP,
 611    OPC_PACKRL_PH        = (0x0E << 6) | OPC_CMPU_EQ_QB_DSP,
 612};
 613
 614#define MASK_SHLL_QB(op)            (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
 615enum {
 616    /* MIPS DSP GPR-Based Shift Sub-class */
 617    OPC_SHLL_QB    = (0x00 << 6) | OPC_SHLL_QB_DSP,
 618    OPC_SHLLV_QB   = (0x02 << 6) | OPC_SHLL_QB_DSP,
 619    OPC_SHLL_PH    = (0x08 << 6) | OPC_SHLL_QB_DSP,
 620    OPC_SHLLV_PH   = (0x0A << 6) | OPC_SHLL_QB_DSP,
 621    OPC_SHLL_S_PH  = (0x0C << 6) | OPC_SHLL_QB_DSP,
 622    OPC_SHLLV_S_PH = (0x0E << 6) | OPC_SHLL_QB_DSP,
 623    OPC_SHLL_S_W   = (0x14 << 6) | OPC_SHLL_QB_DSP,
 624    OPC_SHLLV_S_W  = (0x16 << 6) | OPC_SHLL_QB_DSP,
 625    OPC_SHRL_QB    = (0x01 << 6) | OPC_SHLL_QB_DSP,
 626    OPC_SHRLV_QB   = (0x03 << 6) | OPC_SHLL_QB_DSP,
 627    OPC_SHRL_PH    = (0x19 << 6) | OPC_SHLL_QB_DSP,
 628    OPC_SHRLV_PH   = (0x1B << 6) | OPC_SHLL_QB_DSP,
 629    OPC_SHRA_QB    = (0x04 << 6) | OPC_SHLL_QB_DSP,
 630    OPC_SHRA_R_QB  = (0x05 << 6) | OPC_SHLL_QB_DSP,
 631    OPC_SHRAV_QB   = (0x06 << 6) | OPC_SHLL_QB_DSP,
 632    OPC_SHRAV_R_QB = (0x07 << 6) | OPC_SHLL_QB_DSP,
 633    OPC_SHRA_PH    = (0x09 << 6) | OPC_SHLL_QB_DSP,
 634    OPC_SHRAV_PH   = (0x0B << 6) | OPC_SHLL_QB_DSP,
 635    OPC_SHRA_R_PH  = (0x0D << 6) | OPC_SHLL_QB_DSP,
 636    OPC_SHRAV_R_PH = (0x0F << 6) | OPC_SHLL_QB_DSP,
 637    OPC_SHRA_R_W   = (0x15 << 6) | OPC_SHLL_QB_DSP,
 638    OPC_SHRAV_R_W  = (0x17 << 6) | OPC_SHLL_QB_DSP,
 639};
 640
 641#define MASK_DPA_W_PH(op)           (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
 642enum {
 643    /* MIPS DSP Multiply Sub-class insns */
 644    OPC_DPAU_H_QBL    = (0x03 << 6) | OPC_DPA_W_PH_DSP,
 645    OPC_DPAU_H_QBR    = (0x07 << 6) | OPC_DPA_W_PH_DSP,
 646    OPC_DPSU_H_QBL    = (0x0B << 6) | OPC_DPA_W_PH_DSP,
 647    OPC_DPSU_H_QBR    = (0x0F << 6) | OPC_DPA_W_PH_DSP,
 648    OPC_DPA_W_PH      = (0x00 << 6) | OPC_DPA_W_PH_DSP,
 649    OPC_DPAX_W_PH     = (0x08 << 6) | OPC_DPA_W_PH_DSP,
 650    OPC_DPAQ_S_W_PH   = (0x04 << 6) | OPC_DPA_W_PH_DSP,
 651    OPC_DPAQX_S_W_PH  = (0x18 << 6) | OPC_DPA_W_PH_DSP,
 652    OPC_DPAQX_SA_W_PH = (0x1A << 6) | OPC_DPA_W_PH_DSP,
 653    OPC_DPS_W_PH      = (0x01 << 6) | OPC_DPA_W_PH_DSP,
 654    OPC_DPSX_W_PH     = (0x09 << 6) | OPC_DPA_W_PH_DSP,
 655    OPC_DPSQ_S_W_PH   = (0x05 << 6) | OPC_DPA_W_PH_DSP,
 656    OPC_DPSQX_S_W_PH  = (0x19 << 6) | OPC_DPA_W_PH_DSP,
 657    OPC_DPSQX_SA_W_PH = (0x1B << 6) | OPC_DPA_W_PH_DSP,
 658    OPC_MULSAQ_S_W_PH = (0x06 << 6) | OPC_DPA_W_PH_DSP,
 659    OPC_DPAQ_SA_L_W   = (0x0C << 6) | OPC_DPA_W_PH_DSP,
 660    OPC_DPSQ_SA_L_W   = (0x0D << 6) | OPC_DPA_W_PH_DSP,
 661    OPC_MAQ_S_W_PHL   = (0x14 << 6) | OPC_DPA_W_PH_DSP,
 662    OPC_MAQ_S_W_PHR   = (0x16 << 6) | OPC_DPA_W_PH_DSP,
 663    OPC_MAQ_SA_W_PHL  = (0x10 << 6) | OPC_DPA_W_PH_DSP,
 664    OPC_MAQ_SA_W_PHR  = (0x12 << 6) | OPC_DPA_W_PH_DSP,
 665    OPC_MULSA_W_PH    = (0x02 << 6) | OPC_DPA_W_PH_DSP,
 666};
 667
 668#define MASK_INSV(op)               (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
 669enum {
 670    /* DSP Bit/Manipulation Sub-class */
 671    OPC_INSV = (0x00 << 6) | OPC_INSV_DSP,
 672};
 673
 674#define MASK_APPEND(op)             (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
 675enum {
 676    /* MIPS DSP Append Sub-class */
 677    OPC_APPEND  = (0x00 << 6) | OPC_APPEND_DSP,
 678    OPC_PREPEND = (0x01 << 6) | OPC_APPEND_DSP,
 679    OPC_BALIGN  = (0x10 << 6) | OPC_APPEND_DSP,
 680};
 681
 682#define MASK_EXTR_W(op)             (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
 683enum {
 684    /* MIPS DSP Accumulator and DSPControl Access Sub-class */
 685    OPC_EXTR_W     = (0x00 << 6) | OPC_EXTR_W_DSP,
 686    OPC_EXTR_R_W   = (0x04 << 6) | OPC_EXTR_W_DSP,
 687    OPC_EXTR_RS_W  = (0x06 << 6) | OPC_EXTR_W_DSP,
 688    OPC_EXTR_S_H   = (0x0E << 6) | OPC_EXTR_W_DSP,
 689    OPC_EXTRV_S_H  = (0x0F << 6) | OPC_EXTR_W_DSP,
 690    OPC_EXTRV_W    = (0x01 << 6) | OPC_EXTR_W_DSP,
 691    OPC_EXTRV_R_W  = (0x05 << 6) | OPC_EXTR_W_DSP,
 692    OPC_EXTRV_RS_W = (0x07 << 6) | OPC_EXTR_W_DSP,
 693    OPC_EXTP       = (0x02 << 6) | OPC_EXTR_W_DSP,
 694    OPC_EXTPV      = (0x03 << 6) | OPC_EXTR_W_DSP,
 695    OPC_EXTPDP     = (0x0A << 6) | OPC_EXTR_W_DSP,
 696    OPC_EXTPDPV    = (0x0B << 6) | OPC_EXTR_W_DSP,
 697    OPC_SHILO      = (0x1A << 6) | OPC_EXTR_W_DSP,
 698    OPC_SHILOV     = (0x1B << 6) | OPC_EXTR_W_DSP,
 699    OPC_MTHLIP     = (0x1F << 6) | OPC_EXTR_W_DSP,
 700    OPC_WRDSP      = (0x13 << 6) | OPC_EXTR_W_DSP,
 701    OPC_RDDSP      = (0x12 << 6) | OPC_EXTR_W_DSP,
 702};
 703
 704#define MASK_ABSQ_S_QH(op)          (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
 705enum {
 706    /* MIPS DSP Arithmetic Sub-class */
 707    OPC_PRECEQ_L_PWL    = (0x14 << 6) | OPC_ABSQ_S_QH_DSP,
 708    OPC_PRECEQ_L_PWR    = (0x15 << 6) | OPC_ABSQ_S_QH_DSP,
 709    OPC_PRECEQ_PW_QHL   = (0x0C << 6) | OPC_ABSQ_S_QH_DSP,
 710    OPC_PRECEQ_PW_QHR   = (0x0D << 6) | OPC_ABSQ_S_QH_DSP,
 711    OPC_PRECEQ_PW_QHLA  = (0x0E << 6) | OPC_ABSQ_S_QH_DSP,
 712    OPC_PRECEQ_PW_QHRA  = (0x0F << 6) | OPC_ABSQ_S_QH_DSP,
 713    OPC_PRECEQU_QH_OBL  = (0x04 << 6) | OPC_ABSQ_S_QH_DSP,
 714    OPC_PRECEQU_QH_OBR  = (0x05 << 6) | OPC_ABSQ_S_QH_DSP,
 715    OPC_PRECEQU_QH_OBLA = (0x06 << 6) | OPC_ABSQ_S_QH_DSP,
 716    OPC_PRECEQU_QH_OBRA = (0x07 << 6) | OPC_ABSQ_S_QH_DSP,
 717    OPC_PRECEU_QH_OBL   = (0x1C << 6) | OPC_ABSQ_S_QH_DSP,
 718    OPC_PRECEU_QH_OBR   = (0x1D << 6) | OPC_ABSQ_S_QH_DSP,
 719    OPC_PRECEU_QH_OBLA  = (0x1E << 6) | OPC_ABSQ_S_QH_DSP,
 720    OPC_PRECEU_QH_OBRA  = (0x1F << 6) | OPC_ABSQ_S_QH_DSP,
 721    OPC_ABSQ_S_OB       = (0x01 << 6) | OPC_ABSQ_S_QH_DSP,
 722    OPC_ABSQ_S_PW       = (0x11 << 6) | OPC_ABSQ_S_QH_DSP,
 723    OPC_ABSQ_S_QH       = (0x09 << 6) | OPC_ABSQ_S_QH_DSP,
 724    /* DSP Bit/Manipulation Sub-class */
 725    OPC_REPL_OB         = (0x02 << 6) | OPC_ABSQ_S_QH_DSP,
 726    OPC_REPL_PW         = (0x12 << 6) | OPC_ABSQ_S_QH_DSP,
 727    OPC_REPL_QH         = (0x0A << 6) | OPC_ABSQ_S_QH_DSP,
 728    OPC_REPLV_OB        = (0x03 << 6) | OPC_ABSQ_S_QH_DSP,
 729    OPC_REPLV_PW        = (0x13 << 6) | OPC_ABSQ_S_QH_DSP,
 730    OPC_REPLV_QH        = (0x0B << 6) | OPC_ABSQ_S_QH_DSP,
 731};
 732
 733#define MASK_ADDU_OB(op)            (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
 734enum {
 735    /* MIPS DSP Multiply Sub-class insns */
 736    OPC_MULEQ_S_PW_QHL = (0x1C << 6) | OPC_ADDU_OB_DSP,
 737    OPC_MULEQ_S_PW_QHR = (0x1D << 6) | OPC_ADDU_OB_DSP,
 738    OPC_MULEU_S_QH_OBL = (0x06 << 6) | OPC_ADDU_OB_DSP,
 739    OPC_MULEU_S_QH_OBR = (0x07 << 6) | OPC_ADDU_OB_DSP,
 740    OPC_MULQ_RS_QH     = (0x1F << 6) | OPC_ADDU_OB_DSP,
 741    /* MIPS DSP Arithmetic Sub-class */
 742    OPC_RADDU_L_OB     = (0x14 << 6) | OPC_ADDU_OB_DSP,
 743    OPC_SUBQ_PW        = (0x13 << 6) | OPC_ADDU_OB_DSP,
 744    OPC_SUBQ_S_PW      = (0x17 << 6) | OPC_ADDU_OB_DSP,
 745    OPC_SUBQ_QH        = (0x0B << 6) | OPC_ADDU_OB_DSP,
 746    OPC_SUBQ_S_QH      = (0x0F << 6) | OPC_ADDU_OB_DSP,
 747    OPC_SUBU_OB        = (0x01 << 6) | OPC_ADDU_OB_DSP,
 748    OPC_SUBU_S_OB      = (0x05 << 6) | OPC_ADDU_OB_DSP,
 749    OPC_SUBU_QH        = (0x09 << 6) | OPC_ADDU_OB_DSP,
 750    OPC_SUBU_S_QH      = (0x0D << 6) | OPC_ADDU_OB_DSP,
 751    OPC_SUBUH_OB       = (0x19 << 6) | OPC_ADDU_OB_DSP,
 752    OPC_SUBUH_R_OB     = (0x1B << 6) | OPC_ADDU_OB_DSP,
 753    OPC_ADDQ_PW        = (0x12 << 6) | OPC_ADDU_OB_DSP,
 754    OPC_ADDQ_S_PW      = (0x16 << 6) | OPC_ADDU_OB_DSP,
 755    OPC_ADDQ_QH        = (0x0A << 6) | OPC_ADDU_OB_DSP,
 756    OPC_ADDQ_S_QH      = (0x0E << 6) | OPC_ADDU_OB_DSP,
 757    OPC_ADDU_OB        = (0x00 << 6) | OPC_ADDU_OB_DSP,
 758    OPC_ADDU_S_OB      = (0x04 << 6) | OPC_ADDU_OB_DSP,
 759    OPC_ADDU_QH        = (0x08 << 6) | OPC_ADDU_OB_DSP,
 760    OPC_ADDU_S_QH      = (0x0C << 6) | OPC_ADDU_OB_DSP,
 761    OPC_ADDUH_OB       = (0x18 << 6) | OPC_ADDU_OB_DSP,
 762    OPC_ADDUH_R_OB     = (0x1A << 6) | OPC_ADDU_OB_DSP,
 763};
 764
 765#define MASK_CMPU_EQ_OB(op)         (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
 766enum {
 767    /* DSP Compare-Pick Sub-class */
 768    OPC_CMP_EQ_PW         = (0x10 << 6) | OPC_CMPU_EQ_OB_DSP,
 769    OPC_CMP_LT_PW         = (0x11 << 6) | OPC_CMPU_EQ_OB_DSP,
 770    OPC_CMP_LE_PW         = (0x12 << 6) | OPC_CMPU_EQ_OB_DSP,
 771    OPC_CMP_EQ_QH         = (0x08 << 6) | OPC_CMPU_EQ_OB_DSP,
 772    OPC_CMP_LT_QH         = (0x09 << 6) | OPC_CMPU_EQ_OB_DSP,
 773    OPC_CMP_LE_QH         = (0x0A << 6) | OPC_CMPU_EQ_OB_DSP,
 774    OPC_CMPGDU_EQ_OB      = (0x18 << 6) | OPC_CMPU_EQ_OB_DSP,
 775    OPC_CMPGDU_LT_OB      = (0x19 << 6) | OPC_CMPU_EQ_OB_DSP,
 776    OPC_CMPGDU_LE_OB      = (0x1A << 6) | OPC_CMPU_EQ_OB_DSP,
 777    OPC_CMPGU_EQ_OB       = (0x04 << 6) | OPC_CMPU_EQ_OB_DSP,
 778    OPC_CMPGU_LT_OB       = (0x05 << 6) | OPC_CMPU_EQ_OB_DSP,
 779    OPC_CMPGU_LE_OB       = (0x06 << 6) | OPC_CMPU_EQ_OB_DSP,
 780    OPC_CMPU_EQ_OB        = (0x00 << 6) | OPC_CMPU_EQ_OB_DSP,
 781    OPC_CMPU_LT_OB        = (0x01 << 6) | OPC_CMPU_EQ_OB_DSP,
 782    OPC_CMPU_LE_OB        = (0x02 << 6) | OPC_CMPU_EQ_OB_DSP,
 783    OPC_PACKRL_PW         = (0x0E << 6) | OPC_CMPU_EQ_OB_DSP,
 784    OPC_PICK_OB           = (0x03 << 6) | OPC_CMPU_EQ_OB_DSP,
 785    OPC_PICK_PW           = (0x13 << 6) | OPC_CMPU_EQ_OB_DSP,
 786    OPC_PICK_QH           = (0x0B << 6) | OPC_CMPU_EQ_OB_DSP,
 787    /* MIPS DSP Arithmetic Sub-class */
 788    OPC_PRECR_OB_QH       = (0x0D << 6) | OPC_CMPU_EQ_OB_DSP,
 789    OPC_PRECR_SRA_QH_PW   = (0x1E << 6) | OPC_CMPU_EQ_OB_DSP,
 790    OPC_PRECR_SRA_R_QH_PW = (0x1F << 6) | OPC_CMPU_EQ_OB_DSP,
 791    OPC_PRECRQ_OB_QH      = (0x0C << 6) | OPC_CMPU_EQ_OB_DSP,
 792    OPC_PRECRQ_PW_L       = (0x1C << 6) | OPC_CMPU_EQ_OB_DSP,
 793    OPC_PRECRQ_QH_PW      = (0x14 << 6) | OPC_CMPU_EQ_OB_DSP,
 794    OPC_PRECRQ_RS_QH_PW   = (0x15 << 6) | OPC_CMPU_EQ_OB_DSP,
 795    OPC_PRECRQU_S_OB_QH   = (0x0F << 6) | OPC_CMPU_EQ_OB_DSP,
 796};
 797
 798#define MASK_DAPPEND(op)            (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
 799enum {
 800    /* DSP Append Sub-class */
 801    OPC_DAPPEND  = (0x00 << 6) | OPC_DAPPEND_DSP,
 802    OPC_PREPENDD = (0x03 << 6) | OPC_DAPPEND_DSP,
 803    OPC_PREPENDW = (0x01 << 6) | OPC_DAPPEND_DSP,
 804    OPC_DBALIGN  = (0x10 << 6) | OPC_DAPPEND_DSP,
 805};
 806
 807#define MASK_DEXTR_W(op)            (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
 808enum {
 809    /* MIPS DSP Accumulator and DSPControl Access Sub-class */
 810    OPC_DMTHLIP     = (0x1F << 6) | OPC_DEXTR_W_DSP,
 811    OPC_DSHILO      = (0x1A << 6) | OPC_DEXTR_W_DSP,
 812    OPC_DEXTP       = (0x02 << 6) | OPC_DEXTR_W_DSP,
 813    OPC_DEXTPDP     = (0x0A << 6) | OPC_DEXTR_W_DSP,
 814    OPC_DEXTPDPV    = (0x0B << 6) | OPC_DEXTR_W_DSP,
 815    OPC_DEXTPV      = (0x03 << 6) | OPC_DEXTR_W_DSP,
 816    OPC_DEXTR_L     = (0x10 << 6) | OPC_DEXTR_W_DSP,
 817    OPC_DEXTR_R_L   = (0x14 << 6) | OPC_DEXTR_W_DSP,
 818    OPC_DEXTR_RS_L  = (0x16 << 6) | OPC_DEXTR_W_DSP,
 819    OPC_DEXTR_W     = (0x00 << 6) | OPC_DEXTR_W_DSP,
 820    OPC_DEXTR_R_W   = (0x04 << 6) | OPC_DEXTR_W_DSP,
 821    OPC_DEXTR_RS_W  = (0x06 << 6) | OPC_DEXTR_W_DSP,
 822    OPC_DEXTR_S_H   = (0x0E << 6) | OPC_DEXTR_W_DSP,
 823    OPC_DEXTRV_L    = (0x11 << 6) | OPC_DEXTR_W_DSP,
 824    OPC_DEXTRV_R_L  = (0x15 << 6) | OPC_DEXTR_W_DSP,
 825    OPC_DEXTRV_RS_L = (0x17 << 6) | OPC_DEXTR_W_DSP,
 826    OPC_DEXTRV_S_H  = (0x0F << 6) | OPC_DEXTR_W_DSP,
 827    OPC_DEXTRV_W    = (0x01 << 6) | OPC_DEXTR_W_DSP,
 828    OPC_DEXTRV_R_W  = (0x05 << 6) | OPC_DEXTR_W_DSP,
 829    OPC_DEXTRV_RS_W = (0x07 << 6) | OPC_DEXTR_W_DSP,
 830    OPC_DSHILOV     = (0x1B << 6) | OPC_DEXTR_W_DSP,
 831};
 832
 833#define MASK_DINSV(op)              (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
 834enum {
 835    /* DSP Bit/Manipulation Sub-class */
 836    OPC_DINSV = (0x00 << 6) | OPC_DINSV_DSP,
 837};
 838
 839#define MASK_DPAQ_W_QH(op)          (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
 840enum {
 841    /* MIPS DSP Multiply Sub-class insns */
 842    OPC_DMADD         = (0x19 << 6) | OPC_DPAQ_W_QH_DSP,
 843    OPC_DMADDU        = (0x1D << 6) | OPC_DPAQ_W_QH_DSP,
 844    OPC_DMSUB         = (0x1B << 6) | OPC_DPAQ_W_QH_DSP,
 845    OPC_DMSUBU        = (0x1F << 6) | OPC_DPAQ_W_QH_DSP,
 846    OPC_DPA_W_QH      = (0x00 << 6) | OPC_DPAQ_W_QH_DSP,
 847    OPC_DPAQ_S_W_QH   = (0x04 << 6) | OPC_DPAQ_W_QH_DSP,
 848    OPC_DPAQ_SA_L_PW  = (0x0C << 6) | OPC_DPAQ_W_QH_DSP,
 849    OPC_DPAU_H_OBL    = (0x03 << 6) | OPC_DPAQ_W_QH_DSP,
 850    OPC_DPAU_H_OBR    = (0x07 << 6) | OPC_DPAQ_W_QH_DSP,
 851    OPC_DPS_W_QH      = (0x01 << 6) | OPC_DPAQ_W_QH_DSP,
 852    OPC_DPSQ_S_W_QH   = (0x05 << 6) | OPC_DPAQ_W_QH_DSP,
 853    OPC_DPSQ_SA_L_PW  = (0x0D << 6) | OPC_DPAQ_W_QH_DSP,
 854    OPC_DPSU_H_OBL    = (0x0B << 6) | OPC_DPAQ_W_QH_DSP,
 855    OPC_DPSU_H_OBR    = (0x0F << 6) | OPC_DPAQ_W_QH_DSP,
 856    OPC_MAQ_S_L_PWL   = (0x1C << 6) | OPC_DPAQ_W_QH_DSP,
 857    OPC_MAQ_S_L_PWR   = (0x1E << 6) | OPC_DPAQ_W_QH_DSP,
 858    OPC_MAQ_S_W_QHLL  = (0x14 << 6) | OPC_DPAQ_W_QH_DSP,
 859    OPC_MAQ_SA_W_QHLL = (0x10 << 6) | OPC_DPAQ_W_QH_DSP,
 860    OPC_MAQ_S_W_QHLR  = (0x15 << 6) | OPC_DPAQ_W_QH_DSP,
 861    OPC_MAQ_SA_W_QHLR = (0x11 << 6) | OPC_DPAQ_W_QH_DSP,
 862    OPC_MAQ_S_W_QHRL  = (0x16 << 6) | OPC_DPAQ_W_QH_DSP,
 863    OPC_MAQ_SA_W_QHRL = (0x12 << 6) | OPC_DPAQ_W_QH_DSP,
 864    OPC_MAQ_S_W_QHRR  = (0x17 << 6) | OPC_DPAQ_W_QH_DSP,
 865    OPC_MAQ_SA_W_QHRR = (0x13 << 6) | OPC_DPAQ_W_QH_DSP,
 866    OPC_MULSAQ_S_L_PW = (0x0E << 6) | OPC_DPAQ_W_QH_DSP,
 867    OPC_MULSAQ_S_W_QH = (0x06 << 6) | OPC_DPAQ_W_QH_DSP,
 868};
 869
 870#define MASK_SHLL_OB(op)            (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
 871enum {
 872    /* MIPS DSP GPR-Based Shift Sub-class */
 873    OPC_SHLL_PW    = (0x10 << 6) | OPC_SHLL_OB_DSP,
 874    OPC_SHLL_S_PW  = (0x14 << 6) | OPC_SHLL_OB_DSP,
 875    OPC_SHLLV_OB   = (0x02 << 6) | OPC_SHLL_OB_DSP,
 876    OPC_SHLLV_PW   = (0x12 << 6) | OPC_SHLL_OB_DSP,
 877    OPC_SHLLV_S_PW = (0x16 << 6) | OPC_SHLL_OB_DSP,
 878    OPC_SHLLV_QH   = (0x0A << 6) | OPC_SHLL_OB_DSP,
 879    OPC_SHLLV_S_QH = (0x0E << 6) | OPC_SHLL_OB_DSP,
 880    OPC_SHRA_PW    = (0x11 << 6) | OPC_SHLL_OB_DSP,
 881    OPC_SHRA_R_PW  = (0x15 << 6) | OPC_SHLL_OB_DSP,
 882    OPC_SHRAV_OB   = (0x06 << 6) | OPC_SHLL_OB_DSP,
 883    OPC_SHRAV_R_OB = (0x07 << 6) | OPC_SHLL_OB_DSP,
 884    OPC_SHRAV_PW   = (0x13 << 6) | OPC_SHLL_OB_DSP,
 885    OPC_SHRAV_R_PW = (0x17 << 6) | OPC_SHLL_OB_DSP,
 886    OPC_SHRAV_QH   = (0x0B << 6) | OPC_SHLL_OB_DSP,
 887    OPC_SHRAV_R_QH = (0x0F << 6) | OPC_SHLL_OB_DSP,
 888    OPC_SHRLV_OB   = (0x03 << 6) | OPC_SHLL_OB_DSP,
 889    OPC_SHRLV_QH   = (0x1B << 6) | OPC_SHLL_OB_DSP,
 890    OPC_SHLL_OB    = (0x00 << 6) | OPC_SHLL_OB_DSP,
 891    OPC_SHLL_QH    = (0x08 << 6) | OPC_SHLL_OB_DSP,
 892    OPC_SHLL_S_QH  = (0x0C << 6) | OPC_SHLL_OB_DSP,
 893    OPC_SHRA_OB    = (0x04 << 6) | OPC_SHLL_OB_DSP,
 894    OPC_SHRA_R_OB  = (0x05 << 6) | OPC_SHLL_OB_DSP,
 895    OPC_SHRA_QH    = (0x09 << 6) | OPC_SHLL_OB_DSP,
 896    OPC_SHRA_R_QH  = (0x0D << 6) | OPC_SHLL_OB_DSP,
 897    OPC_SHRL_OB    = (0x01 << 6) | OPC_SHLL_OB_DSP,
 898    OPC_SHRL_QH    = (0x19 << 6) | OPC_SHLL_OB_DSP,
 899};
 900
 901/* Coprocessor 0 (rs field) */
 902#define MASK_CP0(op)                (MASK_OP_MAJOR(op) | (op & (0x1F << 21)))
 903
 904enum {
 905    OPC_MFC0     = (0x00 << 21) | OPC_CP0,
 906    OPC_DMFC0    = (0x01 << 21) | OPC_CP0,
 907    OPC_MFHC0    = (0x02 << 21) | OPC_CP0,
 908    OPC_MTC0     = (0x04 << 21) | OPC_CP0,
 909    OPC_DMTC0    = (0x05 << 21) | OPC_CP0,
 910    OPC_MTHC0    = (0x06 << 21) | OPC_CP0,
 911    OPC_MFTR     = (0x08 << 21) | OPC_CP0,
 912    OPC_RDPGPR   = (0x0A << 21) | OPC_CP0,
 913    OPC_MFMC0    = (0x0B << 21) | OPC_CP0,
 914    OPC_MTTR     = (0x0C << 21) | OPC_CP0,
 915    OPC_WRPGPR   = (0x0E << 21) | OPC_CP0,
 916    OPC_C0       = (0x10 << 21) | OPC_CP0,
 917    OPC_C0_1     = (0x11 << 21) | OPC_CP0,
 918    OPC_C0_2     = (0x12 << 21) | OPC_CP0,
 919    OPC_C0_3     = (0x13 << 21) | OPC_CP0,
 920    OPC_C0_4     = (0x14 << 21) | OPC_CP0,
 921    OPC_C0_5     = (0x15 << 21) | OPC_CP0,
 922    OPC_C0_6     = (0x16 << 21) | OPC_CP0,
 923    OPC_C0_7     = (0x17 << 21) | OPC_CP0,
 924    OPC_C0_8     = (0x18 << 21) | OPC_CP0,
 925    OPC_C0_9     = (0x19 << 21) | OPC_CP0,
 926    OPC_C0_A     = (0x1A << 21) | OPC_CP0,
 927    OPC_C0_B     = (0x1B << 21) | OPC_CP0,
 928    OPC_C0_C     = (0x1C << 21) | OPC_CP0,
 929    OPC_C0_D     = (0x1D << 21) | OPC_CP0,
 930    OPC_C0_E     = (0x1E << 21) | OPC_CP0,
 931    OPC_C0_F     = (0x1F << 21) | OPC_CP0,
 932};
 933
 934/* MFMC0 opcodes */
 935#define MASK_MFMC0(op)              (MASK_CP0(op) | (op & 0xFFFF))
 936
 937enum {
 938    OPC_DMT      = 0x01 | (0 << 5) | (0x0F << 6) | (0x01 << 11) | OPC_MFMC0,
 939    OPC_EMT      = 0x01 | (1 << 5) | (0x0F << 6) | (0x01 << 11) | OPC_MFMC0,
 940    OPC_DVPE     = 0x01 | (0 << 5) | OPC_MFMC0,
 941    OPC_EVPE     = 0x01 | (1 << 5) | OPC_MFMC0,
 942    OPC_DI       = (0 << 5) | (0x0C << 11) | OPC_MFMC0,
 943    OPC_EI       = (1 << 5) | (0x0C << 11) | OPC_MFMC0,
 944    OPC_DVP      = 0x04 | (0 << 3) | (1 << 5) | (0 << 11) | OPC_MFMC0,
 945    OPC_EVP      = 0x04 | (0 << 3) | (0 << 5) | (0 << 11) | OPC_MFMC0,
 946};
 947
 948/* Coprocessor 0 (with rs == C0) */
 949#define MASK_C0(op)                 (MASK_CP0(op) | (op & 0x3F))
 950
 951enum {
 952    OPC_TLBR     = 0x01 | OPC_C0,
 953    OPC_TLBWI    = 0x02 | OPC_C0,
 954    OPC_TLBINV   = 0x03 | OPC_C0,
 955    OPC_TLBINVF  = 0x04 | OPC_C0,
 956    OPC_TLBWR    = 0x06 | OPC_C0,
 957    OPC_TLBP     = 0x08 | OPC_C0,
 958    OPC_RFE      = 0x10 | OPC_C0,
 959    OPC_ERET     = 0x18 | OPC_C0,
 960    OPC_DERET    = 0x1F | OPC_C0,
 961    OPC_WAIT     = 0x20 | OPC_C0,
 962};
 963
 964/* Coprocessor 1 (rs field) */
 965#define MASK_CP1(op)                (MASK_OP_MAJOR(op) | (op & (0x1F << 21)))
 966
 967/* Values for the fmt field in FP instructions */
 968enum {
 969    /* 0 - 15 are reserved */
 970    FMT_S = 16,          /* single fp */
 971    FMT_D = 17,          /* double fp */
 972    FMT_E = 18,          /* extended fp */
 973    FMT_Q = 19,          /* quad fp */
 974    FMT_W = 20,          /* 32-bit fixed */
 975    FMT_L = 21,          /* 64-bit fixed */
 976    FMT_PS = 22,         /* paired single fp */
 977    /* 23 - 31 are reserved */
 978};
 979
 980enum {
 981    OPC_MFC1     = (0x00 << 21) | OPC_CP1,
 982    OPC_DMFC1    = (0x01 << 21) | OPC_CP1,
 983    OPC_CFC1     = (0x02 << 21) | OPC_CP1,
 984    OPC_MFHC1    = (0x03 << 21) | OPC_CP1,
 985    OPC_MTC1     = (0x04 << 21) | OPC_CP1,
 986    OPC_DMTC1    = (0x05 << 21) | OPC_CP1,
 987    OPC_CTC1     = (0x06 << 21) | OPC_CP1,
 988    OPC_MTHC1    = (0x07 << 21) | OPC_CP1,
 989    OPC_BC1      = (0x08 << 21) | OPC_CP1, /* bc */
 990    OPC_BC1ANY2  = (0x09 << 21) | OPC_CP1,
 991    OPC_BC1ANY4  = (0x0A << 21) | OPC_CP1,
 992    OPC_BZ_V     = (0x0B << 21) | OPC_CP1,
 993    OPC_BNZ_V    = (0x0F << 21) | OPC_CP1,
 994    OPC_S_FMT    = (FMT_S << 21) | OPC_CP1,
 995    OPC_D_FMT    = (FMT_D << 21) | OPC_CP1,
 996    OPC_E_FMT    = (FMT_E << 21) | OPC_CP1,
 997    OPC_Q_FMT    = (FMT_Q << 21) | OPC_CP1,
 998    OPC_W_FMT    = (FMT_W << 21) | OPC_CP1,
 999    OPC_L_FMT    = (FMT_L << 21) | OPC_CP1,
1000    OPC_PS_FMT   = (FMT_PS << 21) | OPC_CP1,
1001    OPC_BC1EQZ   = (0x09 << 21) | OPC_CP1,
1002    OPC_BC1NEZ   = (0x0D << 21) | OPC_CP1,
1003    OPC_BZ_B     = (0x18 << 21) | OPC_CP1,
1004    OPC_BZ_H     = (0x19 << 21) | OPC_CP1,
1005    OPC_BZ_W     = (0x1A << 21) | OPC_CP1,
1006    OPC_BZ_D     = (0x1B << 21) | OPC_CP1,
1007    OPC_BNZ_B    = (0x1C << 21) | OPC_CP1,
1008    OPC_BNZ_H    = (0x1D << 21) | OPC_CP1,
1009    OPC_BNZ_W    = (0x1E << 21) | OPC_CP1,
1010    OPC_BNZ_D    = (0x1F << 21) | OPC_CP1,
1011};
1012
1013#define MASK_CP1_FUNC(op)           (MASK_CP1(op) | (op & 0x3F))
1014#define MASK_BC1(op)                (MASK_CP1(op) | (op & (0x3 << 16)))
1015
1016enum {
1017    OPC_BC1F     = (0x00 << 16) | OPC_BC1,
1018    OPC_BC1T     = (0x01 << 16) | OPC_BC1,
1019    OPC_BC1FL    = (0x02 << 16) | OPC_BC1,
1020    OPC_BC1TL    = (0x03 << 16) | OPC_BC1,
1021};
1022
1023enum {
1024    OPC_BC1FANY2     = (0x00 << 16) | OPC_BC1ANY2,
1025    OPC_BC1TANY2     = (0x01 << 16) | OPC_BC1ANY2,
1026};
1027
1028enum {
1029    OPC_BC1FANY4     = (0x00 << 16) | OPC_BC1ANY4,
1030    OPC_BC1TANY4     = (0x01 << 16) | OPC_BC1ANY4,
1031};
1032
1033#define MASK_CP2(op)                (MASK_OP_MAJOR(op) | (op & (0x1F << 21)))
1034
1035enum {
1036    OPC_MFC2    = (0x00 << 21) | OPC_CP2,
1037    OPC_DMFC2   = (0x01 << 21) | OPC_CP2,
1038    OPC_CFC2    = (0x02 << 21) | OPC_CP2,
1039    OPC_MFHC2   = (0x03 << 21) | OPC_CP2,
1040    OPC_MTC2    = (0x04 << 21) | OPC_CP2,
1041    OPC_DMTC2   = (0x05 << 21) | OPC_CP2,
1042    OPC_CTC2    = (0x06 << 21) | OPC_CP2,
1043    OPC_MTHC2   = (0x07 << 21) | OPC_CP2,
1044    OPC_BC2     = (0x08 << 21) | OPC_CP2,
1045    OPC_BC2EQZ  = (0x09 << 21) | OPC_CP2,
1046    OPC_BC2NEZ  = (0x0D << 21) | OPC_CP2,
1047};
1048
1049#define MASK_LMI(op)    (MASK_OP_MAJOR(op) | (op & (0x1F << 21)) | (op & 0x1F))
1050
1051enum {
1052    OPC_PADDSH      = (24 << 21) | (0x00) | OPC_CP2,
1053    OPC_PADDUSH     = (25 << 21) | (0x00) | OPC_CP2,
1054    OPC_PADDH       = (26 << 21) | (0x00) | OPC_CP2,
1055    OPC_PADDW       = (27 << 21) | (0x00) | OPC_CP2,
1056    OPC_PADDSB      = (28 << 21) | (0x00) | OPC_CP2,
1057    OPC_PADDUSB     = (29 << 21) | (0x00) | OPC_CP2,
1058    OPC_PADDB       = (30 << 21) | (0x00) | OPC_CP2,
1059    OPC_PADDD       = (31 << 21) | (0x00) | OPC_CP2,
1060
1061    OPC_PSUBSH      = (24 << 21) | (0x01) | OPC_CP2,
1062    OPC_PSUBUSH     = (25 << 21) | (0x01) | OPC_CP2,
1063    OPC_PSUBH       = (26 << 21) | (0x01) | OPC_CP2,
1064    OPC_PSUBW       = (27 << 21) | (0x01) | OPC_CP2,
1065    OPC_PSUBSB      = (28 << 21) | (0x01) | OPC_CP2,
1066    OPC_PSUBUSB     = (29 << 21) | (0x01) | OPC_CP2,
1067    OPC_PSUBB       = (30 << 21) | (0x01) | OPC_CP2,
1068    OPC_PSUBD       = (31 << 21) | (0x01) | OPC_CP2,
1069
1070    OPC_PSHUFH      = (24 << 21) | (0x02) | OPC_CP2,
1071    OPC_PACKSSWH    = (25 << 21) | (0x02) | OPC_CP2,
1072    OPC_PACKSSHB    = (26 << 21) | (0x02) | OPC_CP2,
1073    OPC_PACKUSHB    = (27 << 21) | (0x02) | OPC_CP2,
1074    OPC_XOR_CP2     = (28 << 21) | (0x02) | OPC_CP2,
1075    OPC_NOR_CP2     = (29 << 21) | (0x02) | OPC_CP2,
1076    OPC_AND_CP2     = (30 << 21) | (0x02) | OPC_CP2,
1077    OPC_PANDN       = (31 << 21) | (0x02) | OPC_CP2,
1078
1079    OPC_PUNPCKLHW   = (24 << 21) | (0x03) | OPC_CP2,
1080    OPC_PUNPCKHHW   = (25 << 21) | (0x03) | OPC_CP2,
1081    OPC_PUNPCKLBH   = (26 << 21) | (0x03) | OPC_CP2,
1082    OPC_PUNPCKHBH   = (27 << 21) | (0x03) | OPC_CP2,
1083    OPC_PINSRH_0    = (28 << 21) | (0x03) | OPC_CP2,
1084    OPC_PINSRH_1    = (29 << 21) | (0x03) | OPC_CP2,
1085    OPC_PINSRH_2    = (30 << 21) | (0x03) | OPC_CP2,
1086    OPC_PINSRH_3    = (31 << 21) | (0x03) | OPC_CP2,
1087
1088    OPC_PAVGH       = (24 << 21) | (0x08) | OPC_CP2,
1089    OPC_PAVGB       = (25 << 21) | (0x08) | OPC_CP2,
1090    OPC_PMAXSH      = (26 << 21) | (0x08) | OPC_CP2,
1091    OPC_PMINSH      = (27 << 21) | (0x08) | OPC_CP2,
1092    OPC_PMAXUB      = (28 << 21) | (0x08) | OPC_CP2,
1093    OPC_PMINUB      = (29 << 21) | (0x08) | OPC_CP2,
1094
1095    OPC_PCMPEQW     = (24 << 21) | (0x09) | OPC_CP2,
1096    OPC_PCMPGTW     = (25 << 21) | (0x09) | OPC_CP2,
1097    OPC_PCMPEQH     = (26 << 21) | (0x09) | OPC_CP2,
1098    OPC_PCMPGTH     = (27 << 21) | (0x09) | OPC_CP2,
1099    OPC_PCMPEQB     = (28 << 21) | (0x09) | OPC_CP2,
1100    OPC_PCMPGTB     = (29 << 21) | (0x09) | OPC_CP2,
1101
1102    OPC_PSLLW       = (24 << 21) | (0x0A) | OPC_CP2,
1103    OPC_PSLLH       = (25 << 21) | (0x0A) | OPC_CP2,
1104    OPC_PMULLH      = (26 << 21) | (0x0A) | OPC_CP2,
1105    OPC_PMULHH      = (27 << 21) | (0x0A) | OPC_CP2,
1106    OPC_PMULUW      = (28 << 21) | (0x0A) | OPC_CP2,
1107    OPC_PMULHUH     = (29 << 21) | (0x0A) | OPC_CP2,
1108
1109    OPC_PSRLW       = (24 << 21) | (0x0B) | OPC_CP2,
1110    OPC_PSRLH       = (25 << 21) | (0x0B) | OPC_CP2,
1111    OPC_PSRAW       = (26 << 21) | (0x0B) | OPC_CP2,
1112    OPC_PSRAH       = (27 << 21) | (0x0B) | OPC_CP2,
1113    OPC_PUNPCKLWD   = (28 << 21) | (0x0B) | OPC_CP2,
1114    OPC_PUNPCKHWD   = (29 << 21) | (0x0B) | OPC_CP2,
1115
1116    OPC_ADDU_CP2    = (24 << 21) | (0x0C) | OPC_CP2,
1117    OPC_OR_CP2      = (25 << 21) | (0x0C) | OPC_CP2,
1118    OPC_ADD_CP2     = (26 << 21) | (0x0C) | OPC_CP2,
1119    OPC_DADD_CP2    = (27 << 21) | (0x0C) | OPC_CP2,
1120    OPC_SEQU_CP2    = (28 << 21) | (0x0C) | OPC_CP2,
1121    OPC_SEQ_CP2     = (29 << 21) | (0x0C) | OPC_CP2,
1122
1123    OPC_SUBU_CP2    = (24 << 21) | (0x0D) | OPC_CP2,
1124    OPC_PASUBUB     = (25 << 21) | (0x0D) | OPC_CP2,
1125    OPC_SUB_CP2     = (26 << 21) | (0x0D) | OPC_CP2,
1126    OPC_DSUB_CP2    = (27 << 21) | (0x0D) | OPC_CP2,
1127    OPC_SLTU_CP2    = (28 << 21) | (0x0D) | OPC_CP2,
1128    OPC_SLT_CP2     = (29 << 21) | (0x0D) | OPC_CP2,
1129
1130    OPC_SLL_CP2     = (24 << 21) | (0x0E) | OPC_CP2,
1131    OPC_DSLL_CP2    = (25 << 21) | (0x0E) | OPC_CP2,
1132    OPC_PEXTRH      = (26 << 21) | (0x0E) | OPC_CP2,
1133    OPC_PMADDHW     = (27 << 21) | (0x0E) | OPC_CP2,
1134    OPC_SLEU_CP2    = (28 << 21) | (0x0E) | OPC_CP2,
1135    OPC_SLE_CP2     = (29 << 21) | (0x0E) | OPC_CP2,
1136
1137    OPC_SRL_CP2     = (24 << 21) | (0x0F) | OPC_CP2,
1138    OPC_DSRL_CP2    = (25 << 21) | (0x0F) | OPC_CP2,
1139    OPC_SRA_CP2     = (26 << 21) | (0x0F) | OPC_CP2,
1140    OPC_DSRA_CP2    = (27 << 21) | (0x0F) | OPC_CP2,
1141    OPC_BIADD       = (28 << 21) | (0x0F) | OPC_CP2,
1142    OPC_PMOVMSKB    = (29 << 21) | (0x0F) | OPC_CP2,
1143};
1144
1145
1146#define MASK_CP3(op)                (MASK_OP_MAJOR(op) | (op & 0x3F))
1147
1148enum {
1149    OPC_LWXC1       = 0x00 | OPC_CP3,
1150    OPC_LDXC1       = 0x01 | OPC_CP3,
1151    OPC_LUXC1       = 0x05 | OPC_CP3,
1152    OPC_SWXC1       = 0x08 | OPC_CP3,
1153    OPC_SDXC1       = 0x09 | OPC_CP3,
1154    OPC_SUXC1       = 0x0D | OPC_CP3,
1155    OPC_PREFX       = 0x0F | OPC_CP3,
1156    OPC_ALNV_PS     = 0x1E | OPC_CP3,
1157    OPC_MADD_S      = 0x20 | OPC_CP3,
1158    OPC_MADD_D      = 0x21 | OPC_CP3,
1159    OPC_MADD_PS     = 0x26 | OPC_CP3,
1160    OPC_MSUB_S      = 0x28 | OPC_CP3,
1161    OPC_MSUB_D      = 0x29 | OPC_CP3,
1162    OPC_MSUB_PS     = 0x2E | OPC_CP3,
1163    OPC_NMADD_S     = 0x30 | OPC_CP3,
1164    OPC_NMADD_D     = 0x31 | OPC_CP3,
1165    OPC_NMADD_PS    = 0x36 | OPC_CP3,
1166    OPC_NMSUB_S     = 0x38 | OPC_CP3,
1167    OPC_NMSUB_D     = 0x39 | OPC_CP3,
1168    OPC_NMSUB_PS    = 0x3E | OPC_CP3,
1169};
1170
1171/* MSA Opcodes */
1172#define MASK_MSA_MINOR(op)          (MASK_OP_MAJOR(op) | (op & 0x3F))
1173enum {
1174    OPC_MSA_I8_00   = 0x00 | OPC_MSA,
1175    OPC_MSA_I8_01   = 0x01 | OPC_MSA,
1176    OPC_MSA_I8_02   = 0x02 | OPC_MSA,
1177    OPC_MSA_I5_06   = 0x06 | OPC_MSA,
1178    OPC_MSA_I5_07   = 0x07 | OPC_MSA,
1179    OPC_MSA_BIT_09  = 0x09 | OPC_MSA,
1180    OPC_MSA_BIT_0A  = 0x0A | OPC_MSA,
1181    OPC_MSA_3R_0D   = 0x0D | OPC_MSA,
1182    OPC_MSA_3R_0E   = 0x0E | OPC_MSA,
1183    OPC_MSA_3R_0F   = 0x0F | OPC_MSA,
1184    OPC_MSA_3R_10   = 0x10 | OPC_MSA,
1185    OPC_MSA_3R_11   = 0x11 | OPC_MSA,
1186    OPC_MSA_3R_12   = 0x12 | OPC_MSA,
1187    OPC_MSA_3R_13   = 0x13 | OPC_MSA,
1188    OPC_MSA_3R_14   = 0x14 | OPC_MSA,
1189    OPC_MSA_3R_15   = 0x15 | OPC_MSA,
1190    OPC_MSA_ELM     = 0x19 | OPC_MSA,
1191    OPC_MSA_3RF_1A  = 0x1A | OPC_MSA,
1192    OPC_MSA_3RF_1B  = 0x1B | OPC_MSA,
1193    OPC_MSA_3RF_1C  = 0x1C | OPC_MSA,
1194    OPC_MSA_VEC     = 0x1E | OPC_MSA,
1195
1196    /* MI10 instruction */
1197    OPC_LD_B        = (0x20) | OPC_MSA,
1198    OPC_LD_H        = (0x21) | OPC_MSA,
1199    OPC_LD_W        = (0x22) | OPC_MSA,
1200    OPC_LD_D        = (0x23) | OPC_MSA,
1201    OPC_ST_B        = (0x24) | OPC_MSA,
1202    OPC_ST_H        = (0x25) | OPC_MSA,
1203    OPC_ST_W        = (0x26) | OPC_MSA,
1204    OPC_ST_D        = (0x27) | OPC_MSA,
1205};
1206
1207enum {
1208    /* I5 instruction df(bits 22..21) = _b, _h, _w, _d */
1209    OPC_ADDVI_df    = (0x0 << 23) | OPC_MSA_I5_06,
1210    OPC_CEQI_df     = (0x0 << 23) | OPC_MSA_I5_07,
1211    OPC_SUBVI_df    = (0x1 << 23) | OPC_MSA_I5_06,
1212    OPC_MAXI_S_df   = (0x2 << 23) | OPC_MSA_I5_06,
1213    OPC_CLTI_S_df   = (0x2 << 23) | OPC_MSA_I5_07,
1214    OPC_MAXI_U_df   = (0x3 << 23) | OPC_MSA_I5_06,
1215    OPC_CLTI_U_df   = (0x3 << 23) | OPC_MSA_I5_07,
1216    OPC_MINI_S_df   = (0x4 << 23) | OPC_MSA_I5_06,
1217    OPC_CLEI_S_df   = (0x4 << 23) | OPC_MSA_I5_07,
1218    OPC_MINI_U_df   = (0x5 << 23) | OPC_MSA_I5_06,
1219    OPC_CLEI_U_df   = (0x5 << 23) | OPC_MSA_I5_07,
1220    OPC_LDI_df      = (0x6 << 23) | OPC_MSA_I5_07,
1221
1222    /* I8 instruction */
1223    OPC_ANDI_B      = (0x0 << 24) | OPC_MSA_I8_00,
1224    OPC_BMNZI_B     = (0x0 << 24) | OPC_MSA_I8_01,
1225    OPC_SHF_B       = (0x0 << 24) | OPC_MSA_I8_02,
1226    OPC_ORI_B       = (0x1 << 24) | OPC_MSA_I8_00,
1227    OPC_BMZI_B      = (0x1 << 24) | OPC_MSA_I8_01,
1228    OPC_SHF_H       = (0x1 << 24) | OPC_MSA_I8_02,
1229    OPC_NORI_B      = (0x2 << 24) | OPC_MSA_I8_00,
1230    OPC_BSELI_B     = (0x2 << 24) | OPC_MSA_I8_01,
1231    OPC_SHF_W       = (0x2 << 24) | OPC_MSA_I8_02,
1232    OPC_XORI_B      = (0x3 << 24) | OPC_MSA_I8_00,
1233
1234    /* VEC/2R/2RF instruction */
1235    OPC_AND_V       = (0x00 << 21) | OPC_MSA_VEC,
1236    OPC_OR_V        = (0x01 << 21) | OPC_MSA_VEC,
1237    OPC_NOR_V       = (0x02 << 21) | OPC_MSA_VEC,
1238    OPC_XOR_V       = (0x03 << 21) | OPC_MSA_VEC,
1239    OPC_BMNZ_V      = (0x04 << 21) | OPC_MSA_VEC,
1240    OPC_BMZ_V       = (0x05 << 21) | OPC_MSA_VEC,
1241    OPC_BSEL_V      = (0x06 << 21) | OPC_MSA_VEC,
1242
1243    OPC_MSA_2R      = (0x18 << 21) | OPC_MSA_VEC,
1244    OPC_MSA_2RF     = (0x19 << 21) | OPC_MSA_VEC,
1245
1246    /* 2R instruction df(bits 17..16) = _b, _h, _w, _d */
1247    OPC_FILL_df     = (0x00 << 18) | OPC_MSA_2R,
1248    OPC_PCNT_df     = (0x01 << 18) | OPC_MSA_2R,
1249    OPC_NLOC_df     = (0x02 << 18) | OPC_MSA_2R,
1250    OPC_NLZC_df     = (0x03 << 18) | OPC_MSA_2R,
1251
1252    /* 2RF instruction df(bit 16) = _w, _d */
1253    OPC_FCLASS_df   = (0x00 << 17) | OPC_MSA_2RF,
1254    OPC_FTRUNC_S_df = (0x01 << 17) | OPC_MSA_2RF,
1255    OPC_FTRUNC_U_df = (0x02 << 17) | OPC_MSA_2RF,
1256    OPC_FSQRT_df    = (0x03 << 17) | OPC_MSA_2RF,
1257    OPC_FRSQRT_df   = (0x04 << 17) | OPC_MSA_2RF,
1258    OPC_FRCP_df     = (0x05 << 17) | OPC_MSA_2RF,
1259    OPC_FRINT_df    = (0x06 << 17) | OPC_MSA_2RF,
1260    OPC_FLOG2_df    = (0x07 << 17) | OPC_MSA_2RF,
1261    OPC_FEXUPL_df   = (0x08 << 17) | OPC_MSA_2RF,
1262    OPC_FEXUPR_df   = (0x09 << 17) | OPC_MSA_2RF,
1263    OPC_FFQL_df     = (0x0A << 17) | OPC_MSA_2RF,
1264    OPC_FFQR_df     = (0x0B << 17) | OPC_MSA_2RF,
1265    OPC_FTINT_S_df  = (0x0C << 17) | OPC_MSA_2RF,
1266    OPC_FTINT_U_df  = (0x0D << 17) | OPC_MSA_2RF,
1267    OPC_FFINT_S_df  = (0x0E << 17) | OPC_MSA_2RF,
1268    OPC_FFINT_U_df  = (0x0F << 17) | OPC_MSA_2RF,
1269
1270    /* 3R instruction df(bits 22..21) = _b, _h, _w, d */
1271    OPC_SLL_df      = (0x0 << 23) | OPC_MSA_3R_0D,
1272    OPC_ADDV_df     = (0x0 << 23) | OPC_MSA_3R_0E,
1273    OPC_CEQ_df      = (0x0 << 23) | OPC_MSA_3R_0F,
1274    OPC_ADD_A_df    = (0x0 << 23) | OPC_MSA_3R_10,
1275    OPC_SUBS_S_df   = (0x0 << 23) | OPC_MSA_3R_11,
1276    OPC_MULV_df     = (0x0 << 23) | OPC_MSA_3R_12,
1277    OPC_DOTP_S_df   = (0x0 << 23) | OPC_MSA_3R_13,
1278    OPC_SLD_df      = (0x0 << 23) | OPC_MSA_3R_14,
1279    OPC_VSHF_df     = (0x0 << 23) | OPC_MSA_3R_15,
1280    OPC_SRA_df      = (0x1 << 23) | OPC_MSA_3R_0D,
1281    OPC_SUBV_df     = (0x1 << 23) | OPC_MSA_3R_0E,
1282    OPC_ADDS_A_df   = (0x1 << 23) | OPC_MSA_3R_10,
1283    OPC_SUBS_U_df   = (0x1 << 23) | OPC_MSA_3R_11,
1284    OPC_MADDV_df    = (0x1 << 23) | OPC_MSA_3R_12,
1285    OPC_DOTP_U_df   = (0x1 << 23) | OPC_MSA_3R_13,
1286    OPC_SPLAT_df    = (0x1 << 23) | OPC_MSA_3R_14,
1287    OPC_SRAR_df     = (0x1 << 23) | OPC_MSA_3R_15,
1288    OPC_SRL_df      = (0x2 << 23) | OPC_MSA_3R_0D,
1289    OPC_MAX_S_df    = (0x2 << 23) | OPC_MSA_3R_0E,
1290    OPC_CLT_S_df    = (0x2 << 23) | OPC_MSA_3R_0F,
1291    OPC_ADDS_S_df   = (0x2 << 23) | OPC_MSA_3R_10,
1292    OPC_SUBSUS_U_df = (0x2 << 23) | OPC_MSA_3R_11,
1293    OPC_MSUBV_df    = (0x2 << 23) | OPC_MSA_3R_12,
1294    OPC_DPADD_S_df  = (0x2 << 23) | OPC_MSA_3R_13,
1295    OPC_PCKEV_df    = (0x2 << 23) | OPC_MSA_3R_14,
1296    OPC_SRLR_df     = (0x2 << 23) | OPC_MSA_3R_15,
1297    OPC_BCLR_df     = (0x3 << 23) | OPC_MSA_3R_0D,
1298    OPC_MAX_U_df    = (0x3 << 23) | OPC_MSA_3R_0E,
1299    OPC_CLT_U_df    = (0x3 << 23) | OPC_MSA_3R_0F,
1300    OPC_ADDS_U_df   = (0x3 << 23) | OPC_MSA_3R_10,
1301    OPC_SUBSUU_S_df = (0x3 << 23) | OPC_MSA_3R_11,
1302    OPC_DPADD_U_df  = (0x3 << 23) | OPC_MSA_3R_13,
1303    OPC_PCKOD_df    = (0x3 << 23) | OPC_MSA_3R_14,
1304    OPC_BSET_df     = (0x4 << 23) | OPC_MSA_3R_0D,
1305    OPC_MIN_S_df    = (0x4 << 23) | OPC_MSA_3R_0E,
1306    OPC_CLE_S_df    = (0x4 << 23) | OPC_MSA_3R_0F,
1307    OPC_AVE_S_df    = (0x4 << 23) | OPC_MSA_3R_10,
1308    OPC_ASUB_S_df   = (0x4 << 23) | OPC_MSA_3R_11,
1309    OPC_DIV_S_df    = (0x4 << 23) | OPC_MSA_3R_12,
1310    OPC_DPSUB_S_df  = (0x4 << 23) | OPC_MSA_3R_13,
1311    OPC_ILVL_df     = (0x4 << 23) | OPC_MSA_3R_14,
1312    OPC_HADD_S_df   = (0x4 << 23) | OPC_MSA_3R_15,
1313    OPC_BNEG_df     = (0x5 << 23) | OPC_MSA_3R_0D,
1314    OPC_MIN_U_df    = (0x5 << 23) | OPC_MSA_3R_0E,
1315    OPC_CLE_U_df    = (0x5 << 23) | OPC_MSA_3R_0F,
1316    OPC_AVE_U_df    = (0x5 << 23) | OPC_MSA_3R_10,
1317    OPC_ASUB_U_df   = (0x5 << 23) | OPC_MSA_3R_11,
1318    OPC_DIV_U_df    = (0x5 << 23) | OPC_MSA_3R_12,
1319    OPC_DPSUB_U_df  = (0x5 << 23) | OPC_MSA_3R_13,
1320    OPC_ILVR_df     = (0x5 << 23) | OPC_MSA_3R_14,
1321    OPC_HADD_U_df   = (0x5 << 23) | OPC_MSA_3R_15,
1322    OPC_BINSL_df    = (0x6 << 23) | OPC_MSA_3R_0D,
1323    OPC_MAX_A_df    = (0x6 << 23) | OPC_MSA_3R_0E,
1324    OPC_AVER_S_df   = (0x6 << 23) | OPC_MSA_3R_10,
1325    OPC_MOD_S_df    = (0x6 << 23) | OPC_MSA_3R_12,
1326    OPC_ILVEV_df    = (0x6 << 23) | OPC_MSA_3R_14,
1327    OPC_HSUB_S_df   = (0x6 << 23) | OPC_MSA_3R_15,
1328    OPC_BINSR_df    = (0x7 << 23) | OPC_MSA_3R_0D,
1329    OPC_MIN_A_df    = (0x7 << 23) | OPC_MSA_3R_0E,
1330    OPC_AVER_U_df   = (0x7 << 23) | OPC_MSA_3R_10,
1331    OPC_MOD_U_df    = (0x7 << 23) | OPC_MSA_3R_12,
1332    OPC_ILVOD_df    = (0x7 << 23) | OPC_MSA_3R_14,
1333    OPC_HSUB_U_df   = (0x7 << 23) | OPC_MSA_3R_15,
1334
1335    /* ELM instructions df(bits 21..16) = _b, _h, _w, _d */
1336    OPC_SLDI_df     = (0x0 << 22) | (0x00 << 16) | OPC_MSA_ELM,
1337    OPC_CTCMSA      = (0x0 << 22) | (0x3E << 16) | OPC_MSA_ELM,
1338    OPC_SPLATI_df   = (0x1 << 22) | (0x00 << 16) | OPC_MSA_ELM,
1339    OPC_CFCMSA      = (0x1 << 22) | (0x3E << 16) | OPC_MSA_ELM,
1340    OPC_COPY_S_df   = (0x2 << 22) | (0x00 << 16) | OPC_MSA_ELM,
1341    OPC_MOVE_V      = (0x2 << 22) | (0x3E << 16) | OPC_MSA_ELM,
1342    OPC_COPY_U_df   = (0x3 << 22) | (0x00 << 16) | OPC_MSA_ELM,
1343    OPC_INSERT_df   = (0x4 << 22) | (0x00 << 16) | OPC_MSA_ELM,
1344    OPC_INSVE_df    = (0x5 << 22) | (0x00 << 16) | OPC_MSA_ELM,
1345
1346    /* 3RF instruction _df(bit 21) = _w, _d */
1347    OPC_FCAF_df     = (0x0 << 22) | OPC_MSA_3RF_1A,
1348    OPC_FADD_df     = (0x0 << 22) | OPC_MSA_3RF_1B,
1349    OPC_FCUN_df     = (0x1 << 22) | OPC_MSA_3RF_1A,
1350    OPC_FSUB_df     = (0x1 << 22) | OPC_MSA_3RF_1B,
1351    OPC_FCOR_df     = (0x1 << 22) | OPC_MSA_3RF_1C,
1352    OPC_FCEQ_df     = (0x2 << 22) | OPC_MSA_3RF_1A,
1353    OPC_FMUL_df     = (0x2 << 22) | OPC_MSA_3RF_1B,
1354    OPC_FCUNE_df    = (0x2 << 22) | OPC_MSA_3RF_1C,
1355    OPC_FCUEQ_df    = (0x3 << 22) | OPC_MSA_3RF_1A,
1356    OPC_FDIV_df     = (0x3 << 22) | OPC_MSA_3RF_1B,
1357    OPC_FCNE_df     = (0x3 << 22) | OPC_MSA_3RF_1C,
1358    OPC_FCLT_df     = (0x4 << 22) | OPC_MSA_3RF_1A,
1359    OPC_FMADD_df    = (0x4 << 22) | OPC_MSA_3RF_1B,
1360    OPC_MUL_Q_df    = (0x4 << 22) | OPC_MSA_3RF_1C,
1361    OPC_FCULT_df    = (0x5 << 22) | OPC_MSA_3RF_1A,
1362    OPC_FMSUB_df    = (0x5 << 22) | OPC_MSA_3RF_1B,
1363    OPC_MADD_Q_df   = (0x5 << 22) | OPC_MSA_3RF_1C,
1364    OPC_FCLE_df     = (0x6 << 22) | OPC_MSA_3RF_1A,
1365    OPC_MSUB_Q_df   = (0x6 << 22) | OPC_MSA_3RF_1C,
1366    OPC_FCULE_df    = (0x7 << 22) | OPC_MSA_3RF_1A,
1367    OPC_FEXP2_df    = (0x7 << 22) | OPC_MSA_3RF_1B,
1368    OPC_FSAF_df     = (0x8 << 22) | OPC_MSA_3RF_1A,
1369    OPC_FEXDO_df    = (0x8 << 22) | OPC_MSA_3RF_1B,
1370    OPC_FSUN_df     = (0x9 << 22) | OPC_MSA_3RF_1A,
1371    OPC_FSOR_df     = (0x9 << 22) | OPC_MSA_3RF_1C,
1372    OPC_FSEQ_df     = (0xA << 22) | OPC_MSA_3RF_1A,
1373    OPC_FTQ_df      = (0xA << 22) | OPC_MSA_3RF_1B,
1374    OPC_FSUNE_df    = (0xA << 22) | OPC_MSA_3RF_1C,
1375    OPC_FSUEQ_df    = (0xB << 22) | OPC_MSA_3RF_1A,
1376    OPC_FSNE_df     = (0xB << 22) | OPC_MSA_3RF_1C,
1377    OPC_FSLT_df     = (0xC << 22) | OPC_MSA_3RF_1A,
1378    OPC_FMIN_df     = (0xC << 22) | OPC_MSA_3RF_1B,
1379    OPC_MULR_Q_df   = (0xC << 22) | OPC_MSA_3RF_1C,
1380    OPC_FSULT_df    = (0xD << 22) | OPC_MSA_3RF_1A,
1381    OPC_FMIN_A_df   = (0xD << 22) | OPC_MSA_3RF_1B,
1382    OPC_MADDR_Q_df  = (0xD << 22) | OPC_MSA_3RF_1C,
1383    OPC_FSLE_df     = (0xE << 22) | OPC_MSA_3RF_1A,
1384    OPC_FMAX_df     = (0xE << 22) | OPC_MSA_3RF_1B,
1385    OPC_MSUBR_Q_df  = (0xE << 22) | OPC_MSA_3RF_1C,
1386    OPC_FSULE_df    = (0xF << 22) | OPC_MSA_3RF_1A,
1387    OPC_FMAX_A_df   = (0xF << 22) | OPC_MSA_3RF_1B,
1388
1389    /* BIT instruction df(bits 22..16) = _B _H _W _D */
1390    OPC_SLLI_df     = (0x0 << 23) | OPC_MSA_BIT_09,
1391    OPC_SAT_S_df    = (0x0 << 23) | OPC_MSA_BIT_0A,
1392    OPC_SRAI_df     = (0x1 << 23) | OPC_MSA_BIT_09,
1393    OPC_SAT_U_df    = (0x1 << 23) | OPC_MSA_BIT_0A,
1394    OPC_SRLI_df     = (0x2 << 23) | OPC_MSA_BIT_09,
1395    OPC_SRARI_df    = (0x2 << 23) | OPC_MSA_BIT_0A,
1396    OPC_BCLRI_df    = (0x3 << 23) | OPC_MSA_BIT_09,
1397    OPC_SRLRI_df    = (0x3 << 23) | OPC_MSA_BIT_0A,
1398    OPC_BSETI_df    = (0x4 << 23) | OPC_MSA_BIT_09,
1399    OPC_BNEGI_df    = (0x5 << 23) | OPC_MSA_BIT_09,
1400    OPC_BINSLI_df   = (0x6 << 23) | OPC_MSA_BIT_09,
1401    OPC_BINSRI_df   = (0x7 << 23) | OPC_MSA_BIT_09,
1402};
1403
1404
1405/*
1406 *
1407 *       AN OVERVIEW OF MXU EXTENSION INSTRUCTION SET
1408 *       ============================================
1409 *
1410 *
1411 * MXU (full name: MIPS eXtension/enhanced Unit) is a SIMD extension of MIPS32
1412 * instructions set. It is designed to fit the needs of signal, graphical and
1413 * video processing applications. MXU instruction set is used in Xburst family
1414 * of microprocessors by Ingenic.
1415 *
1416 * MXU unit contains 17 registers called X0-X16. X0 is always zero, and X16 is
1417 * the control register.
1418 *
1419 *
1420 *     The notation used in MXU assembler mnemonics
1421 *     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1422 *
1423 *  Register operands:
1424 *
1425 *   XRa, XRb, XRc, XRd - MXU registers
1426 *   Rb, Rc, Rd, Rs, Rt - general purpose MIPS registers
1427 *
1428 *  Non-register operands:
1429 *
1430 *   aptn1 - 1-bit accumulate add/subtract pattern
1431 *   aptn2 - 2-bit accumulate add/subtract pattern
1432 *   eptn2 - 2-bit execute add/subtract pattern
1433 *   optn2 - 2-bit operand pattern
1434 *   optn3 - 3-bit operand pattern
1435 *   sft4  - 4-bit shift amount
1436 *   strd2 - 2-bit stride amount
1437 *
1438 *  Prefixes:
1439 *
1440 *   Level of parallelism:                Operand size:
1441 *    S - single operation at a time       32 - word
1442 *    D - two operations in parallel       16 - half word
1443 *    Q - four operations in parallel       8 - byte
1444 *
1445 *  Operations:
1446 *
1447 *   ADD   - Add or subtract
1448 *   ADDC  - Add with carry-in
1449 *   ACC   - Accumulate
1450 *   ASUM  - Sum together then accumulate (add or subtract)
1451 *   ASUMC - Sum together then accumulate (add or subtract) with carry-in
1452 *   AVG   - Average between 2 operands
1453 *   ABD   - Absolute difference
1454 *   ALN   - Align data
1455 *   AND   - Logical bitwise 'and' operation
1456 *   CPS   - Copy sign
1457 *   EXTR  - Extract bits
1458 *   I2M   - Move from GPR register to MXU register
1459 *   LDD   - Load data from memory to XRF
1460 *   LDI   - Load data from memory to XRF (and increase the address base)
1461 *   LUI   - Load unsigned immediate
1462 *   MUL   - Multiply
1463 *   MULU  - Unsigned multiply
1464 *   MADD  - 64-bit operand add 32x32 product
1465 *   MSUB  - 64-bit operand subtract 32x32 product
1466 *   MAC   - Multiply and accumulate (add or subtract)
1467 *   MAD   - Multiply and add or subtract
1468 *   MAX   - Maximum between 2 operands
1469 *   MIN   - Minimum between 2 operands
1470 *   M2I   - Move from MXU register to GPR register
1471 *   MOVZ  - Move if zero
1472 *   MOVN  - Move if non-zero
1473 *   NOR   - Logical bitwise 'nor' operation
1474 *   OR    - Logical bitwise 'or' operation
1475 *   STD   - Store data from XRF to memory
1476 *   SDI   - Store data from XRF to memory (and increase the address base)
1477 *   SLT   - Set of less than comparison
1478 *   SAD   - Sum of absolute differences
1479 *   SLL   - Logical shift left
1480 *   SLR   - Logical shift right
1481 *   SAR   - Arithmetic shift right
1482 *   SAT   - Saturation
1483 *   SFL   - Shuffle
1484 *   SCOP  - Calculate x’s scope (-1, means x<0; 0, means x==0; 1, means x>0)
1485 *   XOR   - Logical bitwise 'exclusive or' operation
1486 *
1487 *  Suffixes:
1488 *
1489 *   E - Expand results
1490 *   F - Fixed point multiplication
1491 *   L - Low part result
1492 *   R - Doing rounding
1493 *   V - Variable instead of immediate
1494 *   W - Combine above L and V
1495 *
1496 *
1497 *     The list of MXU instructions grouped by functionality
1498 *     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1499 *
1500 * Load/Store instructions           Multiplication instructions
1501 * -----------------------           ---------------------------
1502 *
1503 *  S32LDD XRa, Rb, s12               S32MADD XRa, XRd, Rs, Rt
1504 *  S32STD XRa, Rb, s12               S32MADDU XRa, XRd, Rs, Rt
1505 *  S32LDDV XRa, Rb, rc, strd2        S32MSUB XRa, XRd, Rs, Rt
1506 *  S32STDV XRa, Rb, rc, strd2        S32MSUBU XRa, XRd, Rs, Rt
1507 *  S32LDI XRa, Rb, s12               S32MUL XRa, XRd, Rs, Rt
1508 *  S32SDI XRa, Rb, s12               S32MULU XRa, XRd, Rs, Rt
1509 *  S32LDIV XRa, Rb, rc, strd2        D16MUL XRa, XRb, XRc, XRd, optn2
1510 *  S32SDIV XRa, Rb, rc, strd2        D16MULE XRa, XRb, XRc, optn2
1511 *  S32LDDR XRa, Rb, s12              D16MULF XRa, XRb, XRc, optn2
1512 *  S32STDR XRa, Rb, s12              D16MAC XRa, XRb, XRc, XRd, aptn2, optn2
1513 *  S32LDDVR XRa, Rb, rc, strd2       D16MACE XRa, XRb, XRc, XRd, aptn2, optn2
1514 *  S32STDVR XRa, Rb, rc, strd2       D16MACF XRa, XRb, XRc, XRd, aptn2, optn2
1515 *  S32LDIR XRa, Rb, s12              D16MADL XRa, XRb, XRc, XRd, aptn2, optn2
1516 *  S32SDIR XRa, Rb, s12              S16MAD XRa, XRb, XRc, XRd, aptn1, optn2
1517 *  S32LDIVR XRa, Rb, rc, strd2       Q8MUL XRa, XRb, XRc, XRd
1518 *  S32SDIVR XRa, Rb, rc, strd2       Q8MULSU XRa, XRb, XRc, XRd
1519 *  S16LDD XRa, Rb, s10, eptn2        Q8MAC XRa, XRb, XRc, XRd, aptn2
1520 *  S16STD XRa, Rb, s10, eptn2        Q8MACSU XRa, XRb, XRc, XRd, aptn2
1521 *  S16LDI XRa, Rb, s10, eptn2        Q8MADL XRa, XRb, XRc, XRd, aptn2
1522 *  S16SDI XRa, Rb, s10, eptn2
1523 *  S8LDD XRa, Rb, s8, eptn3
1524 *  S8STD XRa, Rb, s8, eptn3         Addition and subtraction instructions
1525 *  S8LDI XRa, Rb, s8, eptn3         -------------------------------------
1526 *  S8SDI XRa, Rb, s8, eptn3
1527 *  LXW Rd, Rs, Rt, strd2             D32ADD XRa, XRb, XRc, XRd, eptn2
1528 *  LXH Rd, Rs, Rt, strd2             D32ADDC XRa, XRb, XRc, XRd
1529 *  LXHU Rd, Rs, Rt, strd2            D32ACC XRa, XRb, XRc, XRd, eptn2
1530 *  LXB Rd, Rs, Rt, strd2             D32ACCM XRa, XRb, XRc, XRd, eptn2
1531 *  LXBU Rd, Rs, Rt, strd2            D32ASUM XRa, XRb, XRc, XRd, eptn2
1532 *                                    S32CPS XRa, XRb, XRc
1533 *                                    Q16ADD XRa, XRb, XRc, XRd, eptn2, optn2
1534 * Comparison instructions            Q16ACC XRa, XRb, XRc, XRd, eptn2
1535 * -----------------------            Q16ACCM XRa, XRb, XRc, XRd, eptn2
1536 *                                    D16ASUM XRa, XRb, XRc, XRd, eptn2
1537 *  S32MAX XRa, XRb, XRc              D16CPS XRa, XRb,
1538 *  S32MIN XRa, XRb, XRc              D16AVG XRa, XRb, XRc
1539 *  S32SLT XRa, XRb, XRc              D16AVGR XRa, XRb, XRc
1540 *  S32MOVZ XRa, XRb, XRc             Q8ADD XRa, XRb, XRc, eptn2
1541 *  S32MOVN XRa, XRb, XRc             Q8ADDE XRa, XRb, XRc, XRd, eptn2
1542 *  D16MAX XRa, XRb, XRc              Q8ACCE XRa, XRb, XRc, XRd, eptn2
1543 *  D16MIN XRa, XRb, XRc              Q8ABD XRa, XRb, XRc
1544 *  D16SLT XRa, XRb, XRc              Q8SAD XRa, XRb, XRc, XRd
1545 *  D16MOVZ XRa, XRb, XRc             Q8AVG XRa, XRb, XRc
1546 *  D16MOVN XRa, XRb, XRc             Q8AVGR XRa, XRb, XRc
1547 *  Q8MAX XRa, XRb, XRc               D8SUM XRa, XRb, XRc, XRd
1548 *  Q8MIN XRa, XRb, XRc               D8SUMC XRa, XRb, XRc, XRd
1549 *  Q8SLT XRa, XRb, XRc
1550 *  Q8SLTU XRa, XRb, XRc
1551 *  Q8MOVZ XRa, XRb, XRc             Shift instructions
1552 *  Q8MOVN XRa, XRb, XRc             ------------------
1553 *
1554 *                                    D32SLL XRa, XRb, XRc, XRd, sft4
1555 * Bitwise instructions               D32SLR XRa, XRb, XRc, XRd, sft4
1556 * --------------------               D32SAR XRa, XRb, XRc, XRd, sft4
1557 *                                    D32SARL XRa, XRb, XRc, sft4
1558 *  S32NOR XRa, XRb, XRc              D32SLLV XRa, XRb, Rb
1559 *  S32AND XRa, XRb, XRc              D32SLRV XRa, XRb, Rb
1560 *  S32XOR XRa, XRb, XRc              D32SARV XRa, XRb, Rb
1561 *  S32OR XRa, XRb, XRc               D32SARW XRa, XRb, XRc, Rb
1562 *                                    Q16SLL XRa, XRb, XRc, XRd, sft4
1563 *                                    Q16SLR XRa, XRb, XRc, XRd, sft4
1564 * Miscellaneous instructions         Q16SAR XRa, XRb, XRc, XRd, sft4
1565 * -------------------------          Q16SLLV XRa, XRb, Rb
1566 *                                    Q16SLRV XRa, XRb, Rb
1567 *  S32SFL XRa, XRb, XRc, XRd, optn2  Q16SARV XRa, XRb, Rb
1568 *  S32ALN XRa, XRb, XRc, Rb
1569 *  S32ALNI XRa, XRb, XRc, s3
1570 *  S32LUI XRa, s8, optn3            Move instructions
1571 *  S32EXTR XRa, XRb, Rb, bits5      -----------------
1572 *  S32EXTRV XRa, XRb, Rs, Rt
1573 *  Q16SCOP XRa, XRb, XRc, XRd        S32M2I XRa, Rb
1574 *  Q16SAT XRa, XRb, XRc              S32I2M XRa, Rb
1575 *
1576 *
1577 *     The opcode organization of MXU instructions
1578 *     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1579 *
1580 * The bits 31..26 of all MXU instructions are equal to 0x1C (also referred
1581 * as opcode SPECIAL2 in the base MIPS ISA). The organization and meaning of
1582 * other bits up to the instruction level is as follows:
1583 *
1584 *              bits
1585 *             05..00
1586 *
1587 *          ┌─ 000000 ─ OPC_MXU_S32MADD
1588 *          ├─ 000001 ─ OPC_MXU_S32MADDU
1589 *          ├─ 000010 ─ <not assigned>   (non-MXU OPC_MUL)
1590 *          │
1591 *          │                               20..18
1592 *          ├─ 000011 ─ OPC_MXU__POOL00 ─┬─ 000 ─ OPC_MXU_S32MAX
1593 *          │                            ├─ 001 ─ OPC_MXU_S32MIN
1594 *          │                            ├─ 010 ─ OPC_MXU_D16MAX
1595 *          │                            ├─ 011 ─ OPC_MXU_D16MIN
1596 *          │                            ├─ 100 ─ OPC_MXU_Q8MAX
1597 *          │                            ├─ 101 ─ OPC_MXU_Q8MIN
1598 *          │                            ├─ 110 ─ OPC_MXU_Q8SLT
1599 *          │                            └─ 111 ─ OPC_MXU_Q8SLTU
1600 *          ├─ 000100 ─ OPC_MXU_S32MSUB
1601 *          ├─ 000101 ─ OPC_MXU_S32MSUBU    20..18
1602 *          ├─ 000110 ─ OPC_MXU__POOL01 ─┬─ 000 ─ OPC_MXU_S32SLT
1603 *          │                            ├─ 001 ─ OPC_MXU_D16SLT
1604 *          │                            ├─ 010 ─ OPC_MXU_D16AVG
1605 *          │                            ├─ 011 ─ OPC_MXU_D16AVGR
1606 *          │                            ├─ 100 ─ OPC_MXU_Q8AVG
1607 *          │                            ├─ 101 ─ OPC_MXU_Q8AVGR
1608 *          │                            └─ 111 ─ OPC_MXU_Q8ADD
1609 *          │
1610 *          │                               20..18
1611 *          ├─ 000111 ─ OPC_MXU__POOL02 ─┬─ 000 ─ OPC_MXU_S32CPS
1612 *          │                            ├─ 010 ─ OPC_MXU_D16CPS
1613 *          │                            ├─ 100 ─ OPC_MXU_Q8ABD
1614 *          │                            └─ 110 ─ OPC_MXU_Q16SAT
1615 *          ├─ 001000 ─ OPC_MXU_D16MUL
1616 *          │                               25..24
1617 *          ├─ 001001 ─ OPC_MXU__POOL03 ─┬─ 00 ─ OPC_MXU_D16MULF
1618 *          │                            └─ 01 ─ OPC_MXU_D16MULE
1619 *          ├─ 001010 ─ OPC_MXU_D16MAC
1620 *          ├─ 001011 ─ OPC_MXU_D16MACF
1621 *          ├─ 001100 ─ OPC_MXU_D16MADL
1622 *          ├─ 001101 ─ OPC_MXU_S16MAD
1623 *          ├─ 001110 ─ OPC_MXU_Q16ADD
1624 *          ├─ 001111 ─ OPC_MXU_D16MACE     23
1625 *          │                            ┌─ 0 ─ OPC_MXU_S32LDD
1626 *          ├─ 010000 ─ OPC_MXU__POOL04 ─┴─ 1 ─ OPC_MXU_S32LDDR
1627 *          │
1628 *          │                               23
1629 *          ├─ 010001 ─ OPC_MXU__POOL05 ─┬─ 0 ─ OPC_MXU_S32STD
1630 *          │                            └─ 1 ─ OPC_MXU_S32STDR
1631 *          │
1632 *          │                               13..10
1633 *          ├─ 010010 ─ OPC_MXU__POOL06 ─┬─ 0000 ─ OPC_MXU_S32LDDV
1634 *          │                            └─ 0001 ─ OPC_MXU_S32LDDVR
1635 *          │
1636 *          │                               13..10
1637 *          ├─ 010011 ─ OPC_MXU__POOL07 ─┬─ 0000 ─ OPC_MXU_S32STDV
1638 *          │                            └─ 0001 ─ OPC_MXU_S32STDVR
1639 *          │
1640 *          │                               23
1641 *          ├─ 010100 ─ OPC_MXU__POOL08 ─┬─ 0 ─ OPC_MXU_S32LDI
1642 *          │                            └─ 1 ─ OPC_MXU_S32LDIR
1643 *          │
1644 *          │                               23
1645 *          ├─ 010101 ─ OPC_MXU__POOL09 ─┬─ 0 ─ OPC_MXU_S32SDI
1646 *          │                            └─ 1 ─ OPC_MXU_S32SDIR
1647 *          │
1648 *          │                               13..10
1649 *          ├─ 010110 ─ OPC_MXU__POOL10 ─┬─ 0000 ─ OPC_MXU_S32LDIV
1650 *          │                            └─ 0001 ─ OPC_MXU_S32LDIVR
1651 *          │
1652 *          │                               13..10
1653 *          ├─ 010111 ─ OPC_MXU__POOL11 ─┬─ 0000 ─ OPC_MXU_S32SDIV
1654 *          │                            └─ 0001 ─ OPC_MXU_S32SDIVR
1655 *          ├─ 011000 ─ OPC_MXU_D32ADD
1656 *          │                               23..22
1657 *   MXU    ├─ 011001 ─ OPC_MXU__POOL12 ─┬─ 00 ─ OPC_MXU_D32ACC
1658 * opcodes ─┤                            ├─ 01 ─ OPC_MXU_D32ACCM
1659 *          │                            └─ 10 ─ OPC_MXU_D32ASUM
1660 *          ├─ 011010 ─ <not assigned>
1661 *          │                               23..22
1662 *          ├─ 011011 ─ OPC_MXU__POOL13 ─┬─ 00 ─ OPC_MXU_Q16ACC
1663 *          │                            ├─ 01 ─ OPC_MXU_Q16ACCM
1664 *          │                            └─ 10 ─ OPC_MXU_Q16ASUM
1665 *          │
1666 *          │                               23..22
1667 *          ├─ 011100 ─ OPC_MXU__POOL14 ─┬─ 00 ─ OPC_MXU_Q8ADDE
1668 *          │                            ├─ 01 ─ OPC_MXU_D8SUM
1669 *          ├─ 011101 ─ OPC_MXU_Q8ACCE   └─ 10 ─ OPC_MXU_D8SUMC
1670 *          ├─ 011110 ─ <not assigned>
1671 *          ├─ 011111 ─ <not assigned>
1672 *          ├─ 100000 ─ <not assigned>   (overlaps with CLZ)
1673 *          ├─ 100001 ─ <not assigned>   (overlaps with CLO)
1674 *          ├─ 100010 ─ OPC_MXU_S8LDD
1675 *          ├─ 100011 ─ OPC_MXU_S8STD       15..14
1676 *          ├─ 100100 ─ OPC_MXU_S8LDI    ┌─ 00 ─ OPC_MXU_S32MUL
1677 *          ├─ 100101 ─ OPC_MXU_S8SDI    ├─ 00 ─ OPC_MXU_S32MULU
1678 *          │                            ├─ 00 ─ OPC_MXU_S32EXTR
1679 *          ├─ 100110 ─ OPC_MXU__POOL15 ─┴─ 00 ─ OPC_MXU_S32EXTRV
1680 *          │
1681 *          │                               20..18
1682 *          ├─ 100111 ─ OPC_MXU__POOL16 ─┬─ 000 ─ OPC_MXU_D32SARW
1683 *          │                            ├─ 001 ─ OPC_MXU_S32ALN
1684 *          │                            ├─ 010 ─ OPC_MXU_S32ALNI
1685 *          │                            ├─ 011 ─ OPC_MXU_S32LUI
1686 *          │                            ├─ 100 ─ OPC_MXU_S32NOR
1687 *          │                            ├─ 101 ─ OPC_MXU_S32AND
1688 *          │                            ├─ 110 ─ OPC_MXU_S32OR
1689 *          │                            └─ 111 ─ OPC_MXU_S32XOR
1690 *          │
1691 *          │                               7..5
1692 *          ├─ 101000 ─ OPC_MXU__POOL17 ─┬─ 000 ─ OPC_MXU_LXB
1693 *          │                            ├─ 001 ─ OPC_MXU_LXH
1694 *          ├─ 101001 ─ <not assigned>   ├─ 011 ─ OPC_MXU_LXW
1695 *          ├─ 101010 ─ OPC_MXU_S16LDD   ├─ 100 ─ OPC_MXU_LXBU
1696 *          ├─ 101011 ─ OPC_MXU_S16STD   └─ 101 ─ OPC_MXU_LXHU
1697 *          ├─ 101100 ─ OPC_MXU_S16LDI
1698 *          ├─ 101101 ─ OPC_MXU_S16SDI
1699 *          ├─ 101110 ─ OPC_MXU_S32M2I
1700 *          ├─ 101111 ─ OPC_MXU_S32I2M
1701 *          ├─ 110000 ─ OPC_MXU_D32SLL
1702 *          ├─ 110001 ─ OPC_MXU_D32SLR      20..18
1703 *          ├─ 110010 ─ OPC_MXU_D32SARL  ┌─ 000 ─ OPC_MXU_D32SLLV
1704 *          ├─ 110011 ─ OPC_MXU_D32SAR   ├─ 001 ─ OPC_MXU_D32SLRV
1705 *          ├─ 110100 ─ OPC_MXU_Q16SLL   ├─ 010 ─ OPC_MXU_D32SARV
1706 *          ├─ 110101 ─ OPC_MXU_Q16SLR   ├─ 011 ─ OPC_MXU_Q16SLLV
1707 *          │                            ├─ 100 ─ OPC_MXU_Q16SLRV
1708 *          ├─ 110110 ─ OPC_MXU__POOL18 ─┴─ 101 ─ OPC_MXU_Q16SARV
1709 *          │
1710 *          ├─ 110111 ─ OPC_MXU_Q16SAR
1711 *          │                               23..22
1712 *          ├─ 111000 ─ OPC_MXU__POOL19 ─┬─ 00 ─ OPC_MXU_Q8MUL
1713 *          │                            └─ 01 ─ OPC_MXU_Q8MULSU
1714 *          │
1715 *          │                               20..18
1716 *          ├─ 111001 ─ OPC_MXU__POOL20 ─┬─ 000 ─ OPC_MXU_Q8MOVZ
1717 *          │                            ├─ 001 ─ OPC_MXU_Q8MOVN
1718 *          │                            ├─ 010 ─ OPC_MXU_D16MOVZ
1719 *          │                            ├─ 011 ─ OPC_MXU_D16MOVN
1720 *          │                            ├─ 100 ─ OPC_MXU_S32MOVZ
1721 *          │                            └─ 101 ─ OPC_MXU_S32MOVN
1722 *          │
1723 *          │                               23..22
1724 *          ├─ 111010 ─ OPC_MXU__POOL21 ─┬─ 00 ─ OPC_MXU_Q8MAC
1725 *          │                            └─ 10 ─ OPC_MXU_Q8MACSU
1726 *          ├─ 111011 ─ OPC_MXU_Q16SCOP
1727 *          ├─ 111100 ─ OPC_MXU_Q8MADL
1728 *          ├─ 111101 ─ OPC_MXU_S32SFL
1729 *          ├─ 111110 ─ OPC_MXU_Q8SAD
1730 *          └─ 111111 ─ <not assigned>   (overlaps with SDBBP)
1731 *
1732 *
1733 * Compiled after:
1734 *
1735 *   "XBurst® Instruction Set Architecture MIPS eXtension/enhanced Unit
1736 *   Programming Manual", Ingenic Semiconductor Co, Ltd., revision June 2, 2017
1737 */
1738
1739enum {
1740    OPC_MXU_S32MADD  = 0x00,
1741    OPC_MXU_S32MADDU = 0x01,
1742    OPC__MXU_MUL     = 0x02,
1743    OPC_MXU__POOL00  = 0x03,
1744    OPC_MXU_S32MSUB  = 0x04,
1745    OPC_MXU_S32MSUBU = 0x05,
1746    OPC_MXU__POOL01  = 0x06,
1747    OPC_MXU__POOL02  = 0x07,
1748    OPC_MXU_D16MUL   = 0x08,
1749    OPC_MXU__POOL03  = 0x09,
1750    OPC_MXU_D16MAC   = 0x0A,
1751    OPC_MXU_D16MACF  = 0x0B,
1752    OPC_MXU_D16MADL  = 0x0C,
1753    OPC_MXU_S16MAD   = 0x0D,
1754    OPC_MXU_Q16ADD   = 0x0E,
1755    OPC_MXU_D16MACE  = 0x0F,
1756    OPC_MXU__POOL04  = 0x10,
1757    OPC_MXU__POOL05  = 0x11,
1758    OPC_MXU__POOL06  = 0x12,
1759    OPC_MXU__POOL07  = 0x13,
1760    OPC_MXU__POOL08  = 0x14,
1761    OPC_MXU__POOL09  = 0x15,
1762    OPC_MXU__POOL10  = 0x16,
1763    OPC_MXU__POOL11  = 0x17,
1764    OPC_MXU_D32ADD   = 0x18,
1765    OPC_MXU__POOL12  = 0x19,
1766    /* not assigned 0x1A */
1767    OPC_MXU__POOL13  = 0x1B,
1768    OPC_MXU__POOL14  = 0x1C,
1769    OPC_MXU_Q8ACCE   = 0x1D,
1770    /* not assigned 0x1E */
1771    /* not assigned 0x1F */
1772    /* not assigned 0x20 */
1773    /* not assigned 0x21 */
1774    OPC_MXU_S8LDD    = 0x22,
1775    OPC_MXU_S8STD    = 0x23,
1776    OPC_MXU_S8LDI    = 0x24,
1777    OPC_MXU_S8SDI    = 0x25,
1778    OPC_MXU__POOL15  = 0x26,
1779    OPC_MXU__POOL16  = 0x27,
1780    OPC_MXU__POOL17  = 0x28,
1781    /* not assigned 0x29 */
1782    OPC_MXU_S16LDD   = 0x2A,
1783    OPC_MXU_S16STD   = 0x2B,
1784    OPC_MXU_S16LDI   = 0x2C,
1785    OPC_MXU_S16SDI   = 0x2D,
1786    OPC_MXU_S32M2I   = 0x2E,
1787    OPC_MXU_S32I2M   = 0x2F,
1788    OPC_MXU_D32SLL   = 0x30,
1789    OPC_MXU_D32SLR   = 0x31,
1790    OPC_MXU_D32SARL  = 0x32,
1791    OPC_MXU_D32SAR   = 0x33,
1792    OPC_MXU_Q16SLL   = 0x34,
1793    OPC_MXU_Q16SLR   = 0x35,
1794    OPC_MXU__POOL18  = 0x36,
1795    OPC_MXU_Q16SAR   = 0x37,
1796    OPC_MXU__POOL19  = 0x38,
1797    OPC_MXU__POOL20  = 0x39,
1798    OPC_MXU__POOL21  = 0x3A,
1799    OPC_MXU_Q16SCOP  = 0x3B,
1800    OPC_MXU_Q8MADL   = 0x3C,
1801    OPC_MXU_S32SFL   = 0x3D,
1802    OPC_MXU_Q8SAD    = 0x3E,
1803    /* not assigned 0x3F */
1804};
1805
1806
1807/*
1808 * MXU pool 00
1809 */
1810enum {
1811    OPC_MXU_S32MAX   = 0x00,
1812    OPC_MXU_S32MIN   = 0x01,
1813    OPC_MXU_D16MAX   = 0x02,
1814    OPC_MXU_D16MIN   = 0x03,
1815    OPC_MXU_Q8MAX    = 0x04,
1816    OPC_MXU_Q8MIN    = 0x05,
1817    OPC_MXU_Q8SLT    = 0x06,
1818    OPC_MXU_Q8SLTU   = 0x07,
1819};
1820
1821/*
1822 * MXU pool 01
1823 */
1824enum {
1825    OPC_MXU_S32SLT   = 0x00,
1826    OPC_MXU_D16SLT   = 0x01,
1827    OPC_MXU_D16AVG   = 0x02,
1828    OPC_MXU_D16AVGR  = 0x03,
1829    OPC_MXU_Q8AVG    = 0x04,
1830    OPC_MXU_Q8AVGR   = 0x05,
1831    OPC_MXU_Q8ADD    = 0x07,
1832};
1833
1834/*
1835 * MXU pool 02
1836 */
1837enum {
1838    OPC_MXU_S32CPS   = 0x00,
1839    OPC_MXU_D16CPS   = 0x02,
1840    OPC_MXU_Q8ABD    = 0x04,
1841    OPC_MXU_Q16SAT   = 0x06,
1842};
1843
1844/*
1845 * MXU pool 03
1846 */
1847enum {
1848    OPC_MXU_D16MULF  = 0x00,
1849    OPC_MXU_D16MULE  = 0x01,
1850};
1851
1852/*
1853 * MXU pool 04
1854 */
1855enum {
1856    OPC_MXU_S32LDD   = 0x00,
1857    OPC_MXU_S32LDDR  = 0x01,
1858};
1859
1860/*
1861 * MXU pool 05
1862 */
1863enum {
1864    OPC_MXU_S32STD   = 0x00,
1865    OPC_MXU_S32STDR  = 0x01,
1866};
1867
1868/*
1869 * MXU pool 06
1870 */
1871enum {
1872    OPC_MXU_S32LDDV  = 0x00,
1873    OPC_MXU_S32LDDVR = 0x01,
1874};
1875
1876/*
1877 * MXU pool 07
1878 */
1879enum {
1880    OPC_MXU_S32STDV  = 0x00,
1881    OPC_MXU_S32STDVR = 0x01,
1882};
1883
1884/*
1885 * MXU pool 08
1886 */
1887enum {
1888    OPC_MXU_S32LDI   = 0x00,
1889    OPC_MXU_S32LDIR  = 0x01,
1890};
1891
1892/*
1893 * MXU pool 09
1894 */
1895enum {
1896    OPC_MXU_S32SDI   = 0x00,
1897    OPC_MXU_S32SDIR  = 0x01,
1898};
1899
1900/*
1901 * MXU pool 10
1902 */
1903enum {
1904    OPC_MXU_S32LDIV  = 0x00,
1905    OPC_MXU_S32LDIVR = 0x01,
1906};
1907
1908/*
1909 * MXU pool 11
1910 */
1911enum {
1912    OPC_MXU_S32SDIV  = 0x00,
1913    OPC_MXU_S32SDIVR = 0x01,
1914};
1915
1916/*
1917 * MXU pool 12
1918 */
1919enum {
1920    OPC_MXU_D32ACC   = 0x00,
1921    OPC_MXU_D32ACCM  = 0x01,
1922    OPC_MXU_D32ASUM  = 0x02,
1923};
1924
1925/*
1926 * MXU pool 13
1927 */
1928enum {
1929    OPC_MXU_Q16ACC   = 0x00,
1930    OPC_MXU_Q16ACCM  = 0x01,
1931    OPC_MXU_Q16ASUM  = 0x02,
1932};
1933
1934/*
1935 * MXU pool 14
1936 */
1937enum {
1938    OPC_MXU_Q8ADDE   = 0x00,
1939    OPC_MXU_D8SUM    = 0x01,
1940    OPC_MXU_D8SUMC   = 0x02,
1941};
1942
1943/*
1944 * MXU pool 15
1945 */
1946enum {
1947    OPC_MXU_S32MUL   = 0x00,
1948    OPC_MXU_S32MULU  = 0x01,
1949    OPC_MXU_S32EXTR  = 0x02,
1950    OPC_MXU_S32EXTRV = 0x03,
1951};
1952
1953/*
1954 * MXU pool 16
1955 */
1956enum {
1957    OPC_MXU_D32SARW  = 0x00,
1958    OPC_MXU_S32ALN   = 0x01,
1959    OPC_MXU_S32ALNI  = 0x02,
1960    OPC_MXU_S32LUI   = 0x03,
1961    OPC_MXU_S32NOR   = 0x04,
1962    OPC_MXU_S32AND   = 0x05,
1963    OPC_MXU_S32OR    = 0x06,
1964    OPC_MXU_S32XOR   = 0x07,
1965};
1966
1967/*
1968 * MXU pool 17
1969 */
1970enum {
1971    OPC_MXU_LXB      = 0x00,
1972    OPC_MXU_LXH      = 0x01,
1973    OPC_MXU_LXW      = 0x03,
1974    OPC_MXU_LXBU     = 0x04,
1975    OPC_MXU_LXHU     = 0x05,
1976};
1977
1978/*
1979 * MXU pool 18
1980 */
1981enum {
1982    OPC_MXU_D32SLLV  = 0x00,
1983    OPC_MXU_D32SLRV  = 0x01,
1984    OPC_MXU_D32SARV  = 0x03,
1985    OPC_MXU_Q16SLLV  = 0x04,
1986    OPC_MXU_Q16SLRV  = 0x05,
1987    OPC_MXU_Q16SARV  = 0x07,
1988};
1989
1990/*
1991 * MXU pool 19
1992 */
1993enum {
1994    OPC_MXU_Q8MUL    = 0x00,
1995    OPC_MXU_Q8MULSU  = 0x01,
1996};
1997
1998/*
1999 * MXU pool 20
2000 */
2001enum {
2002    OPC_MXU_Q8MOVZ   = 0x00,
2003    OPC_MXU_Q8MOVN   = 0x01,
2004    OPC_MXU_D16MOVZ  = 0x02,
2005    OPC_MXU_D16MOVN  = 0x03,
2006    OPC_MXU_S32MOVZ  = 0x04,
2007    OPC_MXU_S32MOVN  = 0x05,
2008};
2009
2010/*
2011 * MXU pool 21
2012 */
2013enum {
2014    OPC_MXU_Q8MAC    = 0x00,
2015    OPC_MXU_Q8MACSU  = 0x01,
2016};
2017
2018/*
2019 *     Overview of the TX79-specific instruction set
2020 *     =============================================
2021 *
2022 * The R5900 and the C790 have 128-bit wide GPRs, where the upper 64 bits
2023 * are only used by the specific quadword (128-bit) LQ/SQ load/store
2024 * instructions and certain multimedia instructions (MMIs). These MMIs
2025 * configure the 128-bit data path as two 64-bit, four 32-bit, eight 16-bit
2026 * or sixteen 8-bit paths.
2027 *
2028 * Reference:
2029 *
2030 * The Toshiba TX System RISC TX79 Core Architecture manual,
2031 * https://wiki.qemu.org/File:C790.pdf
2032 *
2033 *     Three-Operand Multiply and Multiply-Add (4 instructions)
2034 *     --------------------------------------------------------
2035 * MADD    [rd,] rs, rt      Multiply/Add
2036 * MADDU   [rd,] rs, rt      Multiply/Add Unsigned
2037 * MULT    [rd,] rs, rt      Multiply (3-operand)
2038 * MULTU   [rd,] rs, rt      Multiply Unsigned (3-operand)
2039 *
2040 *     Multiply Instructions for Pipeline 1 (10 instructions)
2041 *     ------------------------------------------------------
2042 * MULT1   [rd,] rs, rt      Multiply Pipeline 1
2043 * MULTU1  [rd,] rs, rt      Multiply Unsigned Pipeline 1
2044 * DIV1    rs, rt            Divide Pipeline 1
2045 * DIVU1   rs, rt            Divide Unsigned Pipeline 1
2046 * MADD1   [rd,] rs, rt      Multiply-Add Pipeline 1
2047 * MADDU1  [rd,] rs, rt      Multiply-Add Unsigned Pipeline 1
2048 * MFHI1   rd                Move From HI1 Register
2049 * MFLO1   rd                Move From LO1 Register
2050 * MTHI1   rs                Move To HI1 Register
2051 * MTLO1   rs                Move To LO1 Register
2052 *
2053 *     Arithmetic (19 instructions)
2054 *     ----------------------------
2055 * PADDB   rd, rs, rt        Parallel Add Byte
2056 * PSUBB   rd, rs, rt        Parallel Subtract Byte
2057 * PADDH   rd, rs, rt        Parallel Add Halfword
2058 * PSUBH   rd, rs, rt        Parallel Subtract Halfword
2059 * PADDW   rd, rs, rt        Parallel Add Word
2060 * PSUBW   rd, rs, rt        Parallel Subtract Word
2061 * PADSBH  rd, rs, rt        Parallel Add/Subtract Halfword
2062 * PADDSB  rd, rs, rt        Parallel Add with Signed Saturation Byte
2063 * PSUBSB  rd, rs, rt        Parallel Subtract with Signed Saturation Byte
2064 * PADDSH  rd, rs, rt        Parallel Add with Signed Saturation Halfword
2065 * PSUBSH  rd, rs, rt        Parallel Subtract with Signed Saturation Halfword
2066 * PADDSW  rd, rs, rt        Parallel Add with Signed Saturation Word
2067 * PSUBSW  rd, rs, rt        Parallel Subtract with Signed Saturation Word
2068 * PADDUB  rd, rs, rt        Parallel Add with Unsigned saturation Byte
2069 * PSUBUB  rd, rs, rt        Parallel Subtract with Unsigned saturation Byte
2070 * PADDUH  rd, rs, rt        Parallel Add with Unsigned saturation Halfword
2071 * PSUBUH  rd, rs, rt        Parallel Subtract with Unsigned saturation Halfword
2072 * PADDUW  rd, rs, rt        Parallel Add with Unsigned saturation Word
2073 * PSUBUW  rd, rs, rt        Parallel Subtract with Unsigned saturation Word
2074 *
2075 *     Min/Max (4 instructions)
2076 *     ------------------------
2077 * PMAXH   rd, rs, rt        Parallel Maximum Halfword
2078 * PMINH   rd, rs, rt        Parallel Minimum Halfword
2079 * PMAXW   rd, rs, rt        Parallel Maximum Word
2080 * PMINW   rd, rs, rt        Parallel Minimum Word
2081 *
2082 *     Absolute (2 instructions)
2083 *     -------------------------
2084 * PABSH   rd, rt            Parallel Absolute Halfword
2085 * PABSW   rd, rt            Parallel Absolute Word
2086 *
2087 *     Logical (4 instructions)
2088 *     ------------------------
2089 * PAND    rd, rs, rt        Parallel AND
2090 * POR     rd, rs, rt        Parallel OR
2091 * PXOR    rd, rs, rt        Parallel XOR
2092 * PNOR    rd, rs, rt        Parallel NOR
2093 *
2094 *     Shift (9 instructions)
2095 *     ----------------------
2096 * PSLLH   rd, rt, sa        Parallel Shift Left Logical Halfword
2097 * PSRLH   rd, rt, sa        Parallel Shift Right Logical Halfword
2098 * PSRAH   rd, rt, sa        Parallel Shift Right Arithmetic Halfword
2099 * PSLLW   rd, rt, sa        Parallel Shift Left Logical Word
2100 * PSRLW   rd, rt, sa        Parallel Shift Right Logical Word
2101 * PSRAW   rd, rt, sa        Parallel Shift Right Arithmetic Word
2102 * PSLLVW  rd, rt, rs        Parallel Shift Left Logical Variable Word
2103 * PSRLVW  rd, rt, rs        Parallel Shift Right Logical Variable Word
2104 * PSRAVW  rd, rt, rs        Parallel Shift Right Arithmetic Variable Word
2105 *
2106 *     Compare (6 instructions)
2107 *     ------------------------
2108 * PCGTB   rd, rs, rt        Parallel Compare for Greater Than Byte
2109 * PCEQB   rd, rs, rt        Parallel Compare for Equal Byte
2110 * PCGTH   rd, rs, rt        Parallel Compare for Greater Than Halfword
2111 * PCEQH   rd, rs, rt        Parallel Compare for Equal Halfword
2112 * PCGTW   rd, rs, rt        Parallel Compare for Greater Than Word
2113 * PCEQW   rd, rs, rt        Parallel Compare for Equal Word
2114 *
2115 *     LZC (1 instruction)
2116 *     -------------------
2117 * PLZCW   rd, rs            Parallel Leading Zero or One Count Word
2118 *
2119 *     Quadword Load and Store (2 instructions)
2120 *     ----------------------------------------
2121 * LQ      rt, offset(base)  Load Quadword
2122 * SQ      rt, offset(base)  Store Quadword
2123 *
2124 *     Multiply and Divide (19 instructions)
2125 *     -------------------------------------
2126 * PMULTW  rd, rs, rt        Parallel Multiply Word
2127 * PMULTUW rd, rs, rt        Parallel Multiply Unsigned Word
2128 * PDIVW   rs, rt            Parallel Divide Word
2129 * PDIVUW  rs, rt            Parallel Divide Unsigned Word
2130 * PMADDW  rd, rs, rt        Parallel Multiply-Add Word
2131 * PMADDUW rd, rs, rt        Parallel Multiply-Add Unsigned Word
2132 * PMSUBW  rd, rs, rt        Parallel Multiply-Subtract Word
2133 * PMULTH  rd, rs, rt        Parallel Multiply Halfword
2134 * PMADDH  rd, rs, rt        Parallel Multiply-Add Halfword
2135 * PMSUBH  rd, rs, rt        Parallel Multiply-Subtract Halfword
2136 * PHMADH  rd, rs, rt        Parallel Horizontal Multiply-Add Halfword
2137 * PHMSBH  rd, rs, rt        Parallel Horizontal Multiply-Subtract Halfword
2138 * PDIVBW  rs, rt            Parallel Divide Broadcast Word
2139 * PMFHI   rd                Parallel Move From HI Register
2140 * PMFLO   rd                Parallel Move From LO Register
2141 * PMTHI   rs                Parallel Move To HI Register
2142 * PMTLO   rs                Parallel Move To LO Register
2143 * PMFHL   rd                Parallel Move From HI/LO Register
2144 * PMTHL   rs                Parallel Move To HI/LO Register
2145 *
2146 *     Pack/Extend (11 instructions)
2147 *     -----------------------------
2148 * PPAC5   rd, rt            Parallel Pack to 5 bits
2149 * PPACB   rd, rs, rt        Parallel Pack to Byte
2150 * PPACH   rd, rs, rt        Parallel Pack to Halfword
2151 * PPACW   rd, rs, rt        Parallel Pack to Word
2152 * PEXT5   rd, rt            Parallel Extend Upper from 5 bits
2153 * PEXTUB  rd, rs, rt        Parallel Extend Upper from Byte
2154 * PEXTLB  rd, rs, rt        Parallel Extend Lower from Byte
2155 * PEXTUH  rd, rs, rt        Parallel Extend Upper from Halfword
2156 * PEXTLH  rd, rs, rt        Parallel Extend Lower from Halfword
2157 * PEXTUW  rd, rs, rt        Parallel Extend Upper from Word
2158 * PEXTLW  rd, rs, rt        Parallel Extend Lower from Word
2159 *
2160 *     Others (16 instructions)
2161 *     ------------------------
2162 * PCPYH   rd, rt            Parallel Copy Halfword
2163 * PCPYLD  rd, rs, rt        Parallel Copy Lower Doubleword
2164 * PCPYUD  rd, rs, rt        Parallel Copy Upper Doubleword
2165 * PREVH   rd, rt            Parallel Reverse Halfword
2166 * PINTH   rd, rs, rt        Parallel Interleave Halfword
2167 * PINTEH  rd, rs, rt        Parallel Interleave Even Halfword
2168 * PEXEH   rd, rt            Parallel Exchange Even Halfword
2169 * PEXCH   rd, rt            Parallel Exchange Center Halfword
2170 * PEXEW   rd, rt            Parallel Exchange Even Word
2171 * PEXCW   rd, rt            Parallel Exchange Center Word
2172 * QFSRV   rd, rs, rt        Quadword Funnel Shift Right Variable
2173 * MFSA    rd                Move from Shift Amount Register
2174 * MTSA    rs                Move to Shift Amount Register
2175 * MTSAB   rs, immediate     Move Byte Count to Shift Amount Register
2176 * MTSAH   rs, immediate     Move Halfword Count to Shift Amount Register
2177 * PROT3W  rd, rt            Parallel Rotate 3 Words
2178 *
2179 *     MMI (MultiMedia Instruction) encodings
2180 *     ======================================
2181 *
2182 * MMI instructions encoding table keys:
2183 *
2184 *     *   This code is reserved for future use. An attempt to execute it
2185 *         causes a Reserved Instruction exception.
2186 *     %   This code indicates an instruction class. The instruction word
2187 *         must be further decoded by examining additional tables that show
2188 *         the values for other instruction fields.
2189 *     #   This code is reserved for the unsupported instructions DMULT,
2190 *         DMULTU, DDIV, DDIVU, LL, LLD, SC, SCD, LWC2 and SWC2. An attempt
2191 *         to execute it causes a Reserved Instruction exception.
2192 *
2193 * MMI instructions encoded by opcode field (MMI, LQ, SQ):
2194 *
2195 *  31    26                                        0
2196 * +--------+----------------------------------------+
2197 * | opcode |                                        |
2198 * +--------+----------------------------------------+
2199 *
2200 *   opcode  bits 28..26
2201 *     bits |   0   |   1   |   2   |   3   |   4   |   5   |   6   |   7
2202 *   31..29 |  000  |  001  |  010  |  011  |  100  |  101  |  110  |  111
2203 *   -------+-------+-------+-------+-------+-------+-------+-------+-------
2204 *    0 000 |SPECIAL| REGIMM|   J   |  JAL  |  BEQ  |  BNE  |  BLEZ |  BGTZ
2205 *    1 001 |  ADDI | ADDIU |  SLTI | SLTIU |  ANDI |  ORI  |  XORI |  LUI
2206 *    2 010 |  COP0 |  COP1 |   *   |   *   |  BEQL |  BNEL | BLEZL | BGTZL
2207 *    3 011 | DADDI | DADDIU|  LDL  |  LDR  |  MMI% |   *   |   LQ  |   SQ
2208 *    4 100 |   LB  |   LH  |  LWL  |   LW  |  LBU  |  LHU  |  LWR  |  LWU
2209 *    5 101 |   SB  |   SH  |  SWL  |   SW  |  SDL  |  SDR  |  SWR  | CACHE
2210 *    6 110 |   #   |  LWC1 |   #   |  PREF |   #   |  LDC1 |   #   |   LD
2211 *    7 111 |   #   |  SWC1 |   #   |   *   |   #   |  SDC1 |   #   |   SD
2212 */
2213
2214enum {
2215    MMI_OPC_CLASS_MMI = 0x1C << 26,    /* Same as OPC_SPECIAL2 */
2216    MMI_OPC_LQ        = 0x1E << 26,    /* Same as OPC_MSA */
2217    MMI_OPC_SQ        = 0x1F << 26,    /* Same as OPC_SPECIAL3 */
2218};
2219
2220/*
2221 * MMI instructions with opcode field = MMI:
2222 *
2223 *  31    26                                 5      0
2224 * +--------+-------------------------------+--------+
2225 * |   MMI  |                               |function|
2226 * +--------+-------------------------------+--------+
2227 *
2228 * function  bits 2..0
2229 *     bits |   0   |   1   |   2   |   3   |   4   |   5   |   6   |   7
2230 *     5..3 |  000  |  001  |  010  |  011  |  100  |  101  |  110  |  111
2231 *   -------+-------+-------+-------+-------+-------+-------+-------+-------
2232 *    0 000 |  MADD | MADDU |   *   |   *   | PLZCW |   *   |   *   |   *
2233 *    1 001 | MMI0% | MMI2% |   *   |   *   |   *   |   *   |   *   |   *
2234 *    2 010 | MFHI1 | MTHI1 | MFLO1 | MTLO1 |   *   |   *   |   *   |   *
2235 *    3 011 | MULT1 | MULTU1|  DIV1 | DIVU1 |   *   |   *   |   *   |   *
2236 *    4 100 | MADD1 | MADDU1|   *   |   *   |   *   |   *   |   *   |   *
2237 *    5 101 | MMI1% | MMI3% |   *   |   *   |   *   |   *   |   *   |   *
2238 *    6 110 | PMFHL | PMTHL |   *   |   *   | PSLLH |   *   | PSRLH | PSRAH
2239 *    7 111 |   *   |   *   |   *   |   *   | PSLLW |   *   | PSRLW | PSRAW
2240 */
2241
2242#define MASK_MMI(op) (MASK_OP_MAJOR(op) | ((op) & 0x3F))
2243enum {
2244    MMI_OPC_MADD       = 0x00 | MMI_OPC_CLASS_MMI, /* Same as OPC_MADD */
2245    MMI_OPC_MADDU      = 0x01 | MMI_OPC_CLASS_MMI, /* Same as OPC_MADDU */
2246    MMI_OPC_PLZCW      = 0x04 | MMI_OPC_CLASS_MMI,
2247    MMI_OPC_CLASS_MMI0 = 0x08 | MMI_OPC_CLASS_MMI,
2248    MMI_OPC_CLASS_MMI2 = 0x09 | MMI_OPC_CLASS_MMI,
2249    MMI_OPC_MFHI1      = 0x10 | MMI_OPC_CLASS_MMI, /* Same minor as OPC_MFHI */
2250    MMI_OPC_MTHI1      = 0x11 | MMI_OPC_CLASS_MMI, /* Same minor as OPC_MTHI */
2251    MMI_OPC_MFLO1      = 0x12 | MMI_OPC_CLASS_MMI, /* Same minor as OPC_MFLO */
2252    MMI_OPC_MTLO1      = 0x13 | MMI_OPC_CLASS_MMI, /* Same minor as OPC_MTLO */
2253    MMI_OPC_MULT1      = 0x18 | MMI_OPC_CLASS_MMI, /* Same minor as OPC_MULT */
2254    MMI_OPC_MULTU1     = 0x19 | MMI_OPC_CLASS_MMI, /* Same min. as OPC_MULTU */
2255    MMI_OPC_DIV1       = 0x1A | MMI_OPC_CLASS_MMI, /* Same minor as OPC_DIV  */
2256    MMI_OPC_DIVU1      = 0x1B | MMI_OPC_CLASS_MMI, /* Same minor as OPC_DIVU */
2257    MMI_OPC_MADD1      = 0x20 | MMI_OPC_CLASS_MMI,
2258    MMI_OPC_MADDU1     = 0x21 | MMI_OPC_CLASS_MMI,
2259    MMI_OPC_CLASS_MMI1 = 0x28 | MMI_OPC_CLASS_MMI,
2260    MMI_OPC_CLASS_MMI3 = 0x29 | MMI_OPC_CLASS_MMI,
2261    MMI_OPC_PMFHL      = 0x30 | MMI_OPC_CLASS_MMI,
2262    MMI_OPC_PMTHL      = 0x31 | MMI_OPC_CLASS_MMI,
2263    MMI_OPC_PSLLH      = 0x34 | MMI_OPC_CLASS_MMI,
2264    MMI_OPC_PSRLH      = 0x36 | MMI_OPC_CLASS_MMI,
2265    MMI_OPC_PSRAH      = 0x37 | MMI_OPC_CLASS_MMI,
2266    MMI_OPC_PSLLW      = 0x3C | MMI_OPC_CLASS_MMI,
2267    MMI_OPC_PSRLW      = 0x3E | MMI_OPC_CLASS_MMI,
2268    MMI_OPC_PSRAW      = 0x3F | MMI_OPC_CLASS_MMI,
2269};
2270
2271/*
2272 * MMI instructions with opcode field = MMI and bits 5..0 = MMI0:
2273 *
2274 *  31    26                        10     6 5      0
2275 * +--------+----------------------+--------+--------+
2276 * |   MMI  |                      |function|  MMI0  |
2277 * +--------+----------------------+--------+--------+
2278 *
2279 * function  bits 7..6
2280 *     bits |   0   |   1   |   2   |   3
2281 *    10..8 |   00  |   01  |   10  |   11
2282 *   -------+-------+-------+-------+-------
2283 *    0 000 | PADDW | PSUBW | PCGTW | PMAXW
2284 *    1 001 | PADDH | PSUBH | PCGTH | PMAXH
2285 *    2 010 | PADDB | PSUBB | PCGTB |   *
2286 *    3 011 |   *   |   *   |   *   |   *
2287 *    4 100 | PADDSW| PSUBSW| PEXTLW| PPACW
2288 *    5 101 | PADDSH| PSUBSH| PEXTLH| PPACH
2289 *    6 110 | PADDSB| PSUBSB| PEXTLB| PPACB
2290 *    7 111 |   *   |   *   | PEXT5 | PPAC5
2291 */
2292
2293#define MASK_MMI0(op) (MASK_OP_MAJOR(op) | ((op) & 0x7FF))
2294enum {
2295    MMI_OPC_0_PADDW  = (0x00 << 6) | MMI_OPC_CLASS_MMI0,
2296    MMI_OPC_0_PSUBW  = (0x01 << 6) | MMI_OPC_CLASS_MMI0,
2297    MMI_OPC_0_PCGTW  = (0x02 << 6) | MMI_OPC_CLASS_MMI0,
2298    MMI_OPC_0_PMAXW  = (0x03 << 6) | MMI_OPC_CLASS_MMI0,
2299    MMI_OPC_0_PADDH  = (0x04 << 6) | MMI_OPC_CLASS_MMI0,
2300    MMI_OPC_0_PSUBH  = (0x05 << 6) | MMI_OPC_CLASS_MMI0,
2301    MMI_OPC_0_PCGTH  = (0x06 << 6) | MMI_OPC_CLASS_MMI0,
2302    MMI_OPC_0_PMAXH  = (0x07 << 6) | MMI_OPC_CLASS_MMI0,
2303    MMI_OPC_0_PADDB  = (0x08 << 6) | MMI_OPC_CLASS_MMI0,
2304    MMI_OPC_0_PSUBB  = (0x09 << 6) | MMI_OPC_CLASS_MMI0,
2305    MMI_OPC_0_PCGTB  = (0x0A << 6) | MMI_OPC_CLASS_MMI0,
2306    MMI_OPC_0_PADDSW = (0x10 << 6) | MMI_OPC_CLASS_MMI0,
2307    MMI_OPC_0_PSUBSW = (0x11 << 6) | MMI_OPC_CLASS_MMI0,
2308    MMI_OPC_0_PEXTLW = (0x12 << 6) | MMI_OPC_CLASS_MMI0,
2309    MMI_OPC_0_PPACW  = (0x13 << 6) | MMI_OPC_CLASS_MMI0,
2310    MMI_OPC_0_PADDSH = (0x14 << 6) | MMI_OPC_CLASS_MMI0,
2311    MMI_OPC_0_PSUBSH = (0x15 << 6) | MMI_OPC_CLASS_MMI0,
2312    MMI_OPC_0_PEXTLH = (0x16 << 6) | MMI_OPC_CLASS_MMI0,
2313    MMI_OPC_0_PPACH  = (0x17 << 6) | MMI_OPC_CLASS_MMI0,
2314    MMI_OPC_0_PADDSB = (0x18 << 6) | MMI_OPC_CLASS_MMI0,
2315    MMI_OPC_0_PSUBSB = (0x19 << 6) | MMI_OPC_CLASS_MMI0,
2316    MMI_OPC_0_PEXTLB = (0x1A << 6) | MMI_OPC_CLASS_MMI0,
2317    MMI_OPC_0_PPACB  = (0x1B << 6) | MMI_OPC_CLASS_MMI0,
2318    MMI_OPC_0_PEXT5  = (0x1E << 6) | MMI_OPC_CLASS_MMI0,
2319    MMI_OPC_0_PPAC5  = (0x1F << 6) | MMI_OPC_CLASS_MMI0,
2320};
2321
2322/*
2323 * MMI instructions with opcode field = MMI and bits 5..0 = MMI1:
2324 *
2325 *  31    26                        10     6 5      0
2326 * +--------+----------------------+--------+--------+
2327 * |   MMI  |                      |function|  MMI1  |
2328 * +--------+----------------------+--------+--------+
2329 *
2330 * function  bits 7..6
2331 *     bits |   0   |   1   |   2   |   3
2332 *    10..8 |   00  |   01  |   10  |   11
2333 *   -------+-------+-------+-------+-------
2334 *    0 000 |   *   | PABSW | PCEQW | PMINW
2335 *    1 001 | PADSBH| PABSH | PCEQH | PMINH
2336 *    2 010 |   *   |   *   | PCEQB |   *
2337 *    3 011 |   *   |   *   |   *   |   *
2338 *    4 100 | PADDUW| PSUBUW| PEXTUW|   *
2339 *    5 101 | PADDUH| PSUBUH| PEXTUH|   *
2340 *    6 110 | PADDUB| PSUBUB| PEXTUB| QFSRV
2341 *    7 111 |   *   |   *   |   *   |   *
2342 */
2343
2344#define MASK_MMI1(op) (MASK_OP_MAJOR(op) | ((op) & 0x7FF))
2345enum {
2346    MMI_OPC_1_PABSW  = (0x01 << 6) | MMI_OPC_CLASS_MMI1,
2347    MMI_OPC_1_PCEQW  = (0x02 << 6) | MMI_OPC_CLASS_MMI1,
2348    MMI_OPC_1_PMINW  = (0x03 << 6) | MMI_OPC_CLASS_MMI1,
2349    MMI_OPC_1_PADSBH = (0x04 << 6) | MMI_OPC_CLASS_MMI1,
2350    MMI_OPC_1_PABSH  = (0x05 << 6) | MMI_OPC_CLASS_MMI1,
2351    MMI_OPC_1_PCEQH  = (0x06 << 6) | MMI_OPC_CLASS_MMI1,
2352    MMI_OPC_1_PMINH  = (0x07 << 6) | MMI_OPC_CLASS_MMI1,
2353    MMI_OPC_1_PCEQB  = (0x0A << 6) | MMI_OPC_CLASS_MMI1,
2354    MMI_OPC_1_PADDUW = (0x10 << 6) | MMI_OPC_CLASS_MMI1,
2355    MMI_OPC_1_PSUBUW = (0x11 << 6) | MMI_OPC_CLASS_MMI1,
2356    MMI_OPC_1_PEXTUW = (0x12 << 6) | MMI_OPC_CLASS_MMI1,
2357    MMI_OPC_1_PADDUH = (0x14 << 6) | MMI_OPC_CLASS_MMI1,
2358    MMI_OPC_1_PSUBUH = (0x15 << 6) | MMI_OPC_CLASS_MMI1,
2359    MMI_OPC_1_PEXTUH = (0x16 << 6) | MMI_OPC_CLASS_MMI1,
2360    MMI_OPC_1_PADDUB = (0x18 << 6) | MMI_OPC_CLASS_MMI1,
2361    MMI_OPC_1_PSUBUB = (0x19 << 6) | MMI_OPC_CLASS_MMI1,
2362    MMI_OPC_1_PEXTUB = (0x1A << 6) | MMI_OPC_CLASS_MMI1,
2363    MMI_OPC_1_QFSRV  = (0x1B << 6) | MMI_OPC_CLASS_MMI1,
2364};
2365
2366/*
2367 * MMI instructions with opcode field = MMI and bits 5..0 = MMI2:
2368 *
2369 *  31    26                        10     6 5      0
2370 * +--------+----------------------+--------+--------+
2371 * |   MMI  |                      |function|  MMI2  |
2372 * +--------+----------------------+--------+--------+
2373 *
2374 * function  bits 7..6
2375 *     bits |   0   |   1   |   2   |   3
2376 *    10..8 |   00  |   01  |   10  |   11
2377 *   -------+-------+-------+-------+-------
2378 *    0 000 | PMADDW|   *   | PSLLVW| PSRLVW
2379 *    1 001 | PMSUBW|   *   |   *   |   *
2380 *    2 010 | PMFHI | PMFLO | PINTH |   *
2381 *    3 011 | PMULTW| PDIVW | PCPYLD|   *
2382 *    4 100 | PMADDH| PHMADH|  PAND |  PXOR
2383 *    5 101 | PMSUBH| PHMSBH|   *   |   *
2384 *    6 110 |   *   |   *   | PEXEH | PREVH
2385 *    7 111 | PMULTH| PDIVBW| PEXEW | PROT3W
2386 */
2387
2388#define MASK_MMI2(op) (MASK_OP_MAJOR(op) | ((op) & 0x7FF))
2389enum {
2390    MMI_OPC_2_PMADDW = (0x00 << 6) | MMI_OPC_CLASS_MMI2,
2391    MMI_OPC_2_PSLLVW = (0x02 << 6) | MMI_OPC_CLASS_MMI2,
2392    MMI_OPC_2_PSRLVW = (0x03 << 6) | MMI_OPC_CLASS_MMI2,
2393    MMI_OPC_2_PMSUBW = (0x04 << 6) | MMI_OPC_CLASS_MMI2,
2394    MMI_OPC_2_PMFHI  = (0x08 << 6) | MMI_OPC_CLASS_MMI2,
2395    MMI_OPC_2_PMFLO  = (0x09 << 6) | MMI_OPC_CLASS_MMI2,
2396    MMI_OPC_2_PINTH  = (0x0A << 6) | MMI_OPC_CLASS_MMI2,
2397    MMI_OPC_2_PMULTW = (0x0C << 6) | MMI_OPC_CLASS_MMI2,
2398    MMI_OPC_2_PDIVW  = (0x0D << 6) | MMI_OPC_CLASS_MMI2,
2399    MMI_OPC_2_PCPYLD = (0x0E << 6) | MMI_OPC_CLASS_MMI2,
2400    MMI_OPC_2_PMADDH = (0x10 << 6) | MMI_OPC_CLASS_MMI2,
2401    MMI_OPC_2_PHMADH = (0x11 << 6) | MMI_OPC_CLASS_MMI2,
2402    MMI_OPC_2_PAND   = (0x12 << 6) | MMI_OPC_CLASS_MMI2,
2403    MMI_OPC_2_PXOR   = (0x13 << 6) | MMI_OPC_CLASS_MMI2,
2404    MMI_OPC_2_PMSUBH = (0x14 << 6) | MMI_OPC_CLASS_MMI2,
2405    MMI_OPC_2_PHMSBH = (0x15 << 6) | MMI_OPC_CLASS_MMI2,
2406    MMI_OPC_2_PEXEH  = (0x1A << 6) | MMI_OPC_CLASS_MMI2,
2407    MMI_OPC_2_PREVH  = (0x1B << 6) | MMI_OPC_CLASS_MMI2,
2408    MMI_OPC_2_PMULTH = (0x1C << 6) | MMI_OPC_CLASS_MMI2,
2409    MMI_OPC_2_PDIVBW = (0x1D << 6) | MMI_OPC_CLASS_MMI2,
2410    MMI_OPC_2_PEXEW  = (0x1E << 6) | MMI_OPC_CLASS_MMI2,
2411    MMI_OPC_2_PROT3W = (0x1F << 6) | MMI_OPC_CLASS_MMI2,
2412};
2413
2414/*
2415 * MMI instructions with opcode field = MMI and bits 5..0 = MMI3:
2416 *
2417 *  31    26                        10     6 5      0
2418 * +--------+----------------------+--------+--------+
2419 * |   MMI  |                      |function|  MMI3  |
2420 * +--------+----------------------+--------+--------+
2421 *
2422 * function  bits 7..6
2423 *     bits |   0   |   1   |   2   |   3
2424 *    10..8 |   00  |   01  |   10  |   11
2425 *   -------+-------+-------+-------+-------
2426 *    0 000 |PMADDUW|   *   |   *   | PSRAVW
2427 *    1 001 |   *   |   *   |   *   |   *
2428 *    2 010 | PMTHI | PMTLO | PINTEH|   *
2429 *    3 011 |PMULTUW| PDIVUW| PCPYUD|   *
2430 *    4 100 |   *   |   *   |  POR  |  PNOR
2431 *    5 101 |   *   |   *   |   *   |   *
2432 *    6 110 |   *   |   *   | PEXCH | PCPYH
2433 *    7 111 |   *   |   *   | PEXCW |   *
2434 */
2435
2436#define MASK_MMI3(op) (MASK_OP_MAJOR(op) | ((op) & 0x7FF))
2437enum {
2438    MMI_OPC_3_PMADDUW = (0x00 << 6) | MMI_OPC_CLASS_MMI3,
2439    MMI_OPC_3_PSRAVW  = (0x03 << 6) | MMI_OPC_CLASS_MMI3,
2440    MMI_OPC_3_PMTHI   = (0x08 << 6) | MMI_OPC_CLASS_MMI3,
2441    MMI_OPC_3_PMTLO   = (0x09 << 6) | MMI_OPC_CLASS_MMI3,
2442    MMI_OPC_3_PINTEH  = (0x0A << 6) | MMI_OPC_CLASS_MMI3,
2443    MMI_OPC_3_PMULTUW = (0x0C << 6) | MMI_OPC_CLASS_MMI3,
2444    MMI_OPC_3_PDIVUW  = (0x0D << 6) | MMI_OPC_CLASS_MMI3,
2445    MMI_OPC_3_PCPYUD  = (0x0E << 6) | MMI_OPC_CLASS_MMI3,
2446    MMI_OPC_3_POR     = (0x12 << 6) | MMI_OPC_CLASS_MMI3,
2447    MMI_OPC_3_PNOR    = (0x13 << 6) | MMI_OPC_CLASS_MMI3,
2448    MMI_OPC_3_PEXCH   = (0x1A << 6) | MMI_OPC_CLASS_MMI3,
2449    MMI_OPC_3_PCPYH   = (0x1B << 6) | MMI_OPC_CLASS_MMI3,
2450    MMI_OPC_3_PEXCW   = (0x1E << 6) | MMI_OPC_CLASS_MMI3,
2451};
2452
2453/* global register indices */
2454static TCGv cpu_gpr[32], cpu_PC;
2455static TCGv cpu_HI[MIPS_DSP_ACC], cpu_LO[MIPS_DSP_ACC];
2456static TCGv cpu_dspctrl, btarget, bcond;
2457static TCGv cpu_lladdr, cpu_llval;
2458static TCGv_i32 hflags;
2459static TCGv_i32 fpu_fcr0, fpu_fcr31;
2460static TCGv_i64 fpu_f64[32];
2461static TCGv_i64 msa_wr_d[64];
2462
2463#if defined(TARGET_MIPS64)
2464/* Upper halves of R5900's 128-bit registers: MMRs (multimedia registers) */
2465static TCGv_i64 cpu_mmr[32];
2466#endif
2467
2468#if !defined(TARGET_MIPS64)
2469/* MXU registers */
2470static TCGv mxu_gpr[NUMBER_OF_MXU_REGISTERS - 1];
2471static TCGv mxu_CR;
2472#endif
2473
2474#include "exec/gen-icount.h"
2475
2476#define gen_helper_0e0i(name, arg) do {                           \
2477    TCGv_i32 helper_tmp = tcg_const_i32(arg);                     \
2478    gen_helper_##name(cpu_env, helper_tmp);                       \
2479    tcg_temp_free_i32(helper_tmp);                                \
2480    } while (0)
2481
2482#define gen_helper_0e1i(name, arg1, arg2) do {                    \
2483    TCGv_i32 helper_tmp = tcg_const_i32(arg2);                    \
2484    gen_helper_##name(cpu_env, arg1, helper_tmp);                 \
2485    tcg_temp_free_i32(helper_tmp);                                \
2486    } while (0)
2487
2488#define gen_helper_1e0i(name, ret, arg1) do {                     \
2489    TCGv_i32 helper_tmp = tcg_const_i32(arg1);                    \
2490    gen_helper_##name(ret, cpu_env, helper_tmp);                  \
2491    tcg_temp_free_i32(helper_tmp);                                \
2492    } while (0)
2493
2494#define gen_helper_1e1i(name, ret, arg1, arg2) do {               \
2495    TCGv_i32 helper_tmp = tcg_const_i32(arg2);                    \
2496    gen_helper_##name(ret, cpu_env, arg1, helper_tmp);            \
2497    tcg_temp_free_i32(helper_tmp);                                \
2498    } while (0)
2499
2500#define gen_helper_0e2i(name, arg1, arg2, arg3) do {              \
2501    TCGv_i32 helper_tmp = tcg_const_i32(arg3);                    \
2502    gen_helper_##name(cpu_env, arg1, arg2, helper_tmp);           \
2503    tcg_temp_free_i32(helper_tmp);                                \
2504    } while (0)
2505
2506#define gen_helper_1e2i(name, ret, arg1, arg2, arg3) do {         \
2507    TCGv_i32 helper_tmp = tcg_const_i32(arg3);                    \
2508    gen_helper_##name(ret, cpu_env, arg1, arg2, helper_tmp);      \
2509    tcg_temp_free_i32(helper_tmp);                                \
2510    } while (0)
2511
2512#define gen_helper_0e3i(name, arg1, arg2, arg3, arg4) do {        \
2513    TCGv_i32 helper_tmp = tcg_const_i32(arg4);                    \
2514    gen_helper_##name(cpu_env, arg1, arg2, arg3, helper_tmp);     \
2515    tcg_temp_free_i32(helper_tmp);                                \
2516    } while (0)
2517
2518typedef struct DisasContext {
2519    DisasContextBase base;
2520    target_ulong saved_pc;
2521    target_ulong page_start;
2522    uint32_t opcode;
2523    uint64_t insn_flags;
2524    int32_t CP0_Config1;
2525    int32_t CP0_Config2;
2526    int32_t CP0_Config3;
2527    int32_t CP0_Config5;
2528    /* Routine used to access memory */
2529    int mem_idx;
2530    MemOp default_tcg_memop_mask;
2531    uint32_t hflags, saved_hflags;
2532    target_ulong btarget;
2533    bool ulri;
2534    int kscrexist;
2535    bool rxi;
2536    int ie;
2537    bool bi;
2538    bool bp;
2539    uint64_t PAMask;
2540    bool mvh;
2541    bool eva;
2542    bool sc;
2543    int CP0_LLAddr_shift;
2544    bool ps;
2545    bool vp;
2546    bool cmgcr;
2547    bool mrp;
2548    bool nan2008;
2549    bool abs2008;
2550    bool saar;
2551    bool mi;
2552    int gi;
2553} DisasContext;
2554
2555#define DISAS_STOP       DISAS_TARGET_0
2556#define DISAS_EXIT       DISAS_TARGET_1
2557
2558static const char * const regnames[] = {
2559    "r0", "at", "v0", "v1", "a0", "a1", "a2", "a3",
2560    "t0", "t1", "t2", "t3", "t4", "t5", "t6", "t7",
2561    "s0", "s1", "s2", "s3", "s4", "s5", "s6", "s7",
2562    "t8", "t9", "k0", "k1", "gp", "sp", "s8", "ra",
2563};
2564
2565static const char * const regnames_HI[] = {
2566    "HI0", "HI1", "HI2", "HI3",
2567};
2568
2569static const char * const regnames_LO[] = {
2570    "LO0", "LO1", "LO2", "LO3",
2571};
2572
2573static const char * const fregnames[] = {
2574    "f0",  "f1",  "f2",  "f3",  "f4",  "f5",  "f6",  "f7",
2575    "f8",  "f9",  "f10", "f11", "f12", "f13", "f14", "f15",
2576    "f16", "f17", "f18", "f19", "f20", "f21", "f22", "f23",
2577    "f24", "f25", "f26", "f27", "f28", "f29", "f30", "f31",
2578};
2579
2580static const char * const msaregnames[] = {
2581    "w0.d0",  "w0.d1",  "w1.d0",  "w1.d1",
2582    "w2.d0",  "w2.d1",  "w3.d0",  "w3.d1",
2583    "w4.d0",  "w4.d1",  "w5.d0",  "w5.d1",
2584    "w6.d0",  "w6.d1",  "w7.d0",  "w7.d1",
2585    "w8.d0",  "w8.d1",  "w9.d0",  "w9.d1",
2586    "w10.d0", "w10.d1", "w11.d0", "w11.d1",
2587    "w12.d0", "w12.d1", "w13.d0", "w13.d1",
2588    "w14.d0", "w14.d1", "w15.d0", "w15.d1",
2589    "w16.d0", "w16.d1", "w17.d0", "w17.d1",
2590    "w18.d0", "w18.d1", "w19.d0", "w19.d1",
2591    "w20.d0", "w20.d1", "w21.d0", "w21.d1",
2592    "w22.d0", "w22.d1", "w23.d0", "w23.d1",
2593    "w24.d0", "w24.d1", "w25.d0", "w25.d1",
2594    "w26.d0", "w26.d1", "w27.d0", "w27.d1",
2595    "w28.d0", "w28.d1", "w29.d0", "w29.d1",
2596    "w30.d0", "w30.d1", "w31.d0", "w31.d1",
2597};
2598
2599#if !defined(TARGET_MIPS64)
2600static const char * const mxuregnames[] = {
2601    "XR1",  "XR2",  "XR3",  "XR4",  "XR5",  "XR6",  "XR7",  "XR8",
2602    "XR9",  "XR10", "XR11", "XR12", "XR13", "XR14", "XR15", "MXU_CR",
2603};
2604#endif
2605
2606#define LOG_DISAS(...)                                                        \
2607    do {                                                                      \
2608        if (MIPS_DEBUG_DISAS) {                                               \
2609            qemu_log_mask(CPU_LOG_TB_IN_ASM, ## __VA_ARGS__);                 \
2610        }                                                                     \
2611    } while (0)
2612
2613#define MIPS_INVAL(op)                                                        \
2614    do {                                                                      \
2615        if (MIPS_DEBUG_DISAS) {                                               \
2616            qemu_log_mask(CPU_LOG_TB_IN_ASM,                                  \
2617                          TARGET_FMT_lx ": %08x Invalid %s %03x %03x %03x\n", \
2618                          ctx->base.pc_next, ctx->opcode, op,                 \
2619                          ctx->opcode >> 26, ctx->opcode & 0x3F,              \
2620                          ((ctx->opcode >> 16) & 0x1F));                      \
2621        }                                                                     \
2622    } while (0)
2623
2624/* General purpose registers moves. */
2625static inline void gen_load_gpr(TCGv t, int reg)
2626{
2627    if (reg == 0) {
2628        tcg_gen_movi_tl(t, 0);
2629    } else {
2630        tcg_gen_mov_tl(t, cpu_gpr[reg]);
2631    }
2632}
2633
2634static inline void gen_store_gpr(TCGv t, int reg)
2635{
2636    if (reg != 0) {
2637        tcg_gen_mov_tl(cpu_gpr[reg], t);
2638    }
2639}
2640
2641/* Moves to/from shadow registers. */
2642static inline void gen_load_srsgpr(int from, int to)
2643{
2644    TCGv t0 = tcg_temp_new();
2645
2646    if (from == 0) {
2647        tcg_gen_movi_tl(t0, 0);
2648    } else {
2649        TCGv_i32 t2 = tcg_temp_new_i32();
2650        TCGv_ptr addr = tcg_temp_new_ptr();
2651
2652        tcg_gen_ld_i32(t2, cpu_env, offsetof(CPUMIPSState, CP0_SRSCtl));
2653        tcg_gen_shri_i32(t2, t2, CP0SRSCtl_PSS);
2654        tcg_gen_andi_i32(t2, t2, 0xf);
2655        tcg_gen_muli_i32(t2, t2, sizeof(target_ulong) * 32);
2656        tcg_gen_ext_i32_ptr(addr, t2);
2657        tcg_gen_add_ptr(addr, cpu_env, addr);
2658
2659        tcg_gen_ld_tl(t0, addr, sizeof(target_ulong) * from);
2660        tcg_temp_free_ptr(addr);
2661        tcg_temp_free_i32(t2);
2662    }
2663    gen_store_gpr(t0, to);
2664    tcg_temp_free(t0);
2665}
2666
2667static inline void gen_store_srsgpr(int from, int to)
2668{
2669    if (to != 0) {
2670        TCGv t0 = tcg_temp_new();
2671        TCGv_i32 t2 = tcg_temp_new_i32();
2672        TCGv_ptr addr = tcg_temp_new_ptr();
2673
2674        gen_load_gpr(t0, from);
2675        tcg_gen_ld_i32(t2, cpu_env, offsetof(CPUMIPSState, CP0_SRSCtl));
2676        tcg_gen_shri_i32(t2, t2, CP0SRSCtl_PSS);
2677        tcg_gen_andi_i32(t2, t2, 0xf);
2678        tcg_gen_muli_i32(t2, t2, sizeof(target_ulong) * 32);
2679        tcg_gen_ext_i32_ptr(addr, t2);
2680        tcg_gen_add_ptr(addr, cpu_env, addr);
2681
2682        tcg_gen_st_tl(t0, addr, sizeof(target_ulong) * to);
2683        tcg_temp_free_ptr(addr);
2684        tcg_temp_free_i32(t2);
2685        tcg_temp_free(t0);
2686    }
2687}
2688
2689#if !defined(TARGET_MIPS64)
2690/* MXU General purpose registers moves. */
2691static inline void gen_load_mxu_gpr(TCGv t, unsigned int reg)
2692{
2693    if (reg == 0) {
2694        tcg_gen_movi_tl(t, 0);
2695    } else if (reg <= 15) {
2696        tcg_gen_mov_tl(t, mxu_gpr[reg - 1]);
2697    }
2698}
2699
2700static inline void gen_store_mxu_gpr(TCGv t, unsigned int reg)
2701{
2702    if (reg > 0 && reg <= 15) {
2703        tcg_gen_mov_tl(mxu_gpr[reg - 1], t);
2704    }
2705}
2706
2707/* MXU control register moves. */
2708static inline void gen_load_mxu_cr(TCGv t)
2709{
2710    tcg_gen_mov_tl(t, mxu_CR);
2711}
2712
2713static inline void gen_store_mxu_cr(TCGv t)
2714{
2715    /* TODO: Add handling of RW rules for MXU_CR. */
2716    tcg_gen_mov_tl(mxu_CR, t);
2717}
2718#endif
2719
2720
2721/* Tests */
2722static inline void gen_save_pc(target_ulong pc)
2723{
2724    tcg_gen_movi_tl(cpu_PC, pc);
2725}
2726
2727static inline void save_cpu_state(DisasContext *ctx, int do_save_pc)
2728{
2729    LOG_DISAS("hflags %08x saved %08x\n", ctx->hflags, ctx->saved_hflags);
2730    if (do_save_pc && ctx->base.pc_next != ctx->saved_pc) {
2731        gen_save_pc(ctx->base.pc_next);
2732        ctx->saved_pc = ctx->base.pc_next;
2733    }
2734    if (ctx->hflags != ctx->saved_hflags) {
2735        tcg_gen_movi_i32(hflags, ctx->hflags);
2736        ctx->saved_hflags = ctx->hflags;
2737        switch (ctx->hflags & MIPS_HFLAG_BMASK_BASE) {
2738        case MIPS_HFLAG_BR:
2739            break;
2740        case MIPS_HFLAG_BC:
2741        case MIPS_HFLAG_BL:
2742        case MIPS_HFLAG_B:
2743            tcg_gen_movi_tl(btarget, ctx->btarget);
2744            break;
2745        }
2746    }
2747}
2748
2749static inline void restore_cpu_state(CPUMIPSState *env, DisasContext *ctx)
2750{
2751    ctx->saved_hflags = ctx->hflags;
2752    switch (ctx->hflags & MIPS_HFLAG_BMASK_BASE) {
2753    case MIPS_HFLAG_BR:
2754        break;
2755    case MIPS_HFLAG_BC:
2756    case MIPS_HFLAG_BL:
2757    case MIPS_HFLAG_B:
2758        ctx->btarget = env->btarget;
2759        break;
2760    }
2761}
2762
2763static inline void generate_exception_err(DisasContext *ctx, int excp, int err)
2764{
2765    TCGv_i32 texcp = tcg_const_i32(excp);
2766    TCGv_i32 terr = tcg_const_i32(err);
2767    save_cpu_state(ctx, 1);
2768    gen_helper_raise_exception_err(cpu_env, texcp, terr);
2769    tcg_temp_free_i32(terr);
2770    tcg_temp_free_i32(texcp);
2771    ctx->base.is_jmp = DISAS_NORETURN;
2772}
2773
2774static inline void generate_exception(DisasContext *ctx, int excp)
2775{
2776    gen_helper_0e0i(raise_exception, excp);
2777}
2778
2779static inline void generate_exception_end(DisasContext *ctx, int excp)
2780{
2781    generate_exception_err(ctx, excp, 0);
2782}
2783
2784/* Floating point register moves. */
2785static void gen_load_fpr32(DisasContext *ctx, TCGv_i32 t, int reg)
2786{
2787    if (ctx->hflags & MIPS_HFLAG_FRE) {
2788        generate_exception(ctx, EXCP_RI);
2789    }
2790    tcg_gen_extrl_i64_i32(t, fpu_f64[reg]);
2791}
2792
2793static void gen_store_fpr32(DisasContext *ctx, TCGv_i32 t, int reg)
2794{
2795    TCGv_i64 t64;
2796    if (ctx->hflags & MIPS_HFLAG_FRE) {
2797        generate_exception(ctx, EXCP_RI);
2798    }
2799    t64 = tcg_temp_new_i64();
2800    tcg_gen_extu_i32_i64(t64, t);
2801    tcg_gen_deposit_i64(fpu_f64[reg], fpu_f64[reg], t64, 0, 32);
2802    tcg_temp_free_i64(t64);
2803}
2804
2805static void gen_load_fpr32h(DisasContext *ctx, TCGv_i32 t, int reg)
2806{
2807    if (ctx->hflags & MIPS_HFLAG_F64) {
2808        tcg_gen_extrh_i64_i32(t, fpu_f64[reg]);
2809    } else {
2810        gen_load_fpr32(ctx, t, reg | 1);
2811    }
2812}
2813
2814static void gen_store_fpr32h(DisasContext *ctx, TCGv_i32 t, int reg)
2815{
2816    if (ctx->hflags & MIPS_HFLAG_F64) {
2817        TCGv_i64 t64 = tcg_temp_new_i64();
2818        tcg_gen_extu_i32_i64(t64, t);
2819        tcg_gen_deposit_i64(fpu_f64[reg], fpu_f64[reg], t64, 32, 32);
2820        tcg_temp_free_i64(t64);
2821    } else {
2822        gen_store_fpr32(ctx, t, reg | 1);
2823    }
2824}
2825
2826static void gen_load_fpr64(DisasContext *ctx, TCGv_i64 t, int reg)
2827{
2828    if (ctx->hflags & MIPS_HFLAG_F64) {
2829        tcg_gen_mov_i64(t, fpu_f64[reg]);
2830    } else {
2831        tcg_gen_concat32_i64(t, fpu_f64[reg & ~1], fpu_f64[reg | 1]);
2832    }
2833}
2834
2835static void gen_store_fpr64(DisasContext *ctx, TCGv_i64 t, int reg)
2836{
2837    if (ctx->hflags & MIPS_HFLAG_F64) {
2838        tcg_gen_mov_i64(fpu_f64[reg], t);
2839    } else {
2840        TCGv_i64 t0;
2841        tcg_gen_deposit_i64(fpu_f64[reg & ~1], fpu_f64[reg & ~1], t, 0, 32);
2842        t0 = tcg_temp_new_i64();
2843        tcg_gen_shri_i64(t0, t, 32);
2844        tcg_gen_deposit_i64(fpu_f64[reg | 1], fpu_f64[reg | 1], t0, 0, 32);
2845        tcg_temp_free_i64(t0);
2846    }
2847}
2848
2849static inline int get_fp_bit(int cc)
2850{
2851    if (cc) {
2852        return 24 + cc;
2853    } else {
2854        return 23;
2855    }
2856}
2857
2858/* Addresses computation */
2859static inline void gen_op_addr_add(DisasContext *ctx, TCGv ret, TCGv arg0,
2860                                   TCGv arg1)
2861{
2862    tcg_gen_add_tl(ret, arg0, arg1);
2863
2864#if defined(TARGET_MIPS64)
2865    if (ctx->hflags & MIPS_HFLAG_AWRAP) {
2866        tcg_gen_ext32s_i64(ret, ret);
2867    }
2868#endif
2869}
2870
2871static inline void gen_op_addr_addi(DisasContext *ctx, TCGv ret, TCGv base,
2872                                    target_long ofs)
2873{
2874    tcg_gen_addi_tl(ret, base, ofs);
2875
2876#if defined(TARGET_MIPS64)
2877    if (ctx->hflags & MIPS_HFLAG_AWRAP) {
2878        tcg_gen_ext32s_i64(ret, ret);
2879    }
2880#endif
2881}
2882
2883/* Addresses computation (translation time) */
2884static target_long addr_add(DisasContext *ctx, target_long base,
2885                            target_long offset)
2886{
2887    target_long sum = base + offset;
2888
2889#if defined(TARGET_MIPS64)
2890    if (ctx->hflags & MIPS_HFLAG_AWRAP) {
2891        sum = (int32_t)sum;
2892    }
2893#endif
2894    return sum;
2895}
2896
2897/* Sign-extract the low 32-bits to a target_long.  */
2898static inline void gen_move_low32(TCGv ret, TCGv_i64 arg)
2899{
2900#if defined(TARGET_MIPS64)
2901    tcg_gen_ext32s_i64(ret, arg);
2902#else
2903    tcg_gen_extrl_i64_i32(ret, arg);
2904#endif
2905}
2906
2907/* Sign-extract the high 32-bits to a target_long.  */
2908static inline void gen_move_high32(TCGv ret, TCGv_i64 arg)
2909{
2910#if defined(TARGET_MIPS64)
2911    tcg_gen_sari_i64(ret, arg, 32);
2912#else
2913    tcg_gen_extrh_i64_i32(ret, arg);
2914#endif
2915}
2916
2917static inline void check_cp0_enabled(DisasContext *ctx)
2918{
2919    if (unlikely(!(ctx->hflags & MIPS_HFLAG_CP0))) {
2920        generate_exception_err(ctx, EXCP_CpU, 0);
2921    }
2922}
2923
2924static inline void check_cp1_enabled(DisasContext *ctx)
2925{
2926    if (unlikely(!(ctx->hflags & MIPS_HFLAG_FPU))) {
2927        generate_exception_err(ctx, EXCP_CpU, 1);
2928    }
2929}
2930
2931/*
2932 * Verify that the processor is running with COP1X instructions enabled.
2933 * This is associated with the nabla symbol in the MIPS32 and MIPS64
2934 * opcode tables.
2935 */
2936static inline void check_cop1x(DisasContext *ctx)
2937{
2938    if (unlikely(!(ctx->hflags & MIPS_HFLAG_COP1X))) {
2939        generate_exception_end(ctx, EXCP_RI);
2940    }
2941}
2942
2943/*
2944 * Verify that the processor is running with 64-bit floating-point
2945 * operations enabled.
2946 */
2947static inline void check_cp1_64bitmode(DisasContext *ctx)
2948{
2949    if (unlikely(~ctx->hflags & (MIPS_HFLAG_F64 | MIPS_HFLAG_COP1X))) {
2950        generate_exception_end(ctx, EXCP_RI);
2951    }
2952}
2953
2954/*
2955 * Verify if floating point register is valid; an operation is not defined
2956 * if bit 0 of any register specification is set and the FR bit in the
2957 * Status register equals zero, since the register numbers specify an
2958 * even-odd pair of adjacent coprocessor general registers. When the FR bit
2959 * in the Status register equals one, both even and odd register numbers
2960 * are valid. This limitation exists only for 64 bit wide (d,l,ps) registers.
2961 *
2962 * Multiple 64 bit wide registers can be checked by calling
2963 * gen_op_cp1_registers(freg1 | freg2 | ... | fregN);
2964 */
2965static inline void check_cp1_registers(DisasContext *ctx, int regs)
2966{
2967    if (unlikely(!(ctx->hflags & MIPS_HFLAG_F64) && (regs & 1))) {
2968        generate_exception_end(ctx, EXCP_RI);
2969    }
2970}
2971
2972/*
2973 * Verify that the processor is running with DSP instructions enabled.
2974 * This is enabled by CP0 Status register MX(24) bit.
2975 */
2976static inline void check_dsp(DisasContext *ctx)
2977{
2978    if (unlikely(!(ctx->hflags & MIPS_HFLAG_DSP))) {
2979        if (ctx->insn_flags & ASE_DSP) {
2980            generate_exception_end(ctx, EXCP_DSPDIS);
2981        } else {
2982            generate_exception_end(ctx, EXCP_RI);
2983        }
2984    }
2985}
2986
2987static inline void check_dsp_r2(DisasContext *ctx)
2988{
2989    if (unlikely(!(ctx->hflags & MIPS_HFLAG_DSP_R2))) {
2990        if (ctx->insn_flags & ASE_DSP) {
2991            generate_exception_end(ctx, EXCP_DSPDIS);
2992        } else {
2993            generate_exception_end(ctx, EXCP_RI);
2994        }
2995    }
2996}
2997
2998static inline void check_dsp_r3(DisasContext *ctx)
2999{
3000    if (unlikely(!(ctx->hflags & MIPS_HFLAG_DSP_R3))) {
3001        if (ctx->insn_flags & ASE_DSP) {
3002            generate_exception_end(ctx, EXCP_DSPDIS);
3003        } else {
3004            generate_exception_end(ctx, EXCP_RI);
3005        }
3006    }
3007}
3008
3009/*
3010 * This code generates a "reserved instruction" exception if the
3011 * CPU does not support the instruction set corresponding to flags.
3012 */
3013static inline void check_insn(DisasContext *ctx, uint64_t flags)
3014{
3015    if (unlikely(!(ctx->insn_flags & flags))) {
3016        generate_exception_end(ctx, EXCP_RI);
3017    }
3018}
3019
3020/*
3021 * This code generates a "reserved instruction" exception if the
3022 * CPU has corresponding flag set which indicates that the instruction
3023 * has been removed.
3024 */
3025static inline void check_insn_opc_removed(DisasContext *ctx, uint64_t flags)
3026{
3027    if (unlikely(ctx->insn_flags & flags)) {
3028        generate_exception_end(ctx, EXCP_RI);
3029    }
3030}
3031
3032/*
3033 * The Linux kernel traps certain reserved instruction exceptions to
3034 * emulate the corresponding instructions. QEMU is the kernel in user
3035 * mode, so those traps are emulated by accepting the instructions.
3036 *
3037 * A reserved instruction exception is generated for flagged CPUs if
3038 * QEMU runs in system mode.
3039 */
3040static inline void check_insn_opc_user_only(DisasContext *ctx, uint64_t flags)
3041{
3042#ifndef CONFIG_USER_ONLY
3043    check_insn_opc_removed(ctx, flags);
3044#endif
3045}
3046
3047/*
3048 * This code generates a "reserved instruction" exception if the
3049 * CPU does not support 64-bit paired-single (PS) floating point data type.
3050 */
3051static inline void check_ps(DisasContext *ctx)
3052{
3053    if (unlikely(!ctx->ps)) {
3054        generate_exception(ctx, EXCP_RI);
3055    }
3056    check_cp1_64bitmode(ctx);
3057}
3058
3059#ifdef TARGET_MIPS64
3060/*
3061 * This code generates a "reserved instruction" exception if 64-bit
3062 * instructions are not enabled.
3063 */
3064static inline void check_mips_64(DisasContext *ctx)
3065{
3066    if (unlikely(!(ctx->hflags & MIPS_HFLAG_64))) {
3067        generate_exception_end(ctx, EXCP_RI);
3068    }
3069}
3070#endif
3071
3072#ifndef CONFIG_USER_ONLY
3073static inline void check_mvh(DisasContext *ctx)
3074{
3075    if (unlikely(!ctx->mvh)) {
3076        generate_exception(ctx, EXCP_RI);
3077    }
3078}
3079#endif
3080
3081/*
3082 * This code generates a "reserved instruction" exception if the
3083 * Config5 XNP bit is set.
3084 */
3085static inline void check_xnp(DisasContext *ctx)
3086{
3087    if (unlikely(ctx->CP0_Config5 & (1 << CP0C5_XNP))) {
3088        generate_exception_end(ctx, EXCP_RI);
3089    }
3090}
3091
3092#ifndef CONFIG_USER_ONLY
3093/*
3094 * This code generates a "reserved instruction" exception if the
3095 * Config3 PW bit is NOT set.
3096 */
3097static inline void check_pw(DisasContext *ctx)
3098{
3099    if (unlikely(!(ctx->CP0_Config3 & (1 << CP0C3_PW)))) {
3100        generate_exception_end(ctx, EXCP_RI);
3101    }
3102}
3103#endif
3104
3105/*
3106 * This code generates a "reserved instruction" exception if the
3107 * Config3 MT bit is NOT set.
3108 */
3109static inline void check_mt(DisasContext *ctx)
3110{
3111    if (unlikely(!(ctx->CP0_Config3 & (1 << CP0C3_MT)))) {
3112        generate_exception_end(ctx, EXCP_RI);
3113    }
3114}
3115
3116#ifndef CONFIG_USER_ONLY
3117/*
3118 * This code generates a "coprocessor unusable" exception if CP0 is not
3119 * available, and, if that is not the case, generates a "reserved instruction"
3120 * exception if the Config5 MT bit is NOT set. This is needed for availability
3121 * control of some of MT ASE instructions.
3122 */
3123static inline void check_cp0_mt(DisasContext *ctx)
3124{
3125    if (unlikely(!(ctx->hflags & MIPS_HFLAG_CP0))) {
3126        generate_exception_err(ctx, EXCP_CpU, 0);
3127    } else {
3128        if (unlikely(!(ctx->CP0_Config3 & (1 << CP0C3_MT)))) {
3129            generate_exception_err(ctx, EXCP_RI, 0);
3130        }
3131    }
3132}
3133#endif
3134
3135/*
3136 * This code generates a "reserved instruction" exception if the
3137 * Config5 NMS bit is set.
3138 */
3139static inline void check_nms(DisasContext *ctx)
3140{
3141    if (unlikely(ctx->CP0_Config5 & (1 << CP0C5_NMS))) {
3142        generate_exception_end(ctx, EXCP_RI);
3143    }
3144}
3145
3146/*
3147 * This code generates a "reserved instruction" exception if the
3148 * Config5 NMS bit is set, and Config1 DL, Config1 IL, Config2 SL,
3149 * Config2 TL, and Config5 L2C are unset.
3150 */
3151static inline void check_nms_dl_il_sl_tl_l2c(DisasContext *ctx)
3152{
3153    if (unlikely((ctx->CP0_Config5 & (1 << CP0C5_NMS)) &&
3154                 !(ctx->CP0_Config1 & (1 << CP0C1_DL)) &&
3155                 !(ctx->CP0_Config1 & (1 << CP0C1_IL)) &&
3156                 !(ctx->CP0_Config2 & (1 << CP0C2_SL)) &&
3157                 !(ctx->CP0_Config2 & (1 << CP0C2_TL)) &&
3158                 !(ctx->CP0_Config5 & (1 << CP0C5_L2C)))) {
3159        generate_exception_end(ctx, EXCP_RI);
3160    }
3161}
3162
3163/*
3164 * This code generates a "reserved instruction" exception if the
3165 * Config5 EVA bit is NOT set.
3166 */
3167static inline void check_eva(DisasContext *ctx)
3168{
3169    if (unlikely(!(ctx->CP0_Config5 & (1 << CP0C5_EVA)))) {
3170        generate_exception_end(ctx, EXCP_RI);
3171    }
3172}
3173
3174
3175/*
3176 * Define small wrappers for gen_load_fpr* so that we have a uniform
3177 * calling interface for 32 and 64-bit FPRs.  No sense in changing
3178 * all callers for gen_load_fpr32 when we need the CTX parameter for
3179 * this one use.
3180 */
3181#define gen_ldcmp_fpr32(ctx, x, y) gen_load_fpr32(ctx, x, y)
3182#define gen_ldcmp_fpr64(ctx, x, y) gen_load_fpr64(ctx, x, y)
3183#define FOP_CONDS(type, abs, fmt, ifmt, bits)                                 \
3184static inline void gen_cmp ## type ## _ ## fmt(DisasContext *ctx, int n,      \
3185                                               int ft, int fs, int cc)        \
3186{                                                                             \
3187    TCGv_i##bits fp0 = tcg_temp_new_i##bits();                                \
3188    TCGv_i##bits fp1 = tcg_temp_new_i##bits();                                \
3189    switch (ifmt) {                                                           \
3190    case FMT_PS:                                                              \
3191        check_ps(ctx);                                                        \
3192        break;                                                                \
3193    case FMT_D:                                                               \
3194        if (abs) {                                                            \
3195            check_cop1x(ctx);                                                 \
3196        }                                                                     \
3197        check_cp1_registers(ctx, fs | ft);                                    \
3198        break;                                                                \
3199    case FMT_S:                                                               \
3200        if (abs) {                                                            \
3201            check_cop1x(ctx);                                                 \
3202        }                                                                     \
3203        break;                                                                \
3204    }                                                                         \
3205    gen_ldcmp_fpr##bits(ctx, fp0, fs);                                        \
3206    gen_ldcmp_fpr##bits(ctx, fp1, ft);                                        \
3207    switch (n) {                                                              \
3208    case  0:                                                                  \
3209        gen_helper_0e2i(cmp ## type ## _ ## fmt ## _f, fp0, fp1, cc);         \
3210    break;                                                                    \
3211    case  1:                                                                  \
3212        gen_helper_0e2i(cmp ## type ## _ ## fmt ## _un, fp0, fp1, cc);        \
3213    break;                                                                    \
3214    case  2:                                                                  \
3215        gen_helper_0e2i(cmp ## type ## _ ## fmt ## _eq, fp0, fp1, cc);        \
3216    break;                                                                    \
3217    case  3:                                                                  \
3218        gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ueq, fp0, fp1, cc);       \
3219    break;                                                                    \
3220    case  4:                                                                  \
3221        gen_helper_0e2i(cmp ## type ## _ ## fmt ## _olt, fp0, fp1, cc);       \
3222    break;                                                                    \
3223    case  5:                                                                  \
3224        gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ult, fp0, fp1, cc);       \
3225    break;                                                                    \
3226    case  6:                                                                  \
3227        gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ole, fp0, fp1, cc);       \
3228    break;                                                                    \
3229    case  7:                                                                  \
3230        gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ule, fp0, fp1, cc);       \
3231    break;                                                                    \
3232    case  8:                                                                  \
3233        gen_helper_0e2i(cmp ## type ## _ ## fmt ## _sf, fp0, fp1, cc);        \
3234    break;                                                                    \
3235    case  9:                                                                  \
3236        gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ngle, fp0, fp1, cc);      \
3237    break;                                                                    \
3238    case 10:                                                                  \
3239        gen_helper_0e2i(cmp ## type ## _ ## fmt ## _seq, fp0, fp1, cc);       \
3240    break;                                                                    \
3241    case 11:                                                                  \
3242        gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ngl, fp0, fp1, cc);       \
3243    break;                                                                    \
3244    case 12:                                                                  \
3245        gen_helper_0e2i(cmp ## type ## _ ## fmt ## _lt, fp0, fp1, cc);        \
3246    break;                                                                    \
3247    case 13:                                                                  \
3248        gen_helper_0e2i(cmp ## type ## _ ## fmt ## _nge, fp0, fp1, cc);       \
3249    break;                                                                    \
3250    case 14:                                                                  \
3251        gen_helper_0e2i(cmp ## type ## _ ## fmt ## _le, fp0, fp1, cc);        \
3252    break;                                                                    \
3253    case 15:                                                                  \
3254        gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ngt, fp0, fp1, cc);       \
3255    break;                                                                    \
3256    default:                                                                  \
3257        abort();                                                              \
3258    }                                                                         \
3259    tcg_temp_free_i##bits(fp0);                                               \
3260    tcg_temp_free_i##bits(fp1);                                               \
3261}
3262
3263FOP_CONDS(, 0, d, FMT_D, 64)
3264FOP_CONDS(abs, 1, d, FMT_D, 64)
3265FOP_CONDS(, 0, s, FMT_S, 32)
3266FOP_CONDS(abs, 1, s, FMT_S, 32)
3267FOP_CONDS(, 0, ps, FMT_PS, 64)
3268FOP_CONDS(abs, 1, ps, FMT_PS, 64)
3269#undef FOP_CONDS
3270
3271#define FOP_CONDNS(fmt, ifmt, bits, STORE)                              \
3272static inline void gen_r6_cmp_ ## fmt(DisasContext *ctx, int n,         \
3273                                      int ft, int fs, int fd)           \
3274{                                                                       \
3275    TCGv_i ## bits fp0 = tcg_temp_new_i ## bits();                      \
3276    TCGv_i ## bits fp1 = tcg_temp_new_i ## bits();                      \
3277    if (ifmt == FMT_D) {                                                \
3278        check_cp1_registers(ctx, fs | ft | fd);                         \
3279    }                                                                   \
3280    gen_ldcmp_fpr ## bits(ctx, fp0, fs);                                \
3281    gen_ldcmp_fpr ## bits(ctx, fp1, ft);                                \
3282    switch (n) {                                                        \
3283    case  0:                                                            \
3284        gen_helper_r6_cmp_ ## fmt ## _af(fp0, cpu_env, fp0, fp1);       \
3285        break;                                                          \
3286    case  1:                                                            \
3287        gen_helper_r6_cmp_ ## fmt ## _un(fp0, cpu_env, fp0, fp1);       \
3288        break;                                                          \
3289    case  2:                                                            \
3290        gen_helper_r6_cmp_ ## fmt ## _eq(fp0, cpu_env, fp0, fp1);       \
3291        break;                                                          \
3292    case  3:                                                            \
3293        gen_helper_r6_cmp_ ## fmt ## _ueq(fp0, cpu_env, fp0, fp1);      \
3294        break;                                                          \
3295    case  4:                                                            \
3296        gen_helper_r6_cmp_ ## fmt ## _lt(fp0, cpu_env, fp0, fp1);       \
3297        break;                                                          \
3298    case  5:                                                            \
3299        gen_helper_r6_cmp_ ## fmt ## _ult(fp0, cpu_env, fp0, fp1);      \
3300        break;                                                          \
3301    case  6:                                                            \
3302        gen_helper_r6_cmp_ ## fmt ## _le(fp0, cpu_env, fp0, fp1);       \
3303        break;                                                          \
3304    case  7:                                                            \
3305        gen_helper_r6_cmp_ ## fmt ## _ule(fp0, cpu_env, fp0, fp1);      \
3306        break;                                                          \
3307    case  8:                                                            \
3308        gen_helper_r6_cmp_ ## fmt ## _saf(fp0, cpu_env, fp0, fp1);      \
3309        break;                                                          \
3310    case  9:                                                            \
3311        gen_helper_r6_cmp_ ## fmt ## _sun(fp0, cpu_env, fp0, fp1);      \
3312        break;                                                          \
3313    case 10:                                                            \
3314        gen_helper_r6_cmp_ ## fmt ## _seq(fp0, cpu_env, fp0, fp1);      \
3315        break;                                                          \
3316    case 11:                                                            \
3317        gen_helper_r6_cmp_ ## fmt ## _sueq(fp0, cpu_env, fp0, fp1);     \
3318        break;                                                          \
3319    case 12:                                                            \
3320        gen_helper_r6_cmp_ ## fmt ## _slt(fp0, cpu_env, fp0, fp1);      \
3321        break;                                                          \
3322    case 13:                                                            \
3323        gen_helper_r6_cmp_ ## fmt ## _sult(fp0, cpu_env, fp0, fp1);     \
3324        break;                                                          \
3325    case 14:                                                            \
3326        gen_helper_r6_cmp_ ## fmt ## _sle(fp0, cpu_env, fp0, fp1);      \
3327        break;                                                          \
3328    case 15:                                                            \
3329        gen_helper_r6_cmp_ ## fmt ## _sule(fp0, cpu_env, fp0, fp1);     \
3330        break;                                                          \
3331    case 17:                                                            \
3332        gen_helper_r6_cmp_ ## fmt ## _or(fp0, cpu_env, fp0, fp1);       \
3333        break;                                                          \
3334    case 18:                                                            \
3335        gen_helper_r6_cmp_ ## fmt ## _une(fp0, cpu_env, fp0, fp1);      \
3336        break;                                                          \
3337    case 19:                                                            \
3338        gen_helper_r6_cmp_ ## fmt ## _ne(fp0, cpu_env, fp0, fp1);       \
3339        break;                                                          \
3340    case 25:                                                            \
3341        gen_helper_r6_cmp_ ## fmt ## _sor(fp0, cpu_env, fp0, fp1);      \
3342        break;                                                          \
3343    case 26:                                                            \
3344        gen_helper_r6_cmp_ ## fmt ## _sune(fp0, cpu_env, fp0, fp1);     \
3345        break;                                                          \
3346    case 27:                                                            \
3347        gen_helper_r6_cmp_ ## fmt ## _sne(fp0, cpu_env, fp0, fp1);      \
3348        break;                                                          \
3349    default:                                                            \
3350        abort();                                                        \
3351    }                                                                   \
3352    STORE;                                                              \
3353    tcg_temp_free_i ## bits(fp0);                                       \
3354    tcg_temp_free_i ## bits(fp1);                                       \
3355}
3356
3357FOP_CONDNS(d, FMT_D, 64, gen_store_fpr64(ctx, fp0, fd))
3358FOP_CONDNS(s, FMT_S, 32, gen_store_fpr32(ctx, fp0, fd))
3359#undef FOP_CONDNS
3360#undef gen_ldcmp_fpr32
3361#undef gen_ldcmp_fpr64
3362
3363/* load/store instructions. */
3364#ifdef CONFIG_USER_ONLY
3365#define OP_LD_ATOMIC(insn, fname)                                          \
3366static inline void op_ld_##insn(TCGv ret, TCGv arg1, int mem_idx,          \
3367                                DisasContext *ctx)                         \
3368{                                                                          \
3369    TCGv t0 = tcg_temp_new();                                              \
3370    tcg_gen_mov_tl(t0, arg1);                                              \
3371    tcg_gen_qemu_##fname(ret, arg1, ctx->mem_idx);                         \
3372    tcg_gen_st_tl(t0, cpu_env, offsetof(CPUMIPSState, lladdr));            \
3373    tcg_gen_st_tl(ret, cpu_env, offsetof(CPUMIPSState, llval));            \
3374    tcg_temp_free(t0);                                                     \
3375}
3376#else
3377#define OP_LD_ATOMIC(insn, fname)                                          \
3378static inline void op_ld_##insn(TCGv ret, TCGv arg1, int mem_idx,          \
3379                                DisasContext *ctx)                         \
3380{                                                                          \
3381    gen_helper_1e1i(insn, ret, arg1, mem_idx);                             \
3382}
3383#endif
3384OP_LD_ATOMIC(ll, ld32s);
3385#if defined(TARGET_MIPS64)
3386OP_LD_ATOMIC(lld, ld64);
3387#endif
3388#undef OP_LD_ATOMIC
3389
3390static void gen_base_offset_addr(DisasContext *ctx, TCGv addr,
3391                                 int base, int offset)
3392{
3393    if (base == 0) {
3394        tcg_gen_movi_tl(addr, offset);
3395    } else if (offset == 0) {
3396        gen_load_gpr(addr, base);
3397    } else {
3398        tcg_gen_movi_tl(addr, offset);
3399        gen_op_addr_add(ctx, addr, cpu_gpr[base], addr);
3400    }
3401}
3402
3403static target_ulong pc_relative_pc(DisasContext *ctx)
3404{
3405    target_ulong pc = ctx->base.pc_next;
3406
3407    if (ctx->hflags & MIPS_HFLAG_BMASK) {
3408        int branch_bytes = ctx->hflags & MIPS_HFLAG_BDS16 ? 2 : 4;
3409
3410        pc -= branch_bytes;
3411    }
3412
3413    pc &= ~(target_ulong)3;
3414    return pc;
3415}
3416
3417/* Load */
3418static void gen_ld(DisasContext *ctx, uint32_t opc,
3419                   int rt, int base, int offset)
3420{
3421    TCGv t0, t1, t2;
3422    int mem_idx = ctx->mem_idx;
3423
3424    if (rt == 0 && ctx->insn_flags & (INSN_LOONGSON2E | INSN_LOONGSON2F)) {
3425        /*
3426         * Loongson CPU uses a load to zero register for prefetch.
3427         * We emulate it as a NOP. On other CPU we must perform the
3428         * actual memory access.
3429         */
3430        return;
3431    }
3432
3433    t0 = tcg_temp_new();
3434    gen_base_offset_addr(ctx, t0, base, offset);
3435
3436    switch (opc) {
3437#if defined(TARGET_MIPS64)
3438    case OPC_LWU:
3439        tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TEUL |
3440                           ctx->default_tcg_memop_mask);
3441        gen_store_gpr(t0, rt);
3442        break;
3443    case OPC_LD:
3444        tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TEQ |
3445                           ctx->default_tcg_memop_mask);
3446        gen_store_gpr(t0, rt);
3447        break;
3448    case OPC_LLD:
3449    case R6_OPC_LLD:
3450        op_ld_lld(t0, t0, mem_idx, ctx);
3451        gen_store_gpr(t0, rt);
3452        break;
3453    case OPC_LDL:
3454        t1 = tcg_temp_new();
3455        /*
3456         * Do a byte access to possibly trigger a page
3457         * fault with the unaligned address.
3458         */
3459        tcg_gen_qemu_ld_tl(t1, t0, mem_idx, MO_UB);
3460        tcg_gen_andi_tl(t1, t0, 7);
3461#ifndef TARGET_WORDS_BIGENDIAN
3462        tcg_gen_xori_tl(t1, t1, 7);
3463#endif
3464        tcg_gen_shli_tl(t1, t1, 3);
3465        tcg_gen_andi_tl(t0, t0, ~7);
3466        tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TEQ);
3467        tcg_gen_shl_tl(t0, t0, t1);
3468        t2 = tcg_const_tl(-1);
3469        tcg_gen_shl_tl(t2, t2, t1);
3470        gen_load_gpr(t1, rt);
3471        tcg_gen_andc_tl(t1, t1, t2);
3472        tcg_temp_free(t2);
3473        tcg_gen_or_tl(t0, t0, t1);
3474        tcg_temp_free(t1);
3475        gen_store_gpr(t0, rt);
3476        break;
3477    case OPC_LDR:
3478        t1 = tcg_temp_new();
3479        /*
3480         * Do a byte access to possibly trigger a page
3481         * fault with the unaligned address.
3482         */
3483        tcg_gen_qemu_ld_tl(t1, t0, mem_idx, MO_UB);
3484        tcg_gen_andi_tl(t1, t0, 7);
3485#ifdef TARGET_WORDS_BIGENDIAN
3486        tcg_gen_xori_tl(t1, t1, 7);
3487#endif
3488        tcg_gen_shli_tl(t1, t1, 3);
3489        tcg_gen_andi_tl(t0, t0, ~7);
3490        tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TEQ);
3491        tcg_gen_shr_tl(t0, t0, t1);
3492        tcg_gen_xori_tl(t1, t1, 63);
3493        t2 = tcg_const_tl(0xfffffffffffffffeull);
3494        tcg_gen_shl_tl(t2, t2, t1);
3495        gen_load_gpr(t1, rt);
3496        tcg_gen_and_tl(t1, t1, t2);
3497        tcg_temp_free(t2);
3498        tcg_gen_or_tl(t0, t0, t1);
3499        tcg_temp_free(t1);
3500        gen_store_gpr(t0, rt);
3501        break;
3502    case OPC_LDPC:
3503        t1 = tcg_const_tl(pc_relative_pc(ctx));
3504        gen_op_addr_add(ctx, t0, t0, t1);
3505        tcg_temp_free(t1);
3506        tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TEQ);
3507        gen_store_gpr(t0, rt);
3508        break;
3509#endif
3510    case OPC_LWPC:
3511        t1 = tcg_const_tl(pc_relative_pc(ctx));
3512        gen_op_addr_add(ctx, t0, t0, t1);
3513        tcg_temp_free(t1);
3514        tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TESL);
3515        gen_store_gpr(t0, rt);
3516        break;
3517    case OPC_LWE:
3518        mem_idx = MIPS_HFLAG_UM;
3519        /* fall through */
3520    case OPC_LW:
3521        tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TESL |
3522                           ctx->default_tcg_memop_mask);
3523        gen_store_gpr(t0, rt);
3524        break;
3525    case OPC_LHE:
3526        mem_idx = MIPS_HFLAG_UM;
3527        /* fall through */
3528    case OPC_LH:
3529        tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TESW |
3530                           ctx->default_tcg_memop_mask);
3531        gen_store_gpr(t0, rt);
3532        break;
3533    case OPC_LHUE:
3534        mem_idx = MIPS_HFLAG_UM;
3535        /* fall through */
3536    case OPC_LHU:
3537        tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TEUW |
3538                           ctx->default_tcg_memop_mask);
3539        gen_store_gpr(t0, rt);
3540        break;
3541    case OPC_LBE:
3542        mem_idx = MIPS_HFLAG_UM;
3543        /* fall through */
3544    case OPC_LB:
3545        tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_SB);
3546        gen_store_gpr(t0, rt);
3547        break;
3548    case OPC_LBUE:
3549        mem_idx = MIPS_HFLAG_UM;
3550        /* fall through */
3551    case OPC_LBU:
3552        tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_UB);
3553        gen_store_gpr(t0, rt);
3554        break;
3555    case OPC_LWLE:
3556        mem_idx = MIPS_HFLAG_UM;
3557        /* fall through */
3558    case OPC_LWL:
3559        t1 = tcg_temp_new();
3560        /*
3561         * Do a byte access to possibly trigger a page
3562         * fault with the unaligned address.
3563         */
3564        tcg_gen_qemu_ld_tl(t1, t0, mem_idx, MO_UB);
3565        tcg_gen_andi_tl(t1, t0, 3);
3566#ifndef TARGET_WORDS_BIGENDIAN
3567        tcg_gen_xori_tl(t1, t1, 3);
3568#endif
3569        tcg_gen_shli_tl(t1, t1, 3);
3570        tcg_gen_andi_tl(t0, t0, ~3);
3571        tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TEUL);
3572        tcg_gen_shl_tl(t0, t0, t1);
3573        t2 = tcg_const_tl(-1);
3574        tcg_gen_shl_tl(t2, t2, t1);
3575        gen_load_gpr(t1, rt);
3576        tcg_gen_andc_tl(t1, t1, t2);
3577        tcg_temp_free(t2);
3578        tcg_gen_or_tl(t0, t0, t1);
3579        tcg_temp_free(t1);
3580        tcg_gen_ext32s_tl(t0, t0);
3581        gen_store_gpr(t0, rt);
3582        break;
3583    case OPC_LWRE:
3584        mem_idx = MIPS_HFLAG_UM;
3585        /* fall through */
3586    case OPC_LWR:
3587        t1 = tcg_temp_new();
3588        /*
3589         * Do a byte access to possibly trigger a page
3590         * fault with the unaligned address.
3591         */
3592        tcg_gen_qemu_ld_tl(t1, t0, mem_idx, MO_UB);
3593        tcg_gen_andi_tl(t1, t0, 3);
3594#ifdef TARGET_WORDS_BIGENDIAN
3595        tcg_gen_xori_tl(t1, t1, 3);
3596#endif
3597        tcg_gen_shli_tl(t1, t1, 3);
3598        tcg_gen_andi_tl(t0, t0, ~3);
3599        tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TEUL);
3600        tcg_gen_shr_tl(t0, t0, t1);
3601        tcg_gen_xori_tl(t1, t1, 31);
3602        t2 = tcg_const_tl(0xfffffffeull);
3603        tcg_gen_shl_tl(t2, t2, t1);
3604        gen_load_gpr(t1, rt);
3605        tcg_gen_and_tl(t1, t1, t2);
3606        tcg_temp_free(t2);
3607        tcg_gen_or_tl(t0, t0, t1);
3608        tcg_temp_free(t1);
3609        tcg_gen_ext32s_tl(t0, t0);
3610        gen_store_gpr(t0, rt);
3611        break;
3612    case OPC_LLE:
3613        mem_idx = MIPS_HFLAG_UM;
3614        /* fall through */
3615    case OPC_LL:
3616    case R6_OPC_LL:
3617        op_ld_ll(t0, t0, mem_idx, ctx);
3618        gen_store_gpr(t0, rt);
3619        break;
3620    }
3621    tcg_temp_free(t0);
3622}
3623
3624static void gen_llwp(DisasContext *ctx, uint32_t base, int16_t offset,
3625                    uint32_t reg1, uint32_t reg2)
3626{
3627    TCGv taddr = tcg_temp_new();
3628    TCGv_i64 tval = tcg_temp_new_i64();
3629    TCGv tmp1 = tcg_temp_new();
3630    TCGv tmp2 = tcg_temp_new();
3631
3632    gen_base_offset_addr(ctx, taddr, base, offset);
3633    tcg_gen_qemu_ld64(tval, taddr, ctx->mem_idx);
3634#ifdef TARGET_WORDS_BIGENDIAN
3635    tcg_gen_extr_i64_tl(tmp2, tmp1, tval);
3636#else
3637    tcg_gen_extr_i64_tl(tmp1, tmp2, tval);
3638#endif
3639    gen_store_gpr(tmp1, reg1);
3640    tcg_temp_free(tmp1);
3641    gen_store_gpr(tmp2, reg2);
3642    tcg_temp_free(tmp2);
3643    tcg_gen_st_i64(tval, cpu_env, offsetof(CPUMIPSState, llval_wp));
3644    tcg_temp_free_i64(tval);
3645    tcg_gen_st_tl(taddr, cpu_env, offsetof(CPUMIPSState, lladdr));
3646    tcg_temp_free(taddr);
3647}
3648
3649/* Store */
3650static void gen_st(DisasContext *ctx, uint32_t opc, int rt,
3651                   int base, int offset)
3652{
3653    TCGv t0 = tcg_temp_new();
3654    TCGv t1 = tcg_temp_new();
3655    int mem_idx = ctx->mem_idx;
3656
3657    gen_base_offset_addr(ctx, t0, base, offset);
3658    gen_load_gpr(t1, rt);
3659    switch (opc) {
3660#if defined(TARGET_MIPS64)
3661    case OPC_SD:
3662        tcg_gen_qemu_st_tl(t1, t0, mem_idx, MO_TEQ |
3663                           ctx->default_tcg_memop_mask);
3664        break;
3665    case OPC_SDL:
3666        gen_helper_0e2i(sdl, t1, t0, mem_idx);
3667        break;
3668    case OPC_SDR:
3669        gen_helper_0e2i(sdr, t1, t0, mem_idx);
3670        break;
3671#endif
3672    case OPC_SWE:
3673        mem_idx = MIPS_HFLAG_UM;
3674        /* fall through */
3675    case OPC_SW:
3676        tcg_gen_qemu_st_tl(t1, t0, mem_idx, MO_TEUL |
3677                           ctx->default_tcg_memop_mask);
3678        break;
3679    case OPC_SHE:
3680        mem_idx = MIPS_HFLAG_UM;
3681        /* fall through */
3682    case OPC_SH:
3683        tcg_gen_qemu_st_tl(t1, t0, mem_idx, MO_TEUW |
3684                           ctx->default_tcg_memop_mask);
3685        break;
3686    case OPC_SBE:
3687        mem_idx = MIPS_HFLAG_UM;
3688        /* fall through */
3689    case OPC_SB:
3690        tcg_gen_qemu_st_tl(t1, t0, mem_idx, MO_8);
3691        break;
3692    case OPC_SWLE:
3693        mem_idx = MIPS_HFLAG_UM;
3694        /* fall through */
3695    case OPC_SWL:
3696        gen_helper_0e2i(swl, t1, t0, mem_idx);
3697        break;
3698    case OPC_SWRE:
3699        mem_idx = MIPS_HFLAG_UM;
3700        /* fall through */
3701    case OPC_SWR:
3702        gen_helper_0e2i(swr, t1, t0, mem_idx);
3703        break;
3704    }
3705    tcg_temp_free(t0);
3706    tcg_temp_free(t1);
3707}
3708
3709
3710/* Store conditional */
3711static void gen_st_cond(DisasContext *ctx, int rt, int base, int offset,
3712                        MemOp tcg_mo, bool eva)
3713{
3714    TCGv addr, t0, val;
3715    TCGLabel *l1 = gen_new_label();
3716    TCGLabel *done = gen_new_label();
3717
3718    t0 = tcg_temp_new();
3719    addr = tcg_temp_new();
3720    /* compare the address against that of the preceeding LL */
3721    gen_base_offset_addr(ctx, addr, base, offset);
3722    tcg_gen_brcond_tl(TCG_COND_EQ, addr, cpu_lladdr, l1);
3723    tcg_temp_free(addr);
3724    tcg_gen_movi_tl(t0, 0);
3725    gen_store_gpr(t0, rt);
3726    tcg_gen_br(done);
3727
3728    gen_set_label(l1);
3729    /* generate cmpxchg */
3730    val = tcg_temp_new();
3731    gen_load_gpr(val, rt);
3732    tcg_gen_atomic_cmpxchg_tl(t0, cpu_lladdr, cpu_llval, val,
3733                              eva ? MIPS_HFLAG_UM : ctx->mem_idx, tcg_mo);
3734    tcg_gen_setcond_tl(TCG_COND_EQ, t0, t0, cpu_llval);
3735    gen_store_gpr(t0, rt);
3736    tcg_temp_free(val);
3737
3738    gen_set_label(done);
3739    tcg_temp_free(t0);
3740}
3741
3742
3743static void gen_scwp(DisasContext *ctx, uint32_t base, int16_t offset,
3744                    uint32_t reg1, uint32_t reg2, bool eva)
3745{
3746    TCGv taddr = tcg_temp_local_new();
3747    TCGv lladdr = tcg_temp_local_new();
3748    TCGv_i64 tval = tcg_temp_new_i64();
3749    TCGv_i64 llval = tcg_temp_new_i64();
3750    TCGv_i64 val = tcg_temp_new_i64();
3751    TCGv tmp1 = tcg_temp_new();
3752    TCGv tmp2 = tcg_temp_new();
3753    TCGLabel *lab_fail = gen_new_label();
3754    TCGLabel *lab_done = gen_new_label();
3755
3756    gen_base_offset_addr(ctx, taddr, base, offset);
3757
3758    tcg_gen_ld_tl(lladdr, cpu_env, offsetof(CPUMIPSState, lladdr));
3759    tcg_gen_brcond_tl(TCG_COND_NE, taddr, lladdr, lab_fail);
3760
3761    gen_load_gpr(tmp1, reg1);
3762    gen_load_gpr(tmp2, reg2);
3763
3764#ifdef TARGET_WORDS_BIGENDIAN
3765    tcg_gen_concat_tl_i64(tval, tmp2, tmp1);
3766#else
3767    tcg_gen_concat_tl_i64(tval, tmp1, tmp2);
3768#endif
3769
3770    tcg_gen_ld_i64(llval, cpu_env, offsetof(CPUMIPSState, llval_wp));
3771    tcg_gen_atomic_cmpxchg_i64(val, taddr, llval, tval,
3772                               eva ? MIPS_HFLAG_UM : ctx->mem_idx, MO_64);
3773    if (reg1 != 0) {
3774        tcg_gen_movi_tl(cpu_gpr[reg1], 1);
3775    }
3776    tcg_gen_brcond_i64(TCG_COND_EQ, val, llval, lab_done);
3777
3778    gen_set_label(lab_fail);
3779
3780    if (reg1 != 0) {
3781        tcg_gen_movi_tl(cpu_gpr[reg1], 0);
3782    }
3783    gen_set_label(lab_done);
3784    tcg_gen_movi_tl(lladdr, -1);
3785    tcg_gen_st_tl(lladdr, cpu_env, offsetof(CPUMIPSState, lladdr));
3786}
3787
3788/* Load and store */
3789static void gen_flt_ldst(DisasContext *ctx, uint32_t opc, int ft,
3790                         TCGv t0)
3791{
3792    /*
3793     * Don't do NOP if destination is zero: we must perform the actual
3794     * memory access.
3795     */
3796    switch (opc) {
3797    case OPC_LWC1:
3798        {
3799            TCGv_i32 fp0 = tcg_temp_new_i32();
3800            tcg_gen_qemu_ld_i32(fp0, t0, ctx->mem_idx, MO_TESL |
3801                                ctx->default_tcg_memop_mask);
3802            gen_store_fpr32(ctx, fp0, ft);
3803            tcg_temp_free_i32(fp0);
3804        }
3805        break;
3806    case OPC_SWC1:
3807        {
3808            TCGv_i32 fp0 = tcg_temp_new_i32();
3809            gen_load_fpr32(ctx, fp0, ft);
3810            tcg_gen_qemu_st_i32(fp0, t0, ctx->mem_idx, MO_TEUL |
3811                                ctx->default_tcg_memop_mask);
3812            tcg_temp_free_i32(fp0);
3813        }
3814        break;
3815    case OPC_LDC1:
3816        {
3817            TCGv_i64 fp0 = tcg_temp_new_i64();
3818            tcg_gen_qemu_ld_i64(fp0, t0, ctx->mem_idx, MO_TEQ |
3819                                ctx->default_tcg_memop_mask);
3820            gen_store_fpr64(ctx, fp0, ft);
3821            tcg_temp_free_i64(fp0);
3822        }
3823        break;
3824    case OPC_SDC1:
3825        {
3826            TCGv_i64 fp0 = tcg_temp_new_i64();
3827            gen_load_fpr64(ctx, fp0, ft);
3828            tcg_gen_qemu_st_i64(fp0, t0, ctx->mem_idx, MO_TEQ |
3829                                ctx->default_tcg_memop_mask);
3830            tcg_temp_free_i64(fp0);
3831        }
3832        break;
3833    default:
3834        MIPS_INVAL("flt_ldst");
3835        generate_exception_end(ctx, EXCP_RI);
3836        break;
3837    }
3838}
3839
3840static void gen_cop1_ldst(DisasContext *ctx, uint32_t op, int rt,
3841                          int rs, int16_t imm)
3842{
3843    TCGv t0 = tcg_temp_new();
3844
3845    if (ctx->CP0_Config1 & (1 << CP0C1_FP)) {
3846        check_cp1_enabled(ctx);
3847        switch (op) {
3848        case OPC_LDC1:
3849        case OPC_SDC1:
3850            check_insn(ctx, ISA_MIPS2);
3851            /* Fallthrough */
3852        default:
3853            gen_base_offset_addr(ctx, t0, rs, imm);
3854            gen_flt_ldst(ctx, op, rt, t0);
3855        }
3856    } else {
3857        generate_exception_err(ctx, EXCP_CpU, 1);
3858    }
3859    tcg_temp_free(t0);
3860}
3861
3862/* Arithmetic with immediate operand */
3863static void gen_arith_imm(DisasContext *ctx, uint32_t opc,
3864                          int rt, int rs, int imm)
3865{
3866    target_ulong uimm = (target_long)imm; /* Sign extend to 32/64 bits */
3867
3868    if (rt == 0 && opc != OPC_ADDI && opc != OPC_DADDI) {
3869        /*
3870         * If no destination, treat it as a NOP.
3871         * For addi, we must generate the overflow exception when needed.
3872         */
3873        return;
3874    }
3875    switch (opc) {
3876    case OPC_ADDI:
3877        {
3878            TCGv t0 = tcg_temp_local_new();
3879            TCGv t1 = tcg_temp_new();
3880            TCGv t2 = tcg_temp_new();
3881            TCGLabel *l1 = gen_new_label();
3882
3883            gen_load_gpr(t1, rs);
3884            tcg_gen_addi_tl(t0, t1, uimm);
3885            tcg_gen_ext32s_tl(t0, t0);
3886
3887            tcg_gen_xori_tl(t1, t1, ~uimm);
3888            tcg_gen_xori_tl(t2, t0, uimm);
3889            tcg_gen_and_tl(t1, t1, t2);
3890            tcg_temp_free(t2);
3891            tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
3892            tcg_temp_free(t1);
3893            /* operands of same sign, result different sign */
3894            generate_exception(ctx, EXCP_OVERFLOW);
3895            gen_set_label(l1);
3896            tcg_gen_ext32s_tl(t0, t0);
3897            gen_store_gpr(t0, rt);
3898            tcg_temp_free(t0);
3899        }
3900        break;
3901    case OPC_ADDIU:
3902        if (rs != 0) {
3903            tcg_gen_addi_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
3904            tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
3905        } else {
3906            tcg_gen_movi_tl(cpu_gpr[rt], uimm);
3907        }
3908        break;
3909#if defined(TARGET_MIPS64)
3910    case OPC_DADDI:
3911        {
3912            TCGv t0 = tcg_temp_local_new();
3913            TCGv t1 = tcg_temp_new();
3914            TCGv t2 = tcg_temp_new();
3915            TCGLabel *l1 = gen_new_label();
3916
3917            gen_load_gpr(t1, rs);
3918            tcg_gen_addi_tl(t0, t1, uimm);
3919
3920            tcg_gen_xori_tl(t1, t1, ~uimm);
3921            tcg_gen_xori_tl(t2, t0, uimm);
3922            tcg_gen_and_tl(t1, t1, t2);
3923            tcg_temp_free(t2);
3924            tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
3925            tcg_temp_free(t1);
3926            /* operands of same sign, result different sign */
3927            generate_exception(ctx, EXCP_OVERFLOW);
3928            gen_set_label(l1);
3929            gen_store_gpr(t0, rt);
3930            tcg_temp_free(t0);
3931        }
3932        break;
3933    case OPC_DADDIU:
3934        if (rs != 0) {
3935            tcg_gen_addi_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
3936        } else {
3937            tcg_gen_movi_tl(cpu_gpr[rt], uimm);
3938        }
3939        break;
3940#endif
3941    }
3942}
3943
3944/* Logic with immediate operand */
3945static void gen_logic_imm(DisasContext *ctx, uint32_t opc,
3946                          int rt, int rs, int16_t imm)
3947{
3948    target_ulong uimm;
3949
3950    if (rt == 0) {
3951        /* If no destination, treat it as a NOP. */
3952        return;
3953    }
3954    uimm = (uint16_t)imm;
3955    switch (opc) {
3956    case OPC_ANDI:
3957        if (likely(rs != 0)) {
3958            tcg_gen_andi_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
3959        } else {
3960            tcg_gen_movi_tl(cpu_gpr[rt], 0);
3961        }
3962        break;
3963    case OPC_ORI:
3964        if (rs != 0) {
3965            tcg_gen_ori_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
3966        } else {
3967            tcg_gen_movi_tl(cpu_gpr[rt], uimm);
3968        }
3969        break;
3970    case OPC_XORI:
3971        if (likely(rs != 0)) {
3972            tcg_gen_xori_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
3973        } else {
3974            tcg_gen_movi_tl(cpu_gpr[rt], uimm);
3975        }
3976        break;
3977    case OPC_LUI:
3978        if (rs != 0 && (ctx->insn_flags & ISA_MIPS32R6)) {
3979            /* OPC_AUI */
3980            tcg_gen_addi_tl(cpu_gpr[rt], cpu_gpr[rs], imm << 16);
3981            tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
3982        } else {
3983            tcg_gen_movi_tl(cpu_gpr[rt], imm << 16);
3984        }
3985        break;
3986
3987    default:
3988        break;
3989    }
3990}
3991
3992/* Set on less than with immediate operand */
3993static void gen_slt_imm(DisasContext *ctx, uint32_t opc,
3994                        int rt, int rs, int16_t imm)
3995{
3996    target_ulong uimm = (target_long)imm; /* Sign extend to 32/64 bits */
3997    TCGv t0;
3998
3999    if (rt == 0) {
4000        /* If no destination, treat it as a NOP. */
4001        return;
4002    }
4003    t0 = tcg_temp_new();
4004    gen_load_gpr(t0, rs);
4005    switch (opc) {
4006    case OPC_SLTI:
4007        tcg_gen_setcondi_tl(TCG_COND_LT, cpu_gpr[rt], t0, uimm);
4008        break;
4009    case OPC_SLTIU:
4010        tcg_gen_setcondi_tl(TCG_COND_LTU, cpu_gpr[rt], t0, uimm);
4011        break;
4012    }
4013    tcg_temp_free(t0);
4014}
4015
4016/* Shifts with immediate operand */
4017static void gen_shift_imm(DisasContext *ctx, uint32_t opc,
4018                          int rt, int rs, int16_t imm)
4019{
4020    target_ulong uimm = ((uint16_t)imm) & 0x1f;
4021    TCGv t0;
4022
4023    if (rt == 0) {
4024        /* If no destination, treat it as a NOP. */
4025        return;
4026    }
4027
4028    t0 = tcg_temp_new();
4029    gen_load_gpr(t0, rs);
4030    switch (opc) {
4031    case OPC_SLL:
4032        tcg_gen_shli_tl(t0, t0, uimm);
4033        tcg_gen_ext32s_tl(cpu_gpr[rt], t0);
4034        break;
4035    case OPC_SRA:
4036        tcg_gen_sari_tl(cpu_gpr[rt], t0, uimm);
4037        break;
4038    case OPC_SRL:
4039        if (uimm != 0) {
4040            tcg_gen_ext32u_tl(t0, t0);
4041            tcg_gen_shri_tl(cpu_gpr[rt], t0, uimm);
4042        } else {
4043            tcg_gen_ext32s_tl(cpu_gpr[rt], t0);
4044        }
4045        break;
4046    case OPC_ROTR:
4047        if (uimm != 0) {
4048            TCGv_i32 t1 = tcg_temp_new_i32();
4049
4050            tcg_gen_trunc_tl_i32(t1, t0);
4051            tcg_gen_rotri_i32(t1, t1, uimm);
4052            tcg_gen_ext_i32_tl(cpu_gpr[rt], t1);
4053            tcg_temp_free_i32(t1);
4054        } else {
4055            tcg_gen_ext32s_tl(cpu_gpr[rt], t0);
4056        }
4057        break;
4058#if defined(TARGET_MIPS64)
4059    case OPC_DSLL:
4060        tcg_gen_shli_tl(cpu_gpr[rt], t0, uimm);
4061        break;
4062    case OPC_DSRA:
4063        tcg_gen_sari_tl(cpu_gpr[rt], t0, uimm);
4064        break;
4065    case OPC_DSRL:
4066        tcg_gen_shri_tl(cpu_gpr[rt], t0, uimm);
4067        break;
4068    case OPC_DROTR:
4069        if (uimm != 0) {
4070            tcg_gen_rotri_tl(cpu_gpr[rt], t0, uimm);
4071        } else {
4072            tcg_gen_mov_tl(cpu_gpr[rt], t0);
4073        }
4074        break;
4075    case OPC_DSLL32:
4076        tcg_gen_shli_tl(cpu_gpr[rt], t0, uimm + 32);
4077        break;
4078    case OPC_DSRA32:
4079        tcg_gen_sari_tl(cpu_gpr[rt], t0, uimm + 32);
4080        break;
4081    case OPC_DSRL32:
4082        tcg_gen_shri_tl(cpu_gpr[rt], t0, uimm + 32);
4083        break;
4084    case OPC_DROTR32:
4085        tcg_gen_rotri_tl(cpu_gpr[rt], t0, uimm + 32);
4086        break;
4087#endif
4088    }
4089    tcg_temp_free(t0);
4090}
4091
4092/* Arithmetic */
4093static void gen_arith(DisasContext *ctx, uint32_t opc,
4094                      int rd, int rs, int rt)
4095{
4096    if (rd == 0 && opc != OPC_ADD && opc != OPC_SUB
4097       && opc != OPC_DADD && opc != OPC_DSUB) {
4098        /*
4099         * If no destination, treat it as a NOP.
4100         * For add & sub, we must generate the overflow exception when needed.
4101         */
4102        return;
4103    }
4104
4105    switch (opc) {
4106    case OPC_ADD:
4107        {
4108            TCGv t0 = tcg_temp_local_new();
4109            TCGv t1 = tcg_temp_new();
4110            TCGv t2 = tcg_temp_new();
4111            TCGLabel *l1 = gen_new_label();
4112
4113            gen_load_gpr(t1, rs);
4114            gen_load_gpr(t2, rt);
4115            tcg_gen_add_tl(t0, t1, t2);
4116            tcg_gen_ext32s_tl(t0, t0);
4117            tcg_gen_xor_tl(t1, t1, t2);
4118            tcg_gen_xor_tl(t2, t0, t2);
4119            tcg_gen_andc_tl(t1, t2, t1);
4120            tcg_temp_free(t2);
4121            tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
4122            tcg_temp_free(t1);
4123            /* operands of same sign, result different sign */
4124            generate_exception(ctx, EXCP_OVERFLOW);
4125            gen_set_label(l1);
4126            gen_store_gpr(t0, rd);
4127            tcg_temp_free(t0);
4128        }
4129        break;
4130    case OPC_ADDU:
4131        if (rs != 0 && rt != 0) {
4132            tcg_gen_add_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
4133            tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
4134        } else if (rs == 0 && rt != 0) {
4135            tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
4136        } else if (rs != 0 && rt == 0) {
4137            tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
4138        } else {
4139            tcg_gen_movi_tl(cpu_gpr[rd], 0);
4140        }
4141        break;
4142    case OPC_SUB:
4143        {
4144            TCGv t0 = tcg_temp_local_new();
4145            TCGv t1 = tcg_temp_new();
4146            TCGv t2 = tcg_temp_new();
4147            TCGLabel *l1 = gen_new_label();
4148
4149            gen_load_gpr(t1, rs);
4150            gen_load_gpr(t2, rt);
4151            tcg_gen_sub_tl(t0, t1, t2);
4152            tcg_gen_ext32s_tl(t0, t0);
4153            tcg_gen_xor_tl(t2, t1, t2);
4154            tcg_gen_xor_tl(t1, t0, t1);
4155            tcg_gen_and_tl(t1, t1, t2);
4156            tcg_temp_free(t2);
4157            tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
4158            tcg_temp_free(t1);
4159            /*
4160             * operands of different sign, first operand and the result
4161             * of different sign
4162             */
4163            generate_exception(ctx, EXCP_OVERFLOW);
4164            gen_set_label(l1);
4165            gen_store_gpr(t0, rd);
4166            tcg_temp_free(t0);
4167        }
4168        break;
4169    case OPC_SUBU:
4170        if (rs != 0 && rt != 0) {
4171            tcg_gen_sub_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
4172            tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
4173        } else if (rs == 0 && rt != 0) {
4174            tcg_gen_neg_tl(cpu_gpr[rd], cpu_gpr[rt]);
4175            tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
4176        } else if (rs != 0 && rt == 0) {
4177            tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
4178        } else {
4179            tcg_gen_movi_tl(cpu_gpr[rd], 0);
4180        }
4181        break;
4182#if defined(TARGET_MIPS64)
4183    case OPC_DADD:
4184        {
4185            TCGv t0 = tcg_temp_local_new();
4186            TCGv t1 = tcg_temp_new();
4187            TCGv t2 = tcg_temp_new();
4188            TCGLabel *l1 = gen_new_label();
4189
4190            gen_load_gpr(t1, rs);
4191            gen_load_gpr(t2, rt);
4192            tcg_gen_add_tl(t0, t1, t2);
4193            tcg_gen_xor_tl(t1, t1, t2);
4194            tcg_gen_xor_tl(t2, t0, t2);
4195            tcg_gen_andc_tl(t1, t2, t1);
4196            tcg_temp_free(t2);
4197            tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
4198            tcg_temp_free(t1);
4199            /* operands of same sign, result different sign */
4200            generate_exception(ctx, EXCP_OVERFLOW);
4201            gen_set_label(l1);
4202            gen_store_gpr(t0, rd);
4203            tcg_temp_free(t0);
4204        }
4205        break;
4206    case OPC_DADDU:
4207        if (rs != 0 && rt != 0) {
4208            tcg_gen_add_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
4209        } else if (rs == 0 && rt != 0) {
4210            tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
4211        } else if (rs != 0 && rt == 0) {
4212            tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
4213        } else {
4214            tcg_gen_movi_tl(cpu_gpr[rd], 0);
4215        }
4216        break;
4217    case OPC_DSUB:
4218        {
4219            TCGv t0 = tcg_temp_local_new();
4220            TCGv t1 = tcg_temp_new();
4221            TCGv t2 = tcg_temp_new();
4222            TCGLabel *l1 = gen_new_label();
4223
4224            gen_load_gpr(t1, rs);
4225            gen_load_gpr(t2, rt);
4226            tcg_gen_sub_tl(t0, t1, t2);
4227            tcg_gen_xor_tl(t2, t1, t2);
4228            tcg_gen_xor_tl(t1, t0, t1);
4229            tcg_gen_and_tl(t1, t1, t2);
4230            tcg_temp_free(t2);
4231            tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
4232            tcg_temp_free(t1);
4233            /*
4234             * Operands of different sign, first operand and result different
4235             * sign.
4236             */
4237            generate_exception(ctx, EXCP_OVERFLOW);
4238            gen_set_label(l1);
4239            gen_store_gpr(t0, rd);
4240            tcg_temp_free(t0);
4241        }
4242        break;
4243    case OPC_DSUBU:
4244        if (rs != 0 && rt != 0) {
4245            tcg_gen_sub_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
4246        } else if (rs == 0 && rt != 0) {
4247            tcg_gen_neg_tl(cpu_gpr[rd], cpu_gpr[rt]);
4248        } else if (rs != 0 && rt == 0) {
4249            tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
4250        } else {
4251            tcg_gen_movi_tl(cpu_gpr[rd], 0);
4252        }
4253        break;
4254#endif
4255    case OPC_MUL:
4256        if (likely(rs != 0 && rt != 0)) {
4257            tcg_gen_mul_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
4258            tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
4259        } else {
4260            tcg_gen_movi_tl(cpu_gpr[rd], 0);
4261        }
4262        break;
4263    }
4264}
4265
4266/* Conditional move */
4267static void gen_cond_move(DisasContext *ctx, uint32_t opc,
4268                          int rd, int rs, int rt)
4269{
4270    TCGv t0, t1, t2;
4271
4272    if (rd == 0) {
4273        /* If no destination, treat it as a NOP. */
4274        return;
4275    }
4276
4277    t0 = tcg_temp_new();
4278    gen_load_gpr(t0, rt);
4279    t1 = tcg_const_tl(0);
4280    t2 = tcg_temp_new();
4281    gen_load_gpr(t2, rs);
4282    switch (opc) {
4283    case OPC_MOVN:
4284        tcg_gen_movcond_tl(TCG_COND_NE, cpu_gpr[rd], t0, t1, t2, cpu_gpr[rd]);
4285        break;
4286    case OPC_MOVZ:
4287        tcg_gen_movcond_tl(TCG_COND_EQ, cpu_gpr[rd], t0, t1, t2, cpu_gpr[rd]);
4288        break;
4289    case OPC_SELNEZ:
4290        tcg_gen_movcond_tl(TCG_COND_NE, cpu_gpr[rd], t0, t1, t2, t1);
4291        break;
4292    case OPC_SELEQZ:
4293        tcg_gen_movcond_tl(TCG_COND_EQ, cpu_gpr[rd], t0, t1, t2, t1);
4294        break;
4295    }
4296    tcg_temp_free(t2);
4297    tcg_temp_free(t1);
4298    tcg_temp_free(t0);
4299}
4300
4301/* Logic */
4302static void gen_logic(DisasContext *ctx, uint32_t opc,
4303                      int rd, int rs, int rt)
4304{
4305    if (rd == 0) {
4306        /* If no destination, treat it as a NOP. */
4307        return;
4308    }
4309
4310    switch (opc) {
4311    case OPC_AND:
4312        if (likely(rs != 0 && rt != 0)) {
4313            tcg_gen_and_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
4314        } else {
4315            tcg_gen_movi_tl(cpu_gpr[rd], 0);
4316        }
4317        break;
4318    case OPC_NOR:
4319        if (rs != 0 && rt != 0) {
4320            tcg_gen_nor_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
4321        } else if (rs == 0 && rt != 0) {
4322            tcg_gen_not_tl(cpu_gpr[rd], cpu_gpr[rt]);
4323        } else if (rs != 0 && rt == 0) {
4324            tcg_gen_not_tl(cpu_gpr[rd], cpu_gpr[rs]);
4325        } else {
4326            tcg_gen_movi_tl(cpu_gpr[rd], ~((target_ulong)0));
4327        }
4328        break;
4329    case OPC_OR:
4330        if (likely(rs != 0 && rt != 0)) {
4331            tcg_gen_or_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
4332        } else if (rs == 0 && rt != 0) {
4333            tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
4334        } else if (rs != 0 && rt == 0) {
4335            tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
4336        } else {
4337            tcg_gen_movi_tl(cpu_gpr[rd], 0);
4338        }
4339        break;
4340    case OPC_XOR:
4341        if (likely(rs != 0 && rt != 0)) {
4342            tcg_gen_xor_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
4343        } else if (rs == 0 && rt != 0) {
4344            tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
4345        } else if (rs != 0 && rt == 0) {
4346            tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
4347        } else {
4348            tcg_gen_movi_tl(cpu_gpr[rd], 0);
4349        }
4350        break;
4351    }
4352}
4353
4354/* Set on lower than */
4355static void gen_slt(DisasContext *ctx, uint32_t opc,
4356                    int rd, int rs, int rt)
4357{
4358    TCGv t0, t1;
4359
4360    if (rd == 0) {
4361        /* If no destination, treat it as a NOP. */
4362        return;
4363    }
4364
4365    t0 = tcg_temp_new();
4366    t1 = tcg_temp_new();
4367    gen_load_gpr(t0, rs);
4368    gen_load_gpr(t1, rt);
4369    switch (opc) {
4370    case OPC_SLT:
4371        tcg_gen_setcond_tl(TCG_COND_LT, cpu_gpr[rd], t0, t1);
4372        break;
4373    case OPC_SLTU:
4374        tcg_gen_setcond_tl(TCG_COND_LTU, cpu_gpr[rd], t0, t1);
4375        break;
4376    }
4377    tcg_temp_free(t0);
4378    tcg_temp_free(t1);
4379}
4380
4381/* Shifts */
4382static void gen_shift(DisasContext *ctx, uint32_t opc,
4383                      int rd, int rs, int rt)
4384{
4385    TCGv t0, t1;
4386
4387    if (rd == 0) {
4388        /*
4389         * If no destination, treat it as a NOP.
4390         * For add & sub, we must generate the overflow exception when needed.
4391         */
4392        return;
4393    }
4394
4395    t0 = tcg_temp_new();
4396    t1 = tcg_temp_new();
4397    gen_load_gpr(t0, rs);
4398    gen_load_gpr(t1, rt);
4399    switch (opc) {
4400    case OPC_SLLV:
4401        tcg_gen_andi_tl(t0, t0, 0x1f);
4402        tcg_gen_shl_tl(t0, t1, t0);
4403        tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
4404        break;
4405    case OPC_SRAV:
4406        tcg_gen_andi_tl(t0, t0, 0x1f);
4407        tcg_gen_sar_tl(cpu_gpr[rd], t1, t0);
4408        break;
4409    case OPC_SRLV:
4410        tcg_gen_ext32u_tl(t1, t1);
4411        tcg_gen_andi_tl(t0, t0, 0x1f);
4412        tcg_gen_shr_tl(t0, t1, t0);
4413        tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
4414        break;
4415    case OPC_ROTRV:
4416        {
4417            TCGv_i32 t2 = tcg_temp_new_i32();
4418            TCGv_i32 t3 = tcg_temp_new_i32();
4419
4420            tcg_gen_trunc_tl_i32(t2, t0);
4421            tcg_gen_trunc_tl_i32(t3, t1);
4422            tcg_gen_andi_i32(t2, t2, 0x1f);
4423            tcg_gen_rotr_i32(t2, t3, t2);
4424            tcg_gen_ext_i32_tl(cpu_gpr[rd], t2);
4425            tcg_temp_free_i32(t2);
4426            tcg_temp_free_i32(t3);
4427        }
4428        break;
4429#if defined(TARGET_MIPS64)
4430    case OPC_DSLLV:
4431        tcg_gen_andi_tl(t0, t0, 0x3f);
4432        tcg_gen_shl_tl(cpu_gpr[rd], t1, t0);
4433        break;
4434    case OPC_DSRAV:
4435        tcg_gen_andi_tl(t0, t0, 0x3f);
4436        tcg_gen_sar_tl(cpu_gpr[rd], t1, t0);
4437        break;
4438    case OPC_DSRLV:
4439        tcg_gen_andi_tl(t0, t0, 0x3f);
4440        tcg_gen_shr_tl(cpu_gpr[rd], t1, t0);
4441        break;
4442    case OPC_DROTRV:
4443        tcg_gen_andi_tl(t0, t0, 0x3f);
4444        tcg_gen_rotr_tl(cpu_gpr[rd], t1, t0);
4445        break;
4446#endif
4447    }
4448    tcg_temp_free(t0);
4449    tcg_temp_free(t1);
4450}
4451
4452#if defined(TARGET_MIPS64)
4453/* Copy GPR to and from TX79 HI1/LO1 register. */
4454static void gen_HILO1_tx79(DisasContext *ctx, uint32_t opc, int reg)
4455{
4456    if (reg == 0 && (opc == MMI_OPC_MFHI1 || opc == MMI_OPC_MFLO1)) {
4457        /* Treat as NOP. */
4458        return;
4459    }
4460
4461    switch (opc) {
4462    case MMI_OPC_MFHI1:
4463        tcg_gen_mov_tl(cpu_gpr[reg], cpu_HI[1]);
4464        break;
4465    case MMI_OPC_MFLO1:
4466        tcg_gen_mov_tl(cpu_gpr[reg], cpu_LO[1]);
4467        break;
4468    case MMI_OPC_MTHI1:
4469        if (reg != 0) {
4470            tcg_gen_mov_tl(cpu_HI[1], cpu_gpr[reg]);
4471        } else {
4472            tcg_gen_movi_tl(cpu_HI[1], 0);
4473        }
4474        break;
4475    case MMI_OPC_MTLO1:
4476        if (reg != 0) {
4477            tcg_gen_mov_tl(cpu_LO[1], cpu_gpr[reg]);
4478        } else {
4479            tcg_gen_movi_tl(cpu_LO[1], 0);
4480        }
4481        break;
4482    default:
4483        MIPS_INVAL("mfthilo1 TX79");
4484        generate_exception_end(ctx, EXCP_RI);
4485        break;
4486    }
4487}
4488#endif
4489
4490/* Arithmetic on HI/LO registers */
4491static void gen_HILO(DisasContext *ctx, uint32_t opc, int acc, int reg)
4492{
4493    if (reg == 0 && (opc == OPC_MFHI || opc == OPC_MFLO)) {
4494        /* Treat as NOP. */
4495        return;
4496    }
4497
4498    if (acc != 0) {
4499        check_dsp(ctx);
4500    }
4501
4502    switch (opc) {
4503    case OPC_MFHI:
4504#if defined(TARGET_MIPS64)
4505        if (acc != 0) {
4506            tcg_gen_ext32s_tl(cpu_gpr[reg], cpu_HI[acc]);
4507        } else
4508#endif
4509        {
4510            tcg_gen_mov_tl(cpu_gpr[reg], cpu_HI[acc]);
4511        }
4512        break;
4513    case OPC_MFLO:
4514#if defined(TARGET_MIPS64)
4515        if (acc != 0) {
4516            tcg_gen_ext32s_tl(cpu_gpr[reg], cpu_LO[acc]);
4517        } else
4518#endif
4519        {
4520            tcg_gen_mov_tl(cpu_gpr[reg], cpu_LO[acc]);
4521        }
4522        break;
4523    case OPC_MTHI:
4524        if (reg != 0) {
4525#if defined(TARGET_MIPS64)
4526            if (acc != 0) {
4527                tcg_gen_ext32s_tl(cpu_HI[acc], cpu_gpr[reg]);
4528            } else
4529#endif
4530            {
4531                tcg_gen_mov_tl(cpu_HI[acc], cpu_gpr[reg]);
4532            }
4533        } else {
4534            tcg_gen_movi_tl(cpu_HI[acc], 0);
4535        }
4536        break;
4537    case OPC_MTLO:
4538        if (reg != 0) {
4539#if defined(TARGET_MIPS64)
4540            if (acc != 0) {
4541                tcg_gen_ext32s_tl(cpu_LO[acc], cpu_gpr[reg]);
4542            } else
4543#endif
4544            {
4545                tcg_gen_mov_tl(cpu_LO[acc], cpu_gpr[reg]);
4546            }
4547        } else {
4548            tcg_gen_movi_tl(cpu_LO[acc], 0);
4549        }
4550        break;
4551    }
4552}
4553
4554static inline void gen_r6_ld(target_long addr, int reg, int memidx,
4555                             MemOp memop)
4556{
4557    TCGv t0 = tcg_const_tl(addr);
4558    tcg_gen_qemu_ld_tl(t0, t0, memidx, memop);
4559    gen_store_gpr(t0, reg);
4560    tcg_temp_free(t0);
4561}
4562
4563static inline void gen_pcrel(DisasContext *ctx, int opc, target_ulong pc,
4564                             int rs)
4565{
4566    target_long offset;
4567    target_long addr;
4568
4569    switch (MASK_OPC_PCREL_TOP2BITS(opc)) {
4570    case OPC_ADDIUPC:
4571        if (rs != 0) {
4572            offset = sextract32(ctx->opcode << 2, 0, 21);
4573            addr = addr_add(ctx, pc, offset);
4574            tcg_gen_movi_tl(cpu_gpr[rs], addr);
4575        }
4576        break;
4577    case R6_OPC_LWPC:
4578        offset = sextract32(ctx->opcode << 2, 0, 21);
4579        addr = addr_add(ctx, pc, offset);
4580        gen_r6_ld(addr, rs, ctx->mem_idx, MO_TESL);
4581        break;
4582#if defined(TARGET_MIPS64)
4583    case OPC_LWUPC:
4584        check_mips_64(ctx);
4585        offset = sextract32(ctx->opcode << 2, 0, 21);
4586        addr = addr_add(ctx, pc, offset);
4587        gen_r6_ld(addr, rs, ctx->mem_idx, MO_TEUL);
4588        break;
4589#endif
4590    default:
4591        switch (MASK_OPC_PCREL_TOP5BITS(opc)) {
4592        case OPC_AUIPC:
4593            if (rs != 0) {
4594                offset = sextract32(ctx->opcode, 0, 16) << 16;
4595                addr = addr_add(ctx, pc, offset);
4596                tcg_gen_movi_tl(cpu_gpr[rs], addr);
4597            }
4598            break;
4599        case OPC_ALUIPC:
4600            if (rs != 0) {
4601                offset = sextract32(ctx->opcode, 0, 16) << 16;
4602                addr = ~0xFFFF & addr_add(ctx, pc, offset);
4603                tcg_gen_movi_tl(cpu_gpr[rs], addr);
4604            }
4605            break;
4606#if defined(TARGET_MIPS64)
4607        case R6_OPC_LDPC: /* bits 16 and 17 are part of immediate */
4608        case R6_OPC_LDPC + (1 << 16):
4609        case R6_OPC_LDPC + (2 << 16):
4610        case R6_OPC_LDPC + (3 << 16):
4611            check_mips_64(ctx);
4612            offset = sextract32(ctx->opcode << 3, 0, 21);
4613            addr = addr_add(ctx, (pc & ~0x7), offset);
4614            gen_r6_ld(addr, rs, ctx->mem_idx, MO_TEQ);
4615            break;
4616#endif
4617        default:
4618            MIPS_INVAL("OPC_PCREL");
4619            generate_exception_end(ctx, EXCP_RI);
4620            break;
4621        }
4622        break;
4623    }
4624}
4625
4626static void gen_r6_muldiv(DisasContext *ctx, int opc, int rd, int rs, int rt)
4627{
4628    TCGv t0, t1;
4629
4630    if (rd == 0) {
4631        /* Treat as NOP. */
4632        return;
4633    }
4634
4635    t0 = tcg_temp_new();
4636    t1 = tcg_temp_new();
4637
4638    gen_load_gpr(t0, rs);
4639    gen_load_gpr(t1, rt);
4640
4641    switch (opc) {
4642    case R6_OPC_DIV:
4643        {
4644            TCGv t2 = tcg_temp_new();
4645            TCGv t3 = tcg_temp_new();
4646            tcg_gen_ext32s_tl(t0, t0);
4647            tcg_gen_ext32s_tl(t1, t1);
4648            tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, INT_MIN);
4649            tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1);
4650            tcg_gen_and_tl(t2, t2, t3);
4651            tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
4652            tcg_gen_or_tl(t2, t2, t3);
4653            tcg_gen_movi_tl(t3, 0);
4654            tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
4655            tcg_gen_div_tl(cpu_gpr[rd], t0, t1);
4656            tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
4657            tcg_temp_free(t3);
4658            tcg_temp_free(t2);
4659        }
4660        break;
4661    case R6_OPC_MOD:
4662        {
4663            TCGv t2 = tcg_temp_new();
4664            TCGv t3 = tcg_temp_new();
4665            tcg_gen_ext32s_tl(t0, t0);
4666            tcg_gen_ext32s_tl(t1, t1);
4667            tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, INT_MIN);
4668            tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1);
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_rem_tl(cpu_gpr[rd], t0, t1);
4675            tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
4676            tcg_temp_free(t3);
4677            tcg_temp_free(t2);
4678        }
4679        break;
4680    case R6_OPC_DIVU:
4681        {
4682            TCGv t2 = tcg_const_tl(0);
4683            TCGv t3 = tcg_const_tl(1);
4684            tcg_gen_ext32u_tl(t0, t0);
4685            tcg_gen_ext32u_tl(t1, t1);
4686            tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
4687            tcg_gen_divu_tl(cpu_gpr[rd], t0, t1);
4688            tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
4689            tcg_temp_free(t3);
4690            tcg_temp_free(t2);
4691        }
4692        break;
4693    case R6_OPC_MODU:
4694        {
4695            TCGv t2 = tcg_const_tl(0);
4696            TCGv t3 = tcg_const_tl(1);
4697            tcg_gen_ext32u_tl(t0, t0);
4698            tcg_gen_ext32u_tl(t1, t1);
4699            tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
4700            tcg_gen_remu_tl(cpu_gpr[rd], t0, t1);
4701            tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
4702            tcg_temp_free(t3);
4703            tcg_temp_free(t2);
4704        }
4705        break;
4706    case R6_OPC_MUL:
4707        {
4708            TCGv_i32 t2 = tcg_temp_new_i32();
4709            TCGv_i32 t3 = tcg_temp_new_i32();
4710            tcg_gen_trunc_tl_i32(t2, t0);
4711            tcg_gen_trunc_tl_i32(t3, t1);
4712            tcg_gen_mul_i32(t2, t2, t3);
4713            tcg_gen_ext_i32_tl(cpu_gpr[rd], t2);
4714            tcg_temp_free_i32(t2);
4715            tcg_temp_free_i32(t3);
4716        }
4717        break;
4718    case R6_OPC_MUH:
4719        {
4720            TCGv_i32 t2 = tcg_temp_new_i32();
4721            TCGv_i32 t3 = tcg_temp_new_i32();
4722            tcg_gen_trunc_tl_i32(t2, t0);
4723            tcg_gen_trunc_tl_i32(t3, t1);
4724            tcg_gen_muls2_i32(t2, t3, t2, t3);
4725            tcg_gen_ext_i32_tl(cpu_gpr[rd], t3);
4726            tcg_temp_free_i32(t2);
4727            tcg_temp_free_i32(t3);
4728        }
4729        break;
4730    case R6_OPC_MULU:
4731        {
4732            TCGv_i32 t2 = tcg_temp_new_i32();
4733            TCGv_i32 t3 = tcg_temp_new_i32();
4734            tcg_gen_trunc_tl_i32(t2, t0);
4735            tcg_gen_trunc_tl_i32(t3, t1);
4736            tcg_gen_mul_i32(t2, t2, t3);
4737            tcg_gen_ext_i32_tl(cpu_gpr[rd], t2);
4738            tcg_temp_free_i32(t2);
4739            tcg_temp_free_i32(t3);
4740        }
4741        break;
4742    case R6_OPC_MUHU:
4743        {
4744            TCGv_i32 t2 = tcg_temp_new_i32();
4745            TCGv_i32 t3 = tcg_temp_new_i32();
4746            tcg_gen_trunc_tl_i32(t2, t0);
4747            tcg_gen_trunc_tl_i32(t3, t1);
4748            tcg_gen_mulu2_i32(t2, t3, t2, t3);
4749            tcg_gen_ext_i32_tl(cpu_gpr[rd], t3);
4750            tcg_temp_free_i32(t2);
4751            tcg_temp_free_i32(t3);
4752        }
4753        break;
4754#if defined(TARGET_MIPS64)
4755    case R6_OPC_DDIV:
4756        {
4757            TCGv t2 = tcg_temp_new();
4758            TCGv t3 = tcg_temp_new();
4759            tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, -1LL << 63);
4760            tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1LL);
4761            tcg_gen_and_tl(t2, t2, t3);
4762            tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
4763            tcg_gen_or_tl(t2, t2, t3);
4764            tcg_gen_movi_tl(t3, 0);
4765            tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
4766            tcg_gen_div_tl(cpu_gpr[rd], t0, t1);
4767            tcg_temp_free(t3);
4768            tcg_temp_free(t2);
4769        }
4770        break;
4771    case R6_OPC_DMOD:
4772        {
4773            TCGv t2 = tcg_temp_new();
4774            TCGv t3 = tcg_temp_new();
4775            tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, -1LL << 63);
4776            tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1LL);
4777            tcg_gen_and_tl(t2, t2, t3);
4778            tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
4779            tcg_gen_or_tl(t2, t2, t3);
4780            tcg_gen_movi_tl(t3, 0);
4781            tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
4782            tcg_gen_rem_tl(cpu_gpr[rd], t0, t1);
4783            tcg_temp_free(t3);
4784            tcg_temp_free(t2);
4785        }
4786        break;
4787    case R6_OPC_DDIVU:
4788        {
4789            TCGv t2 = tcg_const_tl(0);
4790            TCGv t3 = tcg_const_tl(1);
4791            tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
4792            tcg_gen_divu_i64(cpu_gpr[rd], t0, t1);
4793            tcg_temp_free(t3);
4794            tcg_temp_free(t2);
4795        }
4796        break;
4797    case R6_OPC_DMODU:
4798        {
4799            TCGv t2 = tcg_const_tl(0);
4800            TCGv t3 = tcg_const_tl(1);
4801            tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
4802            tcg_gen_remu_i64(cpu_gpr[rd], t0, t1);
4803            tcg_temp_free(t3);
4804            tcg_temp_free(t2);
4805        }
4806        break;
4807    case R6_OPC_DMUL:
4808        tcg_gen_mul_i64(cpu_gpr[rd], t0, t1);
4809        break;
4810    case R6_OPC_DMUH:
4811        {
4812            TCGv t2 = tcg_temp_new();
4813            tcg_gen_muls2_i64(t2, cpu_gpr[rd], t0, t1);
4814            tcg_temp_free(t2);
4815        }
4816        break;
4817    case R6_OPC_DMULU:
4818        tcg_gen_mul_i64(cpu_gpr[rd], t0, t1);
4819        break;
4820    case R6_OPC_DMUHU:
4821        {
4822            TCGv t2 = tcg_temp_new();
4823            tcg_gen_mulu2_i64(t2, cpu_gpr[rd], t0, t1);
4824            tcg_temp_free(t2);
4825        }
4826        break;
4827#endif
4828    default:
4829        MIPS_INVAL("r6 mul/div");
4830        generate_exception_end(ctx, EXCP_RI);
4831        goto out;
4832    }
4833 out:
4834    tcg_temp_free(t0);
4835    tcg_temp_free(t1);
4836}
4837
4838#if defined(TARGET_MIPS64)
4839static void gen_div1_tx79(DisasContext *ctx, uint32_t opc, int rs, int rt)
4840{
4841    TCGv t0, t1;
4842
4843    t0 = tcg_temp_new();
4844    t1 = tcg_temp_new();
4845
4846    gen_load_gpr(t0, rs);
4847    gen_load_gpr(t1, rt);
4848
4849    switch (opc) {
4850    case MMI_OPC_DIV1:
4851        {
4852            TCGv t2 = tcg_temp_new();
4853            TCGv t3 = tcg_temp_new();
4854            tcg_gen_ext32s_tl(t0, t0);
4855            tcg_gen_ext32s_tl(t1, t1);
4856            tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, INT_MIN);
4857            tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1);
4858            tcg_gen_and_tl(t2, t2, t3);
4859            tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
4860            tcg_gen_or_tl(t2, t2, t3);
4861            tcg_gen_movi_tl(t3, 0);
4862            tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
4863            tcg_gen_div_tl(cpu_LO[1], t0, t1);
4864            tcg_gen_rem_tl(cpu_HI[1], t0, t1);
4865            tcg_gen_ext32s_tl(cpu_LO[1], cpu_LO[1]);
4866            tcg_gen_ext32s_tl(cpu_HI[1], cpu_HI[1]);
4867            tcg_temp_free(t3);
4868            tcg_temp_free(t2);
4869        }
4870        break;
4871    case MMI_OPC_DIVU1:
4872        {
4873            TCGv t2 = tcg_const_tl(0);
4874            TCGv t3 = tcg_const_tl(1);
4875            tcg_gen_ext32u_tl(t0, t0);
4876            tcg_gen_ext32u_tl(t1, t1);
4877            tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
4878            tcg_gen_divu_tl(cpu_LO[1], t0, t1);
4879            tcg_gen_remu_tl(cpu_HI[1], t0, t1);
4880            tcg_gen_ext32s_tl(cpu_LO[1], cpu_LO[1]);
4881            tcg_gen_ext32s_tl(cpu_HI[1], cpu_HI[1]);
4882            tcg_temp_free(t3);
4883            tcg_temp_free(t2);
4884        }
4885        break;
4886    default:
4887        MIPS_INVAL("div1 TX79");
4888        generate_exception_end(ctx, EXCP_RI);
4889        goto out;
4890    }
4891 out:
4892    tcg_temp_free(t0);
4893    tcg_temp_free(t1);
4894}
4895#endif
4896
4897static void gen_muldiv(DisasContext *ctx, uint32_t opc,
4898                       int acc, int rs, int rt)
4899{
4900    TCGv t0, t1;
4901
4902    t0 = tcg_temp_new();
4903    t1 = tcg_temp_new();
4904
4905    gen_load_gpr(t0, rs);
4906    gen_load_gpr(t1, rt);
4907
4908    if (acc != 0) {
4909        check_dsp(ctx);
4910    }
4911
4912    switch (opc) {
4913    case OPC_DIV:
4914        {
4915            TCGv t2 = tcg_temp_new();
4916            TCGv t3 = tcg_temp_new();
4917            tcg_gen_ext32s_tl(t0, t0);
4918            tcg_gen_ext32s_tl(t1, t1);
4919            tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, INT_MIN);
4920            tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1);
4921            tcg_gen_and_tl(t2, t2, t3);
4922            tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
4923            tcg_gen_or_tl(t2, t2, t3);
4924            tcg_gen_movi_tl(t3, 0);
4925            tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
4926            tcg_gen_div_tl(cpu_LO[acc], t0, t1);
4927            tcg_gen_rem_tl(cpu_HI[acc], t0, t1);
4928            tcg_gen_ext32s_tl(cpu_LO[acc], cpu_LO[acc]);
4929            tcg_gen_ext32s_tl(cpu_HI[acc], cpu_HI[acc]);
4930            tcg_temp_free(t3);
4931            tcg_temp_free(t2);
4932        }
4933        break;
4934    case OPC_DIVU:
4935        {
4936            TCGv t2 = tcg_const_tl(0);
4937            TCGv t3 = tcg_const_tl(1);
4938            tcg_gen_ext32u_tl(t0, t0);
4939            tcg_gen_ext32u_tl(t1, t1);
4940            tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
4941            tcg_gen_divu_tl(cpu_LO[acc], t0, t1);
4942            tcg_gen_remu_tl(cpu_HI[acc], t0, t1);
4943            tcg_gen_ext32s_tl(cpu_LO[acc], cpu_LO[acc]);
4944            tcg_gen_ext32s_tl(cpu_HI[acc], cpu_HI[acc]);
4945            tcg_temp_free(t3);
4946            tcg_temp_free(t2);
4947        }
4948        break;
4949    case OPC_MULT:
4950        {
4951            TCGv_i32 t2 = tcg_temp_new_i32();
4952            TCGv_i32 t3 = tcg_temp_new_i32();
4953            tcg_gen_trunc_tl_i32(t2, t0);
4954            tcg_gen_trunc_tl_i32(t3, t1);
4955            tcg_gen_muls2_i32(t2, t3, t2, t3);
4956            tcg_gen_ext_i32_tl(cpu_LO[acc], t2);
4957            tcg_gen_ext_i32_tl(cpu_HI[acc], t3);
4958            tcg_temp_free_i32(t2);
4959            tcg_temp_free_i32(t3);
4960        }
4961        break;
4962    case OPC_MULTU:
4963        {
4964            TCGv_i32 t2 = tcg_temp_new_i32();
4965            TCGv_i32 t3 = tcg_temp_new_i32();
4966            tcg_gen_trunc_tl_i32(t2, t0);
4967            tcg_gen_trunc_tl_i32(t3, t1);
4968            tcg_gen_mulu2_i32(t2, t3, t2, t3);
4969            tcg_gen_ext_i32_tl(cpu_LO[acc], t2);
4970            tcg_gen_ext_i32_tl(cpu_HI[acc], t3);
4971            tcg_temp_free_i32(t2);
4972            tcg_temp_free_i32(t3);
4973        }
4974        break;
4975#if defined(TARGET_MIPS64)
4976    case OPC_DDIV:
4977        {
4978            TCGv t2 = tcg_temp_new();
4979            TCGv t3 = tcg_temp_new();
4980            tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, -1LL << 63);
4981            tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1LL);
4982            tcg_gen_and_tl(t2, t2, t3);
4983            tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
4984            tcg_gen_or_tl(t2, t2, t3);
4985            tcg_gen_movi_tl(t3, 0);
4986            tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
4987            tcg_gen_div_tl(cpu_LO[acc], t0, t1);
4988            tcg_gen_rem_tl(cpu_HI[acc], t0, t1);
4989            tcg_temp_free(t3);
4990            tcg_temp_free(t2);
4991        }
4992        break;
4993    case OPC_DDIVU:
4994        {
4995            TCGv t2 = tcg_const_tl(0);
4996            TCGv t3 = tcg_const_tl(1);
4997            tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
4998            tcg_gen_divu_i64(cpu_LO[acc], t0, t1);
4999            tcg_gen_remu_i64(cpu_HI[acc], t0, t1);
5000            tcg_temp_free(t3);
5001            tcg_temp_free(t2);
5002        }
5003        break;
5004    case OPC_DMULT:
5005        tcg_gen_muls2_i64(cpu_LO[acc], cpu_HI[acc], t0, t1);
5006        break;
5007    case OPC_DMULTU:
5008        tcg_gen_mulu2_i64(cpu_LO[acc], cpu_HI[acc], t0, t1);
5009        break;
5010#endif
5011    case OPC_MADD:
5012        {
5013            TCGv_i64 t2 = tcg_temp_new_i64();
5014            TCGv_i64 t3 = tcg_temp_new_i64();
5015
5016            tcg_gen_ext_tl_i64(t2, t0);
5017            tcg_gen_ext_tl_i64(t3, t1);
5018            tcg_gen_mul_i64(t2, t2, t3);
5019            tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
5020            tcg_gen_add_i64(t2, t2, t3);
5021            tcg_temp_free_i64(t3);
5022            gen_move_low32(cpu_LO[acc], t2);
5023            gen_move_high32(cpu_HI[acc], t2);
5024            tcg_temp_free_i64(t2);
5025        }
5026        break;
5027    case OPC_MADDU:
5028        {
5029            TCGv_i64 t2 = tcg_temp_new_i64();
5030            TCGv_i64 t3 = tcg_temp_new_i64();
5031
5032            tcg_gen_ext32u_tl(t0, t0);
5033            tcg_gen_ext32u_tl(t1, t1);
5034            tcg_gen_extu_tl_i64(t2, t0);
5035            tcg_gen_extu_tl_i64(t3, t1);
5036            tcg_gen_mul_i64(t2, t2, t3);
5037            tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
5038            tcg_gen_add_i64(t2, t2, t3);
5039            tcg_temp_free_i64(t3);
5040            gen_move_low32(cpu_LO[acc], t2);
5041            gen_move_high32(cpu_HI[acc], t2);
5042            tcg_temp_free_i64(t2);
5043        }
5044        break;
5045    case OPC_MSUB:
5046        {
5047            TCGv_i64 t2 = tcg_temp_new_i64();
5048            TCGv_i64 t3 = tcg_temp_new_i64();
5049
5050            tcg_gen_ext_tl_i64(t2, t0);
5051            tcg_gen_ext_tl_i64(t3, t1);
5052            tcg_gen_mul_i64(t2, t2, t3);
5053            tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
5054            tcg_gen_sub_i64(t2, t3, t2);
5055            tcg_temp_free_i64(t3);
5056            gen_move_low32(cpu_LO[acc], t2);
5057            gen_move_high32(cpu_HI[acc], t2);
5058            tcg_temp_free_i64(t2);
5059        }
5060        break;
5061    case OPC_MSUBU:
5062        {
5063            TCGv_i64 t2 = tcg_temp_new_i64();
5064            TCGv_i64 t3 = tcg_temp_new_i64();
5065
5066            tcg_gen_ext32u_tl(t0, t0);
5067            tcg_gen_ext32u_tl(t1, t1);
5068            tcg_gen_extu_tl_i64(t2, t0);
5069            tcg_gen_extu_tl_i64(t3, t1);
5070            tcg_gen_mul_i64(t2, t2, t3);
5071            tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
5072            tcg_gen_sub_i64(t2, t3, t2);
5073            tcg_temp_free_i64(t3);
5074            gen_move_low32(cpu_LO[acc], t2);
5075            gen_move_high32(cpu_HI[acc], t2);
5076            tcg_temp_free_i64(t2);
5077        }
5078        break;
5079    default:
5080        MIPS_INVAL("mul/div");
5081        generate_exception_end(ctx, EXCP_RI);
5082        goto out;
5083    }
5084 out:
5085    tcg_temp_free(t0);
5086    tcg_temp_free(t1);
5087}
5088
5089/*
5090 * These MULT[U] and MADD[U] instructions implemented in for example
5091 * the Toshiba/Sony R5900 and the Toshiba TX19, TX39 and TX79 core
5092 * architectures are special three-operand variants with the syntax
5093 *
5094 *     MULT[U][1] rd, rs, rt
5095 *
5096 * such that
5097 *
5098 *     (rd, LO, HI) <- rs * rt
5099 *
5100 * and
5101 *
5102 *     MADD[U][1] rd, rs, rt
5103 *
5104 * such that
5105 *
5106 *     (rd, LO, HI) <- (LO, HI) + rs * rt
5107 *
5108 * where the low-order 32-bits of the result is placed into both the
5109 * GPR rd and the special register LO. The high-order 32-bits of the
5110 * result is placed into the special register HI.
5111 *
5112 * If the GPR rd is omitted in assembly language, it is taken to be 0,
5113 * which is the zero register that always reads as 0.
5114 */
5115static void gen_mul_txx9(DisasContext *ctx, uint32_t opc,
5116                         int rd, int rs, int rt)
5117{
5118    TCGv t0 = tcg_temp_new();
5119    TCGv t1 = tcg_temp_new();
5120    int acc = 0;
5121
5122    gen_load_gpr(t0, rs);
5123    gen_load_gpr(t1, rt);
5124
5125    switch (opc) {
5126    case MMI_OPC_MULT1:
5127        acc = 1;
5128        /* Fall through */
5129    case OPC_MULT:
5130        {
5131            TCGv_i32 t2 = tcg_temp_new_i32();
5132            TCGv_i32 t3 = tcg_temp_new_i32();
5133            tcg_gen_trunc_tl_i32(t2, t0);
5134            tcg_gen_trunc_tl_i32(t3, t1);
5135            tcg_gen_muls2_i32(t2, t3, t2, t3);
5136            if (rd) {
5137                tcg_gen_ext_i32_tl(cpu_gpr[rd], t2);
5138            }
5139            tcg_gen_ext_i32_tl(cpu_LO[acc], t2);
5140            tcg_gen_ext_i32_tl(cpu_HI[acc], t3);
5141            tcg_temp_free_i32(t2);
5142            tcg_temp_free_i32(t3);
5143        }
5144        break;
5145    case MMI_OPC_MULTU1:
5146        acc = 1;
5147        /* Fall through */
5148    case OPC_MULTU:
5149        {
5150            TCGv_i32 t2 = tcg_temp_new_i32();
5151            TCGv_i32 t3 = tcg_temp_new_i32();
5152            tcg_gen_trunc_tl_i32(t2, t0);
5153            tcg_gen_trunc_tl_i32(t3, t1);
5154            tcg_gen_mulu2_i32(t2, t3, t2, t3);
5155            if (rd) {
5156                tcg_gen_ext_i32_tl(cpu_gpr[rd], t2);
5157            }
5158            tcg_gen_ext_i32_tl(cpu_LO[acc], t2);
5159            tcg_gen_ext_i32_tl(cpu_HI[acc], t3);
5160            tcg_temp_free_i32(t2);
5161            tcg_temp_free_i32(t3);
5162        }
5163        break;
5164    case MMI_OPC_MADD1:
5165        acc = 1;
5166        /* Fall through */
5167    case MMI_OPC_MADD:
5168        {
5169            TCGv_i64 t2 = tcg_temp_new_i64();
5170            TCGv_i64 t3 = tcg_temp_new_i64();
5171
5172            tcg_gen_ext_tl_i64(t2, t0);
5173            tcg_gen_ext_tl_i64(t3, t1);
5174            tcg_gen_mul_i64(t2, t2, t3);
5175            tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
5176            tcg_gen_add_i64(t2, t2, t3);
5177            tcg_temp_free_i64(t3);
5178            gen_move_low32(cpu_LO[acc], t2);
5179            gen_move_high32(cpu_HI[acc], t2);
5180            if (rd) {
5181                gen_move_low32(cpu_gpr[rd], t2);
5182            }
5183            tcg_temp_free_i64(t2);
5184        }
5185        break;
5186    case MMI_OPC_MADDU1:
5187        acc = 1;
5188        /* Fall through */
5189    case MMI_OPC_MADDU:
5190        {
5191            TCGv_i64 t2 = tcg_temp_new_i64();
5192            TCGv_i64 t3 = tcg_temp_new_i64();
5193
5194            tcg_gen_ext32u_tl(t0, t0);
5195            tcg_gen_ext32u_tl(t1, t1);
5196            tcg_gen_extu_tl_i64(t2, t0);
5197            tcg_gen_extu_tl_i64(t3, t1);
5198            tcg_gen_mul_i64(t2, t2, t3);
5199            tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
5200            tcg_gen_add_i64(t2, t2, t3);
5201            tcg_temp_free_i64(t3);
5202            gen_move_low32(cpu_LO[acc], t2);
5203            gen_move_high32(cpu_HI[acc], t2);
5204            if (rd) {
5205                gen_move_low32(cpu_gpr[rd], t2);
5206            }
5207            tcg_temp_free_i64(t2);
5208        }
5209        break;
5210    default:
5211        MIPS_INVAL("mul/madd TXx9");
5212        generate_exception_end(ctx, EXCP_RI);
5213        goto out;
5214    }
5215
5216 out:
5217    tcg_temp_free(t0);
5218    tcg_temp_free(t1);
5219}
5220
5221static void gen_mul_vr54xx(DisasContext *ctx, uint32_t opc,
5222                           int rd, int rs, int rt)
5223{
5224    TCGv t0 = tcg_temp_new();
5225    TCGv t1 = tcg_temp_new();
5226
5227    gen_load_gpr(t0, rs);
5228    gen_load_gpr(t1, rt);
5229
5230    switch (opc) {
5231    case OPC_VR54XX_MULS:
5232        gen_helper_muls(t0, cpu_env, t0, t1);
5233        break;
5234    case OPC_VR54XX_MULSU:
5235        gen_helper_mulsu(t0, cpu_env, t0, t1);
5236        break;
5237    case OPC_VR54XX_MACC:
5238        gen_helper_macc(t0, cpu_env, t0, t1);
5239        break;
5240    case OPC_VR54XX_MACCU:
5241        gen_helper_maccu(t0, cpu_env, t0, t1);
5242        break;
5243    case OPC_VR54XX_MSAC:
5244        gen_helper_msac(t0, cpu_env, t0, t1);
5245        break;
5246    case OPC_VR54XX_MSACU:
5247        gen_helper_msacu(t0, cpu_env, t0, t1);
5248        break;
5249    case OPC_VR54XX_MULHI:
5250        gen_helper_mulhi(t0, cpu_env, t0, t1);
5251        break;
5252    case OPC_VR54XX_MULHIU:
5253        gen_helper_mulhiu(t0, cpu_env, t0, t1);
5254        break;
5255    case OPC_VR54XX_MULSHI:
5256        gen_helper_mulshi(t0, cpu_env, t0, t1);
5257        break;
5258    case OPC_VR54XX_MULSHIU:
5259        gen_helper_mulshiu(t0, cpu_env, t0, t1);
5260        break;
5261    case OPC_VR54XX_MACCHI:
5262        gen_helper_macchi(t0, cpu_env, t0, t1);
5263        break;
5264    case OPC_VR54XX_MACCHIU:
5265        gen_helper_macchiu(t0, cpu_env, t0, t1);
5266        break;
5267    case OPC_VR54XX_MSACHI:
5268        gen_helper_msachi(t0, cpu_env, t0, t1);
5269        break;
5270    case OPC_VR54XX_MSACHIU:
5271        gen_helper_msachiu(t0, cpu_env, t0, t1);
5272        break;
5273    default:
5274        MIPS_INVAL("mul vr54xx");
5275        generate_exception_end(ctx, EXCP_RI);
5276        goto out;
5277    }
5278    gen_store_gpr(t0, rd);
5279
5280 out:
5281    tcg_temp_free(t0);
5282    tcg_temp_free(t1);
5283}
5284
5285static void gen_cl(DisasContext *ctx, uint32_t opc,
5286                   int rd, int rs)
5287{
5288    TCGv t0;
5289
5290    if (rd == 0) {
5291        /* Treat as NOP. */
5292        return;
5293    }
5294    t0 = cpu_gpr[rd];
5295    gen_load_gpr(t0, rs);
5296
5297    switch (opc) {
5298    case OPC_CLO:
5299    case R6_OPC_CLO:
5300#if defined(TARGET_MIPS64)
5301    case OPC_DCLO:
5302    case R6_OPC_DCLO:
5303#endif
5304        tcg_gen_not_tl(t0, t0);
5305        break;
5306    }
5307
5308    switch (opc) {
5309    case OPC_CLO:
5310    case R6_OPC_CLO:
5311    case OPC_CLZ:
5312    case R6_OPC_CLZ:
5313        tcg_gen_ext32u_tl(t0, t0);
5314        tcg_gen_clzi_tl(t0, t0, TARGET_LONG_BITS);
5315        tcg_gen_subi_tl(t0, t0, TARGET_LONG_BITS - 32);
5316        break;
5317#if defined(TARGET_MIPS64)
5318    case OPC_DCLO:
5319    case R6_OPC_DCLO:
5320    case OPC_DCLZ:
5321    case R6_OPC_DCLZ:
5322        tcg_gen_clzi_i64(t0, t0, 64);
5323        break;
5324#endif
5325    }
5326}
5327
5328/* Godson integer instructions */
5329static void gen_loongson_integer(DisasContext *ctx, uint32_t opc,
5330                                 int rd, int rs, int rt)
5331{
5332    TCGv t0, t1;
5333
5334    if (rd == 0) {
5335        /* Treat as NOP. */
5336        return;
5337    }
5338
5339    switch (opc) {
5340    case OPC_MULT_G_2E:
5341    case OPC_MULT_G_2F:
5342    case OPC_MULTU_G_2E:
5343    case OPC_MULTU_G_2F:
5344#if defined(TARGET_MIPS64)
5345    case OPC_DMULT_G_2E:
5346    case OPC_DMULT_G_2F:
5347    case OPC_DMULTU_G_2E:
5348    case OPC_DMULTU_G_2F:
5349#endif
5350        t0 = tcg_temp_new();
5351        t1 = tcg_temp_new();
5352        break;
5353    default:
5354        t0 = tcg_temp_local_new();
5355        t1 = tcg_temp_local_new();
5356        break;
5357    }
5358
5359    gen_load_gpr(t0, rs);
5360    gen_load_gpr(t1, rt);
5361
5362    switch (opc) {
5363    case OPC_MULT_G_2E:
5364    case OPC_MULT_G_2F:
5365        tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
5366        tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
5367        break;
5368    case OPC_MULTU_G_2E:
5369    case OPC_MULTU_G_2F:
5370        tcg_gen_ext32u_tl(t0, t0);
5371        tcg_gen_ext32u_tl(t1, t1);
5372        tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
5373        tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
5374        break;
5375    case OPC_DIV_G_2E:
5376    case OPC_DIV_G_2F:
5377        {
5378            TCGLabel *l1 = gen_new_label();
5379            TCGLabel *l2 = gen_new_label();
5380            TCGLabel *l3 = gen_new_label();
5381            tcg_gen_ext32s_tl(t0, t0);
5382            tcg_gen_ext32s_tl(t1, t1);
5383            tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
5384            tcg_gen_movi_tl(cpu_gpr[rd], 0);
5385            tcg_gen_br(l3);
5386            gen_set_label(l1);
5387            tcg_gen_brcondi_tl(TCG_COND_NE, t0, INT_MIN, l2);
5388            tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1, l2);
5389            tcg_gen_mov_tl(cpu_gpr[rd], t0);
5390            tcg_gen_br(l3);
5391            gen_set_label(l2);
5392            tcg_gen_div_tl(cpu_gpr[rd], t0, t1);
5393            tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
5394            gen_set_label(l3);
5395        }
5396        break;
5397    case OPC_DIVU_G_2E:
5398    case OPC_DIVU_G_2F:
5399        {
5400            TCGLabel *l1 = gen_new_label();
5401            TCGLabel *l2 = gen_new_label();
5402            tcg_gen_ext32u_tl(t0, t0);
5403            tcg_gen_ext32u_tl(t1, t1);
5404            tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
5405            tcg_gen_movi_tl(cpu_gpr[rd], 0);
5406            tcg_gen_br(l2);
5407            gen_set_label(l1);
5408            tcg_gen_divu_tl(cpu_gpr[rd], t0, t1);
5409            tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
5410            gen_set_label(l2);
5411        }
5412        break;
5413    case OPC_MOD_G_2E:
5414    case OPC_MOD_G_2F:
5415        {
5416            TCGLabel *l1 = gen_new_label();
5417            TCGLabel *l2 = gen_new_label();
5418            TCGLabel *l3 = gen_new_label();
5419            tcg_gen_ext32u_tl(t0, t0);
5420            tcg_gen_ext32u_tl(t1, t1);
5421            tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
5422            tcg_gen_brcondi_tl(TCG_COND_NE, t0, INT_MIN, l2);
5423            tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1, l2);
5424            gen_set_label(l1);
5425            tcg_gen_movi_tl(cpu_gpr[rd], 0);
5426            tcg_gen_br(l3);
5427            gen_set_label(l2);
5428            tcg_gen_rem_tl(cpu_gpr[rd], t0, t1);
5429            tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
5430            gen_set_label(l3);
5431        }
5432        break;
5433    case OPC_MODU_G_2E:
5434    case OPC_MODU_G_2F:
5435        {
5436            TCGLabel *l1 = gen_new_label();
5437            TCGLabel *l2 = gen_new_label();
5438            tcg_gen_ext32u_tl(t0, t0);
5439            tcg_gen_ext32u_tl(t1, t1);
5440            tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
5441            tcg_gen_movi_tl(cpu_gpr[rd], 0);
5442            tcg_gen_br(l2);
5443            gen_set_label(l1);
5444            tcg_gen_remu_tl(cpu_gpr[rd], t0, t1);
5445            tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
5446            gen_set_label(l2);
5447        }
5448        break;
5449#if defined(TARGET_MIPS64)
5450    case OPC_DMULT_G_2E:
5451    case OPC_DMULT_G_2F:
5452        tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
5453        break;
5454    case OPC_DMULTU_G_2E:
5455    case OPC_DMULTU_G_2F:
5456        tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
5457        break;
5458    case OPC_DDIV_G_2E:
5459    case OPC_DDIV_G_2F:
5460        {
5461            TCGLabel *l1 = gen_new_label();
5462            TCGLabel *l2 = gen_new_label();
5463            TCGLabel *l3 = gen_new_label();
5464            tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
5465            tcg_gen_movi_tl(cpu_gpr[rd], 0);
5466            tcg_gen_br(l3);
5467            gen_set_label(l1);
5468            tcg_gen_brcondi_tl(TCG_COND_NE, t0, -1LL << 63, l2);
5469            tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1LL, l2);
5470            tcg_gen_mov_tl(cpu_gpr[rd], t0);
5471            tcg_gen_br(l3);
5472            gen_set_label(l2);
5473            tcg_gen_div_tl(cpu_gpr[rd], t0, t1);
5474            gen_set_label(l3);
5475        }
5476        break;
5477    case OPC_DDIVU_G_2E:
5478    case OPC_DDIVU_G_2F:
5479        {
5480            TCGLabel *l1 = gen_new_label();
5481            TCGLabel *l2 = gen_new_label();
5482            tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
5483            tcg_gen_movi_tl(cpu_gpr[rd], 0);
5484            tcg_gen_br(l2);
5485            gen_set_label(l1);
5486            tcg_gen_divu_tl(cpu_gpr[rd], t0, t1);
5487            gen_set_label(l2);
5488        }
5489        break;
5490    case OPC_DMOD_G_2E:
5491    case OPC_DMOD_G_2F:
5492        {
5493            TCGLabel *l1 = gen_new_label();
5494            TCGLabel *l2 = gen_new_label();
5495            TCGLabel *l3 = gen_new_label();
5496            tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
5497            tcg_gen_brcondi_tl(TCG_COND_NE, t0, -1LL << 63, l2);
5498            tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1LL, l2);
5499            gen_set_label(l1);
5500            tcg_gen_movi_tl(cpu_gpr[rd], 0);
5501            tcg_gen_br(l3);
5502            gen_set_label(l2);
5503            tcg_gen_rem_tl(cpu_gpr[rd], t0, t1);
5504            gen_set_label(l3);
5505        }
5506        break;
5507    case OPC_DMODU_G_2E:
5508    case OPC_DMODU_G_2F:
5509        {
5510            TCGLabel *l1 = gen_new_label();
5511            TCGLabel *l2 = gen_new_label();
5512            tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
5513            tcg_gen_movi_tl(cpu_gpr[rd], 0);
5514            tcg_gen_br(l2);
5515            gen_set_label(l1);
5516            tcg_gen_remu_tl(cpu_gpr[rd], t0, t1);
5517            gen_set_label(l2);
5518        }
5519        break;
5520#endif
5521    }
5522
5523    tcg_temp_free(t0);
5524    tcg_temp_free(t1);
5525}
5526
5527/* Loongson multimedia instructions */
5528static void gen_loongson_multimedia(DisasContext *ctx, int rd, int rs, int rt)
5529{
5530    uint32_t opc, shift_max;
5531    TCGv_i64 t0, t1;
5532    TCGCond cond;
5533
5534    opc = MASK_LMI(ctx->opcode);
5535    switch (opc) {
5536    case OPC_ADD_CP2:
5537    case OPC_SUB_CP2:
5538    case OPC_DADD_CP2:
5539    case OPC_DSUB_CP2:
5540        t0 = tcg_temp_local_new_i64();
5541        t1 = tcg_temp_local_new_i64();
5542        break;
5543    default:
5544        t0 = tcg_temp_new_i64();
5545        t1 = tcg_temp_new_i64();
5546        break;
5547    }
5548
5549    check_cp1_enabled(ctx);
5550    gen_load_fpr64(ctx, t0, rs);
5551    gen_load_fpr64(ctx, t1, rt);
5552
5553    switch (opc) {
5554    case OPC_PADDSH:
5555        gen_helper_paddsh(t0, t0, t1);
5556        break;
5557    case OPC_PADDUSH:
5558        gen_helper_paddush(t0, t0, t1);
5559        break;
5560    case OPC_PADDH:
5561        gen_helper_paddh(t0, t0, t1);
5562        break;
5563    case OPC_PADDW:
5564        gen_helper_paddw(t0, t0, t1);
5565        break;
5566    case OPC_PADDSB:
5567        gen_helper_paddsb(t0, t0, t1);
5568        break;
5569    case OPC_PADDUSB:
5570        gen_helper_paddusb(t0, t0, t1);
5571        break;
5572    case OPC_PADDB:
5573        gen_helper_paddb(t0, t0, t1);
5574        break;
5575
5576    case OPC_PSUBSH:
5577        gen_helper_psubsh(t0, t0, t1);
5578        break;
5579    case OPC_PSUBUSH:
5580        gen_helper_psubush(t0, t0, t1);
5581        break;
5582    case OPC_PSUBH:
5583        gen_helper_psubh(t0, t0, t1);
5584        break;
5585    case OPC_PSUBW:
5586        gen_helper_psubw(t0, t0, t1);
5587        break;
5588    case OPC_PSUBSB:
5589        gen_helper_psubsb(t0, t0, t1);
5590        break;
5591    case OPC_PSUBUSB:
5592        gen_helper_psubusb(t0, t0, t1);
5593        break;
5594    case OPC_PSUBB:
5595        gen_helper_psubb(t0, t0, t1);
5596        break;
5597
5598    case OPC_PSHUFH:
5599        gen_helper_pshufh(t0, t0, t1);
5600        break;
5601    case OPC_PACKSSWH:
5602        gen_helper_packsswh(t0, t0, t1);
5603        break;
5604    case OPC_PACKSSHB:
5605        gen_helper_packsshb(t0, t0, t1);
5606        break;
5607    case OPC_PACKUSHB:
5608        gen_helper_packushb(t0, t0, t1);
5609        break;
5610
5611    case OPC_PUNPCKLHW:
5612        gen_helper_punpcklhw(t0, t0, t1);
5613        break;
5614    case OPC_PUNPCKHHW:
5615        gen_helper_punpckhhw(t0, t0, t1);
5616        break;
5617    case OPC_PUNPCKLBH:
5618        gen_helper_punpcklbh(t0, t0, t1);
5619        break;
5620    case OPC_PUNPCKHBH:
5621        gen_helper_punpckhbh(t0, t0, t1);
5622        break;
5623    case OPC_PUNPCKLWD:
5624        gen_helper_punpcklwd(t0, t0, t1);
5625        break;
5626    case OPC_PUNPCKHWD:
5627        gen_helper_punpckhwd(t0, t0, t1);
5628        break;
5629
5630    case OPC_PAVGH:
5631        gen_helper_pavgh(t0, t0, t1);
5632        break;
5633    case OPC_PAVGB:
5634        gen_helper_pavgb(t0, t0, t1);
5635        break;
5636    case OPC_PMAXSH:
5637        gen_helper_pmaxsh(t0, t0, t1);
5638        break;
5639    case OPC_PMINSH:
5640        gen_helper_pminsh(t0, t0, t1);
5641        break;
5642    case OPC_PMAXUB:
5643        gen_helper_pmaxub(t0, t0, t1);
5644        break;
5645    case OPC_PMINUB:
5646        gen_helper_pminub(t0, t0, t1);
5647        break;
5648
5649    case OPC_PCMPEQW:
5650        gen_helper_pcmpeqw(t0, t0, t1);
5651        break;
5652    case OPC_PCMPGTW:
5653        gen_helper_pcmpgtw(t0, t0, t1);
5654        break;
5655    case OPC_PCMPEQH:
5656        gen_helper_pcmpeqh(t0, t0, t1);
5657        break;
5658    case OPC_PCMPGTH:
5659        gen_helper_pcmpgth(t0, t0, t1);
5660        break;
5661    case OPC_PCMPEQB:
5662        gen_helper_pcmpeqb(t0, t0, t1);
5663        break;
5664    case OPC_PCMPGTB:
5665        gen_helper_pcmpgtb(t0, t0, t1);
5666        break;
5667
5668    case OPC_PSLLW:
5669        gen_helper_psllw(t0, t0, t1);
5670        break;
5671    case OPC_PSLLH:
5672        gen_helper_psllh(t0, t0, t1);
5673        break;
5674    case OPC_PSRLW:
5675        gen_helper_psrlw(t0, t0, t1);
5676        break;
5677    case OPC_PSRLH:
5678        gen_helper_psrlh(t0, t0, t1);
5679        break;
5680    case OPC_PSRAW:
5681        gen_helper_psraw(t0, t0, t1);
5682        break;
5683    case OPC_PSRAH:
5684        gen_helper_psrah(t0, t0, t1);
5685        break;
5686
5687    case OPC_PMULLH:
5688        gen_helper_pmullh(t0, t0, t1);
5689        break;
5690    case OPC_PMULHH:
5691        gen_helper_pmulhh(t0, t0, t1);
5692        break;
5693    case OPC_PMULHUH:
5694        gen_helper_pmulhuh(t0, t0, t1);
5695        break;
5696    case OPC_PMADDHW:
5697        gen_helper_pmaddhw(t0, t0, t1);
5698        break;
5699
5700    case OPC_PASUBUB:
5701        gen_helper_pasubub(t0, t0, t1);
5702        break;
5703    case OPC_BIADD:
5704        gen_helper_biadd(t0, t0);
5705        break;
5706    case OPC_PMOVMSKB:
5707        gen_helper_pmovmskb(t0, t0);
5708        break;
5709
5710    case OPC_PADDD:
5711        tcg_gen_add_i64(t0, t0, t1);
5712        break;
5713    case OPC_PSUBD:
5714        tcg_gen_sub_i64(t0, t0, t1);
5715        break;
5716    case OPC_XOR_CP2:
5717        tcg_gen_xor_i64(t0, t0, t1);
5718        break;
5719    case OPC_NOR_CP2:
5720        tcg_gen_nor_i64(t0, t0, t1);
5721        break;
5722    case OPC_AND_CP2:
5723        tcg_gen_and_i64(t0, t0, t1);
5724        break;
5725    case OPC_OR_CP2:
5726        tcg_gen_or_i64(t0, t0, t1);
5727        break;
5728
5729    case OPC_PANDN:
5730        tcg_gen_andc_i64(t0, t1, t0);
5731        break;
5732
5733    case OPC_PINSRH_0:
5734        tcg_gen_deposit_i64(t0, t0, t1, 0, 16);
5735        break;
5736    case OPC_PINSRH_1:
5737        tcg_gen_deposit_i64(t0, t0, t1, 16, 16);
5738        break;
5739    case OPC_PINSRH_2:
5740        tcg_gen_deposit_i64(t0, t0, t1, 32, 16);
5741        break;
5742    case OPC_PINSRH_3:
5743        tcg_gen_deposit_i64(t0, t0, t1, 48, 16);
5744        break;
5745
5746    case OPC_PEXTRH:
5747        tcg_gen_andi_i64(t1, t1, 3);
5748        tcg_gen_shli_i64(t1, t1, 4);
5749        tcg_gen_shr_i64(t0, t0, t1);
5750        tcg_gen_ext16u_i64(t0, t0);
5751        break;
5752
5753    case OPC_ADDU_CP2:
5754        tcg_gen_add_i64(t0, t0, t1);
5755        tcg_gen_ext32s_i64(t0, t0);
5756        break;
5757    case OPC_SUBU_CP2:
5758        tcg_gen_sub_i64(t0, t0, t1);
5759        tcg_gen_ext32s_i64(t0, t0);
5760        break;
5761
5762    case OPC_SLL_CP2:
5763        shift_max = 32;
5764        goto do_shift;
5765    case OPC_SRL_CP2:
5766        shift_max = 32;
5767        goto do_shift;
5768    case OPC_SRA_CP2:
5769        shift_max = 32;
5770        goto do_shift;
5771    case OPC_DSLL_CP2:
5772        shift_max = 64;
5773        goto do_shift;
5774    case OPC_DSRL_CP2:
5775        shift_max = 64;
5776        goto do_shift;
5777    case OPC_DSRA_CP2:
5778        shift_max = 64;
5779        goto do_shift;
5780    do_shift:
5781        /* Make sure shift count isn't TCG undefined behaviour.  */
5782        tcg_gen_andi_i64(t1, t1, shift_max - 1);
5783
5784        switch (opc) {
5785        case OPC_SLL_CP2:
5786        case OPC_DSLL_CP2:
5787            tcg_gen_shl_i64(t0, t0, t1);
5788            break;
5789        case OPC_SRA_CP2:
5790        case OPC_DSRA_CP2:
5791            /*
5792             * Since SRA is UndefinedResult without sign-extended inputs,
5793             * we can treat SRA and DSRA the same.
5794             */
5795            tcg_gen_sar_i64(t0, t0, t1);
5796            break;
5797        case OPC_SRL_CP2:
5798            /* We want to shift in zeros for SRL; zero-extend first.  */
5799            tcg_gen_ext32u_i64(t0, t0);
5800            /* FALLTHRU */
5801        case OPC_DSRL_CP2:
5802            tcg_gen_shr_i64(t0, t0, t1);
5803            break;
5804        }
5805
5806        if (shift_max == 32) {
5807            tcg_gen_ext32s_i64(t0, t0);
5808        }
5809
5810        /* Shifts larger than MAX produce zero.  */
5811        tcg_gen_setcondi_i64(TCG_COND_LTU, t1, t1, shift_max);
5812        tcg_gen_neg_i64(t1, t1);
5813        tcg_gen_and_i64(t0, t0, t1);
5814        break;
5815
5816    case OPC_ADD_CP2:
5817    case OPC_DADD_CP2:
5818        {
5819            TCGv_i64 t2 = tcg_temp_new_i64();
5820            TCGLabel *lab = gen_new_label();
5821
5822            tcg_gen_mov_i64(t2, t0);
5823            tcg_gen_add_i64(t0, t1, t2);
5824            if (opc == OPC_ADD_CP2) {
5825                tcg_gen_ext32s_i64(t0, t0);
5826            }
5827            tcg_gen_xor_i64(t1, t1, t2);
5828            tcg_gen_xor_i64(t2, t2, t0);
5829            tcg_gen_andc_i64(t1, t2, t1);
5830            tcg_temp_free_i64(t2);
5831            tcg_gen_brcondi_i64(TCG_COND_GE, t1, 0, lab);
5832            generate_exception(ctx, EXCP_OVERFLOW);
5833            gen_set_label(lab);
5834            break;
5835        }
5836
5837    case OPC_SUB_CP2:
5838    case OPC_DSUB_CP2:
5839        {
5840            TCGv_i64 t2 = tcg_temp_new_i64();
5841            TCGLabel *lab = gen_new_label();
5842
5843            tcg_gen_mov_i64(t2, t0);
5844            tcg_gen_sub_i64(t0, t1, t2);
5845            if (opc == OPC_SUB_CP2) {
5846                tcg_gen_ext32s_i64(t0, t0);
5847            }
5848            tcg_gen_xor_i64(t1, t1, t2);
5849            tcg_gen_xor_i64(t2, t2, t0);
5850            tcg_gen_and_i64(t1, t1, t2);
5851            tcg_temp_free_i64(t2);
5852            tcg_gen_brcondi_i64(TCG_COND_GE, t1, 0, lab);
5853            generate_exception(ctx, EXCP_OVERFLOW);
5854            gen_set_label(lab);
5855            break;
5856        }
5857
5858    case OPC_PMULUW:
5859        tcg_gen_ext32u_i64(t0, t0);
5860        tcg_gen_ext32u_i64(t1, t1);
5861        tcg_gen_mul_i64(t0, t0, t1);
5862        break;
5863
5864    case OPC_SEQU_CP2:
5865    case OPC_SEQ_CP2:
5866        cond = TCG_COND_EQ;
5867        goto do_cc_cond;
5868        break;
5869    case OPC_SLTU_CP2:
5870        cond = TCG_COND_LTU;
5871        goto do_cc_cond;
5872        break;
5873    case OPC_SLT_CP2:
5874        cond = TCG_COND_LT;
5875        goto do_cc_cond;
5876        break;
5877    case OPC_SLEU_CP2:
5878        cond = TCG_COND_LEU;
5879        goto do_cc_cond;
5880        break;
5881    case OPC_SLE_CP2:
5882        cond = TCG_COND_LE;
5883    do_cc_cond:
5884        {
5885            int cc = (ctx->opcode >> 8) & 0x7;
5886            TCGv_i64 t64 = tcg_temp_new_i64();
5887            TCGv_i32 t32 = tcg_temp_new_i32();
5888
5889            tcg_gen_setcond_i64(cond, t64, t0, t1);
5890            tcg_gen_extrl_i64_i32(t32, t64);
5891            tcg_gen_deposit_i32(fpu_fcr31, fpu_fcr31, t32,
5892                                get_fp_bit(cc), 1);
5893
5894            tcg_temp_free_i32(t32);
5895            tcg_temp_free_i64(t64);
5896        }
5897        goto no_rd;
5898        break;
5899    default:
5900        MIPS_INVAL("loongson_cp2");
5901        generate_exception_end(ctx, EXCP_RI);
5902        return;
5903    }
5904
5905    gen_store_fpr64(ctx, t0, rd);
5906
5907no_rd:
5908    tcg_temp_free_i64(t0);
5909    tcg_temp_free_i64(t1);
5910}
5911
5912/* Traps */
5913static void gen_trap(DisasContext *ctx, uint32_t opc,
5914                     int rs, int rt, int16_t imm)
5915{
5916    int cond;
5917    TCGv t0 = tcg_temp_new();
5918    TCGv t1 = tcg_temp_new();
5919
5920    cond = 0;
5921    /* Load needed operands */
5922    switch (opc) {
5923    case OPC_TEQ:
5924    case OPC_TGE:
5925    case OPC_TGEU:
5926    case OPC_TLT:
5927    case OPC_TLTU:
5928    case OPC_TNE:
5929        /* Compare two registers */
5930        if (rs != rt) {
5931            gen_load_gpr(t0, rs);
5932            gen_load_gpr(t1, rt);
5933            cond = 1;
5934        }
5935        break;
5936    case OPC_TEQI:
5937    case OPC_TGEI:
5938    case OPC_TGEIU:
5939    case OPC_TLTI:
5940    case OPC_TLTIU:
5941    case OPC_TNEI:
5942        /* Compare register to immediate */
5943        if (rs != 0 || imm != 0) {
5944            gen_load_gpr(t0, rs);
5945            tcg_gen_movi_tl(t1, (int32_t)imm);
5946            cond = 1;
5947        }
5948        break;
5949    }
5950    if (cond == 0) {
5951        switch (opc) {
5952        case OPC_TEQ:   /* rs == rs */
5953        case OPC_TEQI:  /* r0 == 0  */
5954        case OPC_TGE:   /* rs >= rs */
5955        case OPC_TGEI:  /* r0 >= 0  */
5956        case OPC_TGEU:  /* rs >= rs unsigned */
5957        case OPC_TGEIU: /* r0 >= 0  unsigned */
5958            /* Always trap */
5959            generate_exception_end(ctx, EXCP_TRAP);
5960            break;
5961        case OPC_TLT:   /* rs < rs           */
5962        case OPC_TLTI:  /* r0 < 0            */
5963        case OPC_TLTU:  /* rs < rs unsigned  */
5964        case OPC_TLTIU: /* r0 < 0  unsigned  */
5965        case OPC_TNE:   /* rs != rs          */
5966        case OPC_TNEI:  /* r0 != 0           */
5967            /* Never trap: treat as NOP. */
5968            break;
5969        }
5970    } else {
5971        TCGLabel *l1 = gen_new_label();
5972
5973        switch (opc) {
5974        case OPC_TEQ:
5975        case OPC_TEQI:
5976            tcg_gen_brcond_tl(TCG_COND_NE, t0, t1, l1);
5977            break;
5978        case OPC_TGE:
5979        case OPC_TGEI:
5980            tcg_gen_brcond_tl(TCG_COND_LT, t0, t1, l1);
5981            break;
5982        case OPC_TGEU:
5983        case OPC_TGEIU:
5984            tcg_gen_brcond_tl(TCG_COND_LTU, t0, t1, l1);
5985            break;
5986        case OPC_TLT:
5987        case OPC_TLTI:
5988            tcg_gen_brcond_tl(TCG_COND_GE, t0, t1, l1);
5989            break;
5990        case OPC_TLTU:
5991        case OPC_TLTIU:
5992            tcg_gen_brcond_tl(TCG_COND_GEU, t0, t1, l1);
5993            break;
5994        case OPC_TNE:
5995        case OPC_TNEI:
5996            tcg_gen_brcond_tl(TCG_COND_EQ, t0, t1, l1);
5997            break;
5998        }
5999        generate_exception(ctx, EXCP_TRAP);
6000        gen_set_label(l1);
6001    }
6002    tcg_temp_free(t0);
6003    tcg_temp_free(t1);
6004}
6005
6006static inline bool use_goto_tb(DisasContext *ctx, target_ulong dest)
6007{
6008    if (unlikely(ctx->base.singlestep_enabled)) {
6009        return false;
6010    }
6011
6012#ifndef CONFIG_USER_ONLY
6013    return (ctx->base.tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK);
6014#else
6015    return true;
6016#endif
6017}
6018
6019static inline void gen_goto_tb(DisasContext *ctx, int n, target_ulong dest)
6020{
6021    if (use_goto_tb(ctx, dest)) {
6022        tcg_gen_goto_tb(n);
6023        gen_save_pc(dest);
6024        tcg_gen_exit_tb(ctx->base.tb, n);
6025    } else {
6026        gen_save_pc(dest);
6027        if (ctx->base.singlestep_enabled) {
6028            save_cpu_state(ctx, 0);
6029            gen_helper_raise_exception_debug(cpu_env);
6030        }
6031        tcg_gen_lookup_and_goto_ptr();
6032    }
6033}
6034
6035/* Branches (before delay slot) */
6036static void gen_compute_branch(DisasContext *ctx, uint32_t opc,
6037                               int insn_bytes,
6038                               int rs, int rt, int32_t offset,
6039                               int delayslot_size)
6040{
6041    target_ulong btgt = -1;
6042    int blink = 0;
6043    int bcond_compute = 0;
6044    TCGv t0 = tcg_temp_new();
6045    TCGv t1 = tcg_temp_new();
6046
6047    if (ctx->hflags & MIPS_HFLAG_BMASK) {
6048#ifdef MIPS_DEBUG_DISAS
6049        LOG_DISAS("Branch in delay / forbidden slot at PC 0x"
6050                  TARGET_FMT_lx "\n", ctx->base.pc_next);
6051#endif
6052        generate_exception_end(ctx, EXCP_RI);
6053        goto out;
6054    }
6055
6056    /* Load needed operands */
6057    switch (opc) {
6058    case OPC_BEQ:
6059    case OPC_BEQL:
6060    case OPC_BNE:
6061    case OPC_BNEL:
6062        /* Compare two registers */
6063        if (rs != rt) {
6064            gen_load_gpr(t0, rs);
6065            gen_load_gpr(t1, rt);
6066            bcond_compute = 1;
6067        }
6068        btgt = ctx->base.pc_next + insn_bytes + offset;
6069        break;
6070    case OPC_BGEZ:
6071    case OPC_BGEZAL:
6072    case OPC_BGEZALL:
6073    case OPC_BGEZL:
6074    case OPC_BGTZ:
6075    case OPC_BGTZL:
6076    case OPC_BLEZ:
6077    case OPC_BLEZL:
6078    case OPC_BLTZ:
6079    case OPC_BLTZAL:
6080    case OPC_BLTZALL:
6081    case OPC_BLTZL:
6082        /* Compare to zero */
6083        if (rs != 0) {
6084            gen_load_gpr(t0, rs);
6085            bcond_compute = 1;
6086        }
6087        btgt = ctx->base.pc_next + insn_bytes + offset;
6088        break;
6089    case OPC_BPOSGE32:
6090#if defined(TARGET_MIPS64)
6091    case OPC_BPOSGE64:
6092        tcg_gen_andi_tl(t0, cpu_dspctrl, 0x7F);
6093#else
6094        tcg_gen_andi_tl(t0, cpu_dspctrl, 0x3F);
6095#endif
6096        bcond_compute = 1;
6097        btgt = ctx->base.pc_next + insn_bytes + offset;
6098        break;
6099    case OPC_J:
6100    case OPC_JAL:
6101    case OPC_JALX:
6102        /* Jump to immediate */
6103        btgt = ((ctx->base.pc_next + insn_bytes) & (int32_t)0xF0000000) |
6104            (uint32_t)offset;
6105        break;
6106    case OPC_JR:
6107    case OPC_JALR:
6108        /* Jump to register */
6109        if (offset != 0 && offset != 16) {
6110            /*
6111             * Hint = 0 is JR/JALR, hint 16 is JR.HB/JALR.HB, the
6112             * others are reserved.
6113             */
6114            MIPS_INVAL("jump hint");
6115            generate_exception_end(ctx, EXCP_RI);
6116            goto out;
6117        }
6118        gen_load_gpr(btarget, rs);
6119        break;
6120    default:
6121        MIPS_INVAL("branch/jump");
6122        generate_exception_end(ctx, EXCP_RI);
6123        goto out;
6124    }
6125    if (bcond_compute == 0) {
6126        /* No condition to be computed */
6127        switch (opc) {
6128        case OPC_BEQ:     /* rx == rx        */
6129        case OPC_BEQL:    /* rx == rx likely */
6130        case OPC_BGEZ:    /* 0 >= 0          */
6131        case OPC_BGEZL:   /* 0 >= 0 likely   */
6132        case OPC_BLEZ:    /* 0 <= 0          */
6133        case OPC_BLEZL:   /* 0 <= 0 likely   */
6134            /* Always take */
6135            ctx->hflags |= MIPS_HFLAG_B;
6136            break;
6137        case OPC_BGEZAL:  /* 0 >= 0          */
6138        case OPC_BGEZALL: /* 0 >= 0 likely   */
6139            /* Always take and link */
6140            blink = 31;
6141            ctx->hflags |= MIPS_HFLAG_B;
6142            break;
6143        case OPC_BNE:     /* rx != rx        */
6144        case OPC_BGTZ:    /* 0 > 0           */
6145        case OPC_BLTZ:    /* 0 < 0           */
6146            /* Treat as NOP. */
6147            goto out;
6148        case OPC_BLTZAL:  /* 0 < 0           */
6149            /*
6150             * Handle as an unconditional branch to get correct delay
6151             * slot checking.
6152             */
6153            blink = 31;
6154            btgt = ctx->base.pc_next + insn_bytes + delayslot_size;
6155            ctx->hflags |= MIPS_HFLAG_B;
6156            break;
6157        case OPC_BLTZALL: /* 0 < 0 likely */
6158            tcg_gen_movi_tl(cpu_gpr[31], ctx->base.pc_next + 8);
6159            /* Skip the instruction in the delay slot */
6160            ctx->base.pc_next += 4;
6161            goto out;
6162        case OPC_BNEL:    /* rx != rx likely */
6163        case OPC_BGTZL:   /* 0 > 0 likely */
6164        case OPC_BLTZL:   /* 0 < 0 likely */
6165            /* Skip the instruction in the delay slot */
6166            ctx->base.pc_next += 4;
6167            goto out;
6168        case OPC_J:
6169            ctx->hflags |= MIPS_HFLAG_B;
6170            break;
6171        case OPC_JALX:
6172            ctx->hflags |= MIPS_HFLAG_BX;
6173            /* Fallthrough */
6174        case OPC_JAL:
6175            blink = 31;
6176            ctx->hflags |= MIPS_HFLAG_B;
6177            break;
6178        case OPC_JR:
6179            ctx->hflags |= MIPS_HFLAG_BR;
6180            break;
6181        case OPC_JALR:
6182            blink = rt;
6183            ctx->hflags |= MIPS_HFLAG_BR;
6184            break;
6185        default:
6186            MIPS_INVAL("branch/jump");
6187            generate_exception_end(ctx, EXCP_RI);
6188            goto out;
6189        }
6190    } else {
6191        switch (opc) {
6192        case OPC_BEQ:
6193            tcg_gen_setcond_tl(TCG_COND_EQ, bcond, t0, t1);
6194            goto not_likely;
6195        case OPC_BEQL:
6196            tcg_gen_setcond_tl(TCG_COND_EQ, bcond, t0, t1);
6197            goto likely;
6198        case OPC_BNE:
6199            tcg_gen_setcond_tl(TCG_COND_NE, bcond, t0, t1);
6200            goto not_likely;
6201        case OPC_BNEL:
6202            tcg_gen_setcond_tl(TCG_COND_NE, bcond, t0, t1);
6203            goto likely;
6204        case OPC_BGEZ:
6205            tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
6206            goto not_likely;
6207        case OPC_BGEZL:
6208            tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
6209            goto likely;
6210        case OPC_BGEZAL:
6211            tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
6212            blink = 31;
6213            goto not_likely;
6214        case OPC_BGEZALL:
6215            tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
6216            blink = 31;
6217            goto likely;
6218        case OPC_BGTZ:
6219            tcg_gen_setcondi_tl(TCG_COND_GT, bcond, t0, 0);
6220            goto not_likely;
6221        case OPC_BGTZL:
6222            tcg_gen_setcondi_tl(TCG_COND_GT, bcond, t0, 0);
6223            goto likely;
6224        case OPC_BLEZ:
6225            tcg_gen_setcondi_tl(TCG_COND_LE, bcond, t0, 0);
6226            goto not_likely;
6227        case OPC_BLEZL:
6228            tcg_gen_setcondi_tl(TCG_COND_LE, bcond, t0, 0);
6229            goto likely;
6230        case OPC_BLTZ:
6231            tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
6232            goto not_likely;
6233        case OPC_BLTZL:
6234            tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
6235            goto likely;
6236        case OPC_BPOSGE32:
6237            tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 32);
6238            goto not_likely;
6239#if defined(TARGET_MIPS64)
6240        case OPC_BPOSGE64:
6241            tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 64);
6242            goto not_likely;
6243#endif
6244        case OPC_BLTZAL:
6245            tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
6246            blink = 31;
6247        not_likely:
6248            ctx->hflags |= MIPS_HFLAG_BC;
6249            break;
6250        case OPC_BLTZALL:
6251            tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
6252            blink = 31;
6253        likely:
6254            ctx->hflags |= MIPS_HFLAG_BL;
6255            break;
6256        default:
6257            MIPS_INVAL("conditional branch/jump");
6258            generate_exception_end(ctx, EXCP_RI);
6259            goto out;
6260        }
6261    }
6262
6263    ctx->btarget = btgt;
6264
6265    switch (delayslot_size) {
6266    case 2:
6267        ctx->hflags |= MIPS_HFLAG_BDS16;
6268        break;
6269    case 4:
6270        ctx->hflags |= MIPS_HFLAG_BDS32;
6271        break;
6272    }
6273
6274    if (blink > 0) {
6275        int post_delay = insn_bytes + delayslot_size;
6276        int lowbit = !!(ctx->hflags & MIPS_HFLAG_M16);
6277
6278        tcg_gen_movi_tl(cpu_gpr[blink],
6279                        ctx->base.pc_next + post_delay + lowbit);
6280    }
6281
6282 out:
6283    if (insn_bytes == 2) {
6284        ctx->hflags |= MIPS_HFLAG_B16;
6285    }
6286    tcg_temp_free(t0);
6287    tcg_temp_free(t1);
6288}
6289
6290
6291/* nanoMIPS Branches */
6292static void gen_compute_branch_nm(DisasContext *ctx, uint32_t opc,
6293                                int insn_bytes,
6294                                int rs, int rt, int32_t offset)
6295{
6296    target_ulong btgt = -1;
6297    int bcond_compute = 0;
6298    TCGv t0 = tcg_temp_new();
6299    TCGv t1 = tcg_temp_new();
6300
6301    /* Load needed operands */
6302    switch (opc) {
6303    case OPC_BEQ:
6304    case OPC_BNE:
6305        /* Compare two registers */
6306        if (rs != rt) {
6307            gen_load_gpr(t0, rs);
6308            gen_load_gpr(t1, rt);
6309            bcond_compute = 1;
6310        }
6311        btgt = ctx->base.pc_next + insn_bytes + offset;
6312        break;
6313    case OPC_BGEZAL:
6314        /* Compare to zero */
6315        if (rs != 0) {
6316            gen_load_gpr(t0, rs);
6317            bcond_compute = 1;
6318        }
6319        btgt = ctx->base.pc_next + insn_bytes + offset;
6320        break;
6321    case OPC_BPOSGE32:
6322        tcg_gen_andi_tl(t0, cpu_dspctrl, 0x3F);
6323        bcond_compute = 1;
6324        btgt = ctx->base.pc_next + insn_bytes + offset;
6325        break;
6326    case OPC_JR:
6327    case OPC_JALR:
6328        /* Jump to register */
6329        if (offset != 0 && offset != 16) {
6330            /*
6331             * Hint = 0 is JR/JALR, hint 16 is JR.HB/JALR.HB, the
6332             * others are reserved.
6333             */
6334            MIPS_INVAL("jump hint");
6335            generate_exception_end(ctx, EXCP_RI);
6336            goto out;
6337        }
6338        gen_load_gpr(btarget, rs);
6339        break;
6340    default:
6341        MIPS_INVAL("branch/jump");
6342        generate_exception_end(ctx, EXCP_RI);
6343        goto out;
6344    }
6345    if (bcond_compute == 0) {
6346        /* No condition to be computed */
6347        switch (opc) {
6348        case OPC_BEQ:     /* rx == rx        */
6349            /* Always take */
6350            ctx->hflags |= MIPS_HFLAG_B;
6351            break;
6352        case OPC_BGEZAL:  /* 0 >= 0          */
6353            /* Always take and link */
6354            tcg_gen_movi_tl(cpu_gpr[31],
6355                            ctx->base.pc_next + insn_bytes);
6356            ctx->hflags |= MIPS_HFLAG_B;
6357            break;
6358        case OPC_BNE:     /* rx != rx        */
6359            tcg_gen_movi_tl(cpu_gpr[31], ctx->base.pc_next + 8);
6360            /* Skip the instruction in the delay slot */
6361            ctx->base.pc_next += 4;
6362            goto out;
6363        case OPC_JR:
6364            ctx->hflags |= MIPS_HFLAG_BR;
6365            break;
6366        case OPC_JALR:
6367            if (rt > 0) {
6368                tcg_gen_movi_tl(cpu_gpr[rt],
6369                                ctx->base.pc_next + insn_bytes);
6370            }
6371            ctx->hflags |= MIPS_HFLAG_BR;
6372            break;
6373        default:
6374            MIPS_INVAL("branch/jump");
6375            generate_exception_end(ctx, EXCP_RI);
6376            goto out;
6377        }
6378    } else {
6379        switch (opc) {
6380        case OPC_BEQ:
6381            tcg_gen_setcond_tl(TCG_COND_EQ, bcond, t0, t1);
6382            goto not_likely;
6383        case OPC_BNE:
6384            tcg_gen_setcond_tl(TCG_COND_NE, bcond, t0, t1);
6385            goto not_likely;
6386        case OPC_BGEZAL:
6387            tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
6388            tcg_gen_movi_tl(cpu_gpr[31],
6389                            ctx->base.pc_next + insn_bytes);
6390            goto not_likely;
6391        case OPC_BPOSGE32:
6392            tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 32);
6393        not_likely:
6394            ctx->hflags |= MIPS_HFLAG_BC;
6395            break;
6396        default:
6397            MIPS_INVAL("conditional branch/jump");
6398            generate_exception_end(ctx, EXCP_RI);
6399            goto out;
6400        }
6401    }
6402
6403    ctx->btarget = btgt;
6404
6405 out:
6406    if (insn_bytes == 2) {
6407        ctx->hflags |= MIPS_HFLAG_B16;
6408    }
6409    tcg_temp_free(t0);
6410    tcg_temp_free(t1);
6411}
6412
6413
6414/* special3 bitfield operations */
6415static void gen_bitops(DisasContext *ctx, uint32_t opc, int rt,
6416                       int rs, int lsb, int msb)
6417{
6418    TCGv t0 = tcg_temp_new();
6419    TCGv t1 = tcg_temp_new();
6420
6421    gen_load_gpr(t1, rs);
6422    switch (opc) {
6423    case OPC_EXT:
6424        if (lsb + msb > 31) {
6425            goto fail;
6426        }
6427        if (msb != 31) {
6428            tcg_gen_extract_tl(t0, t1, lsb, msb + 1);
6429        } else {
6430            /*
6431             * The two checks together imply that lsb == 0,
6432             * so this is a simple sign-extension.
6433             */
6434            tcg_gen_ext32s_tl(t0, t1);
6435        }
6436        break;
6437#if defined(TARGET_MIPS64)
6438    case OPC_DEXTU:
6439        lsb += 32;
6440        goto do_dext;
6441    case OPC_DEXTM:
6442        msb += 32;
6443        goto do_dext;
6444    case OPC_DEXT:
6445    do_dext:
6446        if (lsb + msb > 63) {
6447            goto fail;
6448        }
6449        tcg_gen_extract_tl(t0, t1, lsb, msb + 1);
6450        break;
6451#endif
6452    case OPC_INS:
6453        if (lsb > msb) {
6454            goto fail;
6455        }
6456        gen_load_gpr(t0, rt);
6457        tcg_gen_deposit_tl(t0, t0, t1, lsb, msb - lsb + 1);
6458        tcg_gen_ext32s_tl(t0, t0);
6459        break;
6460#if defined(TARGET_MIPS64)
6461    case OPC_DINSU:
6462        lsb += 32;
6463        /* FALLTHRU */
6464    case OPC_DINSM:
6465        msb += 32;
6466        /* FALLTHRU */
6467    case OPC_DINS:
6468        if (lsb > msb) {
6469            goto fail;
6470        }
6471        gen_load_gpr(t0, rt);
6472        tcg_gen_deposit_tl(t0, t0, t1, lsb, msb - lsb + 1);
6473        break;
6474#endif
6475    default:
6476fail:
6477        MIPS_INVAL("bitops");
6478        generate_exception_end(ctx, EXCP_RI);
6479        tcg_temp_free(t0);
6480        tcg_temp_free(t1);
6481        return;
6482    }
6483    gen_store_gpr(t0, rt);
6484    tcg_temp_free(t0);
6485    tcg_temp_free(t1);
6486}
6487
6488static void gen_bshfl(DisasContext *ctx, uint32_t op2, int rt, int rd)
6489{
6490    TCGv t0;
6491
6492    if (rd == 0) {
6493        /* If no destination, treat it as a NOP. */
6494        return;
6495    }
6496
6497    t0 = tcg_temp_new();
6498    gen_load_gpr(t0, rt);
6499    switch (op2) {
6500    case OPC_WSBH:
6501        {
6502            TCGv t1 = tcg_temp_new();
6503            TCGv t2 = tcg_const_tl(0x00FF00FF);
6504
6505            tcg_gen_shri_tl(t1, t0, 8);
6506            tcg_gen_and_tl(t1, t1, t2);
6507            tcg_gen_and_tl(t0, t0, t2);
6508            tcg_gen_shli_tl(t0, t0, 8);
6509            tcg_gen_or_tl(t0, t0, t1);
6510            tcg_temp_free(t2);
6511            tcg_temp_free(t1);
6512            tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
6513        }
6514        break;
6515    case OPC_SEB:
6516        tcg_gen_ext8s_tl(cpu_gpr[rd], t0);
6517        break;
6518    case OPC_SEH:
6519        tcg_gen_ext16s_tl(cpu_gpr[rd], t0);
6520        break;
6521#if defined(TARGET_MIPS64)
6522    case OPC_DSBH:
6523        {
6524            TCGv t1 = tcg_temp_new();
6525            TCGv t2 = tcg_const_tl(0x00FF00FF00FF00FFULL);
6526
6527            tcg_gen_shri_tl(t1, t0, 8);
6528            tcg_gen_and_tl(t1, t1, t2);
6529            tcg_gen_and_tl(t0, t0, t2);
6530            tcg_gen_shli_tl(t0, t0, 8);
6531            tcg_gen_or_tl(cpu_gpr[rd], t0, t1);
6532            tcg_temp_free(t2);
6533            tcg_temp_free(t1);
6534        }
6535        break;
6536    case OPC_DSHD:
6537        {
6538            TCGv t1 = tcg_temp_new();
6539            TCGv t2 = tcg_const_tl(0x0000FFFF0000FFFFULL);
6540
6541            tcg_gen_shri_tl(t1, t0, 16);
6542            tcg_gen_and_tl(t1, t1, t2);
6543            tcg_gen_and_tl(t0, t0, t2);
6544            tcg_gen_shli_tl(t0, t0, 16);
6545            tcg_gen_or_tl(t0, t0, t1);
6546            tcg_gen_shri_tl(t1, t0, 32);
6547            tcg_gen_shli_tl(t0, t0, 32);
6548            tcg_gen_or_tl(cpu_gpr[rd], t0, t1);
6549            tcg_temp_free(t2);
6550            tcg_temp_free(t1);
6551        }
6552        break;
6553#endif
6554    default:
6555        MIPS_INVAL("bsfhl");
6556        generate_exception_end(ctx, EXCP_RI);
6557        tcg_temp_free(t0);
6558        return;
6559    }
6560    tcg_temp_free(t0);
6561}
6562
6563static void gen_lsa(DisasContext *ctx, int opc, int rd, int rs, int rt,
6564                    int imm2)
6565{
6566    TCGv t0;
6567    TCGv t1;
6568    if (rd == 0) {
6569        /* Treat as NOP. */
6570        return;
6571    }
6572    t0 = tcg_temp_new();
6573    t1 = tcg_temp_new();
6574    gen_load_gpr(t0, rs);
6575    gen_load_gpr(t1, rt);
6576    tcg_gen_shli_tl(t0, t0, imm2 + 1);
6577    tcg_gen_add_tl(cpu_gpr[rd], t0, t1);
6578    if (opc == OPC_LSA) {
6579        tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
6580    }
6581
6582    tcg_temp_free(t1);
6583    tcg_temp_free(t0);
6584
6585    return;
6586}
6587
6588static void gen_align_bits(DisasContext *ctx, int wordsz, int rd, int rs,
6589                           int rt, int bits)
6590{
6591    TCGv t0;
6592    if (rd == 0) {
6593        /* Treat as NOP. */
6594        return;
6595    }
6596    t0 = tcg_temp_new();
6597    if (bits == 0 || bits == wordsz) {
6598        if (bits == 0) {
6599            gen_load_gpr(t0, rt);
6600        } else {
6601            gen_load_gpr(t0, rs);
6602        }
6603        switch (wordsz) {
6604        case 32:
6605            tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
6606            break;
6607#if defined(TARGET_MIPS64)
6608        case 64:
6609            tcg_gen_mov_tl(cpu_gpr[rd], t0);
6610            break;
6611#endif
6612        }
6613    } else {
6614        TCGv t1 = tcg_temp_new();
6615        gen_load_gpr(t0, rt);
6616        gen_load_gpr(t1, rs);
6617        switch (wordsz) {
6618        case 32:
6619            {
6620                TCGv_i64 t2 = tcg_temp_new_i64();
6621                tcg_gen_concat_tl_i64(t2, t1, t0);
6622                tcg_gen_shri_i64(t2, t2, 32 - bits);
6623                gen_move_low32(cpu_gpr[rd], t2);
6624                tcg_temp_free_i64(t2);
6625            }
6626            break;
6627#if defined(TARGET_MIPS64)
6628        case 64:
6629            tcg_gen_shli_tl(t0, t0, bits);
6630            tcg_gen_shri_tl(t1, t1, 64 - bits);
6631            tcg_gen_or_tl(cpu_gpr[rd], t1, t0);
6632            break;
6633#endif
6634        }
6635        tcg_temp_free(t1);
6636    }
6637
6638    tcg_temp_free(t0);
6639}
6640
6641static void gen_align(DisasContext *ctx, int wordsz, int rd, int rs, int rt,
6642                      int bp)
6643{
6644    gen_align_bits(ctx, wordsz, rd, rs, rt, bp * 8);
6645}
6646
6647static void gen_ext(DisasContext *ctx, int wordsz, int rd, int rs, int rt,
6648                    int shift)
6649{
6650    gen_align_bits(ctx, wordsz, rd, rs, rt, wordsz - shift);
6651}
6652
6653static void gen_bitswap(DisasContext *ctx, int opc, int rd, int rt)
6654{
6655    TCGv t0;
6656    if (rd == 0) {
6657        /* Treat as NOP. */
6658        return;
6659    }
6660    t0 = tcg_temp_new();
6661    gen_load_gpr(t0, rt);
6662    switch (opc) {
6663    case OPC_BITSWAP:
6664        gen_helper_bitswap(cpu_gpr[rd], t0);
6665        break;
6666#if defined(TARGET_MIPS64)
6667    case OPC_DBITSWAP:
6668        gen_helper_dbitswap(cpu_gpr[rd], t0);
6669        break;
6670#endif
6671    }
6672    tcg_temp_free(t0);
6673}
6674
6675#ifndef CONFIG_USER_ONLY
6676/* CP0 (MMU and control) */
6677static inline void gen_mthc0_entrylo(TCGv arg, target_ulong off)
6678{
6679    TCGv_i64 t0 = tcg_temp_new_i64();
6680    TCGv_i64 t1 = tcg_temp_new_i64();
6681
6682    tcg_gen_ext_tl_i64(t0, arg);
6683    tcg_gen_ld_i64(t1, cpu_env, off);
6684#if defined(TARGET_MIPS64)
6685    tcg_gen_deposit_i64(t1, t1, t0, 30, 32);
6686#else
6687    tcg_gen_concat32_i64(t1, t1, t0);
6688#endif
6689    tcg_gen_st_i64(t1, cpu_env, off);
6690    tcg_temp_free_i64(t1);
6691    tcg_temp_free_i64(t0);
6692}
6693
6694static inline void gen_mthc0_store64(TCGv arg, target_ulong off)
6695{
6696    TCGv_i64 t0 = tcg_temp_new_i64();
6697    TCGv_i64 t1 = tcg_temp_new_i64();
6698
6699    tcg_gen_ext_tl_i64(t0, arg);
6700    tcg_gen_ld_i64(t1, cpu_env, off);
6701    tcg_gen_concat32_i64(t1, t1, t0);
6702    tcg_gen_st_i64(t1, cpu_env, off);
6703    tcg_temp_free_i64(t1);
6704    tcg_temp_free_i64(t0);
6705}
6706
6707static inline void gen_mfhc0_entrylo(TCGv arg, target_ulong off)
6708{
6709    TCGv_i64 t0 = tcg_temp_new_i64();
6710
6711    tcg_gen_ld_i64(t0, cpu_env, off);
6712#if defined(TARGET_MIPS64)
6713    tcg_gen_shri_i64(t0, t0, 30);
6714#else
6715    tcg_gen_shri_i64(t0, t0, 32);
6716#endif
6717    gen_move_low32(arg, t0);
6718    tcg_temp_free_i64(t0);
6719}
6720
6721static inline void gen_mfhc0_load64(TCGv arg, target_ulong off, int shift)
6722{
6723    TCGv_i64 t0 = tcg_temp_new_i64();
6724
6725    tcg_gen_ld_i64(t0, cpu_env, off);
6726    tcg_gen_shri_i64(t0, t0, 32 + shift);
6727    gen_move_low32(arg, t0);
6728    tcg_temp_free_i64(t0);
6729}
6730
6731static inline void gen_mfc0_load32(TCGv arg, target_ulong off)
6732{
6733    TCGv_i32 t0 = tcg_temp_new_i32();
6734
6735    tcg_gen_ld_i32(t0, cpu_env, off);
6736    tcg_gen_ext_i32_tl(arg, t0);
6737    tcg_temp_free_i32(t0);
6738}
6739
6740static inline void gen_mfc0_load64(TCGv arg, target_ulong off)
6741{
6742    tcg_gen_ld_tl(arg, cpu_env, off);
6743    tcg_gen_ext32s_tl(arg, arg);
6744}
6745
6746static inline void gen_mtc0_store32(TCGv arg, target_ulong off)
6747{
6748    TCGv_i32 t0 = tcg_temp_new_i32();
6749
6750    tcg_gen_trunc_tl_i32(t0, arg);
6751    tcg_gen_st_i32(t0, cpu_env, off);
6752    tcg_temp_free_i32(t0);
6753}
6754
6755#define CP0_CHECK(c)                            \
6756    do {                                        \
6757        if (!(c)) {                             \
6758            goto cp0_unimplemented;             \
6759        }                                       \
6760    } while (0)
6761
6762static void gen_mfhc0(DisasContext *ctx, TCGv arg, int reg, int sel)
6763{
6764    const char *register_name = "invalid";
6765
6766    switch (reg) {
6767    case CP0_REGISTER_02:
6768        switch (sel) {
6769        case 0:
6770            CP0_CHECK(ctx->hflags & MIPS_HFLAG_ELPA);
6771            gen_mfhc0_entrylo(arg, offsetof(CPUMIPSState, CP0_EntryLo0));
6772            register_name = "EntryLo0";
6773            break;
6774        default:
6775            goto cp0_unimplemented;
6776        }
6777        break;
6778    case CP0_REGISTER_03:
6779        switch (sel) {
6780        case CP0_REG03__ENTRYLO1:
6781            CP0_CHECK(ctx->hflags & MIPS_HFLAG_ELPA);
6782            gen_mfhc0_entrylo(arg, offsetof(CPUMIPSState, CP0_EntryLo1));
6783            register_name = "EntryLo1";
6784            break;
6785        default:
6786            goto cp0_unimplemented;
6787        }
6788        break;
6789    case CP0_REGISTER_09:
6790        switch (sel) {
6791        case CP0_REG09__SAAR:
6792            CP0_CHECK(ctx->saar);
6793            gen_helper_mfhc0_saar(arg, cpu_env);
6794            register_name = "SAAR";
6795            break;
6796        default:
6797            goto cp0_unimplemented;
6798        }
6799        break;
6800    case CP0_REGISTER_17:
6801        switch (sel) {
6802        case CP0_REG17__LLADDR:
6803            gen_mfhc0_load64(arg, offsetof(CPUMIPSState, CP0_LLAddr),
6804                             ctx->CP0_LLAddr_shift);
6805            register_name = "LLAddr";
6806            break;
6807        case CP0_REG17__MAAR:
6808            CP0_CHECK(ctx->mrp);
6809            gen_helper_mfhc0_maar(arg, cpu_env);
6810            register_name = "MAAR";
6811            break;
6812        default:
6813            goto cp0_unimplemented;
6814        }
6815        break;
6816    case CP0_REGISTER_19:
6817        switch (sel) {
6818        case CP0_REG19__WATCHHI0:
6819        case CP0_REG19__WATCHHI1:
6820        case CP0_REG19__WATCHHI2:
6821        case CP0_REG19__WATCHHI3:
6822        case CP0_REG19__WATCHHI4:
6823        case CP0_REG19__WATCHHI5:
6824        case CP0_REG19__WATCHHI6:
6825        case CP0_REG19__WATCHHI7:
6826            /* upper 32 bits are only available when Config5MI != 0 */
6827            CP0_CHECK(ctx->mi);
6828            gen_mfhc0_load64(arg, offsetof(CPUMIPSState, CP0_WatchHi[sel]), 0);
6829            register_name = "WatchHi";
6830            break;
6831        default:
6832            goto cp0_unimplemented;
6833        }
6834        break;
6835    case CP0_REGISTER_28:
6836        switch (sel) {
6837        case 0:
6838        case 2:
6839        case 4:
6840        case 6:
6841            gen_mfhc0_load64(arg, offsetof(CPUMIPSState, CP0_TagLo), 0);
6842            register_name = "TagLo";
6843            break;
6844        default:
6845            goto cp0_unimplemented;
6846        }
6847        break;
6848    default:
6849        goto cp0_unimplemented;
6850    }
6851    trace_mips_translate_c0("mfhc0", register_name, reg, sel);
6852    return;
6853
6854cp0_unimplemented:
6855    qemu_log_mask(LOG_UNIMP, "mfhc0 %s (reg %d sel %d)\n",
6856                  register_name, reg, sel);
6857    tcg_gen_movi_tl(arg, 0);
6858}
6859
6860static void gen_mthc0(DisasContext *ctx, TCGv arg, int reg, int sel)
6861{
6862    const char *register_name = "invalid";
6863    uint64_t mask = ctx->PAMask >> 36;
6864
6865    switch (reg) {
6866    case CP0_REGISTER_02:
6867        switch (sel) {
6868        case 0:
6869            CP0_CHECK(ctx->hflags & MIPS_HFLAG_ELPA);
6870            tcg_gen_andi_tl(arg, arg, mask);
6871            gen_mthc0_entrylo(arg, offsetof(CPUMIPSState, CP0_EntryLo0));
6872            register_name = "EntryLo0";
6873            break;
6874        default:
6875            goto cp0_unimplemented;
6876        }
6877        break;
6878    case CP0_REGISTER_03:
6879        switch (sel) {
6880        case CP0_REG03__ENTRYLO1:
6881            CP0_CHECK(ctx->hflags & MIPS_HFLAG_ELPA);
6882            tcg_gen_andi_tl(arg, arg, mask);
6883            gen_mthc0_entrylo(arg, offsetof(CPUMIPSState, CP0_EntryLo1));
6884            register_name = "EntryLo1";
6885            break;
6886        default:
6887            goto cp0_unimplemented;
6888        }
6889        break;
6890    case CP0_REGISTER_09:
6891        switch (sel) {
6892        case CP0_REG09__SAAR:
6893            CP0_CHECK(ctx->saar);
6894            gen_helper_mthc0_saar(cpu_env, arg);
6895            register_name = "SAAR";
6896            break;
6897        default:
6898            goto cp0_unimplemented;
6899        }
6900        break;
6901    case CP0_REGISTER_17:
6902        switch (sel) {
6903        case CP0_REG17__LLADDR:
6904            /*
6905             * LLAddr is read-only (the only exception is bit 0 if LLB is
6906             * supported); the CP0_LLAddr_rw_bitmask does not seem to be
6907             * relevant for modern MIPS cores supporting MTHC0, therefore
6908             * treating MTHC0 to LLAddr as NOP.
6909             */
6910            register_name = "LLAddr";
6911            break;
6912        case CP0_REG17__MAAR:
6913            CP0_CHECK(ctx->mrp);
6914            gen_helper_mthc0_maar(cpu_env, arg);
6915            register_name = "MAAR";
6916            break;
6917        default:
6918            goto cp0_unimplemented;
6919        }
6920        break;
6921    case CP0_REGISTER_19:
6922        switch (sel) {
6923        case CP0_REG19__WATCHHI0:
6924        case CP0_REG19__WATCHHI1:
6925        case CP0_REG19__WATCHHI2:
6926        case CP0_REG19__WATCHHI3:
6927        case CP0_REG19__WATCHHI4:
6928        case CP0_REG19__WATCHHI5:
6929        case CP0_REG19__WATCHHI6:
6930        case CP0_REG19__WATCHHI7:
6931            /* upper 32 bits are only available when Config5MI != 0 */
6932            CP0_CHECK(ctx->mi);
6933            gen_helper_0e1i(mthc0_watchhi, arg, sel);
6934            register_name = "WatchHi";
6935            break;
6936        default:
6937            goto cp0_unimplemented;
6938        }
6939        break;
6940    case CP0_REGISTER_28:
6941        switch (sel) {
6942        case 0:
6943        case 2:
6944        case 4:
6945        case 6:
6946            tcg_gen_andi_tl(arg, arg, mask);
6947            gen_mthc0_store64(arg, offsetof(CPUMIPSState, CP0_TagLo));
6948            register_name = "TagLo";
6949            break;
6950        default:
6951            goto cp0_unimplemented;
6952        }
6953        break;
6954    default:
6955        goto cp0_unimplemented;
6956    }
6957    trace_mips_translate_c0("mthc0", register_name, reg, sel);
6958
6959cp0_unimplemented:
6960    qemu_log_mask(LOG_UNIMP, "mthc0 %s (reg %d sel %d)\n",
6961                  register_name, reg, sel);
6962}
6963
6964static inline void gen_mfc0_unimplemented(DisasContext *ctx, TCGv arg)
6965{
6966    if (ctx->insn_flags & ISA_MIPS32R6) {
6967        tcg_gen_movi_tl(arg, 0);
6968    } else {
6969        tcg_gen_movi_tl(arg, ~0);
6970    }
6971}
6972
6973static void gen_mfc0(DisasContext *ctx, TCGv arg, int reg, int sel)
6974{
6975    const char *register_name = "invalid";
6976
6977    if (sel != 0) {
6978        check_insn(ctx, ISA_MIPS32);
6979    }
6980
6981    switch (reg) {
6982    case CP0_REGISTER_00:
6983        switch (sel) {
6984        case CP0_REG00__INDEX:
6985            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Index));
6986            register_name = "Index";
6987            break;
6988        case CP0_REG00__MVPCONTROL:
6989            CP0_CHECK(ctx->insn_flags & ASE_MT);
6990            gen_helper_mfc0_mvpcontrol(arg, cpu_env);
6991            register_name = "MVPControl";
6992            break;
6993        case CP0_REG00__MVPCONF0:
6994            CP0_CHECK(ctx->insn_flags & ASE_MT);
6995            gen_helper_mfc0_mvpconf0(arg, cpu_env);
6996            register_name = "MVPConf0";
6997            break;
6998        case CP0_REG00__MVPCONF1:
6999            CP0_CHECK(ctx->insn_flags & ASE_MT);
7000            gen_helper_mfc0_mvpconf1(arg, cpu_env);
7001            register_name = "MVPConf1";
7002            break;
7003        case CP0_REG00__VPCONTROL:
7004            CP0_CHECK(ctx->vp);
7005            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPControl));
7006            register_name = "VPControl";
7007            break;
7008        default:
7009            goto cp0_unimplemented;
7010        }
7011        break;
7012    case CP0_REGISTER_01:
7013        switch (sel) {
7014        case CP0_REG01__RANDOM:
7015            CP0_CHECK(!(ctx->insn_flags & ISA_MIPS32R6));
7016            gen_helper_mfc0_random(arg, cpu_env);
7017            register_name = "Random";
7018            break;
7019        case CP0_REG01__VPECONTROL:
7020            CP0_CHECK(ctx->insn_flags & ASE_MT);
7021            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEControl));
7022            register_name = "VPEControl";
7023            break;
7024        case CP0_REG01__VPECONF0:
7025            CP0_CHECK(ctx->insn_flags & ASE_MT);
7026            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf0));
7027            register_name = "VPEConf0";
7028            break;
7029        case CP0_REG01__VPECONF1:
7030            CP0_CHECK(ctx->insn_flags & ASE_MT);
7031            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf1));
7032            register_name = "VPEConf1";
7033            break;
7034        case CP0_REG01__YQMASK:
7035            CP0_CHECK(ctx->insn_flags & ASE_MT);
7036            gen_mfc0_load64(arg, offsetof(CPUMIPSState, CP0_YQMask));
7037            register_name = "YQMask";
7038            break;
7039        case CP0_REG01__VPESCHEDULE:
7040            CP0_CHECK(ctx->insn_flags & ASE_MT);
7041            gen_mfc0_load64(arg, offsetof(CPUMIPSState, CP0_VPESchedule));
7042            register_name = "VPESchedule";
7043            break;
7044        case CP0_REG01__VPESCHEFBACK:
7045            CP0_CHECK(ctx->insn_flags & ASE_MT);
7046            gen_mfc0_load64(arg, offsetof(CPUMIPSState, CP0_VPEScheFBack));
7047            register_name = "VPEScheFBack";
7048            break;
7049        case CP0_REG01__VPEOPT:
7050            CP0_CHECK(ctx->insn_flags & ASE_MT);
7051            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEOpt));
7052            register_name = "VPEOpt";
7053            break;
7054        default:
7055            goto cp0_unimplemented;
7056        }
7057        break;
7058    case CP0_REGISTER_02:
7059        switch (sel) {
7060        case CP0_REG02__ENTRYLO0:
7061            {
7062                TCGv_i64 tmp = tcg_temp_new_i64();
7063                tcg_gen_ld_i64(tmp, cpu_env,
7064                               offsetof(CPUMIPSState, CP0_EntryLo0));
7065#if defined(TARGET_MIPS64)
7066                if (ctx->rxi) {
7067                    /* Move RI/XI fields to bits 31:30 */
7068                    tcg_gen_shri_tl(arg, tmp, CP0EnLo_XI);
7069                    tcg_gen_deposit_tl(tmp, tmp, arg, 30, 2);
7070                }
7071#endif
7072                gen_move_low32(arg, tmp);
7073                tcg_temp_free_i64(tmp);
7074            }
7075            register_name = "EntryLo0";
7076            break;
7077        case CP0_REG02__TCSTATUS:
7078            CP0_CHECK(ctx->insn_flags & ASE_MT);
7079            gen_helper_mfc0_tcstatus(arg, cpu_env);
7080            register_name = "TCStatus";
7081            break;
7082        case CP0_REG02__TCBIND:
7083            CP0_CHECK(ctx->insn_flags & ASE_MT);
7084            gen_helper_mfc0_tcbind(arg, cpu_env);
7085            register_name = "TCBind";
7086            break;
7087        case CP0_REG02__TCRESTART:
7088            CP0_CHECK(ctx->insn_flags & ASE_MT);
7089            gen_helper_mfc0_tcrestart(arg, cpu_env);
7090            register_name = "TCRestart";
7091            break;
7092        case CP0_REG02__TCHALT:
7093            CP0_CHECK(ctx->insn_flags & ASE_MT);
7094            gen_helper_mfc0_tchalt(arg, cpu_env);
7095            register_name = "TCHalt";
7096            break;
7097        case CP0_REG02__TCCONTEXT:
7098            CP0_CHECK(ctx->insn_flags & ASE_MT);
7099            gen_helper_mfc0_tccontext(arg, cpu_env);
7100            register_name = "TCContext";
7101            break;
7102        case CP0_REG02__TCSCHEDULE:
7103            CP0_CHECK(ctx->insn_flags & ASE_MT);
7104            gen_helper_mfc0_tcschedule(arg, cpu_env);
7105            register_name = "TCSchedule";
7106            break;
7107        case CP0_REG02__TCSCHEFBACK:
7108            CP0_CHECK(ctx->insn_flags & ASE_MT);
7109            gen_helper_mfc0_tcschefback(arg, cpu_env);
7110            register_name = "TCScheFBack";
7111            break;
7112        default:
7113            goto cp0_unimplemented;
7114        }
7115        break;
7116    case CP0_REGISTER_03:
7117        switch (sel) {
7118        case CP0_REG03__ENTRYLO1:
7119            {
7120                TCGv_i64 tmp = tcg_temp_new_i64();
7121                tcg_gen_ld_i64(tmp, cpu_env,
7122                               offsetof(CPUMIPSState, CP0_EntryLo1));
7123#if defined(TARGET_MIPS64)
7124                if (ctx->rxi) {
7125                    /* Move RI/XI fields to bits 31:30 */
7126                    tcg_gen_shri_tl(arg, tmp, CP0EnLo_XI);
7127                    tcg_gen_deposit_tl(tmp, tmp, arg, 30, 2);
7128                }
7129#endif
7130                gen_move_low32(arg, tmp);
7131                tcg_temp_free_i64(tmp);
7132            }
7133            register_name = "EntryLo1";
7134            break;
7135        case CP0_REG03__GLOBALNUM:
7136            CP0_CHECK(ctx->vp);
7137            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_GlobalNumber));
7138            register_name = "GlobalNumber";
7139            break;
7140        default:
7141            goto cp0_unimplemented;
7142        }
7143        break;
7144    case CP0_REGISTER_04:
7145        switch (sel) {
7146        case CP0_REG04__CONTEXT:
7147            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_Context));
7148            tcg_gen_ext32s_tl(arg, arg);
7149            register_name = "Context";
7150            break;
7151        case CP0_REG04__CONTEXTCONFIG:
7152            /* SmartMIPS ASE */
7153            /* gen_helper_mfc0_contextconfig(arg); */
7154            register_name = "ContextConfig";
7155            goto cp0_unimplemented;
7156        case CP0_REG04__USERLOCAL:
7157            CP0_CHECK(ctx->ulri);
7158            tcg_gen_ld_tl(arg, cpu_env,
7159                          offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
7160            tcg_gen_ext32s_tl(arg, arg);
7161            register_name = "UserLocal";
7162            break;
7163        case CP0_REG04__MMID:
7164            CP0_CHECK(ctx->mi);
7165            gen_helper_mtc0_memorymapid(cpu_env, arg);
7166            register_name = "MMID";
7167            break;
7168        default:
7169            goto cp0_unimplemented;
7170        }
7171        break;
7172    case CP0_REGISTER_05:
7173        switch (sel) {
7174        case CP0_REG05__PAGEMASK:
7175            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageMask));
7176            register_name = "PageMask";
7177            break;
7178        case CP0_REG05__PAGEGRAIN:
7179            check_insn(ctx, ISA_MIPS32R2);
7180            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageGrain));
7181            register_name = "PageGrain";
7182            break;
7183        case CP0_REG05__SEGCTL0:
7184            CP0_CHECK(ctx->sc);
7185            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_SegCtl0));
7186            tcg_gen_ext32s_tl(arg, arg);
7187            register_name = "SegCtl0";
7188            break;
7189        case CP0_REG05__SEGCTL1:
7190            CP0_CHECK(ctx->sc);
7191            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_SegCtl1));
7192            tcg_gen_ext32s_tl(arg, arg);
7193            register_name = "SegCtl1";
7194            break;
7195        case CP0_REG05__SEGCTL2:
7196            CP0_CHECK(ctx->sc);
7197            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_SegCtl2));
7198            tcg_gen_ext32s_tl(arg, arg);
7199            register_name = "SegCtl2";
7200            break;
7201        case CP0_REG05__PWBASE:
7202            check_pw(ctx);
7203            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PWBase));
7204            register_name = "PWBase";
7205            break;
7206        case CP0_REG05__PWFIELD:
7207            check_pw(ctx);
7208            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PWField));
7209            register_name = "PWField";
7210            break;
7211        case CP0_REG05__PWSIZE:
7212            check_pw(ctx);
7213            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PWSize));
7214            register_name = "PWSize";
7215            break;
7216        default:
7217            goto cp0_unimplemented;
7218        }
7219        break;
7220    case CP0_REGISTER_06:
7221        switch (sel) {
7222        case CP0_REG06__WIRED:
7223            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Wired));
7224            register_name = "Wired";
7225            break;
7226        case CP0_REG06__SRSCONF0:
7227            check_insn(ctx, ISA_MIPS32R2);
7228            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf0));
7229            register_name = "SRSConf0";
7230            break;
7231        case CP0_REG06__SRSCONF1:
7232            check_insn(ctx, ISA_MIPS32R2);
7233            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf1));
7234            register_name = "SRSConf1";
7235            break;
7236        case CP0_REG06__SRSCONF2:
7237            check_insn(ctx, ISA_MIPS32R2);
7238            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf2));
7239            register_name = "SRSConf2";
7240            break;
7241        case CP0_REG06__SRSCONF3:
7242            check_insn(ctx, ISA_MIPS32R2);
7243            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf3));
7244            register_name = "SRSConf3";
7245            break;
7246        case CP0_REG06__SRSCONF4:
7247            check_insn(ctx, ISA_MIPS32R2);
7248            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf4));
7249            register_name = "SRSConf4";
7250            break;
7251        case CP0_REG06__PWCTL:
7252            check_pw(ctx);
7253            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PWCtl));
7254            register_name = "PWCtl";
7255            break;
7256        default:
7257            goto cp0_unimplemented;
7258        }
7259        break;
7260    case CP0_REGISTER_07:
7261        switch (sel) {
7262        case CP0_REG07__HWRENA:
7263            check_insn(ctx, ISA_MIPS32R2);
7264            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_HWREna));
7265            register_name = "HWREna";
7266            break;
7267        default:
7268            goto cp0_unimplemented;
7269        }
7270        break;
7271    case CP0_REGISTER_08:
7272        switch (sel) {
7273        case CP0_REG08__BADVADDR:
7274            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_BadVAddr));
7275            tcg_gen_ext32s_tl(arg, arg);
7276            register_name = "BadVAddr";
7277            break;
7278        case CP0_REG08__BADINSTR:
7279            CP0_CHECK(ctx->bi);
7280            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_BadInstr));
7281            register_name = "BadInstr";
7282            break;
7283        case CP0_REG08__BADINSTRP:
7284            CP0_CHECK(ctx->bp);
7285            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_BadInstrP));
7286            register_name = "BadInstrP";
7287            break;
7288        case CP0_REG08__BADINSTRX:
7289            CP0_CHECK(ctx->bi);
7290            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_BadInstrX));
7291            tcg_gen_andi_tl(arg, arg, ~0xffff);
7292            register_name = "BadInstrX";
7293            break;
7294        default:
7295            goto cp0_unimplemented;
7296        }
7297        break;
7298    case CP0_REGISTER_09:
7299        switch (sel) {
7300        case CP0_REG09__COUNT:
7301            /* Mark as an IO operation because we read the time.  */
7302            if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
7303                gen_io_start();
7304            }
7305            gen_helper_mfc0_count(arg, cpu_env);
7306            /*
7307             * Break the TB to be able to take timer interrupts immediately
7308             * after reading count. DISAS_STOP isn't sufficient, we need to
7309             * ensure we break completely out of translated code.
7310             */
7311            gen_save_pc(ctx->base.pc_next + 4);
7312            ctx->base.is_jmp = DISAS_EXIT;
7313            register_name = "Count";
7314            break;
7315        case CP0_REG09__SAARI:
7316            CP0_CHECK(ctx->saar);
7317            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SAARI));
7318            register_name = "SAARI";
7319            break;
7320        case CP0_REG09__SAAR:
7321            CP0_CHECK(ctx->saar);
7322            gen_helper_mfc0_saar(arg, cpu_env);
7323            register_name = "SAAR";
7324            break;
7325        default:
7326            goto cp0_unimplemented;
7327        }
7328        break;
7329    case CP0_REGISTER_10:
7330        switch (sel) {
7331        case CP0_REG10__ENTRYHI:
7332            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryHi));
7333            tcg_gen_ext32s_tl(arg, arg);
7334            register_name = "EntryHi";
7335            break;
7336        default:
7337            goto cp0_unimplemented;
7338        }
7339        break;
7340    case CP0_REGISTER_11:
7341        switch (sel) {
7342        case CP0_REG11__COMPARE:
7343            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Compare));
7344            register_name = "Compare";
7345            break;
7346        /* 6,7 are implementation dependent */
7347        default:
7348            goto cp0_unimplemented;
7349        }
7350        break;
7351    case CP0_REGISTER_12:
7352        switch (sel) {
7353        case CP0_REG12__STATUS:
7354            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Status));
7355            register_name = "Status";
7356            break;
7357        case CP0_REG12__INTCTL:
7358            check_insn(ctx, ISA_MIPS32R2);
7359            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_IntCtl));
7360            register_name = "IntCtl";
7361            break;
7362        case CP0_REG12__SRSCTL:
7363            check_insn(ctx, ISA_MIPS32R2);
7364            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSCtl));
7365            register_name = "SRSCtl";
7366            break;
7367        case CP0_REG12__SRSMAP:
7368            check_insn(ctx, ISA_MIPS32R2);
7369            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSMap));
7370            register_name = "SRSMap";
7371            break;
7372        default:
7373            goto cp0_unimplemented;
7374       }
7375        break;
7376    case CP0_REGISTER_13:
7377        switch (sel) {
7378        case CP0_REG13__CAUSE:
7379            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Cause));
7380            register_name = "Cause";
7381            break;
7382        default:
7383            goto cp0_unimplemented;
7384       }
7385        break;
7386    case CP0_REGISTER_14:
7387        switch (sel) {
7388        case CP0_REG14__EPC:
7389            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EPC));
7390            tcg_gen_ext32s_tl(arg, arg);
7391            register_name = "EPC";
7392            break;
7393        default:
7394            goto cp0_unimplemented;
7395        }
7396        break;
7397    case CP0_REGISTER_15:
7398        switch (sel) {
7399        case CP0_REG15__PRID:
7400            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PRid));
7401            register_name = "PRid";
7402            break;
7403        case CP0_REG15__EBASE:
7404            check_insn(ctx, ISA_MIPS32R2);
7405            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EBase));
7406            tcg_gen_ext32s_tl(arg, arg);
7407            register_name = "EBase";
7408            break;
7409        case CP0_REG15__CMGCRBASE:
7410            check_insn(ctx, ISA_MIPS32R2);
7411            CP0_CHECK(ctx->cmgcr);
7412            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_CMGCRBase));
7413            tcg_gen_ext32s_tl(arg, arg);
7414            register_name = "CMGCRBase";
7415            break;
7416        default:
7417            goto cp0_unimplemented;
7418       }
7419        break;
7420    case CP0_REGISTER_16:
7421        switch (sel) {
7422        case CP0_REG16__CONFIG:
7423            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config0));
7424            register_name = "Config";
7425            break;
7426        case CP0_REG16__CONFIG1:
7427            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config1));
7428            register_name = "Config1";
7429            break;
7430        case CP0_REG16__CONFIG2:
7431            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config2));
7432            register_name = "Config2";
7433            break;
7434        case CP0_REG16__CONFIG3:
7435            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config3));
7436            register_name = "Config3";
7437            break;
7438        case CP0_REG16__CONFIG4:
7439            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config4));
7440            register_name = "Config4";
7441            break;
7442        case CP0_REG16__CONFIG5:
7443            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config5));
7444            register_name = "Config5";
7445            break;
7446        /* 6,7 are implementation dependent */
7447        case CP0_REG16__CONFIG6:
7448            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config6));
7449            register_name = "Config6";
7450            break;
7451        case CP0_REG16__CONFIG7:
7452            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config7));
7453            register_name = "Config7";
7454            break;
7455        default:
7456            goto cp0_unimplemented;
7457        }
7458        break;
7459    case CP0_REGISTER_17:
7460        switch (sel) {
7461        case CP0_REG17__LLADDR:
7462            gen_helper_mfc0_lladdr(arg, cpu_env);
7463            register_name = "LLAddr";
7464            break;
7465        case CP0_REG17__MAAR:
7466            CP0_CHECK(ctx->mrp);
7467            gen_helper_mfc0_maar(arg, cpu_env);
7468            register_name = "MAAR";
7469            break;
7470        case CP0_REG17__MAARI:
7471            CP0_CHECK(ctx->mrp);
7472            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_MAARI));
7473            register_name = "MAARI";
7474            break;
7475        default:
7476            goto cp0_unimplemented;
7477        }
7478        break;
7479    case CP0_REGISTER_18:
7480        switch (sel) {
7481        case CP0_REG18__WATCHLO0:
7482        case CP0_REG18__WATCHLO1:
7483        case CP0_REG18__WATCHLO2:
7484        case CP0_REG18__WATCHLO3:
7485        case CP0_REG18__WATCHLO4:
7486        case CP0_REG18__WATCHLO5:
7487        case CP0_REG18__WATCHLO6:
7488        case CP0_REG18__WATCHLO7:
7489            CP0_CHECK(ctx->CP0_Config1 & (1 << CP0C1_WR));
7490            gen_helper_1e0i(mfc0_watchlo, arg, sel);
7491            register_name = "WatchLo";
7492            break;
7493        default:
7494            goto cp0_unimplemented;
7495        }
7496        break;
7497    case CP0_REGISTER_19:
7498        switch (sel) {
7499        case CP0_REG19__WATCHHI0:
7500        case CP0_REG19__WATCHHI1:
7501        case CP0_REG19__WATCHHI2:
7502        case CP0_REG19__WATCHHI3:
7503        case CP0_REG19__WATCHHI4:
7504        case CP0_REG19__WATCHHI5:
7505        case CP0_REG19__WATCHHI6:
7506        case CP0_REG19__WATCHHI7:
7507            CP0_CHECK(ctx->CP0_Config1 & (1 << CP0C1_WR));
7508            gen_helper_1e0i(mfc0_watchhi, arg, sel);
7509            register_name = "WatchHi";
7510            break;
7511        default:
7512            goto cp0_unimplemented;
7513        }
7514        break;
7515    case CP0_REGISTER_20:
7516        switch (sel) {
7517        case CP0_REG20__XCONTEXT:
7518#if defined(TARGET_MIPS64)
7519            check_insn(ctx, ISA_MIPS3);
7520            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_XContext));
7521            tcg_gen_ext32s_tl(arg, arg);
7522            register_name = "XContext";
7523            break;
7524#endif
7525        default:
7526            goto cp0_unimplemented;
7527        }
7528        break;
7529    case CP0_REGISTER_21:
7530       /* Officially reserved, but sel 0 is used for R1x000 framemask */
7531        CP0_CHECK(!(ctx->insn_flags & ISA_MIPS32R6));
7532        switch (sel) {
7533        case 0:
7534            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Framemask));
7535            register_name = "Framemask";
7536            break;
7537        default:
7538            goto cp0_unimplemented;
7539        }
7540        break;
7541    case CP0_REGISTER_22:
7542        tcg_gen_movi_tl(arg, 0); /* unimplemented */
7543        register_name = "'Diagnostic"; /* implementation dependent */
7544        break;
7545    case CP0_REGISTER_23:
7546        switch (sel) {
7547        case CP0_REG23__DEBUG:
7548            gen_helper_mfc0_debug(arg, cpu_env); /* EJTAG support */
7549            register_name = "Debug";
7550            break;
7551        case CP0_REG23__TRACECONTROL:
7552            /* PDtrace support */
7553            /* gen_helper_mfc0_tracecontrol(arg);  */
7554            register_name = "TraceControl";
7555            goto cp0_unimplemented;
7556        case CP0_REG23__TRACECONTROL2:
7557            /* PDtrace support */
7558            /* gen_helper_mfc0_tracecontrol2(arg); */
7559            register_name = "TraceControl2";
7560            goto cp0_unimplemented;
7561        case CP0_REG23__USERTRACEDATA1:
7562            /* PDtrace support */
7563            /* gen_helper_mfc0_usertracedata1(arg);*/
7564            register_name = "UserTraceData1";
7565            goto cp0_unimplemented;
7566        case CP0_REG23__TRACEIBPC:
7567            /* PDtrace support */
7568            /* gen_helper_mfc0_traceibpc(arg);     */
7569            register_name = "TraceIBPC";
7570            goto cp0_unimplemented;
7571        case CP0_REG23__TRACEDBPC:
7572            /* PDtrace support */
7573            /* gen_helper_mfc0_tracedbpc(arg);     */
7574            register_name = "TraceDBPC";
7575            goto cp0_unimplemented;
7576        default:
7577            goto cp0_unimplemented;
7578        }
7579        break;
7580    case CP0_REGISTER_24:
7581        switch (sel) {
7582        case CP0_REG24__DEPC:
7583            /* EJTAG support */
7584            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_DEPC));
7585            tcg_gen_ext32s_tl(arg, arg);
7586            register_name = "DEPC";
7587            break;
7588        default:
7589            goto cp0_unimplemented;
7590        }
7591        break;
7592    case CP0_REGISTER_25:
7593        switch (sel) {
7594        case CP0_REG25__PERFCTL0:
7595            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Performance0));
7596            register_name = "Performance0";
7597            break;
7598        case CP0_REG25__PERFCNT0:
7599            /* gen_helper_mfc0_performance1(arg); */
7600            register_name = "Performance1";
7601            goto cp0_unimplemented;
7602        case CP0_REG25__PERFCTL1:
7603            /* gen_helper_mfc0_performance2(arg); */
7604            register_name = "Performance2";
7605            goto cp0_unimplemented;
7606        case CP0_REG25__PERFCNT1:
7607            /* gen_helper_mfc0_performance3(arg); */
7608            register_name = "Performance3";
7609            goto cp0_unimplemented;
7610        case CP0_REG25__PERFCTL2:
7611            /* gen_helper_mfc0_performance4(arg); */
7612            register_name = "Performance4";
7613            goto cp0_unimplemented;
7614        case CP0_REG25__PERFCNT2:
7615            /* gen_helper_mfc0_performance5(arg); */
7616            register_name = "Performance5";
7617            goto cp0_unimplemented;
7618        case CP0_REG25__PERFCTL3:
7619            /* gen_helper_mfc0_performance6(arg); */
7620            register_name = "Performance6";
7621            goto cp0_unimplemented;
7622        case CP0_REG25__PERFCNT3:
7623            /* gen_helper_mfc0_performance7(arg); */
7624            register_name = "Performance7";
7625            goto cp0_unimplemented;
7626        default:
7627            goto cp0_unimplemented;
7628        }
7629        break;
7630    case CP0_REGISTER_26:
7631        switch (sel) {
7632        case CP0_REG26__ERRCTL:
7633            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_ErrCtl));
7634            register_name = "ErrCtl";
7635            break;
7636        default:
7637            goto cp0_unimplemented;
7638        }
7639        break;
7640    case CP0_REGISTER_27:
7641        switch (sel) {
7642        case CP0_REG27__CACHERR:
7643            tcg_gen_movi_tl(arg, 0); /* unimplemented */
7644            register_name = "CacheErr";
7645            break;
7646        default:
7647            goto cp0_unimplemented;
7648        }
7649        break;
7650    case CP0_REGISTER_28:
7651        switch (sel) {
7652        case CP0_REG28__TAGLO:
7653        case CP0_REG28__TAGLO1:
7654        case CP0_REG28__TAGLO2:
7655        case CP0_REG28__TAGLO3:
7656            {
7657                TCGv_i64 tmp = tcg_temp_new_i64();
7658                tcg_gen_ld_i64(tmp, cpu_env, offsetof(CPUMIPSState, CP0_TagLo));
7659                gen_move_low32(arg, tmp);
7660                tcg_temp_free_i64(tmp);
7661            }
7662            register_name = "TagLo";
7663            break;
7664        case CP0_REG28__DATALO:
7665        case CP0_REG28__DATALO1:
7666        case CP0_REG28__DATALO2:
7667        case CP0_REG28__DATALO3:
7668            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataLo));
7669            register_name = "DataLo";
7670            break;
7671        default:
7672            goto cp0_unimplemented;
7673        }
7674        break;
7675    case CP0_REGISTER_29:
7676        switch (sel) {
7677        case CP0_REG29__TAGHI:
7678        case CP0_REG29__TAGHI1:
7679        case CP0_REG29__TAGHI2:
7680        case CP0_REG29__TAGHI3:
7681            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_TagHi));
7682            register_name = "TagHi";
7683            break;
7684        case CP0_REG29__DATAHI:
7685        case CP0_REG29__DATAHI1:
7686        case CP0_REG29__DATAHI2:
7687        case CP0_REG29__DATAHI3:
7688            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataHi));
7689            register_name = "DataHi";
7690            break;
7691        default:
7692            goto cp0_unimplemented;
7693        }
7694        break;
7695    case CP0_REGISTER_30:
7696        switch (sel) {
7697        case CP0_REG30__ERROREPC:
7698            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_ErrorEPC));
7699            tcg_gen_ext32s_tl(arg, arg);
7700            register_name = "ErrorEPC";
7701            break;
7702        default:
7703            goto cp0_unimplemented;
7704        }
7705        break;
7706    case CP0_REGISTER_31:
7707        switch (sel) {
7708        case CP0_REG31__DESAVE:
7709            /* EJTAG support */
7710            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DESAVE));
7711            register_name = "DESAVE";
7712            break;
7713        case CP0_REG31__KSCRATCH1:
7714        case CP0_REG31__KSCRATCH2:
7715        case CP0_REG31__KSCRATCH3:
7716        case CP0_REG31__KSCRATCH4:
7717        case CP0_REG31__KSCRATCH5:
7718        case CP0_REG31__KSCRATCH6:
7719            CP0_CHECK(ctx->kscrexist & (1 << sel));
7720            tcg_gen_ld_tl(arg, cpu_env,
7721                          offsetof(CPUMIPSState, CP0_KScratch[sel - 2]));
7722            tcg_gen_ext32s_tl(arg, arg);
7723            register_name = "KScratch";
7724            break;
7725        default:
7726            goto cp0_unimplemented;
7727        }
7728        break;
7729    default:
7730       goto cp0_unimplemented;
7731    }
7732    trace_mips_translate_c0("mfc0", register_name, reg, sel);
7733    return;
7734
7735cp0_unimplemented:
7736    qemu_log_mask(LOG_UNIMP, "mfc0 %s (reg %d sel %d)\n",
7737                  register_name, reg, sel);
7738    gen_mfc0_unimplemented(ctx, arg);
7739}
7740
7741static void gen_mtc0(DisasContext *ctx, TCGv arg, int reg, int sel)
7742{
7743    const char *register_name = "invalid";
7744
7745    if (sel != 0) {
7746        check_insn(ctx, ISA_MIPS32);
7747    }
7748
7749    if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
7750        gen_io_start();
7751    }
7752
7753    switch (reg) {
7754    case CP0_REGISTER_00:
7755        switch (sel) {
7756        case CP0_REG00__INDEX:
7757            gen_helper_mtc0_index(cpu_env, arg);
7758            register_name = "Index";
7759            break;
7760        case CP0_REG00__MVPCONTROL:
7761            CP0_CHECK(ctx->insn_flags & ASE_MT);
7762            gen_helper_mtc0_mvpcontrol(cpu_env, arg);
7763            register_name = "MVPControl";
7764            break;
7765        case CP0_REG00__MVPCONF0:
7766            CP0_CHECK(ctx->insn_flags & ASE_MT);
7767            /* ignored */
7768            register_name = "MVPConf0";
7769            break;
7770        case CP0_REG00__MVPCONF1:
7771            CP0_CHECK(ctx->insn_flags & ASE_MT);
7772            /* ignored */
7773            register_name = "MVPConf1";
7774            break;
7775        case CP0_REG00__VPCONTROL:
7776            CP0_CHECK(ctx->vp);
7777            /* ignored */
7778            register_name = "VPControl";
7779            break;
7780        default:
7781            goto cp0_unimplemented;
7782        }
7783        break;
7784    case CP0_REGISTER_01:
7785        switch (sel) {
7786        case CP0_REG01__RANDOM:
7787            /* ignored */
7788            register_name = "Random";
7789            break;
7790        case CP0_REG01__VPECONTROL:
7791            CP0_CHECK(ctx->insn_flags & ASE_MT);
7792            gen_helper_mtc0_vpecontrol(cpu_env, arg);
7793            register_name = "VPEControl";
7794            break;
7795        case CP0_REG01__VPECONF0:
7796            CP0_CHECK(ctx->insn_flags & ASE_MT);
7797            gen_helper_mtc0_vpeconf0(cpu_env, arg);
7798            register_name = "VPEConf0";
7799            break;
7800        case CP0_REG01__VPECONF1:
7801            CP0_CHECK(ctx->insn_flags & ASE_MT);
7802            gen_helper_mtc0_vpeconf1(cpu_env, arg);
7803            register_name = "VPEConf1";
7804            break;
7805        case CP0_REG01__YQMASK:
7806            CP0_CHECK(ctx->insn_flags & ASE_MT);
7807            gen_helper_mtc0_yqmask(cpu_env, arg);
7808            register_name = "YQMask";
7809            break;
7810        case CP0_REG01__VPESCHEDULE:
7811            CP0_CHECK(ctx->insn_flags & ASE_MT);
7812            tcg_gen_st_tl(arg, cpu_env,
7813                          offsetof(CPUMIPSState, CP0_VPESchedule));
7814            register_name = "VPESchedule";
7815            break;
7816        case CP0_REG01__VPESCHEFBACK:
7817            CP0_CHECK(ctx->insn_flags & ASE_MT);
7818            tcg_gen_st_tl(arg, cpu_env,
7819                          offsetof(CPUMIPSState, CP0_VPEScheFBack));
7820            register_name = "VPEScheFBack";
7821            break;
7822        case CP0_REG01__VPEOPT:
7823            CP0_CHECK(ctx->insn_flags & ASE_MT);
7824            gen_helper_mtc0_vpeopt(cpu_env, arg);
7825            register_name = "VPEOpt";
7826            break;
7827        default:
7828            goto cp0_unimplemented;
7829        }
7830        break;
7831    case CP0_REGISTER_02:
7832        switch (sel) {
7833        case CP0_REG02__ENTRYLO0:
7834            gen_helper_mtc0_entrylo0(cpu_env, arg);
7835            register_name = "EntryLo0";
7836            break;
7837        case CP0_REG02__TCSTATUS:
7838            CP0_CHECK(ctx->insn_flags & ASE_MT);
7839            gen_helper_mtc0_tcstatus(cpu_env, arg);
7840            register_name = "TCStatus";
7841            break;
7842        case CP0_REG02__TCBIND:
7843            CP0_CHECK(ctx->insn_flags & ASE_MT);
7844            gen_helper_mtc0_tcbind(cpu_env, arg);
7845            register_name = "TCBind";
7846            break;
7847        case CP0_REG02__TCRESTART:
7848            CP0_CHECK(ctx->insn_flags & ASE_MT);
7849            gen_helper_mtc0_tcrestart(cpu_env, arg);
7850            register_name = "TCRestart";
7851            break;
7852        case CP0_REG02__TCHALT:
7853            CP0_CHECK(ctx->insn_flags & ASE_MT);
7854            gen_helper_mtc0_tchalt(cpu_env, arg);
7855            register_name = "TCHalt";
7856            break;
7857        case CP0_REG02__TCCONTEXT:
7858            CP0_CHECK(ctx->insn_flags & ASE_MT);
7859            gen_helper_mtc0_tccontext(cpu_env, arg);
7860            register_name = "TCContext";
7861            break;
7862        case CP0_REG02__TCSCHEDULE:
7863            CP0_CHECK(ctx->insn_flags & ASE_MT);
7864            gen_helper_mtc0_tcschedule(cpu_env, arg);
7865            register_name = "TCSchedule";
7866            break;
7867        case CP0_REG02__TCSCHEFBACK:
7868            CP0_CHECK(ctx->insn_flags & ASE_MT);
7869            gen_helper_mtc0_tcschefback(cpu_env, arg);
7870            register_name = "TCScheFBack";
7871            break;
7872        default:
7873            goto cp0_unimplemented;
7874        }
7875        break;
7876    case CP0_REGISTER_03:
7877        switch (sel) {
7878        case CP0_REG03__ENTRYLO1:
7879            gen_helper_mtc0_entrylo1(cpu_env, arg);
7880            register_name = "EntryLo1";
7881            break;
7882        case CP0_REG03__GLOBALNUM:
7883            CP0_CHECK(ctx->vp);
7884            /* ignored */
7885            register_name = "GlobalNumber";
7886            break;
7887        default:
7888            goto cp0_unimplemented;
7889        }
7890        break;
7891    case CP0_REGISTER_04:
7892        switch (sel) {
7893        case CP0_REG04__CONTEXT:
7894            gen_helper_mtc0_context(cpu_env, arg);
7895            register_name = "Context";
7896            break;
7897        case CP0_REG04__CONTEXTCONFIG:
7898            /* SmartMIPS ASE */
7899            /* gen_helper_mtc0_contextconfig(arg); */
7900            register_name = "ContextConfig";
7901            goto cp0_unimplemented;
7902        case CP0_REG04__USERLOCAL:
7903            CP0_CHECK(ctx->ulri);
7904            tcg_gen_st_tl(arg, cpu_env,
7905                          offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
7906            register_name = "UserLocal";
7907            break;
7908        case CP0_REG04__MMID:
7909            CP0_CHECK(ctx->mi);
7910            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_MemoryMapID));
7911            register_name = "MMID";
7912            break;
7913        default:
7914            goto cp0_unimplemented;
7915        }
7916        break;
7917    case CP0_REGISTER_05:
7918        switch (sel) {
7919        case CP0_REG05__PAGEMASK:
7920            gen_helper_mtc0_pagemask(cpu_env, arg);
7921            register_name = "PageMask";
7922            break;
7923        case CP0_REG05__PAGEGRAIN:
7924            check_insn(ctx, ISA_MIPS32R2);
7925            gen_helper_mtc0_pagegrain(cpu_env, arg);
7926            register_name = "PageGrain";
7927            ctx->base.is_jmp = DISAS_STOP;
7928            break;
7929        case CP0_REG05__SEGCTL0:
7930            CP0_CHECK(ctx->sc);
7931            gen_helper_mtc0_segctl0(cpu_env, arg);
7932            register_name = "SegCtl0";
7933            break;
7934        case CP0_REG05__SEGCTL1:
7935            CP0_CHECK(ctx->sc);
7936            gen_helper_mtc0_segctl1(cpu_env, arg);
7937            register_name = "SegCtl1";
7938            break;
7939        case CP0_REG05__SEGCTL2:
7940            CP0_CHECK(ctx->sc);
7941            gen_helper_mtc0_segctl2(cpu_env, arg);
7942            register_name = "SegCtl2";
7943            break;
7944        case CP0_REG05__PWBASE:
7945            check_pw(ctx);
7946            gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_PWBase));
7947            register_name = "PWBase";
7948            break;
7949        case CP0_REG05__PWFIELD:
7950            check_pw(ctx);
7951            gen_helper_mtc0_pwfield(cpu_env, arg);
7952            register_name = "PWField";
7953            break;
7954        case CP0_REG05__PWSIZE:
7955            check_pw(ctx);
7956            gen_helper_mtc0_pwsize(cpu_env, arg);
7957            register_name = "PWSize";
7958            break;
7959        default:
7960            goto cp0_unimplemented;
7961        }
7962        break;
7963    case CP0_REGISTER_06:
7964        switch (sel) {
7965        case CP0_REG06__WIRED:
7966            gen_helper_mtc0_wired(cpu_env, arg);
7967            register_name = "Wired";
7968            break;
7969        case CP0_REG06__SRSCONF0:
7970            check_insn(ctx, ISA_MIPS32R2);
7971            gen_helper_mtc0_srsconf0(cpu_env, arg);
7972            register_name = "SRSConf0";
7973            break;
7974        case CP0_REG06__SRSCONF1:
7975            check_insn(ctx, ISA_MIPS32R2);
7976            gen_helper_mtc0_srsconf1(cpu_env, arg);
7977            register_name = "SRSConf1";
7978            break;
7979        case CP0_REG06__SRSCONF2:
7980            check_insn(ctx, ISA_MIPS32R2);
7981            gen_helper_mtc0_srsconf2(cpu_env, arg);
7982            register_name = "SRSConf2";
7983            break;
7984        case CP0_REG06__SRSCONF3:
7985            check_insn(ctx, ISA_MIPS32R2);
7986            gen_helper_mtc0_srsconf3(cpu_env, arg);
7987            register_name = "SRSConf3";
7988            break;
7989        case CP0_REG06__SRSCONF4:
7990            check_insn(ctx, ISA_MIPS32R2);
7991            gen_helper_mtc0_srsconf4(cpu_env, arg);
7992            register_name = "SRSConf4";
7993            break;
7994        case CP0_REG06__PWCTL:
7995            check_pw(ctx);
7996            gen_helper_mtc0_pwctl(cpu_env, arg);
7997            register_name = "PWCtl";
7998            break;
7999        default:
8000            goto cp0_unimplemented;
8001        }
8002        break;
8003    case CP0_REGISTER_07:
8004        switch (sel) {
8005        case CP0_REG07__HWRENA:
8006            check_insn(ctx, ISA_MIPS32R2);
8007            gen_helper_mtc0_hwrena(cpu_env, arg);
8008            ctx->base.is_jmp = DISAS_STOP;
8009            register_name = "HWREna";
8010            break;
8011        default:
8012            goto cp0_unimplemented;
8013        }
8014        break;
8015    case CP0_REGISTER_08:
8016        switch (sel) {
8017        case CP0_REG08__BADVADDR:
8018            /* ignored */
8019            register_name = "BadVAddr";
8020            break;
8021        case CP0_REG08__BADINSTR:
8022            /* ignored */
8023            register_name = "BadInstr";
8024            break;
8025        case CP0_REG08__BADINSTRP:
8026            /* ignored */
8027            register_name = "BadInstrP";
8028            break;
8029        case CP0_REG08__BADINSTRX:
8030            /* ignored */
8031            register_name = "BadInstrX";
8032            break;
8033        default:
8034            goto cp0_unimplemented;
8035        }
8036        break;
8037    case CP0_REGISTER_09:
8038        switch (sel) {
8039        case CP0_REG09__COUNT:
8040            gen_helper_mtc0_count(cpu_env, arg);
8041            register_name = "Count";
8042            break;
8043        case CP0_REG09__SAARI:
8044            CP0_CHECK(ctx->saar);
8045            gen_helper_mtc0_saari(cpu_env, arg);
8046            register_name = "SAARI";
8047            break;
8048        case CP0_REG09__SAAR:
8049            CP0_CHECK(ctx->saar);
8050            gen_helper_mtc0_saar(cpu_env, arg);
8051            register_name = "SAAR";
8052            break;
8053        default:
8054            goto cp0_unimplemented;
8055        }
8056        break;
8057    case CP0_REGISTER_10:
8058        switch (sel) {
8059        case CP0_REG10__ENTRYHI:
8060            gen_helper_mtc0_entryhi(cpu_env, arg);
8061            register_name = "EntryHi";
8062            break;
8063        default:
8064            goto cp0_unimplemented;
8065        }
8066        break;
8067    case CP0_REGISTER_11:
8068        switch (sel) {
8069        case CP0_REG11__COMPARE:
8070            gen_helper_mtc0_compare(cpu_env, arg);
8071            register_name = "Compare";
8072            break;
8073        /* 6,7 are implementation dependent */
8074        default:
8075            goto cp0_unimplemented;
8076        }
8077        break;
8078    case CP0_REGISTER_12:
8079        switch (sel) {
8080        case CP0_REG12__STATUS:
8081            save_cpu_state(ctx, 1);
8082            gen_helper_mtc0_status(cpu_env, arg);
8083            /* DISAS_STOP isn't good enough here, hflags may have changed. */
8084            gen_save_pc(ctx->base.pc_next + 4);
8085            ctx->base.is_jmp = DISAS_EXIT;
8086            register_name = "Status";
8087            break;
8088        case CP0_REG12__INTCTL:
8089            check_insn(ctx, ISA_MIPS32R2);
8090            gen_helper_mtc0_intctl(cpu_env, arg);
8091            /* Stop translation as we may have switched the execution mode */
8092            ctx->base.is_jmp = DISAS_STOP;
8093            register_name = "IntCtl";
8094            break;
8095        case CP0_REG12__SRSCTL:
8096            check_insn(ctx, ISA_MIPS32R2);
8097            gen_helper_mtc0_srsctl(cpu_env, arg);
8098            /* Stop translation as we may have switched the execution mode */
8099            ctx->base.is_jmp = DISAS_STOP;
8100            register_name = "SRSCtl";
8101            break;
8102        case CP0_REG12__SRSMAP:
8103            check_insn(ctx, ISA_MIPS32R2);
8104            gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_SRSMap));
8105            /* Stop translation as we may have switched the execution mode */
8106            ctx->base.is_jmp = DISAS_STOP;
8107            register_name = "SRSMap";
8108            break;
8109        default:
8110            goto cp0_unimplemented;
8111        }
8112        break;
8113    case CP0_REGISTER_13:
8114        switch (sel) {
8115        case CP0_REG13__CAUSE:
8116            save_cpu_state(ctx, 1);
8117            gen_helper_mtc0_cause(cpu_env, arg);
8118            /*
8119             * Stop translation as we may have triggered an interrupt.
8120             * DISAS_STOP isn't sufficient, we need to ensure we break out of
8121             * translated code to check for pending interrupts.
8122             */
8123            gen_save_pc(ctx->base.pc_next + 4);
8124            ctx->base.is_jmp = DISAS_EXIT;
8125            register_name = "Cause";
8126            break;
8127        default:
8128            goto cp0_unimplemented;
8129        }
8130        break;
8131    case CP0_REGISTER_14:
8132        switch (sel) {
8133        case CP0_REG14__EPC:
8134            tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EPC));
8135            register_name = "EPC";
8136            break;
8137        default:
8138            goto cp0_unimplemented;
8139        }
8140        break;
8141    case CP0_REGISTER_15:
8142        switch (sel) {
8143        case CP0_REG15__PRID:
8144            /* ignored */
8145            register_name = "PRid";
8146            break;
8147        case CP0_REG15__EBASE:
8148            check_insn(ctx, ISA_MIPS32R2);
8149            gen_helper_mtc0_ebase(cpu_env, arg);
8150            register_name = "EBase";
8151            break;
8152        default:
8153            goto cp0_unimplemented;
8154        }
8155        break;
8156    case CP0_REGISTER_16:
8157        switch (sel) {
8158        case CP0_REG16__CONFIG:
8159            gen_helper_mtc0_config0(cpu_env, arg);
8160            register_name = "Config";
8161            /* Stop translation as we may have switched the execution mode */
8162            ctx->base.is_jmp = DISAS_STOP;
8163            break;
8164        case CP0_REG16__CONFIG1:
8165            /* ignored, read only */
8166            register_name = "Config1";
8167            break;
8168        case CP0_REG16__CONFIG2:
8169            gen_helper_mtc0_config2(cpu_env, arg);
8170            register_name = "Config2";
8171            /* Stop translation as we may have switched the execution mode */
8172            ctx->base.is_jmp = DISAS_STOP;
8173            break;
8174        case CP0_REG16__CONFIG3:
8175            gen_helper_mtc0_config3(cpu_env, arg);
8176            register_name = "Config3";
8177            /* Stop translation as we may have switched the execution mode */
8178            ctx->base.is_jmp = DISAS_STOP;
8179            break;
8180        case CP0_REG16__CONFIG4:
8181            gen_helper_mtc0_config4(cpu_env, arg);
8182            register_name = "Config4";
8183            ctx->base.is_jmp = DISAS_STOP;
8184            break;
8185        case CP0_REG16__CONFIG5:
8186            gen_helper_mtc0_config5(cpu_env, arg);
8187            register_name = "Config5";
8188            /* Stop translation as we may have switched the execution mode */
8189            ctx->base.is_jmp = DISAS_STOP;
8190            break;
8191        /* 6,7 are implementation dependent */
8192        case CP0_REG16__CONFIG6:
8193            /* ignored */
8194            register_name = "Config6";
8195            break;
8196        case CP0_REG16__CONFIG7:
8197            /* ignored */
8198            register_name = "Config7";
8199            break;
8200        default:
8201            register_name = "Invalid config selector";
8202            goto cp0_unimplemented;
8203        }
8204        break;
8205    case CP0_REGISTER_17:
8206        switch (sel) {
8207        case CP0_REG17__LLADDR:
8208            gen_helper_mtc0_lladdr(cpu_env, arg);
8209            register_name = "LLAddr";
8210            break;
8211        case CP0_REG17__MAAR:
8212            CP0_CHECK(ctx->mrp);
8213            gen_helper_mtc0_maar(cpu_env, arg);
8214            register_name = "MAAR";
8215            break;
8216        case CP0_REG17__MAARI:
8217            CP0_CHECK(ctx->mrp);
8218            gen_helper_mtc0_maari(cpu_env, arg);
8219            register_name = "MAARI";
8220            break;
8221        default:
8222            goto cp0_unimplemented;
8223        }
8224        break;
8225    case CP0_REGISTER_18:
8226        switch (sel) {
8227        case CP0_REG18__WATCHLO0:
8228        case CP0_REG18__WATCHLO1:
8229        case CP0_REG18__WATCHLO2:
8230        case CP0_REG18__WATCHLO3:
8231        case CP0_REG18__WATCHLO4:
8232        case CP0_REG18__WATCHLO5:
8233        case CP0_REG18__WATCHLO6:
8234        case CP0_REG18__WATCHLO7:
8235            CP0_CHECK(ctx->CP0_Config1 & (1 << CP0C1_WR));
8236            gen_helper_0e1i(mtc0_watchlo, arg, sel);
8237            register_name = "WatchLo";
8238            break;
8239        default:
8240            goto cp0_unimplemented;
8241        }
8242        break;
8243    case CP0_REGISTER_19:
8244        switch (sel) {
8245        case CP0_REG19__WATCHHI0:
8246        case CP0_REG19__WATCHHI1:
8247        case CP0_REG19__WATCHHI2:
8248        case CP0_REG19__WATCHHI3:
8249        case CP0_REG19__WATCHHI4:
8250        case CP0_REG19__WATCHHI5:
8251        case CP0_REG19__WATCHHI6:
8252        case CP0_REG19__WATCHHI7:
8253            CP0_CHECK(ctx->CP0_Config1 & (1 << CP0C1_WR));
8254            gen_helper_0e1i(mtc0_watchhi, arg, sel);
8255            register_name = "WatchHi";
8256            break;
8257        default:
8258            goto cp0_unimplemented;
8259        }
8260        break;
8261    case CP0_REGISTER_20:
8262        switch (sel) {
8263        case CP0_REG20__XCONTEXT:
8264#if defined(TARGET_MIPS64)
8265            check_insn(ctx, ISA_MIPS3);
8266            gen_helper_mtc0_xcontext(cpu_env, arg);
8267            register_name = "XContext";
8268            break;
8269#endif
8270        default:
8271            goto cp0_unimplemented;
8272        }
8273        break;
8274    case CP0_REGISTER_21:
8275       /* Officially reserved, but sel 0 is used for R1x000 framemask */
8276        CP0_CHECK(!(ctx->insn_flags & ISA_MIPS32R6));
8277        switch (sel) {
8278        case 0:
8279            gen_helper_mtc0_framemask(cpu_env, arg);
8280            register_name = "Framemask";
8281            break;
8282        default:
8283            goto cp0_unimplemented;
8284        }
8285        break;
8286    case CP0_REGISTER_22:
8287        /* ignored */
8288        register_name = "Diagnostic"; /* implementation dependent */
8289        break;
8290    case CP0_REGISTER_23:
8291        switch (sel) {
8292        case CP0_REG23__DEBUG:
8293            gen_helper_mtc0_debug(cpu_env, arg); /* EJTAG support */
8294            /* DISAS_STOP isn't good enough here, hflags may have changed. */
8295            gen_save_pc(ctx->base.pc_next + 4);
8296            ctx->base.is_jmp = DISAS_EXIT;
8297            register_name = "Debug";
8298            break;
8299        case CP0_REG23__TRACECONTROL:
8300            /* PDtrace support */
8301            /* gen_helper_mtc0_tracecontrol(cpu_env, arg);  */
8302            register_name = "TraceControl";
8303            /* Stop translation as we may have switched the execution mode */
8304            ctx->base.is_jmp = DISAS_STOP;
8305            goto cp0_unimplemented;
8306        case CP0_REG23__TRACECONTROL2:
8307            /* PDtrace support */
8308            /* gen_helper_mtc0_tracecontrol2(cpu_env, arg); */
8309            register_name = "TraceControl2";
8310            /* Stop translation as we may have switched the execution mode */
8311            ctx->base.is_jmp = DISAS_STOP;
8312            goto cp0_unimplemented;
8313        case CP0_REG23__USERTRACEDATA1:
8314            /* Stop translation as we may have switched the execution mode */
8315            ctx->base.is_jmp = DISAS_STOP;
8316            /* PDtrace support */
8317            /* gen_helper_mtc0_usertracedata1(cpu_env, arg);*/
8318            register_name = "UserTraceData";
8319            /* Stop translation as we may have switched the execution mode */
8320            ctx->base.is_jmp = DISAS_STOP;
8321            goto cp0_unimplemented;
8322        case CP0_REG23__TRACEIBPC:
8323            /* PDtrace support */
8324            /* gen_helper_mtc0_traceibpc(cpu_env, arg);     */
8325            /* Stop translation as we may have switched the execution mode */
8326            ctx->base.is_jmp = DISAS_STOP;
8327            register_name = "TraceIBPC";
8328            goto cp0_unimplemented;
8329        case CP0_REG23__TRACEDBPC:
8330            /* PDtrace support */
8331            /* gen_helper_mtc0_tracedbpc(cpu_env, arg);     */
8332            /* Stop translation as we may have switched the execution mode */
8333            ctx->base.is_jmp = DISAS_STOP;
8334            register_name = "TraceDBPC";
8335            goto cp0_unimplemented;
8336        default:
8337            goto cp0_unimplemented;
8338        }
8339        break;
8340    case CP0_REGISTER_24:
8341        switch (sel) {
8342        case CP0_REG24__DEPC:
8343            /* EJTAG support */
8344            tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_DEPC));
8345            register_name = "DEPC";
8346            break;
8347        default:
8348            goto cp0_unimplemented;
8349        }
8350        break;
8351    case CP0_REGISTER_25:
8352        switch (sel) {
8353        case CP0_REG25__PERFCTL0:
8354            gen_helper_mtc0_performance0(cpu_env, arg);
8355            register_name = "Performance0";
8356            break;
8357        case CP0_REG25__PERFCNT0:
8358            /* gen_helper_mtc0_performance1(arg); */
8359            register_name = "Performance1";
8360            goto cp0_unimplemented;
8361        case CP0_REG25__PERFCTL1:
8362            /* gen_helper_mtc0_performance2(arg); */
8363            register_name = "Performance2";
8364            goto cp0_unimplemented;
8365        case CP0_REG25__PERFCNT1:
8366            /* gen_helper_mtc0_performance3(arg); */
8367            register_name = "Performance3";
8368            goto cp0_unimplemented;
8369        case CP0_REG25__PERFCTL2:
8370            /* gen_helper_mtc0_performance4(arg); */
8371            register_name = "Performance4";
8372            goto cp0_unimplemented;
8373        case CP0_REG25__PERFCNT2:
8374            /* gen_helper_mtc0_performance5(arg); */
8375            register_name = "Performance5";
8376            goto cp0_unimplemented;
8377        case CP0_REG25__PERFCTL3:
8378            /* gen_helper_mtc0_performance6(arg); */
8379            register_name = "Performance6";
8380            goto cp0_unimplemented;
8381        case CP0_REG25__PERFCNT3:
8382            /* gen_helper_mtc0_performance7(arg); */
8383            register_name = "Performance7";
8384            goto cp0_unimplemented;
8385        default:
8386            goto cp0_unimplemented;
8387        }
8388       break;
8389    case CP0_REGISTER_26:
8390        switch (sel) {
8391        case CP0_REG26__ERRCTL:
8392            gen_helper_mtc0_errctl(cpu_env, arg);
8393            ctx->base.is_jmp = DISAS_STOP;
8394            register_name = "ErrCtl";
8395            break;
8396        default:
8397            goto cp0_unimplemented;
8398        }
8399        break;
8400    case CP0_REGISTER_27:
8401        switch (sel) {
8402        case CP0_REG27__CACHERR:
8403            /* ignored */
8404            register_name = "CacheErr";
8405            break;
8406        default:
8407            goto cp0_unimplemented;
8408        }
8409       break;
8410    case CP0_REGISTER_28:
8411        switch (sel) {
8412        case CP0_REG28__TAGLO:
8413        case CP0_REG28__TAGLO1:
8414        case CP0_REG28__TAGLO2:
8415        case CP0_REG28__TAGLO3:
8416            gen_helper_mtc0_taglo(cpu_env, arg);
8417            register_name = "TagLo";
8418            break;
8419        case CP0_REG28__DATALO:
8420        case CP0_REG28__DATALO1:
8421        case CP0_REG28__DATALO2:
8422        case CP0_REG28__DATALO3:
8423            gen_helper_mtc0_datalo(cpu_env, arg);
8424            register_name = "DataLo";
8425            break;
8426        default:
8427            goto cp0_unimplemented;
8428        }
8429        break;
8430    case CP0_REGISTER_29:
8431        switch (sel) {
8432        case CP0_REG29__TAGHI:
8433        case CP0_REG29__TAGHI1:
8434        case CP0_REG29__TAGHI2:
8435        case CP0_REG29__TAGHI3:
8436            gen_helper_mtc0_taghi(cpu_env, arg);
8437            register_name = "TagHi";
8438            break;
8439        case CP0_REG29__DATAHI:
8440        case CP0_REG29__DATAHI1:
8441        case CP0_REG29__DATAHI2:
8442        case CP0_REG29__DATAHI3:
8443            gen_helper_mtc0_datahi(cpu_env, arg);
8444            register_name = "DataHi";
8445            break;
8446        default:
8447            register_name = "invalid sel";
8448            goto cp0_unimplemented;
8449        }
8450       break;
8451    case CP0_REGISTER_30:
8452        switch (sel) {
8453        case CP0_REG30__ERROREPC:
8454            tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_ErrorEPC));
8455            register_name = "ErrorEPC";
8456            break;
8457        default:
8458            goto cp0_unimplemented;
8459        }
8460        break;
8461    case CP0_REGISTER_31:
8462        switch (sel) {
8463        case CP0_REG31__DESAVE:
8464            /* EJTAG support */
8465            gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_DESAVE));
8466            register_name = "DESAVE";
8467            break;
8468        case CP0_REG31__KSCRATCH1:
8469        case CP0_REG31__KSCRATCH2:
8470        case CP0_REG31__KSCRATCH3:
8471        case CP0_REG31__KSCRATCH4:
8472        case CP0_REG31__KSCRATCH5:
8473        case CP0_REG31__KSCRATCH6:
8474            CP0_CHECK(ctx->kscrexist & (1 << sel));
8475            tcg_gen_st_tl(arg, cpu_env,
8476                          offsetof(CPUMIPSState, CP0_KScratch[sel - 2]));
8477            register_name = "KScratch";
8478            break;
8479        default:
8480            goto cp0_unimplemented;
8481        }
8482        break;
8483    default:
8484       goto cp0_unimplemented;
8485    }
8486    trace_mips_translate_c0("mtc0", register_name, reg, sel);
8487
8488    /* For simplicity assume that all writes can cause interrupts.  */
8489    if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
8490        /*
8491         * DISAS_STOP isn't sufficient, we need to ensure we break out of
8492         * translated code to check for pending interrupts.
8493         */
8494        gen_save_pc(ctx->base.pc_next + 4);
8495        ctx->base.is_jmp = DISAS_EXIT;
8496    }
8497    return;
8498
8499cp0_unimplemented:
8500    qemu_log_mask(LOG_UNIMP, "mtc0 %s (reg %d sel %d)\n",
8501                  register_name, reg, sel);
8502}
8503
8504#if defined(TARGET_MIPS64)
8505static void gen_dmfc0(DisasContext *ctx, TCGv arg, int reg, int sel)
8506{
8507    const char *register_name = "invalid";
8508
8509    if (sel != 0) {
8510        check_insn(ctx, ISA_MIPS64);
8511    }
8512
8513    switch (reg) {
8514    case CP0_REGISTER_00:
8515        switch (sel) {
8516        case CP0_REG00__INDEX:
8517            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Index));
8518            register_name = "Index";
8519            break;
8520        case CP0_REG00__MVPCONTROL:
8521            CP0_CHECK(ctx->insn_flags & ASE_MT);
8522            gen_helper_mfc0_mvpcontrol(arg, cpu_env);
8523            register_name = "MVPControl";
8524            break;
8525        case CP0_REG00__MVPCONF0:
8526            CP0_CHECK(ctx->insn_flags & ASE_MT);
8527            gen_helper_mfc0_mvpconf0(arg, cpu_env);
8528            register_name = "MVPConf0";
8529            break;
8530        case CP0_REG00__MVPCONF1:
8531            CP0_CHECK(ctx->insn_flags & ASE_MT);
8532            gen_helper_mfc0_mvpconf1(arg, cpu_env);
8533            register_name = "MVPConf1";
8534            break;
8535        case CP0_REG00__VPCONTROL:
8536            CP0_CHECK(ctx->vp);
8537            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPControl));
8538            register_name = "VPControl";
8539            break;
8540        default:
8541            goto cp0_unimplemented;
8542        }
8543        break;
8544    case CP0_REGISTER_01:
8545        switch (sel) {
8546        case CP0_REG01__RANDOM:
8547            CP0_CHECK(!(ctx->insn_flags & ISA_MIPS32R6));
8548            gen_helper_mfc0_random(arg, cpu_env);
8549            register_name = "Random";
8550            break;
8551        case CP0_REG01__VPECONTROL:
8552            CP0_CHECK(ctx->insn_flags & ASE_MT);
8553            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEControl));
8554            register_name = "VPEControl";
8555            break;
8556        case CP0_REG01__VPECONF0:
8557            CP0_CHECK(ctx->insn_flags & ASE_MT);
8558            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf0));
8559            register_name = "VPEConf0";
8560            break;
8561        case CP0_REG01__VPECONF1:
8562            CP0_CHECK(ctx->insn_flags & ASE_MT);
8563            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf1));
8564            register_name = "VPEConf1";
8565            break;
8566        case CP0_REG01__YQMASK:
8567            CP0_CHECK(ctx->insn_flags & ASE_MT);
8568            tcg_gen_ld_tl(arg, cpu_env,
8569                          offsetof(CPUMIPSState, CP0_YQMask));
8570            register_name = "YQMask";
8571            break;
8572        case CP0_REG01__VPESCHEDULE:
8573            CP0_CHECK(ctx->insn_flags & ASE_MT);
8574            tcg_gen_ld_tl(arg, cpu_env,
8575                          offsetof(CPUMIPSState, CP0_VPESchedule));
8576            register_name = "VPESchedule";
8577            break;
8578        case CP0_REG01__VPESCHEFBACK:
8579            CP0_CHECK(ctx->insn_flags & ASE_MT);
8580            tcg_gen_ld_tl(arg, cpu_env,
8581                          offsetof(CPUMIPSState, CP0_VPEScheFBack));
8582            register_name = "VPEScheFBack";
8583            break;
8584        case CP0_REG01__VPEOPT:
8585            CP0_CHECK(ctx->insn_flags & ASE_MT);
8586            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEOpt));
8587            register_name = "VPEOpt";
8588            break;
8589        default:
8590            goto cp0_unimplemented;
8591        }
8592        break;
8593    case CP0_REGISTER_02:
8594        switch (sel) {
8595        case CP0_REG02__ENTRYLO0:
8596            tcg_gen_ld_tl(arg, cpu_env,
8597                          offsetof(CPUMIPSState, CP0_EntryLo0));
8598            register_name = "EntryLo0";
8599            break;
8600        case CP0_REG02__TCSTATUS:
8601            CP0_CHECK(ctx->insn_flags & ASE_MT);
8602            gen_helper_mfc0_tcstatus(arg, cpu_env);
8603            register_name = "TCStatus";
8604            break;
8605        case CP0_REG02__TCBIND:
8606            CP0_CHECK(ctx->insn_flags & ASE_MT);
8607            gen_helper_mfc0_tcbind(arg, cpu_env);
8608            register_name = "TCBind";
8609            break;
8610        case CP0_REG02__TCRESTART:
8611            CP0_CHECK(ctx->insn_flags & ASE_MT);
8612            gen_helper_dmfc0_tcrestart(arg, cpu_env);
8613            register_name = "TCRestart";
8614            break;
8615        case CP0_REG02__TCHALT:
8616            CP0_CHECK(ctx->insn_flags & ASE_MT);
8617            gen_helper_dmfc0_tchalt(arg, cpu_env);
8618            register_name = "TCHalt";
8619            break;
8620        case CP0_REG02__TCCONTEXT:
8621            CP0_CHECK(ctx->insn_flags & ASE_MT);
8622            gen_helper_dmfc0_tccontext(arg, cpu_env);
8623            register_name = "TCContext";
8624            break;
8625        case CP0_REG02__TCSCHEDULE:
8626            CP0_CHECK(ctx->insn_flags & ASE_MT);
8627            gen_helper_dmfc0_tcschedule(arg, cpu_env);
8628            register_name = "TCSchedule";
8629            break;
8630        case CP0_REG02__TCSCHEFBACK:
8631            CP0_CHECK(ctx->insn_flags & ASE_MT);
8632            gen_helper_dmfc0_tcschefback(arg, cpu_env);
8633            register_name = "TCScheFBack";
8634            break;
8635        default:
8636            goto cp0_unimplemented;
8637        }
8638        break;
8639    case CP0_REGISTER_03:
8640        switch (sel) {
8641        case CP0_REG03__ENTRYLO1:
8642            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryLo1));
8643            register_name = "EntryLo1";
8644            break;
8645        case CP0_REG03__GLOBALNUM:
8646            CP0_CHECK(ctx->vp);
8647            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_GlobalNumber));
8648            register_name = "GlobalNumber";
8649            break;
8650        default:
8651            goto cp0_unimplemented;
8652        }
8653        break;
8654    case CP0_REGISTER_04:
8655        switch (sel) {
8656        case CP0_REG04__CONTEXT:
8657            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_Context));
8658            register_name = "Context";
8659            break;
8660        case CP0_REG04__CONTEXTCONFIG:
8661            /* SmartMIPS ASE */
8662            /* gen_helper_dmfc0_contextconfig(arg); */
8663            register_name = "ContextConfig";
8664            goto cp0_unimplemented;
8665        case CP0_REG04__USERLOCAL:
8666            CP0_CHECK(ctx->ulri);
8667            tcg_gen_ld_tl(arg, cpu_env,
8668                          offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
8669            register_name = "UserLocal";
8670            break;
8671        case CP0_REG04__MMID:
8672            CP0_CHECK(ctx->mi);
8673            gen_helper_mtc0_memorymapid(cpu_env, arg);
8674            register_name = "MMID";
8675            break;
8676        default:
8677            goto cp0_unimplemented;
8678        }
8679        break;
8680    case CP0_REGISTER_05:
8681        switch (sel) {
8682        case CP0_REG05__PAGEMASK:
8683            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageMask));
8684            register_name = "PageMask";
8685            break;
8686        case CP0_REG05__PAGEGRAIN:
8687            check_insn(ctx, ISA_MIPS32R2);
8688            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageGrain));
8689            register_name = "PageGrain";
8690            break;
8691        case CP0_REG05__SEGCTL0:
8692            CP0_CHECK(ctx->sc);
8693            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_SegCtl0));
8694            register_name = "SegCtl0";
8695            break;
8696        case CP0_REG05__SEGCTL1:
8697            CP0_CHECK(ctx->sc);
8698            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_SegCtl1));
8699            register_name = "SegCtl1";
8700            break;
8701        case CP0_REG05__SEGCTL2:
8702            CP0_CHECK(ctx->sc);
8703            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_SegCtl2));
8704            register_name = "SegCtl2";
8705            break;
8706        case CP0_REG05__PWBASE:
8707            check_pw(ctx);
8708            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_PWBase));
8709            register_name = "PWBase";
8710            break;
8711        case CP0_REG05__PWFIELD:
8712            check_pw(ctx);
8713            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_PWField));
8714            register_name = "PWField";
8715            break;
8716        case CP0_REG05__PWSIZE:
8717            check_pw(ctx);
8718            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_PWSize));
8719            register_name = "PWSize";
8720            break;
8721        default:
8722            goto cp0_unimplemented;
8723        }
8724        break;
8725    case CP0_REGISTER_06:
8726        switch (sel) {
8727        case CP0_REG06__WIRED:
8728            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Wired));
8729            register_name = "Wired";
8730            break;
8731        case CP0_REG06__SRSCONF0:
8732            check_insn(ctx, ISA_MIPS32R2);
8733            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf0));
8734            register_name = "SRSConf0";
8735            break;
8736        case CP0_REG06__SRSCONF1:
8737            check_insn(ctx, ISA_MIPS32R2);
8738            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf1));
8739            register_name = "SRSConf1";
8740            break;
8741        case CP0_REG06__SRSCONF2:
8742            check_insn(ctx, ISA_MIPS32R2);
8743            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf2));
8744            register_name = "SRSConf2";
8745            break;
8746        case CP0_REG06__SRSCONF3:
8747            check_insn(ctx, ISA_MIPS32R2);
8748            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf3));
8749            register_name = "SRSConf3";
8750            break;
8751        case CP0_REG06__SRSCONF4:
8752            check_insn(ctx, ISA_MIPS32R2);
8753            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf4));
8754            register_name = "SRSConf4";
8755            break;
8756        case CP0_REG06__PWCTL:
8757            check_pw(ctx);
8758            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PWCtl));
8759            register_name = "PWCtl";
8760            break;
8761        default:
8762            goto cp0_unimplemented;
8763        }
8764        break;
8765    case CP0_REGISTER_07:
8766        switch (sel) {
8767        case CP0_REG07__HWRENA:
8768            check_insn(ctx, ISA_MIPS32R2);
8769            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_HWREna));
8770            register_name = "HWREna";
8771            break;
8772        default:
8773            goto cp0_unimplemented;
8774        }
8775        break;
8776    case CP0_REGISTER_08:
8777        switch (sel) {
8778        case CP0_REG08__BADVADDR:
8779            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_BadVAddr));
8780            register_name = "BadVAddr";
8781            break;
8782        case CP0_REG08__BADINSTR:
8783            CP0_CHECK(ctx->bi);
8784            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_BadInstr));
8785            register_name = "BadInstr";
8786            break;
8787        case CP0_REG08__BADINSTRP:
8788            CP0_CHECK(ctx->bp);
8789            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_BadInstrP));
8790            register_name = "BadInstrP";
8791            break;
8792        case CP0_REG08__BADINSTRX:
8793            CP0_CHECK(ctx->bi);
8794            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_BadInstrX));
8795            tcg_gen_andi_tl(arg, arg, ~0xffff);
8796            register_name = "BadInstrX";
8797            break;
8798        default:
8799            goto cp0_unimplemented;
8800        }
8801        break;
8802    case CP0_REGISTER_09:
8803        switch (sel) {
8804        case CP0_REG09__COUNT:
8805            /* Mark as an IO operation because we read the time.  */
8806            if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
8807                gen_io_start();
8808            }
8809            gen_helper_mfc0_count(arg, cpu_env);
8810            /*
8811             * Break the TB to be able to take timer interrupts immediately
8812             * after reading count. DISAS_STOP isn't sufficient, we need to
8813             * ensure we break completely out of translated code.
8814             */
8815            gen_save_pc(ctx->base.pc_next + 4);
8816            ctx->base.is_jmp = DISAS_EXIT;
8817            register_name = "Count";
8818            break;
8819        case CP0_REG09__SAARI:
8820            CP0_CHECK(ctx->saar);
8821            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SAARI));
8822            register_name = "SAARI";
8823            break;
8824        case CP0_REG09__SAAR:
8825            CP0_CHECK(ctx->saar);
8826            gen_helper_dmfc0_saar(arg, cpu_env);
8827            register_name = "SAAR";
8828            break;
8829        default:
8830            goto cp0_unimplemented;
8831        }
8832        break;
8833    case CP0_REGISTER_10:
8834        switch (sel) {
8835        case CP0_REG10__ENTRYHI:
8836            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryHi));
8837            register_name = "EntryHi";
8838            break;
8839        default:
8840            goto cp0_unimplemented;
8841        }
8842        break;
8843    case CP0_REGISTER_11:
8844        switch (sel) {
8845        case CP0_REG11__COMPARE:
8846            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Compare));
8847            register_name = "Compare";
8848            break;
8849        /* 6,7 are implementation dependent */
8850        default:
8851            goto cp0_unimplemented;
8852        }
8853        break;
8854    case CP0_REGISTER_12:
8855        switch (sel) {
8856        case CP0_REG12__STATUS:
8857            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Status));
8858            register_name = "Status";
8859            break;
8860        case CP0_REG12__INTCTL:
8861            check_insn(ctx, ISA_MIPS32R2);
8862            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_IntCtl));
8863            register_name = "IntCtl";
8864            break;
8865        case CP0_REG12__SRSCTL:
8866            check_insn(ctx, ISA_MIPS32R2);
8867            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSCtl));
8868            register_name = "SRSCtl";
8869            break;
8870        case CP0_REG12__SRSMAP:
8871            check_insn(ctx, ISA_MIPS32R2);
8872            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSMap));
8873            register_name = "SRSMap";
8874            break;
8875        default:
8876            goto cp0_unimplemented;
8877        }
8878        break;
8879    case CP0_REGISTER_13:
8880        switch (sel) {
8881        case CP0_REG13__CAUSE:
8882            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Cause));
8883            register_name = "Cause";
8884            break;
8885        default:
8886            goto cp0_unimplemented;
8887        }
8888        break;
8889    case CP0_REGISTER_14:
8890        switch (sel) {
8891        case CP0_REG14__EPC:
8892            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EPC));
8893            register_name = "EPC";
8894            break;
8895        default:
8896            goto cp0_unimplemented;
8897        }
8898        break;
8899    case CP0_REGISTER_15:
8900        switch (sel) {
8901        case CP0_REG15__PRID:
8902            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PRid));
8903            register_name = "PRid";
8904            break;
8905        case CP0_REG15__EBASE:
8906            check_insn(ctx, ISA_MIPS32R2);
8907            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EBase));
8908            register_name = "EBase";
8909            break;
8910        case CP0_REG15__CMGCRBASE:
8911            check_insn(ctx, ISA_MIPS32R2);
8912            CP0_CHECK(ctx->cmgcr);
8913            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_CMGCRBase));
8914            register_name = "CMGCRBase";
8915            break;
8916        default:
8917            goto cp0_unimplemented;
8918        }
8919        break;
8920    case CP0_REGISTER_16:
8921        switch (sel) {
8922        case CP0_REG16__CONFIG:
8923            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config0));
8924            register_name = "Config";
8925            break;
8926        case CP0_REG16__CONFIG1:
8927            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config1));
8928            register_name = "Config1";
8929            break;
8930        case CP0_REG16__CONFIG2:
8931            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config2));
8932            register_name = "Config2";
8933            break;
8934        case CP0_REG16__CONFIG3:
8935            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config3));
8936            register_name = "Config3";
8937            break;
8938        case CP0_REG16__CONFIG4:
8939            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config4));
8940            register_name = "Config4";
8941            break;
8942        case CP0_REG16__CONFIG5:
8943            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config5));
8944            register_name = "Config5";
8945            break;
8946        /* 6,7 are implementation dependent */
8947        case CP0_REG16__CONFIG6:
8948            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config6));
8949            register_name = "Config6";
8950            break;
8951        case CP0_REG16__CONFIG7:
8952            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config7));
8953            register_name = "Config7";
8954            break;
8955        default:
8956            goto cp0_unimplemented;
8957        }
8958        break;
8959    case CP0_REGISTER_17:
8960        switch (sel) {
8961        case CP0_REG17__LLADDR:
8962            gen_helper_dmfc0_lladdr(arg, cpu_env);
8963            register_name = "LLAddr";
8964            break;
8965        case CP0_REG17__MAAR:
8966            CP0_CHECK(ctx->mrp);
8967            gen_helper_dmfc0_maar(arg, cpu_env);
8968            register_name = "MAAR";
8969            break;
8970        case CP0_REG17__MAARI:
8971            CP0_CHECK(ctx->mrp);
8972            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_MAARI));
8973            register_name = "MAARI";
8974            break;
8975        default:
8976            goto cp0_unimplemented;
8977        }
8978        break;
8979    case CP0_REGISTER_18:
8980        switch (sel) {
8981        case CP0_REG18__WATCHLO0:
8982        case CP0_REG18__WATCHLO1:
8983        case CP0_REG18__WATCHLO2:
8984        case CP0_REG18__WATCHLO3:
8985        case CP0_REG18__WATCHLO4:
8986        case CP0_REG18__WATCHLO5:
8987        case CP0_REG18__WATCHLO6:
8988        case CP0_REG18__WATCHLO7:
8989            CP0_CHECK(ctx->CP0_Config1 & (1 << CP0C1_WR));
8990            gen_helper_1e0i(dmfc0_watchlo, arg, sel);
8991            register_name = "WatchLo";
8992            break;
8993        default:
8994            goto cp0_unimplemented;
8995        }
8996        break;
8997    case CP0_REGISTER_19:
8998        switch (sel) {
8999        case CP0_REG19__WATCHHI0:
9000        case CP0_REG19__WATCHHI1:
9001        case CP0_REG19__WATCHHI2:
9002        case CP0_REG19__WATCHHI3:
9003        case CP0_REG19__WATCHHI4:
9004        case CP0_REG19__WATCHHI5:
9005        case CP0_REG19__WATCHHI6:
9006        case CP0_REG19__WATCHHI7:
9007            CP0_CHECK(ctx->CP0_Config1 & (1 << CP0C1_WR));
9008            gen_helper_1e0i(dmfc0_watchhi, arg, sel);
9009            register_name = "WatchHi";
9010            break;
9011        default:
9012            goto cp0_unimplemented;
9013        }
9014        break;
9015    case CP0_REGISTER_20:
9016        switch (sel) {
9017        case CP0_REG20__XCONTEXT:
9018            check_insn(ctx, ISA_MIPS3);
9019            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_XContext));
9020            register_name = "XContext";
9021            break;
9022        default:
9023            goto cp0_unimplemented;
9024        }
9025        break;
9026    case CP0_REGISTER_21:
9027        /* Officially reserved, but sel 0 is used for R1x000 framemask */
9028        CP0_CHECK(!(ctx->insn_flags & ISA_MIPS32R6));
9029        switch (sel) {
9030        case 0:
9031            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Framemask));
9032            register_name = "Framemask";
9033            break;
9034        default:
9035            goto cp0_unimplemented;
9036        }
9037        break;
9038    case CP0_REGISTER_22:
9039        tcg_gen_movi_tl(arg, 0); /* unimplemented */
9040        register_name = "'Diagnostic"; /* implementation dependent */
9041        break;
9042    case CP0_REGISTER_23:
9043        switch (sel) {
9044        case CP0_REG23__DEBUG:
9045            gen_helper_mfc0_debug(arg, cpu_env); /* EJTAG support */
9046            register_name = "Debug";
9047            break;
9048        case CP0_REG23__TRACECONTROL:
9049            /* PDtrace support */
9050            /* gen_helper_dmfc0_tracecontrol(arg, cpu_env);  */
9051            register_name = "TraceControl";
9052            goto cp0_unimplemented;
9053        case CP0_REG23__TRACECONTROL2:
9054            /* PDtrace support */
9055            /* gen_helper_dmfc0_tracecontrol2(arg, cpu_env); */
9056            register_name = "TraceControl2";
9057            goto cp0_unimplemented;
9058        case CP0_REG23__USERTRACEDATA1:
9059            /* PDtrace support */
9060            /* gen_helper_dmfc0_usertracedata1(arg, cpu_env);*/
9061            register_name = "UserTraceData1";
9062            goto cp0_unimplemented;
9063        case CP0_REG23__TRACEIBPC:
9064            /* PDtrace support */
9065            /* gen_helper_dmfc0_traceibpc(arg, cpu_env);     */
9066            register_name = "TraceIBPC";
9067            goto cp0_unimplemented;
9068        case CP0_REG23__TRACEDBPC:
9069            /* PDtrace support */
9070            /* gen_helper_dmfc0_tracedbpc(arg, cpu_env);     */
9071            register_name = "TraceDBPC";
9072            goto cp0_unimplemented;
9073        default:
9074            goto cp0_unimplemented;
9075        }
9076        break;
9077    case CP0_REGISTER_24:
9078        switch (sel) {
9079        case CP0_REG24__DEPC:
9080            /* EJTAG support */
9081            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_DEPC));
9082            register_name = "DEPC";
9083            break;
9084        default:
9085            goto cp0_unimplemented;
9086        }
9087        break;
9088    case CP0_REGISTER_25:
9089        switch (sel) {
9090        case CP0_REG25__PERFCTL0:
9091            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Performance0));
9092            register_name = "Performance0";
9093            break;
9094        case CP0_REG25__PERFCNT0:
9095            /* gen_helper_dmfc0_performance1(arg); */
9096            register_name = "Performance1";
9097            goto cp0_unimplemented;
9098        case CP0_REG25__PERFCTL1:
9099            /* gen_helper_dmfc0_performance2(arg); */
9100            register_name = "Performance2";
9101            goto cp0_unimplemented;
9102        case CP0_REG25__PERFCNT1:
9103            /* gen_helper_dmfc0_performance3(arg); */
9104            register_name = "Performance3";
9105            goto cp0_unimplemented;
9106        case CP0_REG25__PERFCTL2:
9107            /* gen_helper_dmfc0_performance4(arg); */
9108            register_name = "Performance4";
9109            goto cp0_unimplemented;
9110        case CP0_REG25__PERFCNT2:
9111            /* gen_helper_dmfc0_performance5(arg); */
9112            register_name = "Performance5";
9113            goto cp0_unimplemented;
9114        case CP0_REG25__PERFCTL3:
9115            /* gen_helper_dmfc0_performance6(arg); */
9116            register_name = "Performance6";
9117            goto cp0_unimplemented;
9118        case CP0_REG25__PERFCNT3:
9119            /* gen_helper_dmfc0_performance7(arg); */
9120            register_name = "Performance7";
9121            goto cp0_unimplemented;
9122        default:
9123            goto cp0_unimplemented;
9124        }
9125        break;
9126    case CP0_REGISTER_26:
9127        switch (sel) {
9128        case CP0_REG26__ERRCTL:
9129            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_ErrCtl));
9130            register_name = "ErrCtl";
9131            break;
9132        default:
9133            goto cp0_unimplemented;
9134        }
9135        break;
9136    case CP0_REGISTER_27:
9137        switch (sel) {
9138        /* ignored */
9139        case CP0_REG27__CACHERR:
9140            tcg_gen_movi_tl(arg, 0); /* unimplemented */
9141            register_name = "CacheErr";
9142            break;
9143        default:
9144            goto cp0_unimplemented;
9145        }
9146        break;
9147    case CP0_REGISTER_28:
9148        switch (sel) {
9149        case CP0_REG28__TAGLO:
9150        case CP0_REG28__TAGLO1:
9151        case CP0_REG28__TAGLO2:
9152        case CP0_REG28__TAGLO3:
9153            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_TagLo));
9154            register_name = "TagLo";
9155            break;
9156        case CP0_REG28__DATALO:
9157        case CP0_REG28__DATALO1:
9158        case CP0_REG28__DATALO2:
9159        case CP0_REG28__DATALO3:
9160            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataLo));
9161            register_name = "DataLo";
9162            break;
9163        default:
9164            goto cp0_unimplemented;
9165        }
9166        break;
9167    case CP0_REGISTER_29:
9168        switch (sel) {
9169        case CP0_REG29__TAGHI:
9170        case CP0_REG29__TAGHI1:
9171        case CP0_REG29__TAGHI2:
9172        case CP0_REG29__TAGHI3:
9173            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_TagHi));
9174            register_name = "TagHi";
9175            break;
9176        case CP0_REG29__DATAHI:
9177        case CP0_REG29__DATAHI1:
9178        case CP0_REG29__DATAHI2:
9179        case CP0_REG29__DATAHI3:
9180            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataHi));
9181            register_name = "DataHi";
9182            break;
9183        default:
9184            goto cp0_unimplemented;
9185        }
9186        break;
9187    case CP0_REGISTER_30:
9188        switch (sel) {
9189        case CP0_REG30__ERROREPC:
9190            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_ErrorEPC));
9191            register_name = "ErrorEPC";
9192            break;
9193        default:
9194            goto cp0_unimplemented;
9195        }
9196        break;
9197    case CP0_REGISTER_31:
9198        switch (sel) {
9199        case CP0_REG31__DESAVE:
9200            /* EJTAG support */
9201            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DESAVE));
9202            register_name = "DESAVE";
9203            break;
9204        case CP0_REG31__KSCRATCH1:
9205        case CP0_REG31__KSCRATCH2:
9206        case CP0_REG31__KSCRATCH3:
9207        case CP0_REG31__KSCRATCH4:
9208        case CP0_REG31__KSCRATCH5:
9209        case CP0_REG31__KSCRATCH6:
9210            CP0_CHECK(ctx->kscrexist & (1 << sel));
9211            tcg_gen_ld_tl(arg, cpu_env,
9212                          offsetof(CPUMIPSState, CP0_KScratch[sel - 2]));
9213            register_name = "KScratch";
9214            break;
9215        default:
9216            goto cp0_unimplemented;
9217        }
9218        break;
9219    default:
9220        goto cp0_unimplemented;
9221    }
9222    trace_mips_translate_c0("dmfc0", register_name, reg, sel);
9223    return;
9224
9225cp0_unimplemented:
9226    qemu_log_mask(LOG_UNIMP, "dmfc0 %s (reg %d sel %d)\n",
9227                  register_name, reg, sel);
9228    gen_mfc0_unimplemented(ctx, arg);
9229}
9230
9231static void gen_dmtc0(DisasContext *ctx, TCGv arg, int reg, int sel)
9232{
9233    const char *register_name = "invalid";
9234
9235    if (sel != 0) {
9236        check_insn(ctx, ISA_MIPS64);
9237    }
9238
9239    if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
9240        gen_io_start();
9241    }
9242
9243    switch (reg) {
9244    case CP0_REGISTER_00:
9245        switch (sel) {
9246        case CP0_REG00__INDEX:
9247            gen_helper_mtc0_index(cpu_env, arg);
9248            register_name = "Index";
9249            break;
9250        case CP0_REG00__MVPCONTROL:
9251            CP0_CHECK(ctx->insn_flags & ASE_MT);
9252            gen_helper_mtc0_mvpcontrol(cpu_env, arg);
9253            register_name = "MVPControl";
9254            break;
9255        case CP0_REG00__MVPCONF0:
9256            CP0_CHECK(ctx->insn_flags & ASE_MT);
9257            /* ignored */
9258            register_name = "MVPConf0";
9259            break;
9260        case CP0_REG00__MVPCONF1:
9261            CP0_CHECK(ctx->insn_flags & ASE_MT);
9262            /* ignored */
9263            register_name = "MVPConf1";
9264            break;
9265        case CP0_REG00__VPCONTROL:
9266            CP0_CHECK(ctx->vp);
9267            /* ignored */
9268            register_name = "VPControl";
9269            break;
9270        default:
9271            goto cp0_unimplemented;
9272        }
9273        break;
9274    case CP0_REGISTER_01:
9275        switch (sel) {
9276        case CP0_REG01__RANDOM:
9277            /* ignored */
9278            register_name = "Random";
9279            break;
9280        case CP0_REG01__VPECONTROL:
9281            CP0_CHECK(ctx->insn_flags & ASE_MT);
9282            gen_helper_mtc0_vpecontrol(cpu_env, arg);
9283            register_name = "VPEControl";
9284            break;
9285        case CP0_REG01__VPECONF0:
9286            CP0_CHECK(ctx->insn_flags & ASE_MT);
9287            gen_helper_mtc0_vpeconf0(cpu_env, arg);
9288            register_name = "VPEConf0";
9289            break;
9290        case CP0_REG01__VPECONF1:
9291            CP0_CHECK(ctx->insn_flags & ASE_MT);
9292            gen_helper_mtc0_vpeconf1(cpu_env, arg);
9293            register_name = "VPEConf1";
9294            break;
9295        case CP0_REG01__YQMASK:
9296            CP0_CHECK(ctx->insn_flags & ASE_MT);
9297            gen_helper_mtc0_yqmask(cpu_env, arg);
9298            register_name = "YQMask";
9299            break;
9300        case CP0_REG01__VPESCHEDULE:
9301            CP0_CHECK(ctx->insn_flags & ASE_MT);
9302            tcg_gen_st_tl(arg, cpu_env,
9303                          offsetof(CPUMIPSState, CP0_VPESchedule));
9304            register_name = "VPESchedule";
9305            break;
9306        case CP0_REG01__VPESCHEFBACK:
9307            CP0_CHECK(ctx->insn_flags & ASE_MT);
9308            tcg_gen_st_tl(arg, cpu_env,
9309                          offsetof(CPUMIPSState, CP0_VPEScheFBack));
9310            register_name = "VPEScheFBack";
9311            break;
9312        case CP0_REG01__VPEOPT:
9313            CP0_CHECK(ctx->insn_flags & ASE_MT);
9314            gen_helper_mtc0_vpeopt(cpu_env, arg);
9315            register_name = "VPEOpt";
9316            break;
9317        default:
9318            goto cp0_unimplemented;
9319        }
9320        break;
9321    case CP0_REGISTER_02:
9322        switch (sel) {
9323        case CP0_REG02__ENTRYLO0:
9324            gen_helper_dmtc0_entrylo0(cpu_env, arg);
9325            register_name = "EntryLo0";
9326            break;
9327        case CP0_REG02__TCSTATUS:
9328            CP0_CHECK(ctx->insn_flags & ASE_MT);
9329            gen_helper_mtc0_tcstatus(cpu_env, arg);
9330            register_name = "TCStatus";
9331            break;
9332        case CP0_REG02__TCBIND:
9333            CP0_CHECK(ctx->insn_flags & ASE_MT);
9334            gen_helper_mtc0_tcbind(cpu_env, arg);
9335            register_name = "TCBind";
9336            break;
9337        case CP0_REG02__TCRESTART:
9338            CP0_CHECK(ctx->insn_flags & ASE_MT);
9339            gen_helper_mtc0_tcrestart(cpu_env, arg);
9340            register_name = "TCRestart";
9341            break;
9342        case CP0_REG02__TCHALT:
9343            CP0_CHECK(ctx->insn_flags & ASE_MT);
9344            gen_helper_mtc0_tchalt(cpu_env, arg);
9345            register_name = "TCHalt";
9346            break;
9347        case CP0_REG02__TCCONTEXT:
9348            CP0_CHECK(ctx->insn_flags & ASE_MT);
9349            gen_helper_mtc0_tccontext(cpu_env, arg);
9350            register_name = "TCContext";
9351            break;
9352        case CP0_REG02__TCSCHEDULE:
9353            CP0_CHECK(ctx->insn_flags & ASE_MT);
9354            gen_helper_mtc0_tcschedule(cpu_env, arg);
9355            register_name = "TCSchedule";
9356            break;
9357        case CP0_REG02__TCSCHEFBACK:
9358            CP0_CHECK(ctx->insn_flags & ASE_MT);
9359            gen_helper_mtc0_tcschefback(cpu_env, arg);
9360            register_name = "TCScheFBack";
9361            break;
9362        default:
9363            goto cp0_unimplemented;
9364        }
9365        break;
9366    case CP0_REGISTER_03:
9367        switch (sel) {
9368        case CP0_REG03__ENTRYLO1:
9369            gen_helper_dmtc0_entrylo1(cpu_env, arg);
9370            register_name = "EntryLo1";
9371            break;
9372        case CP0_REG03__GLOBALNUM:
9373            CP0_CHECK(ctx->vp);
9374            /* ignored */
9375            register_name = "GlobalNumber";
9376            break;
9377        default:
9378            goto cp0_unimplemented;
9379        }
9380        break;
9381    case CP0_REGISTER_04:
9382        switch (sel) {
9383        case CP0_REG04__CONTEXT:
9384            gen_helper_mtc0_context(cpu_env, arg);
9385            register_name = "Context";
9386            break;
9387        case CP0_REG04__CONTEXTCONFIG:
9388            /* SmartMIPS ASE */
9389            /* gen_helper_dmtc0_contextconfig(arg); */
9390            register_name = "ContextConfig";
9391            goto cp0_unimplemented;
9392        case CP0_REG04__USERLOCAL:
9393            CP0_CHECK(ctx->ulri);
9394            tcg_gen_st_tl(arg, cpu_env,
9395                          offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
9396            register_name = "UserLocal";
9397            break;
9398        case CP0_REG04__MMID:
9399            CP0_CHECK(ctx->mi);
9400            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_MemoryMapID));
9401            register_name = "MMID";
9402            break;
9403        default:
9404            goto cp0_unimplemented;
9405        }
9406        break;
9407    case CP0_REGISTER_05:
9408        switch (sel) {
9409        case CP0_REG05__PAGEMASK:
9410            gen_helper_mtc0_pagemask(cpu_env, arg);
9411            register_name = "PageMask";
9412            break;
9413        case CP0_REG05__PAGEGRAIN:
9414            check_insn(ctx, ISA_MIPS32R2);
9415            gen_helper_mtc0_pagegrain(cpu_env, arg);
9416            register_name = "PageGrain";
9417            break;
9418        case CP0_REG05__SEGCTL0:
9419            CP0_CHECK(ctx->sc);
9420            gen_helper_mtc0_segctl0(cpu_env, arg);
9421            register_name = "SegCtl0";
9422            break;
9423        case CP0_REG05__SEGCTL1:
9424            CP0_CHECK(ctx->sc);
9425            gen_helper_mtc0_segctl1(cpu_env, arg);
9426            register_name = "SegCtl1";
9427            break;
9428        case CP0_REG05__SEGCTL2:
9429            CP0_CHECK(ctx->sc);
9430            gen_helper_mtc0_segctl2(cpu_env, arg);
9431            register_name = "SegCtl2";
9432            break;
9433        case CP0_REG05__PWBASE:
9434            check_pw(ctx);
9435            tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_PWBase));
9436            register_name = "PWBase";
9437            break;
9438        case CP0_REG05__PWFIELD:
9439            check_pw(ctx);
9440            gen_helper_mtc0_pwfield(cpu_env, arg);
9441            register_name = "PWField";
9442            break;
9443        case CP0_REG05__PWSIZE:
9444            check_pw(ctx);
9445            gen_helper_mtc0_pwsize(cpu_env, arg);
9446            register_name = "PWSize";
9447            break;
9448        default:
9449            goto cp0_unimplemented;
9450        }
9451        break;
9452    case CP0_REGISTER_06:
9453        switch (sel) {
9454        case CP0_REG06__WIRED:
9455            gen_helper_mtc0_wired(cpu_env, arg);
9456            register_name = "Wired";
9457            break;
9458        case CP0_REG06__SRSCONF0:
9459            check_insn(ctx, ISA_MIPS32R2);
9460            gen_helper_mtc0_srsconf0(cpu_env, arg);
9461            register_name = "SRSConf0";
9462            break;
9463        case CP0_REG06__SRSCONF1:
9464            check_insn(ctx, ISA_MIPS32R2);
9465            gen_helper_mtc0_srsconf1(cpu_env, arg);
9466            register_name = "SRSConf1";
9467            break;
9468        case CP0_REG06__SRSCONF2:
9469            check_insn(ctx, ISA_MIPS32R2);
9470            gen_helper_mtc0_srsconf2(cpu_env, arg);
9471            register_name = "SRSConf2";
9472            break;
9473        case CP0_REG06__SRSCONF3:
9474            check_insn(ctx, ISA_MIPS32R2);
9475            gen_helper_mtc0_srsconf3(cpu_env, arg);
9476            register_name = "SRSConf3";
9477            break;
9478        case CP0_REG06__SRSCONF4:
9479            check_insn(ctx, ISA_MIPS32R2);
9480            gen_helper_mtc0_srsconf4(cpu_env, arg);
9481            register_name = "SRSConf4";
9482            break;
9483        case CP0_REG06__PWCTL:
9484            check_pw(ctx);
9485            gen_helper_mtc0_pwctl(cpu_env, arg);
9486            register_name = "PWCtl";
9487            break;
9488        default:
9489            goto cp0_unimplemented;
9490        }
9491        break;
9492    case CP0_REGISTER_07:
9493        switch (sel) {
9494        case CP0_REG07__HWRENA:
9495            check_insn(ctx, ISA_MIPS32R2);
9496            gen_helper_mtc0_hwrena(cpu_env, arg);
9497            ctx->base.is_jmp = DISAS_STOP;
9498            register_name = "HWREna";
9499            break;
9500        default:
9501            goto cp0_unimplemented;
9502        }
9503        break;
9504    case CP0_REGISTER_08:
9505        switch (sel) {
9506        case CP0_REG08__BADVADDR:
9507            /* ignored */
9508            register_name = "BadVAddr";
9509            break;
9510        case CP0_REG08__BADINSTR:
9511            /* ignored */
9512            register_name = "BadInstr";
9513            break;
9514        case CP0_REG08__BADINSTRP:
9515            /* ignored */
9516            register_name = "BadInstrP";
9517            break;
9518        case CP0_REG08__BADINSTRX:
9519            /* ignored */
9520            register_name = "BadInstrX";
9521            break;
9522        default:
9523            goto cp0_unimplemented;
9524        }
9525        break;
9526    case CP0_REGISTER_09:
9527        switch (sel) {
9528        case CP0_REG09__COUNT:
9529            gen_helper_mtc0_count(cpu_env, arg);
9530            register_name = "Count";
9531            break;
9532        case CP0_REG09__SAARI:
9533            CP0_CHECK(ctx->saar);
9534            gen_helper_mtc0_saari(cpu_env, arg);
9535            register_name = "SAARI";
9536            break;
9537        case CP0_REG09__SAAR:
9538            CP0_CHECK(ctx->saar);
9539            gen_helper_mtc0_saar(cpu_env, arg);
9540            register_name = "SAAR";
9541            break;
9542        default:
9543            goto cp0_unimplemented;
9544        }
9545        /* Stop translation as we may have switched the execution mode */
9546        ctx->base.is_jmp = DISAS_STOP;
9547        break;
9548    case CP0_REGISTER_10:
9549        switch (sel) {
9550        case CP0_REG10__ENTRYHI:
9551            gen_helper_mtc0_entryhi(cpu_env, arg);
9552            register_name = "EntryHi";
9553            break;
9554        default:
9555            goto cp0_unimplemented;
9556        }
9557        break;
9558    case CP0_REGISTER_11:
9559        switch (sel) {
9560        case CP0_REG11__COMPARE:
9561            gen_helper_mtc0_compare(cpu_env, arg);
9562            register_name = "Compare";
9563            break;
9564        /* 6,7 are implementation dependent */
9565        default:
9566            goto cp0_unimplemented;
9567        }
9568        /* Stop translation as we may have switched the execution mode */
9569        ctx->base.is_jmp = DISAS_STOP;
9570        break;
9571    case CP0_REGISTER_12:
9572        switch (sel) {
9573        case CP0_REG12__STATUS:
9574            save_cpu_state(ctx, 1);
9575            gen_helper_mtc0_status(cpu_env, arg);
9576            /* DISAS_STOP isn't good enough here, hflags may have changed. */
9577            gen_save_pc(ctx->base.pc_next + 4);
9578            ctx->base.is_jmp = DISAS_EXIT;
9579            register_name = "Status";
9580            break;
9581        case CP0_REG12__INTCTL:
9582            check_insn(ctx, ISA_MIPS32R2);
9583            gen_helper_mtc0_intctl(cpu_env, arg);
9584            /* Stop translation as we may have switched the execution mode */
9585            ctx->base.is_jmp = DISAS_STOP;
9586            register_name = "IntCtl";
9587            break;
9588        case CP0_REG12__SRSCTL:
9589            check_insn(ctx, ISA_MIPS32R2);
9590            gen_helper_mtc0_srsctl(cpu_env, arg);
9591            /* Stop translation as we may have switched the execution mode */
9592            ctx->base.is_jmp = DISAS_STOP;
9593            register_name = "SRSCtl";
9594            break;
9595        case CP0_REG12__SRSMAP:
9596            check_insn(ctx, ISA_MIPS32R2);
9597            gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_SRSMap));
9598            /* Stop translation as we may have switched the execution mode */
9599            ctx->base.is_jmp = DISAS_STOP;
9600            register_name = "SRSMap";
9601            break;
9602        default:
9603            goto cp0_unimplemented;
9604        }
9605        break;
9606    case CP0_REGISTER_13:
9607        switch (sel) {
9608        case CP0_REG13__CAUSE:
9609            save_cpu_state(ctx, 1);
9610            gen_helper_mtc0_cause(cpu_env, arg);
9611            /*
9612             * Stop translation as we may have triggered an interrupt.
9613             * DISAS_STOP isn't sufficient, we need to ensure we break out of
9614             * translated code to check for pending interrupts.
9615             */
9616            gen_save_pc(ctx->base.pc_next + 4);
9617            ctx->base.is_jmp = DISAS_EXIT;
9618            register_name = "Cause";
9619            break;
9620        default:
9621            goto cp0_unimplemented;
9622        }
9623        break;
9624    case CP0_REGISTER_14:
9625        switch (sel) {
9626        case CP0_REG14__EPC:
9627            tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EPC));
9628            register_name = "EPC";
9629            break;
9630        default:
9631            goto cp0_unimplemented;
9632        }
9633        break;
9634    case CP0_REGISTER_15:
9635        switch (sel) {
9636        case CP0_REG15__PRID:
9637            /* ignored */
9638            register_name = "PRid";
9639            break;
9640        case CP0_REG15__EBASE:
9641            check_insn(ctx, ISA_MIPS32R2);
9642            gen_helper_mtc0_ebase(cpu_env, arg);
9643            register_name = "EBase";
9644            break;
9645        default:
9646            goto cp0_unimplemented;
9647        }
9648        break;
9649    case CP0_REGISTER_16:
9650        switch (sel) {
9651        case CP0_REG16__CONFIG:
9652            gen_helper_mtc0_config0(cpu_env, arg);
9653            register_name = "Config";
9654            /* Stop translation as we may have switched the execution mode */
9655            ctx->base.is_jmp = DISAS_STOP;
9656            break;
9657        case CP0_REG16__CONFIG1:
9658            /* ignored, read only */
9659            register_name = "Config1";
9660            break;
9661        case CP0_REG16__CONFIG2:
9662            gen_helper_mtc0_config2(cpu_env, arg);
9663            register_name = "Config2";
9664            /* Stop translation as we may have switched the execution mode */
9665            ctx->base.is_jmp = DISAS_STOP;
9666            break;
9667        case CP0_REG16__CONFIG3:
9668            gen_helper_mtc0_config3(cpu_env, arg);
9669            register_name = "Config3";
9670            /* Stop translation as we may have switched the execution mode */
9671            ctx->base.is_jmp = DISAS_STOP;
9672            break;
9673        case CP0_REG16__CONFIG4:
9674            /* currently ignored */
9675            register_name = "Config4";
9676            break;
9677        case CP0_REG16__CONFIG5:
9678            gen_helper_mtc0_config5(cpu_env, arg);
9679            register_name = "Config5";
9680            /* Stop translation as we may have switched the execution mode */
9681            ctx->base.is_jmp = DISAS_STOP;
9682            break;
9683        /* 6,7 are implementation dependent */
9684        default:
9685            register_name = "Invalid config selector";
9686            goto cp0_unimplemented;
9687        }
9688        break;
9689    case CP0_REGISTER_17:
9690        switch (sel) {
9691        case CP0_REG17__LLADDR:
9692            gen_helper_mtc0_lladdr(cpu_env, arg);
9693            register_name = "LLAddr";
9694            break;
9695        case CP0_REG17__MAAR:
9696            CP0_CHECK(ctx->mrp);
9697            gen_helper_mtc0_maar(cpu_env, arg);
9698            register_name = "MAAR";
9699            break;
9700        case CP0_REG17__MAARI:
9701            CP0_CHECK(ctx->mrp);
9702            gen_helper_mtc0_maari(cpu_env, arg);
9703            register_name = "MAARI";
9704            break;
9705        default:
9706            goto cp0_unimplemented;
9707        }
9708        break;
9709    case CP0_REGISTER_18:
9710        switch (sel) {
9711        case CP0_REG18__WATCHLO0:
9712        case CP0_REG18__WATCHLO1:
9713        case CP0_REG18__WATCHLO2:
9714        case CP0_REG18__WATCHLO3:
9715        case CP0_REG18__WATCHLO4:
9716        case CP0_REG18__WATCHLO5:
9717        case CP0_REG18__WATCHLO6:
9718        case CP0_REG18__WATCHLO7:
9719            CP0_CHECK(ctx->CP0_Config1 & (1 << CP0C1_WR));
9720            gen_helper_0e1i(mtc0_watchlo, arg, sel);
9721            register_name = "WatchLo";
9722            break;
9723        default:
9724            goto cp0_unimplemented;
9725        }
9726        break;
9727    case CP0_REGISTER_19:
9728        switch (sel) {
9729        case CP0_REG19__WATCHHI0:
9730        case CP0_REG19__WATCHHI1:
9731        case CP0_REG19__WATCHHI2:
9732        case CP0_REG19__WATCHHI3:
9733        case CP0_REG19__WATCHHI4:
9734        case CP0_REG19__WATCHHI5:
9735        case CP0_REG19__WATCHHI6:
9736        case CP0_REG19__WATCHHI7:
9737            CP0_CHECK(ctx->CP0_Config1 & (1 << CP0C1_WR));
9738            gen_helper_0e1i(mtc0_watchhi, arg, sel);
9739            register_name = "WatchHi";
9740            break;
9741        default:
9742            goto cp0_unimplemented;
9743        }
9744        break;
9745    case CP0_REGISTER_20:
9746        switch (sel) {
9747        case CP0_REG20__XCONTEXT:
9748            check_insn(ctx, ISA_MIPS3);
9749            gen_helper_mtc0_xcontext(cpu_env, arg);
9750            register_name = "XContext";
9751            break;
9752        default:
9753            goto cp0_unimplemented;
9754        }
9755        break;
9756    case CP0_REGISTER_21:
9757       /* Officially reserved, but sel 0 is used for R1x000 framemask */
9758        CP0_CHECK(!(ctx->insn_flags & ISA_MIPS32R6));
9759        switch (sel) {
9760        case 0:
9761            gen_helper_mtc0_framemask(cpu_env, arg);
9762            register_name = "Framemask";
9763            break;
9764        default:
9765            goto cp0_unimplemented;
9766        }
9767        break;
9768    case CP0_REGISTER_22:
9769        /* ignored */
9770        register_name = "Diagnostic"; /* implementation dependent */
9771        break;
9772    case CP0_REGISTER_23:
9773        switch (sel) {
9774        case CP0_REG23__DEBUG:
9775            gen_helper_mtc0_debug(cpu_env, arg); /* EJTAG support */
9776            /* DISAS_STOP isn't good enough here, hflags may have changed. */
9777            gen_save_pc(ctx->base.pc_next + 4);
9778            ctx->base.is_jmp = DISAS_EXIT;
9779            register_name = "Debug";
9780            break;
9781        case CP0_REG23__TRACECONTROL:
9782            /* PDtrace support */
9783            /* gen_helper_mtc0_tracecontrol(cpu_env, arg);  */
9784            /* Stop translation as we may have switched the execution mode */
9785            ctx->base.is_jmp = DISAS_STOP;
9786            register_name = "TraceControl";
9787            goto cp0_unimplemented;
9788        case CP0_REG23__TRACECONTROL2:
9789            /* PDtrace support */
9790            /* gen_helper_mtc0_tracecontrol2(cpu_env, arg); */
9791            /* Stop translation as we may have switched the execution mode */
9792            ctx->base.is_jmp = DISAS_STOP;
9793            register_name = "TraceControl2";
9794            goto cp0_unimplemented;
9795        case CP0_REG23__USERTRACEDATA1:
9796            /* PDtrace support */
9797            /* gen_helper_mtc0_usertracedata1(cpu_env, arg);*/
9798            /* Stop translation as we may have switched the execution mode */
9799            ctx->base.is_jmp = DISAS_STOP;
9800            register_name = "UserTraceData1";
9801            goto cp0_unimplemented;
9802        case CP0_REG23__TRACEIBPC:
9803            /* PDtrace support */
9804            /* gen_helper_mtc0_traceibpc(cpu_env, arg);     */
9805            /* Stop translation as we may have switched the execution mode */
9806            ctx->base.is_jmp = DISAS_STOP;
9807            register_name = "TraceIBPC";
9808            goto cp0_unimplemented;
9809        case CP0_REG23__TRACEDBPC:
9810            /* PDtrace support */
9811            /* gen_helper_mtc0_tracedbpc(cpu_env, arg);     */
9812            /* Stop translation as we may have switched the execution mode */
9813            ctx->base.is_jmp = DISAS_STOP;
9814            register_name = "TraceDBPC";
9815            goto cp0_unimplemented;
9816        default:
9817            goto cp0_unimplemented;
9818        }
9819        break;
9820    case CP0_REGISTER_24:
9821        switch (sel) {
9822        case CP0_REG24__DEPC:
9823            /* EJTAG support */
9824            tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_DEPC));
9825            register_name = "DEPC";
9826            break;
9827        default:
9828            goto cp0_unimplemented;
9829        }
9830        break;
9831    case CP0_REGISTER_25:
9832        switch (sel) {
9833        case CP0_REG25__PERFCTL0:
9834            gen_helper_mtc0_performance0(cpu_env, arg);
9835            register_name = "Performance0";
9836            break;
9837        case CP0_REG25__PERFCNT0:
9838            /* gen_helper_mtc0_performance1(cpu_env, arg); */
9839            register_name = "Performance1";
9840            goto cp0_unimplemented;
9841        case CP0_REG25__PERFCTL1:
9842            /* gen_helper_mtc0_performance2(cpu_env, arg); */
9843            register_name = "Performance2";
9844            goto cp0_unimplemented;
9845        case CP0_REG25__PERFCNT1:
9846            /* gen_helper_mtc0_performance3(cpu_env, arg); */
9847            register_name = "Performance3";
9848            goto cp0_unimplemented;
9849        case CP0_REG25__PERFCTL2:
9850            /* gen_helper_mtc0_performance4(cpu_env, arg); */
9851            register_name = "Performance4";
9852            goto cp0_unimplemented;
9853        case CP0_REG25__PERFCNT2:
9854            /* gen_helper_mtc0_performance5(cpu_env, arg); */
9855            register_name = "Performance5";
9856            goto cp0_unimplemented;
9857        case CP0_REG25__PERFCTL3:
9858            /* gen_helper_mtc0_performance6(cpu_env, arg); */
9859            register_name = "Performance6";
9860            goto cp0_unimplemented;
9861        case CP0_REG25__PERFCNT3:
9862            /* gen_helper_mtc0_performance7(cpu_env, arg); */
9863            register_name = "Performance7";
9864            goto cp0_unimplemented;
9865        default:
9866            goto cp0_unimplemented;
9867        }
9868        break;
9869    case CP0_REGISTER_26:
9870        switch (sel) {
9871        case CP0_REG26__ERRCTL:
9872            gen_helper_mtc0_errctl(cpu_env, arg);
9873            ctx->base.is_jmp = DISAS_STOP;
9874            register_name = "ErrCtl";
9875            break;
9876        default:
9877            goto cp0_unimplemented;
9878        }
9879        break;
9880    case CP0_REGISTER_27:
9881        switch (sel) {
9882        case CP0_REG27__CACHERR:
9883            /* ignored */
9884            register_name = "CacheErr";
9885            break;
9886        default:
9887            goto cp0_unimplemented;
9888        }
9889        break;
9890    case CP0_REGISTER_28:
9891        switch (sel) {
9892        case CP0_REG28__TAGLO:
9893        case CP0_REG28__TAGLO1:
9894        case CP0_REG28__TAGLO2:
9895        case CP0_REG28__TAGLO3:
9896            gen_helper_mtc0_taglo(cpu_env, arg);
9897            register_name = "TagLo";
9898            break;
9899        case CP0_REG28__DATALO:
9900        case CP0_REG28__DATALO1:
9901        case CP0_REG28__DATALO2:
9902        case CP0_REG28__DATALO3:
9903            gen_helper_mtc0_datalo(cpu_env, arg);
9904            register_name = "DataLo";
9905            break;
9906        default:
9907            goto cp0_unimplemented;
9908        }
9909        break;
9910    case CP0_REGISTER_29:
9911        switch (sel) {
9912        case CP0_REG29__TAGHI:
9913        case CP0_REG29__TAGHI1:
9914        case CP0_REG29__TAGHI2:
9915        case CP0_REG29__TAGHI3:
9916            gen_helper_mtc0_taghi(cpu_env, arg);
9917            register_name = "TagHi";
9918            break;
9919        case CP0_REG29__DATAHI:
9920        case CP0_REG29__DATAHI1:
9921        case CP0_REG29__DATAHI2:
9922        case CP0_REG29__DATAHI3:
9923            gen_helper_mtc0_datahi(cpu_env, arg);
9924            register_name = "DataHi";
9925            break;
9926        default:
9927            register_name = "invalid sel";
9928            goto cp0_unimplemented;
9929        }
9930        break;
9931    case CP0_REGISTER_30:
9932        switch (sel) {
9933        case CP0_REG30__ERROREPC:
9934            tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_ErrorEPC));
9935            register_name = "ErrorEPC";
9936            break;
9937        default:
9938            goto cp0_unimplemented;
9939        }
9940        break;
9941    case CP0_REGISTER_31:
9942        switch (sel) {
9943        case CP0_REG31__DESAVE:
9944            /* EJTAG support */
9945            gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_DESAVE));
9946            register_name = "DESAVE";
9947            break;
9948        case CP0_REG31__KSCRATCH1:
9949        case CP0_REG31__KSCRATCH2:
9950        case CP0_REG31__KSCRATCH3:
9951        case CP0_REG31__KSCRATCH4:
9952        case CP0_REG31__KSCRATCH5:
9953        case CP0_REG31__KSCRATCH6:
9954            CP0_CHECK(ctx->kscrexist & (1 << sel));
9955            tcg_gen_st_tl(arg, cpu_env,
9956                          offsetof(CPUMIPSState, CP0_KScratch[sel - 2]));
9957            register_name = "KScratch";
9958            break;
9959        default:
9960            goto cp0_unimplemented;
9961        }
9962        break;
9963    default:
9964        goto cp0_unimplemented;
9965    }
9966    trace_mips_translate_c0("dmtc0", register_name, reg, sel);
9967
9968    /* For simplicity assume that all writes can cause interrupts.  */
9969    if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
9970        /*
9971         * DISAS_STOP isn't sufficient, we need to ensure we break out of
9972         * translated code to check for pending interrupts.
9973         */
9974        gen_save_pc(ctx->base.pc_next + 4);
9975        ctx->base.is_jmp = DISAS_EXIT;
9976    }
9977    return;
9978
9979cp0_unimplemented:
9980    qemu_log_mask(LOG_UNIMP, "dmtc0 %s (reg %d sel %d)\n",
9981                  register_name, reg, sel);
9982}
9983#endif /* TARGET_MIPS64 */
9984
9985static void gen_mftr(CPUMIPSState *env, DisasContext *ctx, int rt, int rd,
9986                     int u, int sel, int h)
9987{
9988    int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
9989    TCGv t0 = tcg_temp_local_new();
9990
9991    if ((env->CP0_VPEConf0 & (1 << CP0VPEC0_MVP)) == 0 &&
9992        ((env->tcs[other_tc].CP0_TCBind & (0xf << CP0TCBd_CurVPE)) !=
9993         (env->active_tc.CP0_TCBind & (0xf << CP0TCBd_CurVPE)))) {
9994        tcg_gen_movi_tl(t0, -1);
9995    } else if ((env->CP0_VPEControl & (0xff << CP0VPECo_TargTC)) >
9996               (env->mvp->CP0_MVPConf0 & (0xff << CP0MVPC0_PTC))) {
9997        tcg_gen_movi_tl(t0, -1);
9998    } else if (u == 0) {
9999        switch (rt) {
10000        case 1:
10001            switch (sel) {
10002            case 1:
10003                gen_helper_mftc0_vpecontrol(t0, cpu_env);
10004                break;
10005            case 2:
10006                gen_helper_mftc0_vpeconf0(t0, cpu_env);
10007                break;
10008            default:
10009                goto die;
10010                break;
10011            }
10012            break;
10013        case 2:
10014            switch (sel) {
10015            case 1:
10016                gen_helper_mftc0_tcstatus(t0, cpu_env);
10017                break;
10018            case 2:
10019                gen_helper_mftc0_tcbind(t0, cpu_env);
10020                break;
10021            case 3:
10022                gen_helper_mftc0_tcrestart(t0, cpu_env);
10023                break;
10024            case 4:
10025                gen_helper_mftc0_tchalt(t0, cpu_env);
10026                break;
10027            case 5:
10028                gen_helper_mftc0_tccontext(t0, cpu_env);
10029                break;
10030            case 6:
10031                gen_helper_mftc0_tcschedule(t0, cpu_env);
10032                break;
10033            case 7:
10034                gen_helper_mftc0_tcschefback(t0, cpu_env);
10035                break;
10036            default:
10037                gen_mfc0(ctx, t0, rt, sel);
10038                break;
10039            }
10040            break;
10041        case 10:
10042            switch (sel) {
10043            case 0:
10044                gen_helper_mftc0_entryhi(t0, cpu_env);
10045                break;
10046            default:
10047                gen_mfc0(ctx, t0, rt, sel);
10048                break;
10049            }
10050            break;
10051        case 12:
10052            switch (sel) {
10053            case 0:
10054                gen_helper_mftc0_status(t0, cpu_env);
10055                break;
10056            default:
10057                gen_mfc0(ctx, t0, rt, sel);
10058                break;
10059            }
10060            break;
10061        case 13:
10062            switch (sel) {
10063            case 0:
10064                gen_helper_mftc0_cause(t0, cpu_env);
10065                break;
10066            default:
10067                goto die;
10068                break;
10069            }
10070            break;
10071        case 14:
10072            switch (sel) {
10073            case 0:
10074                gen_helper_mftc0_epc(t0, cpu_env);
10075                break;
10076            default:
10077                goto die;
10078                break;
10079            }
10080            break;
10081        case 15:
10082            switch (sel) {
10083            case 1:
10084                gen_helper_mftc0_ebase(t0, cpu_env);
10085                break;
10086            default:
10087                goto die;
10088                break;
10089            }
10090            break;
10091        case 16:
10092            switch (sel) {
10093            case 0:
10094            case 1:
10095            case 2:
10096            case 3:
10097            case 4:
10098            case 5:
10099            case 6:
10100            case 7:
10101                gen_helper_mftc0_configx(t0, cpu_env, tcg_const_tl(sel));
10102                break;
10103            default:
10104                goto die;
10105                break;
10106            }
10107            break;
10108        case 23:
10109            switch (sel) {
10110            case 0:
10111                gen_helper_mftc0_debug(t0, cpu_env);
10112                break;
10113            default:
10114                gen_mfc0(ctx, t0, rt, sel);
10115                break;
10116            }
10117            break;
10118        default:
10119            gen_mfc0(ctx, t0, rt, sel);
10120        }
10121    } else {
10122        switch (sel) {
10123        /* GPR registers. */
10124        case 0:
10125            gen_helper_1e0i(mftgpr, t0, rt);
10126            break;
10127        /* Auxiliary CPU registers */
10128        case 1:
10129            switch (rt) {
10130            case 0:
10131                gen_helper_1e0i(mftlo, t0, 0);
10132                break;
10133            case 1:
10134                gen_helper_1e0i(mfthi, t0, 0);
10135                break;
10136            case 2:
10137                gen_helper_1e0i(mftacx, t0, 0);
10138                break;
10139            case 4:
10140                gen_helper_1e0i(mftlo, t0, 1);
10141                break;
10142            case 5:
10143                gen_helper_1e0i(mfthi, t0, 1);
10144                break;
10145            case 6:
10146                gen_helper_1e0i(mftacx, t0, 1);
10147                break;
10148            case 8:
10149                gen_helper_1e0i(mftlo, t0, 2);
10150                break;
10151            case 9:
10152                gen_helper_1e0i(mfthi, t0, 2);
10153                break;
10154            case 10:
10155                gen_helper_1e0i(mftacx, t0, 2);
10156                break;
10157            case 12:
10158                gen_helper_1e0i(mftlo, t0, 3);
10159                break;
10160            case 13:
10161                gen_helper_1e0i(mfthi, t0, 3);
10162                break;
10163            case 14:
10164                gen_helper_1e0i(mftacx, t0, 3);
10165                break;
10166            case 16:
10167                gen_helper_mftdsp(t0, cpu_env);
10168                break;
10169            default:
10170                goto die;
10171            }
10172            break;
10173        /* Floating point (COP1). */
10174        case 2:
10175            /* XXX: For now we support only a single FPU context. */
10176            if (h == 0) {
10177                TCGv_i32 fp0 = tcg_temp_new_i32();
10178
10179                gen_load_fpr32(ctx, fp0, rt);
10180                tcg_gen_ext_i32_tl(t0, fp0);
10181                tcg_temp_free_i32(fp0);
10182            } else {
10183                TCGv_i32 fp0 = tcg_temp_new_i32();
10184
10185                gen_load_fpr32h(ctx, fp0, rt);
10186                tcg_gen_ext_i32_tl(t0, fp0);
10187                tcg_temp_free_i32(fp0);
10188            }
10189            break;
10190        case 3:
10191            /* XXX: For now we support only a single FPU context. */
10192            gen_helper_1e0i(cfc1, t0, rt);
10193            break;
10194        /* COP2: Not implemented. */
10195        case 4:
10196        case 5:
10197            /* fall through */
10198        default:
10199            goto die;
10200        }
10201    }
10202    trace_mips_translate_tr("mftr", rt, u, sel, h);
10203    gen_store_gpr(t0, rd);
10204    tcg_temp_free(t0);
10205    return;
10206
10207die:
10208    tcg_temp_free(t0);
10209    LOG_DISAS("mftr (reg %d u %d sel %d h %d)\n", rt, u, sel, h);
10210    generate_exception_end(ctx, EXCP_RI);
10211}
10212
10213static void gen_mttr(CPUMIPSState *env, DisasContext *ctx, int rd, int rt,
10214                     int u, int sel, int h)
10215{
10216    int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
10217    TCGv t0 = tcg_temp_local_new();
10218
10219    gen_load_gpr(t0, rt);
10220    if ((env->CP0_VPEConf0 & (1 << CP0VPEC0_MVP)) == 0 &&
10221        ((env->tcs[other_tc].CP0_TCBind & (0xf << CP0TCBd_CurVPE)) !=
10222         (env->active_tc.CP0_TCBind & (0xf << CP0TCBd_CurVPE)))) {
10223        /* NOP */
10224        ;
10225    } else if ((env->CP0_VPEControl & (0xff << CP0VPECo_TargTC)) >
10226             (env->mvp->CP0_MVPConf0 & (0xff << CP0MVPC0_PTC))) {
10227        /* NOP */
10228        ;
10229    } else if (u == 0) {
10230        switch (rd) {
10231        case 1:
10232            switch (sel) {
10233            case 1:
10234                gen_helper_mttc0_vpecontrol(cpu_env, t0);
10235                break;
10236            case 2:
10237                gen_helper_mttc0_vpeconf0(cpu_env, t0);
10238                break;
10239            default:
10240                goto die;
10241                break;
10242            }
10243            break;
10244        case 2:
10245            switch (sel) {
10246            case 1:
10247                gen_helper_mttc0_tcstatus(cpu_env, t0);
10248                break;
10249            case 2:
10250                gen_helper_mttc0_tcbind(cpu_env, t0);
10251                break;
10252            case 3:
10253                gen_helper_mttc0_tcrestart(cpu_env, t0);
10254                break;
10255            case 4:
10256                gen_helper_mttc0_tchalt(cpu_env, t0);
10257                break;
10258            case 5:
10259                gen_helper_mttc0_tccontext(cpu_env, t0);
10260                break;
10261            case 6:
10262                gen_helper_mttc0_tcschedule(cpu_env, t0);
10263                break;
10264            case 7:
10265                gen_helper_mttc0_tcschefback(cpu_env, t0);
10266                break;
10267            default:
10268                gen_mtc0(ctx, t0, rd, sel);
10269                break;
10270            }
10271            break;
10272        case 10:
10273            switch (sel) {
10274            case 0:
10275                gen_helper_mttc0_entryhi(cpu_env, t0);
10276                break;
10277            default:
10278                gen_mtc0(ctx, t0, rd, sel);
10279                break;
10280            }
10281            break;
10282        case 12:
10283            switch (sel) {
10284            case 0:
10285                gen_helper_mttc0_status(cpu_env, t0);
10286                break;
10287            default:
10288                gen_mtc0(ctx, t0, rd, sel);
10289                break;
10290            }
10291            break;
10292        case 13:
10293            switch (sel) {
10294            case 0:
10295                gen_helper_mttc0_cause(cpu_env, t0);
10296                break;
10297            default:
10298                goto die;
10299                break;
10300            }
10301            break;
10302        case 15:
10303            switch (sel) {
10304            case 1:
10305                gen_helper_mttc0_ebase(cpu_env, t0);
10306                break;
10307            default:
10308                goto die;
10309                break;
10310            }
10311            break;
10312        case 23:
10313            switch (sel) {
10314            case 0:
10315                gen_helper_mttc0_debug(cpu_env, t0);
10316                break;
10317            default:
10318                gen_mtc0(ctx, t0, rd, sel);
10319                break;
10320            }
10321            break;
10322        default:
10323            gen_mtc0(ctx, t0, rd, sel);
10324        }
10325    } else {
10326        switch (sel) {
10327        /* GPR registers. */
10328        case 0:
10329            gen_helper_0e1i(mttgpr, t0, rd);
10330            break;
10331        /* Auxiliary CPU registers */
10332        case 1:
10333            switch (rd) {
10334            case 0:
10335                gen_helper_0e1i(mttlo, t0, 0);
10336                break;
10337            case 1:
10338                gen_helper_0e1i(mtthi, t0, 0);
10339                break;
10340            case 2:
10341                gen_helper_0e1i(mttacx, t0, 0);
10342                break;
10343            case 4:
10344                gen_helper_0e1i(mttlo, t0, 1);
10345                break;
10346            case 5:
10347                gen_helper_0e1i(mtthi, t0, 1);
10348                break;
10349            case 6:
10350                gen_helper_0e1i(mttacx, t0, 1);
10351                break;
10352            case 8:
10353                gen_helper_0e1i(mttlo, t0, 2);
10354                break;
10355            case 9:
10356                gen_helper_0e1i(mtthi, t0, 2);
10357                break;
10358            case 10:
10359                gen_helper_0e1i(mttacx, t0, 2);
10360                break;
10361            case 12:
10362                gen_helper_0e1i(mttlo, t0, 3);
10363                break;
10364            case 13:
10365                gen_helper_0e1i(mtthi, t0, 3);
10366                break;
10367            case 14:
10368                gen_helper_0e1i(mttacx, t0, 3);
10369                break;
10370            case 16:
10371                gen_helper_mttdsp(cpu_env, t0);
10372                break;
10373            default:
10374                goto die;
10375            }
10376            break;
10377        /* Floating point (COP1). */
10378        case 2:
10379            /* XXX: For now we support only a single FPU context. */
10380            if (h == 0) {
10381                TCGv_i32 fp0 = tcg_temp_new_i32();
10382
10383                tcg_gen_trunc_tl_i32(fp0, t0);
10384                gen_store_fpr32(ctx, fp0, rd);
10385                tcg_temp_free_i32(fp0);
10386            } else {
10387                TCGv_i32 fp0 = tcg_temp_new_i32();
10388
10389                tcg_gen_trunc_tl_i32(fp0, t0);
10390                gen_store_fpr32h(ctx, fp0, rd);
10391                tcg_temp_free_i32(fp0);
10392            }
10393            break;
10394        case 3:
10395            /* XXX: For now we support only a single FPU context. */
10396            {
10397                TCGv_i32 fs_tmp = tcg_const_i32(rd);
10398
10399                gen_helper_0e2i(ctc1, t0, fs_tmp, rt);
10400                tcg_temp_free_i32(fs_tmp);
10401            }
10402            /* Stop translation as we may have changed hflags */
10403            ctx->base.is_jmp = DISAS_STOP;
10404            break;
10405        /* COP2: Not implemented. */
10406        case 4:
10407        case 5:
10408            /* fall through */
10409        default:
10410            goto die;
10411        }
10412    }
10413    trace_mips_translate_tr("mttr", rd, u, sel, h);
10414    tcg_temp_free(t0);
10415    return;
10416
10417die:
10418    tcg_temp_free(t0);
10419    LOG_DISAS("mttr (reg %d u %d sel %d h %d)\n", rd, u, sel, h);
10420    generate_exception_end(ctx, EXCP_RI);
10421}
10422
10423static void gen_cp0(CPUMIPSState *env, DisasContext *ctx, uint32_t opc,
10424                    int rt, int rd)
10425{
10426    const char *opn = "ldst";
10427
10428    check_cp0_enabled(ctx);
10429    switch (opc) {
10430    case OPC_MFC0:
10431        if (rt == 0) {
10432            /* Treat as NOP. */
10433            return;
10434        }
10435        gen_mfc0(ctx, cpu_gpr[rt], rd, ctx->opcode & 0x7);
10436        opn = "mfc0";
10437        break;
10438    case OPC_MTC0:
10439        {
10440            TCGv t0 = tcg_temp_new();
10441
10442            gen_load_gpr(t0, rt);
10443            gen_mtc0(ctx, t0, rd, ctx->opcode & 0x7);
10444            tcg_temp_free(t0);
10445        }
10446        opn = "mtc0";
10447        break;
10448#if defined(TARGET_MIPS64)
10449    case OPC_DMFC0:
10450        check_insn(ctx, ISA_MIPS3);
10451        if (rt == 0) {
10452            /* Treat as NOP. */
10453            return;
10454        }
10455        gen_dmfc0(ctx, cpu_gpr[rt], rd, ctx->opcode & 0x7);
10456        opn = "dmfc0";
10457        break;
10458    case OPC_DMTC0:
10459        check_insn(ctx, ISA_MIPS3);
10460        {
10461            TCGv t0 = tcg_temp_new();
10462
10463            gen_load_gpr(t0, rt);
10464            gen_dmtc0(ctx, t0, rd, ctx->opcode & 0x7);
10465            tcg_temp_free(t0);
10466        }
10467        opn = "dmtc0";
10468        break;
10469#endif
10470    case OPC_MFHC0:
10471        check_mvh(ctx);
10472        if (rt == 0) {
10473            /* Treat as NOP. */
10474            return;
10475        }
10476        gen_mfhc0(ctx, cpu_gpr[rt], rd, ctx->opcode & 0x7);
10477        opn = "mfhc0";
10478        break;
10479    case OPC_MTHC0:
10480        check_mvh(ctx);
10481        {
10482            TCGv t0 = tcg_temp_new();
10483            gen_load_gpr(t0, rt);
10484            gen_mthc0(ctx, t0, rd, ctx->opcode & 0x7);
10485            tcg_temp_free(t0);
10486        }
10487        opn = "mthc0";
10488        break;
10489    case OPC_MFTR:
10490        check_cp0_enabled(ctx);
10491        if (rd == 0) {
10492            /* Treat as NOP. */
10493            return;
10494        }
10495        gen_mftr(env, ctx, rt, rd, (ctx->opcode >> 5) & 1,
10496                 ctx->opcode & 0x7, (ctx->opcode >> 4) & 1);
10497        opn = "mftr";
10498        break;
10499    case OPC_MTTR:
10500        check_cp0_enabled(ctx);
10501        gen_mttr(env, ctx, rd, rt, (ctx->opcode >> 5) & 1,
10502                 ctx->opcode & 0x7, (ctx->opcode >> 4) & 1);
10503        opn = "mttr";
10504        break;
10505    case OPC_TLBWI:
10506        opn = "tlbwi";
10507        if (!env->tlb->helper_tlbwi) {
10508            goto die;
10509        }
10510        gen_helper_tlbwi(cpu_env);
10511        break;
10512    case OPC_TLBINV:
10513        opn = "tlbinv";
10514        if (ctx->ie >= 2) {
10515            if (!env->tlb->helper_tlbinv) {
10516                goto die;
10517            }
10518            gen_helper_tlbinv(cpu_env);
10519        } /* treat as nop if TLBINV not supported */
10520        break;
10521    case OPC_TLBINVF:
10522        opn = "tlbinvf";
10523        if (ctx->ie >= 2) {
10524            if (!env->tlb->helper_tlbinvf) {
10525                goto die;
10526            }
10527            gen_helper_tlbinvf(cpu_env);
10528        } /* treat as nop if TLBINV not supported */
10529        break;
10530    case OPC_TLBWR:
10531        opn = "tlbwr";
10532        if (!env->tlb->helper_tlbwr) {
10533            goto die;
10534        }
10535        gen_helper_tlbwr(cpu_env);
10536        break;
10537    case OPC_TLBP:
10538        opn = "tlbp";
10539        if (!env->tlb->helper_tlbp) {
10540            goto die;
10541        }
10542        gen_helper_tlbp(cpu_env);
10543        break;
10544    case OPC_TLBR:
10545        opn = "tlbr";
10546        if (!env->tlb->helper_tlbr) {
10547            goto die;
10548        }
10549        gen_helper_tlbr(cpu_env);
10550        break;
10551    case OPC_ERET: /* OPC_ERETNC */
10552        if ((ctx->insn_flags & ISA_MIPS32R6) &&
10553            (ctx->hflags & MIPS_HFLAG_BMASK)) {
10554            goto die;
10555        } else {
10556            int bit_shift = (ctx->hflags & MIPS_HFLAG_M16) ? 16 : 6;
10557            if (ctx->opcode & (1 << bit_shift)) {
10558                /* OPC_ERETNC */
10559                opn = "eretnc";
10560                check_insn(ctx, ISA_MIPS32R5);
10561                gen_helper_eretnc(cpu_env);
10562            } else {
10563                /* OPC_ERET */
10564                opn = "eret";
10565                check_insn(ctx, ISA_MIPS2);
10566                gen_helper_eret(cpu_env);
10567            }
10568            ctx->base.is_jmp = DISAS_EXIT;
10569        }
10570        break;
10571    case OPC_DERET:
10572        opn = "deret";
10573        check_insn(ctx, ISA_MIPS32);
10574        if ((ctx->insn_flags & ISA_MIPS32R6) &&
10575            (ctx->hflags & MIPS_HFLAG_BMASK)) {
10576            goto die;
10577        }
10578        if (!(ctx->hflags & MIPS_HFLAG_DM)) {
10579            MIPS_INVAL(opn);
10580            generate_exception_end(ctx, EXCP_RI);
10581        } else {
10582            gen_helper_deret(cpu_env);
10583            ctx->base.is_jmp = DISAS_EXIT;
10584        }
10585        break;
10586    case OPC_WAIT:
10587        opn = "wait";
10588        check_insn(ctx, ISA_MIPS3 | ISA_MIPS32);
10589        if ((ctx->insn_flags & ISA_MIPS32R6) &&
10590            (ctx->hflags & MIPS_HFLAG_BMASK)) {
10591            goto die;
10592        }
10593        /* If we get an exception, we want to restart at next instruction */
10594        ctx->base.pc_next += 4;
10595        save_cpu_state(ctx, 1);
10596        ctx->base.pc_next -= 4;
10597        gen_helper_wait(cpu_env);
10598        ctx->base.is_jmp = DISAS_NORETURN;
10599        break;
10600    default:
10601 die:
10602        MIPS_INVAL(opn);
10603        generate_exception_end(ctx, EXCP_RI);
10604        return;
10605    }
10606    (void)opn; /* avoid a compiler warning */
10607}
10608#endif /* !CONFIG_USER_ONLY */
10609
10610/* CP1 Branches (before delay slot) */
10611static void gen_compute_branch1(DisasContext *ctx, uint32_t op,
10612                                int32_t cc, int32_t offset)
10613{
10614    target_ulong btarget;
10615    TCGv_i32 t0 = tcg_temp_new_i32();
10616
10617    if ((ctx->insn_flags & ISA_MIPS32R6) && (ctx->hflags & MIPS_HFLAG_BMASK)) {
10618        generate_exception_end(ctx, EXCP_RI);
10619        goto out;
10620    }
10621
10622    if (cc != 0) {
10623        check_insn(ctx, ISA_MIPS4 | ISA_MIPS32);
10624    }
10625
10626    btarget = ctx->base.pc_next + 4 + offset;
10627
10628    switch (op) {
10629    case OPC_BC1F:
10630        tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
10631        tcg_gen_not_i32(t0, t0);
10632        tcg_gen_andi_i32(t0, t0, 1);
10633        tcg_gen_extu_i32_tl(bcond, t0);
10634        goto not_likely;
10635    case OPC_BC1FL:
10636        tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
10637        tcg_gen_not_i32(t0, t0);
10638        tcg_gen_andi_i32(t0, t0, 1);
10639        tcg_gen_extu_i32_tl(bcond, t0);
10640        goto likely;
10641    case OPC_BC1T:
10642        tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
10643        tcg_gen_andi_i32(t0, t0, 1);
10644        tcg_gen_extu_i32_tl(bcond, t0);
10645        goto not_likely;
10646    case OPC_BC1TL:
10647        tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
10648        tcg_gen_andi_i32(t0, t0, 1);
10649        tcg_gen_extu_i32_tl(bcond, t0);
10650    likely:
10651        ctx->hflags |= MIPS_HFLAG_BL;
10652        break;
10653    case OPC_BC1FANY2:
10654        {
10655            TCGv_i32 t1 = tcg_temp_new_i32();
10656            tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
10657            tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc + 1));
10658            tcg_gen_nand_i32(t0, t0, t1);
10659            tcg_temp_free_i32(t1);
10660            tcg_gen_andi_i32(t0, t0, 1);
10661            tcg_gen_extu_i32_tl(bcond, t0);
10662        }
10663        goto not_likely;
10664    case OPC_BC1TANY2:
10665        {
10666            TCGv_i32 t1 = tcg_temp_new_i32();
10667            tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
10668            tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc + 1));
10669            tcg_gen_or_i32(t0, t0, t1);
10670            tcg_temp_free_i32(t1);
10671            tcg_gen_andi_i32(t0, t0, 1);
10672            tcg_gen_extu_i32_tl(bcond, t0);
10673        }
10674        goto not_likely;
10675    case OPC_BC1FANY4:
10676        {
10677            TCGv_i32 t1 = tcg_temp_new_i32();
10678            tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
10679            tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc + 1));
10680            tcg_gen_and_i32(t0, t0, t1);
10681            tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc + 2));
10682            tcg_gen_and_i32(t0, t0, t1);
10683            tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc + 3));
10684            tcg_gen_nand_i32(t0, t0, t1);
10685            tcg_temp_free_i32(t1);
10686            tcg_gen_andi_i32(t0, t0, 1);
10687            tcg_gen_extu_i32_tl(bcond, t0);
10688        }
10689        goto not_likely;
10690    case OPC_BC1TANY4:
10691        {
10692            TCGv_i32 t1 = tcg_temp_new_i32();
10693            tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
10694            tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc + 1));
10695            tcg_gen_or_i32(t0, t0, t1);
10696            tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc + 2));
10697            tcg_gen_or_i32(t0, t0, t1);
10698            tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc + 3));
10699            tcg_gen_or_i32(t0, t0, t1);
10700            tcg_temp_free_i32(t1);
10701            tcg_gen_andi_i32(t0, t0, 1);
10702            tcg_gen_extu_i32_tl(bcond, t0);
10703        }
10704    not_likely:
10705        ctx->hflags |= MIPS_HFLAG_BC;
10706        break;
10707    default:
10708        MIPS_INVAL("cp1 cond branch");
10709        generate_exception_end(ctx, EXCP_RI);
10710        goto out;
10711    }
10712    ctx->btarget = btarget;
10713    ctx->hflags |= MIPS_HFLAG_BDS32;
10714 out:
10715    tcg_temp_free_i32(t0);
10716}
10717
10718/* R6 CP1 Branches */
10719static void gen_compute_branch1_r6(DisasContext *ctx, uint32_t op,
10720                                   int32_t ft, int32_t offset,
10721                                   int delayslot_size)
10722{
10723    target_ulong btarget;
10724    TCGv_i64 t0 = tcg_temp_new_i64();
10725
10726    if (ctx->hflags & MIPS_HFLAG_BMASK) {
10727#ifdef MIPS_DEBUG_DISAS
10728        LOG_DISAS("Branch in delay / forbidden slot at PC 0x" TARGET_FMT_lx
10729                  "\n", ctx->base.pc_next);
10730#endif
10731        generate_exception_end(ctx, EXCP_RI);
10732        goto out;
10733    }
10734
10735    gen_load_fpr64(ctx, t0, ft);
10736    tcg_gen_andi_i64(t0, t0, 1);
10737
10738    btarget = addr_add(ctx, ctx->base.pc_next + 4, offset);
10739
10740    switch (op) {
10741    case OPC_BC1EQZ:
10742        tcg_gen_xori_i64(t0, t0, 1);
10743        ctx->hflags |= MIPS_HFLAG_BC;
10744        break;
10745    case OPC_BC1NEZ:
10746        /* t0 already set */
10747        ctx->hflags |= MIPS_HFLAG_BC;
10748        break;
10749    default:
10750        MIPS_INVAL("cp1 cond branch");
10751        generate_exception_end(ctx, EXCP_RI);
10752        goto out;
10753    }
10754
10755    tcg_gen_trunc_i64_tl(bcond, t0);
10756
10757    ctx->btarget = btarget;
10758
10759    switch (delayslot_size) {
10760    case 2:
10761        ctx->hflags |= MIPS_HFLAG_BDS16;
10762        break;
10763    case 4:
10764        ctx->hflags |= MIPS_HFLAG_BDS32;
10765        break;
10766    }
10767
10768out:
10769    tcg_temp_free_i64(t0);
10770}
10771
10772/* Coprocessor 1 (FPU) */
10773
10774#define FOP(func, fmt) (((fmt) << 21) | (func))
10775
10776enum fopcode {
10777    OPC_ADD_S = FOP(0, FMT_S),
10778    OPC_SUB_S = FOP(1, FMT_S),
10779    OPC_MUL_S = FOP(2, FMT_S),
10780    OPC_DIV_S = FOP(3, FMT_S),
10781    OPC_SQRT_S = FOP(4, FMT_S),
10782    OPC_ABS_S = FOP(5, FMT_S),
10783    OPC_MOV_S = FOP(6, FMT_S),
10784    OPC_NEG_S = FOP(7, FMT_S),
10785    OPC_ROUND_L_S = FOP(8, FMT_S),
10786    OPC_TRUNC_L_S = FOP(9, FMT_S),
10787    OPC_CEIL_L_S = FOP(10, FMT_S),
10788    OPC_FLOOR_L_S = FOP(11, FMT_S),
10789    OPC_ROUND_W_S = FOP(12, FMT_S),
10790    OPC_TRUNC_W_S = FOP(13, FMT_S),
10791    OPC_CEIL_W_S = FOP(14, FMT_S),
10792    OPC_FLOOR_W_S = FOP(15, FMT_S),
10793    OPC_SEL_S = FOP(16, FMT_S),
10794    OPC_MOVCF_S = FOP(17, FMT_S),
10795    OPC_MOVZ_S = FOP(18, FMT_S),
10796    OPC_MOVN_S = FOP(19, FMT_S),
10797    OPC_SELEQZ_S = FOP(20, FMT_S),
10798    OPC_RECIP_S = FOP(21, FMT_S),
10799    OPC_RSQRT_S = FOP(22, FMT_S),
10800    OPC_SELNEZ_S = FOP(23, FMT_S),
10801    OPC_MADDF_S = FOP(24, FMT_S),
10802    OPC_MSUBF_S = FOP(25, FMT_S),
10803    OPC_RINT_S = FOP(26, FMT_S),
10804    OPC_CLASS_S = FOP(27, FMT_S),
10805    OPC_MIN_S = FOP(28, FMT_S),
10806    OPC_RECIP2_S = FOP(28, FMT_S),
10807    OPC_MINA_S = FOP(29, FMT_S),
10808    OPC_RECIP1_S = FOP(29, FMT_S),
10809    OPC_MAX_S = FOP(30, FMT_S),
10810    OPC_RSQRT1_S = FOP(30, FMT_S),
10811    OPC_MAXA_S = FOP(31, FMT_S),
10812    OPC_RSQRT2_S = FOP(31, FMT_S),
10813    OPC_CVT_D_S = FOP(33, FMT_S),
10814    OPC_CVT_W_S = FOP(36, FMT_S),
10815    OPC_CVT_L_S = FOP(37, FMT_S),
10816    OPC_CVT_PS_S = FOP(38, FMT_S),
10817    OPC_CMP_F_S = FOP(48, FMT_S),
10818    OPC_CMP_UN_S = FOP(49, FMT_S),
10819    OPC_CMP_EQ_S = FOP(50, FMT_S),
10820    OPC_CMP_UEQ_S = FOP(51, FMT_S),
10821    OPC_CMP_OLT_S = FOP(52, FMT_S),
10822    OPC_CMP_ULT_S = FOP(53, FMT_S),
10823    OPC_CMP_OLE_S = FOP(54, FMT_S),
10824    OPC_CMP_ULE_S = FOP(55, FMT_S),
10825    OPC_CMP_SF_S = FOP(56, FMT_S),
10826    OPC_CMP_NGLE_S = FOP(57, FMT_S),
10827    OPC_CMP_SEQ_S = FOP(58, FMT_S),
10828    OPC_CMP_NGL_S = FOP(59, FMT_S),
10829    OPC_CMP_LT_S = FOP(60, FMT_S),
10830    OPC_CMP_NGE_S = FOP(61, FMT_S),
10831    OPC_CMP_LE_S = FOP(62, FMT_S),
10832    OPC_CMP_NGT_S = FOP(63, FMT_S),
10833
10834    OPC_ADD_D = FOP(0, FMT_D),
10835    OPC_SUB_D = FOP(1, FMT_D),
10836    OPC_MUL_D = FOP(2, FMT_D),
10837    OPC_DIV_D = FOP(3, FMT_D),
10838    OPC_SQRT_D = FOP(4, FMT_D),
10839    OPC_ABS_D = FOP(5, FMT_D),
10840    OPC_MOV_D = FOP(6, FMT_D),
10841    OPC_NEG_D = FOP(7, FMT_D),
10842    OPC_ROUND_L_D = FOP(8, FMT_D),
10843    OPC_TRUNC_L_D = FOP(9, FMT_D),
10844    OPC_CEIL_L_D = FOP(10, FMT_D),
10845    OPC_FLOOR_L_D = FOP(11, FMT_D),
10846    OPC_ROUND_W_D = FOP(12, FMT_D),
10847    OPC_TRUNC_W_D = FOP(13, FMT_D),
10848    OPC_CEIL_W_D = FOP(14, FMT_D),
10849    OPC_FLOOR_W_D = FOP(15, FMT_D),
10850    OPC_SEL_D = FOP(16, FMT_D),
10851    OPC_MOVCF_D = FOP(17, FMT_D),
10852    OPC_MOVZ_D = FOP(18, FMT_D),
10853    OPC_MOVN_D = FOP(19, FMT_D),
10854    OPC_SELEQZ_D = FOP(20, FMT_D),
10855    OPC_RECIP_D = FOP(21, FMT_D),
10856    OPC_RSQRT_D = FOP(22, FMT_D),
10857    OPC_SELNEZ_D = FOP(23, FMT_D),
10858    OPC_MADDF_D = FOP(24, FMT_D),
10859    OPC_MSUBF_D = FOP(25, FMT_D),
10860    OPC_RINT_D = FOP(26, FMT_D),
10861    OPC_CLASS_D = FOP(27, FMT_D),
10862    OPC_MIN_D = FOP(28, FMT_D),
10863    OPC_RECIP2_D = FOP(28, FMT_D),
10864    OPC_MINA_D = FOP(29, FMT_D),
10865    OPC_RECIP1_D = FOP(29, FMT_D),
10866    OPC_MAX_D = FOP(30, FMT_D),
10867    OPC_RSQRT1_D = FOP(30, FMT_D),
10868    OPC_MAXA_D = FOP(31, FMT_D),
10869    OPC_RSQRT2_D = FOP(31, FMT_D),
10870    OPC_CVT_S_D = FOP(32, FMT_D),
10871    OPC_CVT_W_D = FOP(36, FMT_D),
10872    OPC_CVT_L_D = FOP(37, FMT_D),
10873    OPC_CMP_F_D = FOP(48, FMT_D),
10874    OPC_CMP_UN_D = FOP(49, FMT_D),
10875    OPC_CMP_EQ_D = FOP(50, FMT_D),
10876    OPC_CMP_UEQ_D = FOP(51, FMT_D),
10877    OPC_CMP_OLT_D = FOP(52, FMT_D),
10878    OPC_CMP_ULT_D = FOP(53, FMT_D),
10879    OPC_CMP_OLE_D = FOP(54, FMT_D),
10880    OPC_CMP_ULE_D = FOP(55, FMT_D),
10881    OPC_CMP_SF_D = FOP(56, FMT_D),
10882    OPC_CMP_NGLE_D = FOP(57, FMT_D),
10883    OPC_CMP_SEQ_D = FOP(58, FMT_D),
10884    OPC_CMP_NGL_D = FOP(59, FMT_D),
10885    OPC_CMP_LT_D = FOP(60, FMT_D),
10886    OPC_CMP_NGE_D = FOP(61, FMT_D),
10887    OPC_CMP_LE_D = FOP(62, FMT_D),
10888    OPC_CMP_NGT_D = FOP(63, FMT_D),
10889
10890    OPC_CVT_S_W = FOP(32, FMT_W),
10891    OPC_CVT_D_W = FOP(33, FMT_W),
10892    OPC_CVT_S_L = FOP(32, FMT_L),
10893    OPC_CVT_D_L = FOP(33, FMT_L),
10894    OPC_CVT_PS_PW = FOP(38, FMT_W),
10895
10896    OPC_ADD_PS = FOP(0, FMT_PS),
10897    OPC_SUB_PS = FOP(1, FMT_PS),
10898    OPC_MUL_PS = FOP(2, FMT_PS),
10899    OPC_DIV_PS = FOP(3, FMT_PS),
10900    OPC_ABS_PS = FOP(5, FMT_PS),
10901    OPC_MOV_PS = FOP(6, FMT_PS),
10902    OPC_NEG_PS = FOP(7, FMT_PS),
10903    OPC_MOVCF_PS = FOP(17, FMT_PS),
10904    OPC_MOVZ_PS = FOP(18, FMT_PS),
10905    OPC_MOVN_PS = FOP(19, FMT_PS),
10906    OPC_ADDR_PS = FOP(24, FMT_PS),
10907    OPC_MULR_PS = FOP(26, FMT_PS),
10908    OPC_RECIP2_PS = FOP(28, FMT_PS),
10909    OPC_RECIP1_PS = FOP(29, FMT_PS),
10910    OPC_RSQRT1_PS = FOP(30, FMT_PS),
10911    OPC_RSQRT2_PS = FOP(31, FMT_PS),
10912
10913    OPC_CVT_S_PU = FOP(32, FMT_PS),
10914    OPC_CVT_PW_PS = FOP(36, FMT_PS),
10915    OPC_CVT_S_PL = FOP(40, FMT_PS),
10916    OPC_PLL_PS = FOP(44, FMT_PS),
10917    OPC_PLU_PS = FOP(45, FMT_PS),
10918    OPC_PUL_PS = FOP(46, FMT_PS),
10919    OPC_PUU_PS = FOP(47, FMT_PS),
10920    OPC_CMP_F_PS = FOP(48, FMT_PS),
10921    OPC_CMP_UN_PS = FOP(49, FMT_PS),
10922    OPC_CMP_EQ_PS = FOP(50, FMT_PS),
10923    OPC_CMP_UEQ_PS = FOP(51, FMT_PS),
10924    OPC_CMP_OLT_PS = FOP(52, FMT_PS),
10925    OPC_CMP_ULT_PS = FOP(53, FMT_PS),
10926    OPC_CMP_OLE_PS = FOP(54, FMT_PS),
10927    OPC_CMP_ULE_PS = FOP(55, FMT_PS),
10928    OPC_CMP_SF_PS = FOP(56, FMT_PS),
10929    OPC_CMP_NGLE_PS = FOP(57, FMT_PS),
10930    OPC_CMP_SEQ_PS = FOP(58, FMT_PS),
10931    OPC_CMP_NGL_PS = FOP(59, FMT_PS),
10932    OPC_CMP_LT_PS = FOP(60, FMT_PS),
10933    OPC_CMP_NGE_PS = FOP(61, FMT_PS),
10934    OPC_CMP_LE_PS = FOP(62, FMT_PS),
10935    OPC_CMP_NGT_PS = FOP(63, FMT_PS),
10936};
10937
10938enum r6_f_cmp_op {
10939    R6_OPC_CMP_AF_S   = FOP(0, FMT_W),
10940    R6_OPC_CMP_UN_S   = FOP(1, FMT_W),
10941    R6_OPC_CMP_EQ_S   = FOP(2, FMT_W),
10942    R6_OPC_CMP_UEQ_S  = FOP(3, FMT_W),
10943    R6_OPC_CMP_LT_S   = FOP(4, FMT_W),
10944    R6_OPC_CMP_ULT_S  = FOP(5, FMT_W),
10945    R6_OPC_CMP_LE_S   = FOP(6, FMT_W),
10946    R6_OPC_CMP_ULE_S  = FOP(7, FMT_W),
10947    R6_OPC_CMP_SAF_S  = FOP(8, FMT_W),
10948    R6_OPC_CMP_SUN_S  = FOP(9, FMT_W),
10949    R6_OPC_CMP_SEQ_S  = FOP(10, FMT_W),
10950    R6_OPC_CMP_SEUQ_S = FOP(11, FMT_W),
10951    R6_OPC_CMP_SLT_S  = FOP(12, FMT_W),
10952    R6_OPC_CMP_SULT_S = FOP(13, FMT_W),
10953    R6_OPC_CMP_SLE_S  = FOP(14, FMT_W),
10954    R6_OPC_CMP_SULE_S = FOP(15, FMT_W),
10955    R6_OPC_CMP_OR_S   = FOP(17, FMT_W),
10956    R6_OPC_CMP_UNE_S  = FOP(18, FMT_W),
10957    R6_OPC_CMP_NE_S   = FOP(19, FMT_W),
10958    R6_OPC_CMP_SOR_S  = FOP(25, FMT_W),
10959    R6_OPC_CMP_SUNE_S = FOP(26, FMT_W),
10960    R6_OPC_CMP_SNE_S  = FOP(27, FMT_W),
10961
10962    R6_OPC_CMP_AF_D   = FOP(0, FMT_L),
10963    R6_OPC_CMP_UN_D   = FOP(1, FMT_L),
10964    R6_OPC_CMP_EQ_D   = FOP(2, FMT_L),
10965    R6_OPC_CMP_UEQ_D  = FOP(3, FMT_L),
10966    R6_OPC_CMP_LT_D   = FOP(4, FMT_L),
10967    R6_OPC_CMP_ULT_D  = FOP(5, FMT_L),
10968    R6_OPC_CMP_LE_D   = FOP(6, FMT_L),
10969    R6_OPC_CMP_ULE_D  = FOP(7, FMT_L),
10970    R6_OPC_CMP_SAF_D  = FOP(8, FMT_L),
10971    R6_OPC_CMP_SUN_D  = FOP(9, FMT_L),
10972    R6_OPC_CMP_SEQ_D  = FOP(10, FMT_L),
10973    R6_OPC_CMP_SEUQ_D = FOP(11, FMT_L),
10974    R6_OPC_CMP_SLT_D  = FOP(12, FMT_L),
10975    R6_OPC_CMP_SULT_D = FOP(13, FMT_L),
10976    R6_OPC_CMP_SLE_D  = FOP(14, FMT_L),
10977    R6_OPC_CMP_SULE_D = FOP(15, FMT_L),
10978    R6_OPC_CMP_OR_D   = FOP(17, FMT_L),
10979    R6_OPC_CMP_UNE_D  = FOP(18, FMT_L),
10980    R6_OPC_CMP_NE_D   = FOP(19, FMT_L),
10981    R6_OPC_CMP_SOR_D  = FOP(25, FMT_L),
10982    R6_OPC_CMP_SUNE_D = FOP(26, FMT_L),
10983    R6_OPC_CMP_SNE_D  = FOP(27, FMT_L),
10984};
10985
10986static void gen_cp1(DisasContext *ctx, uint32_t opc, int rt, int fs)
10987{
10988    TCGv t0 = tcg_temp_new();
10989
10990    switch (opc) {
10991    case OPC_MFC1:
10992        {
10993            TCGv_i32 fp0 = tcg_temp_new_i32();
10994
10995            gen_load_fpr32(ctx, fp0, fs);
10996            tcg_gen_ext_i32_tl(t0, fp0);
10997            tcg_temp_free_i32(fp0);
10998        }
10999        gen_store_gpr(t0, rt);
11000        break;
11001    case OPC_MTC1:
11002        gen_load_gpr(t0, rt);
11003        {
11004            TCGv_i32 fp0 = tcg_temp_new_i32();
11005
11006            tcg_gen_trunc_tl_i32(fp0, t0);
11007            gen_store_fpr32(ctx, fp0, fs);
11008            tcg_temp_free_i32(fp0);
11009        }
11010        break;
11011    case OPC_CFC1:
11012        gen_helper_1e0i(cfc1, t0, fs);
11013        gen_store_gpr(t0, rt);
11014        break;
11015    case OPC_CTC1:
11016        gen_load_gpr(t0, rt);
11017        save_cpu_state(ctx, 0);
11018        {
11019            TCGv_i32 fs_tmp = tcg_const_i32(fs);
11020
11021            gen_helper_0e2i(ctc1, t0, fs_tmp, rt);
11022            tcg_temp_free_i32(fs_tmp);
11023        }
11024        /* Stop translation as we may have changed hflags */
11025        ctx->base.is_jmp = DISAS_STOP;
11026        break;
11027#if defined(TARGET_MIPS64)
11028    case OPC_DMFC1:
11029        gen_load_fpr64(ctx, t0, fs);
11030        gen_store_gpr(t0, rt);
11031        break;
11032    case OPC_DMTC1:
11033        gen_load_gpr(t0, rt);
11034        gen_store_fpr64(ctx, t0, fs);
11035        break;
11036#endif
11037    case OPC_MFHC1:
11038        {
11039            TCGv_i32 fp0 = tcg_temp_new_i32();
11040
11041            gen_load_fpr32h(ctx, fp0, fs);
11042            tcg_gen_ext_i32_tl(t0, fp0);
11043            tcg_temp_free_i32(fp0);
11044        }
11045        gen_store_gpr(t0, rt);
11046        break;
11047    case OPC_MTHC1:
11048        gen_load_gpr(t0, rt);
11049        {
11050            TCGv_i32 fp0 = tcg_temp_new_i32();
11051
11052            tcg_gen_trunc_tl_i32(fp0, t0);
11053            gen_store_fpr32h(ctx, fp0, fs);
11054            tcg_temp_free_i32(fp0);
11055        }
11056        break;
11057    default:
11058        MIPS_INVAL("cp1 move");
11059        generate_exception_end(ctx, EXCP_RI);
11060        goto out;
11061    }
11062
11063 out:
11064    tcg_temp_free(t0);
11065}
11066
11067static void gen_movci(DisasContext *ctx, int rd, int rs, int cc, int tf)
11068{
11069    TCGLabel *l1;
11070    TCGCond cond;
11071    TCGv_i32 t0;
11072
11073    if (rd == 0) {
11074        /* Treat as NOP. */
11075        return;
11076    }
11077
11078    if (tf) {
11079        cond = TCG_COND_EQ;
11080    } else {
11081        cond = TCG_COND_NE;
11082    }
11083
11084    l1 = gen_new_label();
11085    t0 = tcg_temp_new_i32();
11086    tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
11087    tcg_gen_brcondi_i32(cond, t0, 0, l1);
11088    tcg_temp_free_i32(t0);
11089    if (rs == 0) {
11090        tcg_gen_movi_tl(cpu_gpr[rd], 0);
11091    } else {
11092        tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
11093    }
11094    gen_set_label(l1);
11095}
11096
11097static inline void gen_movcf_s(DisasContext *ctx, int fs, int fd, int cc,
11098                               int tf)
11099{
11100    int cond;
11101    TCGv_i32 t0 = tcg_temp_new_i32();
11102    TCGLabel *l1 = gen_new_label();
11103
11104    if (tf) {
11105        cond = TCG_COND_EQ;
11106    } else {
11107        cond = TCG_COND_NE;
11108    }
11109
11110    tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
11111    tcg_gen_brcondi_i32(cond, t0, 0, l1);
11112    gen_load_fpr32(ctx, t0, fs);
11113    gen_store_fpr32(ctx, t0, fd);
11114    gen_set_label(l1);
11115    tcg_temp_free_i32(t0);
11116}
11117
11118static inline void gen_movcf_d(DisasContext *ctx, int fs, int fd, int cc,
11119                               int tf)
11120{
11121    int cond;
11122    TCGv_i32 t0 = tcg_temp_new_i32();
11123    TCGv_i64 fp0;
11124    TCGLabel *l1 = gen_new_label();
11125
11126    if (tf) {
11127        cond = TCG_COND_EQ;
11128    } else {
11129        cond = TCG_COND_NE;
11130    }
11131
11132    tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
11133    tcg_gen_brcondi_i32(cond, t0, 0, l1);
11134    tcg_temp_free_i32(t0);
11135    fp0 = tcg_temp_new_i64();
11136    gen_load_fpr64(ctx, fp0, fs);
11137    gen_store_fpr64(ctx, fp0, fd);
11138    tcg_temp_free_i64(fp0);
11139    gen_set_label(l1);
11140}
11141
11142static inline void gen_movcf_ps(DisasContext *ctx, int fs, int fd,
11143                                int cc, int tf)
11144{
11145    int cond;
11146    TCGv_i32 t0 = tcg_temp_new_i32();
11147    TCGLabel *l1 = gen_new_label();
11148    TCGLabel *l2 = gen_new_label();
11149
11150    if (tf) {
11151        cond = TCG_COND_EQ;
11152    } else {
11153        cond = TCG_COND_NE;
11154    }
11155
11156    tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
11157    tcg_gen_brcondi_i32(cond, t0, 0, l1);
11158    gen_load_fpr32(ctx, t0, fs);
11159    gen_store_fpr32(ctx, t0, fd);
11160    gen_set_label(l1);
11161
11162    tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc + 1));
11163    tcg_gen_brcondi_i32(cond, t0, 0, l2);
11164    gen_load_fpr32h(ctx, t0, fs);
11165    gen_store_fpr32h(ctx, t0, fd);
11166    tcg_temp_free_i32(t0);
11167    gen_set_label(l2);
11168}
11169
11170static void gen_sel_s(DisasContext *ctx, enum fopcode op1, int fd, int ft,
11171                      int fs)
11172{
11173    TCGv_i32 t1 = tcg_const_i32(0);
11174    TCGv_i32 fp0 = tcg_temp_new_i32();
11175    TCGv_i32 fp1 = tcg_temp_new_i32();
11176    TCGv_i32 fp2 = tcg_temp_new_i32();
11177    gen_load_fpr32(ctx, fp0, fd);
11178    gen_load_fpr32(ctx, fp1, ft);
11179    gen_load_fpr32(ctx, fp2, fs);
11180
11181    switch (op1) {
11182    case OPC_SEL_S:
11183        tcg_gen_andi_i32(fp0, fp0, 1);
11184        tcg_gen_movcond_i32(TCG_COND_NE, fp0, fp0, t1, fp1, fp2);
11185        break;
11186    case OPC_SELEQZ_S:
11187        tcg_gen_andi_i32(fp1, fp1, 1);
11188        tcg_gen_movcond_i32(TCG_COND_EQ, fp0, fp1, t1, fp2, t1);
11189        break;
11190    case OPC_SELNEZ_S:
11191        tcg_gen_andi_i32(fp1, fp1, 1);
11192        tcg_gen_movcond_i32(TCG_COND_NE, fp0, fp1, t1, fp2, t1);
11193        break;
11194    default:
11195        MIPS_INVAL("gen_sel_s");
11196        generate_exception_end(ctx, EXCP_RI);
11197        break;
11198    }
11199
11200    gen_store_fpr32(ctx, fp0, fd);
11201    tcg_temp_free_i32(fp2);
11202    tcg_temp_free_i32(fp1);
11203    tcg_temp_free_i32(fp0);
11204    tcg_temp_free_i32(t1);
11205}
11206
11207static void gen_sel_d(DisasContext *ctx, enum fopcode op1, int fd, int ft,
11208                      int fs)
11209{
11210    TCGv_i64 t1 = tcg_const_i64(0);
11211    TCGv_i64 fp0 = tcg_temp_new_i64();
11212    TCGv_i64 fp1 = tcg_temp_new_i64();
11213    TCGv_i64 fp2 = tcg_temp_new_i64();
11214    gen_load_fpr64(ctx, fp0, fd);
11215    gen_load_fpr64(ctx, fp1, ft);
11216    gen_load_fpr64(ctx, fp2, fs);
11217
11218    switch (op1) {
11219    case OPC_SEL_D:
11220        tcg_gen_andi_i64(fp0, fp0, 1);
11221        tcg_gen_movcond_i64(TCG_COND_NE, fp0, fp0, t1, fp1, fp2);
11222        break;
11223    case OPC_SELEQZ_D:
11224        tcg_gen_andi_i64(fp1, fp1, 1);
11225        tcg_gen_movcond_i64(TCG_COND_EQ, fp0, fp1, t1, fp2, t1);
11226        break;
11227    case OPC_SELNEZ_D:
11228        tcg_gen_andi_i64(fp1, fp1, 1);
11229        tcg_gen_movcond_i64(TCG_COND_NE, fp0, fp1, t1, fp2, t1);
11230        break;
11231    default:
11232        MIPS_INVAL("gen_sel_d");
11233        generate_exception_end(ctx, EXCP_RI);
11234        break;
11235    }
11236
11237    gen_store_fpr64(ctx, fp0, fd);
11238    tcg_temp_free_i64(fp2);
11239    tcg_temp_free_i64(fp1);
11240    tcg_temp_free_i64(fp0);
11241    tcg_temp_free_i64(t1);
11242}
11243
11244static void gen_farith(DisasContext *ctx, enum fopcode op1,
11245                       int ft, int fs, int fd, int cc)
11246{
11247    uint32_t func = ctx->opcode & 0x3f;
11248    switch (op1) {
11249    case OPC_ADD_S:
11250        {
11251            TCGv_i32 fp0 = tcg_temp_new_i32();
11252            TCGv_i32 fp1 = tcg_temp_new_i32();
11253
11254            gen_load_fpr32(ctx, fp0, fs);
11255            gen_load_fpr32(ctx, fp1, ft);
11256            gen_helper_float_add_s(fp0, cpu_env, fp0, fp1);
11257            tcg_temp_free_i32(fp1);
11258            gen_store_fpr32(ctx, fp0, fd);
11259            tcg_temp_free_i32(fp0);
11260        }
11261        break;
11262    case OPC_SUB_S:
11263        {
11264            TCGv_i32 fp0 = tcg_temp_new_i32();
11265            TCGv_i32 fp1 = tcg_temp_new_i32();
11266
11267            gen_load_fpr32(ctx, fp0, fs);
11268            gen_load_fpr32(ctx, fp1, ft);
11269            gen_helper_float_sub_s(fp0, cpu_env, fp0, fp1);
11270            tcg_temp_free_i32(fp1);
11271            gen_store_fpr32(ctx, fp0, fd);
11272            tcg_temp_free_i32(fp0);
11273        }
11274        break;
11275    case OPC_MUL_S:
11276        {
11277            TCGv_i32 fp0 = tcg_temp_new_i32();
11278            TCGv_i32 fp1 = tcg_temp_new_i32();
11279
11280            gen_load_fpr32(ctx, fp0, fs);
11281            gen_load_fpr32(ctx, fp1, ft);
11282            gen_helper_float_mul_s(fp0, cpu_env, fp0, fp1);
11283            tcg_temp_free_i32(fp1);
11284            gen_store_fpr32(ctx, fp0, fd);
11285            tcg_temp_free_i32(fp0);
11286        }
11287        break;
11288    case OPC_DIV_S:
11289        {
11290            TCGv_i32 fp0 = tcg_temp_new_i32();
11291            TCGv_i32 fp1 = tcg_temp_new_i32();
11292
11293            gen_load_fpr32(ctx, fp0, fs);
11294            gen_load_fpr32(ctx, fp1, ft);
11295            gen_helper_float_div_s(fp0, cpu_env, fp0, fp1);
11296            tcg_temp_free_i32(fp1);
11297            gen_store_fpr32(ctx, fp0, fd);
11298            tcg_temp_free_i32(fp0);
11299        }
11300        break;
11301    case OPC_SQRT_S:
11302        {
11303            TCGv_i32 fp0 = tcg_temp_new_i32();
11304
11305            gen_load_fpr32(ctx, fp0, fs);
11306            gen_helper_float_sqrt_s(fp0, cpu_env, fp0);
11307            gen_store_fpr32(ctx, fp0, fd);
11308            tcg_temp_free_i32(fp0);
11309        }
11310        break;
11311    case OPC_ABS_S:
11312        {
11313            TCGv_i32 fp0 = tcg_temp_new_i32();
11314
11315            gen_load_fpr32(ctx, fp0, fs);
11316            if (ctx->abs2008) {
11317                tcg_gen_andi_i32(fp0, fp0, 0x7fffffffUL);
11318            } else {
11319                gen_helper_float_abs_s(fp0, fp0);
11320            }
11321            gen_store_fpr32(ctx, fp0, fd);
11322            tcg_temp_free_i32(fp0);
11323        }
11324        break;
11325    case OPC_MOV_S:
11326        {
11327            TCGv_i32 fp0 = tcg_temp_new_i32();
11328
11329            gen_load_fpr32(ctx, fp0, fs);
11330            gen_store_fpr32(ctx, fp0, fd);
11331            tcg_temp_free_i32(fp0);
11332        }
11333        break;
11334    case OPC_NEG_S:
11335        {
11336            TCGv_i32 fp0 = tcg_temp_new_i32();
11337
11338            gen_load_fpr32(ctx, fp0, fs);
11339            if (ctx->abs2008) {
11340                tcg_gen_xori_i32(fp0, fp0, 1UL << 31);
11341            } else {
11342                gen_helper_float_chs_s(fp0, fp0);
11343            }
11344            gen_store_fpr32(ctx, fp0, fd);
11345            tcg_temp_free_i32(fp0);
11346        }
11347        break;
11348    case OPC_ROUND_L_S:
11349        check_cp1_64bitmode(ctx);
11350        {
11351            TCGv_i32 fp32 = tcg_temp_new_i32();
11352            TCGv_i64 fp64 = tcg_temp_new_i64();
11353
11354            gen_load_fpr32(ctx, fp32, fs);
11355            if (ctx->nan2008) {
11356                gen_helper_float_round_2008_l_s(fp64, cpu_env, fp32);
11357            } else {
11358                gen_helper_float_round_l_s(fp64, cpu_env, fp32);
11359            }
11360            tcg_temp_free_i32(fp32);
11361            gen_store_fpr64(ctx, fp64, fd);
11362            tcg_temp_free_i64(fp64);
11363        }
11364        break;
11365    case OPC_TRUNC_L_S:
11366        check_cp1_64bitmode(ctx);
11367        {
11368            TCGv_i32 fp32 = tcg_temp_new_i32();
11369            TCGv_i64 fp64 = tcg_temp_new_i64();
11370
11371            gen_load_fpr32(ctx, fp32, fs);
11372            if (ctx->nan2008) {
11373                gen_helper_float_trunc_2008_l_s(fp64, cpu_env, fp32);
11374            } else {
11375                gen_helper_float_trunc_l_s(fp64, cpu_env, fp32);
11376            }
11377            tcg_temp_free_i32(fp32);
11378            gen_store_fpr64(ctx, fp64, fd);
11379            tcg_temp_free_i64(fp64);
11380        }
11381        break;
11382    case OPC_CEIL_L_S:
11383        check_cp1_64bitmode(ctx);
11384        {
11385            TCGv_i32 fp32 = tcg_temp_new_i32();
11386            TCGv_i64 fp64 = tcg_temp_new_i64();
11387
11388            gen_load_fpr32(ctx, fp32, fs);
11389            if (ctx->nan2008) {
11390                gen_helper_float_ceil_2008_l_s(fp64, cpu_env, fp32);
11391            } else {
11392                gen_helper_float_ceil_l_s(fp64, cpu_env, fp32);
11393            }
11394            tcg_temp_free_i32(fp32);
11395            gen_store_fpr64(ctx, fp64, fd);
11396            tcg_temp_free_i64(fp64);
11397        }
11398        break;
11399    case OPC_FLOOR_L_S:
11400        check_cp1_64bitmode(ctx);
11401        {
11402            TCGv_i32 fp32 = tcg_temp_new_i32();
11403            TCGv_i64 fp64 = tcg_temp_new_i64();
11404
11405            gen_load_fpr32(ctx, fp32, fs);
11406            if (ctx->nan2008) {
11407                gen_helper_float_floor_2008_l_s(fp64, cpu_env, fp32);
11408            } else {
11409                gen_helper_float_floor_l_s(fp64, cpu_env, fp32);
11410            }
11411            tcg_temp_free_i32(fp32);
11412            gen_store_fpr64(ctx, fp64, fd);
11413            tcg_temp_free_i64(fp64);
11414        }
11415        break;
11416    case OPC_ROUND_W_S:
11417        {
11418            TCGv_i32 fp0 = tcg_temp_new_i32();
11419
11420            gen_load_fpr32(ctx, fp0, fs);
11421            if (ctx->nan2008) {
11422                gen_helper_float_round_2008_w_s(fp0, cpu_env, fp0);
11423            } else {
11424                gen_helper_float_round_w_s(fp0, cpu_env, fp0);
11425            }
11426            gen_store_fpr32(ctx, fp0, fd);
11427            tcg_temp_free_i32(fp0);
11428        }
11429        break;
11430    case OPC_TRUNC_W_S:
11431        {
11432            TCGv_i32 fp0 = tcg_temp_new_i32();
11433
11434            gen_load_fpr32(ctx, fp0, fs);
11435            if (ctx->nan2008) {
11436                gen_helper_float_trunc_2008_w_s(fp0, cpu_env, fp0);
11437            } else {
11438                gen_helper_float_trunc_w_s(fp0, cpu_env, fp0);
11439            }
11440            gen_store_fpr32(ctx, fp0, fd);
11441            tcg_temp_free_i32(fp0);
11442        }
11443        break;
11444    case OPC_CEIL_W_S:
11445        {
11446            TCGv_i32 fp0 = tcg_temp_new_i32();
11447
11448            gen_load_fpr32(ctx, fp0, fs);
11449            if (ctx->nan2008) {
11450                gen_helper_float_ceil_2008_w_s(fp0, cpu_env, fp0);
11451            } else {
11452                gen_helper_float_ceil_w_s(fp0, cpu_env, fp0);
11453            }
11454            gen_store_fpr32(ctx, fp0, fd);
11455            tcg_temp_free_i32(fp0);
11456        }
11457        break;
11458    case OPC_FLOOR_W_S:
11459        {
11460            TCGv_i32 fp0 = tcg_temp_new_i32();
11461
11462            gen_load_fpr32(ctx, fp0, fs);
11463            if (ctx->nan2008) {
11464                gen_helper_float_floor_2008_w_s(fp0, cpu_env, fp0);
11465            } else {
11466                gen_helper_float_floor_w_s(fp0, cpu_env, fp0);
11467            }
11468            gen_store_fpr32(ctx, fp0, fd);
11469            tcg_temp_free_i32(fp0);
11470        }
11471        break;
11472    case OPC_SEL_S:
11473        check_insn(ctx, ISA_MIPS32R6);
11474        gen_sel_s(ctx, op1, fd, ft, fs);
11475        break;
11476    case OPC_SELEQZ_S:
11477        check_insn(ctx, ISA_MIPS32R6);
11478        gen_sel_s(ctx, op1, fd, ft, fs);
11479        break;
11480    case OPC_SELNEZ_S:
11481        check_insn(ctx, ISA_MIPS32R6);
11482        gen_sel_s(ctx, op1, fd, ft, fs);
11483        break;
11484    case OPC_MOVCF_S:
11485        check_insn_opc_removed(ctx, ISA_MIPS32R6);
11486        gen_movcf_s(ctx, fs, fd, (ft >> 2) & 0x7, ft & 0x1);
11487        break;
11488    case OPC_MOVZ_S:
11489        check_insn_opc_removed(ctx, ISA_MIPS32R6);
11490        {
11491            TCGLabel *l1 = gen_new_label();
11492            TCGv_i32 fp0;
11493
11494            if (ft != 0) {
11495                tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[ft], 0, l1);
11496            }
11497            fp0 = tcg_temp_new_i32();
11498            gen_load_fpr32(ctx, fp0, fs);
11499            gen_store_fpr32(ctx, fp0, fd);
11500            tcg_temp_free_i32(fp0);
11501            gen_set_label(l1);
11502        }
11503        break;
11504    case OPC_MOVN_S:
11505        check_insn_opc_removed(ctx, ISA_MIPS32R6);
11506        {
11507            TCGLabel *l1 = gen_new_label();
11508            TCGv_i32 fp0;
11509
11510            if (ft != 0) {
11511                tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[ft], 0, l1);
11512                fp0 = tcg_temp_new_i32();
11513                gen_load_fpr32(ctx, fp0, fs);
11514                gen_store_fpr32(ctx, fp0, fd);
11515                tcg_temp_free_i32(fp0);
11516                gen_set_label(l1);
11517            }
11518        }
11519        break;
11520    case OPC_RECIP_S:
11521        {
11522            TCGv_i32 fp0 = tcg_temp_new_i32();
11523
11524            gen_load_fpr32(ctx, fp0, fs);
11525            gen_helper_float_recip_s(fp0, cpu_env, fp0);
11526            gen_store_fpr32(ctx, fp0, fd);
11527            tcg_temp_free_i32(fp0);
11528        }
11529        break;
11530    case OPC_RSQRT_S:
11531        {
11532            TCGv_i32 fp0 = tcg_temp_new_i32();
11533
11534            gen_load_fpr32(ctx, fp0, fs);
11535            gen_helper_float_rsqrt_s(fp0, cpu_env, fp0);
11536            gen_store_fpr32(ctx, fp0, fd);
11537            tcg_temp_free_i32(fp0);
11538        }
11539        break;
11540    case OPC_MADDF_S:
11541        check_insn(ctx, ISA_MIPS32R6);
11542        {
11543            TCGv_i32 fp0 = tcg_temp_new_i32();
11544            TCGv_i32 fp1 = tcg_temp_new_i32();
11545            TCGv_i32 fp2 = tcg_temp_new_i32();
11546            gen_load_fpr32(ctx, fp0, fs);
11547            gen_load_fpr32(ctx, fp1, ft);
11548            gen_load_fpr32(ctx, fp2, fd);
11549            gen_helper_float_maddf_s(fp2, cpu_env, fp0, fp1, fp2);
11550            gen_store_fpr32(ctx, fp2, fd);
11551            tcg_temp_free_i32(fp2);
11552            tcg_temp_free_i32(fp1);
11553            tcg_temp_free_i32(fp0);
11554        }
11555        break;
11556    case OPC_MSUBF_S:
11557        check_insn(ctx, ISA_MIPS32R6);
11558        {
11559            TCGv_i32 fp0 = tcg_temp_new_i32();
11560            TCGv_i32 fp1 = tcg_temp_new_i32();
11561            TCGv_i32 fp2 = tcg_temp_new_i32();
11562            gen_load_fpr32(ctx, fp0, fs);
11563            gen_load_fpr32(ctx, fp1, ft);
11564            gen_load_fpr32(ctx, fp2, fd);
11565            gen_helper_float_msubf_s(fp2, cpu_env, fp0, fp1, fp2);
11566            gen_store_fpr32(ctx, fp2, fd);
11567            tcg_temp_free_i32(fp2);
11568            tcg_temp_free_i32(fp1);
11569            tcg_temp_free_i32(fp0);
11570        }
11571        break;
11572    case OPC_RINT_S:
11573        check_insn(ctx, ISA_MIPS32R6);
11574        {
11575            TCGv_i32 fp0 = tcg_temp_new_i32();
11576            gen_load_fpr32(ctx, fp0, fs);
11577            gen_helper_float_rint_s(fp0, cpu_env, fp0);
11578            gen_store_fpr32(ctx, fp0, fd);
11579            tcg_temp_free_i32(fp0);
11580        }
11581        break;
11582    case OPC_CLASS_S:
11583        check_insn(ctx, ISA_MIPS32R6);
11584        {
11585            TCGv_i32 fp0 = tcg_temp_new_i32();
11586            gen_load_fpr32(ctx, fp0, fs);
11587            gen_helper_float_class_s(fp0, cpu_env, fp0);
11588            gen_store_fpr32(ctx, fp0, fd);
11589            tcg_temp_free_i32(fp0);
11590        }
11591        break;
11592    case OPC_MIN_S: /* OPC_RECIP2_S */
11593        if (ctx->insn_flags & ISA_MIPS32R6) {
11594            /* OPC_MIN_S */
11595            TCGv_i32 fp0 = tcg_temp_new_i32();
11596            TCGv_i32 fp1 = tcg_temp_new_i32();
11597            TCGv_i32 fp2 = tcg_temp_new_i32();
11598            gen_load_fpr32(ctx, fp0, fs);
11599            gen_load_fpr32(ctx, fp1, ft);
11600            gen_helper_float_min_s(fp2, cpu_env, fp0, fp1);
11601            gen_store_fpr32(ctx, fp2, fd);
11602            tcg_temp_free_i32(fp2);
11603            tcg_temp_free_i32(fp1);
11604            tcg_temp_free_i32(fp0);
11605        } else {
11606            /* OPC_RECIP2_S */
11607            check_cp1_64bitmode(ctx);
11608            {
11609                TCGv_i32 fp0 = tcg_temp_new_i32();
11610                TCGv_i32 fp1 = tcg_temp_new_i32();
11611
11612                gen_load_fpr32(ctx, fp0, fs);
11613                gen_load_fpr32(ctx, fp1, ft);
11614                gen_helper_float_recip2_s(fp0, cpu_env, fp0, fp1);
11615                tcg_temp_free_i32(fp1);
11616                gen_store_fpr32(ctx, fp0, fd);
11617                tcg_temp_free_i32(fp0);
11618            }
11619        }
11620        break;
11621    case OPC_MINA_S: /* OPC_RECIP1_S */
11622        if (ctx->insn_flags & ISA_MIPS32R6) {
11623            /* OPC_MINA_S */
11624            TCGv_i32 fp0 = tcg_temp_new_i32();
11625            TCGv_i32 fp1 = tcg_temp_new_i32();
11626            TCGv_i32 fp2 = tcg_temp_new_i32();
11627            gen_load_fpr32(ctx, fp0, fs);
11628            gen_load_fpr32(ctx, fp1, ft);
11629            gen_helper_float_mina_s(fp2, cpu_env, fp0, fp1);
11630            gen_store_fpr32(ctx, fp2, fd);
11631            tcg_temp_free_i32(fp2);
11632            tcg_temp_free_i32(fp1);
11633            tcg_temp_free_i32(fp0);
11634        } else {
11635            /* OPC_RECIP1_S */
11636            check_cp1_64bitmode(ctx);
11637            {
11638                TCGv_i32 fp0 = tcg_temp_new_i32();
11639
11640                gen_load_fpr32(ctx, fp0, fs);
11641                gen_helper_float_recip1_s(fp0, cpu_env, fp0);
11642                gen_store_fpr32(ctx, fp0, fd);
11643                tcg_temp_free_i32(fp0);
11644            }
11645        }
11646        break;
11647    case OPC_MAX_S: /* OPC_RSQRT1_S */
11648        if (ctx->insn_flags & ISA_MIPS32R6) {
11649            /* OPC_MAX_S */
11650            TCGv_i32 fp0 = tcg_temp_new_i32();
11651            TCGv_i32 fp1 = tcg_temp_new_i32();
11652            gen_load_fpr32(ctx, fp0, fs);
11653            gen_load_fpr32(ctx, fp1, ft);
11654            gen_helper_float_max_s(fp1, cpu_env, fp0, fp1);
11655            gen_store_fpr32(ctx, fp1, fd);
11656            tcg_temp_free_i32(fp1);
11657            tcg_temp_free_i32(fp0);
11658        } else {
11659            /* OPC_RSQRT1_S */
11660            check_cp1_64bitmode(ctx);
11661            {
11662                TCGv_i32 fp0 = tcg_temp_new_i32();
11663
11664                gen_load_fpr32(ctx, fp0, fs);
11665                gen_helper_float_rsqrt1_s(fp0, cpu_env, fp0);
11666                gen_store_fpr32(ctx, fp0, fd);
11667                tcg_temp_free_i32(fp0);
11668            }
11669        }
11670        break;
11671    case OPC_MAXA_S: /* OPC_RSQRT2_S */
11672        if (ctx->insn_flags & ISA_MIPS32R6) {
11673            /* OPC_MAXA_S */
11674            TCGv_i32 fp0 = tcg_temp_new_i32();
11675            TCGv_i32 fp1 = tcg_temp_new_i32();
11676            gen_load_fpr32(ctx, fp0, fs);
11677            gen_load_fpr32(ctx, fp1, ft);
11678            gen_helper_float_maxa_s(fp1, cpu_env, fp0, fp1);
11679            gen_store_fpr32(ctx, fp1, fd);
11680            tcg_temp_free_i32(fp1);
11681            tcg_temp_free_i32(fp0);
11682        } else {
11683            /* OPC_RSQRT2_S */
11684            check_cp1_64bitmode(ctx);
11685            {
11686                TCGv_i32 fp0 = tcg_temp_new_i32();
11687                TCGv_i32 fp1 = tcg_temp_new_i32();
11688
11689                gen_load_fpr32(ctx, fp0, fs);
11690                gen_load_fpr32(ctx, fp1, ft);
11691                gen_helper_float_rsqrt2_s(fp0, cpu_env, fp0, fp1);
11692                tcg_temp_free_i32(fp1);
11693                gen_store_fpr32(ctx, fp0, fd);
11694                tcg_temp_free_i32(fp0);
11695            }
11696        }
11697        break;
11698    case OPC_CVT_D_S:
11699        check_cp1_registers(ctx, fd);
11700        {
11701            TCGv_i32 fp32 = tcg_temp_new_i32();
11702            TCGv_i64 fp64 = tcg_temp_new_i64();
11703
11704            gen_load_fpr32(ctx, fp32, fs);
11705            gen_helper_float_cvtd_s(fp64, cpu_env, fp32);
11706            tcg_temp_free_i32(fp32);
11707            gen_store_fpr64(ctx, fp64, fd);
11708            tcg_temp_free_i64(fp64);
11709        }
11710        break;
11711    case OPC_CVT_W_S:
11712        {
11713            TCGv_i32 fp0 = tcg_temp_new_i32();
11714
11715            gen_load_fpr32(ctx, fp0, fs);
11716            if (ctx->nan2008) {
11717                gen_helper_float_cvt_2008_w_s(fp0, cpu_env, fp0);
11718            } else {
11719                gen_helper_float_cvt_w_s(fp0, cpu_env, fp0);
11720            }
11721            gen_store_fpr32(ctx, fp0, fd);
11722            tcg_temp_free_i32(fp0);
11723        }
11724        break;
11725    case OPC_CVT_L_S:
11726        check_cp1_64bitmode(ctx);
11727        {
11728            TCGv_i32 fp32 = tcg_temp_new_i32();
11729            TCGv_i64 fp64 = tcg_temp_new_i64();
11730
11731            gen_load_fpr32(ctx, fp32, fs);
11732            if (ctx->nan2008) {
11733                gen_helper_float_cvt_2008_l_s(fp64, cpu_env, fp32);
11734            } else {
11735                gen_helper_float_cvt_l_s(fp64, cpu_env, fp32);
11736            }
11737            tcg_temp_free_i32(fp32);
11738            gen_store_fpr64(ctx, fp64, fd);
11739            tcg_temp_free_i64(fp64);
11740        }
11741        break;
11742    case OPC_CVT_PS_S:
11743        check_ps(ctx);
11744        {
11745            TCGv_i64 fp64 = tcg_temp_new_i64();
11746            TCGv_i32 fp32_0 = tcg_temp_new_i32();
11747            TCGv_i32 fp32_1 = tcg_temp_new_i32();
11748
11749            gen_load_fpr32(ctx, fp32_0, fs);
11750            gen_load_fpr32(ctx, fp32_1, ft);
11751            tcg_gen_concat_i32_i64(fp64, fp32_1, fp32_0);
11752            tcg_temp_free_i32(fp32_1);
11753            tcg_temp_free_i32(fp32_0);
11754            gen_store_fpr64(ctx, fp64, fd);
11755            tcg_temp_free_i64(fp64);
11756        }
11757        break;
11758    case OPC_CMP_F_S:
11759    case OPC_CMP_UN_S:
11760    case OPC_CMP_EQ_S:
11761    case OPC_CMP_UEQ_S:
11762    case OPC_CMP_OLT_S:
11763    case OPC_CMP_ULT_S:
11764    case OPC_CMP_OLE_S:
11765    case OPC_CMP_ULE_S:
11766    case OPC_CMP_SF_S:
11767    case OPC_CMP_NGLE_S:
11768    case OPC_CMP_SEQ_S:
11769    case OPC_CMP_NGL_S:
11770    case OPC_CMP_LT_S:
11771    case OPC_CMP_NGE_S:
11772    case OPC_CMP_LE_S:
11773    case OPC_CMP_NGT_S:
11774        check_insn_opc_removed(ctx, ISA_MIPS32R6);
11775        if (ctx->opcode & (1 << 6)) {
11776            gen_cmpabs_s(ctx, func - 48, ft, fs, cc);
11777        } else {
11778            gen_cmp_s(ctx, func - 48, ft, fs, cc);
11779        }
11780        break;
11781    case OPC_ADD_D:
11782        check_cp1_registers(ctx, fs | ft | fd);
11783        {
11784            TCGv_i64 fp0 = tcg_temp_new_i64();
11785            TCGv_i64 fp1 = tcg_temp_new_i64();
11786
11787            gen_load_fpr64(ctx, fp0, fs);
11788            gen_load_fpr64(ctx, fp1, ft);
11789            gen_helper_float_add_d(fp0, cpu_env, fp0, fp1);
11790            tcg_temp_free_i64(fp1);
11791            gen_store_fpr64(ctx, fp0, fd);
11792            tcg_temp_free_i64(fp0);
11793        }
11794        break;
11795    case OPC_SUB_D:
11796        check_cp1_registers(ctx, fs | ft | fd);
11797        {
11798            TCGv_i64 fp0 = tcg_temp_new_i64();
11799            TCGv_i64 fp1 = tcg_temp_new_i64();
11800
11801            gen_load_fpr64(ctx, fp0, fs);
11802            gen_load_fpr64(ctx, fp1, ft);
11803            gen_helper_float_sub_d(fp0, cpu_env, fp0, fp1);
11804            tcg_temp_free_i64(fp1);
11805            gen_store_fpr64(ctx, fp0, fd);
11806            tcg_temp_free_i64(fp0);
11807        }
11808        break;
11809    case OPC_MUL_D:
11810        check_cp1_registers(ctx, fs | ft | fd);
11811        {
11812            TCGv_i64 fp0 = tcg_temp_new_i64();
11813            TCGv_i64 fp1 = tcg_temp_new_i64();
11814
11815            gen_load_fpr64(ctx, fp0, fs);
11816            gen_load_fpr64(ctx, fp1, ft);
11817            gen_helper_float_mul_d(fp0, cpu_env, fp0, fp1);
11818            tcg_temp_free_i64(fp1);
11819            gen_store_fpr64(ctx, fp0, fd);
11820            tcg_temp_free_i64(fp0);
11821        }
11822        break;
11823    case OPC_DIV_D:
11824        check_cp1_registers(ctx, fs | ft | fd);
11825        {
11826            TCGv_i64 fp0 = tcg_temp_new_i64();
11827            TCGv_i64 fp1 = tcg_temp_new_i64();
11828
11829            gen_load_fpr64(ctx, fp0, fs);
11830            gen_load_fpr64(ctx, fp1, ft);
11831            gen_helper_float_div_d(fp0, cpu_env, fp0, fp1);
11832            tcg_temp_free_i64(fp1);
11833            gen_store_fpr64(ctx, fp0, fd);
11834            tcg_temp_free_i64(fp0);
11835        }
11836        break;
11837    case OPC_SQRT_D:
11838        check_cp1_registers(ctx, fs | fd);
11839        {
11840            TCGv_i64 fp0 = tcg_temp_new_i64();
11841
11842            gen_load_fpr64(ctx, fp0, fs);
11843            gen_helper_float_sqrt_d(fp0, cpu_env, fp0);
11844            gen_store_fpr64(ctx, fp0, fd);
11845            tcg_temp_free_i64(fp0);
11846        }
11847        break;
11848    case OPC_ABS_D:
11849        check_cp1_registers(ctx, fs | fd);
11850        {
11851            TCGv_i64 fp0 = tcg_temp_new_i64();
11852
11853            gen_load_fpr64(ctx, fp0, fs);
11854            if (ctx->abs2008) {
11855                tcg_gen_andi_i64(fp0, fp0, 0x7fffffffffffffffULL);
11856            } else {
11857                gen_helper_float_abs_d(fp0, fp0);
11858            }
11859            gen_store_fpr64(ctx, fp0, fd);
11860            tcg_temp_free_i64(fp0);
11861        }
11862        break;
11863    case OPC_MOV_D:
11864        check_cp1_registers(ctx, fs | fd);
11865        {
11866            TCGv_i64 fp0 = tcg_temp_new_i64();
11867
11868            gen_load_fpr64(ctx, fp0, fs);
11869            gen_store_fpr64(ctx, fp0, fd);
11870            tcg_temp_free_i64(fp0);
11871        }
11872        break;
11873    case OPC_NEG_D:
11874        check_cp1_registers(ctx, fs | fd);
11875        {
11876            TCGv_i64 fp0 = tcg_temp_new_i64();
11877
11878            gen_load_fpr64(ctx, fp0, fs);
11879            if (ctx->abs2008) {
11880                tcg_gen_xori_i64(fp0, fp0, 1ULL << 63);
11881            } else {
11882                gen_helper_float_chs_d(fp0, fp0);
11883            }
11884            gen_store_fpr64(ctx, fp0, fd);
11885            tcg_temp_free_i64(fp0);
11886        }
11887        break;
11888    case OPC_ROUND_L_D:
11889        check_cp1_64bitmode(ctx);
11890        {
11891            TCGv_i64 fp0 = tcg_temp_new_i64();
11892
11893            gen_load_fpr64(ctx, fp0, fs);
11894            if (ctx->nan2008) {
11895                gen_helper_float_round_2008_l_d(fp0, cpu_env, fp0);
11896            } else {
11897                gen_helper_float_round_l_d(fp0, cpu_env, fp0);
11898            }
11899            gen_store_fpr64(ctx, fp0, fd);
11900            tcg_temp_free_i64(fp0);
11901        }
11902        break;
11903    case OPC_TRUNC_L_D:
11904        check_cp1_64bitmode(ctx);
11905        {
11906            TCGv_i64 fp0 = tcg_temp_new_i64();
11907
11908            gen_load_fpr64(ctx, fp0, fs);
11909            if (ctx->nan2008) {
11910                gen_helper_float_trunc_2008_l_d(fp0, cpu_env, fp0);
11911            } else {
11912                gen_helper_float_trunc_l_d(fp0, cpu_env, fp0);
11913            }
11914            gen_store_fpr64(ctx, fp0, fd);
11915            tcg_temp_free_i64(fp0);
11916        }
11917        break;
11918    case OPC_CEIL_L_D:
11919        check_cp1_64bitmode(ctx);
11920        {
11921            TCGv_i64 fp0 = tcg_temp_new_i64();
11922
11923            gen_load_fpr64(ctx, fp0, fs);
11924            if (ctx->nan2008) {
11925                gen_helper_float_ceil_2008_l_d(fp0, cpu_env, fp0);
11926            } else {
11927                gen_helper_float_ceil_l_d(fp0, cpu_env, fp0);
11928            }
11929            gen_store_fpr64(ctx, fp0, fd);
11930            tcg_temp_free_i64(fp0);
11931        }
11932        break;
11933    case OPC_FLOOR_L_D:
11934        check_cp1_64bitmode(ctx);
11935        {
11936            TCGv_i64 fp0 = tcg_temp_new_i64();
11937
11938            gen_load_fpr64(ctx, fp0, fs);
11939            if (ctx->nan2008) {
11940                gen_helper_float_floor_2008_l_d(fp0, cpu_env, fp0);
11941            } else {
11942                gen_helper_float_floor_l_d(fp0, cpu_env, fp0);
11943            }
11944            gen_store_fpr64(ctx, fp0, fd);
11945            tcg_temp_free_i64(fp0);
11946        }
11947        break;
11948    case OPC_ROUND_W_D:
11949        check_cp1_registers(ctx, fs);
11950        {
11951            TCGv_i32 fp32 = tcg_temp_new_i32();
11952            TCGv_i64 fp64 = tcg_temp_new_i64();
11953
11954            gen_load_fpr64(ctx, fp64, fs);
11955            if (ctx->nan2008) {
11956                gen_helper_float_round_2008_w_d(fp32, cpu_env, fp64);
11957            } else {
11958                gen_helper_float_round_w_d(fp32, cpu_env, fp64);
11959            }
11960            tcg_temp_free_i64(fp64);
11961            gen_store_fpr32(ctx, fp32, fd);
11962            tcg_temp_free_i32(fp32);
11963        }
11964        break;
11965    case OPC_TRUNC_W_D:
11966        check_cp1_registers(ctx, fs);
11967        {
11968            TCGv_i32 fp32 = tcg_temp_new_i32();
11969            TCGv_i64 fp64 = tcg_temp_new_i64();
11970
11971            gen_load_fpr64(ctx, fp64, fs);
11972            if (ctx->nan2008) {
11973                gen_helper_float_trunc_2008_w_d(fp32, cpu_env, fp64);
11974            } else {
11975                gen_helper_float_trunc_w_d(fp32, cpu_env, fp64);
11976            }
11977            tcg_temp_free_i64(fp64);
11978            gen_store_fpr32(ctx, fp32, fd);
11979            tcg_temp_free_i32(fp32);
11980        }
11981        break;
11982    case OPC_CEIL_W_D:
11983        check_cp1_registers(ctx, fs);
11984        {
11985            TCGv_i32 fp32 = tcg_temp_new_i32();
11986            TCGv_i64 fp64 = tcg_temp_new_i64();
11987
11988            gen_load_fpr64(ctx, fp64, fs);
11989            if (ctx->nan2008) {
11990                gen_helper_float_ceil_2008_w_d(fp32, cpu_env, fp64);
11991            } else {
11992                gen_helper_float_ceil_w_d(fp32, cpu_env, fp64);
11993            }
11994            tcg_temp_free_i64(fp64);
11995            gen_store_fpr32(ctx, fp32, fd);
11996            tcg_temp_free_i32(fp32);
11997        }
11998        break;
11999    case OPC_FLOOR_W_D:
12000        check_cp1_registers(ctx, fs);
12001        {
12002            TCGv_i32 fp32 = tcg_temp_new_i32();
12003            TCGv_i64 fp64 = tcg_temp_new_i64();
12004
12005            gen_load_fpr64(ctx, fp64, fs);
12006            if (ctx->nan2008) {
12007                gen_helper_float_floor_2008_w_d(fp32, cpu_env, fp64);
12008            } else {
12009                gen_helper_float_floor_w_d(fp32, cpu_env, fp64);
12010            }
12011            tcg_temp_free_i64(fp64);
12012            gen_store_fpr32(ctx, fp32, fd);
12013            tcg_temp_free_i32(fp32);
12014        }
12015        break;
12016    case OPC_SEL_D:
12017        check_insn(ctx, ISA_MIPS32R6);
12018        gen_sel_d(ctx, op1, fd, ft, fs);
12019        break;
12020    case OPC_SELEQZ_D:
12021        check_insn(ctx, ISA_MIPS32R6);
12022        gen_sel_d(ctx, op1, fd, ft, fs);
12023        break;
12024    case OPC_SELNEZ_D:
12025        check_insn(ctx, ISA_MIPS32R6);
12026        gen_sel_d(ctx, op1, fd, ft, fs);
12027        break;
12028    case OPC_MOVCF_D:
12029        check_insn_opc_removed(ctx, ISA_MIPS32R6);
12030        gen_movcf_d(ctx, fs, fd, (ft >> 2) & 0x7, ft & 0x1);
12031        break;
12032    case OPC_MOVZ_D:
12033        check_insn_opc_removed(ctx, ISA_MIPS32R6);
12034        {
12035            TCGLabel *l1 = gen_new_label();
12036            TCGv_i64 fp0;
12037
12038            if (ft != 0) {
12039                tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[ft], 0, l1);
12040            }
12041            fp0 = tcg_temp_new_i64();
12042            gen_load_fpr64(ctx, fp0, fs);
12043            gen_store_fpr64(ctx, fp0, fd);
12044            tcg_temp_free_i64(fp0);
12045            gen_set_label(l1);
12046        }
12047        break;
12048    case OPC_MOVN_D:
12049        check_insn_opc_removed(ctx, ISA_MIPS32R6);
12050        {
12051            TCGLabel *l1 = gen_new_label();
12052            TCGv_i64 fp0;
12053
12054            if (ft != 0) {
12055                tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[ft], 0, l1);
12056                fp0 = tcg_temp_new_i64();
12057                gen_load_fpr64(ctx, fp0, fs);
12058                gen_store_fpr64(ctx, fp0, fd);
12059                tcg_temp_free_i64(fp0);
12060                gen_set_label(l1);
12061            }
12062        }
12063        break;
12064    case OPC_RECIP_D:
12065        check_cp1_registers(ctx, fs | fd);
12066        {
12067            TCGv_i64 fp0 = tcg_temp_new_i64();
12068
12069            gen_load_fpr64(ctx, fp0, fs);
12070            gen_helper_float_recip_d(fp0, cpu_env, fp0);
12071            gen_store_fpr64(ctx, fp0, fd);
12072            tcg_temp_free_i64(fp0);
12073        }
12074        break;
12075    case OPC_RSQRT_D:
12076        check_cp1_registers(ctx, fs | fd);
12077        {
12078            TCGv_i64 fp0 = tcg_temp_new_i64();
12079
12080            gen_load_fpr64(ctx, fp0, fs);
12081            gen_helper_float_rsqrt_d(fp0, cpu_env, fp0);
12082            gen_store_fpr64(ctx, fp0, fd);
12083            tcg_temp_free_i64(fp0);
12084        }
12085        break;
12086    case OPC_MADDF_D:
12087        check_insn(ctx, ISA_MIPS32R6);
12088        {
12089            TCGv_i64 fp0 = tcg_temp_new_i64();
12090            TCGv_i64 fp1 = tcg_temp_new_i64();
12091            TCGv_i64 fp2 = tcg_temp_new_i64();
12092            gen_load_fpr64(ctx, fp0, fs);
12093            gen_load_fpr64(ctx, fp1, ft);
12094            gen_load_fpr64(ctx, fp2, fd);
12095            gen_helper_float_maddf_d(fp2, cpu_env, fp0, fp1, fp2);
12096            gen_store_fpr64(ctx, fp2, fd);
12097            tcg_temp_free_i64(fp2);
12098            tcg_temp_free_i64(fp1);
12099            tcg_temp_free_i64(fp0);
12100        }
12101        break;
12102    case OPC_MSUBF_D:
12103        check_insn(ctx, ISA_MIPS32R6);
12104        {
12105            TCGv_i64 fp0 = tcg_temp_new_i64();
12106            TCGv_i64 fp1 = tcg_temp_new_i64();
12107            TCGv_i64 fp2 = tcg_temp_new_i64();
12108            gen_load_fpr64(ctx, fp0, fs);
12109            gen_load_fpr64(ctx, fp1, ft);
12110            gen_load_fpr64(ctx, fp2, fd);
12111            gen_helper_float_msubf_d(fp2, cpu_env, fp0, fp1, fp2);
12112            gen_store_fpr64(ctx, fp2, fd);
12113            tcg_temp_free_i64(fp2);
12114            tcg_temp_free_i64(fp1);
12115            tcg_temp_free_i64(fp0);
12116        }
12117        break;
12118    case OPC_RINT_D:
12119        check_insn(ctx, ISA_MIPS32R6);
12120        {
12121            TCGv_i64 fp0 = tcg_temp_new_i64();
12122            gen_load_fpr64(ctx, fp0, fs);
12123            gen_helper_float_rint_d(fp0, cpu_env, fp0);
12124            gen_store_fpr64(ctx, fp0, fd);
12125            tcg_temp_free_i64(fp0);
12126        }
12127        break;
12128    case OPC_CLASS_D:
12129        check_insn(ctx, ISA_MIPS32R6);
12130        {
12131            TCGv_i64 fp0 = tcg_temp_new_i64();
12132            gen_load_fpr64(ctx, fp0, fs);
12133            gen_helper_float_class_d(fp0, cpu_env, fp0);
12134            gen_store_fpr64(ctx, fp0, fd);
12135            tcg_temp_free_i64(fp0);
12136        }
12137        break;
12138    case OPC_MIN_D: /* OPC_RECIP2_D */
12139        if (ctx->insn_flags & ISA_MIPS32R6) {
12140            /* OPC_MIN_D */
12141            TCGv_i64 fp0 = tcg_temp_new_i64();
12142            TCGv_i64 fp1 = tcg_temp_new_i64();
12143            gen_load_fpr64(ctx, fp0, fs);
12144            gen_load_fpr64(ctx, fp1, ft);
12145            gen_helper_float_min_d(fp1, cpu_env, fp0, fp1);
12146            gen_store_fpr64(ctx, fp1, fd);
12147            tcg_temp_free_i64(fp1);
12148            tcg_temp_free_i64(fp0);
12149        } else {
12150            /* OPC_RECIP2_D */
12151            check_cp1_64bitmode(ctx);
12152            {
12153                TCGv_i64 fp0 = tcg_temp_new_i64();
12154                TCGv_i64 fp1 = tcg_temp_new_i64();
12155
12156                gen_load_fpr64(ctx, fp0, fs);
12157                gen_load_fpr64(ctx, fp1, ft);
12158                gen_helper_float_recip2_d(fp0, cpu_env, fp0, fp1);
12159                tcg_temp_free_i64(fp1);
12160                gen_store_fpr64(ctx, fp0, fd);
12161                tcg_temp_free_i64(fp0);
12162            }
12163        }
12164        break;
12165    case OPC_MINA_D: /* OPC_RECIP1_D */
12166        if (ctx->insn_flags & ISA_MIPS32R6) {
12167            /* OPC_MINA_D */
12168            TCGv_i64 fp0 = tcg_temp_new_i64();
12169            TCGv_i64 fp1 = tcg_temp_new_i64();
12170            gen_load_fpr64(ctx, fp0, fs);
12171            gen_load_fpr64(ctx, fp1, ft);
12172            gen_helper_float_mina_d(fp1, cpu_env, fp0, fp1);
12173            gen_store_fpr64(ctx, fp1, fd);
12174            tcg_temp_free_i64(fp1);
12175            tcg_temp_free_i64(fp0);
12176        } else {
12177            /* OPC_RECIP1_D */
12178            check_cp1_64bitmode(ctx);
12179            {
12180                TCGv_i64 fp0 = tcg_temp_new_i64();
12181
12182                gen_load_fpr64(ctx, fp0, fs);
12183                gen_helper_float_recip1_d(fp0, cpu_env, fp0);
12184                gen_store_fpr64(ctx, fp0, fd);
12185                tcg_temp_free_i64(fp0);
12186            }
12187        }
12188        break;
12189    case OPC_MAX_D: /*  OPC_RSQRT1_D */
12190        if (ctx->insn_flags & ISA_MIPS32R6) {
12191            /* OPC_MAX_D */
12192            TCGv_i64 fp0 = tcg_temp_new_i64();
12193            TCGv_i64 fp1 = tcg_temp_new_i64();
12194            gen_load_fpr64(ctx, fp0, fs);
12195            gen_load_fpr64(ctx, fp1, ft);
12196            gen_helper_float_max_d(fp1, cpu_env, fp0, fp1);
12197            gen_store_fpr64(ctx, fp1, fd);
12198            tcg_temp_free_i64(fp1);
12199            tcg_temp_free_i64(fp0);
12200        } else {
12201            /* OPC_RSQRT1_D */
12202            check_cp1_64bitmode(ctx);
12203            {
12204                TCGv_i64 fp0 = tcg_temp_new_i64();
12205
12206                gen_load_fpr64(ctx, fp0, fs);
12207                gen_helper_float_rsqrt1_d(fp0, cpu_env, fp0);
12208                gen_store_fpr64(ctx, fp0, fd);
12209                tcg_temp_free_i64(fp0);
12210            }
12211        }
12212        break;
12213    case OPC_MAXA_D: /* OPC_RSQRT2_D */
12214        if (ctx->insn_flags & ISA_MIPS32R6) {
12215            /* OPC_MAXA_D */
12216            TCGv_i64 fp0 = tcg_temp_new_i64();
12217            TCGv_i64 fp1 = tcg_temp_new_i64();
12218            gen_load_fpr64(ctx, fp0, fs);
12219            gen_load_fpr64(ctx, fp1, ft);
12220            gen_helper_float_maxa_d(fp1, cpu_env, fp0, fp1);
12221            gen_store_fpr64(ctx, fp1, fd);
12222            tcg_temp_free_i64(fp1);
12223            tcg_temp_free_i64(fp0);
12224        } else {
12225            /* OPC_RSQRT2_D */
12226            check_cp1_64bitmode(ctx);
12227            {
12228                TCGv_i64 fp0 = tcg_temp_new_i64();
12229                TCGv_i64 fp1 = tcg_temp_new_i64();
12230
12231                gen_load_fpr64(ctx, fp0, fs);
12232                gen_load_fpr64(ctx, fp1, ft);
12233                gen_helper_float_rsqrt2_d(fp0, cpu_env, fp0, fp1);
12234                tcg_temp_free_i64(fp1);
12235                gen_store_fpr64(ctx, fp0, fd);
12236                tcg_temp_free_i64(fp0);
12237            }
12238        }
12239        break;
12240    case OPC_CMP_F_D:
12241    case OPC_CMP_UN_D:
12242    case OPC_CMP_EQ_D:
12243    case OPC_CMP_UEQ_D:
12244    case OPC_CMP_OLT_D:
12245    case OPC_CMP_ULT_D:
12246    case OPC_CMP_OLE_D:
12247    case OPC_CMP_ULE_D:
12248    case OPC_CMP_SF_D:
12249    case OPC_CMP_NGLE_D:
12250    case OPC_CMP_SEQ_D:
12251    case OPC_CMP_NGL_D:
12252    case OPC_CMP_LT_D:
12253    case OPC_CMP_NGE_D:
12254    case OPC_CMP_LE_D:
12255    case OPC_CMP_NGT_D:
12256        check_insn_opc_removed(ctx, ISA_MIPS32R6);
12257        if (ctx->opcode & (1 << 6)) {
12258            gen_cmpabs_d(ctx, func - 48, ft, fs, cc);
12259        } else {
12260            gen_cmp_d(ctx, func - 48, ft, fs, cc);
12261        }
12262        break;
12263    case OPC_CVT_S_D:
12264        check_cp1_registers(ctx, fs);
12265        {
12266            TCGv_i32 fp32 = tcg_temp_new_i32();
12267            TCGv_i64 fp64 = tcg_temp_new_i64();
12268
12269            gen_load_fpr64(ctx, fp64, fs);
12270            gen_helper_float_cvts_d(fp32, cpu_env, fp64);
12271            tcg_temp_free_i64(fp64);
12272            gen_store_fpr32(ctx, fp32, fd);
12273            tcg_temp_free_i32(fp32);
12274        }
12275        break;
12276    case OPC_CVT_W_D:
12277        check_cp1_registers(ctx, fs);
12278        {
12279            TCGv_i32 fp32 = tcg_temp_new_i32();
12280            TCGv_i64 fp64 = tcg_temp_new_i64();
12281
12282            gen_load_fpr64(ctx, fp64, fs);
12283            if (ctx->nan2008) {
12284                gen_helper_float_cvt_2008_w_d(fp32, cpu_env, fp64);
12285            } else {
12286                gen_helper_float_cvt_w_d(fp32, cpu_env, fp64);
12287            }
12288            tcg_temp_free_i64(fp64);
12289            gen_store_fpr32(ctx, fp32, fd);
12290            tcg_temp_free_i32(fp32);
12291        }
12292        break;
12293    case OPC_CVT_L_D:
12294        check_cp1_64bitmode(ctx);
12295        {
12296            TCGv_i64 fp0 = tcg_temp_new_i64();
12297
12298            gen_load_fpr64(ctx, fp0, fs);
12299            if (ctx->nan2008) {
12300                gen_helper_float_cvt_2008_l_d(fp0, cpu_env, fp0);
12301            } else {
12302                gen_helper_float_cvt_l_d(fp0, cpu_env, fp0);
12303            }
12304            gen_store_fpr64(ctx, fp0, fd);
12305            tcg_temp_free_i64(fp0);
12306        }
12307        break;
12308    case OPC_CVT_S_W:
12309        {
12310            TCGv_i32 fp0 = tcg_temp_new_i32();
12311
12312            gen_load_fpr32(ctx, fp0, fs);
12313            gen_helper_float_cvts_w(fp0, cpu_env, fp0);
12314            gen_store_fpr32(ctx, fp0, fd);
12315            tcg_temp_free_i32(fp0);
12316        }
12317        break;
12318    case OPC_CVT_D_W:
12319        check_cp1_registers(ctx, fd);
12320        {
12321            TCGv_i32 fp32 = tcg_temp_new_i32();
12322            TCGv_i64 fp64 = tcg_temp_new_i64();
12323
12324            gen_load_fpr32(ctx, fp32, fs);
12325            gen_helper_float_cvtd_w(fp64, cpu_env, fp32);
12326            tcg_temp_free_i32(fp32);
12327            gen_store_fpr64(ctx, fp64, fd);
12328            tcg_temp_free_i64(fp64);
12329        }
12330        break;
12331    case OPC_CVT_S_L:
12332        check_cp1_64bitmode(ctx);
12333        {
12334            TCGv_i32 fp32 = tcg_temp_new_i32();
12335            TCGv_i64 fp64 = tcg_temp_new_i64();
12336
12337            gen_load_fpr64(ctx, fp64, fs);
12338            gen_helper_float_cvts_l(fp32, cpu_env, fp64);
12339            tcg_temp_free_i64(fp64);
12340            gen_store_fpr32(ctx, fp32, fd);
12341            tcg_temp_free_i32(fp32);
12342        }
12343        break;
12344    case OPC_CVT_D_L:
12345        check_cp1_64bitmode(ctx);
12346        {
12347            TCGv_i64 fp0 = tcg_temp_new_i64();
12348
12349            gen_load_fpr64(ctx, fp0, fs);
12350            gen_helper_float_cvtd_l(fp0, cpu_env, fp0);
12351            gen_store_fpr64(ctx, fp0, fd);
12352            tcg_temp_free_i64(fp0);
12353        }
12354        break;
12355    case OPC_CVT_PS_PW:
12356        check_ps(ctx);
12357        {
12358            TCGv_i64 fp0 = tcg_temp_new_i64();
12359
12360            gen_load_fpr64(ctx, fp0, fs);
12361            gen_helper_float_cvtps_pw(fp0, cpu_env, fp0);
12362            gen_store_fpr64(ctx, fp0, fd);
12363            tcg_temp_free_i64(fp0);
12364        }
12365        break;
12366    case OPC_ADD_PS:
12367        check_ps(ctx);
12368        {
12369            TCGv_i64 fp0 = tcg_temp_new_i64();
12370            TCGv_i64 fp1 = tcg_temp_new_i64();
12371
12372            gen_load_fpr64(ctx, fp0, fs);
12373            gen_load_fpr64(ctx, fp1, ft);
12374            gen_helper_float_add_ps(fp0, cpu_env, fp0, fp1);
12375            tcg_temp_free_i64(fp1);
12376            gen_store_fpr64(ctx, fp0, fd);
12377            tcg_temp_free_i64(fp0);
12378        }
12379        break;
12380    case OPC_SUB_PS:
12381        check_ps(ctx);
12382        {
12383            TCGv_i64 fp0 = tcg_temp_new_i64();
12384            TCGv_i64 fp1 = tcg_temp_new_i64();
12385
12386            gen_load_fpr64(ctx, fp0, fs);
12387            gen_load_fpr64(ctx, fp1, ft);
12388            gen_helper_float_sub_ps(fp0, cpu_env, fp0, fp1);
12389            tcg_temp_free_i64(fp1);
12390            gen_store_fpr64(ctx, fp0, fd);
12391            tcg_temp_free_i64(fp0);
12392        }
12393        break;
12394    case OPC_MUL_PS:
12395        check_ps(ctx);
12396        {
12397            TCGv_i64 fp0 = tcg_temp_new_i64();
12398            TCGv_i64 fp1 = tcg_temp_new_i64();
12399
12400            gen_load_fpr64(ctx, fp0, fs);
12401            gen_load_fpr64(ctx, fp1, ft);
12402            gen_helper_float_mul_ps(fp0, cpu_env, fp0, fp1);
12403            tcg_temp_free_i64(fp1);
12404            gen_store_fpr64(ctx, fp0, fd);
12405            tcg_temp_free_i64(fp0);
12406        }
12407        break;
12408    case OPC_ABS_PS:
12409        check_ps(ctx);
12410        {
12411            TCGv_i64 fp0 = tcg_temp_new_i64();
12412
12413            gen_load_fpr64(ctx, fp0, fs);
12414            gen_helper_float_abs_ps(fp0, fp0);
12415            gen_store_fpr64(ctx, fp0, fd);
12416            tcg_temp_free_i64(fp0);
12417        }
12418        break;
12419    case OPC_MOV_PS:
12420        check_ps(ctx);
12421        {
12422            TCGv_i64 fp0 = tcg_temp_new_i64();
12423
12424            gen_load_fpr64(ctx, fp0, fs);
12425            gen_store_fpr64(ctx, fp0, fd);
12426            tcg_temp_free_i64(fp0);
12427        }
12428        break;
12429    case OPC_NEG_PS:
12430        check_ps(ctx);
12431        {
12432            TCGv_i64 fp0 = tcg_temp_new_i64();
12433
12434            gen_load_fpr64(ctx, fp0, fs);
12435            gen_helper_float_chs_ps(fp0, fp0);
12436            gen_store_fpr64(ctx, fp0, fd);
12437            tcg_temp_free_i64(fp0);
12438        }
12439        break;
12440    case OPC_MOVCF_PS:
12441        check_ps(ctx);
12442        gen_movcf_ps(ctx, fs, fd, (ft >> 2) & 0x7, ft & 0x1);
12443        break;
12444    case OPC_MOVZ_PS:
12445        check_ps(ctx);
12446        {
12447            TCGLabel *l1 = gen_new_label();
12448            TCGv_i64 fp0;
12449
12450            if (ft != 0) {
12451                tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[ft], 0, l1);
12452            }
12453            fp0 = tcg_temp_new_i64();
12454            gen_load_fpr64(ctx, fp0, fs);
12455            gen_store_fpr64(ctx, fp0, fd);
12456            tcg_temp_free_i64(fp0);
12457            gen_set_label(l1);
12458        }
12459        break;
12460    case OPC_MOVN_PS:
12461        check_ps(ctx);
12462        {
12463            TCGLabel *l1 = gen_new_label();
12464            TCGv_i64 fp0;
12465
12466            if (ft != 0) {
12467                tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[ft], 0, l1);
12468                fp0 = tcg_temp_new_i64();
12469                gen_load_fpr64(ctx, fp0, fs);
12470                gen_store_fpr64(ctx, fp0, fd);
12471                tcg_temp_free_i64(fp0);
12472                gen_set_label(l1);
12473            }
12474        }
12475        break;
12476    case OPC_ADDR_PS:
12477        check_ps(ctx);
12478        {
12479            TCGv_i64 fp0 = tcg_temp_new_i64();
12480            TCGv_i64 fp1 = tcg_temp_new_i64();
12481
12482            gen_load_fpr64(ctx, fp0, ft);
12483            gen_load_fpr64(ctx, fp1, fs);
12484            gen_helper_float_addr_ps(fp0, cpu_env, fp0, fp1);
12485            tcg_temp_free_i64(fp1);
12486            gen_store_fpr64(ctx, fp0, fd);
12487            tcg_temp_free_i64(fp0);
12488        }
12489        break;
12490    case OPC_MULR_PS:
12491        check_ps(ctx);
12492        {
12493            TCGv_i64 fp0 = tcg_temp_new_i64();
12494            TCGv_i64 fp1 = tcg_temp_new_i64();
12495
12496            gen_load_fpr64(ctx, fp0, ft);
12497            gen_load_fpr64(ctx, fp1, fs);
12498            gen_helper_float_mulr_ps(fp0, cpu_env, fp0, fp1);
12499            tcg_temp_free_i64(fp1);
12500            gen_store_fpr64(ctx, fp0, fd);
12501            tcg_temp_free_i64(fp0);
12502        }
12503        break;
12504    case OPC_RECIP2_PS:
12505        check_ps(ctx);
12506        {
12507            TCGv_i64 fp0 = tcg_temp_new_i64();
12508            TCGv_i64 fp1 = tcg_temp_new_i64();
12509
12510            gen_load_fpr64(ctx, fp0, fs);
12511            gen_load_fpr64(ctx, fp1, ft);
12512            gen_helper_float_recip2_ps(fp0, cpu_env, fp0, fp1);
12513            tcg_temp_free_i64(fp1);
12514            gen_store_fpr64(ctx, fp0, fd);
12515            tcg_temp_free_i64(fp0);
12516        }
12517        break;
12518    case OPC_RECIP1_PS:
12519        check_ps(ctx);
12520        {
12521            TCGv_i64 fp0 = tcg_temp_new_i64();
12522
12523            gen_load_fpr64(ctx, fp0, fs);
12524            gen_helper_float_recip1_ps(fp0, cpu_env, fp0);
12525            gen_store_fpr64(ctx, fp0, fd);
12526            tcg_temp_free_i64(fp0);
12527        }
12528        break;
12529    case OPC_RSQRT1_PS:
12530        check_ps(ctx);
12531        {
12532            TCGv_i64 fp0 = tcg_temp_new_i64();
12533
12534            gen_load_fpr64(ctx, fp0, fs);
12535            gen_helper_float_rsqrt1_ps(fp0, cpu_env, fp0);
12536            gen_store_fpr64(ctx, fp0, fd);
12537            tcg_temp_free_i64(fp0);
12538        }
12539        break;
12540    case OPC_RSQRT2_PS:
12541        check_ps(ctx);
12542        {
12543            TCGv_i64 fp0 = tcg_temp_new_i64();
12544            TCGv_i64 fp1 = tcg_temp_new_i64();
12545
12546            gen_load_fpr64(ctx, fp0, fs);
12547            gen_load_fpr64(ctx, fp1, ft);
12548            gen_helper_float_rsqrt2_ps(fp0, cpu_env, fp0, fp1);
12549            tcg_temp_free_i64(fp1);
12550            gen_store_fpr64(ctx, fp0, fd);
12551            tcg_temp_free_i64(fp0);
12552        }
12553        break;
12554    case OPC_CVT_S_PU:
12555        check_cp1_64bitmode(ctx);
12556        {
12557            TCGv_i32 fp0 = tcg_temp_new_i32();
12558
12559            gen_load_fpr32h(ctx, fp0, fs);
12560            gen_helper_float_cvts_pu(fp0, cpu_env, fp0);
12561            gen_store_fpr32(ctx, fp0, fd);
12562            tcg_temp_free_i32(fp0);
12563        }
12564        break;
12565    case OPC_CVT_PW_PS:
12566        check_ps(ctx);
12567        {
12568            TCGv_i64 fp0 = tcg_temp_new_i64();
12569
12570            gen_load_fpr64(ctx, fp0, fs);
12571            gen_helper_float_cvtpw_ps(fp0, cpu_env, fp0);
12572            gen_store_fpr64(ctx, fp0, fd);
12573            tcg_temp_free_i64(fp0);
12574        }
12575        break;
12576    case OPC_CVT_S_PL:
12577        check_cp1_64bitmode(ctx);
12578        {
12579            TCGv_i32 fp0 = tcg_temp_new_i32();
12580
12581            gen_load_fpr32(ctx, fp0, fs);
12582            gen_helper_float_cvts_pl(fp0, cpu_env, fp0);
12583            gen_store_fpr32(ctx, fp0, fd);
12584            tcg_temp_free_i32(fp0);
12585        }
12586        break;
12587    case OPC_PLL_PS:
12588        check_ps(ctx);
12589        {
12590            TCGv_i32 fp0 = tcg_temp_new_i32();
12591            TCGv_i32 fp1 = tcg_temp_new_i32();
12592
12593            gen_load_fpr32(ctx, fp0, fs);
12594            gen_load_fpr32(ctx, fp1, ft);
12595            gen_store_fpr32h(ctx, fp0, fd);
12596            gen_store_fpr32(ctx, fp1, fd);
12597            tcg_temp_free_i32(fp0);
12598            tcg_temp_free_i32(fp1);
12599        }
12600        break;
12601    case OPC_PLU_PS:
12602        check_ps(ctx);
12603        {
12604            TCGv_i32 fp0 = tcg_temp_new_i32();
12605            TCGv_i32 fp1 = tcg_temp_new_i32();
12606
12607            gen_load_fpr32(ctx, fp0, fs);
12608            gen_load_fpr32h(ctx, fp1, ft);
12609            gen_store_fpr32(ctx, fp1, fd);
12610            gen_store_fpr32h(ctx, fp0, fd);
12611            tcg_temp_free_i32(fp0);
12612            tcg_temp_free_i32(fp1);
12613        }
12614        break;
12615    case OPC_PUL_PS:
12616        check_ps(ctx);
12617        {
12618            TCGv_i32 fp0 = tcg_temp_new_i32();
12619            TCGv_i32 fp1 = tcg_temp_new_i32();
12620
12621            gen_load_fpr32h(ctx, fp0, fs);
12622            gen_load_fpr32(ctx, fp1, ft);
12623            gen_store_fpr32(ctx, fp1, fd);
12624            gen_store_fpr32h(ctx, fp0, fd);
12625            tcg_temp_free_i32(fp0);
12626            tcg_temp_free_i32(fp1);
12627        }
12628        break;
12629    case OPC_PUU_PS:
12630        check_ps(ctx);
12631        {
12632            TCGv_i32 fp0 = tcg_temp_new_i32();
12633            TCGv_i32 fp1 = tcg_temp_new_i32();
12634
12635            gen_load_fpr32h(ctx, fp0, fs);
12636            gen_load_fpr32h(ctx, fp1, ft);
12637            gen_store_fpr32(ctx, fp1, fd);
12638            gen_store_fpr32h(ctx, fp0, fd);
12639            tcg_temp_free_i32(fp0);
12640            tcg_temp_free_i32(fp1);
12641        }
12642        break;
12643    case OPC_CMP_F_PS:
12644    case OPC_CMP_UN_PS:
12645    case OPC_CMP_EQ_PS:
12646    case OPC_CMP_UEQ_PS:
12647    case OPC_CMP_OLT_PS:
12648    case OPC_CMP_ULT_PS:
12649    case OPC_CMP_OLE_PS:
12650    case OPC_CMP_ULE_PS:
12651    case OPC_CMP_SF_PS:
12652    case OPC_CMP_NGLE_PS:
12653    case OPC_CMP_SEQ_PS:
12654    case OPC_CMP_NGL_PS:
12655    case OPC_CMP_LT_PS:
12656    case OPC_CMP_NGE_PS:
12657    case OPC_CMP_LE_PS:
12658    case OPC_CMP_NGT_PS:
12659        if (ctx->opcode & (1 << 6)) {
12660            gen_cmpabs_ps(ctx, func - 48, ft, fs, cc);
12661        } else {
12662            gen_cmp_ps(ctx, func - 48, ft, fs, cc);
12663        }
12664        break;
12665    default:
12666        MIPS_INVAL("farith");
12667        generate_exception_end(ctx, EXCP_RI);
12668        return;
12669    }
12670}
12671
12672/* Coprocessor 3 (FPU) */
12673static void gen_flt3_ldst(DisasContext *ctx, uint32_t opc,
12674                          int fd, int fs, int base, int index)
12675{
12676    TCGv t0 = tcg_temp_new();
12677
12678    if (base == 0) {
12679        gen_load_gpr(t0, index);
12680    } else if (index == 0) {
12681        gen_load_gpr(t0, base);
12682    } else {
12683        gen_op_addr_add(ctx, t0, cpu_gpr[base], cpu_gpr[index]);
12684    }
12685    /*
12686     * Don't do NOP if destination is zero: we must perform the actual
12687     * memory access.
12688     */
12689    switch (opc) {
12690    case OPC_LWXC1:
12691        check_cop1x(ctx);
12692        {
12693            TCGv_i32 fp0 = tcg_temp_new_i32();
12694
12695            tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TESL);
12696            tcg_gen_trunc_tl_i32(fp0, t0);
12697            gen_store_fpr32(ctx, fp0, fd);
12698            tcg_temp_free_i32(fp0);
12699        }
12700        break;
12701    case OPC_LDXC1:
12702        check_cop1x(ctx);
12703        check_cp1_registers(ctx, fd);
12704        {
12705            TCGv_i64 fp0 = tcg_temp_new_i64();
12706            tcg_gen_qemu_ld_i64(fp0, t0, ctx->mem_idx, MO_TEQ);
12707            gen_store_fpr64(ctx, fp0, fd);
12708            tcg_temp_free_i64(fp0);
12709        }
12710        break;
12711    case OPC_LUXC1:
12712        check_cp1_64bitmode(ctx);
12713        tcg_gen_andi_tl(t0, t0, ~0x7);
12714        {
12715            TCGv_i64 fp0 = tcg_temp_new_i64();
12716
12717            tcg_gen_qemu_ld_i64(fp0, t0, ctx->mem_idx, MO_TEQ);
12718            gen_store_fpr64(ctx, fp0, fd);
12719            tcg_temp_free_i64(fp0);
12720        }
12721        break;
12722    case OPC_SWXC1:
12723        check_cop1x(ctx);
12724        {
12725            TCGv_i32 fp0 = tcg_temp_new_i32();
12726            gen_load_fpr32(ctx, fp0, fs);
12727            tcg_gen_qemu_st_i32(fp0, t0, ctx->mem_idx, MO_TEUL);
12728            tcg_temp_free_i32(fp0);
12729        }
12730        break;
12731    case OPC_SDXC1:
12732        check_cop1x(ctx);
12733        check_cp1_registers(ctx, fs);
12734        {
12735            TCGv_i64 fp0 = tcg_temp_new_i64();
12736            gen_load_fpr64(ctx, fp0, fs);
12737            tcg_gen_qemu_st_i64(fp0, t0, ctx->mem_idx, MO_TEQ);
12738            tcg_temp_free_i64(fp0);
12739        }
12740        break;
12741    case OPC_SUXC1:
12742        check_cp1_64bitmode(ctx);
12743        tcg_gen_andi_tl(t0, t0, ~0x7);
12744        {
12745            TCGv_i64 fp0 = tcg_temp_new_i64();
12746            gen_load_fpr64(ctx, fp0, fs);
12747            tcg_gen_qemu_st_i64(fp0, t0, ctx->mem_idx, MO_TEQ);
12748            tcg_temp_free_i64(fp0);
12749        }
12750        break;
12751    }
12752    tcg_temp_free(t0);
12753}
12754
12755static void gen_flt3_arith(DisasContext *ctx, uint32_t opc,
12756                           int fd, int fr, int fs, int ft)
12757{
12758    switch (opc) {
12759    case OPC_ALNV_PS:
12760        check_ps(ctx);
12761        {
12762            TCGv t0 = tcg_temp_local_new();
12763            TCGv_i32 fp = tcg_temp_new_i32();
12764            TCGv_i32 fph = tcg_temp_new_i32();
12765            TCGLabel *l1 = gen_new_label();
12766            TCGLabel *l2 = gen_new_label();
12767
12768            gen_load_gpr(t0, fr);
12769            tcg_gen_andi_tl(t0, t0, 0x7);
12770
12771            tcg_gen_brcondi_tl(TCG_COND_NE, t0, 0, l1);
12772            gen_load_fpr32(ctx, fp, fs);
12773            gen_load_fpr32h(ctx, fph, fs);
12774            gen_store_fpr32(ctx, fp, fd);
12775            gen_store_fpr32h(ctx, fph, fd);
12776            tcg_gen_br(l2);
12777            gen_set_label(l1);
12778            tcg_gen_brcondi_tl(TCG_COND_NE, t0, 4, l2);
12779            tcg_temp_free(t0);
12780#ifdef TARGET_WORDS_BIGENDIAN
12781            gen_load_fpr32(ctx, fp, fs);
12782            gen_load_fpr32h(ctx, fph, ft);
12783            gen_store_fpr32h(ctx, fp, fd);
12784            gen_store_fpr32(ctx, fph, fd);
12785#else
12786            gen_load_fpr32h(ctx, fph, fs);
12787            gen_load_fpr32(ctx, fp, ft);
12788            gen_store_fpr32(ctx, fph, fd);
12789            gen_store_fpr32h(ctx, fp, fd);
12790#endif
12791            gen_set_label(l2);
12792            tcg_temp_free_i32(fp);
12793            tcg_temp_free_i32(fph);
12794        }
12795        break;
12796    case OPC_MADD_S:
12797        check_cop1x(ctx);
12798        {
12799            TCGv_i32 fp0 = tcg_temp_new_i32();
12800            TCGv_i32 fp1 = tcg_temp_new_i32();
12801            TCGv_i32 fp2 = tcg_temp_new_i32();
12802
12803            gen_load_fpr32(ctx, fp0, fs);
12804            gen_load_fpr32(ctx, fp1, ft);
12805            gen_load_fpr32(ctx, fp2, fr);
12806            gen_helper_float_madd_s(fp2, cpu_env, fp0, fp1, fp2);
12807            tcg_temp_free_i32(fp0);
12808            tcg_temp_free_i32(fp1);
12809            gen_store_fpr32(ctx, fp2, fd);
12810            tcg_temp_free_i32(fp2);
12811        }
12812        break;
12813    case OPC_MADD_D:
12814        check_cop1x(ctx);
12815        check_cp1_registers(ctx, fd | fs | ft | fr);
12816        {
12817            TCGv_i64 fp0 = tcg_temp_new_i64();
12818            TCGv_i64 fp1 = tcg_temp_new_i64();
12819            TCGv_i64 fp2 = tcg_temp_new_i64();
12820
12821            gen_load_fpr64(ctx, fp0, fs);
12822            gen_load_fpr64(ctx, fp1, ft);
12823            gen_load_fpr64(ctx, fp2, fr);
12824            gen_helper_float_madd_d(fp2, cpu_env, fp0, fp1, fp2);
12825            tcg_temp_free_i64(fp0);
12826            tcg_temp_free_i64(fp1);
12827            gen_store_fpr64(ctx, fp2, fd);
12828            tcg_temp_free_i64(fp2);
12829        }
12830        break;
12831    case OPC_MADD_PS:
12832        check_ps(ctx);
12833        {
12834            TCGv_i64 fp0 = tcg_temp_new_i64();
12835            TCGv_i64 fp1 = tcg_temp_new_i64();
12836            TCGv_i64 fp2 = tcg_temp_new_i64();
12837
12838            gen_load_fpr64(ctx, fp0, fs);
12839            gen_load_fpr64(ctx, fp1, ft);
12840            gen_load_fpr64(ctx, fp2, fr);
12841            gen_helper_float_madd_ps(fp2, cpu_env, fp0, fp1, fp2);
12842            tcg_temp_free_i64(fp0);
12843            tcg_temp_free_i64(fp1);
12844            gen_store_fpr64(ctx, fp2, fd);
12845            tcg_temp_free_i64(fp2);
12846        }
12847        break;
12848    case OPC_MSUB_S:
12849        check_cop1x(ctx);
12850        {
12851            TCGv_i32 fp0 = tcg_temp_new_i32();
12852            TCGv_i32 fp1 = tcg_temp_new_i32();
12853            TCGv_i32 fp2 = tcg_temp_new_i32();
12854
12855            gen_load_fpr32(ctx, fp0, fs);
12856            gen_load_fpr32(ctx, fp1, ft);
12857            gen_load_fpr32(ctx, fp2, fr);
12858            gen_helper_float_msub_s(fp2, cpu_env, fp0, fp1, fp2);
12859            tcg_temp_free_i32(fp0);
12860            tcg_temp_free_i32(fp1);
12861            gen_store_fpr32(ctx, fp2, fd);
12862            tcg_temp_free_i32(fp2);
12863        }
12864        break;
12865    case OPC_MSUB_D:
12866        check_cop1x(ctx);
12867        check_cp1_registers(ctx, fd | fs | ft | fr);
12868        {
12869            TCGv_i64 fp0 = tcg_temp_new_i64();
12870            TCGv_i64 fp1 = tcg_temp_new_i64();
12871            TCGv_i64 fp2 = tcg_temp_new_i64();
12872
12873            gen_load_fpr64(ctx, fp0, fs);
12874            gen_load_fpr64(ctx, fp1, ft);
12875            gen_load_fpr64(ctx, fp2, fr);
12876            gen_helper_float_msub_d(fp2, cpu_env, fp0, fp1, fp2);
12877            tcg_temp_free_i64(fp0);
12878            tcg_temp_free_i64(fp1);
12879            gen_store_fpr64(ctx, fp2, fd);
12880            tcg_temp_free_i64(fp2);
12881        }
12882        break;
12883    case OPC_MSUB_PS:
12884        check_ps(ctx);
12885        {
12886            TCGv_i64 fp0 = tcg_temp_new_i64();
12887            TCGv_i64 fp1 = tcg_temp_new_i64();
12888            TCGv_i64 fp2 = tcg_temp_new_i64();
12889
12890            gen_load_fpr64(ctx, fp0, fs);
12891            gen_load_fpr64(ctx, fp1, ft);
12892            gen_load_fpr64(ctx, fp2, fr);
12893            gen_helper_float_msub_ps(fp2, cpu_env, fp0, fp1, fp2);
12894            tcg_temp_free_i64(fp0);
12895            tcg_temp_free_i64(fp1);
12896            gen_store_fpr64(ctx, fp2, fd);
12897            tcg_temp_free_i64(fp2);
12898        }
12899        break;
12900    case OPC_NMADD_S:
12901        check_cop1x(ctx);
12902        {
12903            TCGv_i32 fp0 = tcg_temp_new_i32();
12904            TCGv_i32 fp1 = tcg_temp_new_i32();
12905            TCGv_i32 fp2 = tcg_temp_new_i32();
12906
12907            gen_load_fpr32(ctx, fp0, fs);
12908            gen_load_fpr32(ctx, fp1, ft);
12909            gen_load_fpr32(ctx, fp2, fr);
12910            gen_helper_float_nmadd_s(fp2, cpu_env, fp0, fp1, fp2);
12911            tcg_temp_free_i32(fp0);
12912            tcg_temp_free_i32(fp1);
12913            gen_store_fpr32(ctx, fp2, fd);
12914            tcg_temp_free_i32(fp2);
12915        }
12916        break;
12917    case OPC_NMADD_D:
12918        check_cop1x(ctx);
12919        check_cp1_registers(ctx, fd | fs | ft | fr);
12920        {
12921            TCGv_i64 fp0 = tcg_temp_new_i64();
12922            TCGv_i64 fp1 = tcg_temp_new_i64();
12923            TCGv_i64 fp2 = tcg_temp_new_i64();
12924
12925            gen_load_fpr64(ctx, fp0, fs);
12926            gen_load_fpr64(ctx, fp1, ft);
12927            gen_load_fpr64(ctx, fp2, fr);
12928            gen_helper_float_nmadd_d(fp2, cpu_env, fp0, fp1, fp2);
12929            tcg_temp_free_i64(fp0);
12930            tcg_temp_free_i64(fp1);
12931            gen_store_fpr64(ctx, fp2, fd);
12932            tcg_temp_free_i64(fp2);
12933        }
12934        break;
12935    case OPC_NMADD_PS:
12936        check_ps(ctx);
12937        {
12938            TCGv_i64 fp0 = tcg_temp_new_i64();
12939            TCGv_i64 fp1 = tcg_temp_new_i64();
12940            TCGv_i64 fp2 = tcg_temp_new_i64();
12941
12942            gen_load_fpr64(ctx, fp0, fs);
12943            gen_load_fpr64(ctx, fp1, ft);
12944            gen_load_fpr64(ctx, fp2, fr);
12945            gen_helper_float_nmadd_ps(fp2, cpu_env, fp0, fp1, fp2);
12946            tcg_temp_free_i64(fp0);
12947            tcg_temp_free_i64(fp1);
12948            gen_store_fpr64(ctx, fp2, fd);
12949            tcg_temp_free_i64(fp2);
12950        }
12951        break;
12952    case OPC_NMSUB_S:
12953        check_cop1x(ctx);
12954        {
12955            TCGv_i32 fp0 = tcg_temp_new_i32();
12956            TCGv_i32 fp1 = tcg_temp_new_i32();
12957            TCGv_i32 fp2 = tcg_temp_new_i32();
12958
12959            gen_load_fpr32(ctx, fp0, fs);
12960            gen_load_fpr32(ctx, fp1, ft);
12961            gen_load_fpr32(ctx, fp2, fr);
12962            gen_helper_float_nmsub_s(fp2, cpu_env, fp0, fp1, fp2);
12963            tcg_temp_free_i32(fp0);
12964            tcg_temp_free_i32(fp1);
12965            gen_store_fpr32(ctx, fp2, fd);
12966            tcg_temp_free_i32(fp2);
12967        }
12968        break;
12969    case OPC_NMSUB_D:
12970        check_cop1x(ctx);
12971        check_cp1_registers(ctx, fd | fs | ft | fr);
12972        {
12973            TCGv_i64 fp0 = tcg_temp_new_i64();
12974            TCGv_i64 fp1 = tcg_temp_new_i64();
12975            TCGv_i64 fp2 = tcg_temp_new_i64();
12976
12977            gen_load_fpr64(ctx, fp0, fs);
12978            gen_load_fpr64(ctx, fp1, ft);
12979            gen_load_fpr64(ctx, fp2, fr);
12980            gen_helper_float_nmsub_d(fp2, cpu_env, fp0, fp1, fp2);
12981            tcg_temp_free_i64(fp0);
12982            tcg_temp_free_i64(fp1);
12983            gen_store_fpr64(ctx, fp2, fd);
12984            tcg_temp_free_i64(fp2);
12985        }
12986        break;
12987    case OPC_NMSUB_PS:
12988        check_ps(ctx);
12989        {
12990            TCGv_i64 fp0 = tcg_temp_new_i64();
12991            TCGv_i64 fp1 = tcg_temp_new_i64();
12992            TCGv_i64 fp2 = tcg_temp_new_i64();
12993
12994            gen_load_fpr64(ctx, fp0, fs);
12995            gen_load_fpr64(ctx, fp1, ft);
12996            gen_load_fpr64(ctx, fp2, fr);
12997            gen_helper_float_nmsub_ps(fp2, cpu_env, fp0, fp1, fp2);
12998            tcg_temp_free_i64(fp0);
12999            tcg_temp_free_i64(fp1);
13000            gen_store_fpr64(ctx, fp2, fd);
13001            tcg_temp_free_i64(fp2);
13002        }
13003        break;
13004    default:
13005        MIPS_INVAL("flt3_arith");
13006        generate_exception_end(ctx, EXCP_RI);
13007        return;
13008    }
13009}
13010
13011static void gen_rdhwr(DisasContext *ctx, int rt, int rd, int sel)
13012{
13013    TCGv t0;
13014
13015#if !defined(CONFIG_USER_ONLY)
13016    /*
13017     * The Linux kernel will emulate rdhwr if it's not supported natively.
13018     * Therefore only check the ISA in system mode.
13019     */
13020    check_insn(ctx, ISA_MIPS32R2);
13021#endif
13022    t0 = tcg_temp_new();
13023
13024    switch (rd) {
13025    case 0:
13026        gen_helper_rdhwr_cpunum(t0, cpu_env);
13027        gen_store_gpr(t0, rt);
13028        break;
13029    case 1:
13030        gen_helper_rdhwr_synci_step(t0, cpu_env);
13031        gen_store_gpr(t0, rt);
13032        break;
13033    case 2:
13034        if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
13035            gen_io_start();
13036        }
13037        gen_helper_rdhwr_cc(t0, cpu_env);
13038        gen_store_gpr(t0, rt);
13039        /*
13040         * Break the TB to be able to take timer interrupts immediately
13041         * after reading count. DISAS_STOP isn't sufficient, we need to ensure
13042         * we break completely out of translated code.
13043         */
13044        gen_save_pc(ctx->base.pc_next + 4);
13045        ctx->base.is_jmp = DISAS_EXIT;
13046        break;
13047    case 3:
13048        gen_helper_rdhwr_ccres(t0, cpu_env);
13049        gen_store_gpr(t0, rt);
13050        break;
13051    case 4:
13052        check_insn(ctx, ISA_MIPS32R6);
13053        if (sel != 0) {
13054            /*
13055             * Performance counter registers are not implemented other than
13056             * control register 0.
13057             */
13058            generate_exception(ctx, EXCP_RI);
13059        }
13060        gen_helper_rdhwr_performance(t0, cpu_env);
13061        gen_store_gpr(t0, rt);
13062        break;
13063    case 5:
13064        check_insn(ctx, ISA_MIPS32R6);
13065        gen_helper_rdhwr_xnp(t0, cpu_env);
13066        gen_store_gpr(t0, rt);
13067        break;
13068    case 29:
13069#if defined(CONFIG_USER_ONLY)
13070        tcg_gen_ld_tl(t0, cpu_env,
13071                      offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
13072        gen_store_gpr(t0, rt);
13073        break;
13074#else
13075        if ((ctx->hflags & MIPS_HFLAG_CP0) ||
13076            (ctx->hflags & MIPS_HFLAG_HWRENA_ULR)) {
13077            tcg_gen_ld_tl(t0, cpu_env,
13078                          offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
13079            gen_store_gpr(t0, rt);
13080        } else {
13081            generate_exception_end(ctx, EXCP_RI);
13082        }
13083        break;
13084#endif
13085    default:            /* Invalid */
13086        MIPS_INVAL("rdhwr");
13087        generate_exception_end(ctx, EXCP_RI);
13088        break;
13089    }
13090    tcg_temp_free(t0);
13091}
13092
13093static inline void clear_branch_hflags(DisasContext *ctx)
13094{
13095    ctx->hflags &= ~MIPS_HFLAG_BMASK;
13096    if (ctx->base.is_jmp == DISAS_NEXT) {
13097        save_cpu_state(ctx, 0);
13098    } else {
13099        /*
13100         * It is not safe to save ctx->hflags as hflags may be changed
13101         * in execution time by the instruction in delay / forbidden slot.
13102         */
13103        tcg_gen_andi_i32(hflags, hflags, ~MIPS_HFLAG_BMASK);
13104    }
13105}
13106
13107static void gen_branch(DisasContext *ctx, int insn_bytes)
13108{
13109    if (ctx->hflags & MIPS_HFLAG_BMASK) {
13110        int proc_hflags = ctx->hflags & MIPS_HFLAG_BMASK;
13111        /* Branches completion */
13112        clear_branch_hflags(ctx);
13113        ctx->base.is_jmp = DISAS_NORETURN;
13114        /* FIXME: Need to clear can_do_io.  */
13115        switch (proc_hflags & MIPS_HFLAG_BMASK_BASE) {
13116        case MIPS_HFLAG_FBNSLOT:
13117            gen_goto_tb(ctx, 0, ctx->base.pc_next + insn_bytes);
13118            break;
13119        case MIPS_HFLAG_B:
13120            /* unconditional branch */
13121            if (proc_hflags & MIPS_HFLAG_BX) {
13122                tcg_gen_xori_i32(hflags, hflags, MIPS_HFLAG_M16);
13123            }
13124            gen_goto_tb(ctx, 0, ctx->btarget);
13125            break;
13126        case MIPS_HFLAG_BL:
13127            /* blikely taken case */
13128            gen_goto_tb(ctx, 0, ctx->btarget);
13129            break;
13130        case MIPS_HFLAG_BC:
13131            /* Conditional branch */
13132            {
13133                TCGLabel *l1 = gen_new_label();
13134
13135                tcg_gen_brcondi_tl(TCG_COND_NE, bcond, 0, l1);
13136                gen_goto_tb(ctx, 1, ctx->base.pc_next + insn_bytes);
13137                gen_set_label(l1);
13138                gen_goto_tb(ctx, 0, ctx->btarget);
13139            }
13140            break;
13141        case MIPS_HFLAG_BR:
13142            /* unconditional branch to register */
13143            if (ctx->insn_flags & (ASE_MIPS16 | ASE_MICROMIPS)) {
13144                TCGv t0 = tcg_temp_new();
13145                TCGv_i32 t1 = tcg_temp_new_i32();
13146
13147                tcg_gen_andi_tl(t0, btarget, 0x1);
13148                tcg_gen_trunc_tl_i32(t1, t0);
13149                tcg_temp_free(t0);
13150                tcg_gen_andi_i32(hflags, hflags, ~(uint32_t)MIPS_HFLAG_M16);
13151                tcg_gen_shli_i32(t1, t1, MIPS_HFLAG_M16_SHIFT);
13152                tcg_gen_or_i32(hflags, hflags, t1);
13153                tcg_temp_free_i32(t1);
13154
13155                tcg_gen_andi_tl(cpu_PC, btarget, ~(target_ulong)0x1);
13156            } else {
13157                tcg_gen_mov_tl(cpu_PC, btarget);
13158            }
13159            if (ctx->base.singlestep_enabled) {
13160                save_cpu_state(ctx, 0);
13161                gen_helper_raise_exception_debug(cpu_env);
13162            }
13163            tcg_gen_lookup_and_goto_ptr();
13164            break;
13165        default:
13166            fprintf(stderr, "unknown branch 0x%x\n", proc_hflags);
13167            abort();
13168        }
13169    }
13170}
13171
13172/* Compact Branches */
13173static void gen_compute_compact_branch(DisasContext *ctx, uint32_t opc,
13174                                       int rs, int rt, int32_t offset)
13175{
13176    int bcond_compute = 0;
13177    TCGv t0 = tcg_temp_new();
13178    TCGv t1 = tcg_temp_new();
13179    int m16_lowbit = (ctx->hflags & MIPS_HFLAG_M16) != 0;
13180
13181    if (ctx->hflags & MIPS_HFLAG_BMASK) {
13182#ifdef MIPS_DEBUG_DISAS
13183        LOG_DISAS("Branch in delay / forbidden slot at PC 0x" TARGET_FMT_lx
13184                  "\n", ctx->base.pc_next);
13185#endif
13186        generate_exception_end(ctx, EXCP_RI);
13187        goto out;
13188    }
13189
13190    /* Load needed operands and calculate btarget */
13191    switch (opc) {
13192    /* compact branch */
13193    case OPC_BOVC: /* OPC_BEQZALC, OPC_BEQC */
13194    case OPC_BNVC: /* OPC_BNEZALC, OPC_BNEC */
13195        gen_load_gpr(t0, rs);
13196        gen_load_gpr(t1, rt);
13197        bcond_compute = 1;
13198        ctx->btarget = addr_add(ctx, ctx->base.pc_next + 4, offset);
13199        if (rs <= rt && rs == 0) {
13200            /* OPC_BEQZALC, OPC_BNEZALC */
13201            tcg_gen_movi_tl(cpu_gpr[31], ctx->base.pc_next + 4 + m16_lowbit);
13202        }
13203        break;
13204    case OPC_BLEZC: /* OPC_BGEZC, OPC_BGEC */
13205    case OPC_BGTZC: /* OPC_BLTZC, OPC_BLTC */
13206        gen_load_gpr(t0, rs);
13207        gen_load_gpr(t1, rt);
13208        bcond_compute = 1;
13209        ctx->btarget = addr_add(ctx, ctx->base.pc_next + 4, offset);
13210        break;
13211    case OPC_BLEZALC: /* OPC_BGEZALC, OPC_BGEUC */
13212    case OPC_BGTZALC: /* OPC_BLTZALC, OPC_BLTUC */
13213        if (rs == 0 || rs == rt) {
13214            /* OPC_BLEZALC, OPC_BGEZALC */
13215            /* OPC_BGTZALC, OPC_BLTZALC */
13216            tcg_gen_movi_tl(cpu_gpr[31], ctx->base.pc_next + 4 + m16_lowbit);
13217        }
13218        gen_load_gpr(t0, rs);
13219        gen_load_gpr(t1, rt);
13220        bcond_compute = 1;
13221        ctx->btarget = addr_add(ctx, ctx->base.pc_next + 4, offset);
13222        break;
13223    case OPC_BC:
13224    case OPC_BALC:
13225        ctx->btarget = addr_add(ctx, ctx->base.pc_next + 4, offset);
13226        break;
13227    case OPC_BEQZC:
13228    case OPC_BNEZC:
13229        if (rs != 0) {
13230            /* OPC_BEQZC, OPC_BNEZC */
13231            gen_load_gpr(t0, rs);
13232            bcond_compute = 1;
13233            ctx->btarget = addr_add(ctx, ctx->base.pc_next + 4, offset);
13234        } else {
13235            /* OPC_JIC, OPC_JIALC */
13236            TCGv tbase = tcg_temp_new();
13237            TCGv toffset = tcg_temp_new();
13238
13239            gen_load_gpr(tbase, rt);
13240            tcg_gen_movi_tl(toffset, offset);
13241            gen_op_addr_add(ctx, btarget, tbase, toffset);
13242            tcg_temp_free(tbase);
13243            tcg_temp_free(toffset);
13244        }
13245        break;
13246    default:
13247        MIPS_INVAL("Compact branch/jump");
13248        generate_exception_end(ctx, EXCP_RI);
13249        goto out;
13250    }
13251
13252    if (bcond_compute == 0) {
13253        /* Uncoditional compact branch */
13254        switch (opc) {
13255        case OPC_JIALC:
13256            tcg_gen_movi_tl(cpu_gpr[31], ctx->base.pc_next + 4 + m16_lowbit);
13257            /* Fallthrough */
13258        case OPC_JIC:
13259            ctx->hflags |= MIPS_HFLAG_BR;
13260            break;
13261        case OPC_BALC:
13262            tcg_gen_movi_tl(cpu_gpr[31], ctx->base.pc_next + 4 + m16_lowbit);
13263            /* Fallthrough */
13264        case OPC_BC:
13265            ctx->hflags |= MIPS_HFLAG_B;
13266            break;
13267        default:
13268            MIPS_INVAL("Compact branch/jump");
13269            generate_exception_end(ctx, EXCP_RI);
13270            goto out;
13271        }
13272
13273        /* Generating branch here as compact branches don't have delay slot */
13274        gen_branch(ctx, 4);
13275    } else {
13276        /* Conditional compact branch */
13277        TCGLabel *fs = gen_new_label();
13278        save_cpu_state(ctx, 0);
13279
13280        switch (opc) {
13281        case OPC_BLEZALC: /* OPC_BGEZALC, OPC_BGEUC */
13282            if (rs == 0 && rt != 0) {
13283                /* OPC_BLEZALC */
13284                tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LE), t1, 0, fs);
13285            } else if (rs != 0 && rt != 0 && rs == rt) {
13286                /* OPC_BGEZALC */
13287                tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GE), t1, 0, fs);
13288            } else {
13289                /* OPC_BGEUC */
13290                tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_GEU), t0, t1, fs);
13291            }
13292            break;
13293        case OPC_BGTZALC: /* OPC_BLTZALC, OPC_BLTUC */
13294            if (rs == 0 && rt != 0) {
13295                /* OPC_BGTZALC */
13296                tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GT), t1, 0, fs);
13297            } else if (rs != 0 && rt != 0 && rs == rt) {
13298                /* OPC_BLTZALC */
13299                tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LT), t1, 0, fs);
13300            } else {
13301                /* OPC_BLTUC */
13302                tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_LTU), t0, t1, fs);
13303            }
13304            break;
13305        case OPC_BLEZC: /* OPC_BGEZC, OPC_BGEC */
13306            if (rs == 0 && rt != 0) {
13307                /* OPC_BLEZC */
13308                tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LE), t1, 0, fs);
13309            } else if (rs != 0 && rt != 0 && rs == rt) {
13310                /* OPC_BGEZC */
13311                tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GE), t1, 0, fs);
13312            } else {
13313                /* OPC_BGEC */
13314                tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_GE), t0, t1, fs);
13315            }
13316            break;
13317        case OPC_BGTZC: /* OPC_BLTZC, OPC_BLTC */
13318            if (rs == 0 && rt != 0) {
13319                /* OPC_BGTZC */
13320                tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GT), t1, 0, fs);
13321            } else if (rs != 0 && rt != 0 && rs == rt) {
13322                /* OPC_BLTZC */
13323                tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LT), t1, 0, fs);
13324            } else {
13325                /* OPC_BLTC */
13326                tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_LT), t0, t1, fs);
13327            }
13328            break;
13329        case OPC_BOVC: /* OPC_BEQZALC, OPC_BEQC */
13330        case OPC_BNVC: /* OPC_BNEZALC, OPC_BNEC */
13331            if (rs >= rt) {
13332                /* OPC_BOVC, OPC_BNVC */
13333                TCGv t2 = tcg_temp_new();
13334                TCGv t3 = tcg_temp_new();
13335                TCGv t4 = tcg_temp_new();
13336                TCGv input_overflow = tcg_temp_new();
13337
13338                gen_load_gpr(t0, rs);
13339                gen_load_gpr(t1, rt);
13340                tcg_gen_ext32s_tl(t2, t0);
13341                tcg_gen_setcond_tl(TCG_COND_NE, input_overflow, t2, t0);
13342                tcg_gen_ext32s_tl(t3, t1);
13343                tcg_gen_setcond_tl(TCG_COND_NE, t4, t3, t1);
13344                tcg_gen_or_tl(input_overflow, input_overflow, t4);
13345
13346                tcg_gen_add_tl(t4, t2, t3);
13347                tcg_gen_ext32s_tl(t4, t4);
13348                tcg_gen_xor_tl(t2, t2, t3);
13349                tcg_gen_xor_tl(t3, t4, t3);
13350                tcg_gen_andc_tl(t2, t3, t2);
13351                tcg_gen_setcondi_tl(TCG_COND_LT, t4, t2, 0);
13352                tcg_gen_or_tl(t4, t4, input_overflow);
13353                if (opc == OPC_BOVC) {
13354                    /* OPC_BOVC */
13355                    tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_NE), t4, 0, fs);
13356                } else {
13357                    /* OPC_BNVC */
13358                    tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_EQ), t4, 0, fs);
13359                }
13360                tcg_temp_free(input_overflow);
13361                tcg_temp_free(t4);
13362                tcg_temp_free(t3);
13363                tcg_temp_free(t2);
13364            } else if (rs < rt && rs == 0) {
13365                /* OPC_BEQZALC, OPC_BNEZALC */
13366                if (opc == OPC_BEQZALC) {
13367                    /* OPC_BEQZALC */
13368                    tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_EQ), t1, 0, fs);
13369                } else {
13370                    /* OPC_BNEZALC */
13371                    tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_NE), t1, 0, fs);
13372                }
13373            } else {
13374                /* OPC_BEQC, OPC_BNEC */
13375                if (opc == OPC_BEQC) {
13376                    /* OPC_BEQC */
13377                    tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_EQ), t0, t1, fs);
13378                } else {
13379                    /* OPC_BNEC */
13380                    tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_NE), t0, t1, fs);
13381                }
13382            }
13383            break;
13384        case OPC_BEQZC:
13385            tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_EQ), t0, 0, fs);
13386            break;
13387        case OPC_BNEZC:
13388            tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_NE), t0, 0, fs);
13389            break;
13390        default:
13391            MIPS_INVAL("Compact conditional branch/jump");
13392            generate_exception_end(ctx, EXCP_RI);
13393            goto out;
13394        }
13395
13396        /* Generating branch here as compact branches don't have delay slot */
13397        gen_goto_tb(ctx, 1, ctx->btarget);
13398        gen_set_label(fs);
13399
13400        ctx->hflags |= MIPS_HFLAG_FBNSLOT;
13401    }
13402
13403out:
13404    tcg_temp_free(t0);
13405    tcg_temp_free(t1);
13406}
13407
13408/* ISA extensions (ASEs) */
13409/* MIPS16 extension to MIPS32 */
13410
13411/* MIPS16 major opcodes */
13412enum {
13413  M16_OPC_ADDIUSP = 0x00,
13414  M16_OPC_ADDIUPC = 0x01,
13415  M16_OPC_B = 0x02,
13416  M16_OPC_JAL = 0x03,
13417  M16_OPC_BEQZ = 0x04,
13418  M16_OPC_BNEQZ = 0x05,
13419  M16_OPC_SHIFT = 0x06,
13420  M16_OPC_LD = 0x07,
13421  M16_OPC_RRIA = 0x08,
13422  M16_OPC_ADDIU8 = 0x09,
13423  M16_OPC_SLTI = 0x0a,
13424  M16_OPC_SLTIU = 0x0b,
13425  M16_OPC_I8 = 0x0c,
13426  M16_OPC_LI = 0x0d,
13427  M16_OPC_CMPI = 0x0e,
13428  M16_OPC_SD = 0x0f,
13429  M16_OPC_LB = 0x10,
13430  M16_OPC_LH = 0x11,
13431  M16_OPC_LWSP = 0x12,
13432  M16_OPC_LW = 0x13,
13433  M16_OPC_LBU = 0x14,
13434  M16_OPC_LHU = 0x15,
13435  M16_OPC_LWPC = 0x16,
13436  M16_OPC_LWU = 0x17,
13437  M16_OPC_SB = 0x18,
13438  M16_OPC_SH = 0x19,
13439  M16_OPC_SWSP = 0x1a,
13440  M16_OPC_SW = 0x1b,
13441  M16_OPC_RRR = 0x1c,
13442  M16_OPC_RR = 0x1d,
13443  M16_OPC_EXTEND = 0x1e,
13444  M16_OPC_I64 = 0x1f
13445};
13446
13447/* I8 funct field */
13448enum {
13449  I8_BTEQZ = 0x0,
13450  I8_BTNEZ = 0x1,
13451  I8_SWRASP = 0x2,
13452  I8_ADJSP = 0x3,
13453  I8_SVRS = 0x4,
13454  I8_MOV32R = 0x5,
13455  I8_MOVR32 = 0x7
13456};
13457
13458/* RRR f field */
13459enum {
13460  RRR_DADDU = 0x0,
13461  RRR_ADDU = 0x1,
13462  RRR_DSUBU = 0x2,
13463  RRR_SUBU = 0x3
13464};
13465
13466/* RR funct field */
13467enum {
13468  RR_JR = 0x00,
13469  RR_SDBBP = 0x01,
13470  RR_SLT = 0x02,
13471  RR_SLTU = 0x03,
13472  RR_SLLV = 0x04,
13473  RR_BREAK = 0x05,
13474  RR_SRLV = 0x06,
13475  RR_SRAV = 0x07,
13476  RR_DSRL = 0x08,
13477  RR_CMP = 0x0a,
13478  RR_NEG = 0x0b,
13479  RR_AND = 0x0c,
13480  RR_OR = 0x0d,
13481  RR_XOR = 0x0e,
13482  RR_NOT = 0x0f,
13483  RR_MFHI = 0x10,
13484  RR_CNVT = 0x11,
13485  RR_MFLO = 0x12,
13486  RR_DSRA = 0x13,
13487  RR_DSLLV = 0x14,
13488  RR_DSRLV = 0x16,
13489  RR_DSRAV = 0x17,
13490  RR_MULT = 0x18,
13491  RR_MULTU = 0x19,
13492  RR_DIV = 0x1a,
13493  RR_DIVU = 0x1b,
13494  RR_DMULT = 0x1c,
13495  RR_DMULTU = 0x1d,
13496  RR_DDIV = 0x1e,
13497  RR_DDIVU = 0x1f
13498};
13499
13500/* I64 funct field */
13501enum {
13502  I64_LDSP = 0x0,
13503  I64_SDSP = 0x1,
13504  I64_SDRASP = 0x2,
13505  I64_DADJSP = 0x3,
13506  I64_LDPC = 0x4,
13507  I64_DADDIU5 = 0x5,
13508  I64_DADDIUPC = 0x6,
13509  I64_DADDIUSP = 0x7
13510};
13511
13512/* RR ry field for CNVT */
13513enum {
13514  RR_RY_CNVT_ZEB = 0x0,
13515  RR_RY_CNVT_ZEH = 0x1,
13516  RR_RY_CNVT_ZEW = 0x2,
13517  RR_RY_CNVT_SEB = 0x4,
13518  RR_RY_CNVT_SEH = 0x5,
13519  RR_RY_CNVT_SEW = 0x6,
13520};
13521
13522static int xlat(int r)
13523{
13524  static int map[] = { 16, 17, 2, 3, 4, 5, 6, 7 };
13525
13526  return map[r];
13527}
13528
13529static void gen_mips16_save(DisasContext *ctx,
13530                            int xsregs, int aregs,
13531                            int do_ra, int do_s0, int do_s1,
13532                            int framesize)
13533{
13534    TCGv t0 = tcg_temp_new();
13535    TCGv t1 = tcg_temp_new();
13536    TCGv t2 = tcg_temp_new();
13537    int args, astatic;
13538
13539    switch (aregs) {
13540    case 0:
13541    case 1:
13542    case 2:
13543    case 3:
13544    case 11:
13545        args = 0;
13546        break;
13547    case 4:
13548    case 5:
13549    case 6:
13550    case 7:
13551        args = 1;
13552        break;
13553    case 8:
13554    case 9:
13555    case 10:
13556        args = 2;
13557        break;
13558    case 12:
13559    case 13:
13560        args = 3;
13561        break;
13562    case 14:
13563        args = 4;
13564        break;
13565    default:
13566        generate_exception_end(ctx, EXCP_RI);
13567        return;
13568    }
13569
13570    switch (args) {
13571    case 4:
13572        gen_base_offset_addr(ctx, t0, 29, 12);
13573        gen_load_gpr(t1, 7);
13574        tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL);
13575        /* Fall through */
13576    case 3:
13577        gen_base_offset_addr(ctx, t0, 29, 8);
13578        gen_load_gpr(t1, 6);
13579        tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL);
13580        /* Fall through */
13581    case 2:
13582        gen_base_offset_addr(ctx, t0, 29, 4);
13583        gen_load_gpr(t1, 5);
13584        tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL);
13585        /* Fall through */
13586    case 1:
13587        gen_base_offset_addr(ctx, t0, 29, 0);
13588        gen_load_gpr(t1, 4);
13589        tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL);
13590    }
13591
13592    gen_load_gpr(t0, 29);
13593
13594#define DECR_AND_STORE(reg) do {                                 \
13595        tcg_gen_movi_tl(t2, -4);                                 \
13596        gen_op_addr_add(ctx, t0, t0, t2);                        \
13597        gen_load_gpr(t1, reg);                                   \
13598        tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL); \
13599    } while (0)
13600
13601    if (do_ra) {
13602        DECR_AND_STORE(31);
13603    }
13604
13605    switch (xsregs) {
13606    case 7:
13607        DECR_AND_STORE(30);
13608        /* Fall through */
13609    case 6:
13610        DECR_AND_STORE(23);
13611        /* Fall through */
13612    case 5:
13613        DECR_AND_STORE(22);
13614        /* Fall through */
13615    case 4:
13616        DECR_AND_STORE(21);
13617        /* Fall through */
13618    case 3:
13619        DECR_AND_STORE(20);
13620        /* Fall through */
13621    case 2:
13622        DECR_AND_STORE(19);
13623        /* Fall through */
13624    case 1:
13625        DECR_AND_STORE(18);
13626    }
13627
13628    if (do_s1) {
13629        DECR_AND_STORE(17);
13630    }
13631    if (do_s0) {
13632        DECR_AND_STORE(16);
13633    }
13634
13635    switch (aregs) {
13636    case 0:
13637    case 4:
13638    case 8:
13639    case 12:
13640    case 14:
13641        astatic = 0;
13642        break;
13643    case 1:
13644    case 5:
13645    case 9:
13646    case 13:
13647        astatic = 1;
13648        break;
13649    case 2:
13650    case 6:
13651    case 10:
13652        astatic = 2;
13653        break;
13654    case 3:
13655    case 7:
13656        astatic = 3;
13657        break;
13658    case 11:
13659        astatic = 4;
13660        break;
13661    default:
13662        generate_exception_end(ctx, EXCP_RI);
13663        return;
13664    }
13665
13666    if (astatic > 0) {
13667        DECR_AND_STORE(7);
13668        if (astatic > 1) {
13669            DECR_AND_STORE(6);
13670            if (astatic > 2) {
13671                DECR_AND_STORE(5);
13672                if (astatic > 3) {
13673                    DECR_AND_STORE(4);
13674                }
13675            }
13676        }
13677    }
13678#undef DECR_AND_STORE
13679
13680    tcg_gen_movi_tl(t2, -framesize);
13681    gen_op_addr_add(ctx, cpu_gpr[29], cpu_gpr[29], t2);
13682    tcg_temp_free(t0);
13683    tcg_temp_free(t1);
13684    tcg_temp_free(t2);
13685}
13686
13687static void gen_mips16_restore(DisasContext *ctx,
13688                               int xsregs, int aregs,
13689                               int do_ra, int do_s0, int do_s1,
13690                               int framesize)
13691{
13692    int astatic;
13693    TCGv t0 = tcg_temp_new();
13694    TCGv t1 = tcg_temp_new();
13695    TCGv t2 = tcg_temp_new();
13696
13697    tcg_gen_movi_tl(t2, framesize);
13698    gen_op_addr_add(ctx, t0, cpu_gpr[29], t2);
13699
13700#define DECR_AND_LOAD(reg) do {                            \
13701        tcg_gen_movi_tl(t2, -4);                           \
13702        gen_op_addr_add(ctx, t0, t0, t2);                  \
13703        tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TESL); \
13704        gen_store_gpr(t1, reg);                            \
13705    } while (0)
13706
13707    if (do_ra) {
13708        DECR_AND_LOAD(31);
13709    }
13710
13711    switch (xsregs) {
13712    case 7:
13713        DECR_AND_LOAD(30);
13714        /* Fall through */
13715    case 6:
13716        DECR_AND_LOAD(23);
13717        /* Fall through */
13718    case 5:
13719        DECR_AND_LOAD(22);
13720        /* Fall through */
13721    case 4:
13722        DECR_AND_LOAD(21);
13723        /* Fall through */
13724    case 3:
13725        DECR_AND_LOAD(20);
13726        /* Fall through */
13727    case 2:
13728        DECR_AND_LOAD(19);
13729        /* Fall through */
13730    case 1:
13731        DECR_AND_LOAD(18);
13732    }
13733
13734    if (do_s1) {
13735        DECR_AND_LOAD(17);
13736    }
13737    if (do_s0) {
13738        DECR_AND_LOAD(16);
13739    }
13740
13741    switch (aregs) {
13742    case 0:
13743    case 4:
13744    case 8:
13745    case 12:
13746    case 14:
13747        astatic = 0;
13748        break;
13749    case 1:
13750    case 5:
13751    case 9:
13752    case 13:
13753        astatic = 1;
13754        break;
13755    case 2:
13756    case 6:
13757    case 10:
13758        astatic = 2;
13759        break;
13760    case 3:
13761    case 7:
13762        astatic = 3;
13763        break;
13764    case 11:
13765        astatic = 4;
13766        break;
13767    default:
13768        generate_exception_end(ctx, EXCP_RI);
13769        return;
13770    }
13771
13772    if (astatic > 0) {
13773        DECR_AND_LOAD(7);
13774        if (astatic > 1) {
13775            DECR_AND_LOAD(6);
13776            if (astatic > 2) {
13777                DECR_AND_LOAD(5);
13778                if (astatic > 3) {
13779                    DECR_AND_LOAD(4);
13780                }
13781            }
13782        }
13783    }
13784#undef DECR_AND_LOAD
13785
13786    tcg_gen_movi_tl(t2, framesize);
13787    gen_op_addr_add(ctx, cpu_gpr[29], cpu_gpr[29], t2);
13788    tcg_temp_free(t0);
13789    tcg_temp_free(t1);
13790    tcg_temp_free(t2);
13791}
13792
13793static void gen_addiupc(DisasContext *ctx, int rx, int imm,
13794                        int is_64_bit, int extended)
13795{
13796    TCGv t0;
13797
13798    if (extended && (ctx->hflags & MIPS_HFLAG_BMASK)) {
13799        generate_exception_end(ctx, EXCP_RI);
13800        return;
13801    }
13802
13803    t0 = tcg_temp_new();
13804
13805    tcg_gen_movi_tl(t0, pc_relative_pc(ctx));
13806    tcg_gen_addi_tl(cpu_gpr[rx], t0, imm);
13807    if (!is_64_bit) {
13808        tcg_gen_ext32s_tl(cpu_gpr[rx], cpu_gpr[rx]);
13809    }
13810
13811    tcg_temp_free(t0);
13812}
13813
13814static void gen_cache_operation(DisasContext *ctx, uint32_t op, int base,
13815                                int16_t offset)
13816{
13817    TCGv_i32 t0 = tcg_const_i32(op);
13818    TCGv t1 = tcg_temp_new();
13819    gen_base_offset_addr(ctx, t1, base, offset);
13820    gen_helper_cache(cpu_env, t1, t0);
13821}
13822
13823#if defined(TARGET_MIPS64)
13824static void decode_i64_mips16(DisasContext *ctx,
13825                              int ry, int funct, int16_t offset,
13826                              int extended)
13827{
13828    switch (funct) {
13829    case I64_LDSP:
13830        check_insn(ctx, ISA_MIPS3);
13831        check_mips_64(ctx);
13832        offset = extended ? offset : offset << 3;
13833        gen_ld(ctx, OPC_LD, ry, 29, offset);
13834        break;
13835    case I64_SDSP:
13836        check_insn(ctx, ISA_MIPS3);
13837        check_mips_64(ctx);
13838        offset = extended ? offset : offset << 3;
13839        gen_st(ctx, OPC_SD, ry, 29, offset);
13840        break;
13841    case I64_SDRASP:
13842        check_insn(ctx, ISA_MIPS3);
13843        check_mips_64(ctx);
13844        offset = extended ? offset : (ctx->opcode & 0xff) << 3;
13845        gen_st(ctx, OPC_SD, 31, 29, offset);
13846        break;
13847    case I64_DADJSP:
13848        check_insn(ctx, ISA_MIPS3);
13849        check_mips_64(ctx);
13850        offset = extended ? offset : ((int8_t)ctx->opcode) << 3;
13851        gen_arith_imm(ctx, OPC_DADDIU, 29, 29, offset);
13852        break;
13853    case I64_LDPC:
13854        check_insn(ctx, ISA_MIPS3);
13855        check_mips_64(ctx);
13856        if (extended && (ctx->hflags & MIPS_HFLAG_BMASK)) {
13857            generate_exception_end(ctx, EXCP_RI);
13858        } else {
13859            offset = extended ? offset : offset << 3;
13860            gen_ld(ctx, OPC_LDPC, ry, 0, offset);
13861        }
13862        break;
13863    case I64_DADDIU5:
13864        check_insn(ctx, ISA_MIPS3);
13865        check_mips_64(ctx);
13866        offset = extended ? offset : ((int8_t)(offset << 3)) >> 3;
13867        gen_arith_imm(ctx, OPC_DADDIU, ry, ry, offset);
13868        break;
13869    case I64_DADDIUPC:
13870        check_insn(ctx, ISA_MIPS3);
13871        check_mips_64(ctx);
13872        offset = extended ? offset : offset << 2;
13873        gen_addiupc(ctx, ry, offset, 1, extended);
13874        break;
13875    case I64_DADDIUSP:
13876        check_insn(ctx, ISA_MIPS3);
13877        check_mips_64(ctx);
13878        offset = extended ? offset : offset << 2;
13879        gen_arith_imm(ctx, OPC_DADDIU, ry, 29, offset);
13880        break;
13881    }
13882}
13883#endif
13884
13885static int decode_extended_mips16_opc(CPUMIPSState *env, DisasContext *ctx)
13886{
13887    int extend = cpu_lduw_code(env, ctx->base.pc_next + 2);
13888    int op, rx, ry, funct, sa;
13889    int16_t imm, offset;
13890
13891    ctx->opcode = (ctx->opcode << 16) | extend;
13892    op = (ctx->opcode >> 11) & 0x1f;
13893    sa = (ctx->opcode >> 22) & 0x1f;
13894    funct = (ctx->opcode >> 8) & 0x7;
13895    rx = xlat((ctx->opcode >> 8) & 0x7);
13896    ry = xlat((ctx->opcode >> 5) & 0x7);
13897    offset = imm = (int16_t) (((ctx->opcode >> 16) & 0x1f) << 11
13898                              | ((ctx->opcode >> 21) & 0x3f) << 5
13899                              | (ctx->opcode & 0x1f));
13900
13901    /*
13902     * The extended opcodes cleverly reuse the opcodes from their 16-bit
13903     * counterparts.
13904     */
13905    switch (op) {
13906    case M16_OPC_ADDIUSP:
13907        gen_arith_imm(ctx, OPC_ADDIU, rx, 29, imm);
13908        break;
13909    case M16_OPC_ADDIUPC:
13910        gen_addiupc(ctx, rx, imm, 0, 1);
13911        break;
13912    case M16_OPC_B:
13913        gen_compute_branch(ctx, OPC_BEQ, 4, 0, 0, offset << 1, 0);
13914        /* No delay slot, so just process as a normal instruction */
13915        break;
13916    case M16_OPC_BEQZ:
13917        gen_compute_branch(ctx, OPC_BEQ, 4, rx, 0, offset << 1, 0);
13918        /* No delay slot, so just process as a normal instruction */
13919        break;
13920    case M16_OPC_BNEQZ:
13921        gen_compute_branch(ctx, OPC_BNE, 4, rx, 0, offset << 1, 0);
13922        /* No delay slot, so just process as a normal instruction */
13923        break;
13924    case M16_OPC_SHIFT:
13925        switch (ctx->opcode & 0x3) {
13926        case 0x0:
13927            gen_shift_imm(ctx, OPC_SLL, rx, ry, sa);
13928            break;
13929        case 0x1:
13930#if defined(TARGET_MIPS64)
13931            check_mips_64(ctx);
13932            gen_shift_imm(ctx, OPC_DSLL, rx, ry, sa);
13933#else
13934            generate_exception_end(ctx, EXCP_RI);
13935#endif
13936            break;
13937        case 0x2:
13938            gen_shift_imm(ctx, OPC_SRL, rx, ry, sa);
13939            break;
13940        case 0x3:
13941            gen_shift_imm(ctx, OPC_SRA, rx, ry, sa);
13942            break;
13943        }
13944        break;
13945#if defined(TARGET_MIPS64)
13946    case M16_OPC_LD:
13947        check_insn(ctx, ISA_MIPS3);
13948        check_mips_64(ctx);
13949        gen_ld(ctx, OPC_LD, ry, rx, offset);
13950        break;
13951#endif
13952    case M16_OPC_RRIA:
13953        imm = ctx->opcode & 0xf;
13954        imm = imm | ((ctx->opcode >> 20) & 0x7f) << 4;
13955        imm = imm | ((ctx->opcode >> 16) & 0xf) << 11;
13956        imm = (int16_t) (imm << 1) >> 1;
13957        if ((ctx->opcode >> 4) & 0x1) {
13958#if defined(TARGET_MIPS64)
13959            check_mips_64(ctx);
13960            gen_arith_imm(ctx, OPC_DADDIU, ry, rx, imm);
13961#else
13962            generate_exception_end(ctx, EXCP_RI);
13963#endif
13964        } else {
13965            gen_arith_imm(ctx, OPC_ADDIU, ry, rx, imm);
13966        }
13967        break;
13968    case M16_OPC_ADDIU8:
13969        gen_arith_imm(ctx, OPC_ADDIU, rx, rx, imm);
13970        break;
13971    case M16_OPC_SLTI:
13972        gen_slt_imm(ctx, OPC_SLTI, 24, rx, imm);
13973        break;
13974    case M16_OPC_SLTIU:
13975        gen_slt_imm(ctx, OPC_SLTIU, 24, rx, imm);
13976        break;
13977    case M16_OPC_I8:
13978        switch (funct) {
13979        case I8_BTEQZ:
13980            gen_compute_branch(ctx, OPC_BEQ, 4, 24, 0, offset << 1, 0);
13981            break;
13982        case I8_BTNEZ:
13983            gen_compute_branch(ctx, OPC_BNE, 4, 24, 0, offset << 1, 0);
13984            break;
13985        case I8_SWRASP:
13986            gen_st(ctx, OPC_SW, 31, 29, imm);
13987            break;
13988        case I8_ADJSP:
13989            gen_arith_imm(ctx, OPC_ADDIU, 29, 29, imm);
13990            break;
13991        case I8_SVRS:
13992            check_insn(ctx, ISA_MIPS32);
13993            {
13994                int xsregs = (ctx->opcode >> 24) & 0x7;
13995                int aregs = (ctx->opcode >> 16) & 0xf;
13996                int do_ra = (ctx->opcode >> 6) & 0x1;
13997                int do_s0 = (ctx->opcode >> 5) & 0x1;
13998                int do_s1 = (ctx->opcode >> 4) & 0x1;
13999                int framesize = (((ctx->opcode >> 20) & 0xf) << 4
14000                                 | (ctx->opcode & 0xf)) << 3;
14001
14002                if (ctx->opcode & (1 << 7)) {
14003                    gen_mips16_save(ctx, xsregs, aregs,
14004                                    do_ra, do_s0, do_s1,
14005                                    framesize);
14006                } else {
14007                    gen_mips16_restore(ctx, xsregs, aregs,
14008                                       do_ra, do_s0, do_s1,
14009                                       framesize);
14010                }
14011            }
14012            break;
14013        default:
14014            generate_exception_end(ctx, EXCP_RI);
14015            break;
14016        }
14017        break;
14018    case M16_OPC_LI:
14019        tcg_gen_movi_tl(cpu_gpr[rx], (uint16_t) imm);
14020        break;
14021    case M16_OPC_CMPI:
14022        tcg_gen_xori_tl(cpu_gpr[24], cpu_gpr[rx], (uint16_t) imm);
14023        break;
14024#if defined(TARGET_MIPS64)
14025    case M16_OPC_SD:
14026        check_insn(ctx, ISA_MIPS3);
14027        check_mips_64(ctx);
14028        gen_st(ctx, OPC_SD, ry, rx, offset);
14029        break;
14030#endif
14031    case M16_OPC_LB:
14032        gen_ld(ctx, OPC_LB, ry, rx, offset);
14033        break;
14034    case M16_OPC_LH:
14035        gen_ld(ctx, OPC_LH, ry, rx, offset);
14036        break;
14037    case M16_OPC_LWSP:
14038        gen_ld(ctx, OPC_LW, rx, 29, offset);
14039        break;
14040    case M16_OPC_LW:
14041        gen_ld(ctx, OPC_LW, ry, rx, offset);
14042        break;
14043    case M16_OPC_LBU:
14044        gen_ld(ctx, OPC_LBU, ry, rx, offset);
14045        break;
14046    case M16_OPC_LHU:
14047        gen_ld(ctx, OPC_LHU, ry, rx, offset);
14048        break;
14049    case M16_OPC_LWPC:
14050        gen_ld(ctx, OPC_LWPC, rx, 0, offset);
14051        break;
14052#if defined(TARGET_MIPS64)
14053    case M16_OPC_LWU:
14054        check_insn(ctx, ISA_MIPS3);
14055        check_mips_64(ctx);
14056        gen_ld(ctx, OPC_LWU, ry, rx, offset);
14057        break;
14058#endif
14059    case M16_OPC_SB:
14060        gen_st(ctx, OPC_SB, ry, rx, offset);
14061        break;
14062    case M16_OPC_SH:
14063        gen_st(ctx, OPC_SH, ry, rx, offset);
14064        break;
14065    case M16_OPC_SWSP:
14066        gen_st(ctx, OPC_SW, rx, 29, offset);
14067        break;
14068    case M16_OPC_SW:
14069        gen_st(ctx, OPC_SW, ry, rx, offset);
14070        break;
14071#if defined(TARGET_MIPS64)
14072    case M16_OPC_I64:
14073        decode_i64_mips16(ctx, ry, funct, offset, 1);
14074        break;
14075#endif
14076    default:
14077        generate_exception_end(ctx, EXCP_RI);
14078        break;
14079    }
14080
14081    return 4;
14082}
14083
14084static inline bool is_uhi(int sdbbp_code)
14085{
14086#ifdef CONFIG_USER_ONLY
14087    return false;
14088#else
14089    return semihosting_enabled() && sdbbp_code == 1;
14090#endif
14091}
14092
14093#ifdef CONFIG_USER_ONLY
14094/* The above should dead-code away any calls to this..*/
14095static inline void gen_helper_do_semihosting(void *env)
14096{
14097    g_assert_not_reached();
14098}
14099#endif
14100
14101static int decode_mips16_opc(CPUMIPSState *env, DisasContext *ctx)
14102{
14103    int rx, ry;
14104    int sa;
14105    int op, cnvt_op, op1, offset;
14106    int funct;
14107    int n_bytes;
14108
14109    op = (ctx->opcode >> 11) & 0x1f;
14110    sa = (ctx->opcode >> 2) & 0x7;
14111    sa = sa == 0 ? 8 : sa;
14112    rx = xlat((ctx->opcode >> 8) & 0x7);
14113    cnvt_op = (ctx->opcode >> 5) & 0x7;
14114    ry = xlat((ctx->opcode >> 5) & 0x7);
14115    op1 = offset = ctx->opcode & 0x1f;
14116
14117    n_bytes = 2;
14118
14119    switch (op) {
14120    case M16_OPC_ADDIUSP:
14121        {
14122            int16_t imm = ((uint8_t) ctx->opcode) << 2;
14123
14124            gen_arith_imm(ctx, OPC_ADDIU, rx, 29, imm);
14125        }
14126        break;
14127    case M16_OPC_ADDIUPC:
14128        gen_addiupc(ctx, rx, ((uint8_t) ctx->opcode) << 2, 0, 0);
14129        break;
14130    case M16_OPC_B:
14131        offset = (ctx->opcode & 0x7ff) << 1;
14132        offset = (int16_t)(offset << 4) >> 4;
14133        gen_compute_branch(ctx, OPC_BEQ, 2, 0, 0, offset, 0);
14134        /* No delay slot, so just process as a normal instruction */
14135        break;
14136    case M16_OPC_JAL:
14137        offset = cpu_lduw_code(env, ctx->base.pc_next + 2);
14138        offset = (((ctx->opcode & 0x1f) << 21)
14139                  | ((ctx->opcode >> 5) & 0x1f) << 16
14140                  | offset) << 2;
14141        op = ((ctx->opcode >> 10) & 0x1) ? OPC_JALX : OPC_JAL;
14142        gen_compute_branch(ctx, op, 4, rx, ry, offset, 2);
14143        n_bytes = 4;
14144        break;
14145    case M16_OPC_BEQZ:
14146        gen_compute_branch(ctx, OPC_BEQ, 2, rx, 0,
14147                           ((int8_t)ctx->opcode) << 1, 0);
14148        /* No delay slot, so just process as a normal instruction */
14149        break;
14150    case M16_OPC_BNEQZ:
14151        gen_compute_branch(ctx, OPC_BNE, 2, rx, 0,
14152                           ((int8_t)ctx->opcode) << 1, 0);
14153        /* No delay slot, so just process as a normal instruction */
14154        break;
14155    case M16_OPC_SHIFT:
14156        switch (ctx->opcode & 0x3) {
14157        case 0x0:
14158            gen_shift_imm(ctx, OPC_SLL, rx, ry, sa);
14159            break;
14160        case 0x1:
14161#if defined(TARGET_MIPS64)
14162            check_insn(ctx, ISA_MIPS3);
14163            check_mips_64(ctx);
14164            gen_shift_imm(ctx, OPC_DSLL, rx, ry, sa);
14165#else
14166            generate_exception_end(ctx, EXCP_RI);
14167#endif
14168            break;
14169        case 0x2:
14170            gen_shift_imm(ctx, OPC_SRL, rx, ry, sa);
14171            break;
14172        case 0x3:
14173            gen_shift_imm(ctx, OPC_SRA, rx, ry, sa);
14174            break;
14175        }
14176        break;
14177#if defined(TARGET_MIPS64)
14178    case M16_OPC_LD:
14179        check_insn(ctx, ISA_MIPS3);
14180        check_mips_64(ctx);
14181        gen_ld(ctx, OPC_LD, ry, rx, offset << 3);
14182        break;
14183#endif
14184    case M16_OPC_RRIA:
14185        {
14186            int16_t imm = (int8_t)((ctx->opcode & 0xf) << 4) >> 4;
14187
14188            if ((ctx->opcode >> 4) & 1) {
14189#if defined(TARGET_MIPS64)
14190                check_insn(ctx, ISA_MIPS3);
14191                check_mips_64(ctx);
14192                gen_arith_imm(ctx, OPC_DADDIU, ry, rx, imm);
14193#else
14194                generate_exception_end(ctx, EXCP_RI);
14195#endif
14196            } else {
14197                gen_arith_imm(ctx, OPC_ADDIU, ry, rx, imm);
14198            }
14199        }
14200        break;
14201    case M16_OPC_ADDIU8:
14202        {
14203            int16_t imm = (int8_t) ctx->opcode;
14204
14205            gen_arith_imm(ctx, OPC_ADDIU, rx, rx, imm);
14206        }
14207        break;
14208    case M16_OPC_SLTI:
14209        {
14210            int16_t imm = (uint8_t) ctx->opcode;
14211            gen_slt_imm(ctx, OPC_SLTI, 24, rx, imm);
14212        }
14213        break;
14214    case M16_OPC_SLTIU:
14215        {
14216            int16_t imm = (uint8_t) ctx->opcode;
14217            gen_slt_imm(ctx, OPC_SLTIU, 24, rx, imm);
14218        }
14219        break;
14220    case M16_OPC_I8:
14221        {
14222            int reg32;
14223
14224            funct = (ctx->opcode >> 8) & 0x7;
14225            switch (funct) {
14226            case I8_BTEQZ:
14227                gen_compute_branch(ctx, OPC_BEQ, 2, 24, 0,
14228                                   ((int8_t)ctx->opcode) << 1, 0);
14229                break;
14230            case I8_BTNEZ:
14231                gen_compute_branch(ctx, OPC_BNE, 2, 24, 0,
14232                                   ((int8_t)ctx->opcode) << 1, 0);
14233                break;
14234            case I8_SWRASP:
14235                gen_st(ctx, OPC_SW, 31, 29, (ctx->opcode & 0xff) << 2);
14236                break;
14237            case I8_ADJSP:
14238                gen_arith_imm(ctx, OPC_ADDIU, 29, 29,
14239                              ((int8_t)ctx->opcode) << 3);
14240                break;
14241            case I8_SVRS:
14242                check_insn(ctx, ISA_MIPS32);
14243                {
14244                    int do_ra = ctx->opcode & (1 << 6);
14245                    int do_s0 = ctx->opcode & (1 << 5);
14246                    int do_s1 = ctx->opcode & (1 << 4);
14247                    int framesize = ctx->opcode & 0xf;
14248
14249                    if (framesize == 0) {
14250                        framesize = 128;
14251                    } else {
14252                        framesize = framesize << 3;
14253                    }
14254
14255                    if (ctx->opcode & (1 << 7)) {
14256                        gen_mips16_save(ctx, 0, 0,
14257                                        do_ra, do_s0, do_s1, framesize);
14258                    } else {
14259                        gen_mips16_restore(ctx, 0, 0,
14260                                           do_ra, do_s0, do_s1, framesize);
14261                    }
14262                }
14263                break;
14264            case I8_MOV32R:
14265                {
14266                    int rz = xlat(ctx->opcode & 0x7);
14267
14268                    reg32 = (((ctx->opcode >> 3) & 0x3) << 3) |
14269                        ((ctx->opcode >> 5) & 0x7);
14270                    gen_arith(ctx, OPC_ADDU, reg32, rz, 0);
14271                }
14272                break;
14273            case I8_MOVR32:
14274                reg32 = ctx->opcode & 0x1f;
14275                gen_arith(ctx, OPC_ADDU, ry, reg32, 0);
14276                break;
14277            default:
14278                generate_exception_end(ctx, EXCP_RI);
14279                break;
14280            }
14281        }
14282        break;
14283    case M16_OPC_LI:
14284        {
14285            int16_t imm = (uint8_t) ctx->opcode;
14286
14287            gen_arith_imm(ctx, OPC_ADDIU, rx, 0, imm);
14288        }
14289        break;
14290    case M16_OPC_CMPI:
14291        {
14292            int16_t imm = (uint8_t) ctx->opcode;
14293            gen_logic_imm(ctx, OPC_XORI, 24, rx, imm);
14294        }
14295        break;
14296#if defined(TARGET_MIPS64)
14297    case M16_OPC_SD:
14298        check_insn(ctx, ISA_MIPS3);
14299        check_mips_64(ctx);
14300        gen_st(ctx, OPC_SD, ry, rx, offset << 3);
14301        break;
14302#endif
14303    case M16_OPC_LB:
14304        gen_ld(ctx, OPC_LB, ry, rx, offset);
14305        break;
14306    case M16_OPC_LH:
14307        gen_ld(ctx, OPC_LH, ry, rx, offset << 1);
14308        break;
14309    case M16_OPC_LWSP:
14310        gen_ld(ctx, OPC_LW, rx, 29, ((uint8_t)ctx->opcode) << 2);
14311        break;
14312    case M16_OPC_LW:
14313        gen_ld(ctx, OPC_LW, ry, rx, offset << 2);
14314        break;
14315    case M16_OPC_LBU:
14316        gen_ld(ctx, OPC_LBU, ry, rx, offset);
14317        break;
14318    case M16_OPC_LHU:
14319        gen_ld(ctx, OPC_LHU, ry, rx, offset << 1);
14320        break;
14321    case M16_OPC_LWPC:
14322        gen_ld(ctx, OPC_LWPC, rx, 0, ((uint8_t)ctx->opcode) << 2);
14323        break;
14324#if defined(TARGET_MIPS64)
14325    case M16_OPC_LWU:
14326        check_insn(ctx, ISA_MIPS3);
14327        check_mips_64(ctx);
14328        gen_ld(ctx, OPC_LWU, ry, rx, offset << 2);
14329        break;
14330#endif
14331    case M16_OPC_SB:
14332        gen_st(ctx, OPC_SB, ry, rx, offset);
14333        break;
14334    case M16_OPC_SH:
14335        gen_st(ctx, OPC_SH, ry, rx, offset << 1);
14336        break;
14337    case M16_OPC_SWSP:
14338        gen_st(ctx, OPC_SW, rx, 29, ((uint8_t)ctx->opcode) << 2);
14339        break;
14340    case M16_OPC_SW:
14341        gen_st(ctx, OPC_SW, ry, rx, offset << 2);
14342        break;
14343    case M16_OPC_RRR:
14344        {
14345            int rz = xlat((ctx->opcode >> 2) & 0x7);
14346            int mips32_op;
14347
14348            switch (ctx->opcode & 0x3) {
14349            case RRR_ADDU:
14350                mips32_op = OPC_ADDU;
14351                break;
14352            case RRR_SUBU:
14353                mips32_op = OPC_SUBU;
14354                break;
14355#if defined(TARGET_MIPS64)
14356            case RRR_DADDU:
14357                mips32_op = OPC_DADDU;
14358                check_insn(ctx, ISA_MIPS3);
14359                check_mips_64(ctx);
14360                break;
14361            case RRR_DSUBU:
14362                mips32_op = OPC_DSUBU;
14363                check_insn(ctx, ISA_MIPS3);
14364                check_mips_64(ctx);
14365                break;
14366#endif
14367            default:
14368                generate_exception_end(ctx, EXCP_RI);
14369                goto done;
14370            }
14371
14372            gen_arith(ctx, mips32_op, rz, rx, ry);
14373        done:
14374            ;
14375        }
14376        break;
14377    case M16_OPC_RR:
14378        switch (op1) {
14379        case RR_JR:
14380            {
14381                int nd = (ctx->opcode >> 7) & 0x1;
14382                int link = (ctx->opcode >> 6) & 0x1;
14383                int ra = (ctx->opcode >> 5) & 0x1;
14384
14385                if (nd) {
14386                    check_insn(ctx, ISA_MIPS32);
14387                }
14388
14389                if (link) {
14390                    op = OPC_JALR;
14391                } else {
14392                    op = OPC_JR;
14393                }
14394
14395                gen_compute_branch(ctx, op, 2, ra ? 31 : rx, 31, 0,
14396                                   (nd ? 0 : 2));
14397            }
14398            break;
14399        case RR_SDBBP:
14400            if (is_uhi(extract32(ctx->opcode, 5, 6))) {
14401                gen_helper_do_semihosting(cpu_env);
14402            } else {
14403                /*
14404                 * XXX: not clear which exception should be raised
14405                 *      when in debug mode...
14406                 */
14407                check_insn(ctx, ISA_MIPS32);
14408                generate_exception_end(ctx, EXCP_DBp);
14409            }
14410            break;
14411        case RR_SLT:
14412            gen_slt(ctx, OPC_SLT, 24, rx, ry);
14413            break;
14414        case RR_SLTU:
14415            gen_slt(ctx, OPC_SLTU, 24, rx, ry);
14416            break;
14417        case RR_BREAK:
14418            generate_exception_end(ctx, EXCP_BREAK);
14419            break;
14420        case RR_SLLV:
14421            gen_shift(ctx, OPC_SLLV, ry, rx, ry);
14422            break;
14423        case RR_SRLV:
14424            gen_shift(ctx, OPC_SRLV, ry, rx, ry);
14425            break;
14426        case RR_SRAV:
14427            gen_shift(ctx, OPC_SRAV, ry, rx, ry);
14428            break;
14429#if defined(TARGET_MIPS64)
14430        case RR_DSRL:
14431            check_insn(ctx, ISA_MIPS3);
14432            check_mips_64(ctx);
14433            gen_shift_imm(ctx, OPC_DSRL, ry, ry, sa);
14434            break;
14435#endif
14436        case RR_CMP:
14437            gen_logic(ctx, OPC_XOR, 24, rx, ry);
14438            break;
14439        case RR_NEG:
14440            gen_arith(ctx, OPC_SUBU, rx, 0, ry);
14441            break;
14442        case RR_AND:
14443            gen_logic(ctx, OPC_AND, rx, rx, ry);
14444            break;
14445        case RR_OR:
14446            gen_logic(ctx, OPC_OR, rx, rx, ry);
14447            break;
14448        case RR_XOR:
14449            gen_logic(ctx, OPC_XOR, rx, rx, ry);
14450            break;
14451        case RR_NOT:
14452            gen_logic(ctx, OPC_NOR, rx, ry, 0);
14453            break;
14454        case RR_MFHI:
14455            gen_HILO(ctx, OPC_MFHI, 0, rx);
14456            break;
14457        case RR_CNVT:
14458            check_insn(ctx, ISA_MIPS32);
14459            switch (cnvt_op) {
14460            case RR_RY_CNVT_ZEB:
14461                tcg_gen_ext8u_tl(cpu_gpr[rx], cpu_gpr[rx]);
14462                break;
14463            case RR_RY_CNVT_ZEH:
14464                tcg_gen_ext16u_tl(cpu_gpr[rx], cpu_gpr[rx]);
14465                break;
14466            case RR_RY_CNVT_SEB:
14467                tcg_gen_ext8s_tl(cpu_gpr[rx], cpu_gpr[rx]);
14468                break;
14469            case RR_RY_CNVT_SEH:
14470                tcg_gen_ext16s_tl(cpu_gpr[rx], cpu_gpr[rx]);
14471                break;
14472#if defined(TARGET_MIPS64)
14473            case RR_RY_CNVT_ZEW:
14474                check_insn(ctx, ISA_MIPS64);
14475                check_mips_64(ctx);
14476                tcg_gen_ext32u_tl(cpu_gpr[rx], cpu_gpr[rx]);
14477                break;
14478            case RR_RY_CNVT_SEW:
14479                check_insn(ctx, ISA_MIPS64);
14480                check_mips_64(ctx);
14481                tcg_gen_ext32s_tl(cpu_gpr[rx], cpu_gpr[rx]);
14482                break;
14483#endif
14484            default:
14485                generate_exception_end(ctx, EXCP_RI);
14486                break;
14487            }
14488            break;
14489        case RR_MFLO:
14490            gen_HILO(ctx, OPC_MFLO, 0, rx);
14491            break;
14492#if defined(TARGET_MIPS64)
14493        case RR_DSRA:
14494            check_insn(ctx, ISA_MIPS3);
14495            check_mips_64(ctx);
14496            gen_shift_imm(ctx, OPC_DSRA, ry, ry, sa);
14497            break;
14498        case RR_DSLLV:
14499            check_insn(ctx, ISA_MIPS3);
14500            check_mips_64(ctx);
14501            gen_shift(ctx, OPC_DSLLV, ry, rx, ry);
14502            break;
14503        case RR_DSRLV:
14504            check_insn(ctx, ISA_MIPS3);
14505            check_mips_64(ctx);
14506            gen_shift(ctx, OPC_DSRLV, ry, rx, ry);
14507            break;
14508        case RR_DSRAV:
14509            check_insn(ctx, ISA_MIPS3);
14510            check_mips_64(ctx);
14511            gen_shift(ctx, OPC_DSRAV, ry, rx, ry);
14512            break;
14513#endif
14514        case RR_MULT:
14515            gen_muldiv(ctx, OPC_MULT, 0, rx, ry);
14516            break;
14517        case RR_MULTU:
14518            gen_muldiv(ctx, OPC_MULTU, 0, rx, ry);
14519            break;
14520        case RR_DIV:
14521            gen_muldiv(ctx, OPC_DIV, 0, rx, ry);
14522            break;
14523        case RR_DIVU:
14524            gen_muldiv(ctx, OPC_DIVU, 0, rx, ry);
14525            break;
14526#if defined(TARGET_MIPS64)
14527        case RR_DMULT:
14528            check_insn(ctx, ISA_MIPS3);
14529            check_mips_64(ctx);
14530            gen_muldiv(ctx, OPC_DMULT, 0, rx, ry);
14531            break;
14532        case RR_DMULTU:
14533            check_insn(ctx, ISA_MIPS3);
14534            check_mips_64(ctx);
14535            gen_muldiv(ctx, OPC_DMULTU, 0, rx, ry);
14536            break;
14537        case RR_DDIV:
14538            check_insn(ctx, ISA_MIPS3);
14539            check_mips_64(ctx);
14540            gen_muldiv(ctx, OPC_DDIV, 0, rx, ry);
14541            break;
14542        case RR_DDIVU:
14543            check_insn(ctx, ISA_MIPS3);
14544            check_mips_64(ctx);
14545            gen_muldiv(ctx, OPC_DDIVU, 0, rx, ry);
14546            break;
14547#endif
14548        default:
14549            generate_exception_end(ctx, EXCP_RI);
14550            break;
14551        }
14552        break;
14553    case M16_OPC_EXTEND:
14554        decode_extended_mips16_opc(env, ctx);
14555        n_bytes = 4;
14556        break;
14557#if defined(TARGET_MIPS64)
14558    case M16_OPC_I64:
14559        funct = (ctx->opcode >> 8) & 0x7;
14560        decode_i64_mips16(ctx, ry, funct, offset, 0);
14561        break;
14562#endif
14563    default:
14564        generate_exception_end(ctx, EXCP_RI);
14565        break;
14566    }
14567
14568    return n_bytes;
14569}
14570
14571/* microMIPS extension to MIPS32/MIPS64 */
14572
14573/*
14574 * microMIPS32/microMIPS64 major opcodes
14575 *
14576 * 1. MIPS Architecture for Programmers Volume II-B:
14577 *      The microMIPS32 Instruction Set (Revision 3.05)
14578 *
14579 *    Table 6.2 microMIPS32 Encoding of Major Opcode Field
14580 *
14581 * 2. MIPS Architecture For Programmers Volume II-A:
14582 *      The MIPS64 Instruction Set (Revision 3.51)
14583 */
14584
14585enum {
14586    POOL32A = 0x00,
14587    POOL16A = 0x01,
14588    LBU16 = 0x02,
14589    MOVE16 = 0x03,
14590    ADDI32 = 0x04,
14591    R6_LUI = 0x04,
14592    AUI = 0x04,
14593    LBU32 = 0x05,
14594    SB32 = 0x06,
14595    LB32 = 0x07,
14596
14597    POOL32B = 0x08,
14598    POOL16B = 0x09,
14599    LHU16 = 0x0a,
14600    ANDI16 = 0x0b,
14601    ADDIU32 = 0x0c,
14602    LHU32 = 0x0d,
14603    SH32 = 0x0e,
14604    LH32 = 0x0f,
14605
14606    POOL32I = 0x10,
14607    POOL16C = 0x11,
14608    LWSP16 = 0x12,
14609    POOL16D = 0x13,
14610    ORI32 = 0x14,
14611    POOL32F = 0x15,
14612    POOL32S = 0x16,  /* MIPS64 */
14613    DADDIU32 = 0x17, /* MIPS64 */
14614
14615    POOL32C = 0x18,
14616    LWGP16 = 0x19,
14617    LW16 = 0x1a,
14618    POOL16E = 0x1b,
14619    XORI32 = 0x1c,
14620    JALS32 = 0x1d,
14621    BOVC = 0x1d,
14622    BEQC = 0x1d,
14623    BEQZALC = 0x1d,
14624    ADDIUPC = 0x1e,
14625    PCREL = 0x1e,
14626    BNVC = 0x1f,
14627    BNEC = 0x1f,
14628    BNEZALC = 0x1f,
14629
14630    R6_BEQZC = 0x20,
14631    JIC = 0x20,
14632    POOL16F = 0x21,
14633    SB16 = 0x22,
14634    BEQZ16 = 0x23,
14635    BEQZC16 = 0x23,
14636    SLTI32 = 0x24,
14637    BEQ32 = 0x25,
14638    BC = 0x25,
14639    SWC132 = 0x26,
14640    LWC132 = 0x27,
14641
14642    /* 0x29 is reserved */
14643    RES_29 = 0x29,
14644    R6_BNEZC = 0x28,
14645    JIALC = 0x28,
14646    SH16 = 0x2a,
14647    BNEZ16 = 0x2b,
14648    BNEZC16 = 0x2b,
14649    SLTIU32 = 0x2c,
14650    BNE32 = 0x2d,
14651    BALC = 0x2d,
14652    SDC132 = 0x2e,
14653    LDC132 = 0x2f,
14654
14655    /* 0x31 is reserved */
14656    RES_31 = 0x31,
14657    BLEZALC = 0x30,
14658    BGEZALC = 0x30,
14659    BGEUC = 0x30,
14660    SWSP16 = 0x32,
14661    B16 = 0x33,
14662    BC16 = 0x33,
14663    ANDI32 = 0x34,
14664    J32 = 0x35,
14665    BGTZC = 0x35,
14666    BLTZC = 0x35,
14667    BLTC = 0x35,
14668    SD32 = 0x36, /* MIPS64 */
14669    LD32 = 0x37, /* MIPS64 */
14670
14671    /* 0x39 is reserved */
14672    RES_39 = 0x39,
14673    BGTZALC = 0x38,
14674    BLTZALC = 0x38,
14675    BLTUC = 0x38,
14676    SW16 = 0x3a,
14677    LI16 = 0x3b,
14678    JALX32 = 0x3c,
14679    JAL32 = 0x3d,
14680    BLEZC = 0x3d,
14681    BGEZC = 0x3d,
14682    BGEC = 0x3d,
14683    SW32 = 0x3e,
14684    LW32 = 0x3f
14685};
14686
14687/* PCREL Instructions perform PC-Relative address calculation. bits 20..16 */
14688enum {
14689    ADDIUPC_00 = 0x00,
14690    ADDIUPC_01 = 0x01,
14691    ADDIUPC_02 = 0x02,
14692    ADDIUPC_03 = 0x03,
14693    ADDIUPC_04 = 0x04,
14694    ADDIUPC_05 = 0x05,
14695    ADDIUPC_06 = 0x06,
14696    ADDIUPC_07 = 0x07,
14697    AUIPC = 0x1e,
14698    ALUIPC = 0x1f,
14699    LWPC_08 = 0x08,
14700    LWPC_09 = 0x09,
14701    LWPC_0A = 0x0A,
14702    LWPC_0B = 0x0B,
14703    LWPC_0C = 0x0C,
14704    LWPC_0D = 0x0D,
14705    LWPC_0E = 0x0E,
14706    LWPC_0F = 0x0F,
14707};
14708
14709/* POOL32A encoding of minor opcode field */
14710
14711enum {
14712    /*
14713     * These opcodes are distinguished only by bits 9..6; those bits are
14714     * what are recorded below.
14715     */
14716    SLL32 = 0x0,
14717    SRL32 = 0x1,
14718    SRA = 0x2,
14719    ROTR = 0x3,
14720    SELEQZ = 0x5,
14721    SELNEZ = 0x6,
14722    R6_RDHWR = 0x7,
14723
14724    SLLV = 0x0,
14725    SRLV = 0x1,
14726    SRAV = 0x2,
14727    ROTRV = 0x3,
14728    ADD = 0x4,
14729    ADDU32 = 0x5,
14730    SUB = 0x6,
14731    SUBU32 = 0x7,
14732    MUL = 0x8,
14733    AND = 0x9,
14734    OR32 = 0xa,
14735    NOR = 0xb,
14736    XOR32 = 0xc,
14737    SLT = 0xd,
14738    SLTU = 0xe,
14739
14740    MOVN = 0x0,
14741    R6_MUL  = 0x0,
14742    MOVZ = 0x1,
14743    MUH  = 0x1,
14744    MULU = 0x2,
14745    MUHU = 0x3,
14746    LWXS = 0x4,
14747    R6_DIV  = 0x4,
14748    MOD  = 0x5,
14749    R6_DIVU = 0x6,
14750    MODU = 0x7,
14751
14752    /* The following can be distinguished by their lower 6 bits. */
14753    BREAK32 = 0x07,
14754    INS = 0x0c,
14755    LSA = 0x0f,
14756    ALIGN = 0x1f,
14757    EXT = 0x2c,
14758    POOL32AXF = 0x3c,
14759    SIGRIE = 0x3f
14760};
14761
14762/* POOL32AXF encoding of minor opcode field extension */
14763
14764/*
14765 * 1. MIPS Architecture for Programmers Volume II-B:
14766 *      The microMIPS32 Instruction Set (Revision 3.05)
14767 *
14768 *    Table 6.5 POOL32Axf Encoding of Minor Opcode Extension Field
14769 *
14770 * 2. MIPS Architecture for Programmers VolumeIV-e:
14771 *      The MIPS DSP Application-Specific Extension
14772 *        to the microMIPS32 Architecture (Revision 2.34)
14773 *
14774 *    Table 5.5 POOL32Axf Encoding of Minor Opcode Extension Field
14775 */
14776
14777enum {
14778    /* bits 11..6 */
14779    TEQ = 0x00,
14780    TGE = 0x08,
14781    TGEU = 0x10,
14782    TLT = 0x20,
14783    TLTU = 0x28,
14784    TNE = 0x30,
14785
14786    MFC0 = 0x03,
14787    MTC0 = 0x0b,
14788
14789    /* begin of microMIPS32 DSP */
14790
14791    /* bits 13..12 for 0x01 */
14792    MFHI_ACC = 0x0,
14793    MFLO_ACC = 0x1,
14794    MTHI_ACC = 0x2,
14795    MTLO_ACC = 0x3,
14796
14797    /* bits 13..12 for 0x2a */
14798    MADD_ACC = 0x0,
14799    MADDU_ACC = 0x1,
14800    MSUB_ACC = 0x2,
14801    MSUBU_ACC = 0x3,
14802
14803    /* bits 13..12 for 0x32 */
14804    MULT_ACC = 0x0,
14805    MULTU_ACC = 0x1,
14806
14807    /* end of microMIPS32 DSP */
14808
14809    /* bits 15..12 for 0x2c */
14810    BITSWAP = 0x0,
14811    SEB = 0x2,
14812    SEH = 0x3,
14813    CLO = 0x4,
14814    CLZ = 0x5,
14815    RDHWR = 0x6,
14816    WSBH = 0x7,
14817    MULT = 0x8,
14818    MULTU = 0x9,
14819    DIV = 0xa,
14820    DIVU = 0xb,
14821    MADD = 0xc,
14822    MADDU = 0xd,
14823    MSUB = 0xe,
14824    MSUBU = 0xf,
14825
14826    /* bits 15..12 for 0x34 */
14827    MFC2 = 0x4,
14828    MTC2 = 0x5,
14829    MFHC2 = 0x8,
14830    MTHC2 = 0x9,
14831    CFC2 = 0xc,
14832    CTC2 = 0xd,
14833
14834    /* bits 15..12 for 0x3c */
14835    JALR = 0x0,
14836    JR = 0x0,                   /* alias */
14837    JALRC = 0x0,
14838    JRC = 0x0,
14839    JALR_HB = 0x1,
14840    JALRC_HB = 0x1,
14841    JALRS = 0x4,
14842    JALRS_HB = 0x5,
14843
14844    /* bits 15..12 for 0x05 */
14845    RDPGPR = 0xe,
14846    WRPGPR = 0xf,
14847
14848    /* bits 15..12 for 0x0d */
14849    TLBP = 0x0,
14850    TLBR = 0x1,
14851    TLBWI = 0x2,
14852    TLBWR = 0x3,
14853    TLBINV = 0x4,
14854    TLBINVF = 0x5,
14855    WAIT = 0x9,
14856    IRET = 0xd,
14857    DERET = 0xe,
14858    ERET = 0xf,
14859
14860    /* bits 15..12 for 0x15 */
14861    DMT = 0x0,
14862    DVPE = 0x1,
14863    EMT = 0x2,
14864    EVPE = 0x3,
14865
14866    /* bits 15..12 for 0x1d */
14867    DI = 0x4,
14868    EI = 0x5,
14869
14870    /* bits 15..12 for 0x2d */
14871    SYNC = 0x6,
14872    SYSCALL = 0x8,
14873    SDBBP = 0xd,
14874
14875    /* bits 15..12 for 0x35 */
14876    MFHI32 = 0x0,
14877    MFLO32 = 0x1,
14878    MTHI32 = 0x2,
14879    MTLO32 = 0x3,
14880};
14881
14882/* POOL32B encoding of minor opcode field (bits 15..12) */
14883
14884enum {
14885    LWC2 = 0x0,
14886    LWP = 0x1,
14887    LDP = 0x4,
14888    LWM32 = 0x5,
14889    CACHE = 0x6,
14890    LDM = 0x7,
14891    SWC2 = 0x8,
14892    SWP = 0x9,
14893    SDP = 0xc,
14894    SWM32 = 0xd,
14895    SDM = 0xf
14896};
14897
14898/* POOL32C encoding of minor opcode field (bits 15..12) */
14899
14900enum {
14901    LWL = 0x0,
14902    SWL = 0x8,
14903    LWR = 0x1,
14904    SWR = 0x9,
14905    PREF = 0x2,
14906    ST_EVA = 0xa,
14907    LL = 0x3,
14908    SC = 0xb,
14909    LDL = 0x4,
14910    SDL = 0xc,
14911    LDR = 0x5,
14912    SDR = 0xd,
14913    LD_EVA = 0x6,
14914    LWU = 0xe,
14915    LLD = 0x7,
14916    SCD = 0xf
14917};
14918
14919/* POOL32C LD-EVA encoding of minor opcode field (bits 11..9) */
14920
14921enum {
14922    LBUE = 0x0,
14923    LHUE = 0x1,
14924    LWLE = 0x2,
14925    LWRE = 0x3,
14926    LBE = 0x4,
14927    LHE = 0x5,
14928    LLE = 0x6,
14929    LWE = 0x7,
14930};
14931
14932/* POOL32C ST-EVA encoding of minor opcode field (bits 11..9) */
14933
14934enum {
14935    SWLE = 0x0,
14936    SWRE = 0x1,
14937    PREFE = 0x2,
14938    CACHEE = 0x3,
14939    SBE = 0x4,
14940    SHE = 0x5,
14941    SCE = 0x6,
14942    SWE = 0x7,
14943};
14944
14945/* POOL32F encoding of minor opcode field (bits 5..0) */
14946
14947enum {
14948    /* These are the bit 7..6 values */
14949    ADD_FMT = 0x0,
14950
14951    SUB_FMT = 0x1,
14952
14953    MUL_FMT = 0x2,
14954
14955    DIV_FMT = 0x3,
14956
14957    /* These are the bit 8..6 values */
14958    MOVN_FMT = 0x0,
14959    RSQRT2_FMT = 0x0,
14960    MOVF_FMT = 0x0,
14961    RINT_FMT = 0x0,
14962    SELNEZ_FMT = 0x0,
14963
14964    MOVZ_FMT = 0x1,
14965    LWXC1 = 0x1,
14966    MOVT_FMT = 0x1,
14967    CLASS_FMT = 0x1,
14968    SELEQZ_FMT = 0x1,
14969
14970    PLL_PS = 0x2,
14971    SWXC1 = 0x2,
14972    SEL_FMT = 0x2,
14973
14974    PLU_PS = 0x3,
14975    LDXC1 = 0x3,
14976
14977    MOVN_FMT_04 = 0x4,
14978    PUL_PS = 0x4,
14979    SDXC1 = 0x4,
14980    RECIP2_FMT = 0x4,
14981
14982    MOVZ_FMT_05 = 0x05,
14983    PUU_PS = 0x5,
14984    LUXC1 = 0x5,
14985
14986    CVT_PS_S = 0x6,
14987    SUXC1 = 0x6,
14988    ADDR_PS = 0x6,
14989    PREFX = 0x6,
14990    MADDF_FMT = 0x6,
14991
14992    MULR_PS = 0x7,
14993    MSUBF_FMT = 0x7,
14994
14995    MADD_S = 0x01,
14996    MADD_D = 0x09,
14997    MADD_PS = 0x11,
14998    ALNV_PS = 0x19,
14999    MSUB_S = 0x21,
15000    MSUB_D = 0x29,
15001    MSUB_PS = 0x31,
15002
15003    NMADD_S = 0x02,
15004    NMADD_D = 0x0a,
15005    NMADD_PS = 0x12,
15006    NMSUB_S = 0x22,
15007    NMSUB_D = 0x2a,
15008    NMSUB_PS = 0x32,
15009
15010    MIN_FMT = 0x3,
15011    MAX_FMT = 0xb,
15012    MINA_FMT = 0x23,
15013    MAXA_FMT = 0x2b,
15014    POOL32FXF = 0x3b,
15015
15016    CABS_COND_FMT = 0x1c,              /* MIPS3D */
15017    C_COND_FMT = 0x3c,
15018
15019    CMP_CONDN_S = 0x5,
15020    CMP_CONDN_D = 0x15
15021};
15022
15023/* POOL32Fxf encoding of minor opcode extension field */
15024
15025enum {
15026    CVT_L = 0x04,
15027    RSQRT_FMT = 0x08,
15028    FLOOR_L = 0x0c,
15029    CVT_PW_PS = 0x1c,
15030    CVT_W = 0x24,
15031    SQRT_FMT = 0x28,
15032    FLOOR_W = 0x2c,
15033    CVT_PS_PW = 0x3c,
15034    CFC1 = 0x40,
15035    RECIP_FMT = 0x48,
15036    CEIL_L = 0x4c,
15037    CTC1 = 0x60,
15038    CEIL_W = 0x6c,
15039    MFC1 = 0x80,
15040    CVT_S_PL = 0x84,
15041    TRUNC_L = 0x8c,
15042    MTC1 = 0xa0,
15043    CVT_S_PU = 0xa4,
15044    TRUNC_W = 0xac,
15045    MFHC1 = 0xc0,
15046    ROUND_L = 0xcc,
15047    MTHC1 = 0xe0,
15048    ROUND_W = 0xec,
15049
15050    MOV_FMT = 0x01,
15051    MOVF = 0x05,
15052    ABS_FMT = 0x0d,
15053    RSQRT1_FMT = 0x1d,
15054    MOVT = 0x25,
15055    NEG_FMT = 0x2d,
15056    CVT_D = 0x4d,
15057    RECIP1_FMT = 0x5d,
15058    CVT_S = 0x6d
15059};
15060
15061/* POOL32I encoding of minor opcode field (bits 25..21) */
15062
15063enum {
15064    BLTZ = 0x00,
15065    BLTZAL = 0x01,
15066    BGEZ = 0x02,
15067    BGEZAL = 0x03,
15068    BLEZ = 0x04,
15069    BNEZC = 0x05,
15070    BGTZ = 0x06,
15071    BEQZC = 0x07,
15072    TLTI = 0x08,
15073    BC1EQZC = 0x08,
15074    TGEI = 0x09,
15075    BC1NEZC = 0x09,
15076    TLTIU = 0x0a,
15077    BC2EQZC = 0x0a,
15078    TGEIU = 0x0b,
15079    BC2NEZC = 0x0a,
15080    TNEI = 0x0c,
15081    R6_SYNCI = 0x0c,
15082    LUI = 0x0d,
15083    TEQI = 0x0e,
15084    SYNCI = 0x10,
15085    BLTZALS = 0x11,
15086    BGEZALS = 0x13,
15087    BC2F = 0x14,
15088    BC2T = 0x15,
15089    BPOSGE64 = 0x1a,
15090    BPOSGE32 = 0x1b,
15091    /* These overlap and are distinguished by bit16 of the instruction */
15092    BC1F = 0x1c,
15093    BC1T = 0x1d,
15094    BC1ANY2F = 0x1c,
15095    BC1ANY2T = 0x1d,
15096    BC1ANY4F = 0x1e,
15097    BC1ANY4T = 0x1f
15098};
15099
15100/* POOL16A encoding of minor opcode field */
15101
15102enum {
15103    ADDU16 = 0x0,
15104    SUBU16 = 0x1
15105};
15106
15107/* POOL16B encoding of minor opcode field */
15108
15109enum {
15110    SLL16 = 0x0,
15111    SRL16 = 0x1
15112};
15113
15114/* POOL16C encoding of minor opcode field */
15115
15116enum {
15117    NOT16 = 0x00,
15118    XOR16 = 0x04,
15119    AND16 = 0x08,
15120    OR16 = 0x0c,
15121    LWM16 = 0x10,
15122    SWM16 = 0x14,
15123    JR16 = 0x18,
15124    JRC16 = 0x1a,
15125    JALR16 = 0x1c,
15126    JALR16S = 0x1e,
15127    MFHI16 = 0x20,
15128    MFLO16 = 0x24,
15129    BREAK16 = 0x28,
15130    SDBBP16 = 0x2c,
15131    JRADDIUSP = 0x30
15132};
15133
15134/* R6 POOL16C encoding of minor opcode field (bits 0..5) */
15135
15136enum {
15137    R6_NOT16    = 0x00,
15138    R6_AND16    = 0x01,
15139    R6_LWM16    = 0x02,
15140    R6_JRC16    = 0x03,
15141    MOVEP       = 0x04,
15142    MOVEP_05    = 0x05,
15143    MOVEP_06    = 0x06,
15144    MOVEP_07    = 0x07,
15145    R6_XOR16    = 0x08,
15146    R6_OR16     = 0x09,
15147    R6_SWM16    = 0x0a,
15148    JALRC16     = 0x0b,
15149    MOVEP_0C    = 0x0c,
15150    MOVEP_0D    = 0x0d,
15151    MOVEP_0E    = 0x0e,
15152    MOVEP_0F    = 0x0f,
15153    JRCADDIUSP  = 0x13,
15154    R6_BREAK16  = 0x1b,
15155    R6_SDBBP16  = 0x3b
15156};
15157
15158/* POOL16D encoding of minor opcode field */
15159
15160enum {
15161    ADDIUS5 = 0x0,
15162    ADDIUSP = 0x1
15163};
15164
15165/* POOL16E encoding of minor opcode field */
15166
15167enum {
15168    ADDIUR2 = 0x0,
15169    ADDIUR1SP = 0x1
15170};
15171
15172static int mmreg(int r)
15173{
15174    static const int map[] = { 16, 17, 2, 3, 4, 5, 6, 7 };
15175
15176    return map[r];
15177}
15178
15179/* Used for 16-bit store instructions.  */
15180static int mmreg2(int r)
15181{
15182    static const int map[] = { 0, 17, 2, 3, 4, 5, 6, 7 };
15183
15184    return map[r];
15185}
15186
15187#define uMIPS_RD(op) ((op >> 7) & 0x7)
15188#define uMIPS_RS(op) ((op >> 4) & 0x7)
15189#define uMIPS_RS2(op) uMIPS_RS(op)
15190#define uMIPS_RS1(op) ((op >> 1) & 0x7)
15191#define uMIPS_RD5(op) ((op >> 5) & 0x1f)
15192#define uMIPS_RS5(op) (op & 0x1f)
15193
15194/* Signed immediate */
15195#define SIMM(op, start, width)                                          \
15196    ((int32_t)(((op >> start) & ((~0U) >> (32 - width)))                \
15197               << (32 - width))                                         \
15198     >> (32 - width))
15199/* Zero-extended immediate */
15200#define ZIMM(op, start, width) ((op >> start) & ((~0U) >> (32 - width)))
15201
15202static void gen_addiur1sp(DisasContext *ctx)
15203{
15204    int rd = mmreg(uMIPS_RD(ctx->opcode));
15205
15206    gen_arith_imm(ctx, OPC_ADDIU, rd, 29, ((ctx->opcode >> 1) & 0x3f) << 2);
15207}
15208
15209static void gen_addiur2(DisasContext *ctx)
15210{
15211    static const int decoded_imm[] = { 1, 4, 8, 12, 16, 20, 24, -1 };
15212    int rd = mmreg(uMIPS_RD(ctx->opcode));
15213    int rs = mmreg(uMIPS_RS(ctx->opcode));
15214
15215    gen_arith_imm(ctx, OPC_ADDIU, rd, rs, decoded_imm[ZIMM(ctx->opcode, 1, 3)]);
15216}
15217
15218static void gen_addiusp(DisasContext *ctx)
15219{
15220    int encoded = ZIMM(ctx->opcode, 1, 9);
15221    int decoded;
15222
15223    if (encoded <= 1) {
15224        decoded = 256 + encoded;
15225    } else if (encoded <= 255) {
15226        decoded = encoded;
15227    } else if (encoded <= 509) {
15228        decoded = encoded - 512;
15229    } else {
15230        decoded = encoded - 768;
15231    }
15232
15233    gen_arith_imm(ctx, OPC_ADDIU, 29, 29, decoded << 2);
15234}
15235
15236static void gen_addius5(DisasContext *ctx)
15237{
15238    int imm = SIMM(ctx->opcode, 1, 4);
15239    int rd = (ctx->opcode >> 5) & 0x1f;
15240
15241    gen_arith_imm(ctx, OPC_ADDIU, rd, rd, imm);
15242}
15243
15244static void gen_andi16(DisasContext *ctx)
15245{
15246    static const int decoded_imm[] = { 128, 1, 2, 3, 4, 7, 8, 15, 16,
15247                                 31, 32, 63, 64, 255, 32768, 65535 };
15248    int rd = mmreg(uMIPS_RD(ctx->opcode));
15249    int rs = mmreg(uMIPS_RS(ctx->opcode));
15250    int encoded = ZIMM(ctx->opcode, 0, 4);
15251
15252    gen_logic_imm(ctx, OPC_ANDI, rd, rs, decoded_imm[encoded]);
15253}
15254
15255static void gen_ldst_multiple(DisasContext *ctx, uint32_t opc, int reglist,
15256                              int base, int16_t offset)
15257{
15258    TCGv t0, t1;
15259    TCGv_i32 t2;
15260
15261    if (ctx->hflags & MIPS_HFLAG_BMASK) {
15262        generate_exception_end(ctx, EXCP_RI);
15263        return;
15264    }
15265
15266    t0 = tcg_temp_new();
15267
15268    gen_base_offset_addr(ctx, t0, base, offset);
15269
15270    t1 = tcg_const_tl(reglist);
15271    t2 = tcg_const_i32(ctx->mem_idx);
15272
15273    save_cpu_state(ctx, 1);
15274    switch (opc) {
15275    case LWM32:
15276        gen_helper_lwm(cpu_env, t0, t1, t2);
15277        break;
15278    case SWM32:
15279        gen_helper_swm(cpu_env, t0, t1, t2);
15280        break;
15281#ifdef TARGET_MIPS64
15282    case LDM:
15283        gen_helper_ldm(cpu_env, t0, t1, t2);
15284        break;
15285    case SDM:
15286        gen_helper_sdm(cpu_env, t0, t1, t2);
15287        break;
15288#endif
15289    }
15290    tcg_temp_free(t0);
15291    tcg_temp_free(t1);
15292    tcg_temp_free_i32(t2);
15293}
15294
15295
15296static void gen_pool16c_insn(DisasContext *ctx)
15297{
15298    int rd = mmreg((ctx->opcode >> 3) & 0x7);
15299    int rs = mmreg(ctx->opcode & 0x7);
15300
15301    switch (((ctx->opcode) >> 4) & 0x3f) {
15302    case NOT16 + 0:
15303    case NOT16 + 1:
15304    case NOT16 + 2:
15305    case NOT16 + 3:
15306        gen_logic(ctx, OPC_NOR, rd, rs, 0);
15307        break;
15308    case XOR16 + 0:
15309    case XOR16 + 1:
15310    case XOR16 + 2:
15311    case XOR16 + 3:
15312        gen_logic(ctx, OPC_XOR, rd, rd, rs);
15313        break;
15314    case AND16 + 0:
15315    case AND16 + 1:
15316    case AND16 + 2:
15317    case AND16 + 3:
15318        gen_logic(ctx, OPC_AND, rd, rd, rs);
15319        break;
15320    case OR16 + 0:
15321    case OR16 + 1:
15322    case OR16 + 2:
15323    case OR16 + 3:
15324        gen_logic(ctx, OPC_OR, rd, rd, rs);
15325        break;
15326    case LWM16 + 0:
15327    case LWM16 + 1:
15328    case LWM16 + 2:
15329    case LWM16 + 3:
15330        {
15331            static const int lwm_convert[] = { 0x11, 0x12, 0x13, 0x14 };
15332            int offset = ZIMM(ctx->opcode, 0, 4);
15333
15334            gen_ldst_multiple(ctx, LWM32, lwm_convert[(ctx->opcode >> 4) & 0x3],
15335                              29, offset << 2);
15336        }
15337        break;
15338    case SWM16 + 0:
15339    case SWM16 + 1:
15340    case SWM16 + 2:
15341    case SWM16 + 3:
15342        {
15343            static const int swm_convert[] = { 0x11, 0x12, 0x13, 0x14 };
15344            int offset = ZIMM(ctx->opcode, 0, 4);
15345
15346            gen_ldst_multiple(ctx, SWM32, swm_convert[(ctx->opcode >> 4) & 0x3],
15347                              29, offset << 2);
15348        }
15349        break;
15350    case JR16 + 0:
15351    case JR16 + 1:
15352        {
15353            int reg = ctx->opcode & 0x1f;
15354
15355            gen_compute_branch(ctx, OPC_JR, 2, reg, 0, 0, 4);
15356        }
15357        break;
15358    case JRC16 + 0:
15359    case JRC16 + 1:
15360        {
15361            int reg = ctx->opcode & 0x1f;
15362            gen_compute_branch(ctx, OPC_JR, 2, reg, 0, 0, 0);
15363            /*
15364             * Let normal delay slot handling in our caller take us
15365             * to the branch target.
15366             */
15367        }
15368        break;
15369    case JALR16 + 0:
15370    case JALR16 + 1:
15371        gen_compute_branch(ctx, OPC_JALR, 2, ctx->opcode & 0x1f, 31, 0, 4);
15372        ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
15373        break;
15374    case JALR16S + 0:
15375    case JALR16S + 1:
15376        gen_compute_branch(ctx, OPC_JALR, 2, ctx->opcode & 0x1f, 31, 0, 2);
15377        ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
15378        break;
15379    case MFHI16 + 0:
15380    case MFHI16 + 1:
15381        gen_HILO(ctx, OPC_MFHI, 0, uMIPS_RS5(ctx->opcode));
15382        break;
15383    case MFLO16 + 0:
15384    case MFLO16 + 1:
15385        gen_HILO(ctx, OPC_MFLO, 0, uMIPS_RS5(ctx->opcode));
15386        break;
15387    case BREAK16:
15388        generate_exception_end(ctx, EXCP_BREAK);
15389        break;
15390    case SDBBP16:
15391        if (is_uhi(extract32(ctx->opcode, 0, 4))) {
15392            gen_helper_do_semihosting(cpu_env);
15393        } else {
15394            /*
15395             * XXX: not clear which exception should be raised
15396             *      when in debug mode...
15397             */
15398            check_insn(ctx, ISA_MIPS32);
15399            generate_exception_end(ctx, EXCP_DBp);
15400        }
15401        break;
15402    case JRADDIUSP + 0:
15403    case JRADDIUSP + 1:
15404        {
15405            int imm = ZIMM(ctx->opcode, 0, 5);
15406            gen_compute_branch(ctx, OPC_JR, 2, 31, 0, 0, 0);
15407            gen_arith_imm(ctx, OPC_ADDIU, 29, 29, imm << 2);
15408            /*
15409             * Let normal delay slot handling in our caller take us
15410             * to the branch target.
15411             */
15412        }
15413        break;
15414    default:
15415        generate_exception_end(ctx, EXCP_RI);
15416        break;
15417    }
15418}
15419
15420static inline void gen_movep(DisasContext *ctx, int enc_dest, int enc_rt,
15421                             int enc_rs)
15422{
15423    int rd, rs, re, rt;
15424    static const int rd_enc[] = { 5, 5, 6, 4, 4, 4, 4, 4 };
15425    static const int re_enc[] = { 6, 7, 7, 21, 22, 5, 6, 7 };
15426    static const int rs_rt_enc[] = { 0, 17, 2, 3, 16, 18, 19, 20 };
15427    rd = rd_enc[enc_dest];
15428    re = re_enc[enc_dest];
15429    rs = rs_rt_enc[enc_rs];
15430    rt = rs_rt_enc[enc_rt];
15431    if (rs) {
15432        tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
15433    } else {
15434        tcg_gen_movi_tl(cpu_gpr[rd], 0);
15435    }
15436    if (rt) {
15437        tcg_gen_mov_tl(cpu_gpr[re], cpu_gpr[rt]);
15438    } else {
15439        tcg_gen_movi_tl(cpu_gpr[re], 0);
15440    }
15441}
15442
15443static void gen_pool16c_r6_insn(DisasContext *ctx)
15444{
15445    int rt = mmreg((ctx->opcode >> 7) & 0x7);
15446    int rs = mmreg((ctx->opcode >> 4) & 0x7);
15447
15448    switch (ctx->opcode & 0xf) {
15449    case R6_NOT16:
15450        gen_logic(ctx, OPC_NOR, rt, rs, 0);
15451        break;
15452    case R6_AND16:
15453        gen_logic(ctx, OPC_AND, rt, rt, rs);
15454        break;
15455    case R6_LWM16:
15456        {
15457            int lwm_converted = 0x11 + extract32(ctx->opcode, 8, 2);
15458            int offset = extract32(ctx->opcode, 4, 4);
15459            gen_ldst_multiple(ctx, LWM32, lwm_converted, 29, offset << 2);
15460        }
15461        break;
15462    case R6_JRC16: /* JRCADDIUSP */
15463        if ((ctx->opcode >> 4) & 1) {
15464            /* JRCADDIUSP */
15465            int imm = extract32(ctx->opcode, 5, 5);
15466            gen_compute_branch(ctx, OPC_JR, 2, 31, 0, 0, 0);
15467            gen_arith_imm(ctx, OPC_ADDIU, 29, 29, imm << 2);
15468        } else {
15469            /* JRC16 */
15470            rs = extract32(ctx->opcode, 5, 5);
15471            gen_compute_branch(ctx, OPC_JR, 2, rs, 0, 0, 0);
15472        }
15473        break;
15474    case MOVEP:
15475    case MOVEP_05:
15476    case MOVEP_06:
15477    case MOVEP_07:
15478    case MOVEP_0C:
15479    case MOVEP_0D:
15480    case MOVEP_0E:
15481    case MOVEP_0F:
15482        {
15483            int enc_dest = uMIPS_RD(ctx->opcode);
15484            int enc_rt = uMIPS_RS2(ctx->opcode);
15485            int enc_rs = (ctx->opcode & 3) | ((ctx->opcode >> 1) & 4);
15486            gen_movep(ctx, enc_dest, enc_rt, enc_rs);
15487        }
15488        break;
15489    case R6_XOR16:
15490        gen_logic(ctx, OPC_XOR, rt, rt, rs);
15491        break;
15492    case R6_OR16:
15493        gen_logic(ctx, OPC_OR, rt, rt, rs);
15494        break;
15495    case R6_SWM16:
15496        {
15497            int swm_converted = 0x11 + extract32(ctx->opcode, 8, 2);
15498            int offset = extract32(ctx->opcode, 4, 4);
15499            gen_ldst_multiple(ctx, SWM32, swm_converted, 29, offset << 2);
15500        }
15501        break;
15502    case JALRC16: /* BREAK16, SDBBP16 */
15503        switch (ctx->opcode & 0x3f) {
15504        case JALRC16:
15505        case JALRC16 + 0x20:
15506            /* JALRC16 */
15507            gen_compute_branch(ctx, OPC_JALR, 2, (ctx->opcode >> 5) & 0x1f,
15508                               31, 0, 0);
15509            break;
15510        case R6_BREAK16:
15511            /* BREAK16 */
15512            generate_exception(ctx, EXCP_BREAK);
15513            break;
15514        case R6_SDBBP16:
15515            /* SDBBP16 */
15516            if (is_uhi(extract32(ctx->opcode, 6, 4))) {
15517                gen_helper_do_semihosting(cpu_env);
15518            } else {
15519                if (ctx->hflags & MIPS_HFLAG_SBRI) {
15520                    generate_exception(ctx, EXCP_RI);
15521                } else {
15522                    generate_exception(ctx, EXCP_DBp);
15523                }
15524            }
15525            break;
15526        }
15527        break;
15528    default:
15529        generate_exception(ctx, EXCP_RI);
15530        break;
15531    }
15532}
15533
15534static void gen_ldxs(DisasContext *ctx, int base, int index, int rd)
15535{
15536    TCGv t0 = tcg_temp_new();
15537    TCGv t1 = tcg_temp_new();
15538
15539    gen_load_gpr(t0, base);
15540
15541    if (index != 0) {
15542        gen_load_gpr(t1, index);
15543        tcg_gen_shli_tl(t1, t1, 2);
15544        gen_op_addr_add(ctx, t0, t1, t0);
15545    }
15546
15547    tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TESL);
15548    gen_store_gpr(t1, rd);
15549
15550    tcg_temp_free(t0);
15551    tcg_temp_free(t1);
15552}
15553
15554static void gen_ldst_pair(DisasContext *ctx, uint32_t opc, int rd,
15555                          int base, int16_t offset)
15556{
15557    TCGv t0, t1;
15558
15559    if (ctx->hflags & MIPS_HFLAG_BMASK || rd == 31) {
15560        generate_exception_end(ctx, EXCP_RI);
15561        return;
15562    }
15563
15564    t0 = tcg_temp_new();
15565    t1 = tcg_temp_new();
15566
15567    gen_base_offset_addr(ctx, t0, base, offset);
15568
15569    switch (opc) {
15570    case LWP:
15571        if (rd == base) {
15572            generate_exception_end(ctx, EXCP_RI);
15573            return;
15574        }
15575        tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TESL);
15576        gen_store_gpr(t1, rd);
15577        tcg_gen_movi_tl(t1, 4);
15578        gen_op_addr_add(ctx, t0, t0, t1);
15579        tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TESL);
15580        gen_store_gpr(t1, rd + 1);
15581        break;
15582    case SWP:
15583        gen_load_gpr(t1, rd);
15584        tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL);
15585        tcg_gen_movi_tl(t1, 4);
15586        gen_op_addr_add(ctx, t0, t0, t1);
15587        gen_load_gpr(t1, rd + 1);
15588        tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL);
15589        break;
15590#ifdef TARGET_MIPS64
15591    case LDP:
15592        if (rd == base) {
15593            generate_exception_end(ctx, EXCP_RI);
15594            return;
15595        }
15596        tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TEQ);
15597        gen_store_gpr(t1, rd);
15598        tcg_gen_movi_tl(t1, 8);
15599        gen_op_addr_add(ctx, t0, t0, t1);
15600        tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TEQ);
15601        gen_store_gpr(t1, rd + 1);
15602        break;
15603    case SDP:
15604        gen_load_gpr(t1, rd);
15605        tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEQ);
15606        tcg_gen_movi_tl(t1, 8);
15607        gen_op_addr_add(ctx, t0, t0, t1);
15608        gen_load_gpr(t1, rd + 1);
15609        tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEQ);
15610        break;
15611#endif
15612    }
15613    tcg_temp_free(t0);
15614    tcg_temp_free(t1);
15615}
15616
15617static void gen_sync(int stype)
15618{
15619    TCGBar tcg_mo = TCG_BAR_SC;
15620
15621    switch (stype) {
15622    case 0x4: /* SYNC_WMB */
15623        tcg_mo |= TCG_MO_ST_ST;
15624        break;
15625    case 0x10: /* SYNC_MB */
15626        tcg_mo |= TCG_MO_ALL;
15627        break;
15628    case 0x11: /* SYNC_ACQUIRE */
15629        tcg_mo |= TCG_MO_LD_LD | TCG_MO_LD_ST;
15630        break;
15631    case 0x12: /* SYNC_RELEASE */
15632        tcg_mo |= TCG_MO_ST_ST | TCG_MO_LD_ST;
15633        break;
15634    case 0x13: /* SYNC_RMB */
15635        tcg_mo |= TCG_MO_LD_LD;
15636        break;
15637    default:
15638        tcg_mo |= TCG_MO_ALL;
15639        break;
15640    }
15641
15642    tcg_gen_mb(tcg_mo);
15643}
15644
15645static void gen_pool32axf(CPUMIPSState *env, DisasContext *ctx, int rt, int rs)
15646{
15647    int extension = (ctx->opcode >> 6) & 0x3f;
15648    int minor = (ctx->opcode >> 12) & 0xf;
15649    uint32_t mips32_op;
15650
15651    switch (extension) {
15652    case TEQ:
15653        mips32_op = OPC_TEQ;
15654        goto do_trap;
15655    case TGE:
15656        mips32_op = OPC_TGE;
15657        goto do_trap;
15658    case TGEU:
15659        mips32_op = OPC_TGEU;
15660        goto do_trap;
15661    case TLT:
15662        mips32_op = OPC_TLT;
15663        goto do_trap;
15664    case TLTU:
15665        mips32_op = OPC_TLTU;
15666        goto do_trap;
15667    case TNE:
15668        mips32_op = OPC_TNE;
15669    do_trap:
15670        gen_trap(ctx, mips32_op, rs, rt, -1);
15671        break;
15672#ifndef CONFIG_USER_ONLY
15673    case MFC0:
15674    case MFC0 + 32:
15675        check_cp0_enabled(ctx);
15676        if (rt == 0) {
15677            /* Treat as NOP. */
15678            break;
15679        }
15680        gen_mfc0(ctx, cpu_gpr[rt], rs, (ctx->opcode >> 11) & 0x7);
15681        break;
15682    case MTC0:
15683    case MTC0 + 32:
15684        check_cp0_enabled(ctx);
15685        {
15686            TCGv t0 = tcg_temp_new();
15687
15688            gen_load_gpr(t0, rt);
15689            gen_mtc0(ctx, t0, rs, (ctx->opcode >> 11) & 0x7);
15690            tcg_temp_free(t0);
15691        }
15692        break;
15693#endif
15694    case 0x2a:
15695        switch (minor & 3) {
15696        case MADD_ACC:
15697            gen_muldiv(ctx, OPC_MADD, (ctx->opcode >> 14) & 3, rs, rt);
15698            break;
15699        case MADDU_ACC:
15700            gen_muldiv(ctx, OPC_MADDU, (ctx->opcode >> 14) & 3, rs, rt);
15701            break;
15702        case MSUB_ACC:
15703            gen_muldiv(ctx, OPC_MSUB, (ctx->opcode >> 14) & 3, rs, rt);
15704            break;
15705        case MSUBU_ACC:
15706            gen_muldiv(ctx, OPC_MSUBU, (ctx->opcode >> 14) & 3, rs, rt);
15707            break;
15708        default:
15709            goto pool32axf_invalid;
15710        }
15711        break;
15712    case 0x32:
15713        switch (minor & 3) {
15714        case MULT_ACC:
15715            gen_muldiv(ctx, OPC_MULT, (ctx->opcode >> 14) & 3, rs, rt);
15716            break;
15717        case MULTU_ACC:
15718            gen_muldiv(ctx, OPC_MULTU, (ctx->opcode >> 14) & 3, rs, rt);
15719            break;
15720        default:
15721            goto pool32axf_invalid;
15722        }
15723        break;
15724    case 0x2c:
15725        switch (minor) {
15726        case BITSWAP:
15727            check_insn(ctx, ISA_MIPS32R6);
15728            gen_bitswap(ctx, OPC_BITSWAP, rs, rt);
15729            break;
15730        case SEB:
15731            gen_bshfl(ctx, OPC_SEB, rs, rt);
15732            break;
15733        case SEH:
15734            gen_bshfl(ctx, OPC_SEH, rs, rt);
15735            break;
15736        case CLO:
15737            mips32_op = OPC_CLO;
15738            goto do_cl;
15739        case CLZ:
15740            mips32_op = OPC_CLZ;
15741        do_cl:
15742            check_insn(ctx, ISA_MIPS32);
15743            gen_cl(ctx, mips32_op, rt, rs);
15744            break;
15745        case RDHWR:
15746            check_insn_opc_removed(ctx, ISA_MIPS32R6);
15747            gen_rdhwr(ctx, rt, rs, 0);
15748            break;
15749        case WSBH:
15750            gen_bshfl(ctx, OPC_WSBH, rs, rt);
15751            break;
15752        case MULT:
15753            check_insn_opc_removed(ctx, ISA_MIPS32R6);
15754            mips32_op = OPC_MULT;
15755            goto do_mul;
15756        case MULTU:
15757            check_insn_opc_removed(ctx, ISA_MIPS32R6);
15758            mips32_op = OPC_MULTU;
15759            goto do_mul;
15760        case DIV:
15761            check_insn_opc_removed(ctx, ISA_MIPS32R6);
15762            mips32_op = OPC_DIV;
15763            goto do_div;
15764        case DIVU:
15765            check_insn_opc_removed(ctx, ISA_MIPS32R6);
15766            mips32_op = OPC_DIVU;
15767            goto do_div;
15768        do_div:
15769            check_insn(ctx, ISA_MIPS32);
15770            gen_muldiv(ctx, mips32_op, 0, rs, rt);
15771            break;
15772        case MADD:
15773            check_insn_opc_removed(ctx, ISA_MIPS32R6);
15774            mips32_op = OPC_MADD;
15775            goto do_mul;
15776        case MADDU:
15777            check_insn_opc_removed(ctx, ISA_MIPS32R6);
15778            mips32_op = OPC_MADDU;
15779            goto do_mul;
15780        case MSUB:
15781            check_insn_opc_removed(ctx, ISA_MIPS32R6);
15782            mips32_op = OPC_MSUB;
15783            goto do_mul;
15784        case MSUBU:
15785            check_insn_opc_removed(ctx, ISA_MIPS32R6);
15786            mips32_op = OPC_MSUBU;
15787        do_mul:
15788            check_insn(ctx, ISA_MIPS32);
15789            gen_muldiv(ctx, mips32_op, 0, rs, rt);
15790            break;
15791        default:
15792            goto pool32axf_invalid;
15793        }
15794        break;
15795    case 0x34:
15796        switch (minor) {
15797        case MFC2:
15798        case MTC2:
15799        case MFHC2:
15800        case MTHC2:
15801        case CFC2:
15802        case CTC2:
15803            generate_exception_err(ctx, EXCP_CpU, 2);
15804            break;
15805        default:
15806            goto pool32axf_invalid;
15807        }
15808        break;
15809    case 0x3c:
15810        switch (minor) {
15811        case JALR:    /* JALRC */
15812        case JALR_HB: /* JALRC_HB */
15813            if (ctx->insn_flags & ISA_MIPS32R6) {
15814                /* JALRC, JALRC_HB */
15815                gen_compute_branch(ctx, OPC_JALR, 4, rs, rt, 0, 0);
15816            } else {
15817                /* JALR, JALR_HB */
15818                gen_compute_branch(ctx, OPC_JALR, 4, rs, rt, 0, 4);
15819                ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
15820            }
15821            break;
15822        case JALRS:
15823        case JALRS_HB:
15824            check_insn_opc_removed(ctx, ISA_MIPS32R6);
15825            gen_compute_branch(ctx, OPC_JALR, 4, rs, rt, 0, 2);
15826            ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
15827            break;
15828        default:
15829            goto pool32axf_invalid;
15830        }
15831        break;
15832    case 0x05:
15833        switch (minor) {
15834        case RDPGPR:
15835            check_cp0_enabled(ctx);
15836            check_insn(ctx, ISA_MIPS32R2);
15837            gen_load_srsgpr(rs, rt);
15838            break;
15839        case WRPGPR:
15840            check_cp0_enabled(ctx);
15841            check_insn(ctx, ISA_MIPS32R2);
15842            gen_store_srsgpr(rs, rt);
15843            break;
15844        default:
15845            goto pool32axf_invalid;
15846        }
15847        break;
15848#ifndef CONFIG_USER_ONLY
15849    case 0x0d:
15850        switch (minor) {
15851        case TLBP:
15852            mips32_op = OPC_TLBP;
15853            goto do_cp0;
15854        case TLBR:
15855            mips32_op = OPC_TLBR;
15856            goto do_cp0;
15857        case TLBWI:
15858            mips32_op = OPC_TLBWI;
15859            goto do_cp0;
15860        case TLBWR:
15861            mips32_op = OPC_TLBWR;
15862            goto do_cp0;
15863        case TLBINV:
15864            mips32_op = OPC_TLBINV;
15865            goto do_cp0;
15866        case TLBINVF:
15867            mips32_op = OPC_TLBINVF;
15868            goto do_cp0;
15869        case WAIT:
15870            mips32_op = OPC_WAIT;
15871            goto do_cp0;
15872        case DERET:
15873            mips32_op = OPC_DERET;
15874            goto do_cp0;
15875        case ERET:
15876            mips32_op = OPC_ERET;
15877        do_cp0:
15878            gen_cp0(env, ctx, mips32_op, rt, rs);
15879            break;
15880        default:
15881            goto pool32axf_invalid;
15882        }
15883        break;
15884    case 0x1d:
15885        switch (minor) {
15886        case DI:
15887            check_cp0_enabled(ctx);
15888            {
15889                TCGv t0 = tcg_temp_new();
15890
15891                save_cpu_state(ctx, 1);
15892                gen_helper_di(t0, cpu_env);
15893                gen_store_gpr(t0, rs);
15894                /*
15895                 * Stop translation as we may have switched the execution
15896                 * mode.
15897                 */
15898                ctx->base.is_jmp = DISAS_STOP;
15899                tcg_temp_free(t0);
15900            }
15901            break;
15902        case EI:
15903            check_cp0_enabled(ctx);
15904            {
15905                TCGv t0 = tcg_temp_new();
15906
15907                save_cpu_state(ctx, 1);
15908                gen_helper_ei(t0, cpu_env);
15909                gen_store_gpr(t0, rs);
15910                /*
15911                 * DISAS_STOP isn't sufficient, we need to ensure we break out
15912                 * of translated code to check for pending interrupts.
15913                 */
15914                gen_save_pc(ctx->base.pc_next + 4);
15915                ctx->base.is_jmp = DISAS_EXIT;
15916                tcg_temp_free(t0);
15917            }
15918            break;
15919        default:
15920            goto pool32axf_invalid;
15921        }
15922        break;
15923#endif
15924    case 0x2d:
15925        switch (minor) {
15926        case SYNC:
15927            gen_sync(extract32(ctx->opcode, 16, 5));
15928            break;
15929        case SYSCALL:
15930            generate_exception_end(ctx, EXCP_SYSCALL);
15931            break;
15932        case SDBBP:
15933            if (is_uhi(extract32(ctx->opcode, 16, 10))) {
15934                gen_helper_do_semihosting(cpu_env);
15935            } else {
15936                check_insn(ctx, ISA_MIPS32);
15937                if (ctx->hflags & MIPS_HFLAG_SBRI) {
15938                    generate_exception_end(ctx, EXCP_RI);
15939                } else {
15940                    generate_exception_end(ctx, EXCP_DBp);
15941                }
15942            }
15943            break;
15944        default:
15945            goto pool32axf_invalid;
15946        }
15947        break;
15948    case 0x01:
15949        switch (minor & 3) {
15950        case MFHI_ACC:
15951            gen_HILO(ctx, OPC_MFHI, minor >> 2, rs);
15952            break;
15953        case MFLO_ACC:
15954            gen_HILO(ctx, OPC_MFLO, minor >> 2, rs);
15955            break;
15956        case MTHI_ACC:
15957            gen_HILO(ctx, OPC_MTHI, minor >> 2, rs);
15958            break;
15959        case MTLO_ACC:
15960            gen_HILO(ctx, OPC_MTLO, minor >> 2, rs);
15961            break;
15962        default:
15963            goto pool32axf_invalid;
15964        }
15965        break;
15966    case 0x35:
15967        check_insn_opc_removed(ctx, ISA_MIPS32R6);
15968        switch (minor) {
15969        case MFHI32:
15970            gen_HILO(ctx, OPC_MFHI, 0, rs);
15971            break;
15972        case MFLO32:
15973            gen_HILO(ctx, OPC_MFLO, 0, rs);
15974            break;
15975        case MTHI32:
15976            gen_HILO(ctx, OPC_MTHI, 0, rs);
15977            break;
15978        case MTLO32:
15979            gen_HILO(ctx, OPC_MTLO, 0, rs);
15980            break;
15981        default:
15982            goto pool32axf_invalid;
15983        }
15984        break;
15985    default:
15986    pool32axf_invalid:
15987        MIPS_INVAL("pool32axf");
15988        generate_exception_end(ctx, EXCP_RI);
15989        break;
15990    }
15991}
15992
15993/*
15994 * Values for microMIPS fmt field.  Variable-width, depending on which
15995 * formats the instruction supports.
15996 */
15997enum {
15998    FMT_SD_S = 0,
15999    FMT_SD_D = 1,
16000
16001    FMT_SDPS_S = 0,
16002    FMT_SDPS_D = 1,
16003    FMT_SDPS_PS = 2,
16004
16005    FMT_SWL_S = 0,
16006    FMT_SWL_W = 1,
16007    FMT_SWL_L = 2,
16008
16009    FMT_DWL_D = 0,
16010    FMT_DWL_W = 1,
16011    FMT_DWL_L = 2
16012};
16013
16014static void gen_pool32fxf(DisasContext *ctx, int rt, int rs)
16015{
16016    int extension = (ctx->opcode >> 6) & 0x3ff;
16017    uint32_t mips32_op;
16018
16019#define FLOAT_1BIT_FMT(opc, fmt)    ((fmt << 8) | opc)
16020#define FLOAT_2BIT_FMT(opc, fmt)    ((fmt << 7) | opc)
16021#define COND_FLOAT_MOV(opc, cond)   ((cond << 7) | opc)
16022
16023    switch (extension) {
16024    case FLOAT_1BIT_FMT(CFC1, 0):
16025        mips32_op = OPC_CFC1;
16026        goto do_cp1;
16027    case FLOAT_1BIT_FMT(CTC1, 0):
16028        mips32_op = OPC_CTC1;
16029        goto do_cp1;
16030    case FLOAT_1BIT_FMT(MFC1, 0):
16031        mips32_op = OPC_MFC1;
16032        goto do_cp1;
16033    case FLOAT_1BIT_FMT(MTC1, 0):
16034        mips32_op = OPC_MTC1;
16035        goto do_cp1;
16036    case FLOAT_1BIT_FMT(MFHC1, 0):
16037        mips32_op = OPC_MFHC1;
16038        goto do_cp1;
16039    case FLOAT_1BIT_FMT(MTHC1, 0):
16040        mips32_op = OPC_MTHC1;
16041    do_cp1:
16042        gen_cp1(ctx, mips32_op, rt, rs);
16043        break;
16044
16045        /* Reciprocal square root */
16046    case FLOAT_1BIT_FMT(RSQRT_FMT, FMT_SD_S):
16047        mips32_op = OPC_RSQRT_S;
16048        goto do_unaryfp;
16049    case FLOAT_1BIT_FMT(RSQRT_FMT, FMT_SD_D):
16050        mips32_op = OPC_RSQRT_D;
16051        goto do_unaryfp;
16052
16053        /* Square root */
16054    case FLOAT_1BIT_FMT(SQRT_FMT, FMT_SD_S):
16055        mips32_op = OPC_SQRT_S;
16056        goto do_unaryfp;
16057    case FLOAT_1BIT_FMT(SQRT_FMT, FMT_SD_D):
16058        mips32_op = OPC_SQRT_D;
16059        goto do_unaryfp;
16060
16061        /* Reciprocal */
16062    case FLOAT_1BIT_FMT(RECIP_FMT, FMT_SD_S):
16063        mips32_op = OPC_RECIP_S;
16064        goto do_unaryfp;
16065    case FLOAT_1BIT_FMT(RECIP_FMT, FMT_SD_D):
16066        mips32_op = OPC_RECIP_D;
16067        goto do_unaryfp;
16068
16069        /* Floor */
16070    case FLOAT_1BIT_FMT(FLOOR_L, FMT_SD_S):
16071        mips32_op = OPC_FLOOR_L_S;
16072        goto do_unaryfp;
16073    case FLOAT_1BIT_FMT(FLOOR_L, FMT_SD_D):
16074        mips32_op = OPC_FLOOR_L_D;
16075        goto do_unaryfp;
16076    case FLOAT_1BIT_FMT(FLOOR_W, FMT_SD_S):
16077        mips32_op = OPC_FLOOR_W_S;
16078        goto do_unaryfp;
16079    case FLOAT_1BIT_FMT(FLOOR_W, FMT_SD_D):
16080        mips32_op = OPC_FLOOR_W_D;
16081        goto do_unaryfp;
16082
16083        /* Ceiling */
16084    case FLOAT_1BIT_FMT(CEIL_L, FMT_SD_S):
16085        mips32_op = OPC_CEIL_L_S;
16086        goto do_unaryfp;
16087    case FLOAT_1BIT_FMT(CEIL_L, FMT_SD_D):
16088        mips32_op = OPC_CEIL_L_D;
16089        goto do_unaryfp;
16090    case FLOAT_1BIT_FMT(CEIL_W, FMT_SD_S):
16091        mips32_op = OPC_CEIL_W_S;
16092        goto do_unaryfp;
16093    case FLOAT_1BIT_FMT(CEIL_W, FMT_SD_D):
16094        mips32_op = OPC_CEIL_W_D;
16095        goto do_unaryfp;
16096
16097        /* Truncation */
16098    case FLOAT_1BIT_FMT(TRUNC_L, FMT_SD_S):
16099        mips32_op = OPC_TRUNC_L_S;
16100        goto do_unaryfp;
16101    case FLOAT_1BIT_FMT(TRUNC_L, FMT_SD_D):
16102        mips32_op = OPC_TRUNC_L_D;
16103        goto do_unaryfp;
16104    case FLOAT_1BIT_FMT(TRUNC_W, FMT_SD_S):
16105        mips32_op = OPC_TRUNC_W_S;
16106        goto do_unaryfp;
16107    case FLOAT_1BIT_FMT(TRUNC_W, FMT_SD_D):
16108        mips32_op = OPC_TRUNC_W_D;
16109        goto do_unaryfp;
16110
16111        /* Round */
16112    case FLOAT_1BIT_FMT(ROUND_L, FMT_SD_S):
16113        mips32_op = OPC_ROUND_L_S;
16114        goto do_unaryfp;
16115    case FLOAT_1BIT_FMT(ROUND_L, FMT_SD_D):
16116        mips32_op = OPC_ROUND_L_D;
16117        goto do_unaryfp;
16118    case FLOAT_1BIT_FMT(ROUND_W, FMT_SD_S):
16119        mips32_op = OPC_ROUND_W_S;
16120        goto do_unaryfp;
16121    case FLOAT_1BIT_FMT(ROUND_W, FMT_SD_D):
16122        mips32_op = OPC_ROUND_W_D;
16123        goto do_unaryfp;
16124
16125        /* Integer to floating-point conversion */
16126    case FLOAT_1BIT_FMT(CVT_L, FMT_SD_S):
16127        mips32_op = OPC_CVT_L_S;
16128        goto do_unaryfp;
16129    case FLOAT_1BIT_FMT(CVT_L, FMT_SD_D):
16130        mips32_op = OPC_CVT_L_D;
16131        goto do_unaryfp;
16132    case FLOAT_1BIT_FMT(CVT_W, FMT_SD_S):
16133        mips32_op = OPC_CVT_W_S;
16134        goto do_unaryfp;
16135    case FLOAT_1BIT_FMT(CVT_W, FMT_SD_D):
16136        mips32_op = OPC_CVT_W_D;
16137        goto do_unaryfp;
16138
16139        /* Paired-foo conversions */
16140    case FLOAT_1BIT_FMT(CVT_S_PL, 0):
16141        mips32_op = OPC_CVT_S_PL;
16142        goto do_unaryfp;
16143    case FLOAT_1BIT_FMT(CVT_S_PU, 0):
16144        mips32_op = OPC_CVT_S_PU;
16145        goto do_unaryfp;
16146    case FLOAT_1BIT_FMT(CVT_PW_PS, 0):
16147        mips32_op = OPC_CVT_PW_PS;
16148        goto do_unaryfp;
16149    case FLOAT_1BIT_FMT(CVT_PS_PW, 0):
16150        mips32_op = OPC_CVT_PS_PW;
16151        goto do_unaryfp;
16152
16153        /* Floating-point moves */
16154    case FLOAT_2BIT_FMT(MOV_FMT, FMT_SDPS_S):
16155        mips32_op = OPC_MOV_S;
16156        goto do_unaryfp;
16157    case FLOAT_2BIT_FMT(MOV_FMT, FMT_SDPS_D):
16158        mips32_op = OPC_MOV_D;
16159        goto do_unaryfp;
16160    case FLOAT_2BIT_FMT(MOV_FMT, FMT_SDPS_PS):
16161        mips32_op = OPC_MOV_PS;
16162        goto do_unaryfp;
16163
16164        /* Absolute value */
16165    case FLOAT_2BIT_FMT(ABS_FMT, FMT_SDPS_S):
16166        mips32_op = OPC_ABS_S;
16167        goto do_unaryfp;
16168    case FLOAT_2BIT_FMT(ABS_FMT, FMT_SDPS_D):
16169        mips32_op = OPC_ABS_D;
16170        goto do_unaryfp;
16171    case FLOAT_2BIT_FMT(ABS_FMT, FMT_SDPS_PS):
16172        mips32_op = OPC_ABS_PS;
16173        goto do_unaryfp;
16174
16175        /* Negation */
16176    case FLOAT_2BIT_FMT(NEG_FMT, FMT_SDPS_S):
16177        mips32_op = OPC_NEG_S;
16178        goto do_unaryfp;
16179    case FLOAT_2BIT_FMT(NEG_FMT, FMT_SDPS_D):
16180        mips32_op = OPC_NEG_D;
16181        goto do_unaryfp;
16182    case FLOAT_2BIT_FMT(NEG_FMT, FMT_SDPS_PS):
16183        mips32_op = OPC_NEG_PS;
16184        goto do_unaryfp;
16185
16186        /* Reciprocal square root step */
16187    case FLOAT_2BIT_FMT(RSQRT1_FMT, FMT_SDPS_S):
16188        mips32_op = OPC_RSQRT1_S;
16189        goto do_unaryfp;
16190    case FLOAT_2BIT_FMT(RSQRT1_FMT, FMT_SDPS_D):
16191        mips32_op = OPC_RSQRT1_D;
16192        goto do_unaryfp;
16193    case FLOAT_2BIT_FMT(RSQRT1_FMT, FMT_SDPS_PS):
16194        mips32_op = OPC_RSQRT1_PS;
16195        goto do_unaryfp;
16196
16197        /* Reciprocal step */
16198    case FLOAT_2BIT_FMT(RECIP1_FMT, FMT_SDPS_S):
16199        mips32_op = OPC_RECIP1_S;
16200        goto do_unaryfp;
16201    case FLOAT_2BIT_FMT(RECIP1_FMT, FMT_SDPS_D):
16202        mips32_op = OPC_RECIP1_S;
16203        goto do_unaryfp;
16204    case FLOAT_2BIT_FMT(RECIP1_FMT, FMT_SDPS_PS):
16205        mips32_op = OPC_RECIP1_PS;
16206        goto do_unaryfp;
16207
16208        /* Conversions from double */
16209    case FLOAT_2BIT_FMT(CVT_D, FMT_SWL_S):
16210        mips32_op = OPC_CVT_D_S;
16211        goto do_unaryfp;
16212    case FLOAT_2BIT_FMT(CVT_D, FMT_SWL_W):
16213        mips32_op = OPC_CVT_D_W;
16214        goto do_unaryfp;
16215    case FLOAT_2BIT_FMT(CVT_D, FMT_SWL_L):
16216        mips32_op = OPC_CVT_D_L;
16217        goto do_unaryfp;
16218
16219        /* Conversions from single */
16220    case FLOAT_2BIT_FMT(CVT_S, FMT_DWL_D):
16221        mips32_op = OPC_CVT_S_D;
16222        goto do_unaryfp;
16223    case FLOAT_2BIT_FMT(CVT_S, FMT_DWL_W):
16224        mips32_op = OPC_CVT_S_W;
16225        goto do_unaryfp;
16226    case FLOAT_2BIT_FMT(CVT_S, FMT_DWL_L):
16227        mips32_op = OPC_CVT_S_L;
16228    do_unaryfp:
16229        gen_farith(ctx, mips32_op, -1, rs, rt, 0);
16230        break;
16231
16232        /* Conditional moves on floating-point codes */
16233    case COND_FLOAT_MOV(MOVT, 0):
16234    case COND_FLOAT_MOV(MOVT, 1):
16235    case COND_FLOAT_MOV(MOVT, 2):
16236    case COND_FLOAT_MOV(MOVT, 3):
16237    case COND_FLOAT_MOV(MOVT, 4):
16238    case COND_FLOAT_MOV(MOVT, 5):
16239    case COND_FLOAT_MOV(MOVT, 6):
16240    case COND_FLOAT_MOV(MOVT, 7):
16241        check_insn_opc_removed(ctx, ISA_MIPS32R6);
16242        gen_movci(ctx, rt, rs, (ctx->opcode >> 13) & 0x7, 1);
16243        break;
16244    case COND_FLOAT_MOV(MOVF, 0):
16245    case COND_FLOAT_MOV(MOVF, 1):
16246    case COND_FLOAT_MOV(MOVF, 2):
16247    case COND_FLOAT_MOV(MOVF, 3):
16248    case COND_FLOAT_MOV(MOVF, 4):
16249    case COND_FLOAT_MOV(MOVF, 5):
16250    case COND_FLOAT_MOV(MOVF, 6):
16251    case COND_FLOAT_MOV(MOVF, 7):
16252        check_insn_opc_removed(ctx, ISA_MIPS32R6);
16253        gen_movci(ctx, rt, rs, (ctx->opcode >> 13) & 0x7, 0);
16254        break;
16255    default:
16256        MIPS_INVAL("pool32fxf");
16257        generate_exception_end(ctx, EXCP_RI);
16258        break;
16259    }
16260}
16261
16262static void decode_micromips32_opc(CPUMIPSState *env, DisasContext *ctx)
16263{
16264    int32_t offset;
16265    uint16_t insn;
16266    int rt, rs, rd, rr;
16267    int16_t imm;
16268    uint32_t op, minor, minor2, mips32_op;
16269    uint32_t cond, fmt, cc;
16270
16271    insn = cpu_lduw_code(env, ctx->base.pc_next + 2);
16272    ctx->opcode = (ctx->opcode << 16) | insn;
16273
16274    rt = (ctx->opcode >> 21) & 0x1f;
16275    rs = (ctx->opcode >> 16) & 0x1f;
16276    rd = (ctx->opcode >> 11) & 0x1f;
16277    rr = (ctx->opcode >> 6) & 0x1f;
16278    imm = (int16_t) ctx->opcode;
16279
16280    op = (ctx->opcode >> 26) & 0x3f;
16281    switch (op) {
16282    case POOL32A:
16283        minor = ctx->opcode & 0x3f;
16284        switch (minor) {
16285        case 0x00:
16286            minor = (ctx->opcode >> 6) & 0xf;
16287            switch (minor) {
16288            case SLL32:
16289                mips32_op = OPC_SLL;
16290                goto do_shifti;
16291            case SRA:
16292                mips32_op = OPC_SRA;
16293                goto do_shifti;
16294            case SRL32:
16295                mips32_op = OPC_SRL;
16296                goto do_shifti;
16297            case ROTR:
16298                mips32_op = OPC_ROTR;
16299            do_shifti:
16300                gen_shift_imm(ctx, mips32_op, rt, rs, rd);
16301                break;
16302            case SELEQZ:
16303                check_insn(ctx, ISA_MIPS32R6);
16304                gen_cond_move(ctx, OPC_SELEQZ, rd, rs, rt);
16305                break;
16306            case SELNEZ:
16307                check_insn(ctx, ISA_MIPS32R6);
16308                gen_cond_move(ctx, OPC_SELNEZ, rd, rs, rt);
16309                break;
16310            case R6_RDHWR:
16311                check_insn(ctx, ISA_MIPS32R6);
16312                gen_rdhwr(ctx, rt, rs, extract32(ctx->opcode, 11, 3));
16313                break;
16314            default:
16315                goto pool32a_invalid;
16316            }
16317            break;
16318        case 0x10:
16319            minor = (ctx->opcode >> 6) & 0xf;
16320            switch (minor) {
16321                /* Arithmetic */
16322            case ADD:
16323                mips32_op = OPC_ADD;
16324                goto do_arith;
16325            case ADDU32:
16326                mips32_op = OPC_ADDU;
16327                goto do_arith;
16328            case SUB:
16329                mips32_op = OPC_SUB;
16330                goto do_arith;
16331            case SUBU32:
16332                mips32_op = OPC_SUBU;
16333                goto do_arith;
16334            case MUL:
16335                check_insn_opc_removed(ctx, ISA_MIPS32R6);
16336                mips32_op = OPC_MUL;
16337            do_arith:
16338                gen_arith(ctx, mips32_op, rd, rs, rt);
16339                break;
16340                /* Shifts */
16341            case SLLV:
16342                mips32_op = OPC_SLLV;
16343                goto do_shift;
16344            case SRLV:
16345                mips32_op = OPC_SRLV;
16346                goto do_shift;
16347            case SRAV:
16348                mips32_op = OPC_SRAV;
16349                goto do_shift;
16350            case ROTRV:
16351                mips32_op = OPC_ROTRV;
16352            do_shift:
16353                gen_shift(ctx, mips32_op, rd, rs, rt);
16354                break;
16355                /* Logical operations */
16356            case AND:
16357                mips32_op = OPC_AND;
16358                goto do_logic;
16359            case OR32:
16360                mips32_op = OPC_OR;
16361                goto do_logic;
16362            case NOR:
16363                mips32_op = OPC_NOR;
16364                goto do_logic;
16365            case XOR32:
16366                mips32_op = OPC_XOR;
16367            do_logic:
16368                gen_logic(ctx, mips32_op, rd, rs, rt);
16369                break;
16370                /* Set less than */
16371            case SLT:
16372                mips32_op = OPC_SLT;
16373                goto do_slt;
16374            case SLTU:
16375                mips32_op = OPC_SLTU;
16376            do_slt:
16377                gen_slt(ctx, mips32_op, rd, rs, rt);
16378                break;
16379            default:
16380                goto pool32a_invalid;
16381            }
16382            break;
16383        case 0x18:
16384            minor = (ctx->opcode >> 6) & 0xf;
16385            switch (minor) {
16386                /* Conditional moves */
16387            case MOVN: /* MUL */
16388                if (ctx->insn_flags & ISA_MIPS32R6) {
16389                    /* MUL */
16390                    gen_r6_muldiv(ctx, R6_OPC_MUL, rd, rs, rt);
16391                } else {
16392                    /* MOVN */
16393                    gen_cond_move(ctx, OPC_MOVN, rd, rs, rt);
16394                }
16395                break;
16396            case MOVZ: /* MUH */
16397                if (ctx->insn_flags & ISA_MIPS32R6) {
16398                    /* MUH */
16399                    gen_r6_muldiv(ctx, R6_OPC_MUH, rd, rs, rt);
16400                } else {
16401                    /* MOVZ */
16402                    gen_cond_move(ctx, OPC_MOVZ, rd, rs, rt);
16403                }
16404                break;
16405            case MULU:
16406                check_insn(ctx, ISA_MIPS32R6);
16407                gen_r6_muldiv(ctx, R6_OPC_MULU, rd, rs, rt);
16408                break;
16409            case MUHU:
16410                check_insn(ctx, ISA_MIPS32R6);
16411                gen_r6_muldiv(ctx, R6_OPC_MUHU, rd, rs, rt);
16412                break;
16413            case LWXS: /* DIV */
16414                if (ctx->insn_flags & ISA_MIPS32R6) {
16415                    /* DIV */
16416                    gen_r6_muldiv(ctx, R6_OPC_DIV, rd, rs, rt);
16417                } else {
16418                    /* LWXS */
16419                    gen_ldxs(ctx, rs, rt, rd);
16420                }
16421                break;
16422            case MOD:
16423                check_insn(ctx, ISA_MIPS32R6);
16424                gen_r6_muldiv(ctx, R6_OPC_MOD, rd, rs, rt);
16425                break;
16426            case R6_DIVU:
16427                check_insn(ctx, ISA_MIPS32R6);
16428                gen_r6_muldiv(ctx, R6_OPC_DIVU, rd, rs, rt);
16429                break;
16430            case MODU:
16431                check_insn(ctx, ISA_MIPS32R6);
16432                gen_r6_muldiv(ctx, R6_OPC_MODU, rd, rs, rt);
16433                break;
16434            default:
16435                goto pool32a_invalid;
16436            }
16437            break;
16438        case INS:
16439            gen_bitops(ctx, OPC_INS, rt, rs, rr, rd);
16440            return;
16441        case LSA:
16442            check_insn(ctx, ISA_MIPS32R6);
16443            gen_lsa(ctx, OPC_LSA, rd, rs, rt,
16444                    extract32(ctx->opcode, 9, 2));
16445            break;
16446        case ALIGN:
16447            check_insn(ctx, ISA_MIPS32R6);
16448            gen_align(ctx, 32, rd, rs, rt, extract32(ctx->opcode, 9, 2));
16449            break;
16450        case EXT:
16451            gen_bitops(ctx, OPC_EXT, rt, rs, rr, rd);
16452            return;
16453        case POOL32AXF:
16454            gen_pool32axf(env, ctx, rt, rs);
16455            break;
16456        case BREAK32:
16457            generate_exception_end(ctx, EXCP_BREAK);
16458            break;
16459        case SIGRIE:
16460            check_insn(ctx, ISA_MIPS32R6);
16461            generate_exception_end(ctx, EXCP_RI);
16462            break;
16463        default:
16464        pool32a_invalid:
16465                MIPS_INVAL("pool32a");
16466                generate_exception_end(ctx, EXCP_RI);
16467                break;
16468        }
16469        break;
16470    case POOL32B:
16471        minor = (ctx->opcode >> 12) & 0xf;
16472        switch (minor) {
16473        case CACHE:
16474            check_cp0_enabled(ctx);
16475            if (ctx->hflags & MIPS_HFLAG_ITC_CACHE) {
16476                gen_cache_operation(ctx, rt, rs, imm);
16477            }
16478            break;
16479        case LWC2:
16480        case SWC2:
16481            /* COP2: Not implemented. */
16482            generate_exception_err(ctx, EXCP_CpU, 2);
16483            break;
16484#ifdef TARGET_MIPS64
16485        case LDP:
16486        case SDP:
16487            check_insn(ctx, ISA_MIPS3);
16488            check_mips_64(ctx);
16489#endif
16490            /* fall through */
16491        case LWP:
16492        case SWP:
16493            gen_ldst_pair(ctx, minor, rt, rs, SIMM(ctx->opcode, 0, 12));
16494            break;
16495#ifdef TARGET_MIPS64
16496        case LDM:
16497        case SDM:
16498            check_insn(ctx, ISA_MIPS3);
16499            check_mips_64(ctx);
16500#endif
16501            /* fall through */
16502        case LWM32:
16503        case SWM32:
16504            gen_ldst_multiple(ctx, minor, rt, rs, SIMM(ctx->opcode, 0, 12));
16505            break;
16506        default:
16507            MIPS_INVAL("pool32b");
16508            generate_exception_end(ctx, EXCP_RI);
16509            break;
16510        }
16511        break;
16512    case POOL32F:
16513        if (ctx->CP0_Config1 & (1 << CP0C1_FP)) {
16514            minor = ctx->opcode & 0x3f;
16515            check_cp1_enabled(ctx);
16516            switch (minor) {
16517            case ALNV_PS:
16518                check_insn_opc_removed(ctx, ISA_MIPS32R6);
16519                mips32_op = OPC_ALNV_PS;
16520                goto do_madd;
16521            case MADD_S:
16522                check_insn_opc_removed(ctx, ISA_MIPS32R6);
16523                mips32_op = OPC_MADD_S;
16524                goto do_madd;
16525            case MADD_D:
16526                check_insn_opc_removed(ctx, ISA_MIPS32R6);
16527                mips32_op = OPC_MADD_D;
16528                goto do_madd;
16529            case MADD_PS:
16530                check_insn_opc_removed(ctx, ISA_MIPS32R6);
16531                mips32_op = OPC_MADD_PS;
16532                goto do_madd;
16533            case MSUB_S:
16534                check_insn_opc_removed(ctx, ISA_MIPS32R6);
16535                mips32_op = OPC_MSUB_S;
16536                goto do_madd;
16537            case MSUB_D:
16538                check_insn_opc_removed(ctx, ISA_MIPS32R6);
16539                mips32_op = OPC_MSUB_D;
16540                goto do_madd;
16541            case MSUB_PS:
16542                check_insn_opc_removed(ctx, ISA_MIPS32R6);
16543                mips32_op = OPC_MSUB_PS;
16544                goto do_madd;
16545            case NMADD_S:
16546                check_insn_opc_removed(ctx, ISA_MIPS32R6);
16547                mips32_op = OPC_NMADD_S;
16548                goto do_madd;
16549            case NMADD_D:
16550                check_insn_opc_removed(ctx, ISA_MIPS32R6);
16551                mips32_op = OPC_NMADD_D;
16552                goto do_madd;
16553            case NMADD_PS:
16554                check_insn_opc_removed(ctx, ISA_MIPS32R6);
16555                mips32_op = OPC_NMADD_PS;
16556                goto do_madd;
16557            case NMSUB_S:
16558                check_insn_opc_removed(ctx, ISA_MIPS32R6);
16559                mips32_op = OPC_NMSUB_S;
16560                goto do_madd;
16561            case NMSUB_D:
16562                check_insn_opc_removed(ctx, ISA_MIPS32R6);
16563                mips32_op = OPC_NMSUB_D;
16564                goto do_madd;
16565            case NMSUB_PS:
16566                check_insn_opc_removed(ctx, ISA_MIPS32R6);
16567                mips32_op = OPC_NMSUB_PS;
16568            do_madd:
16569                gen_flt3_arith(ctx, mips32_op, rd, rr, rs, rt);
16570                break;
16571            case CABS_COND_FMT:
16572                check_insn_opc_removed(ctx, ISA_MIPS32R6);
16573                cond = (ctx->opcode >> 6) & 0xf;
16574                cc = (ctx->opcode >> 13) & 0x7;
16575                fmt = (ctx->opcode >> 10) & 0x3;
16576                switch (fmt) {
16577                case 0x0:
16578                    gen_cmpabs_s(ctx, cond, rt, rs, cc);
16579                    break;
16580                case 0x1:
16581                    gen_cmpabs_d(ctx, cond, rt, rs, cc);
16582                    break;
16583                case 0x2:
16584                    gen_cmpabs_ps(ctx, cond, rt, rs, cc);
16585                    break;
16586                default:
16587                    goto pool32f_invalid;
16588                }
16589                break;
16590            case C_COND_FMT:
16591                check_insn_opc_removed(ctx, ISA_MIPS32R6);
16592                cond = (ctx->opcode >> 6) & 0xf;
16593                cc = (ctx->opcode >> 13) & 0x7;
16594                fmt = (ctx->opcode >> 10) & 0x3;
16595                switch (fmt) {
16596                case 0x0:
16597                    gen_cmp_s(ctx, cond, rt, rs, cc);
16598                    break;
16599                case 0x1:
16600                    gen_cmp_d(ctx, cond, rt, rs, cc);
16601                    break;
16602                case 0x2:
16603                    gen_cmp_ps(ctx, cond, rt, rs, cc);
16604                    break;
16605                default:
16606                    goto pool32f_invalid;
16607                }
16608                break;
16609            case CMP_CONDN_S:
16610                check_insn(ctx, ISA_MIPS32R6);
16611                gen_r6_cmp_s(ctx, (ctx->opcode >> 6) & 0x1f, rt, rs, rd);
16612                break;
16613            case CMP_CONDN_D:
16614                check_insn(ctx, ISA_MIPS32R6);
16615                gen_r6_cmp_d(ctx, (ctx->opcode >> 6) & 0x1f, rt, rs, rd);
16616                break;
16617            case POOL32FXF:
16618                gen_pool32fxf(ctx, rt, rs);
16619                break;
16620            case 0x00:
16621                /* PLL foo */
16622                switch ((ctx->opcode >> 6) & 0x7) {
16623                case PLL_PS:
16624                    mips32_op = OPC_PLL_PS;
16625                    goto do_ps;
16626                case PLU_PS:
16627                    mips32_op = OPC_PLU_PS;
16628                    goto do_ps;
16629                case PUL_PS:
16630                    mips32_op = OPC_PUL_PS;
16631                    goto do_ps;
16632                case PUU_PS:
16633                    mips32_op = OPC_PUU_PS;
16634                    goto do_ps;
16635                case CVT_PS_S:
16636                    check_insn_opc_removed(ctx, ISA_MIPS32R6);
16637                    mips32_op = OPC_CVT_PS_S;
16638                do_ps:
16639                    gen_farith(ctx, mips32_op, rt, rs, rd, 0);
16640                    break;
16641                default:
16642                    goto pool32f_invalid;
16643                }
16644                break;
16645            case MIN_FMT:
16646                check_insn(ctx, ISA_MIPS32R6);
16647                switch ((ctx->opcode >> 9) & 0x3) {
16648                case FMT_SDPS_S:
16649                    gen_farith(ctx, OPC_MIN_S, rt, rs, rd, 0);
16650                    break;
16651                case FMT_SDPS_D:
16652                    gen_farith(ctx, OPC_MIN_D, rt, rs, rd, 0);
16653                    break;
16654                default:
16655                    goto pool32f_invalid;
16656                }
16657                break;
16658            case 0x08:
16659                /* [LS][WDU]XC1 */
16660                switch ((ctx->opcode >> 6) & 0x7) {
16661                case LWXC1:
16662                    check_insn_opc_removed(ctx, ISA_MIPS32R6);
16663                    mips32_op = OPC_LWXC1;
16664                    goto do_ldst_cp1;
16665                case SWXC1:
16666                    check_insn_opc_removed(ctx, ISA_MIPS32R6);
16667                    mips32_op = OPC_SWXC1;
16668                    goto do_ldst_cp1;
16669                case LDXC1:
16670                    check_insn_opc_removed(ctx, ISA_MIPS32R6);
16671                    mips32_op = OPC_LDXC1;
16672                    goto do_ldst_cp1;
16673                case SDXC1:
16674                    check_insn_opc_removed(ctx, ISA_MIPS32R6);
16675                    mips32_op = OPC_SDXC1;
16676                    goto do_ldst_cp1;
16677                case LUXC1:
16678                    check_insn_opc_removed(ctx, ISA_MIPS32R6);
16679                    mips32_op = OPC_LUXC1;
16680                    goto do_ldst_cp1;
16681                case SUXC1:
16682                    check_insn_opc_removed(ctx, ISA_MIPS32R6);
16683                    mips32_op = OPC_SUXC1;
16684                do_ldst_cp1:
16685                    gen_flt3_ldst(ctx, mips32_op, rd, rd, rt, rs);
16686                    break;
16687                default:
16688                    goto pool32f_invalid;
16689                }
16690                break;
16691            case MAX_FMT:
16692                check_insn(ctx, ISA_MIPS32R6);
16693                switch ((ctx->opcode >> 9) & 0x3) {
16694                case FMT_SDPS_S:
16695                    gen_farith(ctx, OPC_MAX_S, rt, rs, rd, 0);
16696                    break;
16697                case FMT_SDPS_D:
16698                    gen_farith(ctx, OPC_MAX_D, rt, rs, rd, 0);
16699                    break;
16700                default:
16701                    goto pool32f_invalid;
16702                }
16703                break;
16704            case 0x18:
16705                /* 3D insns */
16706                check_insn_opc_removed(ctx, ISA_MIPS32R6);
16707                fmt = (ctx->opcode >> 9) & 0x3;
16708                switch ((ctx->opcode >> 6) & 0x7) {
16709                case RSQRT2_FMT:
16710                    switch (fmt) {
16711                    case FMT_SDPS_S:
16712                        mips32_op = OPC_RSQRT2_S;
16713                        goto do_3d;
16714                    case FMT_SDPS_D:
16715                        mips32_op = OPC_RSQRT2_D;
16716                        goto do_3d;
16717                    case FMT_SDPS_PS:
16718                        mips32_op = OPC_RSQRT2_PS;
16719                        goto do_3d;
16720                    default:
16721                        goto pool32f_invalid;
16722                    }
16723                    break;
16724                case RECIP2_FMT:
16725                    switch (fmt) {
16726                    case FMT_SDPS_S:
16727                        mips32_op = OPC_RECIP2_S;
16728                        goto do_3d;
16729                    case FMT_SDPS_D:
16730                        mips32_op = OPC_RECIP2_D;
16731                        goto do_3d;
16732                    case FMT_SDPS_PS:
16733                        mips32_op = OPC_RECIP2_PS;
16734                        goto do_3d;
16735                    default:
16736                        goto pool32f_invalid;
16737                    }
16738                    break;
16739                case ADDR_PS:
16740                    mips32_op = OPC_ADDR_PS;
16741                    goto do_3d;
16742                case MULR_PS:
16743                    mips32_op = OPC_MULR_PS;
16744                do_3d:
16745                    gen_farith(ctx, mips32_op, rt, rs, rd, 0);
16746                    break;
16747                default:
16748                    goto pool32f_invalid;
16749                }
16750                break;
16751            case 0x20:
16752                /* MOV[FT].fmt, PREFX, RINT.fmt, CLASS.fmt*/
16753                cc = (ctx->opcode >> 13) & 0x7;
16754                fmt = (ctx->opcode >> 9) & 0x3;
16755                switch ((ctx->opcode >> 6) & 0x7) {
16756                case MOVF_FMT: /* RINT_FMT */
16757                    if (ctx->insn_flags & ISA_MIPS32R6) {
16758                        /* RINT_FMT */
16759                        switch (fmt) {
16760                        case FMT_SDPS_S:
16761                            gen_farith(ctx, OPC_RINT_S, 0, rt, rs, 0);
16762                            break;
16763                        case FMT_SDPS_D:
16764                            gen_farith(ctx, OPC_RINT_D, 0, rt, rs, 0);
16765                            break;
16766                        default:
16767                            goto pool32f_invalid;
16768                        }
16769                    } else {
16770                        /* MOVF_FMT */
16771                        switch (fmt) {
16772                        case FMT_SDPS_S:
16773                            gen_movcf_s(ctx, rs, rt, cc, 0);
16774                            break;
16775                        case FMT_SDPS_D:
16776                            gen_movcf_d(ctx, rs, rt, cc, 0);
16777                            break;
16778                        case FMT_SDPS_PS:
16779                            check_ps(ctx);
16780                            gen_movcf_ps(ctx, rs, rt, cc, 0);
16781                            break;
16782                        default:
16783                            goto pool32f_invalid;
16784                        }
16785                    }
16786                    break;
16787                case MOVT_FMT: /* CLASS_FMT */
16788                    if (ctx->insn_flags & ISA_MIPS32R6) {
16789                        /* CLASS_FMT */
16790                        switch (fmt) {
16791                        case FMT_SDPS_S:
16792                            gen_farith(ctx, OPC_CLASS_S, 0, rt, rs, 0);
16793                            break;
16794                        case FMT_SDPS_D:
16795                            gen_farith(ctx, OPC_CLASS_D, 0, rt, rs, 0);
16796                            break;
16797                        default:
16798                            goto pool32f_invalid;
16799                        }
16800                    } else {
16801                        /* MOVT_FMT */
16802                        switch (fmt) {
16803                        case FMT_SDPS_S:
16804                            gen_movcf_s(ctx, rs, rt, cc, 1);
16805                            break;
16806                        case FMT_SDPS_D:
16807                            gen_movcf_d(ctx, rs, rt, cc, 1);
16808                            break;
16809                        case FMT_SDPS_PS:
16810                            check_ps(ctx);
16811                            gen_movcf_ps(ctx, rs, rt, cc, 1);
16812                            break;
16813                        default:
16814                            goto pool32f_invalid;
16815                        }
16816                    }
16817                    break;
16818                case PREFX:
16819                    check_insn_opc_removed(ctx, ISA_MIPS32R6);
16820                    break;
16821                default:
16822                    goto pool32f_invalid;
16823                }
16824                break;
16825#define FINSN_3ARG_SDPS(prfx)                           \
16826                switch ((ctx->opcode >> 8) & 0x3) {     \
16827                case FMT_SDPS_S:                        \
16828                    mips32_op = OPC_##prfx##_S;         \
16829                    goto do_fpop;                       \
16830                case FMT_SDPS_D:                        \
16831                    mips32_op = OPC_##prfx##_D;         \
16832                    goto do_fpop;                       \
16833                case FMT_SDPS_PS:                       \
16834                    check_ps(ctx);                      \
16835                    mips32_op = OPC_##prfx##_PS;        \
16836                    goto do_fpop;                       \
16837                default:                                \
16838                    goto pool32f_invalid;               \
16839                }
16840            case MINA_FMT:
16841                check_insn(ctx, ISA_MIPS32R6);
16842                switch ((ctx->opcode >> 9) & 0x3) {
16843                case FMT_SDPS_S:
16844                    gen_farith(ctx, OPC_MINA_S, rt, rs, rd, 0);
16845                    break;
16846                case FMT_SDPS_D:
16847                    gen_farith(ctx, OPC_MINA_D, rt, rs, rd, 0);
16848                    break;
16849                default:
16850                    goto pool32f_invalid;
16851                }
16852                break;
16853            case MAXA_FMT:
16854                check_insn(ctx, ISA_MIPS32R6);
16855                switch ((ctx->opcode >> 9) & 0x3) {
16856                case FMT_SDPS_S:
16857                    gen_farith(ctx, OPC_MAXA_S, rt, rs, rd, 0);
16858                    break;
16859                case FMT_SDPS_D:
16860                    gen_farith(ctx, OPC_MAXA_D, rt, rs, rd, 0);
16861                    break;
16862                default:
16863                    goto pool32f_invalid;
16864                }
16865                break;
16866            case 0x30:
16867                /* regular FP ops */
16868                switch ((ctx->opcode >> 6) & 0x3) {
16869                case ADD_FMT:
16870                    FINSN_3ARG_SDPS(ADD);
16871                    break;
16872                case SUB_FMT:
16873                    FINSN_3ARG_SDPS(SUB);
16874                    break;
16875                case MUL_FMT:
16876                    FINSN_3ARG_SDPS(MUL);
16877                    break;
16878                case DIV_FMT:
16879                    fmt = (ctx->opcode >> 8) & 0x3;
16880                    if (fmt == 1) {
16881                        mips32_op = OPC_DIV_D;
16882                    } else if (fmt == 0) {
16883                        mips32_op = OPC_DIV_S;
16884                    } else {
16885                        goto pool32f_invalid;
16886                    }
16887                    goto do_fpop;
16888                default:
16889                    goto pool32f_invalid;
16890                }
16891                break;
16892            case 0x38:
16893                /* cmovs */
16894                switch ((ctx->opcode >> 6) & 0x7) {
16895                case MOVN_FMT: /* SELEQZ_FMT */
16896                    if (ctx->insn_flags & ISA_MIPS32R6) {
16897                        /* SELEQZ_FMT */
16898                        switch ((ctx->opcode >> 9) & 0x3) {
16899                        case FMT_SDPS_S:
16900                            gen_sel_s(ctx, OPC_SELEQZ_S, rd, rt, rs);
16901                            break;
16902                        case FMT_SDPS_D:
16903                            gen_sel_d(ctx, OPC_SELEQZ_D, rd, rt, rs);
16904                            break;
16905                        default:
16906                            goto pool32f_invalid;
16907                        }
16908                    } else {
16909                        /* MOVN_FMT */
16910                        FINSN_3ARG_SDPS(MOVN);
16911                    }
16912                    break;
16913                case MOVN_FMT_04:
16914                    check_insn_opc_removed(ctx, ISA_MIPS32R6);
16915                    FINSN_3ARG_SDPS(MOVN);
16916                    break;
16917                case MOVZ_FMT: /* SELNEZ_FMT */
16918                    if (ctx->insn_flags & ISA_MIPS32R6) {
16919                        /* SELNEZ_FMT */
16920                        switch ((ctx->opcode >> 9) & 0x3) {
16921                        case FMT_SDPS_S:
16922                            gen_sel_s(ctx, OPC_SELNEZ_S, rd, rt, rs);
16923                            break;
16924                        case FMT_SDPS_D:
16925                            gen_sel_d(ctx, OPC_SELNEZ_D, rd, rt, rs);
16926                            break;
16927                        default:
16928                            goto pool32f_invalid;
16929                        }
16930                    } else {
16931                        /* MOVZ_FMT */
16932                        FINSN_3ARG_SDPS(MOVZ);
16933                    }
16934                    break;
16935                case MOVZ_FMT_05:
16936                    check_insn_opc_removed(ctx, ISA_MIPS32R6);
16937                    FINSN_3ARG_SDPS(MOVZ);
16938                    break;
16939                case SEL_FMT:
16940                    check_insn(ctx, ISA_MIPS32R6);
16941                    switch ((ctx->opcode >> 9) & 0x3) {
16942                    case FMT_SDPS_S:
16943                        gen_sel_s(ctx, OPC_SEL_S, rd, rt, rs);
16944                        break;
16945                    case FMT_SDPS_D:
16946                        gen_sel_d(ctx, OPC_SEL_D, rd, rt, rs);
16947                        break;
16948                    default:
16949                        goto pool32f_invalid;
16950                    }
16951                    break;
16952                case MADDF_FMT:
16953                    check_insn(ctx, ISA_MIPS32R6);
16954                    switch ((ctx->opcode >> 9) & 0x3) {
16955                    case FMT_SDPS_S:
16956                        mips32_op = OPC_MADDF_S;
16957                        goto do_fpop;
16958                    case FMT_SDPS_D:
16959                        mips32_op = OPC_MADDF_D;
16960                        goto do_fpop;
16961                    default:
16962                        goto pool32f_invalid;
16963                    }
16964                    break;
16965                case MSUBF_FMT:
16966                    check_insn(ctx, ISA_MIPS32R6);
16967                    switch ((ctx->opcode >> 9) & 0x3) {
16968                    case FMT_SDPS_S:
16969                        mips32_op = OPC_MSUBF_S;
16970                        goto do_fpop;
16971                    case FMT_SDPS_D:
16972                        mips32_op = OPC_MSUBF_D;
16973                        goto do_fpop;
16974                    default:
16975                        goto pool32f_invalid;
16976                    }
16977                    break;
16978                default:
16979                    goto pool32f_invalid;
16980                }
16981                break;
16982            do_fpop:
16983                gen_farith(ctx, mips32_op, rt, rs, rd, 0);
16984                break;
16985            default:
16986            pool32f_invalid:
16987                MIPS_INVAL("pool32f");
16988                generate_exception_end(ctx, EXCP_RI);
16989                break;
16990            }
16991        } else {
16992            generate_exception_err(ctx, EXCP_CpU, 1);
16993        }
16994        break;
16995    case POOL32I:
16996        minor = (ctx->opcode >> 21) & 0x1f;
16997        switch (minor) {
16998        case BLTZ:
16999            check_insn_opc_removed(ctx, ISA_MIPS32R6);
17000            gen_compute_branch(ctx, OPC_BLTZ, 4, rs, -1, imm << 1, 4);
17001            break;
17002        case BLTZAL:
17003            check_insn_opc_removed(ctx, ISA_MIPS32R6);
17004            gen_compute_branch(ctx, OPC_BLTZAL, 4, rs, -1, imm << 1, 4);
17005            ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
17006            break;
17007        case BLTZALS:
17008            check_insn_opc_removed(ctx, ISA_MIPS32R6);
17009            gen_compute_branch(ctx, OPC_BLTZAL, 4, rs, -1, imm << 1, 2);
17010            ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
17011            break;
17012        case BGEZ:
17013            check_insn_opc_removed(ctx, ISA_MIPS32R6);
17014            gen_compute_branch(ctx, OPC_BGEZ, 4, rs, -1, imm << 1, 4);
17015            break;
17016        case BGEZAL:
17017            check_insn_opc_removed(ctx, ISA_MIPS32R6);
17018            gen_compute_branch(ctx, OPC_BGEZAL, 4, rs, -1, imm << 1, 4);
17019            ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
17020            break;
17021        case BGEZALS:
17022            check_insn_opc_removed(ctx, ISA_MIPS32R6);
17023            gen_compute_branch(ctx, OPC_BGEZAL, 4, rs, -1, imm << 1, 2);
17024            ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
17025            break;
17026        case BLEZ:
17027            check_insn_opc_removed(ctx, ISA_MIPS32R6);
17028            gen_compute_branch(ctx, OPC_BLEZ, 4, rs, -1, imm << 1, 4);
17029            break;
17030        case BGTZ:
17031            check_insn_opc_removed(ctx, ISA_MIPS32R6);
17032            gen_compute_branch(ctx, OPC_BGTZ, 4, rs, -1, imm << 1, 4);
17033            break;
17034
17035            /* Traps */
17036        case TLTI: /* BC1EQZC */
17037            if (ctx->insn_flags & ISA_MIPS32R6) {
17038                /* BC1EQZC */
17039                check_cp1_enabled(ctx);
17040                gen_compute_branch1_r6(ctx, OPC_BC1EQZ, rs, imm << 1, 0);
17041            } else {
17042                /* TLTI */
17043                mips32_op = OPC_TLTI;
17044                goto do_trapi;
17045            }
17046            break;
17047        case TGEI: /* BC1NEZC */
17048            if (ctx->insn_flags & ISA_MIPS32R6) {
17049                /* BC1NEZC */
17050                check_cp1_enabled(ctx);
17051                gen_compute_branch1_r6(ctx, OPC_BC1NEZ, rs, imm << 1, 0);
17052            } else {
17053                /* TGEI */
17054                mips32_op = OPC_TGEI;
17055                goto do_trapi;
17056            }
17057            break;
17058        case TLTIU:
17059            check_insn_opc_removed(ctx, ISA_MIPS32R6);
17060            mips32_op = OPC_TLTIU;
17061            goto do_trapi;
17062        case TGEIU:
17063            check_insn_opc_removed(ctx, ISA_MIPS32R6);
17064            mips32_op = OPC_TGEIU;
17065            goto do_trapi;
17066        case TNEI: /* SYNCI */
17067            if (ctx->insn_flags & ISA_MIPS32R6) {
17068                /* SYNCI */
17069                /*
17070                 * Break the TB to be able to sync copied instructions
17071                 * immediately.
17072                 */
17073                ctx->base.is_jmp = DISAS_STOP;
17074            } else {
17075                /* TNEI */
17076                mips32_op = OPC_TNEI;
17077                goto do_trapi;
17078            }
17079            break;
17080        case TEQI:
17081            check_insn_opc_removed(ctx, ISA_MIPS32R6);
17082            mips32_op = OPC_TEQI;
17083        do_trapi:
17084            gen_trap(ctx, mips32_op, rs, -1, imm);
17085            break;
17086
17087        case BNEZC:
17088        case BEQZC:
17089            check_insn_opc_removed(ctx, ISA_MIPS32R6);
17090            gen_compute_branch(ctx, minor == BNEZC ? OPC_BNE : OPC_BEQ,
17091                               4, rs, 0, imm << 1, 0);
17092            /*
17093             * Compact branches don't have a delay slot, so just let
17094             * the normal delay slot handling take us to the branch
17095             * target.
17096             */
17097            break;
17098        case LUI:
17099            check_insn_opc_removed(ctx, ISA_MIPS32R6);
17100            gen_logic_imm(ctx, OPC_LUI, rs, 0, imm);
17101            break;
17102        case SYNCI:
17103            check_insn_opc_removed(ctx, ISA_MIPS32R6);
17104            /*
17105             * Break the TB to be able to sync copied instructions
17106             * immediately.
17107             */
17108            ctx->base.is_jmp = DISAS_STOP;
17109            break;
17110        case BC2F:
17111        case BC2T:
17112            check_insn_opc_removed(ctx, ISA_MIPS32R6);
17113            /* COP2: Not implemented. */
17114            generate_exception_err(ctx, EXCP_CpU, 2);
17115            break;
17116        case BC1F:
17117            check_insn_opc_removed(ctx, ISA_MIPS32R6);
17118            mips32_op = (ctx->opcode & (1 << 16)) ? OPC_BC1FANY2 : OPC_BC1F;
17119            goto do_cp1branch;
17120        case BC1T:
17121            check_insn_opc_removed(ctx, ISA_MIPS32R6);
17122            mips32_op = (ctx->opcode & (1 << 16)) ? OPC_BC1TANY2 : OPC_BC1T;
17123            goto do_cp1branch;
17124        case BC1ANY4F:
17125            check_insn_opc_removed(ctx, ISA_MIPS32R6);
17126            mips32_op = OPC_BC1FANY4;
17127            goto do_cp1mips3d;
17128        case BC1ANY4T:
17129            check_insn_opc_removed(ctx, ISA_MIPS32R6);
17130            mips32_op = OPC_BC1TANY4;
17131        do_cp1mips3d:
17132            check_cop1x(ctx);
17133            check_insn(ctx, ASE_MIPS3D);
17134            /* Fall through */
17135        do_cp1branch:
17136            if (env->CP0_Config1 & (1 << CP0C1_FP)) {
17137                check_cp1_enabled(ctx);
17138                gen_compute_branch1(ctx, mips32_op,
17139                                    (ctx->opcode >> 18) & 0x7, imm << 1);
17140            } else {
17141                generate_exception_err(ctx, EXCP_CpU, 1);
17142            }
17143            break;
17144        case BPOSGE64:
17145        case BPOSGE32:
17146            /* MIPS DSP: not implemented */
17147            /* Fall through */
17148        default:
17149            MIPS_INVAL("pool32i");
17150            generate_exception_end(ctx, EXCP_RI);
17151            break;
17152        }
17153        break;
17154    case POOL32C:
17155        minor = (ctx->opcode >> 12) & 0xf;
17156        offset = sextract32(ctx->opcode, 0,
17157                            (ctx->insn_flags & ISA_MIPS32R6) ? 9 : 12);
17158        switch (minor) {
17159        case LWL:
17160            check_insn_opc_removed(ctx, ISA_MIPS32R6);
17161            mips32_op = OPC_LWL;
17162            goto do_ld_lr;
17163        case SWL:
17164            check_insn_opc_removed(ctx, ISA_MIPS32R6);
17165            mips32_op = OPC_SWL;
17166            goto do_st_lr;
17167        case LWR:
17168            check_insn_opc_removed(ctx, ISA_MIPS32R6);
17169            mips32_op = OPC_LWR;
17170            goto do_ld_lr;
17171        case SWR:
17172            check_insn_opc_removed(ctx, ISA_MIPS32R6);
17173            mips32_op = OPC_SWR;
17174            goto do_st_lr;
17175#if defined(TARGET_MIPS64)
17176        case LDL:
17177            check_insn(ctx, ISA_MIPS3);
17178            check_mips_64(ctx);
17179            check_insn_opc_removed(ctx, ISA_MIPS32R6);
17180            mips32_op = OPC_LDL;
17181            goto do_ld_lr;
17182        case SDL:
17183            check_insn(ctx, ISA_MIPS3);
17184            check_mips_64(ctx);
17185            check_insn_opc_removed(ctx, ISA_MIPS32R6);
17186            mips32_op = OPC_SDL;
17187            goto do_st_lr;
17188        case LDR:
17189            check_insn(ctx, ISA_MIPS3);
17190            check_mips_64(ctx);
17191            check_insn_opc_removed(ctx, ISA_MIPS32R6);
17192            mips32_op = OPC_LDR;
17193            goto do_ld_lr;
17194        case SDR:
17195            check_insn(ctx, ISA_MIPS3);
17196            check_mips_64(ctx);
17197            check_insn_opc_removed(ctx, ISA_MIPS32R6);
17198            mips32_op = OPC_SDR;
17199            goto do_st_lr;
17200        case LWU:
17201            check_insn(ctx, ISA_MIPS3);
17202            check_mips_64(ctx);
17203            mips32_op = OPC_LWU;
17204            goto do_ld_lr;
17205        case LLD:
17206            check_insn(ctx, ISA_MIPS3);
17207            check_mips_64(ctx);
17208            mips32_op = OPC_LLD;
17209            goto do_ld_lr;
17210#endif
17211        case LL:
17212            mips32_op = OPC_LL;
17213            goto do_ld_lr;
17214        do_ld_lr:
17215            gen_ld(ctx, mips32_op, rt, rs, offset);
17216            break;
17217        do_st_lr:
17218            gen_st(ctx, mips32_op, rt, rs, offset);
17219            break;
17220        case SC:
17221            gen_st_cond(ctx, rt, rs, offset, MO_TESL, false);
17222            break;
17223#if defined(TARGET_MIPS64)
17224        case SCD:
17225            check_insn(ctx, ISA_MIPS3);
17226            check_mips_64(ctx);
17227            gen_st_cond(ctx, rt, rs, offset, MO_TEQ, false);
17228            break;
17229#endif
17230        case LD_EVA:
17231            if (!ctx->eva) {
17232                MIPS_INVAL("pool32c ld-eva");
17233                generate_exception_end(ctx, EXCP_RI);
17234                break;
17235            }
17236            check_cp0_enabled(ctx);
17237
17238            minor2 = (ctx->opcode >> 9) & 0x7;
17239            offset = sextract32(ctx->opcode, 0, 9);
17240            switch (minor2) {
17241            case LBUE:
17242                mips32_op = OPC_LBUE;
17243                goto do_ld_lr;
17244            case LHUE:
17245                mips32_op = OPC_LHUE;
17246                goto do_ld_lr;
17247            case LWLE:
17248                check_insn_opc_removed(ctx, ISA_MIPS32R6);
17249                mips32_op = OPC_LWLE;
17250                goto do_ld_lr;
17251            case LWRE:
17252                check_insn_opc_removed(ctx, ISA_MIPS32R6);
17253                mips32_op = OPC_LWRE;
17254                goto do_ld_lr;
17255            case LBE:
17256                mips32_op = OPC_LBE;
17257                goto do_ld_lr;
17258            case LHE:
17259                mips32_op = OPC_LHE;
17260                goto do_ld_lr;
17261            case LLE:
17262                mips32_op = OPC_LLE;
17263                goto do_ld_lr;
17264            case LWE:
17265                mips32_op = OPC_LWE;
17266                goto do_ld_lr;
17267            };
17268            break;
17269        case ST_EVA:
17270            if (!ctx->eva) {
17271                MIPS_INVAL("pool32c st-eva");
17272                generate_exception_end(ctx, EXCP_RI);
17273                break;
17274            }
17275            check_cp0_enabled(ctx);
17276
17277            minor2 = (ctx->opcode >> 9) & 0x7;
17278            offset = sextract32(ctx->opcode, 0, 9);
17279            switch (minor2) {
17280            case SWLE:
17281                check_insn_opc_removed(ctx, ISA_MIPS32R6);
17282                mips32_op = OPC_SWLE;
17283                goto do_st_lr;
17284            case SWRE:
17285                check_insn_opc_removed(ctx, ISA_MIPS32R6);
17286                mips32_op = OPC_SWRE;
17287                goto do_st_lr;
17288            case PREFE:
17289                /* Treat as no-op */
17290                if ((ctx->insn_flags & ISA_MIPS32R6) && (rt >= 24)) {
17291                    /* hint codes 24-31 are reserved and signal RI */
17292                    generate_exception(ctx, EXCP_RI);
17293                }
17294                break;
17295            case CACHEE:
17296                /* Treat as no-op */
17297                if (ctx->hflags & MIPS_HFLAG_ITC_CACHE) {
17298                    gen_cache_operation(ctx, rt, rs, offset);
17299                }
17300                break;
17301            case SBE:
17302                mips32_op = OPC_SBE;
17303                goto do_st_lr;
17304            case SHE:
17305                mips32_op = OPC_SHE;
17306                goto do_st_lr;
17307            case SCE:
17308                gen_st_cond(ctx, rt, rs, offset, MO_TESL, true);
17309                break;
17310            case SWE:
17311                mips32_op = OPC_SWE;
17312                goto do_st_lr;
17313            };
17314            break;
17315        case PREF:
17316            /* Treat as no-op */
17317            if ((ctx->insn_flags & ISA_MIPS32R6) && (rt >= 24)) {
17318                /* hint codes 24-31 are reserved and signal RI */
17319                generate_exception(ctx, EXCP_RI);
17320            }
17321            break;
17322        default:
17323            MIPS_INVAL("pool32c");
17324            generate_exception_end(ctx, EXCP_RI);
17325            break;
17326        }
17327        break;
17328    case ADDI32: /* AUI, LUI */
17329        if (ctx->insn_flags & ISA_MIPS32R6) {
17330            /* AUI, LUI */
17331            gen_logic_imm(ctx, OPC_LUI, rt, rs, imm);
17332        } else {
17333            /* ADDI32 */
17334            mips32_op = OPC_ADDI;
17335            goto do_addi;
17336        }
17337        break;
17338    case ADDIU32:
17339        mips32_op = OPC_ADDIU;
17340    do_addi:
17341        gen_arith_imm(ctx, mips32_op, rt, rs, imm);
17342        break;
17343
17344        /* Logical operations */
17345    case ORI32:
17346        mips32_op = OPC_ORI;
17347        goto do_logici;
17348    case XORI32:
17349        mips32_op = OPC_XORI;
17350        goto do_logici;
17351    case ANDI32:
17352        mips32_op = OPC_ANDI;
17353    do_logici:
17354        gen_logic_imm(ctx, mips32_op, rt, rs, imm);
17355        break;
17356
17357        /* Set less than immediate */
17358    case SLTI32:
17359        mips32_op = OPC_SLTI;
17360        goto do_slti;
17361    case SLTIU32:
17362        mips32_op = OPC_SLTIU;
17363    do_slti:
17364        gen_slt_imm(ctx, mips32_op, rt, rs, imm);
17365        break;
17366    case JALX32:
17367        check_insn_opc_removed(ctx, ISA_MIPS32R6);
17368        offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 2;
17369        gen_compute_branch(ctx, OPC_JALX, 4, rt, rs, offset, 4);
17370        ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
17371        break;
17372    case JALS32: /* BOVC, BEQC, BEQZALC */
17373        if (ctx->insn_flags & ISA_MIPS32R6) {
17374            if (rs >= rt) {
17375                /* BOVC */
17376                mips32_op = OPC_BOVC;
17377            } else if (rs < rt && rs == 0) {
17378                /* BEQZALC */
17379                mips32_op = OPC_BEQZALC;
17380            } else {
17381                /* BEQC */
17382                mips32_op = OPC_BEQC;
17383            }
17384            gen_compute_compact_branch(ctx, mips32_op, rs, rt, imm << 1);
17385        } else {
17386            /* JALS32 */
17387            offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 1;
17388            gen_compute_branch(ctx, OPC_JAL, 4, rt, rs, offset, 2);
17389            ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
17390        }
17391        break;
17392    case BEQ32: /* BC */
17393        if (ctx->insn_flags & ISA_MIPS32R6) {
17394            /* BC */
17395            gen_compute_compact_branch(ctx, OPC_BC, 0, 0,
17396                                       sextract32(ctx->opcode << 1, 0, 27));
17397        } else {
17398            /* BEQ32 */
17399            gen_compute_branch(ctx, OPC_BEQ, 4, rt, rs, imm << 1, 4);
17400        }
17401        break;
17402    case BNE32: /* BALC */
17403        if (ctx->insn_flags & ISA_MIPS32R6) {
17404            /* BALC */
17405            gen_compute_compact_branch(ctx, OPC_BALC, 0, 0,
17406                                       sextract32(ctx->opcode << 1, 0, 27));
17407        } else {
17408            /* BNE32 */
17409            gen_compute_branch(ctx, OPC_BNE, 4, rt, rs, imm << 1, 4);
17410        }
17411        break;
17412    case J32: /* BGTZC, BLTZC, BLTC */
17413        if (ctx->insn_flags & ISA_MIPS32R6) {
17414            if (rs == 0 && rt != 0) {
17415                /* BGTZC */
17416                mips32_op = OPC_BGTZC;
17417            } else if (rs != 0 && rt != 0 && rs == rt) {
17418                /* BLTZC */
17419                mips32_op = OPC_BLTZC;
17420            } else {
17421                /* BLTC */
17422                mips32_op = OPC_BLTC;
17423            }
17424            gen_compute_compact_branch(ctx, mips32_op, rs, rt, imm << 1);
17425        } else {
17426            /* J32 */
17427            gen_compute_branch(ctx, OPC_J, 4, rt, rs,
17428                               (int32_t)(ctx->opcode & 0x3FFFFFF) << 1, 4);
17429        }
17430        break;
17431    case JAL32: /* BLEZC, BGEZC, BGEC */
17432        if (ctx->insn_flags & ISA_MIPS32R6) {
17433            if (rs == 0 && rt != 0) {
17434                /* BLEZC */
17435                mips32_op = OPC_BLEZC;
17436            } else if (rs != 0 && rt != 0 && rs == rt) {
17437                /* BGEZC */
17438                mips32_op = OPC_BGEZC;
17439            } else {
17440                /* BGEC */
17441                mips32_op = OPC_BGEC;
17442            }
17443            gen_compute_compact_branch(ctx, mips32_op, rs, rt, imm << 1);
17444        } else {
17445            /* JAL32 */
17446            gen_compute_branch(ctx, OPC_JAL, 4, rt, rs,
17447                               (int32_t)(ctx->opcode & 0x3FFFFFF) << 1, 4);
17448            ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
17449        }
17450        break;
17451        /* Floating point (COP1) */
17452    case LWC132:
17453        mips32_op = OPC_LWC1;
17454        goto do_cop1;
17455    case LDC132:
17456        mips32_op = OPC_LDC1;
17457        goto do_cop1;
17458    case SWC132:
17459        mips32_op = OPC_SWC1;
17460        goto do_cop1;
17461    case SDC132:
17462        mips32_op = OPC_SDC1;
17463    do_cop1:
17464        gen_cop1_ldst(ctx, mips32_op, rt, rs, imm);
17465        break;
17466    case ADDIUPC: /* PCREL: ADDIUPC, AUIPC, ALUIPC, LWPC */
17467        if (ctx->insn_flags & ISA_MIPS32R6) {
17468            /* PCREL: ADDIUPC, AUIPC, ALUIPC, LWPC */
17469            switch ((ctx->opcode >> 16) & 0x1f) {
17470            case ADDIUPC_00:
17471            case ADDIUPC_01:
17472            case ADDIUPC_02:
17473            case ADDIUPC_03:
17474            case ADDIUPC_04:
17475            case ADDIUPC_05:
17476            case ADDIUPC_06:
17477            case ADDIUPC_07:
17478                gen_pcrel(ctx, OPC_ADDIUPC, ctx->base.pc_next & ~0x3, rt);
17479                break;
17480            case AUIPC:
17481                gen_pcrel(ctx, OPC_AUIPC, ctx->base.pc_next, rt);
17482                break;
17483            case ALUIPC:
17484                gen_pcrel(ctx, OPC_ALUIPC, ctx->base.pc_next, rt);
17485                break;
17486            case LWPC_08:
17487            case LWPC_09:
17488            case LWPC_0A:
17489            case LWPC_0B:
17490            case LWPC_0C:
17491            case LWPC_0D:
17492            case LWPC_0E:
17493            case LWPC_0F:
17494                gen_pcrel(ctx, R6_OPC_LWPC, ctx->base.pc_next & ~0x3, rt);
17495                break;
17496            default:
17497                generate_exception(ctx, EXCP_RI);
17498                break;
17499            }
17500        } else {
17501            /* ADDIUPC */
17502            int reg = mmreg(ZIMM(ctx->opcode, 23, 3));
17503            offset = SIMM(ctx->opcode, 0, 23) << 2;
17504
17505            gen_addiupc(ctx, reg, offset, 0, 0);
17506        }
17507        break;
17508    case BNVC: /* BNEC, BNEZALC */
17509        check_insn(ctx, ISA_MIPS32R6);
17510        if (rs >= rt) {
17511            /* BNVC */
17512            mips32_op = OPC_BNVC;
17513        } else if (rs < rt && rs == 0) {
17514            /* BNEZALC */
17515            mips32_op = OPC_BNEZALC;
17516        } else {
17517            /* BNEC */
17518            mips32_op = OPC_BNEC;
17519        }
17520        gen_compute_compact_branch(ctx, mips32_op, rs, rt, imm << 1);
17521        break;
17522    case R6_BNEZC: /* JIALC */
17523        check_insn(ctx, ISA_MIPS32R6);
17524        if (rt != 0) {
17525            /* BNEZC */
17526            gen_compute_compact_branch(ctx, OPC_BNEZC, rt, 0,
17527                                       sextract32(ctx->opcode << 1, 0, 22));
17528        } else {
17529            /* JIALC */
17530            gen_compute_compact_branch(ctx, OPC_JIALC, 0, rs, imm);
17531        }
17532        break;
17533    case R6_BEQZC: /* JIC */
17534        check_insn(ctx, ISA_MIPS32R6);
17535        if (rt != 0) {
17536            /* BEQZC */
17537            gen_compute_compact_branch(ctx, OPC_BEQZC, rt, 0,
17538                                       sextract32(ctx->opcode << 1, 0, 22));
17539        } else {
17540            /* JIC */
17541            gen_compute_compact_branch(ctx, OPC_JIC, 0, rs, imm);
17542        }
17543        break;
17544    case BLEZALC: /* BGEZALC, BGEUC */
17545        check_insn(ctx, ISA_MIPS32R6);
17546        if (rs == 0 && rt != 0) {
17547            /* BLEZALC */
17548            mips32_op = OPC_BLEZALC;
17549        } else if (rs != 0 && rt != 0 && rs == rt) {
17550            /* BGEZALC */
17551            mips32_op = OPC_BGEZALC;
17552        } else {
17553            /* BGEUC */
17554            mips32_op = OPC_BGEUC;
17555        }
17556        gen_compute_compact_branch(ctx, mips32_op, rs, rt, imm << 1);
17557        break;
17558    case BGTZALC: /* BLTZALC, BLTUC */
17559        check_insn(ctx, ISA_MIPS32R6);
17560        if (rs == 0 && rt != 0) {
17561            /* BGTZALC */
17562            mips32_op = OPC_BGTZALC;
17563        } else if (rs != 0 && rt != 0 && rs == rt) {
17564            /* BLTZALC */
17565            mips32_op = OPC_BLTZALC;
17566        } else {
17567            /* BLTUC */
17568            mips32_op = OPC_BLTUC;
17569        }
17570        gen_compute_compact_branch(ctx, mips32_op, rs, rt, imm << 1);
17571        break;
17572        /* Loads and stores */
17573    case LB32:
17574        mips32_op = OPC_LB;
17575        goto do_ld;
17576    case LBU32:
17577        mips32_op = OPC_LBU;
17578        goto do_ld;
17579    case LH32:
17580        mips32_op = OPC_LH;
17581        goto do_ld;
17582    case LHU32:
17583        mips32_op = OPC_LHU;
17584        goto do_ld;
17585    case LW32:
17586        mips32_op = OPC_LW;
17587        goto do_ld;
17588#ifdef TARGET_MIPS64
17589    case LD32:
17590        check_insn(ctx, ISA_MIPS3);
17591        check_mips_64(ctx);
17592        mips32_op = OPC_LD;
17593        goto do_ld;
17594    case SD32:
17595        check_insn(ctx, ISA_MIPS3);
17596        check_mips_64(ctx);
17597        mips32_op = OPC_SD;
17598        goto do_st;
17599#endif
17600    case SB32:
17601        mips32_op = OPC_SB;
17602        goto do_st;
17603    case SH32:
17604        mips32_op = OPC_SH;
17605        goto do_st;
17606    case SW32:
17607        mips32_op = OPC_SW;
17608        goto do_st;
17609    do_ld:
17610        gen_ld(ctx, mips32_op, rt, rs, imm);
17611        break;
17612    do_st:
17613        gen_st(ctx, mips32_op, rt, rs, imm);
17614        break;
17615    default:
17616        generate_exception_end(ctx, EXCP_RI);
17617        break;
17618    }
17619}
17620
17621static int decode_micromips_opc(CPUMIPSState *env, DisasContext *ctx)
17622{
17623    uint32_t op;
17624
17625    /* make sure instructions are on a halfword boundary */
17626    if (ctx->base.pc_next & 0x1) {
17627        env->CP0_BadVAddr = ctx->base.pc_next;
17628        generate_exception_end(ctx, EXCP_AdEL);
17629        return 2;
17630    }
17631
17632    op = (ctx->opcode >> 10) & 0x3f;
17633    /* Enforce properly-sized instructions in a delay slot */
17634    if (ctx->hflags & MIPS_HFLAG_BDS_STRICT) {
17635        switch (op & 0x7) { /* MSB-3..MSB-5 */
17636        case 0:
17637        /* POOL32A, POOL32B, POOL32I, POOL32C */
17638        case 4:
17639        /* ADDI32, ADDIU32, ORI32, XORI32, SLTI32, SLTIU32, ANDI32, JALX32 */
17640        case 5:
17641        /* LBU32, LHU32, POOL32F, JALS32, BEQ32, BNE32, J32, JAL32 */
17642        case 6:
17643        /* SB32, SH32, ADDIUPC, SWC132, SDC132, SW32 */
17644        case 7:
17645        /* LB32, LH32, LWC132, LDC132, LW32 */
17646            if (ctx->hflags & MIPS_HFLAG_BDS16) {
17647                generate_exception_end(ctx, EXCP_RI);
17648                return 2;
17649            }
17650            break;
17651        case 1:
17652        /* POOL16A, POOL16B, POOL16C, LWGP16, POOL16F */
17653        case 2:
17654        /* LBU16, LHU16, LWSP16, LW16, SB16, SH16, SWSP16, SW16 */
17655        case 3:
17656        /* MOVE16, ANDI16, POOL16D, POOL16E, BEQZ16, BNEZ16, B16, LI16 */
17657            if (ctx->hflags & MIPS_HFLAG_BDS32) {
17658                generate_exception_end(ctx, EXCP_RI);
17659                return 2;
17660            }
17661            break;
17662        }
17663    }
17664
17665    switch (op) {
17666    case POOL16A:
17667        {
17668            int rd = mmreg(uMIPS_RD(ctx->opcode));
17669            int rs1 = mmreg(uMIPS_RS1(ctx->opcode));
17670            int rs2 = mmreg(uMIPS_RS2(ctx->opcode));
17671            uint32_t opc = 0;
17672
17673            switch (ctx->opcode & 0x1) {
17674            case ADDU16:
17675                opc = OPC_ADDU;
17676                break;
17677            case SUBU16:
17678                opc = OPC_SUBU;
17679                break;
17680            }
17681            if (ctx->insn_flags & ISA_MIPS32R6) {
17682                /*
17683                 * In the Release 6, the register number location in
17684                 * the instruction encoding has changed.
17685                 */
17686                gen_arith(ctx, opc, rs1, rd, rs2);
17687            } else {
17688                gen_arith(ctx, opc, rd, rs1, rs2);
17689            }
17690        }
17691        break;
17692    case POOL16B:
17693        {
17694            int rd = mmreg(uMIPS_RD(ctx->opcode));
17695            int rs = mmreg(uMIPS_RS(ctx->opcode));
17696            int amount = (ctx->opcode >> 1) & 0x7;
17697            uint32_t opc = 0;
17698            amount = amount == 0 ? 8 : amount;
17699
17700            switch (ctx->opcode & 0x1) {
17701            case SLL16:
17702                opc = OPC_SLL;
17703                break;
17704            case SRL16:
17705                opc = OPC_SRL;
17706                break;
17707            }
17708
17709            gen_shift_imm(ctx, opc, rd, rs, amount);
17710        }
17711        break;
17712    case POOL16C:
17713        if (ctx->insn_flags & ISA_MIPS32R6) {
17714            gen_pool16c_r6_insn(ctx);
17715        } else {
17716            gen_pool16c_insn(ctx);
17717        }
17718        break;
17719    case LWGP16:
17720        {
17721            int rd = mmreg(uMIPS_RD(ctx->opcode));
17722            int rb = 28;            /* GP */
17723            int16_t offset = SIMM(ctx->opcode, 0, 7) << 2;
17724
17725            gen_ld(ctx, OPC_LW, rd, rb, offset);
17726        }
17727        break;
17728    case POOL16F:
17729        check_insn_opc_removed(ctx, ISA_MIPS32R6);
17730        if (ctx->opcode & 1) {
17731            generate_exception_end(ctx, EXCP_RI);
17732        } else {
17733            /* MOVEP */
17734            int enc_dest = uMIPS_RD(ctx->opcode);
17735            int enc_rt = uMIPS_RS2(ctx->opcode);
17736            int enc_rs = uMIPS_RS1(ctx->opcode);
17737            gen_movep(ctx, enc_dest, enc_rt, enc_rs);
17738        }
17739        break;
17740    case LBU16:
17741        {
17742            int rd = mmreg(uMIPS_RD(ctx->opcode));
17743            int rb = mmreg(uMIPS_RS(ctx->opcode));
17744            int16_t offset = ZIMM(ctx->opcode, 0, 4);
17745            offset = (offset == 0xf ? -1 : offset);
17746
17747            gen_ld(ctx, OPC_LBU, rd, rb, offset);
17748        }
17749        break;
17750    case LHU16:
17751        {
17752            int rd = mmreg(uMIPS_RD(ctx->opcode));
17753            int rb = mmreg(uMIPS_RS(ctx->opcode));
17754            int16_t offset = ZIMM(ctx->opcode, 0, 4) << 1;
17755
17756            gen_ld(ctx, OPC_LHU, rd, rb, offset);
17757        }
17758        break;
17759    case LWSP16:
17760        {
17761            int rd = (ctx->opcode >> 5) & 0x1f;
17762            int rb = 29;            /* SP */
17763            int16_t offset = ZIMM(ctx->opcode, 0, 5) << 2;
17764
17765            gen_ld(ctx, OPC_LW, rd, rb, offset);
17766        }
17767        break;
17768    case LW16:
17769        {
17770            int rd = mmreg(uMIPS_RD(ctx->opcode));
17771            int rb = mmreg(uMIPS_RS(ctx->opcode));
17772            int16_t offset = ZIMM(ctx->opcode, 0, 4) << 2;
17773
17774            gen_ld(ctx, OPC_LW, rd, rb, offset);
17775        }
17776        break;
17777    case SB16:
17778        {
17779            int rd = mmreg2(uMIPS_RD(ctx->opcode));
17780            int rb = mmreg(uMIPS_RS(ctx->opcode));
17781            int16_t offset = ZIMM(ctx->opcode, 0, 4);
17782
17783            gen_st(ctx, OPC_SB, rd, rb, offset);
17784        }
17785        break;
17786    case SH16:
17787        {
17788            int rd = mmreg2(uMIPS_RD(ctx->opcode));
17789            int rb = mmreg(uMIPS_RS(ctx->opcode));
17790            int16_t offset = ZIMM(ctx->opcode, 0, 4) << 1;
17791
17792            gen_st(ctx, OPC_SH, rd, rb, offset);
17793        }
17794        break;
17795    case SWSP16:
17796        {
17797            int rd = (ctx->opcode >> 5) & 0x1f;
17798            int rb = 29;            /* SP */
17799            int16_t offset = ZIMM(ctx->opcode, 0, 5) << 2;
17800
17801            gen_st(ctx, OPC_SW, rd, rb, offset);
17802        }
17803        break;
17804    case SW16:
17805        {
17806            int rd = mmreg2(uMIPS_RD(ctx->opcode));
17807            int rb = mmreg(uMIPS_RS(ctx->opcode));
17808            int16_t offset = ZIMM(ctx->opcode, 0, 4) << 2;
17809
17810            gen_st(ctx, OPC_SW, rd, rb, offset);
17811        }
17812        break;
17813    case MOVE16:
17814        {
17815            int rd = uMIPS_RD5(ctx->opcode);
17816            int rs = uMIPS_RS5(ctx->opcode);
17817
17818            gen_arith(ctx, OPC_ADDU, rd, rs, 0);
17819        }
17820        break;
17821    case ANDI16:
17822        gen_andi16(ctx);
17823        break;
17824    case POOL16D:
17825        switch (ctx->opcode & 0x1) {
17826        case ADDIUS5:
17827            gen_addius5(ctx);
17828            break;
17829        case ADDIUSP:
17830            gen_addiusp(ctx);
17831            break;
17832        }
17833        break;
17834    case POOL16E:
17835        switch (ctx->opcode & 0x1) {
17836        case ADDIUR2:
17837            gen_addiur2(ctx);
17838            break;
17839        case ADDIUR1SP:
17840            gen_addiur1sp(ctx);
17841            break;
17842        }
17843        break;
17844    case B16: /* BC16 */
17845        gen_compute_branch(ctx, OPC_BEQ, 2, 0, 0,
17846                           sextract32(ctx->opcode, 0, 10) << 1,
17847                           (ctx->insn_flags & ISA_MIPS32R6) ? 0 : 4);
17848        break;
17849    case BNEZ16: /* BNEZC16 */
17850    case BEQZ16: /* BEQZC16 */
17851        gen_compute_branch(ctx, op == BNEZ16 ? OPC_BNE : OPC_BEQ, 2,
17852                           mmreg(uMIPS_RD(ctx->opcode)),
17853                           0, sextract32(ctx->opcode, 0, 7) << 1,
17854                           (ctx->insn_flags & ISA_MIPS32R6) ? 0 : 4);
17855
17856        break;
17857    case LI16:
17858        {
17859            int reg = mmreg(uMIPS_RD(ctx->opcode));
17860            int imm = ZIMM(ctx->opcode, 0, 7);
17861
17862            imm = (imm == 0x7f ? -1 : imm);
17863            tcg_gen_movi_tl(cpu_gpr[reg], imm);
17864        }
17865        break;
17866    case RES_29:
17867    case RES_31:
17868    case RES_39:
17869        generate_exception_end(ctx, EXCP_RI);
17870        break;
17871    default:
17872        decode_micromips32_opc(env, ctx);
17873        return 4;
17874    }
17875
17876    return 2;
17877}
17878
17879/*
17880 *
17881 * nanoMIPS opcodes
17882 *
17883 */
17884
17885/* MAJOR, P16, and P32 pools opcodes */
17886enum {
17887    NM_P_ADDIU      = 0x00,
17888    NM_ADDIUPC      = 0x01,
17889    NM_MOVE_BALC    = 0x02,
17890    NM_P16_MV       = 0x04,
17891    NM_LW16         = 0x05,
17892    NM_BC16         = 0x06,
17893    NM_P16_SR       = 0x07,
17894
17895    NM_POOL32A      = 0x08,
17896    NM_P_BAL        = 0x0a,
17897    NM_P16_SHIFT    = 0x0c,
17898    NM_LWSP16       = 0x0d,
17899    NM_BALC16       = 0x0e,
17900    NM_P16_4X4      = 0x0f,
17901
17902    NM_P_GP_W       = 0x10,
17903    NM_P_GP_BH      = 0x11,
17904    NM_P_J          = 0x12,
17905    NM_P16C         = 0x14,
17906    NM_LWGP16       = 0x15,
17907    NM_P16_LB       = 0x17,
17908
17909    NM_P48I         = 0x18,
17910    NM_P16_A1       = 0x1c,
17911    NM_LW4X4        = 0x1d,
17912    NM_P16_LH       = 0x1f,
17913
17914    NM_P_U12        = 0x20,
17915    NM_P_LS_U12     = 0x21,
17916    NM_P_BR1        = 0x22,
17917    NM_P16_A2       = 0x24,
17918    NM_SW16         = 0x25,
17919    NM_BEQZC16      = 0x26,
17920
17921    NM_POOL32F      = 0x28,
17922    NM_P_LS_S9      = 0x29,
17923    NM_P_BR2        = 0x2a,
17924
17925    NM_P16_ADDU     = 0x2c,
17926    NM_SWSP16       = 0x2d,
17927    NM_BNEZC16      = 0x2e,
17928    NM_MOVEP        = 0x2f,
17929
17930    NM_POOL32S      = 0x30,
17931    NM_P_BRI        = 0x32,
17932    NM_LI16         = 0x34,
17933    NM_SWGP16       = 0x35,
17934    NM_P16_BR       = 0x36,
17935
17936    NM_P_LUI        = 0x38,
17937    NM_ANDI16       = 0x3c,
17938    NM_SW4X4        = 0x3d,
17939    NM_MOVEPREV     = 0x3f,
17940};
17941
17942/* POOL32A instruction pool */
17943enum {
17944    NM_POOL32A0    = 0x00,
17945    NM_SPECIAL2    = 0x01,
17946    NM_COP2_1      = 0x02,
17947    NM_UDI         = 0x03,
17948    NM_POOL32A5    = 0x05,
17949    NM_POOL32A7    = 0x07,
17950};
17951
17952/* P.GP.W instruction pool */
17953enum {
17954    NM_ADDIUGP_W = 0x00,
17955    NM_LWGP      = 0x02,
17956    NM_SWGP      = 0x03,
17957};
17958
17959/* P48I instruction pool */
17960enum {
17961    NM_LI48        = 0x00,
17962    NM_ADDIU48     = 0x01,
17963    NM_ADDIUGP48   = 0x02,
17964    NM_ADDIUPC48   = 0x03,
17965    NM_LWPC48      = 0x0b,
17966    NM_SWPC48      = 0x0f,
17967};
17968
17969/* P.U12 instruction pool */
17970enum {
17971    NM_ORI      = 0x00,
17972    NM_XORI     = 0x01,
17973    NM_ANDI     = 0x02,
17974    NM_P_SR     = 0x03,
17975    NM_SLTI     = 0x04,
17976    NM_SLTIU    = 0x05,
17977    NM_SEQI     = 0x06,
17978    NM_ADDIUNEG = 0x08,
17979    NM_P_SHIFT  = 0x0c,
17980    NM_P_ROTX   = 0x0d,
17981    NM_P_INS    = 0x0e,
17982    NM_P_EXT    = 0x0f,
17983};
17984
17985/* POOL32F instruction pool */
17986enum {
17987    NM_POOL32F_0   = 0x00,
17988    NM_POOL32F_3   = 0x03,
17989    NM_POOL32F_5   = 0x05,
17990};
17991
17992/* POOL32S instruction pool */
17993enum {
17994    NM_POOL32S_0   = 0x00,
17995    NM_POOL32S_4   = 0x04,
17996};
17997
17998/* P.LUI instruction pool */
17999enum {
18000    NM_LUI      = 0x00,
18001    NM_ALUIPC   = 0x01,
18002};
18003
18004/* P.GP.BH instruction pool */
18005enum {
18006    NM_LBGP      = 0x00,
18007    NM_SBGP      = 0x01,
18008    NM_LBUGP     = 0x02,
18009    NM_ADDIUGP_B = 0x03,
18010    NM_P_GP_LH   = 0x04,
18011    NM_P_GP_SH   = 0x05,
18012    NM_P_GP_CP1  = 0x06,
18013};
18014
18015/* P.LS.U12 instruction pool */
18016enum {
18017    NM_LB        = 0x00,
18018    NM_SB        = 0x01,
18019    NM_LBU       = 0x02,
18020    NM_P_PREFU12 = 0x03,
18021    NM_LH        = 0x04,
18022    NM_SH        = 0x05,
18023    NM_LHU       = 0x06,
18024    NM_LWU       = 0x07,
18025    NM_LW        = 0x08,
18026    NM_SW        = 0x09,
18027    NM_LWC1      = 0x0a,
18028    NM_SWC1      = 0x0b,
18029    NM_LDC1      = 0x0e,
18030    NM_SDC1      = 0x0f,
18031};
18032
18033/* P.LS.S9 instruction pool */
18034enum {
18035    NM_P_LS_S0         = 0x00,
18036    NM_P_LS_S1         = 0x01,
18037    NM_P_LS_E0         = 0x02,
18038    NM_P_LS_WM         = 0x04,
18039    NM_P_LS_UAWM       = 0x05,
18040};
18041
18042/* P.BAL instruction pool */
18043enum {
18044    NM_BC       = 0x00,
18045    NM_BALC     = 0x01,
18046};
18047
18048/* P.J instruction pool */
18049enum {
18050    NM_JALRC    = 0x00,
18051    NM_JALRC_HB = 0x01,
18052    NM_P_BALRSC = 0x08,
18053};
18054
18055/* P.BR1 instruction pool */
18056enum {
18057    NM_BEQC     = 0x00,
18058    NM_P_BR3A   = 0x01,
18059    NM_BGEC     = 0x02,
18060    NM_BGEUC    = 0x03,
18061};
18062
18063/* P.BR2 instruction pool */
18064enum {
18065    NM_BNEC     = 0x00,
18066    NM_BLTC     = 0x02,
18067    NM_BLTUC    = 0x03,
18068};
18069
18070/* P.BRI instruction pool */
18071enum {
18072    NM_BEQIC    = 0x00,
18073    NM_BBEQZC   = 0x01,
18074    NM_BGEIC    = 0x02,
18075    NM_BGEIUC   = 0x03,
18076    NM_BNEIC    = 0x04,
18077    NM_BBNEZC   = 0x05,
18078    NM_BLTIC    = 0x06,
18079    NM_BLTIUC   = 0x07,
18080};
18081
18082/* P16.SHIFT instruction pool */
18083enum {
18084    NM_SLL16    = 0x00,
18085    NM_SRL16    = 0x01,
18086};
18087
18088/* POOL16C instruction pool */
18089enum {
18090    NM_POOL16C_0  = 0x00,
18091    NM_LWXS16     = 0x01,
18092};
18093
18094/* P16.A1 instruction pool */
18095enum {
18096    NM_ADDIUR1SP = 0x01,
18097};
18098
18099/* P16.A2 instruction pool */
18100enum {
18101    NM_ADDIUR2  = 0x00,
18102    NM_P_ADDIURS5  = 0x01,
18103};
18104
18105/* P16.ADDU instruction pool */
18106enum {
18107    NM_ADDU16     = 0x00,
18108    NM_SUBU16     = 0x01,
18109};
18110
18111/* P16.SR instruction pool */
18112enum {
18113    NM_SAVE16        = 0x00,
18114    NM_RESTORE_JRC16 = 0x01,
18115};
18116
18117/* P16.4X4 instruction pool */
18118enum {
18119    NM_ADDU4X4      = 0x00,
18120    NM_MUL4X4       = 0x01,
18121};
18122
18123/* P16.LB instruction pool */
18124enum {
18125    NM_LB16       = 0x00,
18126    NM_SB16       = 0x01,
18127    NM_LBU16      = 0x02,
18128};
18129
18130/* P16.LH  instruction pool */
18131enum {
18132    NM_LH16     = 0x00,
18133    NM_SH16     = 0x01,
18134    NM_LHU16    = 0x02,
18135};
18136
18137/* P.RI instruction pool */
18138enum {
18139    NM_SIGRIE       = 0x00,
18140    NM_P_SYSCALL    = 0x01,
18141    NM_BREAK        = 0x02,
18142    NM_SDBBP        = 0x03,
18143};
18144
18145/* POOL32A0 instruction pool */
18146enum {
18147    NM_P_TRAP   = 0x00,
18148    NM_SEB      = 0x01,
18149    NM_SLLV     = 0x02,
18150    NM_MUL      = 0x03,
18151    NM_MFC0     = 0x06,
18152    NM_MFHC0    = 0x07,
18153    NM_SEH      = 0x09,
18154    NM_SRLV     = 0x0a,
18155    NM_MUH      = 0x0b,
18156    NM_MTC0     = 0x0e,
18157    NM_MTHC0    = 0x0f,
18158    NM_SRAV     = 0x12,
18159    NM_MULU     = 0x13,
18160    NM_ROTRV    = 0x1a,
18161    NM_MUHU     = 0x1b,
18162    NM_ADD      = 0x22,
18163    NM_DIV      = 0x23,
18164    NM_ADDU     = 0x2a,
18165    NM_MOD      = 0x2b,
18166    NM_SUB      = 0x32,
18167    NM_DIVU     = 0x33,
18168    NM_RDHWR    = 0x38,
18169    NM_SUBU     = 0x3a,
18170    NM_MODU     = 0x3b,
18171    NM_P_CMOVE  = 0x42,
18172    NM_FORK     = 0x45,
18173    NM_MFTR     = 0x46,
18174    NM_MFHTR    = 0x47,
18175    NM_AND      = 0x4a,
18176    NM_YIELD    = 0x4d,
18177    NM_MTTR     = 0x4e,
18178    NM_MTHTR    = 0x4f,
18179    NM_OR       = 0x52,
18180    NM_D_E_MT_VPE = 0x56,
18181    NM_NOR      = 0x5a,
18182    NM_XOR      = 0x62,
18183    NM_SLT      = 0x6a,
18184    NM_P_SLTU   = 0x72,
18185    NM_SOV      = 0x7a,
18186};
18187
18188/* CRC32 instruction pool */
18189enum {
18190    NM_CRC32B   = 0x00,
18191    NM_CRC32H   = 0x01,
18192    NM_CRC32W   = 0x02,
18193    NM_CRC32CB  = 0x04,
18194    NM_CRC32CH  = 0x05,
18195    NM_CRC32CW  = 0x06,
18196};
18197
18198/* POOL32A5 instruction pool */
18199enum {
18200    NM_CMP_EQ_PH        = 0x00,
18201    NM_CMP_LT_PH        = 0x08,
18202    NM_CMP_LE_PH        = 0x10,
18203    NM_CMPGU_EQ_QB      = 0x18,
18204    NM_CMPGU_LT_QB      = 0x20,
18205    NM_CMPGU_LE_QB      = 0x28,
18206    NM_CMPGDU_EQ_QB     = 0x30,
18207    NM_CMPGDU_LT_QB     = 0x38,
18208    NM_CMPGDU_LE_QB     = 0x40,
18209    NM_CMPU_EQ_QB       = 0x48,
18210    NM_CMPU_LT_QB       = 0x50,
18211    NM_CMPU_LE_QB       = 0x58,
18212    NM_ADDQ_S_W         = 0x60,
18213    NM_SUBQ_S_W         = 0x68,
18214    NM_ADDSC            = 0x70,
18215    NM_ADDWC            = 0x78,
18216
18217    NM_ADDQ_S_PH   = 0x01,
18218    NM_ADDQH_R_PH  = 0x09,
18219    NM_ADDQH_R_W   = 0x11,
18220    NM_ADDU_S_QB   = 0x19,
18221    NM_ADDU_S_PH   = 0x21,
18222    NM_ADDUH_R_QB  = 0x29,
18223    NM_SHRAV_R_PH  = 0x31,
18224    NM_SHRAV_R_QB  = 0x39,
18225    NM_SUBQ_S_PH   = 0x41,
18226    NM_SUBQH_R_PH  = 0x49,
18227    NM_SUBQH_R_W   = 0x51,
18228    NM_SUBU_S_QB   = 0x59,
18229    NM_SUBU_S_PH   = 0x61,
18230    NM_SUBUH_R_QB  = 0x69,
18231    NM_SHLLV_S_PH  = 0x71,
18232    NM_PRECR_SRA_R_PH_W = 0x79,
18233
18234    NM_MULEU_S_PH_QBL   = 0x12,
18235    NM_MULEU_S_PH_QBR   = 0x1a,
18236    NM_MULQ_RS_PH       = 0x22,
18237    NM_MULQ_S_PH        = 0x2a,
18238    NM_MULQ_RS_W        = 0x32,
18239    NM_MULQ_S_W         = 0x3a,
18240    NM_APPEND           = 0x42,
18241    NM_MODSUB           = 0x52,
18242    NM_SHRAV_R_W        = 0x5a,
18243    NM_SHRLV_PH         = 0x62,
18244    NM_SHRLV_QB         = 0x6a,
18245    NM_SHLLV_QB         = 0x72,
18246    NM_SHLLV_S_W        = 0x7a,
18247
18248    NM_SHILO            = 0x03,
18249
18250    NM_MULEQ_S_W_PHL    = 0x04,
18251    NM_MULEQ_S_W_PHR    = 0x0c,
18252
18253    NM_MUL_S_PH         = 0x05,
18254    NM_PRECR_QB_PH      = 0x0d,
18255    NM_PRECRQ_QB_PH     = 0x15,
18256    NM_PRECRQ_PH_W      = 0x1d,
18257    NM_PRECRQ_RS_PH_W   = 0x25,
18258    NM_PRECRQU_S_QB_PH  = 0x2d,
18259    NM_PACKRL_PH        = 0x35,
18260    NM_PICK_QB          = 0x3d,
18261    NM_PICK_PH          = 0x45,
18262
18263    NM_SHRA_R_W         = 0x5e,
18264    NM_SHRA_R_PH        = 0x66,
18265    NM_SHLL_S_PH        = 0x76,
18266    NM_SHLL_S_W         = 0x7e,
18267
18268    NM_REPL_PH          = 0x07
18269};
18270
18271/* POOL32A7 instruction pool */
18272enum {
18273    NM_P_LSX        = 0x00,
18274    NM_LSA          = 0x01,
18275    NM_EXTW         = 0x03,
18276    NM_POOL32AXF    = 0x07,
18277};
18278
18279/* P.SR instruction pool */
18280enum {
18281    NM_PP_SR           = 0x00,
18282    NM_P_SR_F          = 0x01,
18283};
18284
18285/* P.SHIFT instruction pool */
18286enum {
18287    NM_P_SLL        = 0x00,
18288    NM_SRL          = 0x02,
18289    NM_SRA          = 0x04,
18290    NM_ROTR         = 0x06,
18291};
18292
18293/* P.ROTX instruction pool */
18294enum {
18295    NM_ROTX         = 0x00,
18296};
18297
18298/* P.INS instruction pool */
18299enum {
18300    NM_INS          = 0x00,
18301};
18302
18303/* P.EXT instruction pool */
18304enum {
18305    NM_EXT          = 0x00,
18306};
18307
18308/* POOL32F_0 (fmt) instruction pool */
18309enum {
18310    NM_RINT_S              = 0x04,
18311    NM_RINT_D              = 0x44,
18312    NM_ADD_S               = 0x06,
18313    NM_SELEQZ_S            = 0x07,
18314    NM_SELEQZ_D            = 0x47,
18315    NM_CLASS_S             = 0x0c,
18316    NM_CLASS_D             = 0x4c,
18317    NM_SUB_S               = 0x0e,
18318    NM_SELNEZ_S            = 0x0f,
18319    NM_SELNEZ_D            = 0x4f,
18320    NM_MUL_S               = 0x16,
18321    NM_SEL_S               = 0x17,
18322    NM_SEL_D               = 0x57,
18323    NM_DIV_S               = 0x1e,
18324    NM_ADD_D               = 0x26,
18325    NM_SUB_D               = 0x2e,
18326    NM_MUL_D               = 0x36,
18327    NM_MADDF_S             = 0x37,
18328    NM_MADDF_D             = 0x77,
18329    NM_DIV_D               = 0x3e,
18330    NM_MSUBF_S             = 0x3f,
18331    NM_MSUBF_D             = 0x7f,
18332};
18333
18334/* POOL32F_3  instruction pool */
18335enum {
18336    NM_MIN_FMT         = 0x00,
18337    NM_MAX_FMT         = 0x01,
18338    NM_MINA_FMT        = 0x04,
18339    NM_MAXA_FMT        = 0x05,
18340    NM_POOL32FXF       = 0x07,
18341};
18342
18343/* POOL32F_5  instruction pool */
18344enum {
18345    NM_CMP_CONDN_S     = 0x00,
18346    NM_CMP_CONDN_D     = 0x02,
18347};
18348
18349/* P.GP.LH instruction pool */
18350enum {
18351    NM_LHGP    = 0x00,
18352    NM_LHUGP   = 0x01,
18353};
18354
18355/* P.GP.SH instruction pool */
18356enum {
18357    NM_SHGP    = 0x00,
18358};
18359
18360/* P.GP.CP1 instruction pool */
18361enum {
18362    NM_LWC1GP       = 0x00,
18363    NM_SWC1GP       = 0x01,
18364    NM_LDC1GP       = 0x02,
18365    NM_SDC1GP       = 0x03,
18366};
18367
18368/* P.LS.S0 instruction pool */
18369enum {
18370    NM_LBS9     = 0x00,
18371    NM_LHS9     = 0x04,
18372    NM_LWS9     = 0x08,
18373    NM_LDS9     = 0x0c,
18374
18375    NM_SBS9     = 0x01,
18376    NM_SHS9     = 0x05,
18377    NM_SWS9     = 0x09,
18378    NM_SDS9     = 0x0d,
18379
18380    NM_LBUS9    = 0x02,
18381    NM_LHUS9    = 0x06,
18382    NM_LWC1S9   = 0x0a,
18383    NM_LDC1S9   = 0x0e,
18384
18385    NM_P_PREFS9 = 0x03,
18386    NM_LWUS9    = 0x07,
18387    NM_SWC1S9   = 0x0b,
18388    NM_SDC1S9   = 0x0f,
18389};
18390
18391/* P.LS.S1 instruction pool */
18392enum {
18393    NM_ASET_ACLR = 0x02,
18394    NM_UALH      = 0x04,
18395    NM_UASH      = 0x05,
18396    NM_CACHE     = 0x07,
18397    NM_P_LL      = 0x0a,
18398    NM_P_SC      = 0x0b,
18399};
18400
18401/* P.LS.E0 instruction pool */
18402enum {
18403    NM_LBE      = 0x00,
18404    NM_SBE      = 0x01,
18405    NM_LBUE     = 0x02,
18406    NM_P_PREFE  = 0x03,
18407    NM_LHE      = 0x04,
18408    NM_SHE      = 0x05,
18409    NM_LHUE     = 0x06,
18410    NM_CACHEE   = 0x07,
18411    NM_LWE      = 0x08,
18412    NM_SWE      = 0x09,
18413    NM_P_LLE    = 0x0a,
18414    NM_P_SCE    = 0x0b,
18415};
18416
18417/* P.PREFE instruction pool */
18418enum {
18419    NM_SYNCIE   = 0x00,
18420    NM_PREFE    = 0x01,
18421};
18422
18423/* P.LLE instruction pool */
18424enum {
18425    NM_LLE      = 0x00,
18426    NM_LLWPE    = 0x01,
18427};
18428
18429/* P.SCE instruction pool */
18430enum {
18431    NM_SCE      = 0x00,
18432    NM_SCWPE    = 0x01,
18433};
18434
18435/* P.LS.WM instruction pool */
18436enum {
18437    NM_LWM       = 0x00,
18438    NM_SWM       = 0x01,
18439};
18440
18441/* P.LS.UAWM instruction pool */
18442enum {
18443    NM_UALWM       = 0x00,
18444    NM_UASWM       = 0x01,
18445};
18446
18447/* P.BR3A instruction pool */
18448enum {
18449    NM_BC1EQZC          = 0x00,
18450    NM_BC1NEZC          = 0x01,
18451    NM_BC2EQZC          = 0x02,
18452    NM_BC2NEZC          = 0x03,
18453    NM_BPOSGE32C        = 0x04,
18454};
18455
18456/* P16.RI instruction pool */
18457enum {
18458    NM_P16_SYSCALL  = 0x01,
18459    NM_BREAK16      = 0x02,
18460    NM_SDBBP16      = 0x03,
18461};
18462
18463/* POOL16C_0 instruction pool */
18464enum {
18465    NM_POOL16C_00      = 0x00,
18466};
18467
18468/* P16.JRC instruction pool */
18469enum {
18470    NM_JRC          = 0x00,
18471    NM_JALRC16      = 0x01,
18472};
18473
18474/* P.SYSCALL instruction pool */
18475enum {
18476    NM_SYSCALL      = 0x00,
18477    NM_HYPCALL      = 0x01,
18478};
18479
18480/* P.TRAP instruction pool */
18481enum {
18482    NM_TEQ          = 0x00,
18483    NM_TNE          = 0x01,
18484};
18485
18486/* P.CMOVE instruction pool */
18487enum {
18488    NM_MOVZ            = 0x00,
18489    NM_MOVN            = 0x01,
18490};
18491
18492/* POOL32Axf instruction pool */
18493enum {
18494    NM_POOL32AXF_1 = 0x01,
18495    NM_POOL32AXF_2 = 0x02,
18496    NM_POOL32AXF_4 = 0x04,
18497    NM_POOL32AXF_5 = 0x05,
18498    NM_POOL32AXF_7 = 0x07,
18499};
18500
18501/* POOL32Axf_1 instruction pool */
18502enum {
18503    NM_POOL32AXF_1_0 = 0x00,
18504    NM_POOL32AXF_1_1 = 0x01,
18505    NM_POOL32AXF_1_3 = 0x03,
18506    NM_POOL32AXF_1_4 = 0x04,
18507    NM_POOL32AXF_1_5 = 0x05,
18508    NM_POOL32AXF_1_7 = 0x07,
18509};
18510
18511/* POOL32Axf_2 instruction pool */
18512enum {
18513    NM_POOL32AXF_2_0_7     = 0x00,
18514    NM_POOL32AXF_2_8_15    = 0x01,
18515    NM_POOL32AXF_2_16_23   = 0x02,
18516    NM_POOL32AXF_2_24_31   = 0x03,
18517};
18518
18519/* POOL32Axf_7 instruction pool */
18520enum {
18521    NM_SHRA_R_QB    = 0x0,
18522    NM_SHRL_PH      = 0x1,
18523    NM_REPL_QB      = 0x2,
18524};
18525
18526/* POOL32Axf_1_0 instruction pool */
18527enum {
18528    NM_MFHI = 0x0,
18529    NM_MFLO = 0x1,
18530    NM_MTHI = 0x2,
18531    NM_MTLO = 0x3,
18532};
18533
18534/* POOL32Axf_1_1 instruction pool */
18535enum {
18536    NM_MTHLIP = 0x0,
18537    NM_SHILOV = 0x1,
18538};
18539
18540/* POOL32Axf_1_3 instruction pool */
18541enum {
18542    NM_RDDSP    = 0x0,
18543    NM_WRDSP    = 0x1,
18544    NM_EXTP     = 0x2,
18545    NM_EXTPDP   = 0x3,
18546};
18547
18548/* POOL32Axf_1_4 instruction pool */
18549enum {
18550    NM_SHLL_QB  = 0x0,
18551    NM_SHRL_QB  = 0x1,
18552};
18553
18554/* POOL32Axf_1_5 instruction pool */
18555enum {
18556    NM_MAQ_S_W_PHR   = 0x0,
18557    NM_MAQ_S_W_PHL   = 0x1,
18558    NM_MAQ_SA_W_PHR  = 0x2,
18559    NM_MAQ_SA_W_PHL  = 0x3,
18560};
18561
18562/* POOL32Axf_1_7 instruction pool */
18563enum {
18564    NM_EXTR_W       = 0x0,
18565    NM_EXTR_R_W     = 0x1,
18566    NM_EXTR_RS_W    = 0x2,
18567    NM_EXTR_S_H     = 0x3,
18568};
18569
18570/* POOL32Axf_2_0_7 instruction pool */
18571enum {
18572    NM_DPA_W_PH     = 0x0,
18573    NM_DPAQ_S_W_PH  = 0x1,
18574    NM_DPS_W_PH     = 0x2,
18575    NM_DPSQ_S_W_PH  = 0x3,
18576    NM_BALIGN       = 0x4,
18577    NM_MADD         = 0x5,
18578    NM_MULT         = 0x6,
18579    NM_EXTRV_W      = 0x7,
18580};
18581
18582/* POOL32Axf_2_8_15 instruction pool */
18583enum {
18584    NM_DPAX_W_PH    = 0x0,
18585    NM_DPAQ_SA_L_W  = 0x1,
18586    NM_DPSX_W_PH    = 0x2,
18587    NM_DPSQ_SA_L_W  = 0x3,
18588    NM_MADDU        = 0x5,
18589    NM_MULTU        = 0x6,
18590    NM_EXTRV_R_W    = 0x7,
18591};
18592
18593/* POOL32Axf_2_16_23 instruction pool */
18594enum {
18595    NM_DPAU_H_QBL       = 0x0,
18596    NM_DPAQX_S_W_PH     = 0x1,
18597    NM_DPSU_H_QBL       = 0x2,
18598    NM_DPSQX_S_W_PH     = 0x3,
18599    NM_EXTPV            = 0x4,
18600    NM_MSUB             = 0x5,
18601    NM_MULSA_W_PH       = 0x6,
18602    NM_EXTRV_RS_W       = 0x7,
18603};
18604
18605/* POOL32Axf_2_24_31 instruction pool */
18606enum {
18607    NM_DPAU_H_QBR       = 0x0,
18608    NM_DPAQX_SA_W_PH    = 0x1,
18609    NM_DPSU_H_QBR       = 0x2,
18610    NM_DPSQX_SA_W_PH    = 0x3,
18611    NM_EXTPDPV          = 0x4,
18612    NM_MSUBU            = 0x5,
18613    NM_MULSAQ_S_W_PH    = 0x6,
18614    NM_EXTRV_S_H        = 0x7,
18615};
18616
18617/* POOL32Axf_{4, 5} instruction pool */
18618enum {
18619    NM_CLO      = 0x25,
18620    NM_CLZ      = 0x2d,
18621
18622    NM_TLBP     = 0x01,
18623    NM_TLBR     = 0x09,
18624    NM_TLBWI    = 0x11,
18625    NM_TLBWR    = 0x19,
18626    NM_TLBINV   = 0x03,
18627    NM_TLBINVF  = 0x0b,
18628    NM_DI       = 0x23,
18629    NM_EI       = 0x2b,
18630    NM_RDPGPR   = 0x70,
18631    NM_WRPGPR   = 0x78,
18632    NM_WAIT     = 0x61,
18633    NM_DERET    = 0x71,
18634    NM_ERETX    = 0x79,
18635
18636    /* nanoMIPS DSP instructions */
18637    NM_ABSQ_S_QB        = 0x00,
18638    NM_ABSQ_S_PH        = 0x08,
18639    NM_ABSQ_S_W         = 0x10,
18640    NM_PRECEQ_W_PHL     = 0x28,
18641    NM_PRECEQ_W_PHR     = 0x30,
18642    NM_PRECEQU_PH_QBL   = 0x38,
18643    NM_PRECEQU_PH_QBR   = 0x48,
18644    NM_PRECEU_PH_QBL    = 0x58,
18645    NM_PRECEU_PH_QBR    = 0x68,
18646    NM_PRECEQU_PH_QBLA  = 0x39,
18647    NM_PRECEQU_PH_QBRA  = 0x49,
18648    NM_PRECEU_PH_QBLA   = 0x59,
18649    NM_PRECEU_PH_QBRA   = 0x69,
18650    NM_REPLV_PH         = 0x01,
18651    NM_REPLV_QB         = 0x09,
18652    NM_BITREV           = 0x18,
18653    NM_INSV             = 0x20,
18654    NM_RADDU_W_QB       = 0x78,
18655
18656    NM_BITSWAP          = 0x05,
18657    NM_WSBH             = 0x3d,
18658};
18659
18660/* PP.SR instruction pool */
18661enum {
18662    NM_SAVE         = 0x00,
18663    NM_RESTORE      = 0x02,
18664    NM_RESTORE_JRC  = 0x03,
18665};
18666
18667/* P.SR.F instruction pool */
18668enum {
18669    NM_SAVEF        = 0x00,
18670    NM_RESTOREF     = 0x01,
18671};
18672
18673/* P16.SYSCALL  instruction pool */
18674enum {
18675    NM_SYSCALL16     = 0x00,
18676    NM_HYPCALL16     = 0x01,
18677};
18678
18679/* POOL16C_00 instruction pool */
18680enum {
18681    NM_NOT16           = 0x00,
18682    NM_XOR16           = 0x01,
18683    NM_AND16           = 0x02,
18684    NM_OR16            = 0x03,
18685};
18686
18687/* PP.LSX and PP.LSXS instruction pool */
18688enum {
18689    NM_LBX      = 0x00,
18690    NM_LHX      = 0x04,
18691    NM_LWX      = 0x08,
18692    NM_LDX      = 0x0c,
18693
18694    NM_SBX      = 0x01,
18695    NM_SHX      = 0x05,
18696    NM_SWX      = 0x09,
18697    NM_SDX      = 0x0d,
18698
18699    NM_LBUX     = 0x02,
18700    NM_LHUX     = 0x06,
18701    NM_LWC1X    = 0x0a,
18702    NM_LDC1X    = 0x0e,
18703
18704    NM_LWUX     = 0x07,
18705    NM_SWC1X    = 0x0b,
18706    NM_SDC1X    = 0x0f,
18707
18708    NM_LHXS     = 0x04,
18709    NM_LWXS     = 0x08,
18710    NM_LDXS     = 0x0c,
18711
18712    NM_SHXS     = 0x05,
18713    NM_SWXS     = 0x09,
18714    NM_SDXS     = 0x0d,
18715
18716    NM_LHUXS    = 0x06,
18717    NM_LWC1XS   = 0x0a,
18718    NM_LDC1XS   = 0x0e,
18719
18720    NM_LWUXS    = 0x07,
18721    NM_SWC1XS   = 0x0b,
18722    NM_SDC1XS   = 0x0f,
18723};
18724
18725/* ERETx instruction pool */
18726enum {
18727    NM_ERET     = 0x00,
18728    NM_ERETNC   = 0x01,
18729};
18730
18731/* POOL32FxF_{0, 1} insturction pool */
18732enum {
18733    NM_CFC1     = 0x40,
18734    NM_CTC1     = 0x60,
18735    NM_MFC1     = 0x80,
18736    NM_MTC1     = 0xa0,
18737    NM_MFHC1    = 0xc0,
18738    NM_MTHC1    = 0xe0,
18739
18740    NM_CVT_S_PL = 0x84,
18741    NM_CVT_S_PU = 0xa4,
18742
18743    NM_CVT_L_S     = 0x004,
18744    NM_CVT_L_D     = 0x104,
18745    NM_CVT_W_S     = 0x024,
18746    NM_CVT_W_D     = 0x124,
18747
18748    NM_RSQRT_S     = 0x008,
18749    NM_RSQRT_D     = 0x108,
18750
18751    NM_SQRT_S      = 0x028,
18752    NM_SQRT_D      = 0x128,
18753
18754    NM_RECIP_S     = 0x048,
18755    NM_RECIP_D     = 0x148,
18756
18757    NM_FLOOR_L_S   = 0x00c,
18758    NM_FLOOR_L_D   = 0x10c,
18759
18760    NM_FLOOR_W_S   = 0x02c,
18761    NM_FLOOR_W_D   = 0x12c,
18762
18763    NM_CEIL_L_S    = 0x04c,
18764    NM_CEIL_L_D    = 0x14c,
18765    NM_CEIL_W_S    = 0x06c,
18766    NM_CEIL_W_D    = 0x16c,
18767    NM_TRUNC_L_S   = 0x08c,
18768    NM_TRUNC_L_D   = 0x18c,
18769    NM_TRUNC_W_S   = 0x0ac,
18770    NM_TRUNC_W_D   = 0x1ac,
18771    NM_ROUND_L_S   = 0x0cc,
18772    NM_ROUND_L_D   = 0x1cc,
18773    NM_ROUND_W_S   = 0x0ec,
18774    NM_ROUND_W_D   = 0x1ec,
18775
18776    NM_MOV_S       = 0x01,
18777    NM_MOV_D       = 0x81,
18778    NM_ABS_S       = 0x0d,
18779    NM_ABS_D       = 0x8d,
18780    NM_NEG_S       = 0x2d,
18781    NM_NEG_D       = 0xad,
18782    NM_CVT_D_S     = 0x04d,
18783    NM_CVT_D_W     = 0x0cd,
18784    NM_CVT_D_L     = 0x14d,
18785    NM_CVT_S_D     = 0x06d,
18786    NM_CVT_S_W     = 0x0ed,
18787    NM_CVT_S_L     = 0x16d,
18788};
18789
18790/* P.LL instruction pool */
18791enum {
18792    NM_LL       = 0x00,
18793    NM_LLWP     = 0x01,
18794};
18795
18796/* P.SC instruction pool */
18797enum {
18798    NM_SC       = 0x00,
18799    NM_SCWP     = 0x01,
18800};
18801
18802/* P.DVP instruction pool */
18803enum {
18804    NM_DVP      = 0x00,
18805    NM_EVP      = 0x01,
18806};
18807
18808
18809/*
18810 *
18811 * nanoMIPS decoding engine
18812 *
18813 */
18814
18815
18816/* extraction utilities */
18817
18818#define NANOMIPS_EXTRACT_RT3(op) ((op >> 7) & 0x7)
18819#define NANOMIPS_EXTRACT_RS3(op) ((op >> 4) & 0x7)
18820#define NANOMIPS_EXTRACT_RD3(op) ((op >> 1) & 0x7)
18821#define NANOMIPS_EXTRACT_RD5(op) ((op >> 5) & 0x1f)
18822#define NANOMIPS_EXTRACT_RS5(op) (op & 0x1f)
18823
18824/* Implement nanoMIPS pseudocode decode_gpr(encoded_gpr, 'gpr3'). */
18825static inline int decode_gpr_gpr3(int r)
18826{
18827    static const int map[] = { 16, 17, 18, 19,  4,  5,  6,  7 };
18828
18829    return map[r & 0x7];
18830}
18831
18832/* Implement nanoMIPS pseudocode decode_gpr(encoded_gpr, 'gpr3.src.store'). */
18833static inline int decode_gpr_gpr3_src_store(int r)
18834{
18835    static const int map[] = {  0, 17, 18, 19,  4,  5,  6,  7 };
18836
18837    return map[r & 0x7];
18838}
18839
18840/* Implement nanoMIPS pseudocode decode_gpr(encoded_gpr, 'gpr4'). */
18841static inline int decode_gpr_gpr4(int r)
18842{
18843    static const int map[] = {  8,  9, 10, 11,  4,  5,  6,  7,
18844                               16, 17, 18, 19, 20, 21, 22, 23 };
18845
18846    return map[r & 0xf];
18847}
18848
18849/* Implement nanoMIPS pseudocode decode_gpr(encoded_gpr, 'gpr4.zero'). */
18850static inline int decode_gpr_gpr4_zero(int r)
18851{
18852    static const int map[] = {  8,  9, 10,  0,  4,  5,  6,  7,
18853                               16, 17, 18, 19, 20, 21, 22, 23 };
18854
18855    return map[r & 0xf];
18856}
18857
18858
18859static void gen_adjust_sp(DisasContext *ctx, int u)
18860{
18861    gen_op_addr_addi(ctx, cpu_gpr[29], cpu_gpr[29], u);
18862}
18863
18864static void gen_save(DisasContext *ctx, uint8_t rt, uint8_t count,
18865                     uint8_t gp, uint16_t u)
18866{
18867    int counter = 0;
18868    TCGv va = tcg_temp_new();
18869    TCGv t0 = tcg_temp_new();
18870
18871    while (counter != count) {
18872        bool use_gp = gp && (counter == count - 1);
18873        int this_rt = use_gp ? 28 : (rt & 0x10) | ((rt + counter) & 0x1f);
18874        int this_offset = -((counter + 1) << 2);
18875        gen_base_offset_addr(ctx, va, 29, this_offset);
18876        gen_load_gpr(t0, this_rt);
18877        tcg_gen_qemu_st_tl(t0, va, ctx->mem_idx,
18878                           (MO_TEUL | ctx->default_tcg_memop_mask));
18879        counter++;
18880    }
18881
18882    /* adjust stack pointer */
18883    gen_adjust_sp(ctx, -u);
18884
18885    tcg_temp_free(t0);
18886    tcg_temp_free(va);
18887}
18888
18889static void gen_restore(DisasContext *ctx, uint8_t rt, uint8_t count,
18890                        uint8_t gp, uint16_t u)
18891{
18892    int counter = 0;
18893    TCGv va = tcg_temp_new();
18894    TCGv t0 = tcg_temp_new();
18895
18896    while (counter != count) {
18897        bool use_gp = gp && (counter == count - 1);
18898        int this_rt = use_gp ? 28 : (rt & 0x10) | ((rt + counter) & 0x1f);
18899        int this_offset = u - ((counter + 1) << 2);
18900        gen_base_offset_addr(ctx, va, 29, this_offset);
18901        tcg_gen_qemu_ld_tl(t0, va, ctx->mem_idx, MO_TESL |
18902                        ctx->default_tcg_memop_mask);
18903        tcg_gen_ext32s_tl(t0, t0);
18904        gen_store_gpr(t0, this_rt);
18905        counter++;
18906    }
18907
18908    /* adjust stack pointer */
18909    gen_adjust_sp(ctx, u);
18910
18911    tcg_temp_free(t0);
18912    tcg_temp_free(va);
18913}
18914
18915static void gen_pool16c_nanomips_insn(DisasContext *ctx)
18916{
18917    int rt = decode_gpr_gpr3(NANOMIPS_EXTRACT_RT3(ctx->opcode));
18918    int rs = decode_gpr_gpr3(NANOMIPS_EXTRACT_RS3(ctx->opcode));
18919
18920    switch (extract32(ctx->opcode, 2, 2)) {
18921    case NM_NOT16:
18922        gen_logic(ctx, OPC_NOR, rt, rs, 0);
18923        break;
18924    case NM_AND16:
18925        gen_logic(ctx, OPC_AND, rt, rt, rs);
18926        break;
18927    case NM_XOR16:
18928        gen_logic(ctx, OPC_XOR, rt, rt, rs);
18929        break;
18930    case NM_OR16:
18931        gen_logic(ctx, OPC_OR, rt, rt, rs);
18932        break;
18933    }
18934}
18935
18936static void gen_pool32a0_nanomips_insn(CPUMIPSState *env, DisasContext *ctx)
18937{
18938    int rt = extract32(ctx->opcode, 21, 5);
18939    int rs = extract32(ctx->opcode, 16, 5);
18940    int rd = extract32(ctx->opcode, 11, 5);
18941
18942    switch (extract32(ctx->opcode, 3, 7)) {
18943    case NM_P_TRAP:
18944        switch (extract32(ctx->opcode, 10, 1)) {
18945        case NM_TEQ:
18946            check_nms(ctx);
18947            gen_trap(ctx, OPC_TEQ, rs, rt, -1);
18948            break;
18949        case NM_TNE:
18950            check_nms(ctx);
18951            gen_trap(ctx, OPC_TNE, rs, rt, -1);
18952            break;
18953        }
18954        break;
18955    case NM_RDHWR:
18956        check_nms(ctx);
18957        gen_rdhwr(ctx, rt, rs, extract32(ctx->opcode, 11, 3));
18958        break;
18959    case NM_SEB:
18960        check_nms(ctx);
18961        gen_bshfl(ctx, OPC_SEB, rs, rt);
18962        break;
18963    case NM_SEH:
18964        gen_bshfl(ctx, OPC_SEH, rs, rt);
18965        break;
18966    case NM_SLLV:
18967        gen_shift(ctx, OPC_SLLV, rd, rt, rs);
18968        break;
18969    case NM_SRLV:
18970        gen_shift(ctx, OPC_SRLV, rd, rt, rs);
18971        break;
18972    case NM_SRAV:
18973        gen_shift(ctx, OPC_SRAV, rd, rt, rs);
18974        break;
18975    case NM_ROTRV:
18976        gen_shift(ctx, OPC_ROTRV, rd, rt, rs);
18977        break;
18978    case NM_ADD:
18979        gen_arith(ctx, OPC_ADD, rd, rs, rt);
18980        break;
18981    case NM_ADDU:
18982        gen_arith(ctx, OPC_ADDU, rd, rs, rt);
18983        break;
18984    case NM_SUB:
18985        check_nms(ctx);
18986        gen_arith(ctx, OPC_SUB, rd, rs, rt);
18987        break;
18988    case NM_SUBU:
18989        gen_arith(ctx, OPC_SUBU, rd, rs, rt);
18990        break;
18991    case NM_P_CMOVE:
18992        switch (extract32(ctx->opcode, 10, 1)) {
18993        case NM_MOVZ:
18994            gen_cond_move(ctx, OPC_MOVZ, rd, rs, rt);
18995            break;
18996        case NM_MOVN:
18997            gen_cond_move(ctx, OPC_MOVN, rd, rs, rt);
18998            break;
18999        }
19000        break;
19001    case NM_AND:
19002        gen_logic(ctx, OPC_AND, rd, rs, rt);
19003        break;
19004    case NM_OR:
19005        gen_logic(ctx, OPC_OR, rd, rs, rt);
19006        break;
19007    case NM_NOR:
19008        gen_logic(ctx, OPC_NOR, rd, rs, rt);
19009        break;
19010    case NM_XOR:
19011        gen_logic(ctx, OPC_XOR, rd, rs, rt);
19012        break;
19013    case NM_SLT:
19014        gen_slt(ctx, OPC_SLT, rd, rs, rt);
19015        break;
19016    case NM_P_SLTU:
19017        if (rd == 0) {
19018            /* P_DVP */
19019#ifndef CONFIG_USER_ONLY
19020            TCGv t0 = tcg_temp_new();
19021            switch (extract32(ctx->opcode, 10, 1)) {
19022            case NM_DVP:
19023                if (ctx->vp) {
19024                    check_cp0_enabled(ctx);
19025                    gen_helper_dvp(t0, cpu_env);
19026                    gen_store_gpr(t0, rt);
19027                }
19028                break;
19029            case NM_EVP:
19030                if (ctx->vp) {
19031                    check_cp0_enabled(ctx);
19032                    gen_helper_evp(t0, cpu_env);
19033                    gen_store_gpr(t0, rt);
19034                }
19035                break;
19036            }
19037            tcg_temp_free(t0);
19038#endif
19039        } else {
19040            gen_slt(ctx, OPC_SLTU, rd, rs, rt);
19041        }
19042        break;
19043    case NM_SOV:
19044        {
19045            TCGv t0 = tcg_temp_new();
19046            TCGv t1 = tcg_temp_new();
19047            TCGv t2 = tcg_temp_new();
19048
19049            gen_load_gpr(t1, rs);
19050            gen_load_gpr(t2, rt);
19051            tcg_gen_add_tl(t0, t1, t2);
19052            tcg_gen_ext32s_tl(t0, t0);
19053            tcg_gen_xor_tl(t1, t1, t2);
19054            tcg_gen_xor_tl(t2, t0, t2);
19055            tcg_gen_andc_tl(t1, t2, t1);
19056
19057            /* operands of same sign, result different sign */
19058            tcg_gen_setcondi_tl(TCG_COND_LT, t0, t1, 0);
19059            gen_store_gpr(t0, rd);
19060
19061            tcg_temp_free(t0);
19062            tcg_temp_free(t1);
19063            tcg_temp_free(t2);
19064        }
19065        break;
19066    case NM_MUL:
19067        gen_r6_muldiv(ctx, R6_OPC_MUL, rd, rs, rt);
19068        break;
19069    case NM_MUH:
19070        gen_r6_muldiv(ctx, R6_OPC_MUH, rd, rs, rt);
19071        break;
19072    case NM_MULU:
19073        gen_r6_muldiv(ctx, R6_OPC_MULU, rd, rs, rt);
19074        break;
19075    case NM_MUHU:
19076        gen_r6_muldiv(ctx, R6_OPC_MUHU, rd, rs, rt);
19077        break;
19078    case NM_DIV:
19079        gen_r6_muldiv(ctx, R6_OPC_DIV, rd, rs, rt);
19080        break;
19081    case NM_MOD:
19082        gen_r6_muldiv(ctx, R6_OPC_MOD, rd, rs, rt);
19083        break;
19084    case NM_DIVU:
19085        gen_r6_muldiv(ctx, R6_OPC_DIVU, rd, rs, rt);
19086        break;
19087    case NM_MODU:
19088        gen_r6_muldiv(ctx, R6_OPC_MODU, rd, rs, rt);
19089        break;
19090#ifndef CONFIG_USER_ONLY
19091    case NM_MFC0:
19092        check_cp0_enabled(ctx);
19093        if (rt == 0) {
19094            /* Treat as NOP. */
19095            break;
19096        }
19097        gen_mfc0(ctx, cpu_gpr[rt], rs, extract32(ctx->opcode, 11, 3));
19098        break;
19099    case NM_MTC0:
19100        check_cp0_enabled(ctx);
19101        {
19102            TCGv t0 = tcg_temp_new();
19103
19104            gen_load_gpr(t0, rt);
19105            gen_mtc0(ctx, t0, rs, extract32(ctx->opcode, 11, 3));
19106            tcg_temp_free(t0);
19107        }
19108        break;
19109    case NM_D_E_MT_VPE:
19110        {
19111            uint8_t sc = extract32(ctx->opcode, 10, 1);
19112            TCGv t0 = tcg_temp_new();
19113
19114            switch (sc) {
19115            case 0:
19116                if (rs == 1) {
19117                    /* DMT */
19118                    check_cp0_mt(ctx);
19119                    gen_helper_dmt(t0);
19120                    gen_store_gpr(t0, rt);
19121                } else if (rs == 0) {
19122                    /* DVPE */
19123                    check_cp0_mt(ctx);
19124                    gen_helper_dvpe(t0, cpu_env);
19125                    gen_store_gpr(t0, rt);
19126                } else {
19127                    generate_exception_end(ctx, EXCP_RI);
19128                }
19129                break;
19130            case 1:
19131                if (rs == 1) {
19132                    /* EMT */
19133                    check_cp0_mt(ctx);
19134                    gen_helper_emt(t0);
19135                    gen_store_gpr(t0, rt);
19136                } else if (rs == 0) {
19137                    /* EVPE */
19138                    check_cp0_mt(ctx);
19139                    gen_helper_evpe(t0, cpu_env);
19140                    gen_store_gpr(t0, rt);
19141                } else {
19142                    generate_exception_end(ctx, EXCP_RI);
19143                }
19144                break;
19145            }
19146
19147            tcg_temp_free(t0);
19148        }
19149        break;
19150    case NM_FORK:
19151        check_mt(ctx);
19152        {
19153            TCGv t0 = tcg_temp_new();
19154            TCGv t1 = tcg_temp_new();
19155
19156            gen_load_gpr(t0, rt);
19157            gen_load_gpr(t1, rs);
19158            gen_helper_fork(t0, t1);
19159            tcg_temp_free(t0);
19160            tcg_temp_free(t1);
19161        }
19162        break;
19163    case NM_MFTR:
19164    case NM_MFHTR:
19165        check_cp0_enabled(ctx);
19166        if (rd == 0) {
19167            /* Treat as NOP. */
19168            return;
19169        }
19170        gen_mftr(env, ctx, rs, rt, extract32(ctx->opcode, 10, 1),
19171                 extract32(ctx->opcode, 11, 5), extract32(ctx->opcode, 3, 1));
19172        break;
19173    case NM_MTTR:
19174    case NM_MTHTR:
19175        check_cp0_enabled(ctx);
19176        gen_mttr(env, ctx, rs, rt, extract32(ctx->opcode, 10, 1),
19177                 extract32(ctx->opcode, 11, 5), extract32(ctx->opcode, 3, 1));
19178        break;
19179    case NM_YIELD:
19180        check_mt(ctx);
19181        {
19182            TCGv t0 = tcg_temp_new();
19183
19184            gen_load_gpr(t0, rs);
19185            gen_helper_yield(t0, cpu_env, t0);
19186            gen_store_gpr(t0, rt);
19187            tcg_temp_free(t0);
19188        }
19189        break;
19190#endif
19191    default:
19192        generate_exception_end(ctx, EXCP_RI);
19193        break;
19194    }
19195}
19196
19197/* dsp */
19198static void gen_pool32axf_1_5_nanomips_insn(DisasContext *ctx, uint32_t opc,
19199                                            int ret, int v1, int v2)
19200{
19201    TCGv_i32 t0;
19202    TCGv v0_t;
19203    TCGv v1_t;
19204
19205    t0 = tcg_temp_new_i32();
19206
19207    v0_t = tcg_temp_new();
19208    v1_t = tcg_temp_new();
19209
19210    tcg_gen_movi_i32(t0, v2 >> 3);
19211
19212    gen_load_gpr(v0_t, ret);
19213    gen_load_gpr(v1_t, v1);
19214
19215    switch (opc) {
19216    case NM_MAQ_S_W_PHR:
19217        check_dsp(ctx);
19218        gen_helper_maq_s_w_phr(t0, v1_t, v0_t, cpu_env);
19219        break;
19220    case NM_MAQ_S_W_PHL:
19221        check_dsp(ctx);
19222        gen_helper_maq_s_w_phl(t0, v1_t, v0_t, cpu_env);
19223        break;
19224    case NM_MAQ_SA_W_PHR:
19225        check_dsp(ctx);
19226        gen_helper_maq_sa_w_phr(t0, v1_t, v0_t, cpu_env);
19227        break;
19228    case NM_MAQ_SA_W_PHL:
19229        check_dsp(ctx);
19230        gen_helper_maq_sa_w_phl(t0, v1_t, v0_t, cpu_env);
19231        break;
19232    default:
19233        generate_exception_end(ctx, EXCP_RI);
19234        break;
19235    }
19236
19237    tcg_temp_free_i32(t0);
19238
19239    tcg_temp_free(v0_t);
19240    tcg_temp_free(v1_t);
19241}
19242
19243
19244static void gen_pool32axf_1_nanomips_insn(DisasContext *ctx, uint32_t opc,
19245                                    int ret, int v1, int v2)
19246{
19247    int16_t imm;
19248    TCGv t0 = tcg_temp_new();
19249    TCGv t1 = tcg_temp_new();
19250    TCGv v0_t = tcg_temp_new();
19251
19252    gen_load_gpr(v0_t, v1);
19253
19254    switch (opc) {
19255    case NM_POOL32AXF_1_0:
19256        check_dsp(ctx);
19257        switch (extract32(ctx->opcode, 12, 2)) {
19258        case NM_MFHI:
19259            gen_HILO(ctx, OPC_MFHI, v2 >> 3, ret);
19260            break;
19261        case NM_MFLO:
19262            gen_HILO(ctx, OPC_MFLO, v2 >> 3, ret);
19263            break;
19264        case NM_MTHI:
19265            gen_HILO(ctx, OPC_MTHI, v2 >> 3, v1);
19266            break;
19267        case NM_MTLO:
19268            gen_HILO(ctx, OPC_MTLO, v2 >> 3, v1);
19269            break;
19270        }
19271        break;
19272    case NM_POOL32AXF_1_1:
19273        check_dsp(ctx);
19274        switch (extract32(ctx->opcode, 12, 2)) {
19275        case NM_MTHLIP:
19276            tcg_gen_movi_tl(t0, v2);
19277            gen_helper_mthlip(t0, v0_t, cpu_env);
19278            break;
19279        case NM_SHILOV:
19280            tcg_gen_movi_tl(t0, v2 >> 3);
19281            gen_helper_shilo(t0, v0_t, cpu_env);
19282            break;
19283        default:
19284            generate_exception_end(ctx, EXCP_RI);
19285            break;
19286        }
19287        break;
19288    case NM_POOL32AXF_1_3:
19289        check_dsp(ctx);
19290        imm = extract32(ctx->opcode, 14, 7);
19291        switch (extract32(ctx->opcode, 12, 2)) {
19292        case NM_RDDSP:
19293            tcg_gen_movi_tl(t0, imm);
19294            gen_helper_rddsp(t0, t0, cpu_env);
19295            gen_store_gpr(t0, ret);
19296            break;
19297        case NM_WRDSP:
19298            gen_load_gpr(t0, ret);
19299            tcg_gen_movi_tl(t1, imm);
19300            gen_helper_wrdsp(t0, t1, cpu_env);
19301            break;
19302        case NM_EXTP:
19303            tcg_gen_movi_tl(t0, v2 >> 3);
19304            tcg_gen_movi_tl(t1, v1);
19305            gen_helper_extp(t0, t0, t1, cpu_env);
19306            gen_store_gpr(t0, ret);
19307            break;
19308        case NM_EXTPDP:
19309            tcg_gen_movi_tl(t0, v2 >> 3);
19310            tcg_gen_movi_tl(t1, v1);
19311            gen_helper_extpdp(t0, t0, t1, cpu_env);
19312            gen_store_gpr(t0, ret);
19313            break;
19314        }
19315        break;
19316    case NM_POOL32AXF_1_4:
19317        check_dsp(ctx);
19318        tcg_gen_movi_tl(t0, v2 >> 2);
19319        switch (extract32(ctx->opcode, 12, 1)) {
19320        case NM_SHLL_QB:
19321            gen_helper_shll_qb(t0, t0, v0_t, cpu_env);
19322            gen_store_gpr(t0, ret);
19323            break;
19324        case NM_SHRL_QB:
19325            gen_helper_shrl_qb(t0, t0, v0_t);
19326            gen_store_gpr(t0, ret);
19327            break;
19328        }
19329        break;
19330    case NM_POOL32AXF_1_5:
19331        opc = extract32(ctx->opcode, 12, 2);
19332        gen_pool32axf_1_5_nanomips_insn(ctx, opc, ret, v1, v2);
19333        break;
19334    case NM_POOL32AXF_1_7:
19335        check_dsp(ctx);
19336        tcg_gen_movi_tl(t0, v2 >> 3);
19337        tcg_gen_movi_tl(t1, v1);
19338        switch (extract32(ctx->opcode, 12, 2)) {
19339        case NM_EXTR_W:
19340            gen_helper_extr_w(t0, t0, t1, cpu_env);
19341            gen_store_gpr(t0, ret);
19342            break;
19343        case NM_EXTR_R_W:
19344            gen_helper_extr_r_w(t0, t0, t1, cpu_env);
19345            gen_store_gpr(t0, ret);
19346            break;
19347        case NM_EXTR_RS_W:
19348            gen_helper_extr_rs_w(t0, t0, t1, cpu_env);
19349            gen_store_gpr(t0, ret);
19350            break;
19351        case NM_EXTR_S_H:
19352            gen_helper_extr_s_h(t0, t0, t1, cpu_env);
19353            gen_store_gpr(t0, ret);
19354            break;
19355        }
19356        break;
19357    default:
19358        generate_exception_end(ctx, EXCP_RI);
19359        break;
19360    }
19361
19362    tcg_temp_free(t0);
19363    tcg_temp_free(t1);
19364    tcg_temp_free(v0_t);
19365}
19366
19367static void gen_pool32axf_2_multiply(DisasContext *ctx, uint32_t opc,
19368                                    TCGv v0, TCGv v1, int rd)
19369{
19370    TCGv_i32 t0;
19371
19372    t0 = tcg_temp_new_i32();
19373
19374    tcg_gen_movi_i32(t0, rd >> 3);
19375
19376    switch (opc) {
19377    case NM_POOL32AXF_2_0_7:
19378        switch (extract32(ctx->opcode, 9, 3)) {
19379        case NM_DPA_W_PH:
19380            check_dsp_r2(ctx);
19381            gen_helper_dpa_w_ph(t0, v1, v0, cpu_env);
19382            break;
19383        case NM_DPAQ_S_W_PH:
19384            check_dsp(ctx);
19385            gen_helper_dpaq_s_w_ph(t0, v1, v0, cpu_env);
19386            break;
19387        case NM_DPS_W_PH:
19388            check_dsp_r2(ctx);
19389            gen_helper_dps_w_ph(t0, v1, v0, cpu_env);
19390            break;
19391        case NM_DPSQ_S_W_PH:
19392            check_dsp(ctx);
19393            gen_helper_dpsq_s_w_ph(t0, v1, v0, cpu_env);
19394            break;
19395        default:
19396            generate_exception_end(ctx, EXCP_RI);
19397            break;
19398        }
19399        break;
19400    case NM_POOL32AXF_2_8_15:
19401        switch (extract32(ctx->opcode, 9, 3)) {
19402        case NM_DPAX_W_PH:
19403            check_dsp_r2(ctx);
19404            gen_helper_dpax_w_ph(t0, v0, v1, cpu_env);
19405            break;
19406        case NM_DPAQ_SA_L_W:
19407            check_dsp(ctx);
19408            gen_helper_dpaq_sa_l_w(t0, v0, v1, cpu_env);
19409            break;
19410        case NM_DPSX_W_PH:
19411            check_dsp_r2(ctx);
19412            gen_helper_dpsx_w_ph(t0, v0, v1, cpu_env);
19413            break;
19414        case NM_DPSQ_SA_L_W:
19415            check_dsp(ctx);
19416            gen_helper_dpsq_sa_l_w(t0, v0, v1, cpu_env);
19417            break;
19418        default:
19419            generate_exception_end(ctx, EXCP_RI);
19420            break;
19421        }
19422        break;
19423    case NM_POOL32AXF_2_16_23:
19424        switch (extract32(ctx->opcode, 9, 3)) {
19425        case NM_DPAU_H_QBL:
19426            check_dsp(ctx);
19427            gen_helper_dpau_h_qbl(t0, v0, v1, cpu_env);
19428            break;
19429        case NM_DPAQX_S_W_PH:
19430            check_dsp_r2(ctx);
19431            gen_helper_dpaqx_s_w_ph(t0, v0, v1, cpu_env);
19432            break;
19433        case NM_DPSU_H_QBL:
19434            check_dsp(ctx);
19435            gen_helper_dpsu_h_qbl(t0, v0, v1, cpu_env);
19436            break;
19437        case NM_DPSQX_S_W_PH:
19438            check_dsp_r2(ctx);
19439            gen_helper_dpsqx_s_w_ph(t0, v0, v1, cpu_env);
19440            break;
19441        case NM_MULSA_W_PH:
19442            check_dsp_r2(ctx);
19443            gen_helper_mulsa_w_ph(t0, v0, v1, cpu_env);
19444            break;
19445        default:
19446            generate_exception_end(ctx, EXCP_RI);
19447            break;
19448        }
19449        break;
19450    case NM_POOL32AXF_2_24_31:
19451        switch (extract32(ctx->opcode, 9, 3)) {
19452        case NM_DPAU_H_QBR:
19453            check_dsp(ctx);
19454            gen_helper_dpau_h_qbr(t0, v1, v0, cpu_env);
19455            break;
19456        case NM_DPAQX_SA_W_PH:
19457            check_dsp_r2(ctx);
19458            gen_helper_dpaqx_sa_w_ph(t0, v1, v0, cpu_env);
19459            break;
19460        case NM_DPSU_H_QBR:
19461            check_dsp(ctx);
19462            gen_helper_dpsu_h_qbr(t0, v1, v0, cpu_env);
19463            break;
19464        case NM_DPSQX_SA_W_PH:
19465            check_dsp_r2(ctx);
19466            gen_helper_dpsqx_sa_w_ph(t0, v1, v0, cpu_env);
19467            break;
19468        case NM_MULSAQ_S_W_PH:
19469            check_dsp(ctx);
19470            gen_helper_mulsaq_s_w_ph(t0, v1, v0, cpu_env);
19471            break;
19472        default:
19473            generate_exception_end(ctx, EXCP_RI);
19474            break;
19475        }
19476        break;
19477    default:
19478        generate_exception_end(ctx, EXCP_RI);
19479        break;
19480    }
19481
19482    tcg_temp_free_i32(t0);
19483}
19484
19485static void gen_pool32axf_2_nanomips_insn(DisasContext *ctx, uint32_t opc,
19486                                          int rt, int rs, int rd)
19487{
19488    int ret = rt;
19489    TCGv t0 = tcg_temp_new();
19490    TCGv t1 = tcg_temp_new();
19491    TCGv v0_t = tcg_temp_new();
19492    TCGv v1_t = tcg_temp_new();
19493
19494    gen_load_gpr(v0_t, rt);
19495    gen_load_gpr(v1_t, rs);
19496
19497    switch (opc) {
19498    case NM_POOL32AXF_2_0_7:
19499        switch (extract32(ctx->opcode, 9, 3)) {
19500        case NM_DPA_W_PH:
19501        case NM_DPAQ_S_W_PH:
19502        case NM_DPS_W_PH:
19503        case NM_DPSQ_S_W_PH:
19504            gen_pool32axf_2_multiply(ctx, opc, v0_t, v1_t, rd);
19505            break;
19506        case NM_BALIGN:
19507            check_dsp_r2(ctx);
19508            if (rt != 0) {
19509                gen_load_gpr(t0, rs);
19510                rd &= 3;
19511                if (rd != 0 && rd != 2) {
19512                    tcg_gen_shli_tl(cpu_gpr[ret], cpu_gpr[ret], 8 * rd);
19513                    tcg_gen_ext32u_tl(t0, t0);
19514                    tcg_gen_shri_tl(t0, t0, 8 * (4 - rd));
19515                    tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
19516                }
19517                tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]);
19518            }
19519            break;
19520        case NM_MADD:
19521            check_dsp(ctx);
19522            {
19523                int acc = extract32(ctx->opcode, 14, 2);
19524                TCGv_i64 t2 = tcg_temp_new_i64();
19525                TCGv_i64 t3 = tcg_temp_new_i64();
19526
19527                gen_load_gpr(t0, rt);
19528                gen_load_gpr(t1, rs);
19529                tcg_gen_ext_tl_i64(t2, t0);
19530                tcg_gen_ext_tl_i64(t3, t1);
19531                tcg_gen_mul_i64(t2, t2, t3);
19532                tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
19533                tcg_gen_add_i64(t2, t2, t3);
19534                tcg_temp_free_i64(t3);
19535                gen_move_low32(cpu_LO[acc], t2);
19536                gen_move_high32(cpu_HI[acc], t2);
19537                tcg_temp_free_i64(t2);
19538            }
19539            break;
19540        case NM_MULT:
19541            check_dsp(ctx);
19542            {
19543                int acc = extract32(ctx->opcode, 14, 2);
19544                TCGv_i32 t2 = tcg_temp_new_i32();
19545                TCGv_i32 t3 = tcg_temp_new_i32();
19546
19547                gen_load_gpr(t0, rs);
19548                gen_load_gpr(t1, rt);
19549                tcg_gen_trunc_tl_i32(t2, t0);
19550                tcg_gen_trunc_tl_i32(t3, t1);
19551                tcg_gen_muls2_i32(t2, t3, t2, t3);
19552                tcg_gen_ext_i32_tl(cpu_LO[acc], t2);
19553                tcg_gen_ext_i32_tl(cpu_HI[acc], t3);
19554                tcg_temp_free_i32(t2);
19555                tcg_temp_free_i32(t3);
19556            }
19557            break;
19558        case NM_EXTRV_W:
19559            check_dsp(ctx);
19560            gen_load_gpr(v1_t, rs);
19561            tcg_gen_movi_tl(t0, rd >> 3);
19562            gen_helper_extr_w(t0, t0, v1_t, cpu_env);
19563            gen_store_gpr(t0, ret);
19564            break;
19565        }
19566        break;
19567    case NM_POOL32AXF_2_8_15:
19568        switch (extract32(ctx->opcode, 9, 3)) {
19569        case NM_DPAX_W_PH:
19570        case NM_DPAQ_SA_L_W:
19571        case NM_DPSX_W_PH:
19572        case NM_DPSQ_SA_L_W:
19573            gen_pool32axf_2_multiply(ctx, opc, v0_t, v1_t, rd);
19574            break;
19575        case NM_MADDU:
19576            check_dsp(ctx);
19577            {
19578                int acc = extract32(ctx->opcode, 14, 2);
19579                TCGv_i64 t2 = tcg_temp_new_i64();
19580                TCGv_i64 t3 = tcg_temp_new_i64();
19581
19582                gen_load_gpr(t0, rs);
19583                gen_load_gpr(t1, rt);
19584                tcg_gen_ext32u_tl(t0, t0);
19585                tcg_gen_ext32u_tl(t1, t1);
19586                tcg_gen_extu_tl_i64(t2, t0);
19587                tcg_gen_extu_tl_i64(t3, t1);
19588                tcg_gen_mul_i64(t2, t2, t3);
19589                tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
19590                tcg_gen_add_i64(t2, t2, t3);
19591                tcg_temp_free_i64(t3);
19592                gen_move_low32(cpu_LO[acc], t2);
19593                gen_move_high32(cpu_HI[acc], t2);
19594                tcg_temp_free_i64(t2);
19595            }
19596            break;
19597        case NM_MULTU:
19598            check_dsp(ctx);
19599            {
19600                int acc = extract32(ctx->opcode, 14, 2);
19601                TCGv_i32 t2 = tcg_temp_new_i32();
19602                TCGv_i32 t3 = tcg_temp_new_i32();
19603
19604                gen_load_gpr(t0, rs);
19605                gen_load_gpr(t1, rt);
19606                tcg_gen_trunc_tl_i32(t2, t0);
19607                tcg_gen_trunc_tl_i32(t3, t1);
19608                tcg_gen_mulu2_i32(t2, t3, t2, t3);
19609                tcg_gen_ext_i32_tl(cpu_LO[acc], t2);
19610                tcg_gen_ext_i32_tl(cpu_HI[acc], t3);
19611                tcg_temp_free_i32(t2);
19612                tcg_temp_free_i32(t3);
19613            }
19614            break;
19615        case NM_EXTRV_R_W:
19616            check_dsp(ctx);
19617            tcg_gen_movi_tl(t0, rd >> 3);
19618            gen_helper_extr_r_w(t0, t0, v1_t, cpu_env);
19619            gen_store_gpr(t0, ret);
19620            break;
19621        default:
19622            generate_exception_end(ctx, EXCP_RI);
19623            break;
19624        }
19625        break;
19626    case NM_POOL32AXF_2_16_23:
19627        switch (extract32(ctx->opcode, 9, 3)) {
19628        case NM_DPAU_H_QBL:
19629        case NM_DPAQX_S_W_PH:
19630        case NM_DPSU_H_QBL:
19631        case NM_DPSQX_S_W_PH:
19632        case NM_MULSA_W_PH:
19633            gen_pool32axf_2_multiply(ctx, opc, v0_t, v1_t, rd);
19634            break;
19635        case NM_EXTPV:
19636            check_dsp(ctx);
19637            tcg_gen_movi_tl(t0, rd >> 3);
19638            gen_helper_extp(t0, t0, v1_t, cpu_env);
19639            gen_store_gpr(t0, ret);
19640            break;
19641        case NM_MSUB:
19642            check_dsp(ctx);
19643            {
19644                int acc = extract32(ctx->opcode, 14, 2);
19645                TCGv_i64 t2 = tcg_temp_new_i64();
19646                TCGv_i64 t3 = tcg_temp_new_i64();
19647
19648                gen_load_gpr(t0, rs);
19649                gen_load_gpr(t1, rt);
19650                tcg_gen_ext_tl_i64(t2, t0);
19651                tcg_gen_ext_tl_i64(t3, t1);
19652                tcg_gen_mul_i64(t2, t2, t3);
19653                tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
19654                tcg_gen_sub_i64(t2, t3, t2);
19655                tcg_temp_free_i64(t3);
19656                gen_move_low32(cpu_LO[acc], t2);
19657                gen_move_high32(cpu_HI[acc], t2);
19658                tcg_temp_free_i64(t2);
19659            }
19660            break;
19661        case NM_EXTRV_RS_W:
19662            check_dsp(ctx);
19663            tcg_gen_movi_tl(t0, rd >> 3);
19664            gen_helper_extr_rs_w(t0, t0, v1_t, cpu_env);
19665            gen_store_gpr(t0, ret);
19666            break;
19667        }
19668        break;
19669    case NM_POOL32AXF_2_24_31:
19670        switch (extract32(ctx->opcode, 9, 3)) {
19671        case NM_DPAU_H_QBR:
19672        case NM_DPAQX_SA_W_PH:
19673        case NM_DPSU_H_QBR:
19674        case NM_DPSQX_SA_W_PH:
19675        case NM_MULSAQ_S_W_PH:
19676            gen_pool32axf_2_multiply(ctx, opc, v0_t, v1_t, rd);
19677            break;
19678        case NM_EXTPDPV:
19679            check_dsp(ctx);
19680            tcg_gen_movi_tl(t0, rd >> 3);
19681            gen_helper_extpdp(t0, t0, v1_t, cpu_env);
19682            gen_store_gpr(t0, ret);
19683            break;
19684        case NM_MSUBU:
19685            check_dsp(ctx);
19686            {
19687                int acc = extract32(ctx->opcode, 14, 2);
19688                TCGv_i64 t2 = tcg_temp_new_i64();
19689                TCGv_i64 t3 = tcg_temp_new_i64();
19690
19691                gen_load_gpr(t0, rs);
19692                gen_load_gpr(t1, rt);
19693                tcg_gen_ext32u_tl(t0, t0);
19694                tcg_gen_ext32u_tl(t1, t1);
19695                tcg_gen_extu_tl_i64(t2, t0);
19696                tcg_gen_extu_tl_i64(t3, t1);
19697                tcg_gen_mul_i64(t2, t2, t3);
19698                tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
19699                tcg_gen_sub_i64(t2, t3, t2);
19700                tcg_temp_free_i64(t3);
19701                gen_move_low32(cpu_LO[acc], t2);
19702                gen_move_high32(cpu_HI[acc], t2);
19703                tcg_temp_free_i64(t2);
19704            }
19705            break;
19706        case NM_EXTRV_S_H:
19707            check_dsp(ctx);
19708            tcg_gen_movi_tl(t0, rd >> 3);
19709            gen_helper_extr_s_h(t0, t0, v0_t, cpu_env);
19710            gen_store_gpr(t0, ret);
19711            break;
19712        }
19713        break;
19714    default:
19715        generate_exception_end(ctx, EXCP_RI);
19716        break;
19717    }
19718
19719    tcg_temp_free(t0);
19720    tcg_temp_free(t1);
19721
19722    tcg_temp_free(v0_t);
19723    tcg_temp_free(v1_t);
19724}
19725
19726static void gen_pool32axf_4_nanomips_insn(DisasContext *ctx, uint32_t opc,
19727                                          int rt, int rs)
19728{
19729    int ret = rt;
19730    TCGv t0 = tcg_temp_new();
19731    TCGv v0_t = tcg_temp_new();
19732
19733    gen_load_gpr(v0_t, rs);
19734
19735    switch (opc) {
19736    case NM_ABSQ_S_QB:
19737        check_dsp_r2(ctx);
19738        gen_helper_absq_s_qb(v0_t, v0_t, cpu_env);
19739        gen_store_gpr(v0_t, ret);
19740        break;
19741    case NM_ABSQ_S_PH:
19742        check_dsp(ctx);
19743        gen_helper_absq_s_ph(v0_t, v0_t, cpu_env);
19744        gen_store_gpr(v0_t, ret);
19745        break;
19746    case NM_ABSQ_S_W:
19747        check_dsp(ctx);
19748        gen_helper_absq_s_w(v0_t, v0_t, cpu_env);
19749        gen_store_gpr(v0_t, ret);
19750        break;
19751    case NM_PRECEQ_W_PHL:
19752        check_dsp(ctx);
19753        tcg_gen_andi_tl(v0_t, v0_t, 0xFFFF0000);
19754        tcg_gen_ext32s_tl(v0_t, v0_t);
19755        gen_store_gpr(v0_t, ret);
19756        break;
19757    case NM_PRECEQ_W_PHR:
19758        check_dsp(ctx);
19759        tcg_gen_andi_tl(v0_t, v0_t, 0x0000FFFF);
19760        tcg_gen_shli_tl(v0_t, v0_t, 16);
19761        tcg_gen_ext32s_tl(v0_t, v0_t);
19762        gen_store_gpr(v0_t, ret);
19763        break;
19764    case NM_PRECEQU_PH_QBL:
19765        check_dsp(ctx);
19766        gen_helper_precequ_ph_qbl(v0_t, v0_t);
19767        gen_store_gpr(v0_t, ret);
19768        break;
19769    case NM_PRECEQU_PH_QBR:
19770        check_dsp(ctx);
19771        gen_helper_precequ_ph_qbr(v0_t, v0_t);
19772        gen_store_gpr(v0_t, ret);
19773        break;
19774    case NM_PRECEQU_PH_QBLA:
19775        check_dsp(ctx);
19776        gen_helper_precequ_ph_qbla(v0_t, v0_t);
19777        gen_store_gpr(v0_t, ret);
19778        break;
19779    case NM_PRECEQU_PH_QBRA:
19780        check_dsp(ctx);
19781        gen_helper_precequ_ph_qbra(v0_t, v0_t);
19782        gen_store_gpr(v0_t, ret);
19783        break;
19784    case NM_PRECEU_PH_QBL:
19785        check_dsp(ctx);
19786        gen_helper_preceu_ph_qbl(v0_t, v0_t);
19787        gen_store_gpr(v0_t, ret);
19788        break;
19789    case NM_PRECEU_PH_QBR:
19790        check_dsp(ctx);
19791        gen_helper_preceu_ph_qbr(v0_t, v0_t);
19792        gen_store_gpr(v0_t, ret);
19793        break;
19794    case NM_PRECEU_PH_QBLA:
19795        check_dsp(ctx);
19796        gen_helper_preceu_ph_qbla(v0_t, v0_t);
19797        gen_store_gpr(v0_t, ret);
19798        break;
19799    case NM_PRECEU_PH_QBRA:
19800        check_dsp(ctx);
19801        gen_helper_preceu_ph_qbra(v0_t, v0_t);
19802        gen_store_gpr(v0_t, ret);
19803        break;
19804    case NM_REPLV_PH:
19805        check_dsp(ctx);
19806        tcg_gen_ext16u_tl(v0_t, v0_t);
19807        tcg_gen_shli_tl(t0, v0_t, 16);
19808        tcg_gen_or_tl(v0_t, v0_t, t0);
19809        tcg_gen_ext32s_tl(v0_t, v0_t);
19810        gen_store_gpr(v0_t, ret);
19811        break;
19812    case NM_REPLV_QB:
19813        check_dsp(ctx);
19814        tcg_gen_ext8u_tl(v0_t, v0_t);
19815        tcg_gen_shli_tl(t0, v0_t, 8);
19816        tcg_gen_or_tl(v0_t, v0_t, t0);
19817        tcg_gen_shli_tl(t0, v0_t, 16);
19818        tcg_gen_or_tl(v0_t, v0_t, t0);
19819        tcg_gen_ext32s_tl(v0_t, v0_t);
19820        gen_store_gpr(v0_t, ret);
19821        break;
19822    case NM_BITREV:
19823        check_dsp(ctx);
19824        gen_helper_bitrev(v0_t, v0_t);
19825        gen_store_gpr(v0_t, ret);
19826        break;
19827    case NM_INSV:
19828        check_dsp(ctx);
19829        {
19830            TCGv tv0 = tcg_temp_new();
19831
19832            gen_load_gpr(tv0, rt);
19833            gen_helper_insv(v0_t, cpu_env, v0_t, tv0);
19834            gen_store_gpr(v0_t, ret);
19835            tcg_temp_free(tv0);
19836        }
19837        break;
19838    case NM_RADDU_W_QB:
19839        check_dsp(ctx);
19840        gen_helper_raddu_w_qb(v0_t, v0_t);
19841        gen_store_gpr(v0_t, ret);
19842        break;
19843    case NM_BITSWAP:
19844        gen_bitswap(ctx, OPC_BITSWAP, ret, rs);
19845        break;
19846    case NM_CLO:
19847        check_nms(ctx);
19848        gen_cl(ctx, OPC_CLO, ret, rs);
19849        break;
19850    case NM_CLZ:
19851        check_nms(ctx);
19852        gen_cl(ctx, OPC_CLZ, ret, rs);
19853        break;
19854    case NM_WSBH:
19855        gen_bshfl(ctx, OPC_WSBH, ret, rs);
19856        break;
19857    default:
19858        generate_exception_end(ctx, EXCP_RI);
19859        break;
19860    }
19861
19862    tcg_temp_free(v0_t);
19863    tcg_temp_free(t0);
19864}
19865
19866static void gen_pool32axf_7_nanomips_insn(DisasContext *ctx, uint32_t opc,
19867                                          int rt, int rs, int rd)
19868{
19869    TCGv t0 = tcg_temp_new();
19870    TCGv rs_t = tcg_temp_new();
19871
19872    gen_load_gpr(rs_t, rs);
19873
19874    switch (opc) {
19875    case NM_SHRA_R_QB:
19876        check_dsp_r2(ctx);
19877        tcg_gen_movi_tl(t0, rd >> 2);
19878        switch (extract32(ctx->opcode, 12, 1)) {
19879        case 0:
19880            /* NM_SHRA_QB */
19881            gen_helper_shra_qb(t0, t0, rs_t);
19882            gen_store_gpr(t0, rt);
19883            break;
19884        case 1:
19885            /* NM_SHRA_R_QB */
19886            gen_helper_shra_r_qb(t0, t0, rs_t);
19887            gen_store_gpr(t0, rt);
19888            break;
19889        }
19890        break;
19891    case NM_SHRL_PH:
19892        check_dsp_r2(ctx);
19893        tcg_gen_movi_tl(t0, rd >> 1);
19894        gen_helper_shrl_ph(t0, t0, rs_t);
19895        gen_store_gpr(t0, rt);
19896        break;
19897    case NM_REPL_QB:
19898        check_dsp(ctx);
19899        {
19900            int16_t imm;
19901            target_long result;
19902            imm = extract32(ctx->opcode, 13, 8);
19903            result = (uint32_t)imm << 24 |
19904                     (uint32_t)imm << 16 |
19905                     (uint32_t)imm << 8  |
19906                     (uint32_t)imm;
19907            result = (int32_t)result;
19908            tcg_gen_movi_tl(t0, result);
19909            gen_store_gpr(t0, rt);
19910        }
19911        break;
19912    default:
19913        generate_exception_end(ctx, EXCP_RI);
19914        break;
19915    }
19916    tcg_temp_free(t0);
19917    tcg_temp_free(rs_t);
19918}
19919
19920
19921static void gen_pool32axf_nanomips_insn(CPUMIPSState *env, DisasContext *ctx)
19922{
19923    int rt = extract32(ctx->opcode, 21, 5);
19924    int rs = extract32(ctx->opcode, 16, 5);
19925    int rd = extract32(ctx->opcode, 11, 5);
19926
19927    switch (extract32(ctx->opcode, 6, 3)) {
19928    case NM_POOL32AXF_1:
19929        {
19930            int32_t op1 = extract32(ctx->opcode, 9, 3);
19931            gen_pool32axf_1_nanomips_insn(ctx, op1, rt, rs, rd);
19932        }
19933        break;
19934    case NM_POOL32AXF_2:
19935        {
19936            int32_t op1 = extract32(ctx->opcode, 12, 2);
19937            gen_pool32axf_2_nanomips_insn(ctx, op1, rt, rs, rd);
19938        }
19939        break;
19940    case NM_POOL32AXF_4:
19941        {
19942            int32_t op1 = extract32(ctx->opcode, 9, 7);
19943            gen_pool32axf_4_nanomips_insn(ctx, op1, rt, rs);
19944        }
19945        break;
19946    case NM_POOL32AXF_5:
19947        switch (extract32(ctx->opcode, 9, 7)) {
19948#ifndef CONFIG_USER_ONLY
19949        case NM_TLBP:
19950            gen_cp0(env, ctx, OPC_TLBP, 0, 0);
19951            break;
19952        case NM_TLBR:
19953            gen_cp0(env, ctx, OPC_TLBR, 0, 0);
19954            break;
19955        case NM_TLBWI:
19956            gen_cp0(env, ctx, OPC_TLBWI, 0, 0);
19957            break;
19958        case NM_TLBWR:
19959            gen_cp0(env, ctx, OPC_TLBWR, 0, 0);
19960            break;
19961        case NM_TLBINV:
19962            gen_cp0(env, ctx, OPC_TLBINV, 0, 0);
19963            break;
19964        case NM_TLBINVF:
19965            gen_cp0(env, ctx, OPC_TLBINVF, 0, 0);
19966            break;
19967        case NM_DI:
19968            check_cp0_enabled(ctx);
19969            {
19970                TCGv t0 = tcg_temp_new();
19971
19972                save_cpu_state(ctx, 1);
19973                gen_helper_di(t0, cpu_env);
19974                gen_store_gpr(t0, rt);
19975            /* Stop translation as we may have switched the execution mode */
19976                ctx->base.is_jmp = DISAS_STOP;
19977                tcg_temp_free(t0);
19978            }
19979            break;
19980        case NM_EI:
19981            check_cp0_enabled(ctx);
19982            {
19983                TCGv t0 = tcg_temp_new();
19984
19985                save_cpu_state(ctx, 1);
19986                gen_helper_ei(t0, cpu_env);
19987                gen_store_gpr(t0, rt);
19988            /* Stop translation as we may have switched the execution mode */
19989                ctx->base.is_jmp = DISAS_STOP;
19990                tcg_temp_free(t0);
19991            }
19992            break;
19993        case NM_RDPGPR:
19994            gen_load_srsgpr(rs, rt);
19995            break;
19996        case NM_WRPGPR:
19997            gen_store_srsgpr(rs, rt);
19998            break;
19999        case NM_WAIT:
20000            gen_cp0(env, ctx, OPC_WAIT, 0, 0);
20001            break;
20002        case NM_DERET:
20003            gen_cp0(env, ctx, OPC_DERET, 0, 0);
20004            break;
20005        case NM_ERETX:
20006            gen_cp0(env, ctx, OPC_ERET, 0, 0);
20007            break;
20008#endif
20009        default:
20010            generate_exception_end(ctx, EXCP_RI);
20011            break;
20012        }
20013        break;
20014    case NM_POOL32AXF_7:
20015        {
20016            int32_t op1 = extract32(ctx->opcode, 9, 3);
20017            gen_pool32axf_7_nanomips_insn(ctx, op1, rt, rs, rd);
20018        }
20019        break;
20020    default:
20021        generate_exception_end(ctx, EXCP_RI);
20022        break;
20023    }
20024}
20025
20026/* Immediate Value Compact Branches */
20027static void gen_compute_imm_branch(DisasContext *ctx, uint32_t opc,
20028                                   int rt, int32_t imm, int32_t offset)
20029{
20030    TCGCond cond;
20031    int bcond_compute = 0;
20032    TCGv t0 = tcg_temp_new();
20033    TCGv t1 = tcg_temp_new();
20034
20035    gen_load_gpr(t0, rt);
20036    tcg_gen_movi_tl(t1, imm);
20037    ctx->btarget = addr_add(ctx, ctx->base.pc_next + 4, offset);
20038
20039    /* Load needed operands and calculate btarget */
20040    switch (opc) {
20041    case NM_BEQIC:
20042        if (rt == 0 && imm == 0) {
20043            /* Unconditional branch */
20044        } else if (rt == 0 && imm != 0) {
20045            /* Treat as NOP */
20046            goto out;
20047        } else {
20048            bcond_compute = 1;
20049            cond = TCG_COND_EQ;
20050        }
20051        break;
20052    case NM_BBEQZC:
20053    case NM_BBNEZC:
20054        check_nms(ctx);
20055        if (imm >= 32 && !(ctx->hflags & MIPS_HFLAG_64)) {
20056            generate_exception_end(ctx, EXCP_RI);
20057            goto out;
20058        } else if (rt == 0 && opc == NM_BBEQZC) {
20059            /* Unconditional branch */
20060        } else if (rt == 0 && opc == NM_BBNEZC) {
20061            /* Treat as NOP */
20062            goto out;
20063        } else {
20064            tcg_gen_shri_tl(t0, t0, imm);
20065            tcg_gen_andi_tl(t0, t0, 1);
20066            tcg_gen_movi_tl(t1, 0);
20067            bcond_compute = 1;
20068            if (opc == NM_BBEQZC) {
20069                cond = TCG_COND_EQ;
20070            } else {
20071                cond = TCG_COND_NE;
20072            }
20073        }
20074        break;
20075    case NM_BNEIC:
20076        if (rt == 0 && imm == 0) {
20077            /* Treat as NOP */
20078            goto out;
20079        } else if (rt == 0 && imm != 0) {
20080            /* Unconditional branch */
20081        } else {
20082            bcond_compute = 1;
20083            cond = TCG_COND_NE;
20084        }
20085        break;
20086    case NM_BGEIC:
20087        if (rt == 0 && imm == 0) {
20088            /* Unconditional branch */
20089        } else  {
20090            bcond_compute = 1;
20091            cond = TCG_COND_GE;
20092        }
20093        break;
20094    case NM_BLTIC:
20095        bcond_compute = 1;
20096        cond = TCG_COND_LT;
20097        break;
20098    case NM_BGEIUC:
20099        if (rt == 0 && imm == 0) {
20100            /* Unconditional branch */
20101        } else  {
20102            bcond_compute = 1;
20103            cond = TCG_COND_GEU;
20104        }
20105        break;
20106    case NM_BLTIUC:
20107        bcond_compute = 1;
20108        cond = TCG_COND_LTU;
20109        break;
20110    default:
20111        MIPS_INVAL("Immediate Value Compact branch");
20112        generate_exception_end(ctx, EXCP_RI);
20113        goto out;
20114    }
20115
20116    /* branch completion */
20117    clear_branch_hflags(ctx);
20118    ctx->base.is_jmp = DISAS_NORETURN;
20119
20120    if (bcond_compute == 0) {
20121        /* Uncoditional compact branch */
20122        gen_goto_tb(ctx, 0, ctx->btarget);
20123    } else {
20124        /* Conditional compact branch */
20125        TCGLabel *fs = gen_new_label();
20126
20127        tcg_gen_brcond_tl(tcg_invert_cond(cond), t0, t1, fs);
20128
20129        gen_goto_tb(ctx, 1, ctx->btarget);
20130        gen_set_label(fs);
20131
20132        gen_goto_tb(ctx, 0, ctx->base.pc_next + 4);
20133    }
20134
20135out:
20136    tcg_temp_free(t0);
20137    tcg_temp_free(t1);
20138}
20139
20140/* P.BALRSC type nanoMIPS R6 branches: BALRSC and BRSC */
20141static void gen_compute_nanomips_pbalrsc_branch(DisasContext *ctx, int rs,
20142                                                int rt)
20143{
20144    TCGv t0 = tcg_temp_new();
20145    TCGv t1 = tcg_temp_new();
20146
20147    /* load rs */
20148    gen_load_gpr(t0, rs);
20149
20150    /* link */
20151    if (rt != 0) {
20152        tcg_gen_movi_tl(cpu_gpr[rt], ctx->base.pc_next + 4);
20153    }
20154
20155    /* calculate btarget */
20156    tcg_gen_shli_tl(t0, t0, 1);
20157    tcg_gen_movi_tl(t1, ctx->base.pc_next + 4);
20158    gen_op_addr_add(ctx, btarget, t1, t0);
20159
20160    /* branch completion */
20161    clear_branch_hflags(ctx);
20162    ctx->base.is_jmp = DISAS_NORETURN;
20163
20164    /* unconditional branch to register */
20165    tcg_gen_mov_tl(cpu_PC, btarget);
20166    tcg_gen_lookup_and_goto_ptr();
20167
20168    tcg_temp_free(t0);
20169    tcg_temp_free(t1);
20170}
20171
20172/* nanoMIPS Branches */
20173static void gen_compute_compact_branch_nm(DisasContext *ctx, uint32_t opc,
20174                                       int rs, int rt, int32_t offset)
20175{
20176    int bcond_compute = 0;
20177    TCGv t0 = tcg_temp_new();
20178    TCGv t1 = tcg_temp_new();
20179
20180    /* Load needed operands and calculate btarget */
20181    switch (opc) {
20182    /* compact branch */
20183    case OPC_BGEC:
20184    case OPC_BLTC:
20185        gen_load_gpr(t0, rs);
20186        gen_load_gpr(t1, rt);
20187        bcond_compute = 1;
20188        ctx->btarget = addr_add(ctx, ctx->base.pc_next + 4, offset);
20189        break;
20190    case OPC_BGEUC:
20191    case OPC_BLTUC:
20192        if (rs == 0 || rs == rt) {
20193            /* OPC_BLEZALC, OPC_BGEZALC */
20194            /* OPC_BGTZALC, OPC_BLTZALC */
20195            tcg_gen_movi_tl(cpu_gpr[31], ctx->base.pc_next + 4);
20196        }
20197        gen_load_gpr(t0, rs);
20198        gen_load_gpr(t1, rt);
20199        bcond_compute = 1;
20200        ctx->btarget = addr_add(ctx, ctx->base.pc_next + 4, offset);
20201        break;
20202    case OPC_BC:
20203        ctx->btarget = addr_add(ctx, ctx->base.pc_next + 4, offset);
20204        break;
20205    case OPC_BEQZC:
20206        if (rs != 0) {
20207            /* OPC_BEQZC, OPC_BNEZC */
20208            gen_load_gpr(t0, rs);
20209            bcond_compute = 1;
20210            ctx->btarget = addr_add(ctx, ctx->base.pc_next + 4, offset);
20211        } else {
20212            /* OPC_JIC, OPC_JIALC */
20213            TCGv tbase = tcg_temp_new();
20214            TCGv toffset = tcg_temp_new();
20215
20216            gen_load_gpr(tbase, rt);
20217            tcg_gen_movi_tl(toffset, offset);
20218            gen_op_addr_add(ctx, btarget, tbase, toffset);
20219            tcg_temp_free(tbase);
20220            tcg_temp_free(toffset);
20221        }
20222        break;
20223    default:
20224        MIPS_INVAL("Compact branch/jump");
20225        generate_exception_end(ctx, EXCP_RI);
20226        goto out;
20227    }
20228
20229    if (bcond_compute == 0) {
20230        /* Uncoditional compact branch */
20231        switch (opc) {
20232        case OPC_BC:
20233            gen_goto_tb(ctx, 0, ctx->btarget);
20234            break;
20235        default:
20236            MIPS_INVAL("Compact branch/jump");
20237            generate_exception_end(ctx, EXCP_RI);
20238            goto out;
20239        }
20240    } else {
20241        /* Conditional compact branch */
20242        TCGLabel *fs = gen_new_label();
20243
20244        switch (opc) {
20245        case OPC_BGEUC:
20246            if (rs == 0 && rt != 0) {
20247                /* OPC_BLEZALC */
20248                tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LE), t1, 0, fs);
20249            } else if (rs != 0 && rt != 0 && rs == rt) {
20250                /* OPC_BGEZALC */
20251                tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GE), t1, 0, fs);
20252            } else {
20253                /* OPC_BGEUC */
20254                tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_GEU), t0, t1, fs);
20255            }
20256            break;
20257        case OPC_BLTUC:
20258            if (rs == 0 && rt != 0) {
20259                /* OPC_BGTZALC */
20260                tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GT), t1, 0, fs);
20261            } else if (rs != 0 && rt != 0 && rs == rt) {
20262                /* OPC_BLTZALC */
20263                tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LT), t1, 0, fs);
20264            } else {
20265                /* OPC_BLTUC */
20266                tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_LTU), t0, t1, fs);
20267            }
20268            break;
20269        case OPC_BGEC:
20270            if (rs == 0 && rt != 0) {
20271                /* OPC_BLEZC */
20272                tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LE), t1, 0, fs);
20273            } else if (rs != 0 && rt != 0 && rs == rt) {
20274                /* OPC_BGEZC */
20275                tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GE), t1, 0, fs);
20276            } else {
20277                /* OPC_BGEC */
20278                tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_GE), t0, t1, fs);
20279            }
20280            break;
20281        case OPC_BLTC:
20282            if (rs == 0 && rt != 0) {
20283                /* OPC_BGTZC */
20284                tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GT), t1, 0, fs);
20285            } else if (rs != 0 && rt != 0 && rs == rt) {
20286                /* OPC_BLTZC */
20287                tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LT), t1, 0, fs);
20288            } else {
20289                /* OPC_BLTC */
20290                tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_LT), t0, t1, fs);
20291            }
20292            break;
20293        case OPC_BEQZC:
20294            tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_EQ), t0, 0, fs);
20295            break;
20296        default:
20297            MIPS_INVAL("Compact conditional branch/jump");
20298            generate_exception_end(ctx, EXCP_RI);
20299            goto out;
20300        }
20301
20302        /* branch completion */
20303        clear_branch_hflags(ctx);
20304        ctx->base.is_jmp = DISAS_NORETURN;
20305
20306        /* Generating branch here as compact branches don't have delay slot */
20307        gen_goto_tb(ctx, 1, ctx->btarget);
20308        gen_set_label(fs);
20309
20310        gen_goto_tb(ctx, 0, ctx->base.pc_next + 4);
20311    }
20312
20313out:
20314    tcg_temp_free(t0);
20315    tcg_temp_free(t1);
20316}
20317
20318
20319/* nanoMIPS CP1 Branches */
20320static void gen_compute_branch_cp1_nm(DisasContext *ctx, uint32_t op,
20321                                   int32_t ft, int32_t offset)
20322{
20323    target_ulong btarget;
20324    TCGv_i64 t0 = tcg_temp_new_i64();
20325
20326    gen_load_fpr64(ctx, t0, ft);
20327    tcg_gen_andi_i64(t0, t0, 1);
20328
20329    btarget = addr_add(ctx, ctx->base.pc_next + 4, offset);
20330
20331    switch (op) {
20332    case NM_BC1EQZC:
20333        tcg_gen_xori_i64(t0, t0, 1);
20334        ctx->hflags |= MIPS_HFLAG_BC;
20335        break;
20336    case NM_BC1NEZC:
20337        /* t0 already set */
20338        ctx->hflags |= MIPS_HFLAG_BC;
20339        break;
20340    default:
20341        MIPS_INVAL("cp1 cond branch");
20342        generate_exception_end(ctx, EXCP_RI);
20343        goto out;
20344    }
20345
20346    tcg_gen_trunc_i64_tl(bcond, t0);
20347
20348    ctx->btarget = btarget;
20349
20350out:
20351    tcg_temp_free_i64(t0);
20352}
20353
20354
20355static void gen_p_lsx(DisasContext *ctx, int rd, int rs, int rt)
20356{
20357    TCGv t0, t1;
20358    t0 = tcg_temp_new();
20359    t1 = tcg_temp_new();
20360
20361    gen_load_gpr(t0, rs);
20362    gen_load_gpr(t1, rt);
20363
20364    if ((extract32(ctx->opcode, 6, 1)) == 1) {
20365        /* PP.LSXS instructions require shifting */
20366        switch (extract32(ctx->opcode, 7, 4)) {
20367        case NM_SHXS:
20368            check_nms(ctx);
20369            /* fall through */
20370        case NM_LHXS:
20371        case NM_LHUXS:
20372            tcg_gen_shli_tl(t0, t0, 1);
20373            break;
20374        case NM_SWXS:
20375            check_nms(ctx);
20376            /* fall through */
20377        case NM_LWXS:
20378        case NM_LWC1XS:
20379        case NM_SWC1XS:
20380            tcg_gen_shli_tl(t0, t0, 2);
20381            break;
20382        case NM_LDC1XS:
20383        case NM_SDC1XS:
20384            tcg_gen_shli_tl(t0, t0, 3);
20385            break;
20386        }
20387    }
20388    gen_op_addr_add(ctx, t0, t0, t1);
20389
20390    switch (extract32(ctx->opcode, 7, 4)) {
20391    case NM_LBX:
20392        tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx,
20393                           MO_SB);
20394        gen_store_gpr(t0, rd);
20395        break;
20396    case NM_LHX:
20397    /*case NM_LHXS:*/
20398        tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx,
20399                           MO_TESW);
20400        gen_store_gpr(t0, rd);
20401        break;
20402    case NM_LWX:
20403    /*case NM_LWXS:*/
20404        tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx,
20405                           MO_TESL);
20406        gen_store_gpr(t0, rd);
20407        break;
20408    case NM_LBUX:
20409        tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx,
20410                           MO_UB);
20411        gen_store_gpr(t0, rd);
20412        break;
20413    case NM_LHUX:
20414    /*case NM_LHUXS:*/
20415        tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx,
20416                           MO_TEUW);
20417        gen_store_gpr(t0, rd);
20418        break;
20419    case NM_SBX:
20420        check_nms(ctx);
20421        gen_load_gpr(t1, rd);
20422        tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx,
20423                           MO_8);
20424        break;
20425    case NM_SHX:
20426    /*case NM_SHXS:*/
20427        check_nms(ctx);
20428        gen_load_gpr(t1, rd);
20429        tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx,
20430                           MO_TEUW);
20431        break;
20432    case NM_SWX:
20433    /*case NM_SWXS:*/
20434        check_nms(ctx);
20435        gen_load_gpr(t1, rd);
20436        tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx,
20437                           MO_TEUL);
20438        break;
20439    case NM_LWC1X:
20440    /*case NM_LWC1XS:*/
20441    case NM_LDC1X:
20442    /*case NM_LDC1XS:*/
20443    case NM_SWC1X:
20444    /*case NM_SWC1XS:*/
20445    case NM_SDC1X:
20446    /*case NM_SDC1XS:*/
20447        if (ctx->CP0_Config1 & (1 << CP0C1_FP)) {
20448            check_cp1_enabled(ctx);
20449            switch (extract32(ctx->opcode, 7, 4)) {
20450            case NM_LWC1X:
20451            /*case NM_LWC1XS:*/
20452                gen_flt_ldst(ctx, OPC_LWC1, rd, t0);
20453                break;
20454            case NM_LDC1X:
20455            /*case NM_LDC1XS:*/
20456                gen_flt_ldst(ctx, OPC_LDC1, rd, t0);
20457                break;
20458            case NM_SWC1X:
20459            /*case NM_SWC1XS:*/
20460                gen_flt_ldst(ctx, OPC_SWC1, rd, t0);
20461                break;
20462            case NM_SDC1X:
20463            /*case NM_SDC1XS:*/
20464                gen_flt_ldst(ctx, OPC_SDC1, rd, t0);
20465                break;
20466            }
20467        } else {
20468            generate_exception_err(ctx, EXCP_CpU, 1);
20469        }
20470        break;
20471    default:
20472        generate_exception_end(ctx, EXCP_RI);
20473        break;
20474    }
20475
20476    tcg_temp_free(t0);
20477    tcg_temp_free(t1);
20478}
20479
20480static void gen_pool32f_nanomips_insn(DisasContext *ctx)
20481{
20482    int rt, rs, rd;
20483
20484    rt = extract32(ctx->opcode, 21, 5);
20485    rs = extract32(ctx->opcode, 16, 5);
20486    rd = extract32(ctx->opcode, 11, 5);
20487
20488    if (!(ctx->CP0_Config1 & (1 << CP0C1_FP))) {
20489        generate_exception_end(ctx, EXCP_RI);
20490        return;
20491    }
20492    check_cp1_enabled(ctx);
20493    switch (extract32(ctx->opcode, 0, 3)) {
20494    case NM_POOL32F_0:
20495        switch (extract32(ctx->opcode, 3, 7)) {
20496        case NM_RINT_S:
20497            gen_farith(ctx, OPC_RINT_S, 0, rt, rs, 0);
20498            break;
20499        case NM_RINT_D:
20500            gen_farith(ctx, OPC_RINT_D, 0, rt, rs, 0);
20501            break;
20502        case NM_CLASS_S:
20503            gen_farith(ctx, OPC_CLASS_S, 0, rt, rs, 0);
20504            break;
20505        case NM_CLASS_D:
20506            gen_farith(ctx, OPC_CLASS_D, 0, rt, rs, 0);
20507            break;
20508        case NM_ADD_S:
20509            gen_farith(ctx, OPC_ADD_S, rt, rs, rd, 0);
20510            break;
20511        case NM_ADD_D:
20512            gen_farith(ctx, OPC_ADD_D, rt, rs, rd, 0);
20513            break;
20514        case NM_SUB_S:
20515            gen_farith(ctx, OPC_SUB_S, rt, rs, rd, 0);
20516            break;
20517        case NM_SUB_D:
20518            gen_farith(ctx, OPC_SUB_D, rt, rs, rd, 0);
20519            break;
20520        case NM_MUL_S:
20521            gen_farith(ctx, OPC_MUL_S, rt, rs, rd, 0);
20522            break;
20523        case NM_MUL_D:
20524            gen_farith(ctx, OPC_MUL_D, rt, rs, rd, 0);
20525            break;
20526        case NM_DIV_S:
20527            gen_farith(ctx, OPC_DIV_S, rt, rs, rd, 0);
20528            break;
20529        case NM_DIV_D:
20530            gen_farith(ctx, OPC_DIV_D, rt, rs, rd, 0);
20531            break;
20532        case NM_SELEQZ_S:
20533            gen_sel_s(ctx, OPC_SELEQZ_S, rd, rt, rs);
20534            break;
20535        case NM_SELEQZ_D:
20536            gen_sel_d(ctx, OPC_SELEQZ_D, rd, rt, rs);
20537            break;
20538        case NM_SELNEZ_S:
20539            gen_sel_s(ctx, OPC_SELNEZ_S, rd, rt, rs);
20540            break;
20541        case NM_SELNEZ_D:
20542            gen_sel_d(ctx, OPC_SELNEZ_D, rd, rt, rs);
20543            break;
20544        case NM_SEL_S:
20545            gen_sel_s(ctx, OPC_SEL_S, rd, rt, rs);
20546            break;
20547        case NM_SEL_D:
20548            gen_sel_d(ctx, OPC_SEL_D, rd, rt, rs);
20549            break;
20550        case NM_MADDF_S:
20551            gen_farith(ctx, OPC_MADDF_S, rt, rs, rd, 0);
20552            break;
20553        case NM_MADDF_D:
20554            gen_farith(ctx, OPC_MADDF_D, rt, rs, rd, 0);
20555            break;
20556        case NM_MSUBF_S:
20557            gen_farith(ctx, OPC_MSUBF_S, rt, rs, rd, 0);
20558            break;
20559        case NM_MSUBF_D:
20560            gen_farith(ctx, OPC_MSUBF_D, rt, rs, rd, 0);
20561            break;
20562        default:
20563            generate_exception_end(ctx, EXCP_RI);
20564            break;
20565        }
20566        break;
20567    case NM_POOL32F_3:
20568        switch (extract32(ctx->opcode, 3, 3)) {
20569        case NM_MIN_FMT:
20570            switch (extract32(ctx->opcode, 9, 1)) {
20571            case FMT_SDPS_S:
20572                gen_farith(ctx, OPC_MIN_S, rt, rs, rd, 0);
20573                break;
20574            case FMT_SDPS_D:
20575                gen_farith(ctx, OPC_MIN_D, rt, rs, rd, 0);
20576                break;
20577            }
20578            break;
20579        case NM_MAX_FMT:
20580            switch (extract32(ctx->opcode, 9, 1)) {
20581            case FMT_SDPS_S:
20582                gen_farith(ctx, OPC_MAX_S, rt, rs, rd, 0);
20583                break;
20584            case FMT_SDPS_D:
20585                gen_farith(ctx, OPC_MAX_D, rt, rs, rd, 0);
20586                break;
20587            }
20588            break;
20589        case NM_MINA_FMT:
20590            switch (extract32(ctx->opcode, 9, 1)) {
20591            case FMT_SDPS_S:
20592                gen_farith(ctx, OPC_MINA_S, rt, rs, rd, 0);
20593                break;
20594            case FMT_SDPS_D:
20595                gen_farith(ctx, OPC_MINA_D, rt, rs, rd, 0);
20596                break;
20597            }
20598            break;
20599        case NM_MAXA_FMT:
20600            switch (extract32(ctx->opcode, 9, 1)) {
20601            case FMT_SDPS_S:
20602                gen_farith(ctx, OPC_MAXA_S, rt, rs, rd, 0);
20603                break;
20604            case FMT_SDPS_D:
20605                gen_farith(ctx, OPC_MAXA_D, rt, rs, rd, 0);
20606                break;
20607            }
20608            break;
20609        case NM_POOL32FXF:
20610            switch (extract32(ctx->opcode, 6, 8)) {
20611            case NM_CFC1:
20612                gen_cp1(ctx, OPC_CFC1, rt, rs);
20613                break;
20614            case NM_CTC1:
20615                gen_cp1(ctx, OPC_CTC1, rt, rs);
20616                break;
20617            case NM_MFC1:
20618                gen_cp1(ctx, OPC_MFC1, rt, rs);
20619                break;
20620            case NM_MTC1:
20621                gen_cp1(ctx, OPC_MTC1, rt, rs);
20622                break;
20623            case NM_MFHC1:
20624                gen_cp1(ctx, OPC_MFHC1, rt, rs);
20625                break;
20626            case NM_MTHC1:
20627                gen_cp1(ctx, OPC_MTHC1, rt, rs);
20628                break;
20629            case NM_CVT_S_PL:
20630                gen_farith(ctx, OPC_CVT_S_PL, -1, rs, rt, 0);
20631                break;
20632            case NM_CVT_S_PU:
20633                gen_farith(ctx, OPC_CVT_S_PU, -1, rs, rt, 0);
20634                break;
20635            default:
20636                switch (extract32(ctx->opcode, 6, 9)) {
20637                case NM_CVT_L_S:
20638                    gen_farith(ctx, OPC_CVT_L_S, -1, rs, rt, 0);
20639                    break;
20640                case NM_CVT_L_D:
20641                    gen_farith(ctx, OPC_CVT_L_D, -1, rs, rt, 0);
20642                    break;
20643                case NM_CVT_W_S:
20644                    gen_farith(ctx, OPC_CVT_W_S, -1, rs, rt, 0);
20645                    break;
20646                case NM_CVT_W_D:
20647                    gen_farith(ctx, OPC_CVT_W_D, -1, rs, rt, 0);
20648                    break;
20649                case NM_RSQRT_S:
20650                    gen_farith(ctx, OPC_RSQRT_S, -1, rs, rt, 0);
20651                    break;
20652                case NM_RSQRT_D:
20653                    gen_farith(ctx, OPC_RSQRT_D, -1, rs, rt, 0);
20654                    break;
20655                case NM_SQRT_S:
20656                    gen_farith(ctx, OPC_SQRT_S, -1, rs, rt, 0);
20657                    break;
20658                case NM_SQRT_D:
20659                    gen_farith(ctx, OPC_SQRT_D, -1, rs, rt, 0);
20660                    break;
20661                case NM_RECIP_S:
20662                    gen_farith(ctx, OPC_RECIP_S, -1, rs, rt, 0);
20663                    break;
20664                case NM_RECIP_D:
20665                    gen_farith(ctx, OPC_RECIP_D, -1, rs, rt, 0);
20666                    break;
20667                case NM_FLOOR_L_S:
20668                    gen_farith(ctx, OPC_FLOOR_L_S, -1, rs, rt, 0);
20669                    break;
20670                case NM_FLOOR_L_D:
20671                    gen_farith(ctx, OPC_FLOOR_L_D, -1, rs, rt, 0);
20672                    break;
20673                case NM_FLOOR_W_S:
20674                    gen_farith(ctx, OPC_FLOOR_W_S, -1, rs, rt, 0);
20675                    break;
20676                case NM_FLOOR_W_D:
20677                    gen_farith(ctx, OPC_FLOOR_W_D, -1, rs, rt, 0);
20678                    break;
20679                case NM_CEIL_L_S:
20680                    gen_farith(ctx, OPC_CEIL_L_S, -1, rs, rt, 0);
20681                    break;
20682                case NM_CEIL_L_D:
20683                    gen_farith(ctx, OPC_CEIL_L_D, -1, rs, rt, 0);
20684                    break;
20685                case NM_CEIL_W_S:
20686                    gen_farith(ctx, OPC_CEIL_W_S, -1, rs, rt, 0);
20687                    break;
20688                case NM_CEIL_W_D:
20689                    gen_farith(ctx, OPC_CEIL_W_D, -1, rs, rt, 0);
20690                    break;
20691                case NM_TRUNC_L_S:
20692                    gen_farith(ctx, OPC_TRUNC_L_S, -1, rs, rt, 0);
20693                    break;
20694                case NM_TRUNC_L_D:
20695                    gen_farith(ctx, OPC_TRUNC_L_D, -1, rs, rt, 0);
20696                    break;
20697                case NM_TRUNC_W_S:
20698                    gen_farith(ctx, OPC_TRUNC_W_S, -1, rs, rt, 0);
20699                    break;
20700                case NM_TRUNC_W_D:
20701                    gen_farith(ctx, OPC_TRUNC_W_D, -1, rs, rt, 0);
20702                    break;
20703                case NM_ROUND_L_S:
20704                    gen_farith(ctx, OPC_ROUND_L_S, -1, rs, rt, 0);
20705                    break;
20706                case NM_ROUND_L_D:
20707                    gen_farith(ctx, OPC_ROUND_L_D, -1, rs, rt, 0);
20708                    break;
20709                case NM_ROUND_W_S:
20710                    gen_farith(ctx, OPC_ROUND_W_S, -1, rs, rt, 0);
20711                    break;
20712                case NM_ROUND_W_D:
20713                    gen_farith(ctx, OPC_ROUND_W_D, -1, rs, rt, 0);
20714                    break;
20715                case NM_MOV_S:
20716                    gen_farith(ctx, OPC_MOV_S, -1, rs, rt, 0);
20717                    break;
20718                case NM_MOV_D:
20719                    gen_farith(ctx, OPC_MOV_D, -1, rs, rt, 0);
20720                    break;
20721                case NM_ABS_S:
20722                    gen_farith(ctx, OPC_ABS_S, -1, rs, rt, 0);
20723                    break;
20724                case NM_ABS_D:
20725                    gen_farith(ctx, OPC_ABS_D, -1, rs, rt, 0);
20726                    break;
20727                case NM_NEG_S:
20728                    gen_farith(ctx, OPC_NEG_S, -1, rs, rt, 0);
20729                    break;
20730                case NM_NEG_D:
20731                    gen_farith(ctx, OPC_NEG_D, -1, rs, rt, 0);
20732                    break;
20733                case NM_CVT_D_S:
20734                    gen_farith(ctx, OPC_CVT_D_S, -1, rs, rt, 0);
20735                    break;
20736                case NM_CVT_D_W:
20737                    gen_farith(ctx, OPC_CVT_D_W, -1, rs, rt, 0);
20738                    break;
20739                case NM_CVT_D_L:
20740                    gen_farith(ctx, OPC_CVT_D_L, -1, rs, rt, 0);
20741                    break;
20742                case NM_CVT_S_D:
20743                    gen_farith(ctx, OPC_CVT_S_D, -1, rs, rt, 0);
20744                    break;
20745                case NM_CVT_S_W:
20746                    gen_farith(ctx, OPC_CVT_S_W, -1, rs, rt, 0);
20747                    break;
20748                case NM_CVT_S_L:
20749                    gen_farith(ctx, OPC_CVT_S_L, -1, rs, rt, 0);
20750                    break;
20751                default:
20752                    generate_exception_end(ctx, EXCP_RI);
20753                    break;
20754                }
20755                break;
20756            }
20757            break;
20758        }
20759        break;
20760    case NM_POOL32F_5:
20761        switch (extract32(ctx->opcode, 3, 3)) {
20762        case NM_CMP_CONDN_S:
20763            gen_r6_cmp_s(ctx, extract32(ctx->opcode, 6, 5), rt, rs, rd);
20764            break;
20765        case NM_CMP_CONDN_D:
20766            gen_r6_cmp_d(ctx, extract32(ctx->opcode, 6, 5), rt, rs, rd);
20767            break;
20768        default:
20769            generate_exception_end(ctx, EXCP_RI);
20770            break;
20771        }
20772        break;
20773    default:
20774        generate_exception_end(ctx, EXCP_RI);
20775        break;
20776    }
20777}
20778
20779static void gen_pool32a5_nanomips_insn(DisasContext *ctx, int opc,
20780                                       int rd, int rs, int rt)
20781{
20782    int ret = rd;
20783    TCGv t0 = tcg_temp_new();
20784    TCGv v1_t = tcg_temp_new();
20785    TCGv v2_t = tcg_temp_new();
20786
20787    gen_load_gpr(v1_t, rs);
20788    gen_load_gpr(v2_t, rt);
20789
20790    switch (opc) {
20791    case NM_CMP_EQ_PH:
20792        check_dsp(ctx);
20793        gen_helper_cmp_eq_ph(v1_t, v2_t, cpu_env);
20794        break;
20795    case NM_CMP_LT_PH:
20796        check_dsp(ctx);
20797        gen_helper_cmp_lt_ph(v1_t, v2_t, cpu_env);
20798        break;
20799    case NM_CMP_LE_PH:
20800        check_dsp(ctx);
20801        gen_helper_cmp_le_ph(v1_t, v2_t, cpu_env);
20802        break;
20803    case NM_CMPU_EQ_QB:
20804        check_dsp(ctx);
20805        gen_helper_cmpu_eq_qb(v1_t, v2_t, cpu_env);
20806        break;
20807    case NM_CMPU_LT_QB:
20808        check_dsp(ctx);
20809        gen_helper_cmpu_lt_qb(v1_t, v2_t, cpu_env);
20810        break;
20811    case NM_CMPU_LE_QB:
20812        check_dsp(ctx);
20813        gen_helper_cmpu_le_qb(v1_t, v2_t, cpu_env);
20814        break;
20815    case NM_CMPGU_EQ_QB:
20816        check_dsp(ctx);
20817        gen_helper_cmpgu_eq_qb(v1_t, v1_t, v2_t);
20818        gen_store_gpr(v1_t, ret);
20819        break;
20820    case NM_CMPGU_LT_QB:
20821        check_dsp(ctx);
20822        gen_helper_cmpgu_lt_qb(v1_t, v1_t, v2_t);
20823        gen_store_gpr(v1_t, ret);
20824        break;
20825    case NM_CMPGU_LE_QB:
20826        check_dsp(ctx);
20827        gen_helper_cmpgu_le_qb(v1_t, v1_t, v2_t);
20828        gen_store_gpr(v1_t, ret);
20829        break;
20830    case NM_CMPGDU_EQ_QB:
20831        check_dsp_r2(ctx);
20832        gen_helper_cmpgu_eq_qb(v1_t, v1_t, v2_t);
20833        tcg_gen_deposit_tl(cpu_dspctrl, cpu_dspctrl, v1_t, 24, 4);
20834        gen_store_gpr(v1_t, ret);
20835        break;
20836    case NM_CMPGDU_LT_QB:
20837        check_dsp_r2(ctx);
20838        gen_helper_cmpgu_lt_qb(v1_t, v1_t, v2_t);
20839        tcg_gen_deposit_tl(cpu_dspctrl, cpu_dspctrl, v1_t, 24, 4);
20840        gen_store_gpr(v1_t, ret);
20841        break;
20842    case NM_CMPGDU_LE_QB:
20843        check_dsp_r2(ctx);
20844        gen_helper_cmpgu_le_qb(v1_t, v1_t, v2_t);
20845        tcg_gen_deposit_tl(cpu_dspctrl, cpu_dspctrl, v1_t, 24, 4);
20846        gen_store_gpr(v1_t, ret);
20847        break;
20848    case NM_PACKRL_PH:
20849        check_dsp(ctx);
20850        gen_helper_packrl_ph(v1_t, v1_t, v2_t);
20851        gen_store_gpr(v1_t, ret);
20852        break;
20853    case NM_PICK_QB:
20854        check_dsp(ctx);
20855        gen_helper_pick_qb(v1_t, v1_t, v2_t, cpu_env);
20856        gen_store_gpr(v1_t, ret);
20857        break;
20858    case NM_PICK_PH:
20859        check_dsp(ctx);
20860        gen_helper_pick_ph(v1_t, v1_t, v2_t, cpu_env);
20861        gen_store_gpr(v1_t, ret);
20862        break;
20863    case NM_ADDQ_S_W:
20864        check_dsp(ctx);
20865        gen_helper_addq_s_w(v1_t, v1_t, v2_t, cpu_env);
20866        gen_store_gpr(v1_t, ret);
20867        break;
20868    case NM_SUBQ_S_W:
20869        check_dsp(ctx);
20870        gen_helper_subq_s_w(v1_t, v1_t, v2_t, cpu_env);
20871        gen_store_gpr(v1_t, ret);
20872        break;
20873    case NM_ADDSC:
20874        check_dsp(ctx);
20875        gen_helper_addsc(v1_t, v1_t, v2_t, cpu_env);
20876        gen_store_gpr(v1_t, ret);
20877        break;
20878    case NM_ADDWC:
20879        check_dsp(ctx);
20880        gen_helper_addwc(v1_t, v1_t, v2_t, cpu_env);
20881        gen_store_gpr(v1_t, ret);
20882        break;
20883    case NM_ADDQ_S_PH:
20884        check_dsp(ctx);
20885        switch (extract32(ctx->opcode, 10, 1)) {
20886        case 0:
20887            /* ADDQ_PH */
20888            gen_helper_addq_ph(v1_t, v1_t, v2_t, cpu_env);
20889            gen_store_gpr(v1_t, ret);
20890            break;
20891        case 1:
20892            /* ADDQ_S_PH */
20893            gen_helper_addq_s_ph(v1_t, v1_t, v2_t, cpu_env);
20894            gen_store_gpr(v1_t, ret);
20895            break;
20896        }
20897        break;
20898    case NM_ADDQH_R_PH:
20899        check_dsp_r2(ctx);
20900        switch (extract32(ctx->opcode, 10, 1)) {
20901        case 0:
20902            /* ADDQH_PH */
20903            gen_helper_addqh_ph(v1_t, v1_t, v2_t);
20904            gen_store_gpr(v1_t, ret);
20905            break;
20906        case 1:
20907            /* ADDQH_R_PH */
20908            gen_helper_addqh_r_ph(v1_t, v1_t, v2_t);
20909            gen_store_gpr(v1_t, ret);
20910            break;
20911        }
20912        break;
20913    case NM_ADDQH_R_W:
20914        check_dsp_r2(ctx);
20915        switch (extract32(ctx->opcode, 10, 1)) {
20916        case 0:
20917            /* ADDQH_W */
20918            gen_helper_addqh_w(v1_t, v1_t, v2_t);
20919            gen_store_gpr(v1_t, ret);
20920            break;
20921        case 1:
20922            /* ADDQH_R_W */
20923            gen_helper_addqh_r_w(v1_t, v1_t, v2_t);
20924            gen_store_gpr(v1_t, ret);
20925            break;
20926        }
20927        break;
20928    case NM_ADDU_S_QB:
20929        check_dsp(ctx);
20930        switch (extract32(ctx->opcode, 10, 1)) {
20931        case 0:
20932            /* ADDU_QB */
20933            gen_helper_addu_qb(v1_t, v1_t, v2_t, cpu_env);
20934            gen_store_gpr(v1_t, ret);
20935            break;
20936        case 1:
20937            /* ADDU_S_QB */
20938            gen_helper_addu_s_qb(v1_t, v1_t, v2_t, cpu_env);
20939            gen_store_gpr(v1_t, ret);
20940            break;
20941        }
20942        break;
20943    case NM_ADDU_S_PH:
20944        check_dsp_r2(ctx);
20945        switch (extract32(ctx->opcode, 10, 1)) {
20946        case 0:
20947            /* ADDU_PH */
20948            gen_helper_addu_ph(v1_t, v1_t, v2_t, cpu_env);
20949            gen_store_gpr(v1_t, ret);
20950            break;
20951        case 1:
20952            /* ADDU_S_PH */
20953            gen_helper_addu_s_ph(v1_t, v1_t, v2_t, cpu_env);
20954            gen_store_gpr(v1_t, ret);
20955            break;
20956        }
20957        break;
20958    case NM_ADDUH_R_QB:
20959        check_dsp_r2(ctx);
20960        switch (extract32(ctx->opcode, 10, 1)) {
20961        case 0:
20962            /* ADDUH_QB */
20963            gen_helper_adduh_qb(v1_t, v1_t, v2_t);
20964            gen_store_gpr(v1_t, ret);
20965            break;
20966        case 1:
20967            /* ADDUH_R_QB */
20968            gen_helper_adduh_r_qb(v1_t, v1_t, v2_t);
20969            gen_store_gpr(v1_t, ret);
20970            break;
20971        }
20972        break;
20973    case NM_SHRAV_R_PH:
20974        check_dsp(ctx);
20975        switch (extract32(ctx->opcode, 10, 1)) {
20976        case 0:
20977            /* SHRAV_PH */
20978            gen_helper_shra_ph(v1_t, v1_t, v2_t);
20979            gen_store_gpr(v1_t, ret);
20980            break;
20981        case 1:
20982            /* SHRAV_R_PH */
20983            gen_helper_shra_r_ph(v1_t, v1_t, v2_t);
20984            gen_store_gpr(v1_t, ret);
20985            break;
20986        }
20987        break;
20988    case NM_SHRAV_R_QB:
20989        check_dsp_r2(ctx);
20990        switch (extract32(ctx->opcode, 10, 1)) {
20991        case 0:
20992            /* SHRAV_QB */
20993            gen_helper_shra_qb(v1_t, v1_t, v2_t);
20994            gen_store_gpr(v1_t, ret);
20995            break;
20996        case 1:
20997            /* SHRAV_R_QB */
20998            gen_helper_shra_r_qb(v1_t, v1_t, v2_t);
20999            gen_store_gpr(v1_t, ret);
21000            break;
21001        }
21002        break;
21003    case NM_SUBQ_S_PH:
21004        check_dsp(ctx);
21005        switch (extract32(ctx->opcode, 10, 1)) {
21006        case 0:
21007            /* SUBQ_PH */
21008            gen_helper_subq_ph(v1_t, v1_t, v2_t, cpu_env);
21009            gen_store_gpr(v1_t, ret);
21010            break;
21011        case 1:
21012            /* SUBQ_S_PH */
21013            gen_helper_subq_s_ph(v1_t, v1_t, v2_t, cpu_env);
21014            gen_store_gpr(v1_t, ret);
21015            break;
21016        }
21017        break;
21018    case NM_SUBQH_R_PH:
21019        check_dsp_r2(ctx);
21020        switch (extract32(ctx->opcode, 10, 1)) {
21021        case 0:
21022            /* SUBQH_PH */
21023            gen_helper_subqh_ph(v1_t, v1_t, v2_t);
21024            gen_store_gpr(v1_t, ret);
21025            break;
21026        case 1:
21027            /* SUBQH_R_PH */
21028            gen_helper_subqh_r_ph(v1_t, v1_t, v2_t);
21029            gen_store_gpr(v1_t, ret);
21030            break;
21031        }
21032        break;
21033    case NM_SUBQH_R_W:
21034        check_dsp_r2(ctx);
21035        switch (extract32(ctx->opcode, 10, 1)) {
21036        case 0:
21037            /* SUBQH_W */
21038            gen_helper_subqh_w(v1_t, v1_t, v2_t);
21039            gen_store_gpr(v1_t, ret);
21040            break;
21041        case 1:
21042            /* SUBQH_R_W */
21043            gen_helper_subqh_r_w(v1_t, v1_t, v2_t);
21044            gen_store_gpr(v1_t, ret);
21045            break;
21046        }
21047        break;
21048    case NM_SUBU_S_QB:
21049        check_dsp(ctx);
21050        switch (extract32(ctx->opcode, 10, 1)) {
21051        case 0:
21052            /* SUBU_QB */
21053            gen_helper_subu_qb(v1_t, v1_t, v2_t, cpu_env);
21054            gen_store_gpr(v1_t, ret);
21055            break;
21056        case 1:
21057            /* SUBU_S_QB */
21058            gen_helper_subu_s_qb(v1_t, v1_t, v2_t, cpu_env);
21059            gen_store_gpr(v1_t, ret);
21060            break;
21061        }
21062        break;
21063    case NM_SUBU_S_PH:
21064        check_dsp_r2(ctx);
21065        switch (extract32(ctx->opcode, 10, 1)) {
21066        case 0:
21067            /* SUBU_PH */
21068            gen_helper_subu_ph(v1_t, v1_t, v2_t, cpu_env);
21069            gen_store_gpr(v1_t, ret);
21070            break;
21071        case 1:
21072            /* SUBU_S_PH */
21073            gen_helper_subu_s_ph(v1_t, v1_t, v2_t, cpu_env);
21074            gen_store_gpr(v1_t, ret);
21075            break;
21076        }
21077        break;
21078    case NM_SUBUH_R_QB:
21079        check_dsp_r2(ctx);
21080        switch (extract32(ctx->opcode, 10, 1)) {
21081        case 0:
21082            /* SUBUH_QB */
21083            gen_helper_subuh_qb(v1_t, v1_t, v2_t);
21084            gen_store_gpr(v1_t, ret);
21085            break;
21086        case 1:
21087            /* SUBUH_R_QB */
21088            gen_helper_subuh_r_qb(v1_t, v1_t, v2_t);
21089            gen_store_gpr(v1_t, ret);
21090            break;
21091        }
21092        break;
21093    case NM_SHLLV_S_PH:
21094        check_dsp(ctx);
21095        switch (extract32(ctx->opcode, 10, 1)) {
21096        case 0:
21097            /* SHLLV_PH */
21098            gen_helper_shll_ph(v1_t, v1_t, v2_t, cpu_env);
21099            gen_store_gpr(v1_t, ret);
21100            break;
21101        case 1:
21102            /* SHLLV_S_PH */
21103            gen_helper_shll_s_ph(v1_t, v1_t, v2_t, cpu_env);
21104            gen_store_gpr(v1_t, ret);
21105            break;
21106        }
21107        break;
21108    case NM_PRECR_SRA_R_PH_W:
21109        check_dsp_r2(ctx);
21110        switch (extract32(ctx->opcode, 10, 1)) {
21111        case 0:
21112            /* PRECR_SRA_PH_W */
21113            {
21114                TCGv_i32 sa_t = tcg_const_i32(rd);
21115                gen_helper_precr_sra_ph_w(v1_t, sa_t, v1_t,
21116                                          cpu_gpr[rt]);
21117                gen_store_gpr(v1_t, rt);
21118                tcg_temp_free_i32(sa_t);
21119            }
21120            break;
21121        case 1:
21122            /* PRECR_SRA_R_PH_W */
21123            {
21124                TCGv_i32 sa_t = tcg_const_i32(rd);
21125                gen_helper_precr_sra_r_ph_w(v1_t, sa_t, v1_t,
21126                                            cpu_gpr[rt]);
21127                gen_store_gpr(v1_t, rt);
21128                tcg_temp_free_i32(sa_t);
21129            }
21130            break;
21131       }
21132        break;
21133    case NM_MULEU_S_PH_QBL:
21134        check_dsp(ctx);
21135        gen_helper_muleu_s_ph_qbl(v1_t, v1_t, v2_t, cpu_env);
21136        gen_store_gpr(v1_t, ret);
21137        break;
21138    case NM_MULEU_S_PH_QBR:
21139        check_dsp(ctx);
21140        gen_helper_muleu_s_ph_qbr(v1_t, v1_t, v2_t, cpu_env);
21141        gen_store_gpr(v1_t, ret);
21142        break;
21143    case NM_MULQ_RS_PH:
21144        check_dsp(ctx);
21145        gen_helper_mulq_rs_ph(v1_t, v1_t, v2_t, cpu_env);
21146        gen_store_gpr(v1_t, ret);
21147        break;
21148    case NM_MULQ_S_PH:
21149        check_dsp_r2(ctx);
21150        gen_helper_mulq_s_ph(v1_t, v1_t, v2_t, cpu_env);
21151        gen_store_gpr(v1_t, ret);
21152        break;
21153    case NM_MULQ_RS_W:
21154        check_dsp_r2(ctx);
21155        gen_helper_mulq_rs_w(v1_t, v1_t, v2_t, cpu_env);
21156        gen_store_gpr(v1_t, ret);
21157        break;
21158    case NM_MULQ_S_W:
21159        check_dsp_r2(ctx);
21160        gen_helper_mulq_s_w(v1_t, v1_t, v2_t, cpu_env);
21161        gen_store_gpr(v1_t, ret);
21162        break;
21163    case NM_APPEND:
21164        check_dsp_r2(ctx);
21165        gen_load_gpr(t0, rs);
21166        if (rd != 0) {
21167            tcg_gen_deposit_tl(cpu_gpr[rt], t0, cpu_gpr[rt], rd, 32 - rd);
21168        }
21169        tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
21170        break;
21171    case NM_MODSUB:
21172        check_dsp(ctx);
21173        gen_helper_modsub(v1_t, v1_t, v2_t);
21174        gen_store_gpr(v1_t, ret);
21175        break;
21176    case NM_SHRAV_R_W:
21177        check_dsp(ctx);
21178        gen_helper_shra_r_w(v1_t, v1_t, v2_t);
21179        gen_store_gpr(v1_t, ret);
21180        break;
21181    case NM_SHRLV_PH:
21182        check_dsp_r2(ctx);
21183        gen_helper_shrl_ph(v1_t, v1_t, v2_t);
21184        gen_store_gpr(v1_t, ret);
21185        break;
21186    case NM_SHRLV_QB:
21187        check_dsp(ctx);
21188        gen_helper_shrl_qb(v1_t, v1_t, v2_t);
21189        gen_store_gpr(v1_t, ret);
21190        break;
21191    case NM_SHLLV_QB:
21192        check_dsp(ctx);
21193        gen_helper_shll_qb(v1_t, v1_t, v2_t, cpu_env);
21194        gen_store_gpr(v1_t, ret);
21195        break;
21196    case NM_SHLLV_S_W:
21197        check_dsp(ctx);
21198        gen_helper_shll_s_w(v1_t, v1_t, v2_t, cpu_env);
21199        gen_store_gpr(v1_t, ret);
21200        break;
21201    case NM_SHILO:
21202        check_dsp(ctx);
21203        {
21204            TCGv tv0 = tcg_temp_new();
21205            TCGv tv1 = tcg_temp_new();
21206            int16_t imm = extract32(ctx->opcode, 16, 7);
21207
21208            tcg_gen_movi_tl(tv0, rd >> 3);
21209            tcg_gen_movi_tl(tv1, imm);
21210            gen_helper_shilo(tv0, tv1, cpu_env);
21211        }
21212        break;
21213    case NM_MULEQ_S_W_PHL:
21214        check_dsp(ctx);
21215        gen_helper_muleq_s_w_phl(v1_t, v1_t, v2_t, cpu_env);
21216        gen_store_gpr(v1_t, ret);
21217        break;
21218    case NM_MULEQ_S_W_PHR:
21219        check_dsp(ctx);
21220        gen_helper_muleq_s_w_phr(v1_t, v1_t, v2_t, cpu_env);
21221        gen_store_gpr(v1_t, ret);
21222        break;
21223    case NM_MUL_S_PH:
21224        check_dsp_r2(ctx);
21225        switch (extract32(ctx->opcode, 10, 1)) {
21226        case 0:
21227            /* MUL_PH */
21228            gen_helper_mul_ph(v1_t, v1_t, v2_t, cpu_env);
21229            gen_store_gpr(v1_t, ret);
21230            break;
21231        case 1:
21232            /* MUL_S_PH */
21233            gen_helper_mul_s_ph(v1_t, v1_t, v2_t, cpu_env);
21234            gen_store_gpr(v1_t, ret);
21235            break;
21236        }
21237        break;
21238    case NM_PRECR_QB_PH:
21239        check_dsp_r2(ctx);
21240        gen_helper_precr_qb_ph(v1_t, v1_t, v2_t);
21241        gen_store_gpr(v1_t, ret);
21242        break;
21243    case NM_PRECRQ_QB_PH:
21244        check_dsp(ctx);
21245        gen_helper_precrq_qb_ph(v1_t, v1_t, v2_t);
21246        gen_store_gpr(v1_t, ret);
21247        break;
21248    case NM_PRECRQ_PH_W:
21249        check_dsp(ctx);
21250        gen_helper_precrq_ph_w(v1_t, v1_t, v2_t);
21251        gen_store_gpr(v1_t, ret);
21252        break;
21253    case NM_PRECRQ_RS_PH_W:
21254        check_dsp(ctx);
21255        gen_helper_precrq_rs_ph_w(v1_t, v1_t, v2_t, cpu_env);
21256        gen_store_gpr(v1_t, ret);
21257        break;
21258    case NM_PRECRQU_S_QB_PH:
21259        check_dsp(ctx);
21260        gen_helper_precrqu_s_qb_ph(v1_t, v1_t, v2_t, cpu_env);
21261        gen_store_gpr(v1_t, ret);
21262        break;
21263    case NM_SHRA_R_W:
21264        check_dsp(ctx);
21265        tcg_gen_movi_tl(t0, rd);
21266        gen_helper_shra_r_w(v1_t, t0, v1_t);
21267        gen_store_gpr(v1_t, rt);
21268        break;
21269    case NM_SHRA_R_PH:
21270        check_dsp(ctx);
21271        tcg_gen_movi_tl(t0, rd >> 1);
21272        switch (extract32(ctx->opcode, 10, 1)) {
21273        case 0:
21274            /* SHRA_PH */
21275            gen_helper_shra_ph(v1_t, t0, v1_t);
21276            gen_store_gpr(v1_t, rt);
21277            break;
21278        case 1:
21279            /* SHRA_R_PH */
21280            gen_helper_shra_r_ph(v1_t, t0, v1_t);
21281            gen_store_gpr(v1_t, rt);
21282            break;
21283        }
21284        break;
21285    case NM_SHLL_S_PH:
21286        check_dsp(ctx);
21287        tcg_gen_movi_tl(t0, rd >> 1);
21288        switch (extract32(ctx->opcode, 10, 2)) {
21289        case 0:
21290            /* SHLL_PH */
21291            gen_helper_shll_ph(v1_t, t0, v1_t, cpu_env);
21292            gen_store_gpr(v1_t, rt);
21293            break;
21294        case 2:
21295            /* SHLL_S_PH */
21296            gen_helper_shll_s_ph(v1_t, t0, v1_t, cpu_env);
21297            gen_store_gpr(v1_t, rt);
21298            break;
21299        default:
21300            generate_exception_end(ctx, EXCP_RI);
21301            break;
21302        }
21303        break;
21304    case NM_SHLL_S_W:
21305        check_dsp(ctx);
21306        tcg_gen_movi_tl(t0, rd);
21307        gen_helper_shll_s_w(v1_t, t0, v1_t, cpu_env);
21308        gen_store_gpr(v1_t, rt);
21309        break;
21310    case NM_REPL_PH:
21311        check_dsp(ctx);
21312        {
21313            int16_t imm;
21314            imm = sextract32(ctx->opcode, 11, 11);
21315            imm = (int16_t)(imm << 6) >> 6;
21316            if (rt != 0) {
21317                tcg_gen_movi_tl(cpu_gpr[rt], dup_const(MO_16, imm));
21318            }
21319        }
21320        break;
21321    default:
21322        generate_exception_end(ctx, EXCP_RI);
21323        break;
21324    }
21325}
21326
21327static int decode_nanomips_32_48_opc(CPUMIPSState *env, DisasContext *ctx)
21328{
21329    uint16_t insn;
21330    uint32_t op;
21331    int rt, rs, rd;
21332    int offset;
21333    int imm;
21334
21335    insn = cpu_lduw_code(env, ctx->base.pc_next + 2);
21336    ctx->opcode = (ctx->opcode << 16) | insn;
21337
21338    rt = extract32(ctx->opcode, 21, 5);
21339    rs = extract32(ctx->opcode, 16, 5);
21340    rd = extract32(ctx->opcode, 11, 5);
21341
21342    op = extract32(ctx->opcode, 26, 6);
21343    switch (op) {
21344    case NM_P_ADDIU:
21345        if (rt == 0) {
21346            /* P.RI */
21347            switch (extract32(ctx->opcode, 19, 2)) {
21348            case NM_SIGRIE:
21349            default:
21350                generate_exception_end(ctx, EXCP_RI);
21351                break;
21352            case NM_P_SYSCALL:
21353                if ((extract32(ctx->opcode, 18, 1)) == NM_SYSCALL) {
21354                    generate_exception_end(ctx, EXCP_SYSCALL);
21355                } else {
21356                    generate_exception_end(ctx, EXCP_RI);
21357                }
21358                break;
21359            case NM_BREAK:
21360                generate_exception_end(ctx, EXCP_BREAK);
21361                break;
21362            case NM_SDBBP:
21363                if (is_uhi(extract32(ctx->opcode, 0, 19))) {
21364                    gen_helper_do_semihosting(cpu_env);
21365                } else {
21366                    if (ctx->hflags & MIPS_HFLAG_SBRI) {
21367                        generate_exception_end(ctx, EXCP_RI);
21368                    } else {
21369                        generate_exception_end(ctx, EXCP_DBp);
21370                    }
21371                }
21372                break;
21373            }
21374        } else {
21375            /* NM_ADDIU */
21376            imm = extract32(ctx->opcode, 0, 16);
21377            if (rs != 0) {
21378                tcg_gen_addi_tl(cpu_gpr[rt], cpu_gpr[rs], imm);
21379            } else {
21380                tcg_gen_movi_tl(cpu_gpr[rt], imm);
21381            }
21382            tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
21383        }
21384        break;
21385    case NM_ADDIUPC:
21386        if (rt != 0) {
21387            offset = sextract32(ctx->opcode, 0, 1) << 21 |
21388                     extract32(ctx->opcode, 1, 20) << 1;
21389            target_long addr = addr_add(ctx, ctx->base.pc_next + 4, offset);
21390            tcg_gen_movi_tl(cpu_gpr[rt], addr);
21391        }
21392        break;
21393    case NM_POOL32A:
21394        switch (ctx->opcode & 0x07) {
21395        case NM_POOL32A0:
21396            gen_pool32a0_nanomips_insn(env, ctx);
21397            break;
21398        case NM_POOL32A5:
21399            {
21400                int32_t op1 = extract32(ctx->opcode, 3, 7);
21401                gen_pool32a5_nanomips_insn(ctx, op1, rd, rs, rt);
21402            }
21403            break;
21404        case NM_POOL32A7:
21405            switch (extract32(ctx->opcode, 3, 3)) {
21406            case NM_P_LSX:
21407                gen_p_lsx(ctx, rd, rs, rt);
21408                break;
21409            case NM_LSA:
21410                /*
21411                 * In nanoMIPS, the shift field directly encodes the shift
21412                 * amount, meaning that the supported shift values are in
21413                 * the range 0 to 3 (instead of 1 to 4 in MIPSR6).
21414                 */
21415                gen_lsa(ctx, OPC_LSA, rd, rs, rt,
21416                        extract32(ctx->opcode, 9, 2) - 1);
21417                break;
21418            case NM_EXTW:
21419                gen_ext(ctx, 32, rd, rs, rt, extract32(ctx->opcode, 6, 5));
21420                break;
21421            case NM_POOL32AXF:
21422                gen_pool32axf_nanomips_insn(env, ctx);
21423                break;
21424            default:
21425                generate_exception_end(ctx, EXCP_RI);
21426                break;
21427            }
21428            break;
21429        default:
21430            generate_exception_end(ctx, EXCP_RI);
21431            break;
21432        }
21433        break;
21434    case NM_P_GP_W:
21435        switch (ctx->opcode & 0x03) {
21436        case NM_ADDIUGP_W:
21437            if (rt != 0) {
21438                offset = extract32(ctx->opcode, 0, 21);
21439                gen_op_addr_addi(ctx, cpu_gpr[rt], cpu_gpr[28], offset);
21440            }
21441            break;
21442        case NM_LWGP:
21443            gen_ld(ctx, OPC_LW, rt, 28, extract32(ctx->opcode, 2, 19) << 2);
21444            break;
21445        case NM_SWGP:
21446            gen_st(ctx, OPC_SW, rt, 28, extract32(ctx->opcode, 2, 19) << 2);
21447            break;
21448        default:
21449            generate_exception_end(ctx, EXCP_RI);
21450            break;
21451        }
21452        break;
21453    case NM_P48I:
21454        {
21455            insn = cpu_lduw_code(env, ctx->base.pc_next + 4);
21456            target_long addr_off = extract32(ctx->opcode, 0, 16) | insn << 16;
21457            switch (extract32(ctx->opcode, 16, 5)) {
21458            case NM_LI48:
21459                check_nms(ctx);
21460                if (rt != 0) {
21461                    tcg_gen_movi_tl(cpu_gpr[rt], addr_off);
21462                }
21463                break;
21464            case NM_ADDIU48:
21465                check_nms(ctx);
21466                if (rt != 0) {
21467                    tcg_gen_addi_tl(cpu_gpr[rt], cpu_gpr[rt], addr_off);
21468                    tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
21469                }
21470                break;
21471            case NM_ADDIUGP48:
21472                check_nms(ctx);
21473                if (rt != 0) {
21474                    gen_op_addr_addi(ctx, cpu_gpr[rt], cpu_gpr[28], addr_off);
21475                }
21476                break;
21477            case NM_ADDIUPC48:
21478                check_nms(ctx);
21479                if (rt != 0) {
21480                    target_long addr = addr_add(ctx, ctx->base.pc_next + 6,
21481                                                addr_off);
21482
21483                    tcg_gen_movi_tl(cpu_gpr[rt], addr);
21484                }
21485                break;
21486            case NM_LWPC48:
21487                check_nms(ctx);
21488                if (rt != 0) {
21489                    TCGv t0;
21490                    t0 = tcg_temp_new();
21491
21492                    target_long addr = addr_add(ctx, ctx->base.pc_next + 6,
21493                                                addr_off);
21494
21495                    tcg_gen_movi_tl(t0, addr);
21496                    tcg_gen_qemu_ld_tl(cpu_gpr[rt], t0, ctx->mem_idx, MO_TESL);
21497                    tcg_temp_free(t0);
21498                }
21499                break;
21500            case NM_SWPC48:
21501                check_nms(ctx);
21502                {
21503                    TCGv t0, t1;
21504                    t0 = tcg_temp_new();
21505                    t1 = tcg_temp_new();
21506
21507                    target_long addr = addr_add(ctx, ctx->base.pc_next + 6,
21508                                                addr_off);
21509
21510                    tcg_gen_movi_tl(t0, addr);
21511                    gen_load_gpr(t1, rt);
21512
21513                    tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL);
21514
21515                    tcg_temp_free(t0);
21516                    tcg_temp_free(t1);
21517                }
21518                break;
21519            default:
21520                generate_exception_end(ctx, EXCP_RI);
21521                break;
21522            }
21523            return 6;
21524        }
21525    case NM_P_U12:
21526        switch (extract32(ctx->opcode, 12, 4)) {
21527        case NM_ORI:
21528            gen_logic_imm(ctx, OPC_ORI, rt, rs, extract32(ctx->opcode, 0, 12));
21529            break;
21530        case NM_XORI:
21531            gen_logic_imm(ctx, OPC_XORI, rt, rs, extract32(ctx->opcode, 0, 12));
21532            break;
21533        case NM_ANDI:
21534            gen_logic_imm(ctx, OPC_ANDI, rt, rs, extract32(ctx->opcode, 0, 12));
21535            break;
21536        case NM_P_SR:
21537            switch (extract32(ctx->opcode, 20, 1)) {
21538            case NM_PP_SR:
21539                switch (ctx->opcode & 3) {
21540                case NM_SAVE:
21541                    gen_save(ctx, rt, extract32(ctx->opcode, 16, 4),
21542                             extract32(ctx->opcode, 2, 1),
21543                             extract32(ctx->opcode, 3, 9) << 3);
21544                    break;
21545                case NM_RESTORE:
21546                case NM_RESTORE_JRC:
21547                    gen_restore(ctx, rt, extract32(ctx->opcode, 16, 4),
21548                                extract32(ctx->opcode, 2, 1),
21549                                extract32(ctx->opcode, 3, 9) << 3);
21550                    if ((ctx->opcode & 3) == NM_RESTORE_JRC) {
21551                        gen_compute_branch_nm(ctx, OPC_JR, 2, 31, 0, 0);
21552                    }
21553                    break;
21554                default:
21555                    generate_exception_end(ctx, EXCP_RI);
21556                    break;
21557                }
21558                break;
21559            case NM_P_SR_F:
21560                generate_exception_end(ctx, EXCP_RI);
21561                break;
21562            }
21563            break;
21564        case NM_SLTI:
21565            gen_slt_imm(ctx, OPC_SLTI, rt, rs, extract32(ctx->opcode, 0, 12));
21566            break;
21567        case NM_SLTIU:
21568            gen_slt_imm(ctx, OPC_SLTIU, rt, rs, extract32(ctx->opcode, 0, 12));
21569            break;
21570        case NM_SEQI:
21571            {
21572                TCGv t0 = tcg_temp_new();
21573
21574                imm = extract32(ctx->opcode, 0, 12);
21575                gen_load_gpr(t0, rs);
21576                tcg_gen_setcondi_tl(TCG_COND_EQ, t0, t0, imm);
21577                gen_store_gpr(t0, rt);
21578
21579                tcg_temp_free(t0);
21580            }
21581            break;
21582        case NM_ADDIUNEG:
21583            imm = (int16_t) extract32(ctx->opcode, 0, 12);
21584            gen_arith_imm(ctx, OPC_ADDIU, rt, rs, -imm);
21585            break;
21586        case NM_P_SHIFT:
21587            {
21588                int shift = extract32(ctx->opcode, 0, 5);
21589                switch (extract32(ctx->opcode, 5, 4)) {
21590                case NM_P_SLL:
21591                    if (rt == 0 && shift == 0) {
21592                        /* NOP */
21593                    } else if (rt == 0 && shift == 3) {
21594                        /* EHB - treat as NOP */
21595                    } else if (rt == 0 && shift == 5) {
21596                        /* PAUSE - treat as NOP */
21597                    } else if (rt == 0 && shift == 6) {
21598                        /* SYNC */
21599                        gen_sync(extract32(ctx->opcode, 16, 5));
21600                    } else {
21601                        /* SLL */
21602                        gen_shift_imm(ctx, OPC_SLL, rt, rs,
21603                                      extract32(ctx->opcode, 0, 5));
21604                    }
21605                    break;
21606                case NM_SRL:
21607                    gen_shift_imm(ctx, OPC_SRL, rt, rs,
21608                                  extract32(ctx->opcode, 0, 5));
21609                    break;
21610                case NM_SRA:
21611                    gen_shift_imm(ctx, OPC_SRA, rt, rs,
21612                                  extract32(ctx->opcode, 0, 5));
21613                    break;
21614                case NM_ROTR:
21615                    gen_shift_imm(ctx, OPC_ROTR, rt, rs,
21616                                  extract32(ctx->opcode, 0, 5));
21617                    break;
21618                }
21619            }
21620            break;
21621        case NM_P_ROTX:
21622            check_nms(ctx);
21623            if (rt != 0) {
21624                TCGv t0 = tcg_temp_new();
21625                TCGv_i32 shift = tcg_const_i32(extract32(ctx->opcode, 0, 5));
21626                TCGv_i32 shiftx = tcg_const_i32(extract32(ctx->opcode, 7, 4)
21627                                                << 1);
21628                TCGv_i32 stripe = tcg_const_i32(extract32(ctx->opcode, 6, 1));
21629
21630                gen_load_gpr(t0, rs);
21631                gen_helper_rotx(cpu_gpr[rt], t0, shift, shiftx, stripe);
21632                tcg_temp_free(t0);
21633
21634                tcg_temp_free_i32(shift);
21635                tcg_temp_free_i32(shiftx);
21636                tcg_temp_free_i32(stripe);
21637            }
21638            break;
21639        case NM_P_INS:
21640            switch (((ctx->opcode >> 10) & 2) |
21641                    (extract32(ctx->opcode, 5, 1))) {
21642            case NM_INS:
21643                check_nms(ctx);
21644                gen_bitops(ctx, OPC_INS, rt, rs, extract32(ctx->opcode, 0, 5),
21645                           extract32(ctx->opcode, 6, 5));
21646                break;
21647            default:
21648                generate_exception_end(ctx, EXCP_RI);
21649                break;
21650            }
21651            break;
21652        case NM_P_EXT:
21653            switch (((ctx->opcode >> 10) & 2) |
21654                    (extract32(ctx->opcode, 5, 1))) {
21655            case NM_EXT:
21656                check_nms(ctx);
21657                gen_bitops(ctx, OPC_EXT, rt, rs, extract32(ctx->opcode, 0, 5),
21658                           extract32(ctx->opcode, 6, 5));
21659                break;
21660            default:
21661                generate_exception_end(ctx, EXCP_RI);
21662                break;
21663            }
21664            break;
21665        default:
21666            generate_exception_end(ctx, EXCP_RI);
21667            break;
21668        }
21669        break;
21670    case NM_POOL32F:
21671        gen_pool32f_nanomips_insn(ctx);
21672        break;
21673    case NM_POOL32S:
21674        break;
21675    case NM_P_LUI:
21676        switch (extract32(ctx->opcode, 1, 1)) {
21677        case NM_LUI:
21678            if (rt != 0) {
21679                tcg_gen_movi_tl(cpu_gpr[rt],
21680                                sextract32(ctx->opcode, 0, 1) << 31 |
21681                                extract32(ctx->opcode, 2, 10) << 21 |
21682                                extract32(ctx->opcode, 12, 9) << 12);
21683            }
21684            break;
21685        case NM_ALUIPC:
21686            if (rt != 0) {
21687                offset = sextract32(ctx->opcode, 0, 1) << 31 |
21688                         extract32(ctx->opcode, 2, 10) << 21 |
21689                         extract32(ctx->opcode, 12, 9) << 12;
21690                target_long addr;
21691                addr = ~0xFFF & addr_add(ctx, ctx->base.pc_next + 4, offset);
21692                tcg_gen_movi_tl(cpu_gpr[rt], addr);
21693            }
21694            break;
21695        }
21696        break;
21697    case NM_P_GP_BH:
21698        {
21699            uint32_t u = extract32(ctx->opcode, 0, 18);
21700
21701            switch (extract32(ctx->opcode, 18, 3)) {
21702            case NM_LBGP:
21703                gen_ld(ctx, OPC_LB, rt, 28, u);
21704                break;
21705            case NM_SBGP:
21706                gen_st(ctx, OPC_SB, rt, 28, u);
21707                break;
21708            case NM_LBUGP:
21709                gen_ld(ctx, OPC_LBU, rt, 28, u);
21710                break;
21711            case NM_ADDIUGP_B:
21712                if (rt != 0) {
21713                    gen_op_addr_addi(ctx, cpu_gpr[rt], cpu_gpr[28], u);
21714                }
21715                break;
21716            case NM_P_GP_LH:
21717                u &= ~1;
21718                switch (ctx->opcode & 1) {
21719                case NM_LHGP:
21720                    gen_ld(ctx, OPC_LH, rt, 28, u);
21721                    break;
21722                case NM_LHUGP:
21723                    gen_ld(ctx, OPC_LHU, rt, 28, u);
21724                    break;
21725                }
21726                break;
21727            case NM_P_GP_SH:
21728                u &= ~1;
21729                switch (ctx->opcode & 1) {
21730                case NM_SHGP:
21731                    gen_st(ctx, OPC_SH, rt, 28, u);
21732                    break;
21733                default:
21734                    generate_exception_end(ctx, EXCP_RI);
21735                    break;
21736                }
21737                break;
21738            case NM_P_GP_CP1:
21739                u &= ~0x3;
21740                switch (ctx->opcode & 0x3) {
21741                case NM_LWC1GP:
21742                    gen_cop1_ldst(ctx, OPC_LWC1, rt, 28, u);
21743                    break;
21744                case NM_LDC1GP:
21745                    gen_cop1_ldst(ctx, OPC_LDC1, rt, 28, u);
21746                    break;
21747                case NM_SWC1GP:
21748                    gen_cop1_ldst(ctx, OPC_SWC1, rt, 28, u);
21749                    break;
21750                case NM_SDC1GP:
21751                    gen_cop1_ldst(ctx, OPC_SDC1, rt, 28, u);
21752                    break;
21753                }
21754                break;
21755            default:
21756                generate_exception_end(ctx, EXCP_RI);
21757                break;
21758            }
21759        }
21760        break;
21761    case NM_P_LS_U12:
21762        {
21763            uint32_t u = extract32(ctx->opcode, 0, 12);
21764
21765            switch (extract32(ctx->opcode, 12, 4)) {
21766            case NM_P_PREFU12:
21767                if (rt == 31) {
21768                    /* SYNCI */
21769                    /*
21770                     * Break the TB to be able to sync copied instructions
21771                     * immediately.
21772                     */
21773                    ctx->base.is_jmp = DISAS_STOP;
21774                } else {
21775                    /* PREF */
21776                    /* Treat as NOP. */
21777                }
21778                break;
21779            case NM_LB:
21780                gen_ld(ctx, OPC_LB, rt, rs, u);
21781                break;
21782            case NM_LH:
21783                gen_ld(ctx, OPC_LH, rt, rs, u);
21784                break;
21785            case NM_LW:
21786                gen_ld(ctx, OPC_LW, rt, rs, u);
21787                break;
21788            case NM_LBU:
21789                gen_ld(ctx, OPC_LBU, rt, rs, u);
21790                break;
21791            case NM_LHU:
21792                gen_ld(ctx, OPC_LHU, rt, rs, u);
21793                break;
21794            case NM_SB:
21795                gen_st(ctx, OPC_SB, rt, rs, u);
21796                break;
21797            case NM_SH:
21798                gen_st(ctx, OPC_SH, rt, rs, u);
21799                break;
21800            case NM_SW:
21801                gen_st(ctx, OPC_SW, rt, rs, u);
21802                break;
21803            case NM_LWC1:
21804                gen_cop1_ldst(ctx, OPC_LWC1, rt, rs, u);
21805                break;
21806            case NM_LDC1:
21807                gen_cop1_ldst(ctx, OPC_LDC1, rt, rs, u);
21808                break;
21809            case NM_SWC1:
21810                gen_cop1_ldst(ctx, OPC_SWC1, rt, rs, u);
21811                break;
21812            case NM_SDC1:
21813                gen_cop1_ldst(ctx, OPC_SDC1, rt, rs, u);
21814                break;
21815            default:
21816                generate_exception_end(ctx, EXCP_RI);
21817                break;
21818            }
21819        }
21820        break;
21821    case NM_P_LS_S9:
21822        {
21823            int32_t s = (sextract32(ctx->opcode, 15, 1) << 8) |
21824                        extract32(ctx->opcode, 0, 8);
21825
21826            switch (extract32(ctx->opcode, 8, 3)) {
21827            case NM_P_LS_S0:
21828                switch (extract32(ctx->opcode, 11, 4)) {
21829                case NM_LBS9:
21830                    gen_ld(ctx, OPC_LB, rt, rs, s);
21831                    break;
21832                case NM_LHS9:
21833                    gen_ld(ctx, OPC_LH, rt, rs, s);
21834                    break;
21835                case NM_LWS9:
21836                    gen_ld(ctx, OPC_LW, rt, rs, s);
21837                    break;
21838                case NM_LBUS9:
21839                    gen_ld(ctx, OPC_LBU, rt, rs, s);
21840                    break;
21841                case NM_LHUS9:
21842                    gen_ld(ctx, OPC_LHU, rt, rs, s);
21843                    break;
21844                case NM_SBS9:
21845                    gen_st(ctx, OPC_SB, rt, rs, s);
21846                    break;
21847                case NM_SHS9:
21848                    gen_st(ctx, OPC_SH, rt, rs, s);
21849                    break;
21850                case NM_SWS9:
21851                    gen_st(ctx, OPC_SW, rt, rs, s);
21852                    break;
21853                case NM_LWC1S9:
21854                    gen_cop1_ldst(ctx, OPC_LWC1, rt, rs, s);
21855                    break;
21856                case NM_LDC1S9:
21857                    gen_cop1_ldst(ctx, OPC_LDC1, rt, rs, s);
21858                    break;
21859                case NM_SWC1S9:
21860                    gen_cop1_ldst(ctx, OPC_SWC1, rt, rs, s);
21861                    break;
21862                case NM_SDC1S9:
21863                    gen_cop1_ldst(ctx, OPC_SDC1, rt, rs, s);
21864                    break;
21865                case NM_P_PREFS9:
21866                    if (rt == 31) {
21867                        /* SYNCI */
21868                        /*
21869                         * Break the TB to be able to sync copied instructions
21870                         * immediately.
21871                         */
21872                        ctx->base.is_jmp = DISAS_STOP;
21873                    } else {
21874                        /* PREF */
21875                        /* Treat as NOP. */
21876                    }
21877                    break;
21878                default:
21879                    generate_exception_end(ctx, EXCP_RI);
21880                    break;
21881                }
21882                break;
21883            case NM_P_LS_S1:
21884                switch (extract32(ctx->opcode, 11, 4)) {
21885                case NM_UALH:
21886                case NM_UASH:
21887                    check_nms(ctx);
21888                    {
21889                        TCGv t0 = tcg_temp_new();
21890                        TCGv t1 = tcg_temp_new();
21891
21892                        gen_base_offset_addr(ctx, t0, rs, s);
21893
21894                        switch (extract32(ctx->opcode, 11, 4)) {
21895                        case NM_UALH:
21896                            tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TESW |
21897                                               MO_UNALN);
21898                            gen_store_gpr(t0, rt);
21899                            break;
21900                        case NM_UASH:
21901                            gen_load_gpr(t1, rt);
21902                            tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUW |
21903                                               MO_UNALN);
21904                            break;
21905                        }
21906                        tcg_temp_free(t0);
21907                        tcg_temp_free(t1);
21908                    }
21909                    break;
21910                case NM_P_LL:
21911                    switch (ctx->opcode & 0x03) {
21912                    case NM_LL:
21913                        gen_ld(ctx, OPC_LL, rt, rs, s);
21914                        break;
21915                    case NM_LLWP:
21916                        check_xnp(ctx);
21917                        gen_llwp(ctx, rs, 0, rt, extract32(ctx->opcode, 3, 5));
21918                        break;
21919                    }
21920                    break;
21921                case NM_P_SC:
21922                    switch (ctx->opcode & 0x03) {
21923                    case NM_SC:
21924                        gen_st_cond(ctx, rt, rs, s, MO_TESL, false);
21925                        break;
21926                    case NM_SCWP:
21927                        check_xnp(ctx);
21928                        gen_scwp(ctx, rs, 0, rt, extract32(ctx->opcode, 3, 5),
21929                                 false);
21930                        break;
21931                    }
21932                    break;
21933                case NM_CACHE:
21934                    check_cp0_enabled(ctx);
21935                    if (ctx->hflags & MIPS_HFLAG_ITC_CACHE) {
21936                        gen_cache_operation(ctx, rt, rs, s);
21937                    }
21938                    break;
21939                }
21940                break;
21941            case NM_P_LS_E0:
21942                switch (extract32(ctx->opcode, 11, 4)) {
21943                case NM_LBE:
21944                    check_eva(ctx);
21945                    check_cp0_enabled(ctx);
21946                    gen_ld(ctx, OPC_LBE, rt, rs, s);
21947                    break;
21948                case NM_SBE:
21949                    check_eva(ctx);
21950                    check_cp0_enabled(ctx);
21951                    gen_st(ctx, OPC_SBE, rt, rs, s);
21952                    break;
21953                case NM_LBUE:
21954                    check_eva(ctx);
21955                    check_cp0_enabled(ctx);
21956                    gen_ld(ctx, OPC_LBUE, rt, rs, s);
21957                    break;
21958                case NM_P_PREFE:
21959                    if (rt == 31) {
21960                        /* case NM_SYNCIE */
21961                        check_eva(ctx);
21962                        check_cp0_enabled(ctx);
21963                        /*
21964                         * Break the TB to be able to sync copied instructions
21965                         * immediately.
21966                         */
21967                        ctx->base.is_jmp = DISAS_STOP;
21968                    } else {
21969                        /* case NM_PREFE */
21970                        check_eva(ctx);
21971                        check_cp0_enabled(ctx);
21972                        /* Treat as NOP. */
21973                    }
21974                    break;
21975                case NM_LHE:
21976                    check_eva(ctx);
21977                    check_cp0_enabled(ctx);
21978                    gen_ld(ctx, OPC_LHE, rt, rs, s);
21979                    break;
21980                case NM_SHE:
21981                    check_eva(ctx);
21982                    check_cp0_enabled(ctx);
21983                    gen_st(ctx, OPC_SHE, rt, rs, s);
21984                    break;
21985                case NM_LHUE:
21986                    check_eva(ctx);
21987                    check_cp0_enabled(ctx);
21988                    gen_ld(ctx, OPC_LHUE, rt, rs, s);
21989                    break;
21990                case NM_CACHEE:
21991                    check_nms_dl_il_sl_tl_l2c(ctx);
21992                    gen_cache_operation(ctx, rt, rs, s);
21993                    break;
21994                case NM_LWE:
21995                    check_eva(ctx);
21996                    check_cp0_enabled(ctx);
21997                    gen_ld(ctx, OPC_LWE, rt, rs, s);
21998                    break;
21999                case NM_SWE:
22000                    check_eva(ctx);
22001                    check_cp0_enabled(ctx);
22002                    gen_st(ctx, OPC_SWE, rt, rs, s);
22003                    break;
22004                case NM_P_LLE:
22005                    switch (extract32(ctx->opcode, 2, 2)) {
22006                    case NM_LLE:
22007                        check_xnp(ctx);
22008                        check_eva(ctx);
22009                        check_cp0_enabled(ctx);
22010                        gen_ld(ctx, OPC_LLE, rt, rs, s);
22011                        break;
22012                    case NM_LLWPE:
22013                        check_xnp(ctx);
22014                        check_eva(ctx);
22015                        check_cp0_enabled(ctx);
22016                        gen_llwp(ctx, rs, 0, rt, extract32(ctx->opcode, 3, 5));
22017                        break;
22018                    default:
22019                        generate_exception_end(ctx, EXCP_RI);
22020                        break;
22021                    }
22022                    break;
22023                case NM_P_SCE:
22024                    switch (extract32(ctx->opcode, 2, 2)) {
22025                    case NM_SCE:
22026                        check_xnp(ctx);
22027                        check_eva(ctx);
22028                        check_cp0_enabled(ctx);
22029                        gen_st_cond(ctx, rt, rs, s, MO_TESL, true);
22030                        break;
22031                    case NM_SCWPE:
22032                        check_xnp(ctx);
22033                        check_eva(ctx);
22034                        check_cp0_enabled(ctx);
22035                        gen_scwp(ctx, rs, 0, rt, extract32(ctx->opcode, 3, 5),
22036                                 true);
22037                        break;
22038                    default:
22039                        generate_exception_end(ctx, EXCP_RI);
22040                        break;
22041                    }
22042                    break;
22043                }
22044                break;
22045            case NM_P_LS_WM:
22046            case NM_P_LS_UAWM:
22047                check_nms(ctx);
22048                {
22049                    int count = extract32(ctx->opcode, 12, 3);
22050                    int counter = 0;
22051
22052                    offset = sextract32(ctx->opcode, 15, 1) << 8 |
22053                             extract32(ctx->opcode, 0, 8);
22054                    TCGv va = tcg_temp_new();
22055                    TCGv t1 = tcg_temp_new();
22056                    MemOp memop = (extract32(ctx->opcode, 8, 3)) ==
22057                                      NM_P_LS_UAWM ? MO_UNALN : 0;
22058
22059                    count = (count == 0) ? 8 : count;
22060                    while (counter != count) {
22061                        int this_rt = ((rt + counter) & 0x1f) | (rt & 0x10);
22062                        int this_offset = offset + (counter << 2);
22063
22064                        gen_base_offset_addr(ctx, va, rs, this_offset);
22065
22066                        switch (extract32(ctx->opcode, 11, 1)) {
22067                        case NM_LWM:
22068                            tcg_gen_qemu_ld_tl(t1, va, ctx->mem_idx,
22069                                               memop | MO_TESL);
22070                            gen_store_gpr(t1, this_rt);
22071                            if ((this_rt == rs) &&
22072                                (counter != (count - 1))) {
22073                                /* UNPREDICTABLE */
22074                            }
22075                            break;
22076                        case NM_SWM:
22077                            this_rt = (rt == 0) ? 0 : this_rt;
22078                            gen_load_gpr(t1, this_rt);
22079                            tcg_gen_qemu_st_tl(t1, va, ctx->mem_idx,
22080                                               memop | MO_TEUL);
22081                            break;
22082                        }
22083                        counter++;
22084                    }
22085                    tcg_temp_free(va);
22086                    tcg_temp_free(t1);
22087                }
22088                break;
22089            default:
22090                generate_exception_end(ctx, EXCP_RI);
22091                break;
22092            }
22093        }
22094        break;
22095    case NM_MOVE_BALC:
22096        check_nms(ctx);
22097        {
22098            TCGv t0 = tcg_temp_new();
22099            int32_t s = sextract32(ctx->opcode, 0, 1) << 21 |
22100                        extract32(ctx->opcode, 1, 20) << 1;
22101            rd = (extract32(ctx->opcode, 24, 1)) == 0 ? 4 : 5;
22102            rt = decode_gpr_gpr4_zero(extract32(ctx->opcode, 25, 1) << 3 |
22103                            extract32(ctx->opcode, 21, 3));
22104            gen_load_gpr(t0, rt);
22105            tcg_gen_mov_tl(cpu_gpr[rd], t0);
22106            gen_compute_branch_nm(ctx, OPC_BGEZAL, 4, 0, 0, s);
22107            tcg_temp_free(t0);
22108        }
22109        break;
22110    case NM_P_BAL:
22111        {
22112            int32_t s = sextract32(ctx->opcode, 0, 1) << 25 |
22113                        extract32(ctx->opcode, 1, 24) << 1;
22114
22115            if ((extract32(ctx->opcode, 25, 1)) == 0) {
22116                /* BC */
22117                gen_compute_branch_nm(ctx, OPC_BEQ, 4, 0, 0, s);
22118            } else {
22119                /* BALC */
22120                gen_compute_branch_nm(ctx, OPC_BGEZAL, 4, 0, 0, s);
22121            }
22122        }
22123        break;
22124    case NM_P_J:
22125        switch (extract32(ctx->opcode, 12, 4)) {
22126        case NM_JALRC:
22127        case NM_JALRC_HB:
22128            gen_compute_branch_nm(ctx, OPC_JALR, 4, rs, rt, 0);
22129            break;
22130        case NM_P_BALRSC:
22131            gen_compute_nanomips_pbalrsc_branch(ctx, rs, rt);
22132            break;
22133        default:
22134            generate_exception_end(ctx, EXCP_RI);
22135            break;
22136        }
22137        break;
22138    case NM_P_BR1:
22139        {
22140            int32_t s = sextract32(ctx->opcode, 0, 1) << 14 |
22141                        extract32(ctx->opcode, 1, 13) << 1;
22142            switch (extract32(ctx->opcode, 14, 2)) {
22143            case NM_BEQC:
22144                check_nms(ctx);
22145                gen_compute_branch_nm(ctx, OPC_BEQ, 4, rs, rt, s);
22146                break;
22147            case NM_P_BR3A:
22148                s = sextract32(ctx->opcode, 0, 1) << 14 |
22149                    extract32(ctx->opcode, 1, 13) << 1;
22150                check_cp1_enabled(ctx);
22151                switch (extract32(ctx->opcode, 16, 5)) {
22152                case NM_BC1EQZC:
22153                    gen_compute_branch_cp1_nm(ctx, OPC_BC1EQZ, rt, s);
22154                    break;
22155                case NM_BC1NEZC:
22156                    gen_compute_branch_cp1_nm(ctx, OPC_BC1NEZ, rt, s);
22157                    break;
22158                case NM_BPOSGE32C:
22159                    check_dsp_r3(ctx);
22160                    {
22161                        int32_t imm = extract32(ctx->opcode, 1, 13) |
22162                                      extract32(ctx->opcode, 0, 1) << 13;
22163
22164                        gen_compute_branch_nm(ctx, OPC_BPOSGE32, 4, -1, -2,
22165                                              imm);
22166                    }
22167                    break;
22168                default:
22169                    generate_exception_end(ctx, EXCP_RI);
22170                    break;
22171                }
22172                break;
22173            case NM_BGEC:
22174                if (rs == rt) {
22175                    gen_compute_compact_branch_nm(ctx, OPC_BC, rs, rt, s);
22176                } else {
22177                    gen_compute_compact_branch_nm(ctx, OPC_BGEC, rs, rt, s);
22178                }
22179                break;
22180            case NM_BGEUC:
22181                if (rs == rt || rt == 0) {
22182                    gen_compute_compact_branch_nm(ctx, OPC_BC, 0, 0, s);
22183                } else if (rs == 0) {
22184                    gen_compute_compact_branch_nm(ctx, OPC_BEQZC, rt, 0, s);
22185                } else {
22186                    gen_compute_compact_branch_nm(ctx, OPC_BGEUC, rs, rt, s);
22187                }
22188                break;
22189            }
22190        }
22191        break;
22192    case NM_P_BR2:
22193        {
22194            int32_t s = sextract32(ctx->opcode, 0, 1) << 14 |
22195                        extract32(ctx->opcode, 1, 13) << 1;
22196            switch (extract32(ctx->opcode, 14, 2)) {
22197            case NM_BNEC:
22198                check_nms(ctx);
22199                gen_compute_branch_nm(ctx, OPC_BNE, 4, rs, rt, s);
22200                break;
22201            case NM_BLTC:
22202                if (rs != 0 && rt != 0 && rs == rt) {
22203                    /* NOP */
22204                    ctx->hflags |= MIPS_HFLAG_FBNSLOT;
22205                } else {
22206                    gen_compute_compact_branch_nm(ctx, OPC_BLTC, rs, rt, s);
22207                }
22208                break;
22209            case NM_BLTUC:
22210                if (rs == 0 || rs == rt) {
22211                    /* NOP */
22212                    ctx->hflags |= MIPS_HFLAG_FBNSLOT;
22213                } else {
22214                    gen_compute_compact_branch_nm(ctx, OPC_BLTUC, rs, rt, s);
22215                }
22216                break;
22217            default:
22218                generate_exception_end(ctx, EXCP_RI);
22219                break;
22220            }
22221        }
22222        break;
22223    case NM_P_BRI:
22224        {
22225            int32_t s = sextract32(ctx->opcode, 0, 1) << 11 |
22226                        extract32(ctx->opcode, 1, 10) << 1;
22227            uint32_t u = extract32(ctx->opcode, 11, 7);
22228
22229            gen_compute_imm_branch(ctx, extract32(ctx->opcode, 18, 3),
22230                                   rt, u, s);
22231        }
22232        break;
22233    default:
22234        generate_exception_end(ctx, EXCP_RI);
22235        break;
22236    }
22237    return 4;
22238}
22239
22240static int decode_nanomips_opc(CPUMIPSState *env, DisasContext *ctx)
22241{
22242    uint32_t op;
22243    int rt = decode_gpr_gpr3(NANOMIPS_EXTRACT_RT3(ctx->opcode));
22244    int rs = decode_gpr_gpr3(NANOMIPS_EXTRACT_RS3(ctx->opcode));
22245    int rd = decode_gpr_gpr3(NANOMIPS_EXTRACT_RD3(ctx->opcode));
22246    int offset;
22247    int imm;
22248
22249    /* make sure instructions are on a halfword boundary */
22250    if (ctx->base.pc_next & 0x1) {
22251        TCGv tmp = tcg_const_tl(ctx->base.pc_next);
22252        tcg_gen_st_tl(tmp, cpu_env, offsetof(CPUMIPSState, CP0_BadVAddr));
22253        tcg_temp_free(tmp);
22254        generate_exception_end(ctx, EXCP_AdEL);
22255        return 2;
22256    }
22257
22258    op = extract32(ctx->opcode, 10, 6);
22259    switch (op) {
22260    case NM_P16_MV:
22261        rt = NANOMIPS_EXTRACT_RD5(ctx->opcode);
22262        if (rt != 0) {
22263            /* MOVE */
22264            rs = NANOMIPS_EXTRACT_RS5(ctx->opcode);
22265            gen_arith(ctx, OPC_ADDU, rt, rs, 0);
22266        } else {
22267            /* P16.RI */
22268            switch (extract32(ctx->opcode, 3, 2)) {
22269            case NM_P16_SYSCALL:
22270                if (extract32(ctx->opcode, 2, 1) == 0) {
22271                    generate_exception_end(ctx, EXCP_SYSCALL);
22272                } else {
22273                    generate_exception_end(ctx, EXCP_RI);
22274                }
22275                break;
22276            case NM_BREAK16:
22277                generate_exception_end(ctx, EXCP_BREAK);
22278                break;
22279            case NM_SDBBP16:
22280                if (is_uhi(extract32(ctx->opcode, 0, 3))) {
22281                    gen_helper_do_semihosting(cpu_env);
22282                } else {
22283                    if (ctx->hflags & MIPS_HFLAG_SBRI) {
22284                        generate_exception_end(ctx, EXCP_RI);
22285                    } else {
22286                        generate_exception_end(ctx, EXCP_DBp);
22287                    }
22288                }
22289                break;
22290            default:
22291                generate_exception_end(ctx, EXCP_RI);
22292                break;
22293            }
22294        }
22295        break;
22296    case NM_P16_SHIFT:
22297        {
22298            int shift = extract32(ctx->opcode, 0, 3);
22299            uint32_t opc = 0;
22300            shift = (shift == 0) ? 8 : shift;
22301
22302            switch (extract32(ctx->opcode, 3, 1)) {
22303            case NM_SLL16:
22304                opc = OPC_SLL;
22305                break;
22306            case NM_SRL16:
22307                opc = OPC_SRL;
22308                break;
22309            }
22310            gen_shift_imm(ctx, opc, rt, rs, shift);
22311        }
22312        break;
22313    case NM_P16C:
22314        switch (ctx->opcode & 1) {
22315        case NM_POOL16C_0:
22316            gen_pool16c_nanomips_insn(ctx);
22317            break;
22318        case NM_LWXS16:
22319            gen_ldxs(ctx, rt, rs, rd);
22320            break;
22321        }
22322        break;
22323    case NM_P16_A1:
22324        switch (extract32(ctx->opcode, 6, 1)) {
22325        case NM_ADDIUR1SP:
22326            imm = extract32(ctx->opcode, 0, 6) << 2;
22327            gen_arith_imm(ctx, OPC_ADDIU, rt, 29, imm);
22328            break;
22329        default:
22330            generate_exception_end(ctx, EXCP_RI);
22331            break;
22332        }
22333        break;
22334    case NM_P16_A2:
22335        switch (extract32(ctx->opcode, 3, 1)) {
22336        case NM_ADDIUR2:
22337            imm = extract32(ctx->opcode, 0, 3) << 2;
22338            gen_arith_imm(ctx, OPC_ADDIU, rt, rs, imm);
22339            break;
22340        case NM_P_ADDIURS5:
22341            rt = extract32(ctx->opcode, 5, 5);
22342            if (rt != 0) {
22343                /* imm = sign_extend(s[3] . s[2:0] , from_nbits = 4) */
22344                imm = (sextract32(ctx->opcode, 4, 1) << 3) |
22345                      (extract32(ctx->opcode, 0, 3));
22346                gen_arith_imm(ctx, OPC_ADDIU, rt, rt, imm);
22347            }
22348            break;
22349        }
22350        break;
22351    case NM_P16_ADDU:
22352        switch (ctx->opcode & 0x1) {
22353        case NM_ADDU16:
22354            gen_arith(ctx, OPC_ADDU, rd, rs, rt);
22355            break;
22356        case NM_SUBU16:
22357            gen_arith(ctx, OPC_SUBU, rd, rs, rt);
22358            break;
22359        }
22360        break;
22361    case NM_P16_4X4:
22362        rt = (extract32(ctx->opcode, 9, 1) << 3) |
22363              extract32(ctx->opcode, 5, 3);
22364        rs = (extract32(ctx->opcode, 4, 1) << 3) |
22365              extract32(ctx->opcode, 0, 3);
22366        rt = decode_gpr_gpr4(rt);
22367        rs = decode_gpr_gpr4(rs);
22368        switch ((extract32(ctx->opcode, 7, 2) & 0x2) |
22369                (extract32(ctx->opcode, 3, 1))) {
22370        case NM_ADDU4X4:
22371            check_nms(ctx);
22372            gen_arith(ctx, OPC_ADDU, rt, rs, rt);
22373            break;
22374        case NM_MUL4X4:
22375            check_nms(ctx);
22376            gen_r6_muldiv(ctx, R6_OPC_MUL, rt, rs, rt);
22377            break;
22378        default:
22379            generate_exception_end(ctx, EXCP_RI);
22380            break;
22381        }
22382        break;
22383    case NM_LI16:
22384        {
22385            int imm = extract32(ctx->opcode, 0, 7);
22386            imm = (imm == 0x7f ? -1 : imm);
22387            if (rt != 0) {
22388                tcg_gen_movi_tl(cpu_gpr[rt], imm);
22389            }
22390        }
22391        break;
22392    case NM_ANDI16:
22393        {
22394            uint32_t u = extract32(ctx->opcode, 0, 4);
22395            u = (u == 12) ? 0xff :
22396                (u == 13) ? 0xffff : u;
22397            gen_logic_imm(ctx, OPC_ANDI, rt, rs, u);
22398        }
22399        break;
22400    case NM_P16_LB:
22401        offset = extract32(ctx->opcode, 0, 2);
22402        switch (extract32(ctx->opcode, 2, 2)) {
22403        case NM_LB16:
22404            gen_ld(ctx, OPC_LB, rt, rs, offset);
22405            break;
22406        case NM_SB16:
22407            rt = decode_gpr_gpr3_src_store(
22408                     NANOMIPS_EXTRACT_RT3(ctx->opcode));
22409            gen_st(ctx, OPC_SB, rt, rs, offset);
22410            break;
22411        case NM_LBU16:
22412            gen_ld(ctx, OPC_LBU, rt, rs, offset);
22413            break;
22414        default:
22415            generate_exception_end(ctx, EXCP_RI);
22416            break;
22417        }
22418        break;
22419    case NM_P16_LH:
22420        offset = extract32(ctx->opcode, 1, 2) << 1;
22421        switch ((extract32(ctx->opcode, 3, 1) << 1) | (ctx->opcode & 1)) {
22422        case NM_LH16:
22423            gen_ld(ctx, OPC_LH, rt, rs, offset);
22424            break;
22425        case NM_SH16:
22426            rt = decode_gpr_gpr3_src_store(
22427                     NANOMIPS_EXTRACT_RT3(ctx->opcode));
22428            gen_st(ctx, OPC_SH, rt, rs, offset);
22429            break;
22430        case NM_LHU16:
22431            gen_ld(ctx, OPC_LHU, rt, rs, offset);
22432            break;
22433        default:
22434            generate_exception_end(ctx, EXCP_RI);
22435            break;
22436        }
22437        break;
22438    case NM_LW16:
22439        offset = extract32(ctx->opcode, 0, 4) << 2;
22440        gen_ld(ctx, OPC_LW, rt, rs, offset);
22441        break;
22442    case NM_LWSP16:
22443        rt = NANOMIPS_EXTRACT_RD5(ctx->opcode);
22444        offset = extract32(ctx->opcode, 0, 5) << 2;
22445        gen_ld(ctx, OPC_LW, rt, 29, offset);
22446        break;
22447    case NM_LW4X4:
22448        check_nms(ctx);
22449        rt = (extract32(ctx->opcode, 9, 1) << 3) |
22450             extract32(ctx->opcode, 5, 3);
22451        rs = (extract32(ctx->opcode, 4, 1) << 3) |
22452             extract32(ctx->opcode, 0, 3);
22453        offset = (extract32(ctx->opcode, 3, 1) << 3) |
22454                 (extract32(ctx->opcode, 8, 1) << 2);
22455        rt = decode_gpr_gpr4(rt);
22456        rs = decode_gpr_gpr4(rs);
22457        gen_ld(ctx, OPC_LW, rt, rs, offset);
22458        break;
22459    case NM_SW4X4:
22460        check_nms(ctx);
22461        rt = (extract32(ctx->opcode, 9, 1) << 3) |
22462             extract32(ctx->opcode, 5, 3);
22463        rs = (extract32(ctx->opcode, 4, 1) << 3) |
22464             extract32(ctx->opcode, 0, 3);
22465        offset = (extract32(ctx->opcode, 3, 1) << 3) |
22466                 (extract32(ctx->opcode, 8, 1) << 2);
22467        rt = decode_gpr_gpr4_zero(rt);
22468        rs = decode_gpr_gpr4(rs);
22469        gen_st(ctx, OPC_SW, rt, rs, offset);
22470        break;
22471    case NM_LWGP16:
22472        offset = extract32(ctx->opcode, 0, 7) << 2;
22473        gen_ld(ctx, OPC_LW, rt, 28, offset);
22474        break;
22475    case NM_SWSP16:
22476        rt = NANOMIPS_EXTRACT_RD5(ctx->opcode);
22477        offset = extract32(ctx->opcode, 0, 5) << 2;
22478        gen_st(ctx, OPC_SW, rt, 29, offset);
22479        break;
22480    case NM_SW16:
22481        rt = decode_gpr_gpr3_src_store(
22482                 NANOMIPS_EXTRACT_RT3(ctx->opcode));
22483        rs = decode_gpr_gpr3(NANOMIPS_EXTRACT_RS3(ctx->opcode));
22484        offset = extract32(ctx->opcode, 0, 4) << 2;
22485        gen_st(ctx, OPC_SW, rt, rs, offset);
22486        break;
22487    case NM_SWGP16:
22488        rt = decode_gpr_gpr3_src_store(
22489                 NANOMIPS_EXTRACT_RT3(ctx->opcode));
22490        offset = extract32(ctx->opcode, 0, 7) << 2;
22491        gen_st(ctx, OPC_SW, rt, 28, offset);
22492        break;
22493    case NM_BC16:
22494        gen_compute_branch_nm(ctx, OPC_BEQ, 2, 0, 0,
22495                           (sextract32(ctx->opcode, 0, 1) << 10) |
22496                           (extract32(ctx->opcode, 1, 9) << 1));
22497        break;
22498    case NM_BALC16:
22499        gen_compute_branch_nm(ctx, OPC_BGEZAL, 2, 0, 0,
22500                           (sextract32(ctx->opcode, 0, 1) << 10) |
22501                           (extract32(ctx->opcode, 1, 9) << 1));
22502        break;
22503    case NM_BEQZC16:
22504        gen_compute_branch_nm(ctx, OPC_BEQ, 2, rt, 0,
22505                           (sextract32(ctx->opcode, 0, 1) << 7) |
22506                           (extract32(ctx->opcode, 1, 6) << 1));
22507        break;
22508    case NM_BNEZC16:
22509        gen_compute_branch_nm(ctx, OPC_BNE, 2, rt, 0,
22510                           (sextract32(ctx->opcode, 0, 1) << 7) |
22511                           (extract32(ctx->opcode, 1, 6) << 1));
22512        break;
22513    case NM_P16_BR:
22514        switch (ctx->opcode & 0xf) {
22515        case 0:
22516            /* P16.JRC */
22517            switch (extract32(ctx->opcode, 4, 1)) {
22518            case NM_JRC:
22519                gen_compute_branch_nm(ctx, OPC_JR, 2,
22520                                   extract32(ctx->opcode, 5, 5), 0, 0);
22521                break;
22522            case NM_JALRC16:
22523                gen_compute_branch_nm(ctx, OPC_JALR, 2,
22524                                   extract32(ctx->opcode, 5, 5), 31, 0);
22525                break;
22526            }
22527            break;
22528        default:
22529            {
22530                /* P16.BRI */
22531                uint32_t opc = extract32(ctx->opcode, 4, 3) <
22532                               extract32(ctx->opcode, 7, 3) ? OPC_BEQ : OPC_BNE;
22533                gen_compute_branch_nm(ctx, opc, 2, rs, rt,
22534                                   extract32(ctx->opcode, 0, 4) << 1);
22535            }
22536            break;
22537        }
22538        break;
22539    case NM_P16_SR:
22540        {
22541            int count = extract32(ctx->opcode, 0, 4);
22542            int u = extract32(ctx->opcode, 4, 4) << 4;
22543
22544            rt = 30 + extract32(ctx->opcode, 9, 1);
22545            switch (extract32(ctx->opcode, 8, 1)) {
22546            case NM_SAVE16:
22547                gen_save(ctx, rt, count, 0, u);
22548                break;
22549            case NM_RESTORE_JRC16:
22550                gen_restore(ctx, rt, count, 0, u);
22551                gen_compute_branch_nm(ctx, OPC_JR, 2, 31, 0, 0);
22552                break;
22553            }
22554        }
22555        break;
22556    case NM_MOVEP:
22557    case NM_MOVEPREV:
22558        check_nms(ctx);
22559        {
22560            static const int gpr2reg1[] = {4, 5, 6, 7};
22561            static const int gpr2reg2[] = {5, 6, 7, 8};
22562            int re;
22563            int rd2 = extract32(ctx->opcode, 3, 1) << 1 |
22564                      extract32(ctx->opcode, 8, 1);
22565            int r1 = gpr2reg1[rd2];
22566            int r2 = gpr2reg2[rd2];
22567            int r3 = extract32(ctx->opcode, 4, 1) << 3 |
22568                     extract32(ctx->opcode, 0, 3);
22569            int r4 = extract32(ctx->opcode, 9, 1) << 3 |
22570                     extract32(ctx->opcode, 5, 3);
22571            TCGv t0 = tcg_temp_new();
22572            TCGv t1 = tcg_temp_new();
22573            if (op == NM_MOVEP) {
22574                rd = r1;
22575                re = r2;
22576                rs = decode_gpr_gpr4_zero(r3);
22577                rt = decode_gpr_gpr4_zero(r4);
22578            } else {
22579                rd = decode_gpr_gpr4(r3);
22580                re = decode_gpr_gpr4(r4);
22581                rs = r1;
22582                rt = r2;
22583            }
22584            gen_load_gpr(t0, rs);
22585            gen_load_gpr(t1, rt);
22586            tcg_gen_mov_tl(cpu_gpr[rd], t0);
22587            tcg_gen_mov_tl(cpu_gpr[re], t1);
22588            tcg_temp_free(t0);
22589            tcg_temp_free(t1);
22590        }
22591        break;
22592    default:
22593        return decode_nanomips_32_48_opc(env, ctx);
22594    }
22595
22596    return 2;
22597}
22598
22599
22600/* SmartMIPS extension to MIPS32 */
22601
22602#if defined(TARGET_MIPS64)
22603
22604/* MDMX extension to MIPS64 */
22605
22606#endif
22607
22608/* MIPSDSP functions. */
22609static void gen_mipsdsp_ld(DisasContext *ctx, uint32_t opc,
22610                           int rd, int base, int offset)
22611{
22612    TCGv t0;
22613
22614    check_dsp(ctx);
22615    t0 = tcg_temp_new();
22616
22617    if (base == 0) {
22618        gen_load_gpr(t0, offset);
22619    } else if (offset == 0) {
22620        gen_load_gpr(t0, base);
22621    } else {
22622        gen_op_addr_add(ctx, t0, cpu_gpr[base], cpu_gpr[offset]);
22623    }
22624
22625    switch (opc) {
22626    case OPC_LBUX:
22627        tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_UB);
22628        gen_store_gpr(t0, rd);
22629        break;
22630    case OPC_LHX:
22631        tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TESW);
22632        gen_store_gpr(t0, rd);
22633        break;
22634    case OPC_LWX:
22635        tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TESL);
22636        gen_store_gpr(t0, rd);
22637        break;
22638#if defined(TARGET_MIPS64)
22639    case OPC_LDX:
22640        tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEQ);
22641        gen_store_gpr(t0, rd);
22642        break;
22643#endif
22644    }
22645    tcg_temp_free(t0);
22646}
22647
22648static void gen_mipsdsp_arith(DisasContext *ctx, uint32_t op1, uint32_t op2,
22649                              int ret, int v1, int v2)
22650{
22651    TCGv v1_t;
22652    TCGv v2_t;
22653
22654    if (ret == 0) {
22655        /* Treat as NOP. */
22656        return;
22657    }
22658
22659    v1_t = tcg_temp_new();
22660    v2_t = tcg_temp_new();
22661
22662    gen_load_gpr(v1_t, v1);
22663    gen_load_gpr(v2_t, v2);
22664
22665    switch (op1) {
22666    /* OPC_MULT_G_2E is equal OPC_ADDUH_QB_DSP */
22667    case OPC_MULT_G_2E:
22668        check_dsp_r2(ctx);
22669        switch (op2) {
22670        case OPC_ADDUH_QB:
22671            gen_helper_adduh_qb(cpu_gpr[ret], v1_t, v2_t);
22672            break;
22673        case OPC_ADDUH_R_QB:
22674            gen_helper_adduh_r_qb(cpu_gpr[ret], v1_t, v2_t);
22675            break;
22676        case OPC_ADDQH_PH:
22677            gen_helper_addqh_ph(cpu_gpr[ret], v1_t, v2_t);
22678            break;
22679        case OPC_ADDQH_R_PH:
22680            gen_helper_addqh_r_ph(cpu_gpr[ret], v1_t, v2_t);
22681            break;
22682        case OPC_ADDQH_W:
22683            gen_helper_addqh_w(cpu_gpr[ret], v1_t, v2_t);
22684            break;
22685        case OPC_ADDQH_R_W:
22686            gen_helper_addqh_r_w(cpu_gpr[ret], v1_t, v2_t);
22687            break;
22688        case OPC_SUBUH_QB:
22689            gen_helper_subuh_qb(cpu_gpr[ret], v1_t, v2_t);
22690            break;
22691        case OPC_SUBUH_R_QB:
22692            gen_helper_subuh_r_qb(cpu_gpr[ret], v1_t, v2_t);
22693            break;
22694        case OPC_SUBQH_PH:
22695            gen_helper_subqh_ph(cpu_gpr[ret], v1_t, v2_t);
22696            break;
22697        case OPC_SUBQH_R_PH:
22698            gen_helper_subqh_r_ph(cpu_gpr[ret], v1_t, v2_t);
22699            break;
22700        case OPC_SUBQH_W:
22701            gen_helper_subqh_w(cpu_gpr[ret], v1_t, v2_t);
22702            break;
22703        case OPC_SUBQH_R_W:
22704            gen_helper_subqh_r_w(cpu_gpr[ret], v1_t, v2_t);
22705            break;
22706        }
22707        break;
22708    case OPC_ABSQ_S_PH_DSP:
22709        switch (op2) {
22710        case OPC_ABSQ_S_QB:
22711            check_dsp_r2(ctx);
22712            gen_helper_absq_s_qb(cpu_gpr[ret], v2_t, cpu_env);
22713            break;
22714        case OPC_ABSQ_S_PH:
22715            check_dsp(ctx);
22716            gen_helper_absq_s_ph(cpu_gpr[ret], v2_t, cpu_env);
22717            break;
22718        case OPC_ABSQ_S_W:
22719            check_dsp(ctx);
22720            gen_helper_absq_s_w(cpu_gpr[ret], v2_t, cpu_env);
22721            break;
22722        case OPC_PRECEQ_W_PHL:
22723            check_dsp(ctx);
22724            tcg_gen_andi_tl(cpu_gpr[ret], v2_t, 0xFFFF0000);
22725            tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]);
22726            break;
22727        case OPC_PRECEQ_W_PHR:
22728            check_dsp(ctx);
22729            tcg_gen_andi_tl(cpu_gpr[ret], v2_t, 0x0000FFFF);
22730            tcg_gen_shli_tl(cpu_gpr[ret], cpu_gpr[ret], 16);
22731            tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]);
22732            break;
22733        case OPC_PRECEQU_PH_QBL:
22734            check_dsp(ctx);
22735            gen_helper_precequ_ph_qbl(cpu_gpr[ret], v2_t);
22736            break;
22737        case OPC_PRECEQU_PH_QBR:
22738            check_dsp(ctx);
22739            gen_helper_precequ_ph_qbr(cpu_gpr[ret], v2_t);
22740            break;
22741        case OPC_PRECEQU_PH_QBLA:
22742            check_dsp(ctx);
22743            gen_helper_precequ_ph_qbla(cpu_gpr[ret], v2_t);
22744            break;
22745        case OPC_PRECEQU_PH_QBRA:
22746            check_dsp(ctx);
22747            gen_helper_precequ_ph_qbra(cpu_gpr[ret], v2_t);
22748            break;
22749        case OPC_PRECEU_PH_QBL:
22750            check_dsp(ctx);
22751            gen_helper_preceu_ph_qbl(cpu_gpr[ret], v2_t);
22752            break;
22753        case OPC_PRECEU_PH_QBR:
22754            check_dsp(ctx);
22755            gen_helper_preceu_ph_qbr(cpu_gpr[ret], v2_t);
22756            break;
22757        case OPC_PRECEU_PH_QBLA:
22758            check_dsp(ctx);
22759            gen_helper_preceu_ph_qbla(cpu_gpr[ret], v2_t);
22760            break;
22761        case OPC_PRECEU_PH_QBRA:
22762            check_dsp(ctx);
22763            gen_helper_preceu_ph_qbra(cpu_gpr[ret], v2_t);
22764            break;
22765        }
22766        break;
22767    case OPC_ADDU_QB_DSP:
22768        switch (op2) {
22769        case OPC_ADDQ_PH:
22770            check_dsp(ctx);
22771            gen_helper_addq_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22772            break;
22773        case OPC_ADDQ_S_PH:
22774            check_dsp(ctx);
22775            gen_helper_addq_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22776            break;
22777        case OPC_ADDQ_S_W:
22778            check_dsp(ctx);
22779            gen_helper_addq_s_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22780            break;
22781        case OPC_ADDU_QB:
22782            check_dsp(ctx);
22783            gen_helper_addu_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22784            break;
22785        case OPC_ADDU_S_QB:
22786            check_dsp(ctx);
22787            gen_helper_addu_s_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22788            break;
22789        case OPC_ADDU_PH:
22790            check_dsp_r2(ctx);
22791            gen_helper_addu_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22792            break;
22793        case OPC_ADDU_S_PH:
22794            check_dsp_r2(ctx);
22795            gen_helper_addu_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22796            break;
22797        case OPC_SUBQ_PH:
22798            check_dsp(ctx);
22799            gen_helper_subq_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22800            break;
22801        case OPC_SUBQ_S_PH:
22802            check_dsp(ctx);
22803            gen_helper_subq_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22804            break;
22805        case OPC_SUBQ_S_W:
22806            check_dsp(ctx);
22807            gen_helper_subq_s_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22808            break;
22809        case OPC_SUBU_QB:
22810            check_dsp(ctx);
22811            gen_helper_subu_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22812            break;
22813        case OPC_SUBU_S_QB:
22814            check_dsp(ctx);
22815            gen_helper_subu_s_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22816            break;
22817        case OPC_SUBU_PH:
22818            check_dsp_r2(ctx);
22819            gen_helper_subu_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22820            break;
22821        case OPC_SUBU_S_PH:
22822            check_dsp_r2(ctx);
22823            gen_helper_subu_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22824            break;
22825        case OPC_ADDSC:
22826            check_dsp(ctx);
22827            gen_helper_addsc(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22828            break;
22829        case OPC_ADDWC:
22830            check_dsp(ctx);
22831            gen_helper_addwc(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22832            break;
22833        case OPC_MODSUB:
22834            check_dsp(ctx);
22835            gen_helper_modsub(cpu_gpr[ret], v1_t, v2_t);
22836            break;
22837        case OPC_RADDU_W_QB:
22838            check_dsp(ctx);
22839            gen_helper_raddu_w_qb(cpu_gpr[ret], v1_t);
22840            break;
22841        }
22842        break;
22843    case OPC_CMPU_EQ_QB_DSP:
22844        switch (op2) {
22845        case OPC_PRECR_QB_PH:
22846            check_dsp_r2(ctx);
22847            gen_helper_precr_qb_ph(cpu_gpr[ret], v1_t, v2_t);
22848            break;
22849        case OPC_PRECRQ_QB_PH:
22850            check_dsp(ctx);
22851            gen_helper_precrq_qb_ph(cpu_gpr[ret], v1_t, v2_t);
22852            break;
22853        case OPC_PRECR_SRA_PH_W:
22854            check_dsp_r2(ctx);
22855            {
22856                TCGv_i32 sa_t = tcg_const_i32(v2);
22857                gen_helper_precr_sra_ph_w(cpu_gpr[ret], sa_t, v1_t,
22858                                          cpu_gpr[ret]);
22859                tcg_temp_free_i32(sa_t);
22860                break;
22861            }
22862        case OPC_PRECR_SRA_R_PH_W:
22863            check_dsp_r2(ctx);
22864            {
22865                TCGv_i32 sa_t = tcg_const_i32(v2);
22866                gen_helper_precr_sra_r_ph_w(cpu_gpr[ret], sa_t, v1_t,
22867                                            cpu_gpr[ret]);
22868                tcg_temp_free_i32(sa_t);
22869                break;
22870            }
22871        case OPC_PRECRQ_PH_W:
22872            check_dsp(ctx);
22873            gen_helper_precrq_ph_w(cpu_gpr[ret], v1_t, v2_t);
22874            break;
22875        case OPC_PRECRQ_RS_PH_W:
22876            check_dsp(ctx);
22877            gen_helper_precrq_rs_ph_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22878            break;
22879        case OPC_PRECRQU_S_QB_PH:
22880            check_dsp(ctx);
22881            gen_helper_precrqu_s_qb_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22882            break;
22883        }
22884        break;
22885#ifdef TARGET_MIPS64
22886    case OPC_ABSQ_S_QH_DSP:
22887        switch (op2) {
22888        case OPC_PRECEQ_L_PWL:
22889            check_dsp(ctx);
22890            tcg_gen_andi_tl(cpu_gpr[ret], v2_t, 0xFFFFFFFF00000000ull);
22891            break;
22892        case OPC_PRECEQ_L_PWR:
22893            check_dsp(ctx);
22894            tcg_gen_shli_tl(cpu_gpr[ret], v2_t, 32);
22895            break;
22896        case OPC_PRECEQ_PW_QHL:
22897            check_dsp(ctx);
22898            gen_helper_preceq_pw_qhl(cpu_gpr[ret], v2_t);
22899            break;
22900        case OPC_PRECEQ_PW_QHR:
22901            check_dsp(ctx);
22902            gen_helper_preceq_pw_qhr(cpu_gpr[ret], v2_t);
22903            break;
22904        case OPC_PRECEQ_PW_QHLA:
22905            check_dsp(ctx);
22906            gen_helper_preceq_pw_qhla(cpu_gpr[ret], v2_t);
22907            break;
22908        case OPC_PRECEQ_PW_QHRA:
22909            check_dsp(ctx);
22910            gen_helper_preceq_pw_qhra(cpu_gpr[ret], v2_t);
22911            break;
22912        case OPC_PRECEQU_QH_OBL:
22913            check_dsp(ctx);
22914            gen_helper_precequ_qh_obl(cpu_gpr[ret], v2_t);
22915            break;
22916        case OPC_PRECEQU_QH_OBR:
22917            check_dsp(ctx);
22918            gen_helper_precequ_qh_obr(cpu_gpr[ret], v2_t);
22919            break;
22920        case OPC_PRECEQU_QH_OBLA:
22921            check_dsp(ctx);
22922            gen_helper_precequ_qh_obla(cpu_gpr[ret], v2_t);
22923            break;
22924        case OPC_PRECEQU_QH_OBRA:
22925            check_dsp(ctx);
22926            gen_helper_precequ_qh_obra(cpu_gpr[ret], v2_t);
22927            break;
22928        case OPC_PRECEU_QH_OBL:
22929            check_dsp(ctx);
22930            gen_helper_preceu_qh_obl(cpu_gpr[ret], v2_t);
22931            break;
22932        case OPC_PRECEU_QH_OBR:
22933            check_dsp(ctx);
22934            gen_helper_preceu_qh_obr(cpu_gpr[ret], v2_t);
22935            break;
22936        case OPC_PRECEU_QH_OBLA:
22937            check_dsp(ctx);
22938            gen_helper_preceu_qh_obla(cpu_gpr[ret], v2_t);
22939            break;
22940        case OPC_PRECEU_QH_OBRA:
22941            check_dsp(ctx);
22942            gen_helper_preceu_qh_obra(cpu_gpr[ret], v2_t);
22943            break;
22944        case OPC_ABSQ_S_OB:
22945            check_dsp_r2(ctx);
22946            gen_helper_absq_s_ob(cpu_gpr[ret], v2_t, cpu_env);
22947            break;
22948        case OPC_ABSQ_S_PW:
22949            check_dsp(ctx);
22950            gen_helper_absq_s_pw(cpu_gpr[ret], v2_t, cpu_env);
22951            break;
22952        case OPC_ABSQ_S_QH:
22953            check_dsp(ctx);
22954            gen_helper_absq_s_qh(cpu_gpr[ret], v2_t, cpu_env);
22955            break;
22956        }
22957        break;
22958    case OPC_ADDU_OB_DSP:
22959        switch (op2) {
22960        case OPC_RADDU_L_OB:
22961            check_dsp(ctx);
22962            gen_helper_raddu_l_ob(cpu_gpr[ret], v1_t);
22963            break;
22964        case OPC_SUBQ_PW:
22965            check_dsp(ctx);
22966            gen_helper_subq_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22967            break;
22968        case OPC_SUBQ_S_PW:
22969            check_dsp(ctx);
22970            gen_helper_subq_s_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22971            break;
22972        case OPC_SUBQ_QH:
22973            check_dsp(ctx);
22974            gen_helper_subq_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22975            break;
22976        case OPC_SUBQ_S_QH:
22977            check_dsp(ctx);
22978            gen_helper_subq_s_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22979            break;
22980        case OPC_SUBU_OB:
22981            check_dsp(ctx);
22982            gen_helper_subu_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22983            break;
22984        case OPC_SUBU_S_OB:
22985            check_dsp(ctx);
22986            gen_helper_subu_s_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22987            break;
22988        case OPC_SUBU_QH:
22989            check_dsp_r2(ctx);
22990            gen_helper_subu_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22991            break;
22992        case OPC_SUBU_S_QH:
22993            check_dsp_r2(ctx);
22994            gen_helper_subu_s_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22995            break;
22996        case OPC_SUBUH_OB:
22997            check_dsp_r2(ctx);
22998            gen_helper_subuh_ob(cpu_gpr[ret], v1_t, v2_t);
22999            break;
23000        case OPC_SUBUH_R_OB:
23001            check_dsp_r2(ctx);
23002            gen_helper_subuh_r_ob(cpu_gpr[ret], v1_t, v2_t);
23003            break;
23004        case OPC_ADDQ_PW:
23005            check_dsp(ctx);
23006            gen_helper_addq_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
23007            break;
23008        case OPC_ADDQ_S_PW:
23009            check_dsp(ctx);
23010            gen_helper_addq_s_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
23011            break;
23012        case OPC_ADDQ_QH:
23013            check_dsp(ctx);
23014            gen_helper_addq_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
23015            break;
23016        case OPC_ADDQ_S_QH:
23017            check_dsp(ctx);
23018            gen_helper_addq_s_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
23019            break;
23020        case OPC_ADDU_OB:
23021            check_dsp(ctx);
23022            gen_helper_addu_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
23023            break;
23024        case OPC_ADDU_S_OB:
23025            check_dsp(ctx);
23026            gen_helper_addu_s_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
23027            break;
23028        case OPC_ADDU_QH:
23029            check_dsp_r2(ctx);
23030            gen_helper_addu_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
23031            break;
23032        case OPC_ADDU_S_QH:
23033            check_dsp_r2(ctx);
23034            gen_helper_addu_s_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
23035            break;
23036        case OPC_ADDUH_OB:
23037            check_dsp_r2(ctx);
23038            gen_helper_adduh_ob(cpu_gpr[ret], v1_t, v2_t);
23039            break;
23040        case OPC_ADDUH_R_OB:
23041            check_dsp_r2(ctx);
23042            gen_helper_adduh_r_ob(cpu_gpr[ret], v1_t, v2_t);
23043            break;
23044        }
23045        break;
23046    case OPC_CMPU_EQ_OB_DSP:
23047        switch (op2) {
23048        case OPC_PRECR_OB_QH:
23049            check_dsp_r2(ctx);
23050            gen_helper_precr_ob_qh(cpu_gpr[ret], v1_t, v2_t);
23051            break;
23052        case OPC_PRECR_SRA_QH_PW:
23053            check_dsp_r2(ctx);
23054            {
23055                TCGv_i32 ret_t = tcg_const_i32(ret);
23056                gen_helper_precr_sra_qh_pw(v2_t, v1_t, v2_t, ret_t);
23057                tcg_temp_free_i32(ret_t);
23058                break;
23059            }
23060        case OPC_PRECR_SRA_R_QH_PW:
23061            check_dsp_r2(ctx);
23062            {
23063                TCGv_i32 sa_v = tcg_const_i32(ret);
23064                gen_helper_precr_sra_r_qh_pw(v2_t, v1_t, v2_t, sa_v);
23065                tcg_temp_free_i32(sa_v);
23066                break;
23067            }
23068        case OPC_PRECRQ_OB_QH:
23069            check_dsp(ctx);
23070            gen_helper_precrq_ob_qh(cpu_gpr[ret], v1_t, v2_t);
23071            break;
23072        case OPC_PRECRQ_PW_L:
23073            check_dsp(ctx);
23074            gen_helper_precrq_pw_l(cpu_gpr[ret], v1_t, v2_t);
23075            break;
23076        case OPC_PRECRQ_QH_PW:
23077            check_dsp(ctx);
23078            gen_helper_precrq_qh_pw(cpu_gpr[ret], v1_t, v2_t);
23079            break;
23080        case OPC_PRECRQ_RS_QH_PW:
23081            check_dsp(ctx);
23082            gen_helper_precrq_rs_qh_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
23083            break;
23084        case OPC_PRECRQU_S_OB_QH:
23085            check_dsp(ctx);
23086            gen_helper_precrqu_s_ob_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
23087            break;
23088        }
23089        break;
23090#endif
23091    }
23092
23093    tcg_temp_free(v1_t);
23094    tcg_temp_free(v2_t);
23095}
23096
23097static void gen_mipsdsp_shift(DisasContext *ctx, uint32_t opc,
23098                              int ret, int v1, int v2)
23099{
23100    uint32_t op2;
23101    TCGv t0;
23102    TCGv v1_t;
23103    TCGv v2_t;
23104
23105    if (ret == 0) {
23106        /* Treat as NOP. */
23107        return;
23108    }
23109
23110    t0 = tcg_temp_new();
23111    v1_t = tcg_temp_new();
23112    v2_t = tcg_temp_new();
23113
23114    tcg_gen_movi_tl(t0, v1);
23115    gen_load_gpr(v1_t, v1);
23116    gen_load_gpr(v2_t, v2);
23117
23118    switch (opc) {
23119    case OPC_SHLL_QB_DSP:
23120        {
23121            op2 = MASK_SHLL_QB(ctx->opcode);
23122            switch (op2) {
23123            case OPC_SHLL_QB:
23124                check_dsp(ctx);
23125                gen_helper_shll_qb(cpu_gpr[ret], t0, v2_t, cpu_env);
23126                break;
23127            case OPC_SHLLV_QB:
23128                check_dsp(ctx);
23129                gen_helper_shll_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
23130                break;
23131            case OPC_SHLL_PH:
23132                check_dsp(ctx);
23133                gen_helper_shll_ph(cpu_gpr[ret], t0, v2_t, cpu_env);
23134                break;
23135            case OPC_SHLLV_PH:
23136                check_dsp(ctx);
23137                gen_helper_shll_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
23138                break;
23139            case OPC_SHLL_S_PH:
23140                check_dsp(ctx);
23141                gen_helper_shll_s_ph(cpu_gpr[ret], t0, v2_t, cpu_env);
23142                break;
23143            case OPC_SHLLV_S_PH:
23144                check_dsp(ctx);
23145                gen_helper_shll_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
23146                break;
23147            case OPC_SHLL_S_W:
23148                check_dsp(ctx);
23149                gen_helper_shll_s_w(cpu_gpr[ret], t0, v2_t, cpu_env);
23150                break;
23151            case OPC_SHLLV_S_W:
23152                check_dsp(ctx);
23153                gen_helper_shll_s_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
23154                break;
23155            case OPC_SHRL_QB:
23156                check_dsp(ctx);
23157                gen_helper_shrl_qb(cpu_gpr[ret], t0, v2_t);
23158                break;
23159            case OPC_SHRLV_QB:
23160                check_dsp(ctx);
23161                gen_helper_shrl_qb(cpu_gpr[ret], v1_t, v2_t);
23162                break;
23163            case OPC_SHRL_PH:
23164                check_dsp_r2(ctx);
23165                gen_helper_shrl_ph(cpu_gpr[ret], t0, v2_t);
23166                break;
23167            case OPC_SHRLV_PH:
23168                check_dsp_r2(ctx);
23169                gen_helper_shrl_ph(cpu_gpr[ret], v1_t, v2_t);
23170                break;
23171            case OPC_SHRA_QB:
23172                check_dsp_r2(ctx);
23173                gen_helper_shra_qb(cpu_gpr[ret], t0, v2_t);
23174                break;
23175            case OPC_SHRA_R_QB:
23176                check_dsp_r2(ctx);
23177                gen_helper_shra_r_qb(cpu_gpr[ret], t0, v2_t);
23178                break;
23179            case OPC_SHRAV_QB:
23180                check_dsp_r2(ctx);
23181                gen_helper_shra_qb(cpu_gpr[ret], v1_t, v2_t);
23182                break;
23183            case OPC_SHRAV_R_QB:
23184                check_dsp_r2(ctx);
23185                gen_helper_shra_r_qb(cpu_gpr[ret], v1_t, v2_t);
23186                break;
23187            case OPC_SHRA_PH:
23188                check_dsp(ctx);
23189                gen_helper_shra_ph(cpu_gpr[ret], t0, v2_t);
23190                break;
23191            case OPC_SHRA_R_PH:
23192                check_dsp(ctx);
23193                gen_helper_shra_r_ph(cpu_gpr[ret], t0, v2_t);
23194                break;
23195            case OPC_SHRAV_PH:
23196                check_dsp(ctx);
23197                gen_helper_shra_ph(cpu_gpr[ret], v1_t, v2_t);
23198                break;
23199            case OPC_SHRAV_R_PH:
23200                check_dsp(ctx);
23201                gen_helper_shra_r_ph(cpu_gpr[ret], v1_t, v2_t);
23202                break;
23203            case OPC_SHRA_R_W:
23204                check_dsp(ctx);
23205                gen_helper_shra_r_w(cpu_gpr[ret], t0, v2_t);
23206                break;
23207            case OPC_SHRAV_R_W:
23208                check_dsp(ctx);
23209                gen_helper_shra_r_w(cpu_gpr[ret], v1_t, v2_t);
23210                break;
23211            default:            /* Invalid */
23212                MIPS_INVAL("MASK SHLL.QB");
23213                generate_exception_end(ctx, EXCP_RI);
23214                break;
23215            }
23216            break;
23217        }
23218#ifdef TARGET_MIPS64
23219    case OPC_SHLL_OB_DSP:
23220        op2 = MASK_SHLL_OB(ctx->opcode);
23221        switch (op2) {
23222        case OPC_SHLL_PW:
23223            check_dsp(ctx);
23224            gen_helper_shll_pw(cpu_gpr[ret], v2_t, t0, cpu_env);
23225            break;
23226        case OPC_SHLLV_PW:
23227            check_dsp(ctx);
23228            gen_helper_shll_pw(cpu_gpr[ret], v2_t, v1_t, cpu_env);
23229            break;
23230        case OPC_SHLL_S_PW:
23231            check_dsp(ctx);
23232            gen_helper_shll_s_pw(cpu_gpr[ret], v2_t, t0, cpu_env);
23233            break;
23234        case OPC_SHLLV_S_PW:
23235            check_dsp(ctx);
23236            gen_helper_shll_s_pw(cpu_gpr[ret], v2_t, v1_t, cpu_env);
23237            break;
23238        case OPC_SHLL_OB:
23239            check_dsp(ctx);
23240            gen_helper_shll_ob(cpu_gpr[ret], v2_t, t0, cpu_env);
23241            break;
23242        case OPC_SHLLV_OB:
23243            check_dsp(ctx);
23244            gen_helper_shll_ob(cpu_gpr[ret], v2_t, v1_t, cpu_env);
23245            break;
23246        case OPC_SHLL_QH:
23247            check_dsp(ctx);
23248            gen_helper_shll_qh(cpu_gpr[ret], v2_t, t0, cpu_env);
23249            break;
23250        case OPC_SHLLV_QH:
23251            check_dsp(ctx);
23252            gen_helper_shll_qh(cpu_gpr[ret], v2_t, v1_t, cpu_env);
23253            break;
23254        case OPC_SHLL_S_QH:
23255            check_dsp(ctx);
23256            gen_helper_shll_s_qh(cpu_gpr[ret], v2_t, t0, cpu_env);
23257            break;
23258        case OPC_SHLLV_S_QH:
23259            check_dsp(ctx);
23260            gen_helper_shll_s_qh(cpu_gpr[ret], v2_t, v1_t, cpu_env);
23261            break;
23262        case OPC_SHRA_OB:
23263            check_dsp_r2(ctx);
23264            gen_helper_shra_ob(cpu_gpr[ret], v2_t, t0);
23265            break;
23266        case OPC_SHRAV_OB:
23267            check_dsp_r2(ctx);
23268            gen_helper_shra_ob(cpu_gpr[ret], v2_t, v1_t);
23269            break;
23270        case OPC_SHRA_R_OB:
23271            check_dsp_r2(ctx);
23272            gen_helper_shra_r_ob(cpu_gpr[ret], v2_t, t0);
23273            break;
23274        case OPC_SHRAV_R_OB:
23275            check_dsp_r2(ctx);
23276            gen_helper_shra_r_ob(cpu_gpr[ret], v2_t, v1_t);
23277            break;
23278        case OPC_SHRA_PW:
23279            check_dsp(ctx);
23280            gen_helper_shra_pw(cpu_gpr[ret], v2_t, t0);
23281            break;
23282        case OPC_SHRAV_PW:
23283            check_dsp(ctx);
23284            gen_helper_shra_pw(cpu_gpr[ret], v2_t, v1_t);
23285            break;
23286        case OPC_SHRA_R_PW:
23287            check_dsp(ctx);
23288            gen_helper_shra_r_pw(cpu_gpr[ret], v2_t, t0);
23289            break;
23290        case OPC_SHRAV_R_PW:
23291            check_dsp(ctx);
23292            gen_helper_shra_r_pw(cpu_gpr[ret], v2_t, v1_t);
23293            break;
23294        case OPC_SHRA_QH:
23295            check_dsp(ctx);
23296            gen_helper_shra_qh(cpu_gpr[ret], v2_t, t0);
23297            break;
23298        case OPC_SHRAV_QH:
23299            check_dsp(ctx);
23300            gen_helper_shra_qh(cpu_gpr[ret], v2_t, v1_t);
23301            break;
23302        case OPC_SHRA_R_QH:
23303            check_dsp(ctx);
23304            gen_helper_shra_r_qh(cpu_gpr[ret], v2_t, t0);
23305            break;
23306        case OPC_SHRAV_R_QH:
23307            check_dsp(ctx);
23308            gen_helper_shra_r_qh(cpu_gpr[ret], v2_t, v1_t);
23309            break;
23310        case OPC_SHRL_OB:
23311            check_dsp(ctx);
23312            gen_helper_shrl_ob(cpu_gpr[ret], v2_t, t0);
23313            break;
23314        case OPC_SHRLV_OB:
23315            check_dsp(ctx);
23316            gen_helper_shrl_ob(cpu_gpr[ret], v2_t, v1_t);
23317            break;
23318        case OPC_SHRL_QH:
23319            check_dsp_r2(ctx);
23320            gen_helper_shrl_qh(cpu_gpr[ret], v2_t, t0);
23321            break;
23322        case OPC_SHRLV_QH:
23323            check_dsp_r2(ctx);
23324            gen_helper_shrl_qh(cpu_gpr[ret], v2_t, v1_t);
23325            break;
23326        default:            /* Invalid */
23327            MIPS_INVAL("MASK SHLL.OB");
23328            generate_exception_end(ctx, EXCP_RI);
23329            break;
23330        }
23331        break;
23332#endif
23333    }
23334
23335    tcg_temp_free(t0);
23336    tcg_temp_free(v1_t);
23337    tcg_temp_free(v2_t);
23338}
23339
23340static void gen_mipsdsp_multiply(DisasContext *ctx, uint32_t op1, uint32_t op2,
23341                                 int ret, int v1, int v2, int check_ret)
23342{
23343    TCGv_i32 t0;
23344    TCGv v1_t;
23345    TCGv v2_t;
23346
23347    if ((ret == 0) && (check_ret == 1)) {
23348        /* Treat as NOP. */
23349        return;
23350    }
23351
23352    t0 = tcg_temp_new_i32();
23353    v1_t = tcg_temp_new();
23354    v2_t = tcg_temp_new();
23355
23356    tcg_gen_movi_i32(t0, ret);
23357    gen_load_gpr(v1_t, v1);
23358    gen_load_gpr(v2_t, v2);
23359
23360    switch (op1) {
23361    /*
23362     * OPC_MULT_G_2E, OPC_ADDUH_QB_DSP, OPC_MUL_PH_DSP have
23363     * the same mask and op1.
23364     */
23365    case OPC_MULT_G_2E:
23366        check_dsp_r2(ctx);
23367        switch (op2) {
23368        case  OPC_MUL_PH:
23369            gen_helper_mul_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
23370            break;
23371        case  OPC_MUL_S_PH:
23372            gen_helper_mul_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
23373            break;
23374        case OPC_MULQ_S_W:
23375            gen_helper_mulq_s_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
23376            break;
23377        case OPC_MULQ_RS_W:
23378            gen_helper_mulq_rs_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
23379            break;
23380        }
23381        break;
23382    case OPC_DPA_W_PH_DSP:
23383        switch (op2) {
23384        case OPC_DPAU_H_QBL:
23385            check_dsp(ctx);
23386            gen_helper_dpau_h_qbl(t0, v1_t, v2_t, cpu_env);
23387            break;
23388        case OPC_DPAU_H_QBR:
23389            check_dsp(ctx);
23390            gen_helper_dpau_h_qbr(t0, v1_t, v2_t, cpu_env);
23391            break;
23392        case OPC_DPSU_H_QBL:
23393            check_dsp(ctx);
23394            gen_helper_dpsu_h_qbl(t0, v1_t, v2_t, cpu_env);
23395            break;
23396        case OPC_DPSU_H_QBR:
23397            check_dsp(ctx);
23398            gen_helper_dpsu_h_qbr(t0, v1_t, v2_t, cpu_env);
23399            break;
23400        case OPC_DPA_W_PH:
23401            check_dsp_r2(ctx);
23402            gen_helper_dpa_w_ph(t0, v1_t, v2_t, cpu_env);
23403            break;
23404        case OPC_DPAX_W_PH:
23405            check_dsp_r2(ctx);
23406            gen_helper_dpax_w_ph(t0, v1_t, v2_t, cpu_env);
23407            break;
23408        case OPC_DPAQ_S_W_PH:
23409            check_dsp(ctx);
23410            gen_helper_dpaq_s_w_ph(t0, v1_t, v2_t, cpu_env);
23411            break;
23412        case OPC_DPAQX_S_W_PH:
23413            check_dsp_r2(ctx);
23414            gen_helper_dpaqx_s_w_ph(t0, v1_t, v2_t, cpu_env);
23415            break;
23416        case OPC_DPAQX_SA_W_PH:
23417            check_dsp_r2(ctx);
23418            gen_helper_dpaqx_sa_w_ph(t0, v1_t, v2_t, cpu_env);
23419            break;
23420        case OPC_DPS_W_PH:
23421            check_dsp_r2(ctx);
23422            gen_helper_dps_w_ph(t0, v1_t, v2_t, cpu_env);
23423            break;
23424        case OPC_DPSX_W_PH:
23425            check_dsp_r2(ctx);
23426            gen_helper_dpsx_w_ph(t0, v1_t, v2_t, cpu_env);
23427            break;
23428        case OPC_DPSQ_S_W_PH:
23429            check_dsp(ctx);
23430            gen_helper_dpsq_s_w_ph(t0, v1_t, v2_t, cpu_env);
23431            break;
23432        case OPC_DPSQX_S_W_PH:
23433            check_dsp_r2(ctx);
23434            gen_helper_dpsqx_s_w_ph(t0, v1_t, v2_t, cpu_env);
23435            break;
23436        case OPC_DPSQX_SA_W_PH:
23437            check_dsp_r2(ctx);
23438            gen_helper_dpsqx_sa_w_ph(t0, v1_t, v2_t, cpu_env);
23439            break;
23440        case OPC_MULSAQ_S_W_PH:
23441            check_dsp(ctx);
23442            gen_helper_mulsaq_s_w_ph(t0, v1_t, v2_t, cpu_env);
23443            break;
23444        case OPC_DPAQ_SA_L_W:
23445            check_dsp(ctx);
23446            gen_helper_dpaq_sa_l_w(t0, v1_t, v2_t, cpu_env);
23447            break;
23448        case OPC_DPSQ_SA_L_W:
23449            check_dsp(ctx);
23450            gen_helper_dpsq_sa_l_w(t0, v1_t, v2_t, cpu_env);
23451            break;
23452        case OPC_MAQ_S_W_PHL:
23453            check_dsp(ctx);
23454            gen_helper_maq_s_w_phl(t0, v1_t, v2_t, cpu_env);
23455            break;
23456        case OPC_MAQ_S_W_PHR:
23457            check_dsp(ctx);
23458            gen_helper_maq_s_w_phr(t0, v1_t, v2_t, cpu_env);
23459            break;
23460        case OPC_MAQ_SA_W_PHL:
23461            check_dsp(ctx);
23462            gen_helper_maq_sa_w_phl(t0, v1_t, v2_t, cpu_env);
23463            break;
23464        case OPC_MAQ_SA_W_PHR:
23465            check_dsp(ctx);
23466            gen_helper_maq_sa_w_phr(t0, v1_t, v2_t, cpu_env);
23467            break;
23468        case OPC_MULSA_W_PH:
23469            check_dsp_r2(ctx);
23470            gen_helper_mulsa_w_ph(t0, v1_t, v2_t, cpu_env);
23471            break;
23472        }
23473        break;
23474#ifdef TARGET_MIPS64
23475    case OPC_DPAQ_W_QH_DSP:
23476        {
23477            int ac = ret & 0x03;
23478            tcg_gen_movi_i32(t0, ac);
23479
23480            switch (op2) {
23481            case OPC_DMADD:
23482                check_dsp(ctx);
23483                gen_helper_dmadd(v1_t, v2_t, t0, cpu_env);
23484                break;
23485            case OPC_DMADDU:
23486                check_dsp(ctx);
23487                gen_helper_dmaddu(v1_t, v2_t, t0, cpu_env);
23488                break;
23489            case OPC_DMSUB:
23490                check_dsp(ctx);
23491                gen_helper_dmsub(v1_t, v2_t, t0, cpu_env);
23492                break;
23493            case OPC_DMSUBU:
23494                check_dsp(ctx);
23495                gen_helper_dmsubu(v1_t, v2_t, t0, cpu_env);
23496                break;
23497            case OPC_DPA_W_QH:
23498                check_dsp_r2(ctx);
23499                gen_helper_dpa_w_qh(v1_t, v2_t, t0, cpu_env);
23500                break;
23501            case OPC_DPAQ_S_W_QH:
23502                check_dsp(ctx);
23503                gen_helper_dpaq_s_w_qh(v1_t, v2_t, t0, cpu_env);
23504                break;
23505            case OPC_DPAQ_SA_L_PW:
23506                check_dsp(ctx);
23507                gen_helper_dpaq_sa_l_pw(v1_t, v2_t, t0, cpu_env);
23508                break;
23509            case OPC_DPAU_H_OBL:
23510                check_dsp(ctx);
23511                gen_helper_dpau_h_obl(v1_t, v2_t, t0, cpu_env);
23512                break;
23513            case OPC_DPAU_H_OBR:
23514                check_dsp(ctx);
23515                gen_helper_dpau_h_obr(v1_t, v2_t, t0, cpu_env);
23516                break;
23517            case OPC_DPS_W_QH:
23518                check_dsp_r2(ctx);
23519                gen_helper_dps_w_qh(v1_t, v2_t, t0, cpu_env);
23520                break;
23521            case OPC_DPSQ_S_W_QH:
23522                check_dsp(ctx);
23523                gen_helper_dpsq_s_w_qh(v1_t, v2_t, t0, cpu_env);
23524                break;
23525            case OPC_DPSQ_SA_L_PW:
23526                check_dsp(ctx);
23527                gen_helper_dpsq_sa_l_pw(v1_t, v2_t, t0, cpu_env);
23528                break;
23529            case OPC_DPSU_H_OBL:
23530                check_dsp(ctx);
23531                gen_helper_dpsu_h_obl(v1_t, v2_t, t0, cpu_env);
23532                break;
23533            case OPC_DPSU_H_OBR:
23534                check_dsp(ctx);
23535                gen_helper_dpsu_h_obr(v1_t, v2_t, t0, cpu_env);
23536                break;
23537            case OPC_MAQ_S_L_PWL:
23538                check_dsp(ctx);
23539                gen_helper_maq_s_l_pwl(v1_t, v2_t, t0, cpu_env);
23540                break;
23541            case OPC_MAQ_S_L_PWR:
23542                check_dsp(ctx);
23543                gen_helper_maq_s_l_pwr(v1_t, v2_t, t0, cpu_env);
23544                break;
23545            case OPC_MAQ_S_W_QHLL:
23546                check_dsp(ctx);
23547                gen_helper_maq_s_w_qhll(v1_t, v2_t, t0, cpu_env);
23548                break;
23549            case OPC_MAQ_SA_W_QHLL:
23550                check_dsp(ctx);
23551                gen_helper_maq_sa_w_qhll(v1_t, v2_t, t0, cpu_env);
23552                break;
23553            case OPC_MAQ_S_W_QHLR:
23554                check_dsp(ctx);
23555                gen_helper_maq_s_w_qhlr(v1_t, v2_t, t0, cpu_env);
23556                break;
23557            case OPC_MAQ_SA_W_QHLR:
23558                check_dsp(ctx);
23559                gen_helper_maq_sa_w_qhlr(v1_t, v2_t, t0, cpu_env);
23560                break;
23561            case OPC_MAQ_S_W_QHRL:
23562                check_dsp(ctx);
23563                gen_helper_maq_s_w_qhrl(v1_t, v2_t, t0, cpu_env);
23564                break;
23565            case OPC_MAQ_SA_W_QHRL:
23566                check_dsp(ctx);
23567                gen_helper_maq_sa_w_qhrl(v1_t, v2_t, t0, cpu_env);
23568                break;
23569            case OPC_MAQ_S_W_QHRR:
23570                check_dsp(ctx);
23571                gen_helper_maq_s_w_qhrr(v1_t, v2_t, t0, cpu_env);
23572                break;
23573            case OPC_MAQ_SA_W_QHRR:
23574                check_dsp(ctx);
23575                gen_helper_maq_sa_w_qhrr(v1_t, v2_t, t0, cpu_env);
23576                break;
23577            case OPC_MULSAQ_S_L_PW:
23578                check_dsp(ctx);
23579                gen_helper_mulsaq_s_l_pw(v1_t, v2_t, t0, cpu_env);
23580                break;
23581            case OPC_MULSAQ_S_W_QH:
23582                check_dsp(ctx);
23583                gen_helper_mulsaq_s_w_qh(v1_t, v2_t, t0, cpu_env);
23584                break;
23585            }
23586        }
23587        break;
23588#endif
23589    case OPC_ADDU_QB_DSP:
23590        switch (op2) {
23591        case OPC_MULEU_S_PH_QBL:
23592            check_dsp(ctx);
23593            gen_helper_muleu_s_ph_qbl(cpu_gpr[ret], v1_t, v2_t, cpu_env);
23594            break;
23595        case OPC_MULEU_S_PH_QBR:
23596            check_dsp(ctx);
23597            gen_helper_muleu_s_ph_qbr(cpu_gpr[ret], v1_t, v2_t, cpu_env);
23598            break;
23599        case OPC_MULQ_RS_PH:
23600            check_dsp(ctx);
23601            gen_helper_mulq_rs_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
23602            break;
23603        case OPC_MULEQ_S_W_PHL:
23604            check_dsp(ctx);
23605            gen_helper_muleq_s_w_phl(cpu_gpr[ret], v1_t, v2_t, cpu_env);
23606            break;
23607        case OPC_MULEQ_S_W_PHR:
23608            check_dsp(ctx);
23609            gen_helper_muleq_s_w_phr(cpu_gpr[ret], v1_t, v2_t, cpu_env);
23610            break;
23611        case OPC_MULQ_S_PH:
23612            check_dsp_r2(ctx);
23613            gen_helper_mulq_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
23614            break;
23615        }
23616        break;
23617#ifdef TARGET_MIPS64
23618    case OPC_ADDU_OB_DSP:
23619        switch (op2) {
23620        case OPC_MULEQ_S_PW_QHL:
23621            check_dsp(ctx);
23622            gen_helper_muleq_s_pw_qhl(cpu_gpr[ret], v1_t, v2_t, cpu_env);
23623            break;
23624        case OPC_MULEQ_S_PW_QHR:
23625            check_dsp(ctx);
23626            gen_helper_muleq_s_pw_qhr(cpu_gpr[ret], v1_t, v2_t, cpu_env);
23627            break;
23628        case OPC_MULEU_S_QH_OBL:
23629            check_dsp(ctx);
23630            gen_helper_muleu_s_qh_obl(cpu_gpr[ret], v1_t, v2_t, cpu_env);
23631            break;
23632        case OPC_MULEU_S_QH_OBR:
23633            check_dsp(ctx);
23634            gen_helper_muleu_s_qh_obr(cpu_gpr[ret], v1_t, v2_t, cpu_env);
23635            break;
23636        case OPC_MULQ_RS_QH:
23637            check_dsp(ctx);
23638            gen_helper_mulq_rs_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
23639            break;
23640        }
23641        break;
23642#endif
23643    }
23644
23645    tcg_temp_free_i32(t0);
23646    tcg_temp_free(v1_t);
23647    tcg_temp_free(v2_t);
23648}
23649
23650static void gen_mipsdsp_bitinsn(DisasContext *ctx, uint32_t op1, uint32_t op2,
23651                                int ret, int val)
23652{
23653    int16_t imm;
23654    TCGv t0;
23655    TCGv val_t;
23656
23657    if (ret == 0) {
23658        /* Treat as NOP. */
23659        return;
23660    }
23661
23662    t0 = tcg_temp_new();
23663    val_t = tcg_temp_new();
23664    gen_load_gpr(val_t, val);
23665
23666    switch (op1) {
23667    case OPC_ABSQ_S_PH_DSP:
23668        switch (op2) {
23669        case OPC_BITREV:
23670            check_dsp(ctx);
23671            gen_helper_bitrev(cpu_gpr[ret], val_t);
23672            break;
23673        case OPC_REPL_QB:
23674            check_dsp(ctx);
23675            {
23676                target_long result;
23677                imm = (ctx->opcode >> 16) & 0xFF;
23678                result = (uint32_t)imm << 24 |
23679                         (uint32_t)imm << 16 |
23680                         (uint32_t)imm << 8  |
23681                         (uint32_t)imm;
23682                result = (int32_t)result;
23683                tcg_gen_movi_tl(cpu_gpr[ret], result);
23684            }
23685            break;
23686        case OPC_REPLV_QB:
23687            check_dsp(ctx);
23688            tcg_gen_ext8u_tl(cpu_gpr[ret], val_t);
23689            tcg_gen_shli_tl(t0, cpu_gpr[ret], 8);
23690            tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
23691            tcg_gen_shli_tl(t0, cpu_gpr[ret], 16);
23692            tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
23693            tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]);
23694            break;
23695        case OPC_REPL_PH:
23696            check_dsp(ctx);
23697            {
23698                imm = (ctx->opcode >> 16) & 0x03FF;
23699                imm = (int16_t)(imm << 6) >> 6;
23700                tcg_gen_movi_tl(cpu_gpr[ret], \
23701                                (target_long)((int32_t)imm << 16 | \
23702                                (uint16_t)imm));
23703            }
23704            break;
23705        case OPC_REPLV_PH:
23706            check_dsp(ctx);
23707            tcg_gen_ext16u_tl(cpu_gpr[ret], val_t);
23708            tcg_gen_shli_tl(t0, cpu_gpr[ret], 16);
23709            tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
23710            tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]);
23711            break;
23712        }
23713        break;
23714#ifdef TARGET_MIPS64
23715    case OPC_ABSQ_S_QH_DSP:
23716        switch (op2) {
23717        case OPC_REPL_OB:
23718            check_dsp(ctx);
23719            {
23720                target_long temp;
23721
23722                imm = (ctx->opcode >> 16) & 0xFF;
23723                temp = ((uint64_t)imm << 8) | (uint64_t)imm;
23724                temp = (temp << 16) | temp;
23725                temp = (temp << 32) | temp;
23726                tcg_gen_movi_tl(cpu_gpr[ret], temp);
23727                break;
23728            }
23729        case OPC_REPL_PW:
23730            check_dsp(ctx);
23731            {
23732                target_long temp;
23733
23734                imm = (ctx->opcode >> 16) & 0x03FF;
23735                imm = (int16_t)(imm << 6) >> 6;
23736                temp = ((target_long)imm << 32) \
23737                       | ((target_long)imm & 0xFFFFFFFF);
23738                tcg_gen_movi_tl(cpu_gpr[ret], temp);
23739                break;
23740            }
23741        case OPC_REPL_QH:
23742            check_dsp(ctx);
23743            {
23744                target_long temp;
23745
23746                imm = (ctx->opcode >> 16) & 0x03FF;
23747                imm = (int16_t)(imm << 6) >> 6;
23748
23749                temp = ((uint64_t)(uint16_t)imm << 48) |
23750                       ((uint64_t)(uint16_t)imm << 32) |
23751                       ((uint64_t)(uint16_t)imm << 16) |
23752                       (uint64_t)(uint16_t)imm;
23753                tcg_gen_movi_tl(cpu_gpr[ret], temp);
23754                break;
23755            }
23756        case OPC_REPLV_OB:
23757            check_dsp(ctx);
23758            tcg_gen_ext8u_tl(cpu_gpr[ret], val_t);
23759            tcg_gen_shli_tl(t0, cpu_gpr[ret], 8);
23760            tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
23761            tcg_gen_shli_tl(t0, cpu_gpr[ret], 16);
23762            tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
23763            tcg_gen_shli_tl(t0, cpu_gpr[ret], 32);
23764            tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
23765            break;
23766        case OPC_REPLV_PW:
23767            check_dsp(ctx);
23768            tcg_gen_ext32u_i64(cpu_gpr[ret], val_t);
23769            tcg_gen_shli_tl(t0, cpu_gpr[ret], 32);
23770            tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
23771            break;
23772        case OPC_REPLV_QH:
23773            check_dsp(ctx);
23774            tcg_gen_ext16u_tl(cpu_gpr[ret], val_t);
23775            tcg_gen_shli_tl(t0, cpu_gpr[ret], 16);
23776            tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
23777            tcg_gen_shli_tl(t0, cpu_gpr[ret], 32);
23778            tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
23779            break;
23780        }
23781        break;
23782#endif
23783    }
23784    tcg_temp_free(t0);
23785    tcg_temp_free(val_t);
23786}
23787
23788static void gen_mipsdsp_add_cmp_pick(DisasContext *ctx,
23789                                     uint32_t op1, uint32_t op2,
23790                                     int ret, int v1, int v2, int check_ret)
23791{
23792    TCGv t1;
23793    TCGv v1_t;
23794    TCGv v2_t;
23795
23796    if ((ret == 0) && (check_ret == 1)) {
23797        /* Treat as NOP. */
23798        return;
23799    }
23800
23801    t1 = tcg_temp_new();
23802    v1_t = tcg_temp_new();
23803    v2_t = tcg_temp_new();
23804
23805    gen_load_gpr(v1_t, v1);
23806    gen_load_gpr(v2_t, v2);
23807
23808    switch (op1) {
23809    case OPC_CMPU_EQ_QB_DSP:
23810        switch (op2) {
23811        case OPC_CMPU_EQ_QB:
23812            check_dsp(ctx);
23813            gen_helper_cmpu_eq_qb(v1_t, v2_t, cpu_env);
23814            break;
23815        case OPC_CMPU_LT_QB:
23816            check_dsp(ctx);
23817            gen_helper_cmpu_lt_qb(v1_t, v2_t, cpu_env);
23818            break;
23819        case OPC_CMPU_LE_QB:
23820            check_dsp(ctx);
23821            gen_helper_cmpu_le_qb(v1_t, v2_t, cpu_env);
23822            break;
23823        case OPC_CMPGU_EQ_QB:
23824            check_dsp(ctx);
23825            gen_helper_cmpgu_eq_qb(cpu_gpr[ret], v1_t, v2_t);
23826            break;
23827        case OPC_CMPGU_LT_QB:
23828            check_dsp(ctx);
23829            gen_helper_cmpgu_lt_qb(cpu_gpr[ret], v1_t, v2_t);
23830            break;
23831        case OPC_CMPGU_LE_QB:
23832            check_dsp(ctx);
23833            gen_helper_cmpgu_le_qb(cpu_gpr[ret], v1_t, v2_t);
23834            break;
23835        case OPC_CMPGDU_EQ_QB:
23836            check_dsp_r2(ctx);
23837            gen_helper_cmpgu_eq_qb(t1, v1_t, v2_t);
23838            tcg_gen_mov_tl(cpu_gpr[ret], t1);
23839            tcg_gen_andi_tl(cpu_dspctrl, cpu_dspctrl, 0xF0FFFFFF);
23840            tcg_gen_shli_tl(t1, t1, 24);
23841            tcg_gen_or_tl(cpu_dspctrl, cpu_dspctrl, t1);
23842            break;
23843        case OPC_CMPGDU_LT_QB:
23844            check_dsp_r2(ctx);
23845            gen_helper_cmpgu_lt_qb(t1, v1_t, v2_t);
23846            tcg_gen_mov_tl(cpu_gpr[ret], t1);
23847            tcg_gen_andi_tl(cpu_dspctrl, cpu_dspctrl, 0xF0FFFFFF);
23848            tcg_gen_shli_tl(t1, t1, 24);
23849            tcg_gen_or_tl(cpu_dspctrl, cpu_dspctrl, t1);
23850            break;
23851        case OPC_CMPGDU_LE_QB:
23852            check_dsp_r2(ctx);
23853            gen_helper_cmpgu_le_qb(t1, v1_t, v2_t);
23854            tcg_gen_mov_tl(cpu_gpr[ret], t1);
23855            tcg_gen_andi_tl(cpu_dspctrl, cpu_dspctrl, 0xF0FFFFFF);
23856            tcg_gen_shli_tl(t1, t1, 24);
23857            tcg_gen_or_tl(cpu_dspctrl, cpu_dspctrl, t1);
23858            break;
23859        case OPC_CMP_EQ_PH:
23860            check_dsp(ctx);
23861            gen_helper_cmp_eq_ph(v1_t, v2_t, cpu_env);
23862            break;
23863        case OPC_CMP_LT_PH:
23864            check_dsp(ctx);
23865            gen_helper_cmp_lt_ph(v1_t, v2_t, cpu_env);
23866            break;
23867        case OPC_CMP_LE_PH:
23868            check_dsp(ctx);
23869            gen_helper_cmp_le_ph(v1_t, v2_t, cpu_env);
23870            break;
23871        case OPC_PICK_QB:
23872            check_dsp(ctx);
23873            gen_helper_pick_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
23874            break;
23875        case OPC_PICK_PH:
23876            check_dsp(ctx);
23877            gen_helper_pick_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
23878            break;
23879        case OPC_PACKRL_PH:
23880            check_dsp(ctx);
23881            gen_helper_packrl_ph(cpu_gpr[ret], v1_t, v2_t);
23882            break;
23883        }
23884        break;
23885#ifdef TARGET_MIPS64
23886    case OPC_CMPU_EQ_OB_DSP:
23887        switch (op2) {
23888        case OPC_CMP_EQ_PW:
23889            check_dsp(ctx);
23890            gen_helper_cmp_eq_pw(v1_t, v2_t, cpu_env);
23891            break;
23892        case OPC_CMP_LT_PW:
23893            check_dsp(ctx);
23894            gen_helper_cmp_lt_pw(v1_t, v2_t, cpu_env);
23895            break;
23896        case OPC_CMP_LE_PW:
23897            check_dsp(ctx);
23898            gen_helper_cmp_le_pw(v1_t, v2_t, cpu_env);
23899            break;
23900        case OPC_CMP_EQ_QH:
23901            check_dsp(ctx);
23902            gen_helper_cmp_eq_qh(v1_t, v2_t, cpu_env);
23903            break;
23904        case OPC_CMP_LT_QH:
23905            check_dsp(ctx);
23906            gen_helper_cmp_lt_qh(v1_t, v2_t, cpu_env);
23907            break;
23908        case OPC_CMP_LE_QH:
23909            check_dsp(ctx);
23910            gen_helper_cmp_le_qh(v1_t, v2_t, cpu_env);
23911            break;
23912        case OPC_CMPGDU_EQ_OB:
23913            check_dsp_r2(ctx);
23914            gen_helper_cmpgdu_eq_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
23915            break;
23916        case OPC_CMPGDU_LT_OB:
23917            check_dsp_r2(ctx);
23918            gen_helper_cmpgdu_lt_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
23919            break;
23920        case OPC_CMPGDU_LE_OB:
23921            check_dsp_r2(ctx);
23922            gen_helper_cmpgdu_le_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
23923            break;
23924        case OPC_CMPGU_EQ_OB:
23925            check_dsp(ctx);
23926            gen_helper_cmpgu_eq_ob(cpu_gpr[ret], v1_t, v2_t);
23927            break;
23928        case OPC_CMPGU_LT_OB:
23929            check_dsp(ctx);
23930            gen_helper_cmpgu_lt_ob(cpu_gpr[ret], v1_t, v2_t);
23931            break;
23932        case OPC_CMPGU_LE_OB:
23933            check_dsp(ctx);
23934            gen_helper_cmpgu_le_ob(cpu_gpr[ret], v1_t, v2_t);
23935            break;
23936        case OPC_CMPU_EQ_OB:
23937            check_dsp(ctx);
23938            gen_helper_cmpu_eq_ob(v1_t, v2_t, cpu_env);
23939            break;
23940        case OPC_CMPU_LT_OB:
23941            check_dsp(ctx);
23942            gen_helper_cmpu_lt_ob(v1_t, v2_t, cpu_env);
23943            break;
23944        case OPC_CMPU_LE_OB:
23945            check_dsp(ctx);
23946            gen_helper_cmpu_le_ob(v1_t, v2_t, cpu_env);
23947            break;
23948        case OPC_PACKRL_PW:
23949            check_dsp(ctx);
23950            gen_helper_packrl_pw(cpu_gpr[ret], v1_t, v2_t);
23951            break;
23952        case OPC_PICK_OB:
23953            check_dsp(ctx);
23954            gen_helper_pick_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
23955            break;
23956        case OPC_PICK_PW:
23957            check_dsp(ctx);
23958            gen_helper_pick_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
23959            break;
23960        case OPC_PICK_QH:
23961            check_dsp(ctx);
23962            gen_helper_pick_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
23963            break;
23964        }
23965        break;
23966#endif
23967    }
23968
23969    tcg_temp_free(t1);
23970    tcg_temp_free(v1_t);
23971    tcg_temp_free(v2_t);
23972}
23973
23974static void gen_mipsdsp_append(CPUMIPSState *env, DisasContext *ctx,
23975                               uint32_t op1, int rt, int rs, int sa)
23976{
23977    TCGv t0;
23978
23979    check_dsp_r2(ctx);
23980
23981    if (rt == 0) {
23982        /* Treat as NOP. */
23983        return;
23984    }
23985
23986    t0 = tcg_temp_new();
23987    gen_load_gpr(t0, rs);
23988
23989    switch (op1) {
23990    case OPC_APPEND_DSP:
23991        switch (MASK_APPEND(ctx->opcode)) {
23992        case OPC_APPEND:
23993            if (sa != 0) {
23994                tcg_gen_deposit_tl(cpu_gpr[rt], t0, cpu_gpr[rt], sa, 32 - sa);
23995            }
23996            tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
23997            break;
23998        case OPC_PREPEND:
23999            if (sa != 0) {
24000                tcg_gen_ext32u_tl(cpu_gpr[rt], cpu_gpr[rt]);
24001                tcg_gen_shri_tl(cpu_gpr[rt], cpu_gpr[rt], sa);
24002                tcg_gen_shli_tl(t0, t0, 32 - sa);
24003                tcg_gen_or_tl(cpu_gpr[rt], cpu_gpr[rt], t0);
24004            }
24005            tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
24006            break;
24007        case OPC_BALIGN:
24008            sa &= 3;
24009            if (sa != 0 && sa != 2) {
24010                tcg_gen_shli_tl(cpu_gpr[rt], cpu_gpr[rt], 8 * sa);
24011                tcg_gen_ext32u_tl(t0, t0);
24012                tcg_gen_shri_tl(t0, t0, 8 * (4 - sa));
24013                tcg_gen_or_tl(cpu_gpr[rt], cpu_gpr[rt], t0);
24014            }
24015            tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
24016            break;
24017        default:            /* Invalid */
24018            MIPS_INVAL("MASK APPEND");
24019            generate_exception_end(ctx, EXCP_RI);
24020            break;
24021        }
24022        break;
24023#ifdef TARGET_MIPS64
24024    case OPC_DAPPEND_DSP:
24025        switch (MASK_DAPPEND(ctx->opcode)) {
24026        case OPC_DAPPEND:
24027            if (sa != 0) {
24028                tcg_gen_deposit_tl(cpu_gpr[rt], t0, cpu_gpr[rt], sa, 64 - sa);
24029            }
24030            break;
24031        case OPC_PREPENDD:
24032            tcg_gen_shri_tl(cpu_gpr[rt], cpu_gpr[rt], 0x20 | sa);
24033            tcg_gen_shli_tl(t0, t0, 64 - (0x20 | sa));
24034            tcg_gen_or_tl(cpu_gpr[rt], t0, t0);
24035            break;
24036        case OPC_PREPENDW:
24037            if (sa != 0) {
24038                tcg_gen_shri_tl(cpu_gpr[rt], cpu_gpr[rt], sa);
24039                tcg_gen_shli_tl(t0, t0, 64 - sa);
24040                tcg_gen_or_tl(cpu_gpr[rt], cpu_gpr[rt], t0);
24041            }
24042            break;
24043        case OPC_DBALIGN:
24044            sa &= 7;
24045            if (sa != 0 && sa != 2 && sa != 4) {
24046                tcg_gen_shli_tl(cpu_gpr[rt], cpu_gpr[rt], 8 * sa);
24047                tcg_gen_shri_tl(t0, t0, 8 * (8 - sa));
24048                tcg_gen_or_tl(cpu_gpr[rt], cpu_gpr[rt], t0);
24049            }
24050            break;
24051        default:            /* Invalid */
24052            MIPS_INVAL("MASK DAPPEND");
24053            generate_exception_end(ctx, EXCP_RI);
24054            break;
24055        }
24056        break;
24057#endif
24058    }
24059    tcg_temp_free(t0);
24060}
24061
24062static void gen_mipsdsp_accinsn(DisasContext *ctx, uint32_t op1, uint32_t op2,
24063                                int ret, int v1, int v2, int check_ret)
24064
24065{
24066    TCGv t0;
24067    TCGv t1;
24068    TCGv v1_t;
24069    TCGv v2_t;
24070    int16_t imm;
24071
24072    if ((ret == 0) && (check_ret == 1)) {
24073        /* Treat as NOP. */
24074        return;
24075    }
24076
24077    t0 = tcg_temp_new();
24078    t1 = tcg_temp_new();
24079    v1_t = tcg_temp_new();
24080    v2_t = tcg_temp_new();
24081
24082    gen_load_gpr(v1_t, v1);
24083    gen_load_gpr(v2_t, v2);
24084
24085    switch (op1) {
24086    case OPC_EXTR_W_DSP:
24087        check_dsp(ctx);
24088        switch (op2) {
24089        case OPC_EXTR_W:
24090            tcg_gen_movi_tl(t0, v2);
24091            tcg_gen_movi_tl(t1, v1);
24092            gen_helper_extr_w(cpu_gpr[ret], t0, t1, cpu_env);
24093            break;
24094        case OPC_EXTR_R_W:
24095            tcg_gen_movi_tl(t0, v2);
24096            tcg_gen_movi_tl(t1, v1);
24097            gen_helper_extr_r_w(cpu_gpr[ret], t0, t1, cpu_env);
24098            break;
24099        case OPC_EXTR_RS_W:
24100            tcg_gen_movi_tl(t0, v2);
24101            tcg_gen_movi_tl(t1, v1);
24102            gen_helper_extr_rs_w(cpu_gpr[ret], t0, t1, cpu_env);
24103            break;
24104        case OPC_EXTR_S_H:
24105            tcg_gen_movi_tl(t0, v2);
24106            tcg_gen_movi_tl(t1, v1);
24107            gen_helper_extr_s_h(cpu_gpr[ret], t0, t1, cpu_env);
24108            break;
24109        case OPC_EXTRV_S_H:
24110            tcg_gen_movi_tl(t0, v2);
24111            gen_helper_extr_s_h(cpu_gpr[ret], t0, v1_t, cpu_env);
24112            break;
24113        case OPC_EXTRV_W:
24114            tcg_gen_movi_tl(t0, v2);
24115            gen_helper_extr_w(cpu_gpr[ret], t0, v1_t, cpu_env);
24116            break;
24117        case OPC_EXTRV_R_W:
24118            tcg_gen_movi_tl(t0, v2);
24119            gen_helper_extr_r_w(cpu_gpr[ret], t0, v1_t, cpu_env);
24120            break;
24121        case OPC_EXTRV_RS_W:
24122            tcg_gen_movi_tl(t0, v2);
24123            gen_helper_extr_rs_w(cpu_gpr[ret], t0, v1_t, cpu_env);
24124            break;
24125        case OPC_EXTP:
24126            tcg_gen_movi_tl(t0, v2);
24127            tcg_gen_movi_tl(t1, v1);
24128            gen_helper_extp(cpu_gpr[ret], t0, t1, cpu_env);
24129            break;
24130        case OPC_EXTPV:
24131            tcg_gen_movi_tl(t0, v2);
24132            gen_helper_extp(cpu_gpr[ret], t0, v1_t, cpu_env);
24133            break;
24134        case OPC_EXTPDP:
24135            tcg_gen_movi_tl(t0, v2);
24136            tcg_gen_movi_tl(t1, v1);
24137            gen_helper_extpdp(cpu_gpr[ret], t0, t1, cpu_env);
24138            break;
24139        case OPC_EXTPDPV:
24140            tcg_gen_movi_tl(t0, v2);
24141            gen_helper_extpdp(cpu_gpr[ret], t0, v1_t, cpu_env);
24142            break;
24143        case OPC_SHILO:
24144            imm = (ctx->opcode >> 20) & 0x3F;
24145            tcg_gen_movi_tl(t0, ret);
24146            tcg_gen_movi_tl(t1, imm);
24147            gen_helper_shilo(t0, t1, cpu_env);
24148            break;
24149        case OPC_SHILOV:
24150            tcg_gen_movi_tl(t0, ret);
24151            gen_helper_shilo(t0, v1_t, cpu_env);
24152            break;
24153        case OPC_MTHLIP:
24154            tcg_gen_movi_tl(t0, ret);
24155            gen_helper_mthlip(t0, v1_t, cpu_env);
24156            break;
24157        case OPC_WRDSP:
24158            imm = (ctx->opcode >> 11) & 0x3FF;
24159            tcg_gen_movi_tl(t0, imm);
24160            gen_helper_wrdsp(v1_t, t0, cpu_env);
24161            break;
24162        case OPC_RDDSP:
24163            imm = (ctx->opcode >> 16) & 0x03FF;
24164            tcg_gen_movi_tl(t0, imm);
24165            gen_helper_rddsp(cpu_gpr[ret], t0, cpu_env);
24166            break;
24167        }
24168        break;
24169#ifdef TARGET_MIPS64
24170    case OPC_DEXTR_W_DSP:
24171        check_dsp(ctx);
24172        switch (op2) {
24173        case OPC_DMTHLIP:
24174            tcg_gen_movi_tl(t0, ret);
24175            gen_helper_dmthlip(v1_t, t0, cpu_env);
24176            break;
24177        case OPC_DSHILO:
24178            {
24179                int shift = (ctx->opcode >> 19) & 0x7F;
24180                int ac = (ctx->opcode >> 11) & 0x03;
24181                tcg_gen_movi_tl(t0, shift);
24182                tcg_gen_movi_tl(t1, ac);
24183                gen_helper_dshilo(t0, t1, cpu_env);
24184                break;
24185            }
24186        case OPC_DSHILOV:
24187            {
24188                int ac = (ctx->opcode >> 11) & 0x03;
24189                tcg_gen_movi_tl(t0, ac);
24190                gen_helper_dshilo(v1_t, t0, cpu_env);
24191                break;
24192            }
24193        case OPC_DEXTP:
24194            tcg_gen_movi_tl(t0, v2);
24195            tcg_gen_movi_tl(t1, v1);
24196
24197            gen_helper_dextp(cpu_gpr[ret], t0, t1, cpu_env);
24198            break;
24199        case OPC_DEXTPV:
24200            tcg_gen_movi_tl(t0, v2);
24201            gen_helper_dextp(cpu_gpr[ret], t0, v1_t, cpu_env);
24202            break;
24203        case OPC_DEXTPDP:
24204            tcg_gen_movi_tl(t0, v2);
24205            tcg_gen_movi_tl(t1, v1);
24206            gen_helper_dextpdp(cpu_gpr[ret], t0, t1, cpu_env);
24207            break;
24208        case OPC_DEXTPDPV:
24209            tcg_gen_movi_tl(t0, v2);
24210            gen_helper_dextpdp(cpu_gpr[ret], t0, v1_t, cpu_env);
24211            break;
24212        case OPC_DEXTR_L:
24213            tcg_gen_movi_tl(t0, v2);
24214            tcg_gen_movi_tl(t1, v1);
24215            gen_helper_dextr_l(cpu_gpr[ret], t0, t1, cpu_env);
24216            break;
24217        case OPC_DEXTR_R_L:
24218            tcg_gen_movi_tl(t0, v2);
24219            tcg_gen_movi_tl(t1, v1);
24220            gen_helper_dextr_r_l(cpu_gpr[ret], t0, t1, cpu_env);
24221            break;
24222        case OPC_DEXTR_RS_L:
24223            tcg_gen_movi_tl(t0, v2);
24224            tcg_gen_movi_tl(t1, v1);
24225            gen_helper_dextr_rs_l(cpu_gpr[ret], t0, t1, cpu_env);
24226            break;
24227        case OPC_DEXTR_W:
24228            tcg_gen_movi_tl(t0, v2);
24229            tcg_gen_movi_tl(t1, v1);
24230            gen_helper_dextr_w(cpu_gpr[ret], t0, t1, cpu_env);
24231            break;
24232        case OPC_DEXTR_R_W:
24233            tcg_gen_movi_tl(t0, v2);
24234            tcg_gen_movi_tl(t1, v1);
24235            gen_helper_dextr_r_w(cpu_gpr[ret], t0, t1, cpu_env);
24236            break;
24237        case OPC_DEXTR_RS_W:
24238            tcg_gen_movi_tl(t0, v2);
24239            tcg_gen_movi_tl(t1, v1);
24240            gen_helper_dextr_rs_w(cpu_gpr[ret], t0, t1, cpu_env);
24241            break;
24242        case OPC_DEXTR_S_H:
24243            tcg_gen_movi_tl(t0, v2);
24244            tcg_gen_movi_tl(t1, v1);
24245            gen_helper_dextr_s_h(cpu_gpr[ret], t0, t1, cpu_env);
24246            break;
24247        case OPC_DEXTRV_S_H:
24248            tcg_gen_movi_tl(t0, v2);
24249            tcg_gen_movi_tl(t1, v1);
24250            gen_helper_dextr_s_h(cpu_gpr[ret], t0, t1, cpu_env);
24251            break;
24252        case OPC_DEXTRV_L:
24253            tcg_gen_movi_tl(t0, v2);
24254            gen_helper_dextr_l(cpu_gpr[ret], t0, v1_t, cpu_env);
24255            break;
24256        case OPC_DEXTRV_R_L:
24257            tcg_gen_movi_tl(t0, v2);
24258            gen_helper_dextr_r_l(cpu_gpr[ret], t0, v1_t, cpu_env);
24259            break;
24260        case OPC_DEXTRV_RS_L:
24261            tcg_gen_movi_tl(t0, v2);
24262            gen_helper_dextr_rs_l(cpu_gpr[ret], t0, v1_t, cpu_env);
24263            break;
24264        case OPC_DEXTRV_W:
24265            tcg_gen_movi_tl(t0, v2);
24266            gen_helper_dextr_w(cpu_gpr[ret], t0, v1_t, cpu_env);
24267            break;
24268        case OPC_DEXTRV_R_W:
24269            tcg_gen_movi_tl(t0, v2);
24270            gen_helper_dextr_r_w(cpu_gpr[ret], t0, v1_t, cpu_env);
24271            break;
24272        case OPC_DEXTRV_RS_W:
24273            tcg_gen_movi_tl(t0, v2);
24274            gen_helper_dextr_rs_w(cpu_gpr[ret], t0, v1_t, cpu_env);
24275            break;
24276        }
24277        break;
24278#endif
24279    }
24280
24281    tcg_temp_free(t0);
24282    tcg_temp_free(t1);
24283    tcg_temp_free(v1_t);
24284    tcg_temp_free(v2_t);
24285}
24286
24287/* End MIPSDSP functions. */
24288
24289static void decode_opc_special_r6(CPUMIPSState *env, DisasContext *ctx)
24290{
24291    int rs, rt, rd, sa;
24292    uint32_t op1, op2;
24293
24294    rs = (ctx->opcode >> 21) & 0x1f;
24295    rt = (ctx->opcode >> 16) & 0x1f;
24296    rd = (ctx->opcode >> 11) & 0x1f;
24297    sa = (ctx->opcode >> 6) & 0x1f;
24298
24299    op1 = MASK_SPECIAL(ctx->opcode);
24300    switch (op1) {
24301    case OPC_LSA:
24302        gen_lsa(ctx, op1, rd, rs, rt, extract32(ctx->opcode, 6, 2));
24303        break;
24304    case OPC_MULT:
24305    case OPC_MULTU:
24306    case OPC_DIV:
24307    case OPC_DIVU:
24308        op2 = MASK_R6_MULDIV(ctx->opcode);
24309        switch (op2) {
24310        case R6_OPC_MUL:
24311        case R6_OPC_MUH:
24312        case R6_OPC_MULU:
24313        case R6_OPC_MUHU:
24314        case R6_OPC_DIV:
24315        case R6_OPC_MOD:
24316        case R6_OPC_DIVU:
24317        case R6_OPC_MODU:
24318            gen_r6_muldiv(ctx, op2, rd, rs, rt);
24319            break;
24320        default:
24321            MIPS_INVAL("special_r6 muldiv");
24322            generate_exception_end(ctx, EXCP_RI);
24323            break;
24324        }
24325        break;
24326    case OPC_SELEQZ:
24327    case OPC_SELNEZ:
24328        gen_cond_move(ctx, op1, rd, rs, rt);
24329        break;
24330    case R6_OPC_CLO:
24331    case R6_OPC_CLZ:
24332        if (rt == 0 && sa == 1) {
24333            /*
24334             * Major opcode and function field is shared with preR6 MFHI/MTHI.
24335             * We need additionally to check other fields.
24336             */
24337            gen_cl(ctx, op1, rd, rs);
24338        } else {
24339            generate_exception_end(ctx, EXCP_RI);
24340        }
24341        break;
24342    case R6_OPC_SDBBP:
24343        if (is_uhi(extract32(ctx->opcode, 6, 20))) {
24344            gen_helper_do_semihosting(cpu_env);
24345        } else {
24346            if (ctx->hflags & MIPS_HFLAG_SBRI) {
24347                generate_exception_end(ctx, EXCP_RI);
24348            } else {
24349                generate_exception_end(ctx, EXCP_DBp);
24350            }
24351        }
24352        break;
24353#if defined(TARGET_MIPS64)
24354    case OPC_DLSA:
24355        check_mips_64(ctx);
24356        gen_lsa(ctx, op1, rd, rs, rt, extract32(ctx->opcode, 6, 2));
24357        break;
24358    case R6_OPC_DCLO:
24359    case R6_OPC_DCLZ:
24360        if (rt == 0 && sa == 1) {
24361            /*
24362             * Major opcode and function field is shared with preR6 MFHI/MTHI.
24363             * We need additionally to check other fields.
24364             */
24365            check_mips_64(ctx);
24366            gen_cl(ctx, op1, rd, rs);
24367        } else {
24368            generate_exception_end(ctx, EXCP_RI);
24369        }
24370        break;
24371    case OPC_DMULT:
24372    case OPC_DMULTU:
24373    case OPC_DDIV:
24374    case OPC_DDIVU:
24375
24376        op2 = MASK_R6_MULDIV(ctx->opcode);
24377        switch (op2) {
24378        case R6_OPC_DMUL:
24379        case R6_OPC_DMUH:
24380        case R6_OPC_DMULU:
24381        case R6_OPC_DMUHU:
24382        case R6_OPC_DDIV:
24383        case R6_OPC_DMOD:
24384        case R6_OPC_DDIVU:
24385        case R6_OPC_DMODU:
24386            check_mips_64(ctx);
24387            gen_r6_muldiv(ctx, op2, rd, rs, rt);
24388            break;
24389        default:
24390            MIPS_INVAL("special_r6 muldiv");
24391            generate_exception_end(ctx, EXCP_RI);
24392            break;
24393        }
24394        break;
24395#endif
24396    default:            /* Invalid */
24397        MIPS_INVAL("special_r6");
24398        generate_exception_end(ctx, EXCP_RI);
24399        break;
24400    }
24401}
24402
24403static void decode_opc_special_tx79(CPUMIPSState *env, DisasContext *ctx)
24404{
24405    int rs = extract32(ctx->opcode, 21, 5);
24406    int rt = extract32(ctx->opcode, 16, 5);
24407    int rd = extract32(ctx->opcode, 11, 5);
24408    uint32_t op1 = MASK_SPECIAL(ctx->opcode);
24409
24410    switch (op1) {
24411    case OPC_MOVN:         /* Conditional move */
24412    case OPC_MOVZ:
24413        gen_cond_move(ctx, op1, rd, rs, rt);
24414        break;
24415    case OPC_MFHI:          /* Move from HI/LO */
24416    case OPC_MFLO:
24417        gen_HILO(ctx, op1, 0, rd);
24418        break;
24419    case OPC_MTHI:
24420    case OPC_MTLO:          /* Move to HI/LO */
24421        gen_HILO(ctx, op1, 0, rs);
24422        break;
24423    case OPC_MULT:
24424    case OPC_MULTU:
24425        gen_mul_txx9(ctx, op1, rd, rs, rt);
24426        break;
24427    case OPC_DIV:
24428    case OPC_DIVU:
24429        gen_muldiv(ctx, op1, 0, rs, rt);
24430        break;
24431#if defined(TARGET_MIPS64)
24432    case OPC_DMULT:
24433    case OPC_DMULTU:
24434    case OPC_DDIV:
24435    case OPC_DDIVU:
24436        check_insn_opc_user_only(ctx, INSN_R5900);
24437        gen_muldiv(ctx, op1, 0, rs, rt);
24438        break;
24439#endif
24440    case OPC_JR:
24441        gen_compute_branch(ctx, op1, 4, rs, 0, 0, 4);
24442        break;
24443    default:            /* Invalid */
24444        MIPS_INVAL("special_tx79");
24445        generate_exception_end(ctx, EXCP_RI);
24446        break;
24447    }
24448}
24449
24450static void decode_opc_special_legacy(CPUMIPSState *env, DisasContext *ctx)
24451{
24452    int rs, rt, rd, sa;
24453    uint32_t op1;
24454
24455    rs = (ctx->opcode >> 21) & 0x1f;
24456    rt = (ctx->opcode >> 16) & 0x1f;
24457    rd = (ctx->opcode >> 11) & 0x1f;
24458    sa = (ctx->opcode >> 6) & 0x1f;
24459
24460    op1 = MASK_SPECIAL(ctx->opcode);
24461    switch (op1) {
24462    case OPC_MOVN:         /* Conditional move */
24463    case OPC_MOVZ:
24464        check_insn(ctx, ISA_MIPS4 | ISA_MIPS32 |
24465                   INSN_LOONGSON2E | INSN_LOONGSON2F);
24466        gen_cond_move(ctx, op1, rd, rs, rt);
24467        break;
24468    case OPC_MFHI:          /* Move from HI/LO */
24469    case OPC_MFLO:
24470        gen_HILO(ctx, op1, rs & 3, rd);
24471        break;
24472    case OPC_MTHI:
24473    case OPC_MTLO:          /* Move to HI/LO */
24474        gen_HILO(ctx, op1, rd & 3, rs);
24475        break;
24476    case OPC_MOVCI:
24477        check_insn(ctx, ISA_MIPS4 | ISA_MIPS32);
24478        if (env->CP0_Config1 & (1 << CP0C1_FP)) {
24479            check_cp1_enabled(ctx);
24480            gen_movci(ctx, rd, rs, (ctx->opcode >> 18) & 0x7,
24481                      (ctx->opcode >> 16) & 1);
24482        } else {
24483            generate_exception_err(ctx, EXCP_CpU, 1);
24484        }
24485        break;
24486    case OPC_MULT:
24487    case OPC_MULTU:
24488        if (sa) {
24489            check_insn(ctx, INSN_VR54XX);
24490            op1 = MASK_MUL_VR54XX(ctx->opcode);
24491            gen_mul_vr54xx(ctx, op1, rd, rs, rt);
24492        } else {
24493            gen_muldiv(ctx, op1, rd & 3, rs, rt);
24494        }
24495        break;
24496    case OPC_DIV:
24497    case OPC_DIVU:
24498        gen_muldiv(ctx, op1, 0, rs, rt);
24499        break;
24500#if defined(TARGET_MIPS64)
24501    case OPC_DMULT:
24502    case OPC_DMULTU:
24503    case OPC_DDIV:
24504    case OPC_DDIVU:
24505        check_insn(ctx, ISA_MIPS3);
24506        check_mips_64(ctx);
24507        gen_muldiv(ctx, op1, 0, rs, rt);
24508        break;
24509#endif
24510    case OPC_JR:
24511        gen_compute_branch(ctx, op1, 4, rs, rd, sa, 4);
24512        break;
24513    case OPC_SPIM:
24514#ifdef MIPS_STRICT_STANDARD
24515        MIPS_INVAL("SPIM");
24516        generate_exception_end(ctx, EXCP_RI);
24517#else
24518        /* Implemented as RI exception for now. */
24519        MIPS_INVAL("spim (unofficial)");
24520        generate_exception_end(ctx, EXCP_RI);
24521#endif
24522        break;
24523    default:            /* Invalid */
24524        MIPS_INVAL("special_legacy");
24525        generate_exception_end(ctx, EXCP_RI);
24526        break;
24527    }
24528}
24529
24530static void decode_opc_special(CPUMIPSState *env, DisasContext *ctx)
24531{
24532    int rs, rt, rd, sa;
24533    uint32_t op1;
24534
24535    rs = (ctx->opcode >> 21) & 0x1f;
24536    rt = (ctx->opcode >> 16) & 0x1f;
24537    rd = (ctx->opcode >> 11) & 0x1f;
24538    sa = (ctx->opcode >> 6) & 0x1f;
24539
24540    op1 = MASK_SPECIAL(ctx->opcode);
24541    switch (op1) {
24542    case OPC_SLL:          /* Shift with immediate */
24543        if (sa == 5 && rd == 0 &&
24544            rs == 0 && rt == 0) { /* PAUSE */
24545            if ((ctx->insn_flags & ISA_MIPS32R6) &&
24546                (ctx->hflags & MIPS_HFLAG_BMASK)) {
24547                generate_exception_end(ctx, EXCP_RI);
24548                break;
24549            }
24550        }
24551        /* Fallthrough */
24552    case OPC_SRA:
24553        gen_shift_imm(ctx, op1, rd, rt, sa);
24554        break;
24555    case OPC_SRL:
24556        switch ((ctx->opcode >> 21) & 0x1f) {
24557        case 1:
24558            /* rotr is decoded as srl on non-R2 CPUs */
24559            if (ctx->insn_flags & ISA_MIPS32R2) {
24560                op1 = OPC_ROTR;
24561            }
24562            /* Fallthrough */
24563        case 0:
24564            gen_shift_imm(ctx, op1, rd, rt, sa);
24565            break;
24566        default:
24567            generate_exception_end(ctx, EXCP_RI);
24568            break;
24569        }
24570        break;
24571    case OPC_ADD:
24572    case OPC_ADDU:
24573    case OPC_SUB:
24574    case OPC_SUBU:
24575        gen_arith(ctx, op1, rd, rs, rt);
24576        break;
24577    case OPC_SLLV:         /* Shifts */
24578    case OPC_SRAV:
24579        gen_shift(ctx, op1, rd, rs, rt);
24580        break;
24581    case OPC_SRLV:
24582        switch ((ctx->opcode >> 6) & 0x1f) {
24583        case 1:
24584            /* rotrv is decoded as srlv on non-R2 CPUs */
24585            if (ctx->insn_flags & ISA_MIPS32R2) {
24586                op1 = OPC_ROTRV;
24587            }
24588            /* Fallthrough */
24589        case 0:
24590            gen_shift(ctx, op1, rd, rs, rt);
24591            break;
24592        default:
24593            generate_exception_end(ctx, EXCP_RI);
24594            break;
24595        }
24596        break;
24597    case OPC_SLT:          /* Set on less than */
24598    case OPC_SLTU:
24599        gen_slt(ctx, op1, rd, rs, rt);
24600        break;
24601    case OPC_AND:          /* Logic*/
24602    case OPC_OR:
24603    case OPC_NOR:
24604    case OPC_XOR:
24605        gen_logic(ctx, op1, rd, rs, rt);
24606        break;
24607    case OPC_JALR:
24608        gen_compute_branch(ctx, op1, 4, rs, rd, sa, 4);
24609        break;
24610    case OPC_TGE: /* Traps */
24611    case OPC_TGEU:
24612    case OPC_TLT:
24613    case OPC_TLTU:
24614    case OPC_TEQ:
24615    case OPC_TNE:
24616        check_insn(ctx, ISA_MIPS2);
24617        gen_trap(ctx, op1, rs, rt, -1);
24618        break;
24619    case OPC_LSA: /* OPC_PMON */
24620        if ((ctx->insn_flags & ISA_MIPS32R6) ||
24621            (env->CP0_Config3 & (1 << CP0C3_MSAP))) {
24622            decode_opc_special_r6(env, ctx);
24623        } else {
24624            /* Pmon entry point, also R4010 selsl */
24625#ifdef MIPS_STRICT_STANDARD
24626            MIPS_INVAL("PMON / selsl");
24627            generate_exception_end(ctx, EXCP_RI);
24628#else
24629            gen_helper_0e0i(pmon, sa);
24630#endif
24631        }
24632        break;
24633    case OPC_SYSCALL:
24634        generate_exception_end(ctx, EXCP_SYSCALL);
24635        break;
24636    case OPC_BREAK:
24637        generate_exception_end(ctx, EXCP_BREAK);
24638        break;
24639    case OPC_SYNC:
24640        check_insn(ctx, ISA_MIPS2);
24641        gen_sync(extract32(ctx->opcode, 6, 5));
24642        break;
24643
24644#if defined(TARGET_MIPS64)
24645        /* MIPS64 specific opcodes */
24646    case OPC_DSLL:
24647    case OPC_DSRA:
24648    case OPC_DSLL32:
24649    case OPC_DSRA32:
24650        check_insn(ctx, ISA_MIPS3);
24651        check_mips_64(ctx);
24652        gen_shift_imm(ctx, op1, rd, rt, sa);
24653        break;
24654    case OPC_DSRL:
24655        switch ((ctx->opcode >> 21) & 0x1f) {
24656        case 1:
24657            /* drotr is decoded as dsrl on non-R2 CPUs */
24658            if (ctx->insn_flags & ISA_MIPS32R2) {
24659                op1 = OPC_DROTR;
24660            }
24661            /* Fallthrough */
24662        case 0:
24663            check_insn(ctx, ISA_MIPS3);
24664            check_mips_64(ctx);
24665            gen_shift_imm(ctx, op1, rd, rt, sa);
24666            break;
24667        default:
24668            generate_exception_end(ctx, EXCP_RI);
24669            break;
24670        }
24671        break;
24672    case OPC_DSRL32:
24673        switch ((ctx->opcode >> 21) & 0x1f) {
24674        case 1:
24675            /* drotr32 is decoded as dsrl32 on non-R2 CPUs */
24676            if (ctx->insn_flags & ISA_MIPS32R2) {
24677                op1 = OPC_DROTR32;
24678            }
24679            /* Fallthrough */
24680        case 0:
24681            check_insn(ctx, ISA_MIPS3);
24682            check_mips_64(ctx);
24683            gen_shift_imm(ctx, op1, rd, rt, sa);
24684            break;
24685        default:
24686            generate_exception_end(ctx, EXCP_RI);
24687            break;
24688        }
24689        break;
24690    case OPC_DADD:
24691    case OPC_DADDU:
24692    case OPC_DSUB:
24693    case OPC_DSUBU:
24694        check_insn(ctx, ISA_MIPS3);
24695        check_mips_64(ctx);
24696        gen_arith(ctx, op1, rd, rs, rt);
24697        break;
24698    case OPC_DSLLV:
24699    case OPC_DSRAV:
24700        check_insn(ctx, ISA_MIPS3);
24701        check_mips_64(ctx);
24702        gen_shift(ctx, op1, rd, rs, rt);
24703        break;
24704    case OPC_DSRLV:
24705        switch ((ctx->opcode >> 6) & 0x1f) {
24706        case 1:
24707            /* drotrv is decoded as dsrlv on non-R2 CPUs */
24708            if (ctx->insn_flags & ISA_MIPS32R2) {
24709                op1 = OPC_DROTRV;
24710            }
24711            /* Fallthrough */
24712        case 0:
24713            check_insn(ctx, ISA_MIPS3);
24714            check_mips_64(ctx);
24715            gen_shift(ctx, op1, rd, rs, rt);
24716            break;
24717        default:
24718            generate_exception_end(ctx, EXCP_RI);
24719            break;
24720        }
24721        break;
24722    case OPC_DLSA:
24723        if ((ctx->insn_flags & ISA_MIPS32R6) ||
24724            (env->CP0_Config3 & (1 << CP0C3_MSAP))) {
24725            decode_opc_special_r6(env, ctx);
24726        }
24727        break;
24728#endif
24729    default:
24730        if (ctx->insn_flags & ISA_MIPS32R6) {
24731            decode_opc_special_r6(env, ctx);
24732        } else if (ctx->insn_flags & INSN_R5900) {
24733            decode_opc_special_tx79(env, ctx);
24734        } else {
24735            decode_opc_special_legacy(env, ctx);
24736        }
24737    }
24738}
24739
24740
24741#if defined(TARGET_MIPS64)
24742
24743/*
24744 *
24745 *           MMI (MultiMedia Interface) ASE instructions
24746 *           ===========================================
24747 */
24748
24749/*
24750 *          MMI instructions category: data communication
24751 *          ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
24752 *
24753 *   PCPYH    PEXCH    PEXTLB   PINTH    PPACB    PEXT5    PREVH
24754 *   PCPYLD   PEXCW    PEXTLH   PINTEH   PPACH    PPAC5    PROT3W
24755 *   PCPYUD   PEXEH    PEXTLW            PPACW
24756 *            PEXEW    PEXTUB
24757 *                     PEXTUH
24758 *                     PEXTUW
24759 */
24760
24761/*
24762 *  PCPYH rd, rt
24763 *
24764 *    Parallel Copy Halfword
24765 *
24766 *   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
24767 *  +-----------+---------+---------+---------+---------+-----------+
24768 *  |    MMI    |0 0 0 0 0|   rt    |   rd    |  PCPYH  |    MMI3   |
24769 *  +-----------+---------+---------+---------+---------+-----------+
24770 */
24771static void gen_mmi_pcpyh(DisasContext *ctx)
24772{
24773    uint32_t pd, rt, rd;
24774    uint32_t opcode;
24775
24776    opcode = ctx->opcode;
24777
24778    pd = extract32(opcode, 21, 5);
24779    rt = extract32(opcode, 16, 5);
24780    rd = extract32(opcode, 11, 5);
24781
24782    if (unlikely(pd != 0)) {
24783        generate_exception_end(ctx, EXCP_RI);
24784    } else if (rd == 0) {
24785        /* nop */
24786    } else if (rt == 0) {
24787        tcg_gen_movi_i64(cpu_gpr[rd], 0);
24788        tcg_gen_movi_i64(cpu_mmr[rd], 0);
24789    } else {
24790        TCGv_i64 t0 = tcg_temp_new();
24791        TCGv_i64 t1 = tcg_temp_new();
24792        uint64_t mask = (1ULL << 16) - 1;
24793
24794        tcg_gen_andi_i64(t0, cpu_gpr[rt], mask);
24795        tcg_gen_movi_i64(t1, 0);
24796        tcg_gen_or_i64(t1, t0, t1);
24797        tcg_gen_shli_i64(t0, t0, 16);
24798        tcg_gen_or_i64(t1, t0, t1);
24799        tcg_gen_shli_i64(t0, t0, 16);
24800        tcg_gen_or_i64(t1, t0, t1);
24801        tcg_gen_shli_i64(t0, t0, 16);
24802        tcg_gen_or_i64(t1, t0, t1);
24803
24804        tcg_gen_mov_i64(cpu_gpr[rd], t1);
24805
24806        tcg_gen_andi_i64(t0, cpu_mmr[rt], mask);
24807        tcg_gen_movi_i64(t1, 0);
24808        tcg_gen_or_i64(t1, t0, t1);
24809        tcg_gen_shli_i64(t0, t0, 16);
24810        tcg_gen_or_i64(t1, t0, t1);
24811        tcg_gen_shli_i64(t0, t0, 16);
24812        tcg_gen_or_i64(t1, t0, t1);
24813        tcg_gen_shli_i64(t0, t0, 16);
24814        tcg_gen_or_i64(t1, t0, t1);
24815
24816        tcg_gen_mov_i64(cpu_mmr[rd], t1);
24817
24818        tcg_temp_free(t0);
24819        tcg_temp_free(t1);
24820    }
24821}
24822
24823/*
24824 *  PCPYLD rd, rs, rt
24825 *
24826 *    Parallel Copy Lower Doubleword
24827 *
24828 *   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
24829 *  +-----------+---------+---------+---------+---------+-----------+
24830 *  |    MMI    |   rs    |   rt    |   rd    | PCPYLD  |    MMI2   |
24831 *  +-----------+---------+---------+---------+---------+-----------+
24832 */
24833static void gen_mmi_pcpyld(DisasContext *ctx)
24834{
24835    uint32_t rs, rt, rd;
24836    uint32_t opcode;
24837
24838    opcode = ctx->opcode;
24839
24840    rs = extract32(opcode, 21, 5);
24841    rt = extract32(opcode, 16, 5);
24842    rd = extract32(opcode, 11, 5);
24843
24844    if (rd == 0) {
24845        /* nop */
24846    } else {
24847        if (rs == 0) {
24848            tcg_gen_movi_i64(cpu_mmr[rd], 0);
24849        } else {
24850            tcg_gen_mov_i64(cpu_mmr[rd], cpu_gpr[rs]);
24851        }
24852        if (rt == 0) {
24853            tcg_gen_movi_i64(cpu_gpr[rd], 0);
24854        } else {
24855            if (rd != rt) {
24856                tcg_gen_mov_i64(cpu_gpr[rd], cpu_gpr[rt]);
24857            }
24858        }
24859    }
24860}
24861
24862/*
24863 *  PCPYUD rd, rs, rt
24864 *
24865 *    Parallel Copy Upper Doubleword
24866 *
24867 *   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
24868 *  +-----------+---------+---------+---------+---------+-----------+
24869 *  |    MMI    |   rs    |   rt    |   rd    | PCPYUD  |    MMI3   |
24870 *  +-----------+---------+---------+---------+---------+-----------+
24871 */
24872static void gen_mmi_pcpyud(DisasContext *ctx)
24873{
24874    uint32_t rs, rt, rd;
24875    uint32_t opcode;
24876
24877    opcode = ctx->opcode;
24878
24879    rs = extract32(opcode, 21, 5);
24880    rt = extract32(opcode, 16, 5);
24881    rd = extract32(opcode, 11, 5);
24882
24883    if (rd == 0) {
24884        /* nop */
24885    } else {
24886        if (rs == 0) {
24887            tcg_gen_movi_i64(cpu_gpr[rd], 0);
24888        } else {
24889            tcg_gen_mov_i64(cpu_gpr[rd], cpu_mmr[rs]);
24890        }
24891        if (rt == 0) {
24892            tcg_gen_movi_i64(cpu_mmr[rd], 0);
24893        } else {
24894            if (rd != rt) {
24895                tcg_gen_mov_i64(cpu_mmr[rd], cpu_mmr[rt]);
24896            }
24897        }
24898    }
24899}
24900
24901#endif
24902
24903
24904#if !defined(TARGET_MIPS64)
24905
24906/* MXU accumulate add/subtract 1-bit pattern 'aptn1' */
24907#define MXU_APTN1_A    0
24908#define MXU_APTN1_S    1
24909
24910/* MXU accumulate add/subtract 2-bit pattern 'aptn2' */
24911#define MXU_APTN2_AA    0
24912#define MXU_APTN2_AS    1
24913#define MXU_APTN2_SA    2
24914#define MXU_APTN2_SS    3
24915
24916/* MXU execute add/subtract 2-bit pattern 'eptn2' */
24917#define MXU_EPTN2_AA    0
24918#define MXU_EPTN2_AS    1
24919#define MXU_EPTN2_SA    2
24920#define MXU_EPTN2_SS    3
24921
24922/* MXU operand getting pattern 'optn2' */
24923#define MXU_OPTN2_PTN0  0
24924#define MXU_OPTN2_PTN1  1
24925#define MXU_OPTN2_PTN2  2
24926#define MXU_OPTN2_PTN3  3
24927/* alternative naming scheme for 'optn2' */
24928#define MXU_OPTN2_WW    0
24929#define MXU_OPTN2_LW    1
24930#define MXU_OPTN2_HW    2
24931#define MXU_OPTN2_XW    3
24932
24933/* MXU operand getting pattern 'optn3' */
24934#define MXU_OPTN3_PTN0  0
24935#define MXU_OPTN3_PTN1  1
24936#define MXU_OPTN3_PTN2  2
24937#define MXU_OPTN3_PTN3  3
24938#define MXU_OPTN3_PTN4  4
24939#define MXU_OPTN3_PTN5  5
24940#define MXU_OPTN3_PTN6  6
24941#define MXU_OPTN3_PTN7  7
24942
24943
24944/*
24945 * S32I2M XRa, rb - Register move from GRF to XRF
24946 */
24947static void gen_mxu_s32i2m(DisasContext *ctx)
24948{
24949    TCGv t0;
24950    uint32_t XRa, Rb;
24951
24952    t0 = tcg_temp_new();
24953
24954    XRa = extract32(ctx->opcode, 6, 5);
24955    Rb = extract32(ctx->opcode, 16, 5);
24956
24957    gen_load_gpr(t0, Rb);
24958    if (XRa <= 15) {
24959        gen_store_mxu_gpr(t0, XRa);
24960    } else if (XRa == 16) {
24961        gen_store_mxu_cr(t0);
24962    }
24963
24964    tcg_temp_free(t0);
24965}
24966
24967/*
24968 * S32M2I XRa, rb - Register move from XRF to GRF
24969 */
24970static void gen_mxu_s32m2i(DisasContext *ctx)
24971{
24972    TCGv t0;
24973    uint32_t XRa, Rb;
24974
24975    t0 = tcg_temp_new();
24976
24977    XRa = extract32(ctx->opcode, 6, 5);
24978    Rb = extract32(ctx->opcode, 16, 5);
24979
24980    if (XRa <= 15) {
24981        gen_load_mxu_gpr(t0, XRa);
24982    } else if (XRa == 16) {
24983        gen_load_mxu_cr(t0);
24984    }
24985
24986    gen_store_gpr(t0, Rb);
24987
24988    tcg_temp_free(t0);
24989}
24990
24991/*
24992 * S8LDD XRa, Rb, s8, optn3 - Load a byte from memory to XRF
24993 */
24994static void gen_mxu_s8ldd(DisasContext *ctx)
24995{
24996    TCGv t0, t1;
24997    uint32_t XRa, Rb, s8, optn3;
24998
24999    t0 = tcg_temp_new();
25000    t1 = tcg_temp_new();
25001
25002    XRa = extract32(ctx->opcode, 6, 4);
25003    s8 = extract32(ctx->opcode, 10, 8);
25004    optn3 = extract32(ctx->opcode, 18, 3);
25005    Rb = extract32(ctx->opcode, 21, 5);
25006
25007    gen_load_gpr(t0, Rb);
25008    tcg_gen_addi_tl(t0, t0, (int8_t)s8);
25009
25010    switch (optn3) {
25011    /* XRa[7:0] = tmp8 */
25012    case MXU_OPTN3_PTN0:
25013        tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_UB);
25014        gen_load_mxu_gpr(t0, XRa);
25015        tcg_gen_deposit_tl(t0, t0, t1, 0, 8);
25016        break;
25017    /* XRa[15:8] = tmp8 */
25018    case MXU_OPTN3_PTN1:
25019        tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_UB);
25020        gen_load_mxu_gpr(t0, XRa);
25021        tcg_gen_deposit_tl(t0, t0, t1, 8, 8);
25022        break;
25023    /* XRa[23:16] = tmp8 */
25024    case MXU_OPTN3_PTN2:
25025        tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_UB);
25026        gen_load_mxu_gpr(t0, XRa);
25027        tcg_gen_deposit_tl(t0, t0, t1, 16, 8);
25028        break;
25029    /* XRa[31:24] = tmp8 */
25030    case MXU_OPTN3_PTN3:
25031        tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_UB);
25032        gen_load_mxu_gpr(t0, XRa);
25033        tcg_gen_deposit_tl(t0, t0, t1, 24, 8);
25034        break;
25035    /* XRa = {8'b0, tmp8, 8'b0, tmp8} */
25036    case MXU_OPTN3_PTN4:
25037        tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_UB);
25038        tcg_gen_deposit_tl(t0, t1, t1, 16, 16);
25039        break;
25040    /* XRa = {tmp8, 8'b0, tmp8, 8'b0} */
25041    case MXU_OPTN3_PTN5:
25042        tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_UB);
25043        tcg_gen_shli_tl(t1, t1, 8);
25044        tcg_gen_deposit_tl(t0, t1, t1, 16, 16);
25045        break;
25046    /* XRa = {{8{sign of tmp8}}, tmp8, {8{sign of tmp8}}, tmp8} */
25047    case MXU_OPTN3_PTN6:
25048        tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_SB);
25049        tcg_gen_mov_tl(t0, t1);
25050        tcg_gen_andi_tl(t0, t0, 0xFF00FFFF);
25051        tcg_gen_shli_tl(t1, t1, 16);
25052        tcg_gen_or_tl(t0, t0, t1);
25053        break;
25054    /* XRa = {tmp8, tmp8, tmp8, tmp8} */
25055    case MXU_OPTN3_PTN7:
25056        tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_UB);
25057        tcg_gen_deposit_tl(t1, t1, t1, 8, 8);
25058        tcg_gen_deposit_tl(t0, t1, t1, 16, 16);
25059        break;
25060    }
25061
25062    gen_store_mxu_gpr(t0, XRa);
25063
25064    tcg_temp_free(t0);
25065    tcg_temp_free(t1);
25066}
25067
25068/*
25069 * D16MUL XRa, XRb, XRc, XRd, optn2 - Signed 16 bit pattern multiplication
25070 */
25071static void gen_mxu_d16mul(DisasContext *ctx)
25072{
25073    TCGv t0, t1, t2, t3;
25074    uint32_t XRa, XRb, XRc, XRd, optn2;
25075
25076    t0 = tcg_temp_new();
25077    t1 = tcg_temp_new();
25078    t2 = tcg_temp_new();
25079    t3 = tcg_temp_new();
25080
25081    XRa = extract32(ctx->opcode, 6, 4);
25082    XRb = extract32(ctx->opcode, 10, 4);
25083    XRc = extract32(ctx->opcode, 14, 4);
25084    XRd = extract32(ctx->opcode, 18, 4);
25085    optn2 = extract32(ctx->opcode, 22, 2);
25086
25087    gen_load_mxu_gpr(t1, XRb);
25088    tcg_gen_sextract_tl(t0, t1, 0, 16);
25089    tcg_gen_sextract_tl(t1, t1, 16, 16);
25090    gen_load_mxu_gpr(t3, XRc);
25091    tcg_gen_sextract_tl(t2, t3, 0, 16);
25092    tcg_gen_sextract_tl(t3, t3, 16, 16);
25093
25094    switch (optn2) {
25095    case MXU_OPTN2_WW: /* XRB.H*XRC.H == lop, XRB.L*XRC.L == rop */
25096        tcg_gen_mul_tl(t3, t1, t3);
25097        tcg_gen_mul_tl(t2, t0, t2);
25098        break;
25099    case MXU_OPTN2_LW: /* XRB.L*XRC.H == lop, XRB.L*XRC.L == rop */
25100        tcg_gen_mul_tl(t3, t0, t3);
25101        tcg_gen_mul_tl(t2, t0, t2);
25102        break;
25103    case MXU_OPTN2_HW: /* XRB.H*XRC.H == lop, XRB.H*XRC.L == rop */
25104        tcg_gen_mul_tl(t3, t1, t3);
25105        tcg_gen_mul_tl(t2, t1, t2);
25106        break;
25107    case MXU_OPTN2_XW: /* XRB.L*XRC.H == lop, XRB.H*XRC.L == rop */
25108        tcg_gen_mul_tl(t3, t0, t3);
25109        tcg_gen_mul_tl(t2, t1, t2);
25110        break;
25111    }
25112    gen_store_mxu_gpr(t3, XRa);
25113    gen_store_mxu_gpr(t2, XRd);
25114
25115    tcg_temp_free(t0);
25116    tcg_temp_free(t1);
25117    tcg_temp_free(t2);
25118    tcg_temp_free(t3);
25119}
25120
25121/*
25122 * D16MAC XRa, XRb, XRc, XRd, aptn2, optn2 - Signed 16 bit pattern multiply
25123 *                                           and accumulate
25124 */
25125static void gen_mxu_d16mac(DisasContext *ctx)
25126{
25127    TCGv t0, t1, t2, t3;
25128    uint32_t XRa, XRb, XRc, XRd, optn2, aptn2;
25129
25130    t0 = tcg_temp_new();
25131    t1 = tcg_temp_new();
25132    t2 = tcg_temp_new();
25133    t3 = tcg_temp_new();
25134
25135    XRa = extract32(ctx->opcode, 6, 4);
25136    XRb = extract32(ctx->opcode, 10, 4);
25137    XRc = extract32(ctx->opcode, 14, 4);
25138    XRd = extract32(ctx->opcode, 18, 4);
25139    optn2 = extract32(ctx->opcode, 22, 2);
25140    aptn2 = extract32(ctx->opcode, 24, 2);
25141
25142    gen_load_mxu_gpr(t1, XRb);
25143    tcg_gen_sextract_tl(t0, t1, 0, 16);
25144    tcg_gen_sextract_tl(t1, t1, 16, 16);
25145
25146    gen_load_mxu_gpr(t3, XRc);
25147    tcg_gen_sextract_tl(t2, t3, 0, 16);
25148    tcg_gen_sextract_tl(t3, t3, 16, 16);
25149
25150    switch (optn2) {
25151    case MXU_OPTN2_WW: /* XRB.H*XRC.H == lop, XRB.L*XRC.L == rop */
25152        tcg_gen_mul_tl(t3, t1, t3);
25153        tcg_gen_mul_tl(t2, t0, t2);
25154        break;
25155    case MXU_OPTN2_LW: /* XRB.L*XRC.H == lop, XRB.L*XRC.L == rop */
25156        tcg_gen_mul_tl(t3, t0, t3);
25157        tcg_gen_mul_tl(t2, t0, t2);
25158        break;
25159    case MXU_OPTN2_HW: /* XRB.H*XRC.H == lop, XRB.H*XRC.L == rop */
25160        tcg_gen_mul_tl(t3, t1, t3);
25161        tcg_gen_mul_tl(t2, t1, t2);
25162        break;
25163    case MXU_OPTN2_XW: /* XRB.L*XRC.H == lop, XRB.H*XRC.L == rop */
25164        tcg_gen_mul_tl(t3, t0, t3);
25165        tcg_gen_mul_tl(t2, t1, t2);
25166        break;
25167    }
25168    gen_load_mxu_gpr(t0, XRa);
25169    gen_load_mxu_gpr(t1, XRd);
25170
25171    switch (aptn2) {
25172    case MXU_APTN2_AA:
25173        tcg_gen_add_tl(t3, t0, t3);
25174        tcg_gen_add_tl(t2, t1, t2);
25175        break;
25176    case MXU_APTN2_AS:
25177        tcg_gen_add_tl(t3, t0, t3);
25178        tcg_gen_sub_tl(t2, t1, t2);
25179        break;
25180    case MXU_APTN2_SA:
25181        tcg_gen_sub_tl(t3, t0, t3);
25182        tcg_gen_add_tl(t2, t1, t2);
25183        break;
25184    case MXU_APTN2_SS:
25185        tcg_gen_sub_tl(t3, t0, t3);
25186        tcg_gen_sub_tl(t2, t1, t2);
25187        break;
25188    }
25189    gen_store_mxu_gpr(t3, XRa);
25190    gen_store_mxu_gpr(t2, XRd);
25191
25192    tcg_temp_free(t0);
25193    tcg_temp_free(t1);
25194    tcg_temp_free(t2);
25195    tcg_temp_free(t3);
25196}
25197
25198/*
25199 * Q8MUL   XRa, XRb, XRc, XRd - Parallel unsigned 8 bit pattern multiply
25200 * Q8MULSU XRa, XRb, XRc, XRd - Parallel signed 8 bit pattern multiply
25201 */
25202static void gen_mxu_q8mul_q8mulsu(DisasContext *ctx)
25203{
25204    TCGv t0, t1, t2, t3, t4, t5, t6, t7;
25205    uint32_t XRa, XRb, XRc, XRd, sel;
25206
25207    t0 = tcg_temp_new();
25208    t1 = tcg_temp_new();
25209    t2 = tcg_temp_new();
25210    t3 = tcg_temp_new();
25211    t4 = tcg_temp_new();
25212    t5 = tcg_temp_new();
25213    t6 = tcg_temp_new();
25214    t7 = tcg_temp_new();
25215
25216    XRa = extract32(ctx->opcode, 6, 4);
25217    XRb = extract32(ctx->opcode, 10, 4);
25218    XRc = extract32(ctx->opcode, 14, 4);
25219    XRd = extract32(ctx->opcode, 18, 4);
25220    sel = extract32(ctx->opcode, 22, 2);
25221
25222    gen_load_mxu_gpr(t3, XRb);
25223    gen_load_mxu_gpr(t7, XRc);
25224
25225    if (sel == 0x2) {
25226        /* Q8MULSU */
25227        tcg_gen_ext8s_tl(t0, t3);
25228        tcg_gen_shri_tl(t3, t3, 8);
25229        tcg_gen_ext8s_tl(t1, t3);
25230        tcg_gen_shri_tl(t3, t3, 8);
25231        tcg_gen_ext8s_tl(t2, t3);
25232        tcg_gen_shri_tl(t3, t3, 8);
25233        tcg_gen_ext8s_tl(t3, t3);
25234    } else {
25235        /* Q8MUL */
25236        tcg_gen_ext8u_tl(t0, t3);
25237        tcg_gen_shri_tl(t3, t3, 8);
25238        tcg_gen_ext8u_tl(t1, t3);
25239        tcg_gen_shri_tl(t3, t3, 8);
25240        tcg_gen_ext8u_tl(t2, t3);
25241        tcg_gen_shri_tl(t3, t3, 8);
25242        tcg_gen_ext8u_tl(t3, t3);
25243    }
25244
25245    tcg_gen_ext8u_tl(t4, t7);
25246    tcg_gen_shri_tl(t7, t7, 8);
25247    tcg_gen_ext8u_tl(t5, t7);
25248    tcg_gen_shri_tl(t7, t7, 8);
25249    tcg_gen_ext8u_tl(t6, t7);
25250    tcg_gen_shri_tl(t7, t7, 8);
25251    tcg_gen_ext8u_tl(t7, t7);
25252
25253    tcg_gen_mul_tl(t0, t0, t4);
25254    tcg_gen_mul_tl(t1, t1, t5);
25255    tcg_gen_mul_tl(t2, t2, t6);
25256    tcg_gen_mul_tl(t3, t3, t7);
25257
25258    tcg_gen_andi_tl(t0, t0, 0xFFFF);
25259    tcg_gen_andi_tl(t1, t1, 0xFFFF);
25260    tcg_gen_andi_tl(t2, t2, 0xFFFF);
25261    tcg_gen_andi_tl(t3, t3, 0xFFFF);
25262
25263    tcg_gen_shli_tl(t1, t1, 16);
25264    tcg_gen_shli_tl(t3, t3, 16);
25265
25266    tcg_gen_or_tl(t0, t0, t1);
25267    tcg_gen_or_tl(t1, t2, t3);
25268
25269    gen_store_mxu_gpr(t0, XRd);
25270    gen_store_mxu_gpr(t1, XRa);
25271
25272    tcg_temp_free(t0);
25273    tcg_temp_free(t1);
25274    tcg_temp_free(t2);
25275    tcg_temp_free(t3);
25276    tcg_temp_free(t4);
25277    tcg_temp_free(t5);
25278    tcg_temp_free(t6);
25279    tcg_temp_free(t7);
25280}
25281
25282/*
25283 * S32LDD  XRa, Rb, S12 - Load a word from memory to XRF
25284 * S32LDDR XRa, Rb, S12 - Load a word from memory to XRF, reversed byte seq.
25285 */
25286static void gen_mxu_s32ldd_s32lddr(DisasContext *ctx)
25287{
25288    TCGv t0, t1;
25289    uint32_t XRa, Rb, s12, sel;
25290
25291    t0 = tcg_temp_new();
25292    t1 = tcg_temp_new();
25293
25294    XRa = extract32(ctx->opcode, 6, 4);
25295    s12 = extract32(ctx->opcode, 10, 10);
25296    sel = extract32(ctx->opcode, 20, 1);
25297    Rb = extract32(ctx->opcode, 21, 5);
25298
25299    gen_load_gpr(t0, Rb);
25300
25301    tcg_gen_movi_tl(t1, s12);
25302    tcg_gen_shli_tl(t1, t1, 2);
25303    if (s12 & 0x200) {
25304        tcg_gen_ori_tl(t1, t1, 0xFFFFF000);
25305    }
25306    tcg_gen_add_tl(t1, t0, t1);
25307    tcg_gen_qemu_ld_tl(t1, t1, ctx->mem_idx, MO_SL);
25308
25309    if (sel == 1) {
25310        /* S32LDDR */
25311        tcg_gen_bswap32_tl(t1, t1);
25312    }
25313    gen_store_mxu_gpr(t1, XRa);
25314
25315    tcg_temp_free(t0);
25316    tcg_temp_free(t1);
25317}
25318
25319
25320/*
25321 *                 MXU instruction category: logic
25322 *                 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
25323 *
25324 *               S32NOR    S32AND    S32OR    S32XOR
25325 */
25326
25327/*
25328 *  S32NOR XRa, XRb, XRc
25329 *    Update XRa with the result of logical bitwise 'nor' operation
25330 *    applied to the content of XRb and XRc.
25331 *
25332 *   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
25333 *  +-----------+---------+-----+-------+-------+-------+-----------+
25334 *  |  SPECIAL2 |0 0 0 0 0| opc |  XRc  |  XRb  |  XRa  |MXU__POOL16|
25335 *  +-----------+---------+-----+-------+-------+-------+-----------+
25336 */
25337static void gen_mxu_S32NOR(DisasContext *ctx)
25338{
25339    uint32_t pad, XRc, XRb, XRa;
25340
25341    pad = extract32(ctx->opcode, 21, 5);
25342    XRc = extract32(ctx->opcode, 14, 4);
25343    XRb = extract32(ctx->opcode, 10, 4);
25344    XRa = extract32(ctx->opcode,  6, 4);
25345
25346    if (unlikely(pad != 0)) {
25347        /* opcode padding incorrect -> do nothing */
25348    } else if (unlikely(XRa == 0)) {
25349        /* destination is zero register -> do nothing */
25350    } else if (unlikely((XRb == 0) && (XRc == 0))) {
25351        /* both operands zero registers -> just set destination to all 1s */
25352        tcg_gen_movi_i32(mxu_gpr[XRa - 1], 0xFFFFFFFF);
25353    } else if (unlikely(XRb == 0)) {
25354        /* XRb zero register -> just set destination to the negation of XRc */
25355        tcg_gen_not_i32(mxu_gpr[XRa - 1], mxu_gpr[XRc - 1]);
25356    } else if (unlikely(XRc == 0)) {
25357        /* XRa zero register -> just set destination to the negation of XRb */
25358        tcg_gen_not_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1]);
25359    } else if (unlikely(XRb == XRc)) {
25360        /* both operands same -> just set destination to the negation of XRb */
25361        tcg_gen_not_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1]);
25362    } else {
25363        /* the most general case */
25364        tcg_gen_nor_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1], mxu_gpr[XRc - 1]);
25365    }
25366}
25367
25368/*
25369 *  S32AND XRa, XRb, XRc
25370 *    Update XRa with the result of logical bitwise 'and' operation
25371 *    applied to the content of XRb and XRc.
25372 *
25373 *   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
25374 *  +-----------+---------+-----+-------+-------+-------+-----------+
25375 *  |  SPECIAL2 |0 0 0 0 0| opc |  XRc  |  XRb  |  XRa  |MXU__POOL16|
25376 *  +-----------+---------+-----+-------+-------+-------+-----------+
25377 */
25378static void gen_mxu_S32AND(DisasContext *ctx)
25379{
25380    uint32_t pad, XRc, XRb, XRa;
25381
25382    pad = extract32(ctx->opcode, 21, 5);
25383    XRc = extract32(ctx->opcode, 14, 4);
25384    XRb = extract32(ctx->opcode, 10, 4);
25385    XRa = extract32(ctx->opcode,  6, 4);
25386
25387    if (unlikely(pad != 0)) {
25388        /* opcode padding incorrect -> do nothing */
25389    } else if (unlikely(XRa == 0)) {
25390        /* destination is zero register -> do nothing */
25391    } else if (unlikely((XRb == 0) || (XRc == 0))) {
25392        /* one of operands zero register -> just set destination to all 0s */
25393        tcg_gen_movi_i32(mxu_gpr[XRa - 1], 0);
25394    } else if (unlikely(XRb == XRc)) {
25395        /* both operands same -> just set destination to one of them */
25396        tcg_gen_mov_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1]);
25397    } else {
25398        /* the most general case */
25399        tcg_gen_and_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1], mxu_gpr[XRc - 1]);
25400    }
25401}
25402
25403/*
25404 *  S32OR XRa, XRb, XRc
25405 *    Update XRa with the result of logical bitwise 'or' operation
25406 *    applied to the content of XRb and XRc.
25407 *
25408 *   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
25409 *  +-----------+---------+-----+-------+-------+-------+-----------+
25410 *  |  SPECIAL2 |0 0 0 0 0| opc |  XRc  |  XRb  |  XRa  |MXU__POOL16|
25411 *  +-----------+---------+-----+-------+-------+-------+-----------+
25412 */
25413static void gen_mxu_S32OR(DisasContext *ctx)
25414{
25415    uint32_t pad, XRc, XRb, XRa;
25416
25417    pad = extract32(ctx->opcode, 21, 5);
25418    XRc = extract32(ctx->opcode, 14, 4);
25419    XRb = extract32(ctx->opcode, 10, 4);
25420    XRa = extract32(ctx->opcode,  6, 4);
25421
25422    if (unlikely(pad != 0)) {
25423        /* opcode padding incorrect -> do nothing */
25424    } else if (unlikely(XRa == 0)) {
25425        /* destination is zero register -> do nothing */
25426    } else if (unlikely((XRb == 0) && (XRc == 0))) {
25427        /* both operands zero registers -> just set destination to all 0s */
25428        tcg_gen_movi_i32(mxu_gpr[XRa - 1], 0);
25429    } else if (unlikely(XRb == 0)) {
25430        /* XRb zero register -> just set destination to the content of XRc */
25431        tcg_gen_mov_i32(mxu_gpr[XRa - 1], mxu_gpr[XRc - 1]);
25432    } else if (unlikely(XRc == 0)) {
25433        /* XRc zero register -> just set destination to the content of XRb */
25434        tcg_gen_mov_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1]);
25435    } else if (unlikely(XRb == XRc)) {
25436        /* both operands same -> just set destination to one of them */
25437        tcg_gen_mov_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1]);
25438    } else {
25439        /* the most general case */
25440        tcg_gen_or_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1], mxu_gpr[XRc - 1]);
25441    }
25442}
25443
25444/*
25445 *  S32XOR XRa, XRb, XRc
25446 *    Update XRa with the result of logical bitwise 'xor' operation
25447 *    applied to the content of XRb and XRc.
25448 *
25449 *   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
25450 *  +-----------+---------+-----+-------+-------+-------+-----------+
25451 *  |  SPECIAL2 |0 0 0 0 0| opc |  XRc  |  XRb  |  XRa  |MXU__POOL16|
25452 *  +-----------+---------+-----+-------+-------+-------+-----------+
25453 */
25454static void gen_mxu_S32XOR(DisasContext *ctx)
25455{
25456    uint32_t pad, XRc, XRb, XRa;
25457
25458    pad = extract32(ctx->opcode, 21, 5);
25459    XRc = extract32(ctx->opcode, 14, 4);
25460    XRb = extract32(ctx->opcode, 10, 4);
25461    XRa = extract32(ctx->opcode,  6, 4);
25462
25463    if (unlikely(pad != 0)) {
25464        /* opcode padding incorrect -> do nothing */
25465    } else if (unlikely(XRa == 0)) {
25466        /* destination is zero register -> do nothing */
25467    } else if (unlikely((XRb == 0) && (XRc == 0))) {
25468        /* both operands zero registers -> just set destination to all 0s */
25469        tcg_gen_movi_i32(mxu_gpr[XRa - 1], 0);
25470    } else if (unlikely(XRb == 0)) {
25471        /* XRb zero register -> just set destination to the content of XRc */
25472        tcg_gen_mov_i32(mxu_gpr[XRa - 1], mxu_gpr[XRc - 1]);
25473    } else if (unlikely(XRc == 0)) {
25474        /* XRc zero register -> just set destination to the content of XRb */
25475        tcg_gen_mov_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1]);
25476    } else if (unlikely(XRb == XRc)) {
25477        /* both operands same -> just set destination to all 0s */
25478        tcg_gen_movi_i32(mxu_gpr[XRa - 1], 0);
25479    } else {
25480        /* the most general case */
25481        tcg_gen_xor_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1], mxu_gpr[XRc - 1]);
25482    }
25483}
25484
25485
25486/*
25487 *                   MXU instruction category max/min
25488 *                   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
25489 *
25490 *                     S32MAX     D16MAX     Q8MAX
25491 *                     S32MIN     D16MIN     Q8MIN
25492 */
25493
25494/*
25495 *  S32MAX XRa, XRb, XRc
25496 *    Update XRa with the maximum of signed 32-bit integers contained
25497 *    in XRb and XRc.
25498 *
25499 *  S32MIN XRa, XRb, XRc
25500 *    Update XRa with the minimum of signed 32-bit integers contained
25501 *    in XRb and XRc.
25502 *
25503 *   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
25504 *  +-----------+---------+-----+-------+-------+-------+-----------+
25505 *  |  SPECIAL2 |0 0 0 0 0| opc |  XRc  |  XRb  |  XRa  |MXU__POOL00|
25506 *  +-----------+---------+-----+-------+-------+-------+-----------+
25507 */
25508static void gen_mxu_S32MAX_S32MIN(DisasContext *ctx)
25509{
25510    uint32_t pad, opc, XRc, XRb, XRa;
25511
25512    pad = extract32(ctx->opcode, 21, 5);
25513    opc = extract32(ctx->opcode, 18, 3);
25514    XRc = extract32(ctx->opcode, 14, 4);
25515    XRb = extract32(ctx->opcode, 10, 4);
25516    XRa = extract32(ctx->opcode,  6, 4);
25517
25518    if (unlikely(pad != 0)) {
25519        /* opcode padding incorrect -> do nothing */
25520    } else if (unlikely(XRa == 0)) {
25521        /* destination is zero register -> do nothing */
25522    } else if (unlikely((XRb == 0) && (XRc == 0))) {
25523        /* both operands zero registers -> just set destination to zero */
25524        tcg_gen_movi_i32(mxu_gpr[XRa - 1], 0);
25525    } else if (unlikely((XRb == 0) || (XRc == 0))) {
25526        /* exactly one operand is zero register - find which one is not...*/
25527        uint32_t XRx = XRb ? XRb : XRc;
25528        /* ...and do max/min operation with one operand 0 */
25529        if (opc == OPC_MXU_S32MAX) {
25530            tcg_gen_smax_i32(mxu_gpr[XRa - 1], mxu_gpr[XRx - 1], 0);
25531        } else {
25532            tcg_gen_smin_i32(mxu_gpr[XRa - 1], mxu_gpr[XRx - 1], 0);
25533        }
25534    } else if (unlikely(XRb == XRc)) {
25535        /* both operands same -> just set destination to one of them */
25536        tcg_gen_mov_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1]);
25537    } else {
25538        /* the most general case */
25539        if (opc == OPC_MXU_S32MAX) {
25540            tcg_gen_smax_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1],
25541                                               mxu_gpr[XRc - 1]);
25542        } else {
25543            tcg_gen_smin_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1],
25544                                               mxu_gpr[XRc - 1]);
25545        }
25546    }
25547}
25548
25549/*
25550 *  D16MAX
25551 *    Update XRa with the 16-bit-wise maximums of signed integers
25552 *    contained in XRb and XRc.
25553 *
25554 *  D16MIN
25555 *    Update XRa with the 16-bit-wise minimums of signed integers
25556 *    contained in XRb and XRc.
25557 *
25558 *   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
25559 *  +-----------+---------+-----+-------+-------+-------+-----------+
25560 *  |  SPECIAL2 |0 0 0 0 0| opc |  XRc  |  XRb  |  XRa  |MXU__POOL00|
25561 *  +-----------+---------+-----+-------+-------+-------+-----------+
25562 */
25563static void gen_mxu_D16MAX_D16MIN(DisasContext *ctx)
25564{
25565    uint32_t pad, opc, XRc, XRb, XRa;
25566
25567    pad = extract32(ctx->opcode, 21, 5);
25568    opc = extract32(ctx->opcode, 18, 3);
25569    XRc = extract32(ctx->opcode, 14, 4);
25570    XRb = extract32(ctx->opcode, 10, 4);
25571    XRa = extract32(ctx->opcode,  6, 4);
25572
25573    if (unlikely(pad != 0)) {
25574        /* opcode padding incorrect -> do nothing */
25575    } else if (unlikely(XRc == 0)) {
25576        /* destination is zero register -> do nothing */
25577    } else if (unlikely((XRb == 0) && (XRa == 0))) {
25578        /* both operands zero registers -> just set destination to zero */
25579        tcg_gen_movi_i32(mxu_gpr[XRc - 1], 0);
25580    } else if (unlikely((XRb == 0) || (XRa == 0))) {
25581        /* exactly one operand is zero register - find which one is not...*/
25582        uint32_t XRx = XRb ? XRb : XRc;
25583        /* ...and do half-word-wise max/min with one operand 0 */
25584        TCGv_i32 t0 = tcg_temp_new();
25585        TCGv_i32 t1 = tcg_const_i32(0);
25586
25587        /* the left half-word first */
25588        tcg_gen_andi_i32(t0, mxu_gpr[XRx - 1], 0xFFFF0000);
25589        if (opc == OPC_MXU_D16MAX) {
25590            tcg_gen_smax_i32(mxu_gpr[XRa - 1], t0, t1);
25591        } else {
25592            tcg_gen_smin_i32(mxu_gpr[XRa - 1], t0, t1);
25593        }
25594
25595        /* the right half-word */
25596        tcg_gen_andi_i32(t0, mxu_gpr[XRx - 1], 0x0000FFFF);
25597        /* move half-words to the leftmost position */
25598        tcg_gen_shli_i32(t0, t0, 16);
25599        /* t0 will be max/min of t0 and t1 */
25600        if (opc == OPC_MXU_D16MAX) {
25601            tcg_gen_smax_i32(t0, t0, t1);
25602        } else {
25603            tcg_gen_smin_i32(t0, t0, t1);
25604        }
25605        /* return resulting half-words to its original position */
25606        tcg_gen_shri_i32(t0, t0, 16);
25607        /* finaly update the destination */
25608        tcg_gen_or_i32(mxu_gpr[XRa - 1], mxu_gpr[XRa - 1], t0);
25609
25610        tcg_temp_free(t1);
25611        tcg_temp_free(t0);
25612    } else if (unlikely(XRb == XRc)) {
25613        /* both operands same -> just set destination to one of them */
25614        tcg_gen_mov_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1]);
25615    } else {
25616        /* the most general case */
25617        TCGv_i32 t0 = tcg_temp_new();
25618        TCGv_i32 t1 = tcg_temp_new();
25619
25620        /* the left half-word first */
25621        tcg_gen_andi_i32(t0, mxu_gpr[XRb - 1], 0xFFFF0000);
25622        tcg_gen_andi_i32(t1, mxu_gpr[XRc - 1], 0xFFFF0000);
25623        if (opc == OPC_MXU_D16MAX) {
25624            tcg_gen_smax_i32(mxu_gpr[XRa - 1], t0, t1);
25625        } else {
25626            tcg_gen_smin_i32(mxu_gpr[XRa - 1], t0, t1);
25627        }
25628
25629        /* the right half-word */
25630        tcg_gen_andi_i32(t0, mxu_gpr[XRb - 1], 0x0000FFFF);
25631        tcg_gen_andi_i32(t1, mxu_gpr[XRc - 1], 0x0000FFFF);
25632        /* move half-words to the leftmost position */
25633        tcg_gen_shli_i32(t0, t0, 16);
25634        tcg_gen_shli_i32(t1, t1, 16);
25635        /* t0 will be max/min of t0 and t1 */
25636        if (opc == OPC_MXU_D16MAX) {
25637            tcg_gen_smax_i32(t0, t0, t1);
25638        } else {
25639            tcg_gen_smin_i32(t0, t0, t1);
25640        }
25641        /* return resulting half-words to its original position */
25642        tcg_gen_shri_i32(t0, t0, 16);
25643        /* finaly update the destination */
25644        tcg_gen_or_i32(mxu_gpr[XRa - 1], mxu_gpr[XRa - 1], t0);
25645
25646        tcg_temp_free(t1);
25647        tcg_temp_free(t0);
25648    }
25649}
25650
25651/*
25652 *  Q8MAX
25653 *    Update XRa with the 8-bit-wise maximums of signed integers
25654 *    contained in XRb and XRc.
25655 *
25656 *  Q8MIN
25657 *    Update XRa with the 8-bit-wise minimums of signed integers
25658 *    contained in XRb and XRc.
25659 *
25660 *   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
25661 *  +-----------+---------+-----+-------+-------+-------+-----------+
25662 *  |  SPECIAL2 |0 0 0 0 0| opc |  XRc  |  XRb  |  XRa  |MXU__POOL00|
25663 *  +-----------+---------+-----+-------+-------+-------+-----------+
25664 */
25665static void gen_mxu_Q8MAX_Q8MIN(DisasContext *ctx)
25666{
25667    uint32_t pad, opc, XRc, XRb, XRa;
25668
25669    pad = extract32(ctx->opcode, 21, 5);
25670    opc = extract32(ctx->opcode, 18, 3);
25671    XRc = extract32(ctx->opcode, 14, 4);
25672    XRb = extract32(ctx->opcode, 10, 4);
25673    XRa = extract32(ctx->opcode,  6, 4);
25674
25675    if (unlikely(pad != 0)) {
25676        /* opcode padding incorrect -> do nothing */
25677    } else if (unlikely(XRa == 0)) {
25678        /* destination is zero register -> do nothing */
25679    } else if (unlikely((XRb == 0) && (XRc == 0))) {
25680        /* both operands zero registers -> just set destination to zero */
25681        tcg_gen_movi_i32(mxu_gpr[XRa - 1], 0);
25682    } else if (unlikely((XRb == 0) || (XRc == 0))) {
25683        /* exactly one operand is zero register - make it be the first...*/
25684        uint32_t XRx = XRb ? XRb : XRc;
25685        /* ...and do byte-wise max/min with one operand 0 */
25686        TCGv_i32 t0 = tcg_temp_new();
25687        TCGv_i32 t1 = tcg_const_i32(0);
25688        int32_t i;
25689
25690        /* the leftmost byte (byte 3) first */
25691        tcg_gen_andi_i32(t0, mxu_gpr[XRx - 1], 0xFF000000);
25692        if (opc == OPC_MXU_Q8MAX) {
25693            tcg_gen_smax_i32(mxu_gpr[XRa - 1], t0, t1);
25694        } else {
25695            tcg_gen_smin_i32(mxu_gpr[XRa - 1], t0, t1);
25696        }
25697
25698        /* bytes 2, 1, 0 */
25699        for (i = 2; i >= 0; i--) {
25700            /* extract the byte */
25701            tcg_gen_andi_i32(t0, mxu_gpr[XRx - 1], 0xFF << (8 * i));
25702            /* move the byte to the leftmost position */
25703            tcg_gen_shli_i32(t0, t0, 8 * (3 - i));
25704            /* t0 will be max/min of t0 and t1 */
25705            if (opc == OPC_MXU_Q8MAX) {
25706                tcg_gen_smax_i32(t0, t0, t1);
25707            } else {
25708                tcg_gen_smin_i32(t0, t0, t1);
25709            }
25710            /* return resulting byte to its original position */
25711            tcg_gen_shri_i32(t0, t0, 8 * (3 - i));
25712            /* finaly update the destination */
25713            tcg_gen_or_i32(mxu_gpr[XRa - 1], mxu_gpr[XRa - 1], t0);
25714        }
25715
25716        tcg_temp_free(t1);
25717        tcg_temp_free(t0);
25718    } else if (unlikely(XRb == XRc)) {
25719        /* both operands same -> just set destination to one of them */
25720        tcg_gen_mov_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1]);
25721    } else {
25722        /* the most general case */
25723        TCGv_i32 t0 = tcg_temp_new();
25724        TCGv_i32 t1 = tcg_temp_new();
25725        int32_t i;
25726
25727        /* the leftmost bytes (bytes 3) first */
25728        tcg_gen_andi_i32(t0, mxu_gpr[XRb - 1], 0xFF000000);
25729        tcg_gen_andi_i32(t1, mxu_gpr[XRc - 1], 0xFF000000);
25730        if (opc == OPC_MXU_Q8MAX) {
25731            tcg_gen_smax_i32(mxu_gpr[XRa - 1], t0, t1);
25732        } else {
25733            tcg_gen_smin_i32(mxu_gpr[XRa - 1], t0, t1);
25734        }
25735
25736        /* bytes 2, 1, 0 */
25737        for (i = 2; i >= 0; i--) {
25738            /* extract corresponding bytes */
25739            tcg_gen_andi_i32(t0, mxu_gpr[XRb - 1], 0xFF << (8 * i));
25740            tcg_gen_andi_i32(t1, mxu_gpr[XRc - 1], 0xFF << (8 * i));
25741            /* move the bytes to the leftmost position */
25742            tcg_gen_shli_i32(t0, t0, 8 * (3 - i));
25743            tcg_gen_shli_i32(t1, t1, 8 * (3 - i));
25744            /* t0 will be max/min of t0 and t1 */
25745            if (opc == OPC_MXU_Q8MAX) {
25746                tcg_gen_smax_i32(t0, t0, t1);
25747            } else {
25748                tcg_gen_smin_i32(t0, t0, t1);
25749            }
25750            /* return resulting byte to its original position */
25751            tcg_gen_shri_i32(t0, t0, 8 * (3 - i));
25752            /* finaly update the destination */
25753            tcg_gen_or_i32(mxu_gpr[XRa - 1], mxu_gpr[XRa - 1], t0);
25754        }
25755
25756        tcg_temp_free(t1);
25757        tcg_temp_free(t0);
25758    }
25759}
25760
25761
25762/*
25763 *                 MXU instruction category: align
25764 *                 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
25765 *
25766 *                       S32ALN     S32ALNI
25767 */
25768
25769/*
25770 *  S32ALNI XRc, XRb, XRa, optn3
25771 *    Arrange bytes from XRb and XRc according to one of five sets of
25772 *    rules determined by optn3, and place the result in XRa.
25773 *
25774 *   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
25775 *  +-----------+-----+---+-----+-------+-------+-------+-----------+
25776 *  |  SPECIAL2 |optn3|0 0|x x x|  XRc  |  XRb  |  XRa  |MXU__POOL16|
25777 *  +-----------+-----+---+-----+-------+-------+-------+-----------+
25778 *
25779 */
25780static void gen_mxu_S32ALNI(DisasContext *ctx)
25781{
25782    uint32_t optn3, pad, XRc, XRb, XRa;
25783
25784    optn3 = extract32(ctx->opcode,  23, 3);
25785    pad   = extract32(ctx->opcode,  21, 2);
25786    XRc   = extract32(ctx->opcode, 14, 4);
25787    XRb   = extract32(ctx->opcode, 10, 4);
25788    XRa   = extract32(ctx->opcode,  6, 4);
25789
25790    if (unlikely(pad != 0)) {
25791        /* opcode padding incorrect -> do nothing */
25792    } else if (unlikely(XRa == 0)) {
25793        /* destination is zero register -> do nothing */
25794    } else if (unlikely((XRb == 0) && (XRc == 0))) {
25795        /* both operands zero registers -> just set destination to all 0s */
25796        tcg_gen_movi_i32(mxu_gpr[XRa - 1], 0);
25797    } else if (unlikely(XRb == 0)) {
25798        /* XRb zero register -> just appropriatelly shift XRc into XRa */
25799        switch (optn3) {
25800        case MXU_OPTN3_PTN0:
25801            tcg_gen_movi_i32(mxu_gpr[XRa - 1], 0);
25802            break;
25803        case MXU_OPTN3_PTN1:
25804        case MXU_OPTN3_PTN2:
25805        case MXU_OPTN3_PTN3:
25806            tcg_gen_shri_i32(mxu_gpr[XRa - 1], mxu_gpr[XRc - 1],
25807                             8 * (4 - optn3));
25808            break;
25809        case MXU_OPTN3_PTN4:
25810            tcg_gen_mov_i32(mxu_gpr[XRa - 1], mxu_gpr[XRc - 1]);
25811            break;
25812        }
25813    } else if (unlikely(XRc == 0)) {
25814        /* XRc zero register -> just appropriatelly shift XRb into XRa */
25815        switch (optn3) {
25816        case MXU_OPTN3_PTN0:
25817            tcg_gen_mov_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1]);
25818            break;
25819        case MXU_OPTN3_PTN1:
25820        case MXU_OPTN3_PTN2:
25821        case MXU_OPTN3_PTN3:
25822            tcg_gen_shri_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1], 8 * optn3);
25823            break;
25824        case MXU_OPTN3_PTN4:
25825            tcg_gen_movi_i32(mxu_gpr[XRa - 1], 0);
25826            break;
25827        }
25828    } else if (unlikely(XRb == XRc)) {
25829        /* both operands same -> just rotation or moving from any of them */
25830        switch (optn3) {
25831        case MXU_OPTN3_PTN0:
25832        case MXU_OPTN3_PTN4:
25833            tcg_gen_mov_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1]);
25834            break;
25835        case MXU_OPTN3_PTN1:
25836        case MXU_OPTN3_PTN2:
25837        case MXU_OPTN3_PTN3:
25838            tcg_gen_rotli_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1], 8 * optn3);
25839            break;
25840        }
25841    } else {
25842        /* the most general case */
25843        switch (optn3) {
25844        case MXU_OPTN3_PTN0:
25845            {
25846                /*                                         */
25847                /*         XRb                XRc          */
25848                /*  +---------------+                      */
25849                /*  | A   B   C   D |    E   F   G   H     */
25850                /*  +-------+-------+                      */
25851                /*          |                              */
25852                /*         XRa                             */
25853                /*                                         */
25854
25855                tcg_gen_mov_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1]);
25856            }
25857            break;
25858        case MXU_OPTN3_PTN1:
25859            {
25860                /*                                         */
25861                /*         XRb                 XRc         */
25862                /*      +-------------------+              */
25863                /*    A | B   C   D       E | F   G   H    */
25864                /*      +---------+---------+              */
25865                /*                |                        */
25866                /*               XRa                       */
25867                /*                                         */
25868
25869                TCGv_i32 t0 = tcg_temp_new();
25870                TCGv_i32 t1 = tcg_temp_new();
25871
25872                tcg_gen_andi_i32(t0, mxu_gpr[XRb - 1], 0x00FFFFFF);
25873                tcg_gen_shli_i32(t0, t0, 8);
25874
25875                tcg_gen_andi_i32(t1, mxu_gpr[XRc - 1], 0xFF000000);
25876                tcg_gen_shri_i32(t1, t1, 24);
25877
25878                tcg_gen_or_i32(mxu_gpr[XRa - 1], t0, t1);
25879
25880                tcg_temp_free(t1);
25881                tcg_temp_free(t0);
25882            }
25883            break;
25884        case MXU_OPTN3_PTN2:
25885            {
25886                /*                                         */
25887                /*         XRb                 XRc         */
25888                /*          +-------------------+          */
25889                /*    A   B | C   D       E   F | G   H    */
25890                /*          +---------+---------+          */
25891                /*                    |                    */
25892                /*                   XRa                   */
25893                /*                                         */
25894
25895                TCGv_i32 t0 = tcg_temp_new();
25896                TCGv_i32 t1 = tcg_temp_new();
25897
25898                tcg_gen_andi_i32(t0, mxu_gpr[XRb - 1], 0x0000FFFF);
25899                tcg_gen_shli_i32(t0, t0, 16);
25900
25901                tcg_gen_andi_i32(t1, mxu_gpr[XRc - 1], 0xFFFF0000);
25902                tcg_gen_shri_i32(t1, t1, 16);
25903
25904                tcg_gen_or_i32(mxu_gpr[XRa - 1], t0, t1);
25905
25906                tcg_temp_free(t1);
25907                tcg_temp_free(t0);
25908            }
25909            break;
25910        case MXU_OPTN3_PTN3:
25911            {
25912                /*                                         */
25913                /*         XRb                 XRc         */
25914                /*              +-------------------+      */
25915                /*    A   B   C | D       E   F   G | H    */
25916                /*              +---------+---------+      */
25917                /*                        |                */
25918                /*                       XRa               */
25919                /*                                         */
25920
25921                TCGv_i32 t0 = tcg_temp_new();
25922                TCGv_i32 t1 = tcg_temp_new();
25923
25924                tcg_gen_andi_i32(t0, mxu_gpr[XRb - 1], 0x000000FF);
25925                tcg_gen_shli_i32(t0, t0, 24);
25926
25927                tcg_gen_andi_i32(t1, mxu_gpr[XRc - 1], 0xFFFFFF00);
25928                tcg_gen_shri_i32(t1, t1, 8);
25929
25930                tcg_gen_or_i32(mxu_gpr[XRa - 1], t0, t1);
25931
25932                tcg_temp_free(t1);
25933                tcg_temp_free(t0);
25934            }
25935            break;
25936        case MXU_OPTN3_PTN4:
25937            {
25938                /*                                         */
25939                /*         XRb                 XRc         */
25940                /*                     +---------------+   */
25941                /*    A   B   C   D    | E   F   G   H |   */
25942                /*                     +-------+-------+   */
25943                /*                             |           */
25944                /*                            XRa          */
25945                /*                                         */
25946
25947                tcg_gen_mov_i32(mxu_gpr[XRa - 1], mxu_gpr[XRc - 1]);
25948            }
25949            break;
25950        }
25951    }
25952}
25953
25954
25955/*
25956 * Decoding engine for MXU
25957 * =======================
25958 */
25959
25960/*
25961 *
25962 * Decode MXU pool00
25963 *
25964 *   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
25965 *  +-----------+---------+-----+-------+-------+-------+-----------+
25966 *  |  SPECIAL2 |0 0 0 0 0|x x x|  XRc  |  XRb  |  XRa  |MXU__POOL00|
25967 *  +-----------+---------+-----+-------+-------+-------+-----------+
25968 *
25969 */
25970static void decode_opc_mxu__pool00(CPUMIPSState *env, DisasContext *ctx)
25971{
25972    uint32_t opcode = extract32(ctx->opcode, 18, 3);
25973
25974    switch (opcode) {
25975    case OPC_MXU_S32MAX:
25976    case OPC_MXU_S32MIN:
25977        gen_mxu_S32MAX_S32MIN(ctx);
25978        break;
25979    case OPC_MXU_D16MAX:
25980    case OPC_MXU_D16MIN:
25981        gen_mxu_D16MAX_D16MIN(ctx);
25982        break;
25983    case OPC_MXU_Q8MAX:
25984    case OPC_MXU_Q8MIN:
25985        gen_mxu_Q8MAX_Q8MIN(ctx);
25986        break;
25987    case OPC_MXU_Q8SLT:
25988        /* TODO: Implement emulation of Q8SLT instruction. */
25989        MIPS_INVAL("OPC_MXU_Q8SLT");
25990        generate_exception_end(ctx, EXCP_RI);
25991        break;
25992    case OPC_MXU_Q8SLTU:
25993        /* TODO: Implement emulation of Q8SLTU instruction. */
25994        MIPS_INVAL("OPC_MXU_Q8SLTU");
25995        generate_exception_end(ctx, EXCP_RI);
25996        break;
25997    default:
25998        MIPS_INVAL("decode_opc_mxu");
25999        generate_exception_end(ctx, EXCP_RI);
26000        break;
26001    }
26002}
26003
26004/*
26005 *
26006 * Decode MXU pool01
26007 *
26008 *  S32SLT, D16SLT, D16AVG, D16AVGR, Q8AVG, Q8AVGR:
26009 *   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
26010 *  +-----------+---------+-----+-------+-------+-------+-----------+
26011 *  |  SPECIAL2 |0 0 0 0 0|x x x|  XRc  |  XRb  |  XRa  |MXU__POOL01|
26012 *  +-----------+---------+-----+-------+-------+-------+-----------+
26013 *
26014 *  Q8ADD:
26015 *   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
26016 *  +-----------+---+-----+-----+-------+-------+-------+-----------+
26017 *  |  SPECIAL2 |en2|0 0 0|x x x|  XRc  |  XRb  |  XRa  |MXU__POOL01|
26018 *  +-----------+---+-----+-----+-------+-------+-------+-----------+
26019 *
26020 */
26021static void decode_opc_mxu__pool01(CPUMIPSState *env, DisasContext *ctx)
26022{
26023    uint32_t opcode = extract32(ctx->opcode, 18, 3);
26024
26025    switch (opcode) {
26026    case OPC_MXU_S32SLT:
26027        /* TODO: Implement emulation of S32SLT instruction. */
26028        MIPS_INVAL("OPC_MXU_S32SLT");
26029        generate_exception_end(ctx, EXCP_RI);
26030        break;
26031    case OPC_MXU_D16SLT:
26032        /* TODO: Implement emulation of D16SLT instruction. */
26033        MIPS_INVAL("OPC_MXU_D16SLT");
26034        generate_exception_end(ctx, EXCP_RI);
26035        break;
26036    case OPC_MXU_D16AVG:
26037        /* TODO: Implement emulation of D16AVG instruction. */
26038        MIPS_INVAL("OPC_MXU_D16AVG");
26039        generate_exception_end(ctx, EXCP_RI);
26040        break;
26041    case OPC_MXU_D16AVGR:
26042        /* TODO: Implement emulation of D16AVGR instruction. */
26043        MIPS_INVAL("OPC_MXU_D16AVGR");
26044        generate_exception_end(ctx, EXCP_RI);
26045        break;
26046    case OPC_MXU_Q8AVG:
26047        /* TODO: Implement emulation of Q8AVG instruction. */
26048        MIPS_INVAL("OPC_MXU_Q8AVG");
26049        generate_exception_end(ctx, EXCP_RI);
26050        break;
26051    case OPC_MXU_Q8AVGR:
26052        /* TODO: Implement emulation of Q8AVGR instruction. */
26053        MIPS_INVAL("OPC_MXU_Q8AVGR");
26054        generate_exception_end(ctx, EXCP_RI);
26055        break;
26056    case OPC_MXU_Q8ADD:
26057        /* TODO: Implement emulation of Q8ADD instruction. */
26058        MIPS_INVAL("OPC_MXU_Q8ADD");
26059        generate_exception_end(ctx, EXCP_RI);
26060        break;
26061    default:
26062        MIPS_INVAL("decode_opc_mxu");
26063        generate_exception_end(ctx, EXCP_RI);
26064        break;
26065    }
26066}
26067
26068/*
26069 *
26070 * Decode MXU pool02
26071 *
26072 *   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
26073 *  +-----------+---------+-----+-------+-------+-------+-----------+
26074 *  |  SPECIAL2 |0 0 0 0 0|x x x|  XRc  |  XRb  |  XRa  |MXU__POOL02|
26075 *  +-----------+---------+-----+-------+-------+-------+-----------+
26076 *
26077 */
26078static void decode_opc_mxu__pool02(CPUMIPSState *env, DisasContext *ctx)
26079{
26080    uint32_t opcode = extract32(ctx->opcode, 18, 3);
26081
26082    switch (opcode) {
26083    case OPC_MXU_S32CPS:
26084        /* TODO: Implement emulation of S32CPS instruction. */
26085        MIPS_INVAL("OPC_MXU_S32CPS");
26086        generate_exception_end(ctx, EXCP_RI);
26087        break;
26088    case OPC_MXU_D16CPS:
26089        /* TODO: Implement emulation of D16CPS instruction. */
26090        MIPS_INVAL("OPC_MXU_D16CPS");
26091        generate_exception_end(ctx, EXCP_RI);
26092        break;
26093    case OPC_MXU_Q8ABD:
26094        /* TODO: Implement emulation of Q8ABD instruction. */
26095        MIPS_INVAL("OPC_MXU_Q8ABD");
26096        generate_exception_end(ctx, EXCP_RI);
26097        break;
26098    case OPC_MXU_Q16SAT:
26099        /* TODO: Implement emulation of Q16SAT instruction. */
26100        MIPS_INVAL("OPC_MXU_Q16SAT");
26101        generate_exception_end(ctx, EXCP_RI);
26102        break;
26103    default:
26104        MIPS_INVAL("decode_opc_mxu");
26105        generate_exception_end(ctx, EXCP_RI);
26106        break;
26107    }
26108}
26109
26110/*
26111 *
26112 * Decode MXU pool03
26113 *
26114 *  D16MULF:
26115 *   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
26116 *  +-----------+---+---+-------+-------+-------+-------+-----------+
26117 *  |  SPECIAL2 |x x|on2|0 0 0 0|  XRc  |  XRb  |  XRa  |MXU__POOL03|
26118 *  +-----------+---+---+-------+-------+-------+-------+-----------+
26119 *
26120 *  D16MULE:
26121 *   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
26122 *  +-----------+---+---+-------+-------+-------+-------+-----------+
26123 *  |  SPECIAL2 |x x|on2|   Xd  |  XRc  |  XRb  |  XRa  |MXU__POOL03|
26124 *  +-----------+---+---+-------+-------+-------+-------+-----------+
26125 *
26126 */
26127static void decode_opc_mxu__pool03(CPUMIPSState *env, DisasContext *ctx)
26128{
26129    uint32_t opcode = extract32(ctx->opcode, 24, 2);
26130
26131    switch (opcode) {
26132    case OPC_MXU_D16MULF:
26133        /* TODO: Implement emulation of D16MULF instruction. */
26134        MIPS_INVAL("OPC_MXU_D16MULF");
26135        generate_exception_end(ctx, EXCP_RI);
26136        break;
26137    case OPC_MXU_D16MULE:
26138        /* TODO: Implement emulation of D16MULE instruction. */
26139        MIPS_INVAL("OPC_MXU_D16MULE");
26140        generate_exception_end(ctx, EXCP_RI);
26141        break;
26142    default:
26143        MIPS_INVAL("decode_opc_mxu");
26144        generate_exception_end(ctx, EXCP_RI);
26145        break;
26146    }
26147}
26148
26149/*
26150 *
26151 * Decode MXU pool04
26152 *
26153 *   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
26154 *  +-----------+---------+-+-------------------+-------+-----------+
26155 *  |  SPECIAL2 |    rb   |x|        s12        |  XRa  |MXU__POOL04|
26156 *  +-----------+---------+-+-------------------+-------+-----------+
26157 *
26158 */
26159static void decode_opc_mxu__pool04(CPUMIPSState *env, DisasContext *ctx)
26160{
26161    uint32_t opcode = extract32(ctx->opcode, 20, 1);
26162
26163    switch (opcode) {
26164    case OPC_MXU_S32LDD:
26165    case OPC_MXU_S32LDDR:
26166        gen_mxu_s32ldd_s32lddr(ctx);
26167        break;
26168    default:
26169        MIPS_INVAL("decode_opc_mxu");
26170        generate_exception_end(ctx, EXCP_RI);
26171        break;
26172    }
26173}
26174
26175/*
26176 *
26177 * Decode MXU pool05
26178 *
26179 *   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
26180 *  +-----------+---------+-+-------------------+-------+-----------+
26181 *  |  SPECIAL2 |    rb   |x|        s12        |  XRa  |MXU__POOL05|
26182 *  +-----------+---------+-+-------------------+-------+-----------+
26183 *
26184 */
26185static void decode_opc_mxu__pool05(CPUMIPSState *env, DisasContext *ctx)
26186{
26187    uint32_t opcode = extract32(ctx->opcode, 20, 1);
26188
26189    switch (opcode) {
26190    case OPC_MXU_S32STD:
26191        /* TODO: Implement emulation of S32STD instruction. */
26192        MIPS_INVAL("OPC_MXU_S32STD");
26193        generate_exception_end(ctx, EXCP_RI);
26194        break;
26195    case OPC_MXU_S32STDR:
26196        /* TODO: Implement emulation of S32STDR instruction. */
26197        MIPS_INVAL("OPC_MXU_S32STDR");
26198        generate_exception_end(ctx, EXCP_RI);
26199        break;
26200    default:
26201        MIPS_INVAL("decode_opc_mxu");
26202        generate_exception_end(ctx, EXCP_RI);
26203        break;
26204    }
26205}
26206
26207/*
26208 *
26209 * Decode MXU pool06
26210 *
26211 *   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
26212 *  +-----------+---------+---------+---+-------+-------+-----------+
26213 *  |  SPECIAL2 |    rb   |    rc   |st2|x x x x|  XRa  |MXU__POOL06|
26214 *  +-----------+---------+---------+---+-------+-------+-----------+
26215 *
26216 */
26217static void decode_opc_mxu__pool06(CPUMIPSState *env, DisasContext *ctx)
26218{
26219    uint32_t opcode = extract32(ctx->opcode, 10, 4);
26220
26221    switch (opcode) {
26222    case OPC_MXU_S32LDDV:
26223        /* TODO: Implement emulation of S32LDDV instruction. */
26224        MIPS_INVAL("OPC_MXU_S32LDDV");
26225        generate_exception_end(ctx, EXCP_RI);
26226        break;
26227    case OPC_MXU_S32LDDVR:
26228        /* TODO: Implement emulation of S32LDDVR instruction. */
26229        MIPS_INVAL("OPC_MXU_S32LDDVR");
26230        generate_exception_end(ctx, EXCP_RI);
26231        break;
26232    default:
26233        MIPS_INVAL("decode_opc_mxu");
26234        generate_exception_end(ctx, EXCP_RI);
26235        break;
26236    }
26237}
26238
26239/*
26240 *
26241 * Decode MXU pool07
26242 *
26243 *   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
26244 *  +-----------+---------+---------+---+-------+-------+-----------+
26245 *  |  SPECIAL2 |    rb   |    rc   |st2|x x x x|  XRa  |MXU__POOL07|
26246 *  +-----------+---------+---------+---+-------+-------+-----------+
26247 *
26248 */
26249static void decode_opc_mxu__pool07(CPUMIPSState *env, DisasContext *ctx)
26250{
26251    uint32_t opcode = extract32(ctx->opcode, 10, 4);
26252
26253    switch (opcode) {
26254    case OPC_MXU_S32STDV:
26255        /* TODO: Implement emulation of S32TDV instruction. */
26256        MIPS_INVAL("OPC_MXU_S32TDV");
26257        generate_exception_end(ctx, EXCP_RI);
26258        break;
26259    case OPC_MXU_S32STDVR:
26260        /* TODO: Implement emulation of S32TDVR instruction. */
26261        MIPS_INVAL("OPC_MXU_S32TDVR");
26262        generate_exception_end(ctx, EXCP_RI);
26263        break;
26264    default:
26265        MIPS_INVAL("decode_opc_mxu");
26266        generate_exception_end(ctx, EXCP_RI);
26267        break;
26268    }
26269}
26270
26271/*
26272 *
26273 * Decode MXU pool08
26274 *
26275 *   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
26276 *  +-----------+---------+-+-------------------+-------+-----------+
26277 *  |  SPECIAL2 |    rb   |x|        s12        |  XRa  |MXU__POOL08|
26278 *  +-----------+---------+-+-------------------+-------+-----------+
26279 *
26280 */
26281static void decode_opc_mxu__pool08(CPUMIPSState *env, DisasContext *ctx)
26282{
26283    uint32_t opcode = extract32(ctx->opcode, 20, 1);
26284
26285    switch (opcode) {
26286    case OPC_MXU_S32LDI:
26287        /* TODO: Implement emulation of S32LDI instruction. */
26288        MIPS_INVAL("OPC_MXU_S32LDI");
26289        generate_exception_end(ctx, EXCP_RI);
26290        break;
26291    case OPC_MXU_S32LDIR:
26292        /* TODO: Implement emulation of S32LDIR instruction. */
26293        MIPS_INVAL("OPC_MXU_S32LDIR");
26294        generate_exception_end(ctx, EXCP_RI);
26295        break;
26296    default:
26297        MIPS_INVAL("decode_opc_mxu");
26298        generate_exception_end(ctx, EXCP_RI);
26299        break;
26300    }
26301}
26302
26303/*
26304 *
26305 * Decode MXU pool09
26306 *
26307 *   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
26308 *  +-----------+---------+-+-------------------+-------+-----------+
26309 *  |  SPECIAL2 |    rb   |x|        s12        |  XRa  |MXU__POOL09|
26310 *  +-----------+---------+-+-------------------+-------+-----------+
26311 *
26312 */
26313static void decode_opc_mxu__pool09(CPUMIPSState *env, DisasContext *ctx)
26314{
26315    uint32_t opcode = extract32(ctx->opcode, 5, 0);
26316
26317    switch (opcode) {
26318    case OPC_MXU_S32SDI:
26319        /* TODO: Implement emulation of S32SDI instruction. */
26320        MIPS_INVAL("OPC_MXU_S32SDI");
26321        generate_exception_end(ctx, EXCP_RI);
26322        break;
26323    case OPC_MXU_S32SDIR:
26324        /* TODO: Implement emulation of S32SDIR instruction. */
26325        MIPS_INVAL("OPC_MXU_S32SDIR");
26326        generate_exception_end(ctx, EXCP_RI);
26327        break;
26328    default:
26329        MIPS_INVAL("decode_opc_mxu");
26330        generate_exception_end(ctx, EXCP_RI);
26331        break;
26332    }
26333}
26334
26335/*
26336 *
26337 * Decode MXU pool10
26338 *
26339 *   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
26340 *  +-----------+---------+---------+---+-------+-------+-----------+
26341 *  |  SPECIAL2 |    rb   |    rc   |st2|x x x x|  XRa  |MXU__POOL10|
26342 *  +-----------+---------+---------+---+-------+-------+-----------+
26343 *
26344 */
26345static void decode_opc_mxu__pool10(CPUMIPSState *env, DisasContext *ctx)
26346{
26347    uint32_t opcode = extract32(ctx->opcode, 5, 0);
26348
26349    switch (opcode) {
26350    case OPC_MXU_S32LDIV:
26351        /* TODO: Implement emulation of S32LDIV instruction. */
26352        MIPS_INVAL("OPC_MXU_S32LDIV");
26353        generate_exception_end(ctx, EXCP_RI);
26354        break;
26355    case OPC_MXU_S32LDIVR:
26356        /* TODO: Implement emulation of S32LDIVR instruction. */
26357        MIPS_INVAL("OPC_MXU_S32LDIVR");
26358        generate_exception_end(ctx, EXCP_RI);
26359        break;
26360    default:
26361        MIPS_INVAL("decode_opc_mxu");
26362        generate_exception_end(ctx, EXCP_RI);
26363        break;
26364    }
26365}
26366
26367/*
26368 *
26369 * Decode MXU pool11
26370 *
26371 *   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
26372 *  +-----------+---------+---------+---+-------+-------+-----------+
26373 *  |  SPECIAL2 |    rb   |    rc   |st2|x x x x|  XRa  |MXU__POOL11|
26374 *  +-----------+---------+---------+---+-------+-------+-----------+
26375 *
26376 */
26377static void decode_opc_mxu__pool11(CPUMIPSState *env, DisasContext *ctx)
26378{
26379    uint32_t opcode = extract32(ctx->opcode, 10, 4);
26380
26381    switch (opcode) {
26382    case OPC_MXU_S32SDIV:
26383        /* TODO: Implement emulation of S32SDIV instruction. */
26384        MIPS_INVAL("OPC_MXU_S32SDIV");
26385        generate_exception_end(ctx, EXCP_RI);
26386        break;
26387    case OPC_MXU_S32SDIVR:
26388        /* TODO: Implement emulation of S32SDIVR instruction. */
26389        MIPS_INVAL("OPC_MXU_S32SDIVR");
26390        generate_exception_end(ctx, EXCP_RI);
26391        break;
26392    default:
26393        MIPS_INVAL("decode_opc_mxu");
26394        generate_exception_end(ctx, EXCP_RI);
26395        break;
26396    }
26397}
26398
26399/*
26400 *
26401 * Decode MXU pool12
26402 *
26403 *   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
26404 *  +-----------+---+---+-------+-------+-------+-------+-----------+
26405 *  |  SPECIAL2 |an2|x x|   Xd  |  XRc  |  XRb  |  XRa  |MXU__POOL12|
26406 *  +-----------+---+---+-------+-------+-------+-------+-----------+
26407 *
26408 */
26409static void decode_opc_mxu__pool12(CPUMIPSState *env, DisasContext *ctx)
26410{
26411    uint32_t opcode = extract32(ctx->opcode, 22, 2);
26412
26413    switch (opcode) {
26414    case OPC_MXU_D32ACC:
26415        /* TODO: Implement emulation of D32ACC instruction. */
26416        MIPS_INVAL("OPC_MXU_D32ACC");
26417        generate_exception_end(ctx, EXCP_RI);
26418        break;
26419    case OPC_MXU_D32ACCM:
26420        /* TODO: Implement emulation of D32ACCM instruction. */
26421        MIPS_INVAL("OPC_MXU_D32ACCM");
26422        generate_exception_end(ctx, EXCP_RI);
26423        break;
26424    case OPC_MXU_D32ASUM:
26425        /* TODO: Implement emulation of D32ASUM instruction. */
26426        MIPS_INVAL("OPC_MXU_D32ASUM");
26427        generate_exception_end(ctx, EXCP_RI);
26428        break;
26429    default:
26430        MIPS_INVAL("decode_opc_mxu");
26431        generate_exception_end(ctx, EXCP_RI);
26432        break;
26433    }
26434}
26435
26436/*
26437 *
26438 * Decode MXU pool13
26439 *
26440 *   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
26441 *  +-----------+---+---+-------+-------+-------+-------+-----------+
26442 *  |  SPECIAL2 |en2|x x|0 0 0 0|  XRc  |  XRb  |  XRa  |MXU__POOL13|
26443 *  +-----------+---+---+-------+-------+-------+-------+-----------+
26444 *
26445 */
26446static void decode_opc_mxu__pool13(CPUMIPSState *env, DisasContext *ctx)
26447{
26448    uint32_t opcode = extract32(ctx->opcode, 22, 2);
26449
26450    switch (opcode) {
26451    case OPC_MXU_Q16ACC:
26452        /* TODO: Implement emulation of Q16ACC instruction. */
26453        MIPS_INVAL("OPC_MXU_Q16ACC");
26454        generate_exception_end(ctx, EXCP_RI);
26455        break;
26456    case OPC_MXU_Q16ACCM:
26457        /* TODO: Implement emulation of Q16ACCM instruction. */
26458        MIPS_INVAL("OPC_MXU_Q16ACCM");
26459        generate_exception_end(ctx, EXCP_RI);
26460        break;
26461    case OPC_MXU_Q16ASUM:
26462        /* TODO: Implement emulation of Q16ASUM instruction. */
26463        MIPS_INVAL("OPC_MXU_Q16ASUM");
26464        generate_exception_end(ctx, EXCP_RI);
26465        break;
26466    default:
26467        MIPS_INVAL("decode_opc_mxu");
26468        generate_exception_end(ctx, EXCP_RI);
26469        break;
26470    }
26471}
26472
26473/*
26474 *
26475 * Decode MXU pool14
26476 *
26477 *  Q8ADDE, Q8ACCE:
26478 *   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
26479 *  +-----------+---+---+-------+-------+-------+-------+-----------+
26480 *  |  SPECIAL2 |0 0|x x|  XRd  |  XRc  |  XRb  |  XRa  |MXU__POOL14|
26481 *  +-----------+---+---+-------+-------+-------+-------+-----------+
26482 *
26483 *  D8SUM, D8SUMC:
26484 *   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
26485 *  +-----------+---+---+-------+-------+-------+-------+-----------+
26486 *  |  SPECIAL2 |en2|x x|0 0 0 0|  XRc  |  XRb  |  XRa  |MXU__POOL14|
26487 *  +-----------+---+---+-------+-------+-------+-------+-----------+
26488 *
26489 */
26490static void decode_opc_mxu__pool14(CPUMIPSState *env, DisasContext *ctx)
26491{
26492    uint32_t opcode = extract32(ctx->opcode, 22, 2);
26493
26494    switch (opcode) {
26495    case OPC_MXU_Q8ADDE:
26496        /* TODO: Implement emulation of Q8ADDE instruction. */
26497        MIPS_INVAL("OPC_MXU_Q8ADDE");
26498        generate_exception_end(ctx, EXCP_RI);
26499        break;
26500    case OPC_MXU_D8SUM:
26501        /* TODO: Implement emulation of D8SUM instruction. */
26502        MIPS_INVAL("OPC_MXU_D8SUM");
26503        generate_exception_end(ctx, EXCP_RI);
26504        break;
26505    case OPC_MXU_D8SUMC:
26506        /* TODO: Implement emulation of D8SUMC instruction. */
26507        MIPS_INVAL("OPC_MXU_D8SUMC");
26508        generate_exception_end(ctx, EXCP_RI);
26509        break;
26510    default:
26511        MIPS_INVAL("decode_opc_mxu");
26512        generate_exception_end(ctx, EXCP_RI);
26513        break;
26514    }
26515}
26516
26517/*
26518 *
26519 * Decode MXU pool15
26520 *
26521 *  S32MUL, S32MULU, S32EXTRV:
26522 *   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
26523 *  +-----------+---------+---------+---+-------+-------+-----------+
26524 *  |  SPECIAL2 |    rs   |    rt   |x x|  XRd  |  XRa  |MXU__POOL15|
26525 *  +-----------+---------+---------+---+-------+-------+-----------+
26526 *
26527 *  S32EXTR:
26528 *   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
26529 *  +-----------+---------+---------+---+-------+-------+-----------+
26530 *  |  SPECIAL2 |    rb   |   sft5  |x x|  XRd  |  XRa  |MXU__POOL15|
26531 *  +-----------+---------+---------+---+-------+-------+-----------+
26532 *
26533 */
26534static void decode_opc_mxu__pool15(CPUMIPSState *env, DisasContext *ctx)
26535{
26536    uint32_t opcode = extract32(ctx->opcode, 14, 2);
26537
26538    switch (opcode) {
26539    case OPC_MXU_S32MUL:
26540        /* TODO: Implement emulation of S32MUL instruction. */
26541        MIPS_INVAL("OPC_MXU_S32MUL");
26542        generate_exception_end(ctx, EXCP_RI);
26543        break;
26544    case OPC_MXU_S32MULU:
26545        /* TODO: Implement emulation of S32MULU instruction. */
26546        MIPS_INVAL("OPC_MXU_S32MULU");
26547        generate_exception_end(ctx, EXCP_RI);
26548        break;
26549    case OPC_MXU_S32EXTR:
26550        /* TODO: Implement emulation of S32EXTR instruction. */
26551        MIPS_INVAL("OPC_MXU_S32EXTR");
26552        generate_exception_end(ctx, EXCP_RI);
26553        break;
26554    case OPC_MXU_S32EXTRV:
26555        /* TODO: Implement emulation of S32EXTRV instruction. */
26556        MIPS_INVAL("OPC_MXU_S32EXTRV");
26557        generate_exception_end(ctx, EXCP_RI);
26558        break;
26559    default:
26560        MIPS_INVAL("decode_opc_mxu");
26561        generate_exception_end(ctx, EXCP_RI);
26562        break;
26563    }
26564}
26565
26566/*
26567 *
26568 * Decode MXU pool16
26569 *
26570 *  D32SARW:
26571 *   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
26572 *  +-----------+---------+-----+-------+-------+-------+-----------+
26573 *  |  SPECIAL2 |    rb   |x x x|  XRc  |  XRb  |  XRa  |MXU__POOL16|
26574 *  +-----------+---------+-----+-------+-------+-------+-----------+
26575 *
26576 *  S32ALN:
26577 *   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
26578 *  +-----------+---------+-----+-------+-------+-------+-----------+
26579 *  |  SPECIAL2 |    rs   |x x x|  XRc  |  XRb  |  XRa  |MXU__POOL16|
26580 *  +-----------+---------+-----+-------+-------+-------+-----------+
26581 *
26582 *  S32ALNI:
26583 *   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
26584 *  +-----------+-----+---+-----+-------+-------+-------+-----------+
26585 *  |  SPECIAL2 |  s3 |0 0|x x x|  XRc  |  XRb  |  XRa  |MXU__POOL16|
26586 *  +-----------+-----+---+-----+-------+-------+-------+-----------+
26587 *
26588 *  S32LUI:
26589 *   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
26590 *  +-----------+-----+---+-----+-------+---------------+-----------+
26591 *  |  SPECIAL2 |optn3|0 0|x x x|  XRc  |       s8      |MXU__POOL16|
26592 *  +-----------+-----+---+-----+-------+---------------+-----------+
26593 *
26594 *  S32NOR, S32AND, S32OR, S32XOR:
26595 *   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
26596 *  +-----------+---------+-----+-------+-------+-------+-----------+
26597 *  |  SPECIAL2 |0 0 0 0 0|x x x|  XRc  |  XRb  |  XRa  |MXU__POOL16|
26598 *  +-----------+---------+-----+-------+-------+-------+-----------+
26599 *
26600 */
26601static void decode_opc_mxu__pool16(CPUMIPSState *env, DisasContext *ctx)
26602{
26603    uint32_t opcode = extract32(ctx->opcode, 18, 3);
26604
26605    switch (opcode) {
26606    case OPC_MXU_D32SARW:
26607        /* TODO: Implement emulation of D32SARW instruction. */
26608        MIPS_INVAL("OPC_MXU_D32SARW");
26609        generate_exception_end(ctx, EXCP_RI);
26610        break;
26611    case OPC_MXU_S32ALN:
26612        /* TODO: Implement emulation of S32ALN instruction. */
26613        MIPS_INVAL("OPC_MXU_S32ALN");
26614        generate_exception_end(ctx, EXCP_RI);
26615        break;
26616    case OPC_MXU_S32ALNI:
26617        gen_mxu_S32ALNI(ctx);
26618        break;
26619    case OPC_MXU_S32LUI:
26620        /* TODO: Implement emulation of S32LUI instruction. */
26621        MIPS_INVAL("OPC_MXU_S32LUI");
26622        generate_exception_end(ctx, EXCP_RI);
26623        break;
26624    case OPC_MXU_S32NOR:
26625        gen_mxu_S32NOR(ctx);
26626        break;
26627    case OPC_MXU_S32AND:
26628        gen_mxu_S32AND(ctx);
26629        break;
26630    case OPC_MXU_S32OR:
26631        gen_mxu_S32OR(ctx);
26632        break;
26633    case OPC_MXU_S32XOR:
26634        gen_mxu_S32XOR(ctx);
26635        break;
26636    default:
26637        MIPS_INVAL("decode_opc_mxu");
26638        generate_exception_end(ctx, EXCP_RI);
26639        break;
26640    }
26641}
26642
26643/*
26644 *
26645 * Decode MXU pool17
26646 *
26647 *   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
26648 *  +-----------+---------+---------+---+---------+-----+-----------+
26649 *  |  SPECIAL2 |    rs   |    rt   |0 0|    rd   |x x x|MXU__POOL15|
26650 *  +-----------+---------+---------+---+---------+-----+-----------+
26651 *
26652 */
26653static void decode_opc_mxu__pool17(CPUMIPSState *env, DisasContext *ctx)
26654{
26655    uint32_t opcode = extract32(ctx->opcode, 6, 2);
26656
26657    switch (opcode) {
26658    case OPC_MXU_LXW:
26659        /* TODO: Implement emulation of LXW instruction. */
26660        MIPS_INVAL("OPC_MXU_LXW");
26661        generate_exception_end(ctx, EXCP_RI);
26662        break;
26663    case OPC_MXU_LXH:
26664        /* TODO: Implement emulation of LXH instruction. */
26665        MIPS_INVAL("OPC_MXU_LXH");
26666        generate_exception_end(ctx, EXCP_RI);
26667        break;
26668    case OPC_MXU_LXHU:
26669        /* TODO: Implement emulation of LXHU instruction. */
26670        MIPS_INVAL("OPC_MXU_LXHU");
26671        generate_exception_end(ctx, EXCP_RI);
26672        break;
26673    case OPC_MXU_LXB:
26674        /* TODO: Implement emulation of LXB instruction. */
26675        MIPS_INVAL("OPC_MXU_LXB");
26676        generate_exception_end(ctx, EXCP_RI);
26677        break;
26678    case OPC_MXU_LXBU:
26679        /* TODO: Implement emulation of LXBU instruction. */
26680        MIPS_INVAL("OPC_MXU_LXBU");
26681        generate_exception_end(ctx, EXCP_RI);
26682        break;
26683    default:
26684        MIPS_INVAL("decode_opc_mxu");
26685        generate_exception_end(ctx, EXCP_RI);
26686        break;
26687    }
26688}
26689/*
26690 *
26691 * Decode MXU pool18
26692 *
26693 *   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
26694 *  +-----------+---------+-----+-------+-------+-------+-----------+
26695 *  |  SPECIAL2 |    rb   |x x x|  XRd  |  XRa  |0 0 0 0|MXU__POOL18|
26696 *  +-----------+---------+-----+-------+-------+-------+-----------+
26697 *
26698 */
26699static void decode_opc_mxu__pool18(CPUMIPSState *env, DisasContext *ctx)
26700{
26701    uint32_t opcode = extract32(ctx->opcode, 18, 3);
26702
26703    switch (opcode) {
26704    case OPC_MXU_D32SLLV:
26705        /* TODO: Implement emulation of D32SLLV instruction. */
26706        MIPS_INVAL("OPC_MXU_D32SLLV");
26707        generate_exception_end(ctx, EXCP_RI);
26708        break;
26709    case OPC_MXU_D32SLRV:
26710        /* TODO: Implement emulation of D32SLRV instruction. */
26711        MIPS_INVAL("OPC_MXU_D32SLRV");
26712        generate_exception_end(ctx, EXCP_RI);
26713        break;
26714    case OPC_MXU_D32SARV:
26715        /* TODO: Implement emulation of D32SARV instruction. */
26716        MIPS_INVAL("OPC_MXU_D32SARV");
26717        generate_exception_end(ctx, EXCP_RI);
26718        break;
26719    case OPC_MXU_Q16SLLV:
26720        /* TODO: Implement emulation of Q16SLLV instruction. */
26721        MIPS_INVAL("OPC_MXU_Q16SLLV");
26722        generate_exception_end(ctx, EXCP_RI);
26723        break;
26724    case OPC_MXU_Q16SLRV:
26725        /* TODO: Implement emulation of Q16SLRV instruction. */
26726        MIPS_INVAL("OPC_MXU_Q16SLRV");
26727        generate_exception_end(ctx, EXCP_RI);
26728        break;
26729    case OPC_MXU_Q16SARV:
26730        /* TODO: Implement emulation of Q16SARV instruction. */
26731        MIPS_INVAL("OPC_MXU_Q16SARV");
26732        generate_exception_end(ctx, EXCP_RI);
26733        break;
26734    default:
26735        MIPS_INVAL("decode_opc_mxu");
26736        generate_exception_end(ctx, EXCP_RI);
26737        break;
26738    }
26739}
26740
26741/*
26742 *
26743 * Decode MXU pool19
26744 *
26745 *   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
26746 *  +-----------+---+---+-------+-------+-------+-------+-----------+
26747 *  |  SPECIAL2 |0 0|x x|  XRd  |  XRc  |  XRb  |  XRa  |MXU__POOL19|
26748 *  +-----------+---+---+-------+-------+-------+-------+-----------+
26749 *
26750 */
26751static void decode_opc_mxu__pool19(CPUMIPSState *env, DisasContext *ctx)
26752{
26753    uint32_t opcode = extract32(ctx->opcode, 22, 2);
26754
26755    switch (opcode) {
26756    case OPC_MXU_Q8MUL:
26757    case OPC_MXU_Q8MULSU:
26758        gen_mxu_q8mul_q8mulsu(ctx);
26759        break;
26760    default:
26761        MIPS_INVAL("decode_opc_mxu");
26762        generate_exception_end(ctx, EXCP_RI);
26763        break;
26764    }
26765}
26766
26767/*
26768 *
26769 * Decode MXU pool20
26770 *
26771 *   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
26772 *  +-----------+---------+-----+-------+-------+-------+-----------+
26773 *  |  SPECIAL2 |0 0 0 0 0|x x x|  XRc  |  XRb  |  XRa  |MXU__POOL20|
26774 *  +-----------+---------+-----+-------+-------+-------+-----------+
26775 *
26776 */
26777static void decode_opc_mxu__pool20(CPUMIPSState *env, DisasContext *ctx)
26778{
26779    uint32_t opcode = extract32(ctx->opcode, 18, 3);
26780
26781    switch (opcode) {
26782    case OPC_MXU_Q8MOVZ:
26783        /* TODO: Implement emulation of Q8MOVZ instruction. */
26784        MIPS_INVAL("OPC_MXU_Q8MOVZ");
26785        generate_exception_end(ctx, EXCP_RI);
26786        break;
26787    case OPC_MXU_Q8MOVN:
26788        /* TODO: Implement emulation of Q8MOVN instruction. */
26789        MIPS_INVAL("OPC_MXU_Q8MOVN");
26790        generate_exception_end(ctx, EXCP_RI);
26791        break;
26792    case OPC_MXU_D16MOVZ:
26793        /* TODO: Implement emulation of D16MOVZ instruction. */
26794        MIPS_INVAL("OPC_MXU_D16MOVZ");
26795        generate_exception_end(ctx, EXCP_RI);
26796        break;
26797    case OPC_MXU_D16MOVN:
26798        /* TODO: Implement emulation of D16MOVN instruction. */
26799        MIPS_INVAL("OPC_MXU_D16MOVN");
26800        generate_exception_end(ctx, EXCP_RI);
26801        break;
26802    case OPC_MXU_S32MOVZ:
26803        /* TODO: Implement emulation of S32MOVZ instruction. */
26804        MIPS_INVAL("OPC_MXU_S32MOVZ");
26805        generate_exception_end(ctx, EXCP_RI);
26806        break;
26807    case OPC_MXU_S32MOVN:
26808        /* TODO: Implement emulation of S32MOVN instruction. */
26809        MIPS_INVAL("OPC_MXU_S32MOVN");
26810        generate_exception_end(ctx, EXCP_RI);
26811        break;
26812    default:
26813        MIPS_INVAL("decode_opc_mxu");
26814        generate_exception_end(ctx, EXCP_RI);
26815        break;
26816    }
26817}
26818
26819/*
26820 *
26821 * Decode MXU pool21
26822 *
26823 *   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
26824 *  +-----------+---+---+-------+-------+-------+-------+-----------+
26825 *  |  SPECIAL2 |an2|x x|  XRd  |  XRc  |  XRb  |  XRa  |MXU__POOL21|
26826 *  +-----------+---+---+-------+-------+-------+-------+-----------+
26827 *
26828 */
26829static void decode_opc_mxu__pool21(CPUMIPSState *env, DisasContext *ctx)
26830{
26831    uint32_t opcode = extract32(ctx->opcode, 22, 2);
26832
26833    switch (opcode) {
26834    case OPC_MXU_Q8MAC:
26835        /* TODO: Implement emulation of Q8MAC instruction. */
26836        MIPS_INVAL("OPC_MXU_Q8MAC");
26837        generate_exception_end(ctx, EXCP_RI);
26838        break;
26839    case OPC_MXU_Q8MACSU:
26840        /* TODO: Implement emulation of Q8MACSU instruction. */
26841        MIPS_INVAL("OPC_MXU_Q8MACSU");
26842        generate_exception_end(ctx, EXCP_RI);
26843        break;
26844    default:
26845        MIPS_INVAL("decode_opc_mxu");
26846        generate_exception_end(ctx, EXCP_RI);
26847        break;
26848    }
26849}
26850
26851
26852/*
26853 * Main MXU decoding function
26854 *
26855 *   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
26856 *  +-----------+---------------------------------------+-----------+
26857 *  |  SPECIAL2 |                                       |x x x x x x|
26858 *  +-----------+---------------------------------------+-----------+
26859 *
26860 */
26861static void decode_opc_mxu(CPUMIPSState *env, DisasContext *ctx)
26862{
26863    /*
26864     * TODO: Investigate necessity of including handling of
26865     * CLZ, CLO, SDBB in this function, as they belong to
26866     * SPECIAL2 opcode space for regular pre-R6 MIPS ISAs.
26867     */
26868    uint32_t opcode = extract32(ctx->opcode, 0, 6);
26869
26870    if (opcode == OPC__MXU_MUL) {
26871        uint32_t  rs, rt, rd, op1;
26872
26873        rs = extract32(ctx->opcode, 21, 5);
26874        rt = extract32(ctx->opcode, 16, 5);
26875        rd = extract32(ctx->opcode, 11, 5);
26876        op1 = MASK_SPECIAL2(ctx->opcode);
26877
26878        gen_arith(ctx, op1, rd, rs, rt);
26879
26880        return;
26881    }
26882
26883    if (opcode == OPC_MXU_S32M2I) {
26884        gen_mxu_s32m2i(ctx);
26885        return;
26886    }
26887
26888    if (opcode == OPC_MXU_S32I2M) {
26889        gen_mxu_s32i2m(ctx);
26890        return;
26891    }
26892
26893    {
26894        TCGv t_mxu_cr = tcg_temp_new();
26895        TCGLabel *l_exit = gen_new_label();
26896
26897        gen_load_mxu_cr(t_mxu_cr);
26898        tcg_gen_andi_tl(t_mxu_cr, t_mxu_cr, MXU_CR_MXU_EN);
26899        tcg_gen_brcondi_tl(TCG_COND_NE, t_mxu_cr, MXU_CR_MXU_EN, l_exit);
26900
26901        switch (opcode) {
26902        case OPC_MXU_S32MADD:
26903            /* TODO: Implement emulation of S32MADD instruction. */
26904            MIPS_INVAL("OPC_MXU_S32MADD");
26905            generate_exception_end(ctx, EXCP_RI);
26906            break;
26907        case OPC_MXU_S32MADDU:
26908            /* TODO: Implement emulation of S32MADDU instruction. */
26909            MIPS_INVAL("OPC_MXU_S32MADDU");
26910            generate_exception_end(ctx, EXCP_RI);
26911            break;
26912        case OPC_MXU__POOL00:
26913            decode_opc_mxu__pool00(env, ctx);
26914            break;
26915        case OPC_MXU_S32MSUB:
26916            /* TODO: Implement emulation of S32MSUB instruction. */
26917            MIPS_INVAL("OPC_MXU_S32MSUB");
26918            generate_exception_end(ctx, EXCP_RI);
26919            break;
26920        case OPC_MXU_S32MSUBU:
26921            /* TODO: Implement emulation of S32MSUBU instruction. */
26922            MIPS_INVAL("OPC_MXU_S32MSUBU");
26923            generate_exception_end(ctx, EXCP_RI);
26924            break;
26925        case OPC_MXU__POOL01:
26926            decode_opc_mxu__pool01(env, ctx);
26927            break;
26928        case OPC_MXU__POOL02:
26929            decode_opc_mxu__pool02(env, ctx);
26930            break;
26931        case OPC_MXU_D16MUL:
26932            gen_mxu_d16mul(ctx);
26933            break;
26934        case OPC_MXU__POOL03:
26935            decode_opc_mxu__pool03(env, ctx);
26936            break;
26937        case OPC_MXU_D16MAC:
26938            gen_mxu_d16mac(ctx);
26939            break;
26940        case OPC_MXU_D16MACF:
26941            /* TODO: Implement emulation of D16MACF instruction. */
26942            MIPS_INVAL("OPC_MXU_D16MACF");
26943            generate_exception_end(ctx, EXCP_RI);
26944            break;
26945        case OPC_MXU_D16MADL:
26946            /* TODO: Implement emulation of D16MADL instruction. */
26947            MIPS_INVAL("OPC_MXU_D16MADL");
26948            generate_exception_end(ctx, EXCP_RI);
26949            break;
26950        case OPC_MXU_S16MAD:
26951            /* TODO: Implement emulation of S16MAD instruction. */
26952            MIPS_INVAL("OPC_MXU_S16MAD");
26953            generate_exception_end(ctx, EXCP_RI);
26954            break;
26955        case OPC_MXU_Q16ADD:
26956            /* TODO: Implement emulation of Q16ADD instruction. */
26957            MIPS_INVAL("OPC_MXU_Q16ADD");
26958            generate_exception_end(ctx, EXCP_RI);
26959            break;
26960        case OPC_MXU_D16MACE:
26961            /* TODO: Implement emulation of D16MACE instruction. */
26962            MIPS_INVAL("OPC_MXU_D16MACE");
26963            generate_exception_end(ctx, EXCP_RI);
26964            break;
26965        case OPC_MXU__POOL04:
26966            decode_opc_mxu__pool04(env, ctx);
26967            break;
26968        case OPC_MXU__POOL05:
26969            decode_opc_mxu__pool05(env, ctx);
26970            break;
26971        case OPC_MXU__POOL06:
26972            decode_opc_mxu__pool06(env, ctx);
26973            break;
26974        case OPC_MXU__POOL07:
26975            decode_opc_mxu__pool07(env, ctx);
26976            break;
26977        case OPC_MXU__POOL08:
26978            decode_opc_mxu__pool08(env, ctx);
26979            break;
26980        case OPC_MXU__POOL09:
26981            decode_opc_mxu__pool09(env, ctx);
26982            break;
26983        case OPC_MXU__POOL10:
26984            decode_opc_mxu__pool10(env, ctx);
26985            break;
26986        case OPC_MXU__POOL11:
26987            decode_opc_mxu__pool11(env, ctx);
26988            break;
26989        case OPC_MXU_D32ADD:
26990            /* TODO: Implement emulation of D32ADD instruction. */
26991            MIPS_INVAL("OPC_MXU_D32ADD");
26992            generate_exception_end(ctx, EXCP_RI);
26993            break;
26994        case OPC_MXU__POOL12:
26995            decode_opc_mxu__pool12(env, ctx);
26996            break;
26997        case OPC_MXU__POOL13:
26998            decode_opc_mxu__pool13(env, ctx);
26999            break;
27000        case OPC_MXU__POOL14:
27001            decode_opc_mxu__pool14(env, ctx);
27002            break;
27003        case OPC_MXU_Q8ACCE:
27004            /* TODO: Implement emulation of Q8ACCE instruction. */
27005            MIPS_INVAL("OPC_MXU_Q8ACCE");
27006            generate_exception_end(ctx, EXCP_RI);
27007            break;
27008        case OPC_MXU_S8LDD:
27009            gen_mxu_s8ldd(ctx);
27010            break;
27011        case OPC_MXU_S8STD:
27012            /* TODO: Implement emulation of S8STD instruction. */
27013            MIPS_INVAL("OPC_MXU_S8STD");
27014            generate_exception_end(ctx, EXCP_RI);
27015            break;
27016        case OPC_MXU_S8LDI:
27017            /* TODO: Implement emulation of S8LDI instruction. */
27018            MIPS_INVAL("OPC_MXU_S8LDI");
27019            generate_exception_end(ctx, EXCP_RI);
27020            break;
27021        case OPC_MXU_S8SDI:
27022            /* TODO: Implement emulation of S8SDI instruction. */
27023            MIPS_INVAL("OPC_MXU_S8SDI");
27024            generate_exception_end(ctx, EXCP_RI);
27025            break;
27026        case OPC_MXU__POOL15:
27027            decode_opc_mxu__pool15(env, ctx);
27028            break;
27029        case OPC_MXU__POOL16:
27030            decode_opc_mxu__pool16(env, ctx);
27031            break;
27032        case OPC_MXU__POOL17:
27033            decode_opc_mxu__pool17(env, ctx);
27034            break;
27035        case OPC_MXU_S16LDD:
27036            /* TODO: Implement emulation of S16LDD instruction. */
27037            MIPS_INVAL("OPC_MXU_S16LDD");
27038            generate_exception_end(ctx, EXCP_RI);
27039            break;
27040        case OPC_MXU_S16STD:
27041            /* TODO: Implement emulation of S16STD instruction. */
27042            MIPS_INVAL("OPC_MXU_S16STD");
27043            generate_exception_end(ctx, EXCP_RI);
27044            break;
27045        case OPC_MXU_S16LDI:
27046            /* TODO: Implement emulation of S16LDI instruction. */
27047            MIPS_INVAL("OPC_MXU_S16LDI");
27048            generate_exception_end(ctx, EXCP_RI);
27049            break;
27050        case OPC_MXU_S16SDI:
27051            /* TODO: Implement emulation of S16SDI instruction. */
27052            MIPS_INVAL("OPC_MXU_S16SDI");
27053            generate_exception_end(ctx, EXCP_RI);
27054            break;
27055        case OPC_MXU_D32SLL:
27056            /* TODO: Implement emulation of D32SLL instruction. */
27057            MIPS_INVAL("OPC_MXU_D32SLL");
27058            generate_exception_end(ctx, EXCP_RI);
27059            break;
27060        case OPC_MXU_D32SLR:
27061            /* TODO: Implement emulation of D32SLR instruction. */
27062            MIPS_INVAL("OPC_MXU_D32SLR");
27063            generate_exception_end(ctx, EXCP_RI);
27064            break;
27065        case OPC_MXU_D32SARL:
27066            /* TODO: Implement emulation of D32SARL instruction. */
27067            MIPS_INVAL("OPC_MXU_D32SARL");
27068            generate_exception_end(ctx, EXCP_RI);
27069            break;
27070        case OPC_MXU_D32SAR:
27071            /* TODO: Implement emulation of D32SAR instruction. */
27072            MIPS_INVAL("OPC_MXU_D32SAR");
27073            generate_exception_end(ctx, EXCP_RI);
27074            break;
27075        case OPC_MXU_Q16SLL:
27076            /* TODO: Implement emulation of Q16SLL instruction. */
27077            MIPS_INVAL("OPC_MXU_Q16SLL");
27078            generate_exception_end(ctx, EXCP_RI);
27079            break;
27080        case OPC_MXU_Q16SLR:
27081            /* TODO: Implement emulation of Q16SLR instruction. */
27082            MIPS_INVAL("OPC_MXU_Q16SLR");
27083            generate_exception_end(ctx, EXCP_RI);
27084            break;
27085        case OPC_MXU__POOL18:
27086            decode_opc_mxu__pool18(env, ctx);
27087            break;
27088        case OPC_MXU_Q16SAR:
27089            /* TODO: Implement emulation of Q16SAR instruction. */
27090            MIPS_INVAL("OPC_MXU_Q16SAR");
27091            generate_exception_end(ctx, EXCP_RI);
27092            break;
27093        case OPC_MXU__POOL19:
27094            decode_opc_mxu__pool19(env, ctx);
27095            break;
27096        case OPC_MXU__POOL20:
27097            decode_opc_mxu__pool20(env, ctx);
27098            break;
27099        case OPC_MXU__POOL21:
27100            decode_opc_mxu__pool21(env, ctx);
27101            break;
27102        case OPC_MXU_Q16SCOP:
27103            /* TODO: Implement emulation of Q16SCOP instruction. */
27104            MIPS_INVAL("OPC_MXU_Q16SCOP");
27105            generate_exception_end(ctx, EXCP_RI);
27106            break;
27107        case OPC_MXU_Q8MADL:
27108            /* TODO: Implement emulation of Q8MADL instruction. */
27109            MIPS_INVAL("OPC_MXU_Q8MADL");
27110            generate_exception_end(ctx, EXCP_RI);
27111            break;
27112        case OPC_MXU_S32SFL:
27113            /* TODO: Implement emulation of S32SFL instruction. */
27114            MIPS_INVAL("OPC_MXU_S32SFL");
27115            generate_exception_end(ctx, EXCP_RI);
27116            break;
27117        case OPC_MXU_Q8SAD:
27118            /* TODO: Implement emulation of Q8SAD instruction. */
27119            MIPS_INVAL("OPC_MXU_Q8SAD");
27120            generate_exception_end(ctx, EXCP_RI);
27121            break;
27122        default:
27123            MIPS_INVAL("decode_opc_mxu");
27124            generate_exception_end(ctx, EXCP_RI);
27125        }
27126
27127        gen_set_label(l_exit);
27128        tcg_temp_free(t_mxu_cr);
27129    }
27130}
27131
27132#endif /* !defined(TARGET_MIPS64) */
27133
27134
27135static void decode_opc_special2_legacy(CPUMIPSState *env, DisasContext *ctx)
27136{
27137    int rs, rt, rd;
27138    uint32_t op1;
27139
27140    check_insn_opc_removed(ctx, ISA_MIPS32R6);
27141
27142    rs = (ctx->opcode >> 21) & 0x1f;
27143    rt = (ctx->opcode >> 16) & 0x1f;
27144    rd = (ctx->opcode >> 11) & 0x1f;
27145
27146    op1 = MASK_SPECIAL2(ctx->opcode);
27147    switch (op1) {
27148    case OPC_MADD: /* Multiply and add/sub */
27149    case OPC_MADDU:
27150    case OPC_MSUB:
27151    case OPC_MSUBU:
27152        check_insn(ctx, ISA_MIPS32);
27153        gen_muldiv(ctx, op1, rd & 3, rs, rt);
27154        break;
27155    case OPC_MUL:
27156        gen_arith(ctx, op1, rd, rs, rt);
27157        break;
27158    case OPC_DIV_G_2F:
27159    case OPC_DIVU_G_2F:
27160    case OPC_MULT_G_2F:
27161    case OPC_MULTU_G_2F:
27162    case OPC_MOD_G_2F:
27163    case OPC_MODU_G_2F:
27164        check_insn(ctx, INSN_LOONGSON2F);
27165        gen_loongson_integer(ctx, op1, rd, rs, rt);
27166        break;
27167    case OPC_CLO:
27168    case OPC_CLZ:
27169        check_insn(ctx, ISA_MIPS32);
27170        gen_cl(ctx, op1, rd, rs);
27171        break;
27172    case OPC_SDBBP:
27173        if (is_uhi(extract32(ctx->opcode, 6, 20))) {
27174            gen_helper_do_semihosting(cpu_env);
27175        } else {
27176            /*
27177             * XXX: not clear which exception should be raised
27178             *      when in debug mode...
27179             */
27180            check_insn(ctx, ISA_MIPS32);
27181            generate_exception_end(ctx, EXCP_DBp);
27182        }
27183        break;
27184#if defined(TARGET_MIPS64)
27185    case OPC_DCLO:
27186    case OPC_DCLZ:
27187        check_insn(ctx, ISA_MIPS64);
27188        check_mips_64(ctx);
27189        gen_cl(ctx, op1, rd, rs);
27190        break;
27191    case OPC_DMULT_G_2F:
27192    case OPC_DMULTU_G_2F:
27193    case OPC_DDIV_G_2F:
27194    case OPC_DDIVU_G_2F:
27195    case OPC_DMOD_G_2F:
27196    case OPC_DMODU_G_2F:
27197        check_insn(ctx, INSN_LOONGSON2F);
27198        gen_loongson_integer(ctx, op1, rd, rs, rt);
27199        break;
27200#endif
27201    default:            /* Invalid */
27202        MIPS_INVAL("special2_legacy");
27203        generate_exception_end(ctx, EXCP_RI);
27204        break;
27205    }
27206}
27207
27208static void decode_opc_special3_r6(CPUMIPSState *env, DisasContext *ctx)
27209{
27210    int rs, rt, rd, sa;
27211    uint32_t op1, op2;
27212    int16_t imm;
27213
27214    rs = (ctx->opcode >> 21) & 0x1f;
27215    rt = (ctx->opcode >> 16) & 0x1f;
27216    rd = (ctx->opcode >> 11) & 0x1f;
27217    sa = (ctx->opcode >> 6) & 0x1f;
27218    imm = (int16_t)ctx->opcode >> 7;
27219
27220    op1 = MASK_SPECIAL3(ctx->opcode);
27221    switch (op1) {
27222    case R6_OPC_PREF:
27223        if (rt >= 24) {
27224            /* hint codes 24-31 are reserved and signal RI */
27225            generate_exception_end(ctx, EXCP_RI);
27226        }
27227        /* Treat as NOP. */
27228        break;
27229    case R6_OPC_CACHE:
27230        check_cp0_enabled(ctx);
27231        if (ctx->hflags & MIPS_HFLAG_ITC_CACHE) {
27232            gen_cache_operation(ctx, rt, rs, imm);
27233        }
27234        break;
27235    case R6_OPC_SC:
27236        gen_st_cond(ctx, rt, rs, imm, MO_TESL, false);
27237        break;
27238    case R6_OPC_LL:
27239        gen_ld(ctx, op1, rt, rs, imm);
27240        break;
27241    case OPC_BSHFL:
27242        {
27243            if (rd == 0) {
27244                /* Treat as NOP. */
27245                break;
27246            }
27247            op2 = MASK_BSHFL(ctx->opcode);
27248            switch (op2) {
27249            case OPC_ALIGN:
27250            case OPC_ALIGN_1:
27251            case OPC_ALIGN_2:
27252            case OPC_ALIGN_3:
27253                gen_align(ctx, 32, rd, rs, rt, sa & 3);
27254                break;
27255            case OPC_BITSWAP:
27256                gen_bitswap(ctx, op2, rd, rt);
27257                break;
27258            }
27259        }
27260        break;
27261#ifndef CONFIG_USER_ONLY
27262    case OPC_GINV:
27263        if (unlikely(ctx->gi <= 1)) {
27264            generate_exception_end(ctx, EXCP_RI);
27265        }
27266        check_cp0_enabled(ctx);
27267        switch ((ctx->opcode >> 6) & 3) {
27268        case 0:    /* GINVI */
27269            /* Treat as NOP. */
27270            break;
27271        case 2:    /* GINVT */
27272            gen_helper_0e1i(ginvt, cpu_gpr[rs], extract32(ctx->opcode, 8, 2));
27273            break;
27274        default:
27275            generate_exception_end(ctx, EXCP_RI);
27276            break;
27277        }
27278        break;
27279#endif
27280#if defined(TARGET_MIPS64)
27281    case R6_OPC_SCD:
27282        gen_st_cond(ctx, rt, rs, imm, MO_TEQ, false);
27283        break;
27284    case R6_OPC_LLD:
27285        gen_ld(ctx, op1, rt, rs, imm);
27286        break;
27287    case OPC_DBSHFL:
27288        check_mips_64(ctx);
27289        {
27290            if (rd == 0) {
27291                /* Treat as NOP. */
27292                break;
27293            }
27294            op2 = MASK_DBSHFL(ctx->opcode);
27295            switch (op2) {
27296            case OPC_DALIGN:
27297            case OPC_DALIGN_1:
27298            case OPC_DALIGN_2:
27299            case OPC_DALIGN_3:
27300            case OPC_DALIGN_4:
27301            case OPC_DALIGN_5:
27302            case OPC_DALIGN_6:
27303            case OPC_DALIGN_7:
27304                gen_align(ctx, 64, rd, rs, rt, sa & 7);
27305                break;
27306            case OPC_DBITSWAP:
27307                gen_bitswap(ctx, op2, rd, rt);
27308                break;
27309            }
27310
27311        }
27312        break;
27313#endif
27314    default:            /* Invalid */
27315        MIPS_INVAL("special3_r6");
27316        generate_exception_end(ctx, EXCP_RI);
27317        break;
27318    }
27319}
27320
27321static void decode_opc_special3_legacy(CPUMIPSState *env, DisasContext *ctx)
27322{
27323    int rs, rt, rd;
27324    uint32_t op1, op2;
27325
27326    rs = (ctx->opcode >> 21) & 0x1f;
27327    rt = (ctx->opcode >> 16) & 0x1f;
27328    rd = (ctx->opcode >> 11) & 0x1f;
27329
27330    op1 = MASK_SPECIAL3(ctx->opcode);
27331    switch (op1) {
27332    case OPC_DIV_G_2E:
27333    case OPC_DIVU_G_2E:
27334    case OPC_MOD_G_2E:
27335    case OPC_MODU_G_2E:
27336    case OPC_MULT_G_2E:
27337    case OPC_MULTU_G_2E:
27338        /*
27339         * OPC_MULT_G_2E, OPC_ADDUH_QB_DSP, OPC_MUL_PH_DSP have
27340         * the same mask and op1.
27341         */
27342        if ((ctx->insn_flags & ASE_DSP_R2) && (op1 == OPC_MULT_G_2E)) {
27343            op2 = MASK_ADDUH_QB(ctx->opcode);
27344            switch (op2) {
27345            case OPC_ADDUH_QB:
27346            case OPC_ADDUH_R_QB:
27347            case OPC_ADDQH_PH:
27348            case OPC_ADDQH_R_PH:
27349            case OPC_ADDQH_W:
27350            case OPC_ADDQH_R_W:
27351            case OPC_SUBUH_QB:
27352            case OPC_SUBUH_R_QB:
27353            case OPC_SUBQH_PH:
27354            case OPC_SUBQH_R_PH:
27355            case OPC_SUBQH_W:
27356            case OPC_SUBQH_R_W:
27357                gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
27358                break;
27359            case OPC_MUL_PH:
27360            case OPC_MUL_S_PH:
27361            case OPC_MULQ_S_W:
27362            case OPC_MULQ_RS_W:
27363                gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 1);
27364                break;
27365            default:
27366                MIPS_INVAL("MASK ADDUH.QB");
27367                generate_exception_end(ctx, EXCP_RI);
27368                break;
27369            }
27370        } else if (ctx->insn_flags & INSN_LOONGSON2E) {
27371            gen_loongson_integer(ctx, op1, rd, rs, rt);
27372        } else {
27373            generate_exception_end(ctx, EXCP_RI);
27374        }
27375        break;
27376    case OPC_LX_DSP:
27377        op2 = MASK_LX(ctx->opcode);
27378        switch (op2) {
27379#if defined(TARGET_MIPS64)
27380        case OPC_LDX:
27381#endif
27382        case OPC_LBUX:
27383        case OPC_LHX:
27384        case OPC_LWX:
27385            gen_mipsdsp_ld(ctx, op2, rd, rs, rt);
27386            break;
27387        default:            /* Invalid */
27388            MIPS_INVAL("MASK LX");
27389            generate_exception_end(ctx, EXCP_RI);
27390            break;
27391        }
27392        break;
27393    case OPC_ABSQ_S_PH_DSP:
27394        op2 = MASK_ABSQ_S_PH(ctx->opcode);
27395        switch (op2) {
27396        case OPC_ABSQ_S_QB:
27397        case OPC_ABSQ_S_PH:
27398        case OPC_ABSQ_S_W:
27399        case OPC_PRECEQ_W_PHL:
27400        case OPC_PRECEQ_W_PHR:
27401        case OPC_PRECEQU_PH_QBL:
27402        case OPC_PRECEQU_PH_QBR:
27403        case OPC_PRECEQU_PH_QBLA:
27404        case OPC_PRECEQU_PH_QBRA:
27405        case OPC_PRECEU_PH_QBL:
27406        case OPC_PRECEU_PH_QBR:
27407        case OPC_PRECEU_PH_QBLA:
27408        case OPC_PRECEU_PH_QBRA:
27409            gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
27410            break;
27411        case OPC_BITREV:
27412        case OPC_REPL_QB:
27413        case OPC_REPLV_QB:
27414        case OPC_REPL_PH:
27415        case OPC_REPLV_PH:
27416            gen_mipsdsp_bitinsn(ctx, op1, op2, rd, rt);
27417            break;
27418        default:
27419            MIPS_INVAL("MASK ABSQ_S.PH");
27420            generate_exception_end(ctx, EXCP_RI);
27421            break;
27422        }
27423        break;
27424    case OPC_ADDU_QB_DSP:
27425        op2 = MASK_ADDU_QB(ctx->opcode);
27426        switch (op2) {
27427        case OPC_ADDQ_PH:
27428        case OPC_ADDQ_S_PH:
27429        case OPC_ADDQ_S_W:
27430        case OPC_ADDU_QB:
27431        case OPC_ADDU_S_QB:
27432        case OPC_ADDU_PH:
27433        case OPC_ADDU_S_PH:
27434        case OPC_SUBQ_PH:
27435        case OPC_SUBQ_S_PH:
27436        case OPC_SUBQ_S_W:
27437        case OPC_SUBU_QB:
27438        case OPC_SUBU_S_QB:
27439        case OPC_SUBU_PH:
27440        case OPC_SUBU_S_PH:
27441        case OPC_ADDSC:
27442        case OPC_ADDWC:
27443        case OPC_MODSUB:
27444        case OPC_RADDU_W_QB:
27445            gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
27446            break;
27447        case OPC_MULEU_S_PH_QBL:
27448        case OPC_MULEU_S_PH_QBR:
27449        case OPC_MULQ_RS_PH:
27450        case OPC_MULEQ_S_W_PHL:
27451        case OPC_MULEQ_S_W_PHR:
27452        case OPC_MULQ_S_PH:
27453            gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 1);
27454            break;
27455        default:            /* Invalid */
27456            MIPS_INVAL("MASK ADDU.QB");
27457            generate_exception_end(ctx, EXCP_RI);
27458            break;
27459
27460        }
27461        break;
27462    case OPC_CMPU_EQ_QB_DSP:
27463        op2 = MASK_CMPU_EQ_QB(ctx->opcode);
27464        switch (op2) {
27465        case OPC_PRECR_SRA_PH_W:
27466        case OPC_PRECR_SRA_R_PH_W:
27467            gen_mipsdsp_arith(ctx, op1, op2, rt, rs, rd);
27468            break;
27469        case OPC_PRECR_QB_PH:
27470        case OPC_PRECRQ_QB_PH:
27471        case OPC_PRECRQ_PH_W:
27472        case OPC_PRECRQ_RS_PH_W:
27473        case OPC_PRECRQU_S_QB_PH:
27474            gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
27475            break;
27476        case OPC_CMPU_EQ_QB:
27477        case OPC_CMPU_LT_QB:
27478        case OPC_CMPU_LE_QB:
27479        case OPC_CMP_EQ_PH:
27480        case OPC_CMP_LT_PH:
27481        case OPC_CMP_LE_PH:
27482            gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 0);
27483            break;
27484        case OPC_CMPGU_EQ_QB:
27485        case OPC_CMPGU_LT_QB:
27486        case OPC_CMPGU_LE_QB:
27487        case OPC_CMPGDU_EQ_QB:
27488        case OPC_CMPGDU_LT_QB:
27489        case OPC_CMPGDU_LE_QB:
27490        case OPC_PICK_QB:
27491        case OPC_PICK_PH:
27492        case OPC_PACKRL_PH:
27493            gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 1);
27494            break;
27495        default:            /* Invalid */
27496            MIPS_INVAL("MASK CMPU.EQ.QB");
27497            generate_exception_end(ctx, EXCP_RI);
27498            break;
27499        }
27500        break;
27501    case OPC_SHLL_QB_DSP:
27502        gen_mipsdsp_shift(ctx, op1, rd, rs, rt);
27503        break;
27504    case OPC_DPA_W_PH_DSP:
27505        op2 = MASK_DPA_W_PH(ctx->opcode);
27506        switch (op2) {
27507        case OPC_DPAU_H_QBL:
27508        case OPC_DPAU_H_QBR:
27509        case OPC_DPSU_H_QBL:
27510        case OPC_DPSU_H_QBR:
27511        case OPC_DPA_W_PH:
27512        case OPC_DPAX_W_PH:
27513        case OPC_DPAQ_S_W_PH:
27514        case OPC_DPAQX_S_W_PH:
27515        case OPC_DPAQX_SA_W_PH:
27516        case OPC_DPS_W_PH:
27517        case OPC_DPSX_W_PH:
27518        case OPC_DPSQ_S_W_PH:
27519        case OPC_DPSQX_S_W_PH:
27520        case OPC_DPSQX_SA_W_PH:
27521        case OPC_MULSAQ_S_W_PH:
27522        case OPC_DPAQ_SA_L_W:
27523        case OPC_DPSQ_SA_L_W:
27524        case OPC_MAQ_S_W_PHL:
27525        case OPC_MAQ_S_W_PHR:
27526        case OPC_MAQ_SA_W_PHL:
27527        case OPC_MAQ_SA_W_PHR:
27528        case OPC_MULSA_W_PH:
27529            gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 0);
27530            break;
27531        default:            /* Invalid */
27532            MIPS_INVAL("MASK DPAW.PH");
27533            generate_exception_end(ctx, EXCP_RI);
27534            break;
27535        }
27536        break;
27537    case OPC_INSV_DSP:
27538        op2 = MASK_INSV(ctx->opcode);
27539        switch (op2) {
27540        case OPC_INSV:
27541            check_dsp(ctx);
27542            {
27543                TCGv t0, t1;
27544
27545                if (rt == 0) {
27546                    break;
27547                }
27548
27549                t0 = tcg_temp_new();
27550                t1 = tcg_temp_new();
27551
27552                gen_load_gpr(t0, rt);
27553                gen_load_gpr(t1, rs);
27554
27555                gen_helper_insv(cpu_gpr[rt], cpu_env, t1, t0);
27556
27557                tcg_temp_free(t0);
27558                tcg_temp_free(t1);
27559                break;
27560            }
27561        default:            /* Invalid */
27562            MIPS_INVAL("MASK INSV");
27563            generate_exception_end(ctx, EXCP_RI);
27564            break;
27565        }
27566        break;
27567    case OPC_APPEND_DSP:
27568        gen_mipsdsp_append(env, ctx, op1, rt, rs, rd);
27569        break;
27570    case OPC_EXTR_W_DSP:
27571        op2 = MASK_EXTR_W(ctx->opcode);
27572        switch (op2) {
27573        case OPC_EXTR_W:
27574        case OPC_EXTR_R_W:
27575        case OPC_EXTR_RS_W:
27576        case OPC_EXTR_S_H:
27577        case OPC_EXTRV_S_H:
27578        case OPC_EXTRV_W:
27579        case OPC_EXTRV_R_W:
27580        case OPC_EXTRV_RS_W:
27581        case OPC_EXTP:
27582        case OPC_EXTPV:
27583        case OPC_EXTPDP:
27584        case OPC_EXTPDPV:
27585            gen_mipsdsp_accinsn(ctx, op1, op2, rt, rs, rd, 1);
27586            break;
27587        case OPC_RDDSP:
27588            gen_mipsdsp_accinsn(ctx, op1, op2, rd, rs, rt, 1);
27589            break;
27590        case OPC_SHILO:
27591        case OPC_SHILOV:
27592        case OPC_MTHLIP:
27593        case OPC_WRDSP:
27594            gen_mipsdsp_accinsn(ctx, op1, op2, rd, rs, rt, 0);
27595            break;
27596        default:            /* Invalid */
27597            MIPS_INVAL("MASK EXTR.W");
27598            generate_exception_end(ctx, EXCP_RI);
27599            break;
27600        }
27601        break;
27602#if defined(TARGET_MIPS64)
27603    case OPC_DDIV_G_2E:
27604    case OPC_DDIVU_G_2E:
27605    case OPC_DMULT_G_2E:
27606    case OPC_DMULTU_G_2E:
27607    case OPC_DMOD_G_2E:
27608    case OPC_DMODU_G_2E:
27609        check_insn(ctx, INSN_LOONGSON2E);
27610        gen_loongson_integer(ctx, op1, rd, rs, rt);
27611        break;
27612    case OPC_ABSQ_S_QH_DSP:
27613        op2 = MASK_ABSQ_S_QH(ctx->opcode);
27614        switch (op2) {
27615        case OPC_PRECEQ_L_PWL:
27616        case OPC_PRECEQ_L_PWR:
27617        case OPC_PRECEQ_PW_QHL:
27618        case OPC_PRECEQ_PW_QHR:
27619        case OPC_PRECEQ_PW_QHLA:
27620        case OPC_PRECEQ_PW_QHRA:
27621        case OPC_PRECEQU_QH_OBL:
27622        case OPC_PRECEQU_QH_OBR:
27623        case OPC_PRECEQU_QH_OBLA:
27624        case OPC_PRECEQU_QH_OBRA:
27625        case OPC_PRECEU_QH_OBL:
27626        case OPC_PRECEU_QH_OBR:
27627        case OPC_PRECEU_QH_OBLA:
27628        case OPC_PRECEU_QH_OBRA:
27629        case OPC_ABSQ_S_OB:
27630        case OPC_ABSQ_S_PW:
27631        case OPC_ABSQ_S_QH:
27632            gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
27633            break;
27634        case OPC_REPL_OB:
27635        case OPC_REPL_PW:
27636        case OPC_REPL_QH:
27637        case OPC_REPLV_OB:
27638        case OPC_REPLV_PW:
27639        case OPC_REPLV_QH:
27640            gen_mipsdsp_bitinsn(ctx, op1, op2, rd, rt);
27641            break;
27642        default:            /* Invalid */
27643            MIPS_INVAL("MASK ABSQ_S.QH");
27644            generate_exception_end(ctx, EXCP_RI);
27645            break;
27646        }
27647        break;
27648    case OPC_ADDU_OB_DSP:
27649        op2 = MASK_ADDU_OB(ctx->opcode);
27650        switch (op2) {
27651        case OPC_RADDU_L_OB:
27652        case OPC_SUBQ_PW:
27653        case OPC_SUBQ_S_PW:
27654        case OPC_SUBQ_QH:
27655        case OPC_SUBQ_S_QH:
27656        case OPC_SUBU_OB:
27657        case OPC_SUBU_S_OB:
27658        case OPC_SUBU_QH:
27659        case OPC_SUBU_S_QH:
27660        case OPC_SUBUH_OB:
27661        case OPC_SUBUH_R_OB:
27662        case OPC_ADDQ_PW:
27663        case OPC_ADDQ_S_PW:
27664        case OPC_ADDQ_QH:
27665        case OPC_ADDQ_S_QH:
27666        case OPC_ADDU_OB:
27667        case OPC_ADDU_S_OB:
27668        case OPC_ADDU_QH:
27669        case OPC_ADDU_S_QH:
27670        case OPC_ADDUH_OB:
27671        case OPC_ADDUH_R_OB:
27672            gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
27673            break;
27674        case OPC_MULEQ_S_PW_QHL:
27675        case OPC_MULEQ_S_PW_QHR:
27676        case OPC_MULEU_S_QH_OBL:
27677        case OPC_MULEU_S_QH_OBR:
27678        case OPC_MULQ_RS_QH:
27679            gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 1);
27680            break;
27681        default:            /* Invalid */
27682            MIPS_INVAL("MASK ADDU.OB");
27683            generate_exception_end(ctx, EXCP_RI);
27684            break;
27685        }
27686        break;
27687    case OPC_CMPU_EQ_OB_DSP:
27688        op2 = MASK_CMPU_EQ_OB(ctx->opcode);
27689        switch (op2) {
27690        case OPC_PRECR_SRA_QH_PW:
27691        case OPC_PRECR_SRA_R_QH_PW:
27692            /* Return value is rt. */
27693            gen_mipsdsp_arith(ctx, op1, op2, rt, rs, rd);
27694            break;
27695        case OPC_PRECR_OB_QH:
27696        case OPC_PRECRQ_OB_QH:
27697        case OPC_PRECRQ_PW_L:
27698        case OPC_PRECRQ_QH_PW:
27699        case OPC_PRECRQ_RS_QH_PW:
27700        case OPC_PRECRQU_S_OB_QH:
27701            gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
27702            break;
27703        case OPC_CMPU_EQ_OB:
27704        case OPC_CMPU_LT_OB:
27705        case OPC_CMPU_LE_OB:
27706        case OPC_CMP_EQ_QH:
27707        case OPC_CMP_LT_QH:
27708        case OPC_CMP_LE_QH:
27709        case OPC_CMP_EQ_PW:
27710        case OPC_CMP_LT_PW:
27711        case OPC_CMP_LE_PW:
27712            gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 0);
27713            break;
27714        case OPC_CMPGDU_EQ_OB:
27715        case OPC_CMPGDU_LT_OB:
27716        case OPC_CMPGDU_LE_OB:
27717        case OPC_CMPGU_EQ_OB:
27718        case OPC_CMPGU_LT_OB:
27719        case OPC_CMPGU_LE_OB:
27720        case OPC_PACKRL_PW:
27721        case OPC_PICK_OB:
27722        case OPC_PICK_PW:
27723        case OPC_PICK_QH:
27724            gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 1);
27725            break;
27726        default:            /* Invalid */
27727            MIPS_INVAL("MASK CMPU_EQ.OB");
27728            generate_exception_end(ctx, EXCP_RI);
27729            break;
27730        }
27731        break;
27732    case OPC_DAPPEND_DSP:
27733        gen_mipsdsp_append(env, ctx, op1, rt, rs, rd);
27734        break;
27735    case OPC_DEXTR_W_DSP:
27736        op2 = MASK_DEXTR_W(ctx->opcode);
27737        switch (op2) {
27738        case OPC_DEXTP:
27739        case OPC_DEXTPDP:
27740        case OPC_DEXTPDPV:
27741        case OPC_DEXTPV:
27742        case OPC_DEXTR_L:
27743        case OPC_DEXTR_R_L:
27744        case OPC_DEXTR_RS_L:
27745        case OPC_DEXTR_W:
27746        case OPC_DEXTR_R_W:
27747        case OPC_DEXTR_RS_W:
27748        case OPC_DEXTR_S_H:
27749        case OPC_DEXTRV_L:
27750        case OPC_DEXTRV_R_L:
27751        case OPC_DEXTRV_RS_L:
27752        case OPC_DEXTRV_S_H:
27753        case OPC_DEXTRV_W:
27754        case OPC_DEXTRV_R_W:
27755        case OPC_DEXTRV_RS_W:
27756            gen_mipsdsp_accinsn(ctx, op1, op2, rt, rs, rd, 1);
27757            break;
27758        case OPC_DMTHLIP:
27759        case OPC_DSHILO:
27760        case OPC_DSHILOV:
27761            gen_mipsdsp_accinsn(ctx, op1, op2, rd, rs, rt, 0);
27762            break;
27763        default:            /* Invalid */
27764            MIPS_INVAL("MASK EXTR.W");
27765            generate_exception_end(ctx, EXCP_RI);
27766            break;
27767        }
27768        break;
27769    case OPC_DPAQ_W_QH_DSP:
27770        op2 = MASK_DPAQ_W_QH(ctx->opcode);
27771        switch (op2) {
27772        case OPC_DPAU_H_OBL:
27773        case OPC_DPAU_H_OBR:
27774        case OPC_DPSU_H_OBL:
27775        case OPC_DPSU_H_OBR:
27776        case OPC_DPA_W_QH:
27777        case OPC_DPAQ_S_W_QH:
27778        case OPC_DPS_W_QH:
27779        case OPC_DPSQ_S_W_QH:
27780        case OPC_MULSAQ_S_W_QH:
27781        case OPC_DPAQ_SA_L_PW:
27782        case OPC_DPSQ_SA_L_PW:
27783        case OPC_MULSAQ_S_L_PW:
27784            gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 0);
27785            break;
27786        case OPC_MAQ_S_W_QHLL:
27787        case OPC_MAQ_S_W_QHLR:
27788        case OPC_MAQ_S_W_QHRL:
27789        case OPC_MAQ_S_W_QHRR:
27790        case OPC_MAQ_SA_W_QHLL:
27791        case OPC_MAQ_SA_W_QHLR:
27792        case OPC_MAQ_SA_W_QHRL:
27793        case OPC_MAQ_SA_W_QHRR:
27794        case OPC_MAQ_S_L_PWL:
27795        case OPC_MAQ_S_L_PWR:
27796        case OPC_DMADD:
27797        case OPC_DMADDU:
27798        case OPC_DMSUB:
27799        case OPC_DMSUBU:
27800            gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 0);
27801            break;
27802        default:            /* Invalid */
27803            MIPS_INVAL("MASK DPAQ.W.QH");
27804            generate_exception_end(ctx, EXCP_RI);
27805            break;
27806        }
27807        break;
27808    case OPC_DINSV_DSP:
27809        op2 = MASK_INSV(ctx->opcode);
27810        switch (op2) {
27811        case OPC_DINSV:
27812        {
27813            TCGv t0, t1;
27814
27815            if (rt == 0) {
27816                break;
27817            }
27818            check_dsp(ctx);
27819
27820            t0 = tcg_temp_new();
27821            t1 = tcg_temp_new();
27822
27823            gen_load_gpr(t0, rt);
27824            gen_load_gpr(t1, rs);
27825
27826            gen_helper_dinsv(cpu_gpr[rt], cpu_env, t1, t0);
27827
27828            tcg_temp_free(t0);
27829            tcg_temp_free(t1);
27830            break;
27831        }
27832        default:            /* Invalid */
27833            MIPS_INVAL("MASK DINSV");
27834            generate_exception_end(ctx, EXCP_RI);
27835            break;
27836        }
27837        break;
27838    case OPC_SHLL_OB_DSP:
27839        gen_mipsdsp_shift(ctx, op1, rd, rs, rt);
27840        break;
27841#endif
27842    default:            /* Invalid */
27843        MIPS_INVAL("special3_legacy");
27844        generate_exception_end(ctx, EXCP_RI);
27845        break;
27846    }
27847}
27848
27849
27850#if defined(TARGET_MIPS64)
27851
27852static void decode_mmi0(CPUMIPSState *env, DisasContext *ctx)
27853{
27854    uint32_t opc = MASK_MMI0(ctx->opcode);
27855
27856    switch (opc) {
27857    case MMI_OPC_0_PADDW:     /* TODO: MMI_OPC_0_PADDW */
27858    case MMI_OPC_0_PSUBW:     /* TODO: MMI_OPC_0_PSUBW */
27859    case MMI_OPC_0_PCGTW:     /* TODO: MMI_OPC_0_PCGTW */
27860    case MMI_OPC_0_PMAXW:     /* TODO: MMI_OPC_0_PMAXW */
27861    case MMI_OPC_0_PADDH:     /* TODO: MMI_OPC_0_PADDH */
27862    case MMI_OPC_0_PSUBH:     /* TODO: MMI_OPC_0_PSUBH */
27863    case MMI_OPC_0_PCGTH:     /* TODO: MMI_OPC_0_PCGTH */
27864    case MMI_OPC_0_PMAXH:     /* TODO: MMI_OPC_0_PMAXH */
27865    case MMI_OPC_0_PADDB:     /* TODO: MMI_OPC_0_PADDB */
27866    case MMI_OPC_0_PSUBB:     /* TODO: MMI_OPC_0_PSUBB */
27867    case MMI_OPC_0_PCGTB:     /* TODO: MMI_OPC_0_PCGTB */
27868    case MMI_OPC_0_PADDSW:    /* TODO: MMI_OPC_0_PADDSW */
27869    case MMI_OPC_0_PSUBSW:    /* TODO: MMI_OPC_0_PSUBSW */
27870    case MMI_OPC_0_PEXTLW:    /* TODO: MMI_OPC_0_PEXTLW */
27871    case MMI_OPC_0_PPACW:     /* TODO: MMI_OPC_0_PPACW */
27872    case MMI_OPC_0_PADDSH:    /* TODO: MMI_OPC_0_PADDSH */
27873    case MMI_OPC_0_PSUBSH:    /* TODO: MMI_OPC_0_PSUBSH */
27874    case MMI_OPC_0_PEXTLH:    /* TODO: MMI_OPC_0_PEXTLH */
27875    case MMI_OPC_0_PPACH:     /* TODO: MMI_OPC_0_PPACH */
27876    case MMI_OPC_0_PADDSB:    /* TODO: MMI_OPC_0_PADDSB */
27877    case MMI_OPC_0_PSUBSB:    /* TODO: MMI_OPC_0_PSUBSB */
27878    case MMI_OPC_0_PEXTLB:    /* TODO: MMI_OPC_0_PEXTLB */
27879    case MMI_OPC_0_PPACB:     /* TODO: MMI_OPC_0_PPACB */
27880    case MMI_OPC_0_PEXT5:     /* TODO: MMI_OPC_0_PEXT5 */
27881    case MMI_OPC_0_PPAC5:     /* TODO: MMI_OPC_0_PPAC5 */
27882        generate_exception_end(ctx, EXCP_RI); /* TODO: MMI_OPC_CLASS_MMI0 */
27883        break;
27884    default:
27885        MIPS_INVAL("TX79 MMI class MMI0");
27886        generate_exception_end(ctx, EXCP_RI);
27887        break;
27888    }
27889}
27890
27891static void decode_mmi1(CPUMIPSState *env, DisasContext *ctx)
27892{
27893    uint32_t opc = MASK_MMI1(ctx->opcode);
27894
27895    switch (opc) {
27896    case MMI_OPC_1_PABSW:     /* TODO: MMI_OPC_1_PABSW */
27897    case MMI_OPC_1_PCEQW:     /* TODO: MMI_OPC_1_PCEQW */
27898    case MMI_OPC_1_PMINW:     /* TODO: MMI_OPC_1_PMINW */
27899    case MMI_OPC_1_PADSBH:    /* TODO: MMI_OPC_1_PADSBH */
27900    case MMI_OPC_1_PABSH:     /* TODO: MMI_OPC_1_PABSH */
27901    case MMI_OPC_1_PCEQH:     /* TODO: MMI_OPC_1_PCEQH */
27902    case MMI_OPC_1_PMINH:     /* TODO: MMI_OPC_1_PMINH */
27903    case MMI_OPC_1_PCEQB:     /* TODO: MMI_OPC_1_PCEQB */
27904    case MMI_OPC_1_PADDUW:    /* TODO: MMI_OPC_1_PADDUW */
27905    case MMI_OPC_1_PSUBUW:    /* TODO: MMI_OPC_1_PSUBUW */
27906    case MMI_OPC_1_PEXTUW:    /* TODO: MMI_OPC_1_PEXTUW */
27907    case MMI_OPC_1_PADDUH:    /* TODO: MMI_OPC_1_PADDUH */
27908    case MMI_OPC_1_PSUBUH:    /* TODO: MMI_OPC_1_PSUBUH */
27909    case MMI_OPC_1_PEXTUH:    /* TODO: MMI_OPC_1_PEXTUH */
27910    case MMI_OPC_1_PADDUB:    /* TODO: MMI_OPC_1_PADDUB */
27911    case MMI_OPC_1_PSUBUB:    /* TODO: MMI_OPC_1_PSUBUB */
27912    case MMI_OPC_1_PEXTUB:    /* TODO: MMI_OPC_1_PEXTUB */
27913    case MMI_OPC_1_QFSRV:     /* TODO: MMI_OPC_1_QFSRV */
27914        generate_exception_end(ctx, EXCP_RI); /* TODO: MMI_OPC_CLASS_MMI1 */
27915        break;
27916    default:
27917        MIPS_INVAL("TX79 MMI class MMI1");
27918        generate_exception_end(ctx, EXCP_RI);
27919        break;
27920    }
27921}
27922
27923static void decode_mmi2(CPUMIPSState *env, DisasContext *ctx)
27924{
27925    uint32_t opc = MASK_MMI2(ctx->opcode);
27926
27927    switch (opc) {
27928    case MMI_OPC_2_PMADDW:    /* TODO: MMI_OPC_2_PMADDW */
27929    case MMI_OPC_2_PSLLVW:    /* TODO: MMI_OPC_2_PSLLVW */
27930    case MMI_OPC_2_PSRLVW:    /* TODO: MMI_OPC_2_PSRLVW */
27931    case MMI_OPC_2_PMSUBW:    /* TODO: MMI_OPC_2_PMSUBW */
27932    case MMI_OPC_2_PMFHI:     /* TODO: MMI_OPC_2_PMFHI */
27933    case MMI_OPC_2_PMFLO:     /* TODO: MMI_OPC_2_PMFLO */
27934    case MMI_OPC_2_PINTH:     /* TODO: MMI_OPC_2_PINTH */
27935    case MMI_OPC_2_PMULTW:    /* TODO: MMI_OPC_2_PMULTW */
27936    case MMI_OPC_2_PDIVW:     /* TODO: MMI_OPC_2_PDIVW */
27937    case MMI_OPC_2_PMADDH:    /* TODO: MMI_OPC_2_PMADDH */
27938    case MMI_OPC_2_PHMADH:    /* TODO: MMI_OPC_2_PHMADH */
27939    case MMI_OPC_2_PAND:      /* TODO: MMI_OPC_2_PAND */
27940    case MMI_OPC_2_PXOR:      /* TODO: MMI_OPC_2_PXOR */
27941    case MMI_OPC_2_PMSUBH:    /* TODO: MMI_OPC_2_PMSUBH */
27942    case MMI_OPC_2_PHMSBH:    /* TODO: MMI_OPC_2_PHMSBH */
27943    case MMI_OPC_2_PEXEH:     /* TODO: MMI_OPC_2_PEXEH */
27944    case MMI_OPC_2_PREVH:     /* TODO: MMI_OPC_2_PREVH */
27945    case MMI_OPC_2_PMULTH:    /* TODO: MMI_OPC_2_PMULTH */
27946    case MMI_OPC_2_PDIVBW:    /* TODO: MMI_OPC_2_PDIVBW */
27947    case MMI_OPC_2_PEXEW:     /* TODO: MMI_OPC_2_PEXEW */
27948    case MMI_OPC_2_PROT3W:    /* TODO: MMI_OPC_2_PROT3W */
27949        generate_exception_end(ctx, EXCP_RI); /* TODO: MMI_OPC_CLASS_MMI2 */
27950        break;
27951    case MMI_OPC_2_PCPYLD:
27952        gen_mmi_pcpyld(ctx);
27953        break;
27954    default:
27955        MIPS_INVAL("TX79 MMI class MMI2");
27956        generate_exception_end(ctx, EXCP_RI);
27957        break;
27958    }
27959}
27960
27961static void decode_mmi3(CPUMIPSState *env, DisasContext *ctx)
27962{
27963    uint32_t opc = MASK_MMI3(ctx->opcode);
27964
27965    switch (opc) {
27966    case MMI_OPC_3_PMADDUW:    /* TODO: MMI_OPC_3_PMADDUW */
27967    case MMI_OPC_3_PSRAVW:     /* TODO: MMI_OPC_3_PSRAVW */
27968    case MMI_OPC_3_PMTHI:      /* TODO: MMI_OPC_3_PMTHI */
27969    case MMI_OPC_3_PMTLO:      /* TODO: MMI_OPC_3_PMTLO */
27970    case MMI_OPC_3_PINTEH:     /* TODO: MMI_OPC_3_PINTEH */
27971    case MMI_OPC_3_PMULTUW:    /* TODO: MMI_OPC_3_PMULTUW */
27972    case MMI_OPC_3_PDIVUW:     /* TODO: MMI_OPC_3_PDIVUW */
27973    case MMI_OPC_3_POR:        /* TODO: MMI_OPC_3_POR */
27974    case MMI_OPC_3_PNOR:       /* TODO: MMI_OPC_3_PNOR */
27975    case MMI_OPC_3_PEXCH:      /* TODO: MMI_OPC_3_PEXCH */
27976    case MMI_OPC_3_PEXCW:      /* TODO: MMI_OPC_3_PEXCW */
27977        generate_exception_end(ctx, EXCP_RI); /* TODO: MMI_OPC_CLASS_MMI3 */
27978        break;
27979    case MMI_OPC_3_PCPYH:
27980        gen_mmi_pcpyh(ctx);
27981        break;
27982    case MMI_OPC_3_PCPYUD:
27983        gen_mmi_pcpyud(ctx);
27984        break;
27985    default:
27986        MIPS_INVAL("TX79 MMI class MMI3");
27987        generate_exception_end(ctx, EXCP_RI);
27988        break;
27989    }
27990}
27991
27992static void decode_mmi(CPUMIPSState *env, DisasContext *ctx)
27993{
27994    uint32_t opc = MASK_MMI(ctx->opcode);
27995    int rs = extract32(ctx->opcode, 21, 5);
27996    int rt = extract32(ctx->opcode, 16, 5);
27997    int rd = extract32(ctx->opcode, 11, 5);
27998
27999    switch (opc) {
28000    case MMI_OPC_CLASS_MMI0:
28001        decode_mmi0(env, ctx);
28002        break;
28003    case MMI_OPC_CLASS_MMI1:
28004        decode_mmi1(env, ctx);
28005        break;
28006    case MMI_OPC_CLASS_MMI2:
28007        decode_mmi2(env, ctx);
28008        break;
28009    case MMI_OPC_CLASS_MMI3:
28010        decode_mmi3(env, ctx);
28011        break;
28012    case MMI_OPC_MULT1:
28013    case MMI_OPC_MULTU1:
28014    case MMI_OPC_MADD:
28015    case MMI_OPC_MADDU:
28016    case MMI_OPC_MADD1:
28017    case MMI_OPC_MADDU1:
28018        gen_mul_txx9(ctx, opc, rd, rs, rt);
28019        break;
28020    case MMI_OPC_DIV1:
28021    case MMI_OPC_DIVU1:
28022        gen_div1_tx79(ctx, opc, rs, rt);
28023        break;
28024    case MMI_OPC_MTLO1:
28025    case MMI_OPC_MTHI1:
28026        gen_HILO1_tx79(ctx, opc, rs);
28027        break;
28028    case MMI_OPC_MFLO1:
28029    case MMI_OPC_MFHI1:
28030        gen_HILO1_tx79(ctx, opc, rd);
28031        break;
28032    case MMI_OPC_PLZCW:         /* TODO: MMI_OPC_PLZCW */
28033    case MMI_OPC_PMFHL:         /* TODO: MMI_OPC_PMFHL */
28034    case MMI_OPC_PMTHL:         /* TODO: MMI_OPC_PMTHL */
28035    case MMI_OPC_PSLLH:         /* TODO: MMI_OPC_PSLLH */
28036    case MMI_OPC_PSRLH:         /* TODO: MMI_OPC_PSRLH */
28037    case MMI_OPC_PSRAH:         /* TODO: MMI_OPC_PSRAH */
28038    case MMI_OPC_PSLLW:         /* TODO: MMI_OPC_PSLLW */
28039    case MMI_OPC_PSRLW:         /* TODO: MMI_OPC_PSRLW */
28040    case MMI_OPC_PSRAW:         /* TODO: MMI_OPC_PSRAW */
28041        generate_exception_end(ctx, EXCP_RI);    /* TODO: MMI_OPC_CLASS_MMI */
28042        break;
28043    default:
28044        MIPS_INVAL("TX79 MMI class");
28045        generate_exception_end(ctx, EXCP_RI);
28046        break;
28047    }
28048}
28049
28050static void gen_mmi_lq(CPUMIPSState *env, DisasContext *ctx)
28051{
28052    generate_exception_end(ctx, EXCP_RI);    /* TODO: MMI_OPC_LQ */
28053}
28054
28055static void gen_mmi_sq(DisasContext *ctx, int base, int rt, int offset)
28056{
28057    generate_exception_end(ctx, EXCP_RI);    /* TODO: MMI_OPC_SQ */
28058}
28059
28060/*
28061 * The TX79-specific instruction Store Quadword
28062 *
28063 * +--------+-------+-------+------------------------+
28064 * | 011111 |  base |   rt  |           offset       | SQ
28065 * +--------+-------+-------+------------------------+
28066 *      6       5       5                 16
28067 *
28068 * has the same opcode as the Read Hardware Register instruction
28069 *
28070 * +--------+-------+-------+-------+-------+--------+
28071 * | 011111 | 00000 |   rt  |   rd  | 00000 | 111011 | RDHWR
28072 * +--------+-------+-------+-------+-------+--------+
28073 *      6       5       5       5       5        6
28074 *
28075 * that is required, trapped and emulated by the Linux kernel. However, all
28076 * RDHWR encodings yield address error exceptions on the TX79 since the SQ
28077 * offset is odd. Therefore all valid SQ instructions can execute normally.
28078 * In user mode, QEMU must verify the upper and lower 11 bits to distinguish
28079 * between SQ and RDHWR, as the Linux kernel does.
28080 */
28081static void decode_mmi_sq(CPUMIPSState *env, DisasContext *ctx)
28082{
28083    int base = extract32(ctx->opcode, 21, 5);
28084    int rt = extract32(ctx->opcode, 16, 5);
28085    int offset = extract32(ctx->opcode, 0, 16);
28086
28087#ifdef CONFIG_USER_ONLY
28088    uint32_t op1 = MASK_SPECIAL3(ctx->opcode);
28089    uint32_t op2 = extract32(ctx->opcode, 6, 5);
28090
28091    if (base == 0 && op2 == 0 && op1 == OPC_RDHWR) {
28092        int rd = extract32(ctx->opcode, 11, 5);
28093
28094        gen_rdhwr(ctx, rt, rd, 0);
28095        return;
28096    }
28097#endif
28098
28099    gen_mmi_sq(ctx, base, rt, offset);
28100}
28101
28102#endif
28103
28104static void decode_opc_special3(CPUMIPSState *env, DisasContext *ctx)
28105{
28106    int rs, rt, rd, sa;
28107    uint32_t op1, op2;
28108    int16_t imm;
28109
28110    rs = (ctx->opcode >> 21) & 0x1f;
28111    rt = (ctx->opcode >> 16) & 0x1f;
28112    rd = (ctx->opcode >> 11) & 0x1f;
28113    sa = (ctx->opcode >> 6) & 0x1f;
28114    imm = sextract32(ctx->opcode, 7, 9);
28115
28116    op1 = MASK_SPECIAL3(ctx->opcode);
28117
28118    /*
28119     * EVA loads and stores overlap Loongson 2E instructions decoded by
28120     * decode_opc_special3_legacy(), so be careful to allow their decoding when
28121     * EVA is absent.
28122     */
28123    if (ctx->eva) {
28124        switch (op1) {
28125        case OPC_LWLE:
28126        case OPC_LWRE:
28127            check_insn_opc_removed(ctx, ISA_MIPS32R6);
28128            /* fall through */
28129        case OPC_LBUE:
28130        case OPC_LHUE:
28131        case OPC_LBE:
28132        case OPC_LHE:
28133        case OPC_LLE:
28134        case OPC_LWE:
28135            check_cp0_enabled(ctx);
28136            gen_ld(ctx, op1, rt, rs, imm);
28137            return;
28138        case OPC_SWLE:
28139        case OPC_SWRE:
28140            check_insn_opc_removed(ctx, ISA_MIPS32R6);
28141            /* fall through */
28142        case OPC_SBE:
28143        case OPC_SHE:
28144        case OPC_SWE:
28145            check_cp0_enabled(ctx);
28146            gen_st(ctx, op1, rt, rs, imm);
28147            return;
28148        case OPC_SCE:
28149            check_cp0_enabled(ctx);
28150            gen_st_cond(ctx, rt, rs, imm, MO_TESL, true);
28151            return;
28152        case OPC_CACHEE:
28153            check_cp0_enabled(ctx);
28154            if (ctx->hflags & MIPS_HFLAG_ITC_CACHE) {
28155                gen_cache_operation(ctx, rt, rs, imm);
28156            }
28157            /* Treat as NOP. */
28158            return;
28159        case OPC_PREFE:
28160            check_cp0_enabled(ctx);
28161            /* Treat as NOP. */
28162            return;
28163        }
28164    }
28165
28166    switch (op1) {
28167    case OPC_EXT:
28168    case OPC_INS:
28169        check_insn(ctx, ISA_MIPS32R2);
28170        gen_bitops(ctx, op1, rt, rs, sa, rd);
28171        break;
28172    case OPC_BSHFL:
28173        op2 = MASK_BSHFL(ctx->opcode);
28174        switch (op2) {
28175        case OPC_ALIGN:
28176        case OPC_ALIGN_1:
28177        case OPC_ALIGN_2:
28178        case OPC_ALIGN_3:
28179        case OPC_BITSWAP:
28180            check_insn(ctx, ISA_MIPS32R6);
28181            decode_opc_special3_r6(env, ctx);
28182            break;
28183        default:
28184            check_insn(ctx, ISA_MIPS32R2);
28185            gen_bshfl(ctx, op2, rt, rd);
28186            break;
28187        }
28188        break;
28189#if defined(TARGET_MIPS64)
28190    case OPC_DEXTM:
28191    case OPC_DEXTU:
28192    case OPC_DEXT:
28193    case OPC_DINSM:
28194    case OPC_DINSU:
28195    case OPC_DINS:
28196        check_insn(ctx, ISA_MIPS64R2);
28197        check_mips_64(ctx);
28198        gen_bitops(ctx, op1, rt, rs, sa, rd);
28199        break;
28200    case OPC_DBSHFL:
28201        op2 = MASK_DBSHFL(ctx->opcode);
28202        switch (op2) {
28203        case OPC_DALIGN:
28204        case OPC_DALIGN_1:
28205        case OPC_DALIGN_2:
28206        case OPC_DALIGN_3:
28207        case OPC_DALIGN_4:
28208        case OPC_DALIGN_5:
28209        case OPC_DALIGN_6:
28210        case OPC_DALIGN_7:
28211        case OPC_DBITSWAP:
28212            check_insn(ctx, ISA_MIPS32R6);
28213            decode_opc_special3_r6(env, ctx);
28214            break;
28215        default:
28216            check_insn(ctx, ISA_MIPS64R2);
28217            check_mips_64(ctx);
28218            op2 = MASK_DBSHFL(ctx->opcode);
28219            gen_bshfl(ctx, op2, rt, rd);
28220            break;
28221        }
28222        break;
28223#endif
28224    case OPC_RDHWR:
28225        gen_rdhwr(ctx, rt, rd, extract32(ctx->opcode, 6, 3));
28226        break;
28227    case OPC_FORK:
28228        check_mt(ctx);
28229        {
28230            TCGv t0 = tcg_temp_new();
28231            TCGv t1 = tcg_temp_new();
28232
28233            gen_load_gpr(t0, rt);
28234            gen_load_gpr(t1, rs);
28235            gen_helper_fork(t0, t1);
28236            tcg_temp_free(t0);
28237            tcg_temp_free(t1);
28238        }
28239        break;
28240    case OPC_YIELD:
28241        check_mt(ctx);
28242        {
28243            TCGv t0 = tcg_temp_new();
28244
28245            gen_load_gpr(t0, rs);
28246            gen_helper_yield(t0, cpu_env, t0);
28247            gen_store_gpr(t0, rd);
28248            tcg_temp_free(t0);
28249        }
28250        break;
28251    default:
28252        if (ctx->insn_flags & ISA_MIPS32R6) {
28253            decode_opc_special3_r6(env, ctx);
28254        } else {
28255            decode_opc_special3_legacy(env, ctx);
28256        }
28257    }
28258}
28259
28260/* MIPS SIMD Architecture (MSA)  */
28261static inline int check_msa_access(DisasContext *ctx)
28262{
28263    if (unlikely((ctx->hflags & MIPS_HFLAG_FPU) &&
28264                 !(ctx->hflags & MIPS_HFLAG_F64))) {
28265        generate_exception_end(ctx, EXCP_RI);
28266        return 0;
28267    }
28268
28269    if (unlikely(!(ctx->hflags & MIPS_HFLAG_MSA))) {
28270        if (ctx->insn_flags & ASE_MSA) {
28271            generate_exception_end(ctx, EXCP_MSADIS);
28272            return 0;
28273        } else {
28274            generate_exception_end(ctx, EXCP_RI);
28275            return 0;
28276        }
28277    }
28278    return 1;
28279}
28280
28281static void gen_check_zero_element(TCGv tresult, uint8_t df, uint8_t wt)
28282{
28283    /* generates tcg ops to check if any element is 0 */
28284    /* Note this function only works with MSA_WRLEN = 128 */
28285    uint64_t eval_zero_or_big = 0;
28286    uint64_t eval_big = 0;
28287    TCGv_i64 t0 = tcg_temp_new_i64();
28288    TCGv_i64 t1 = tcg_temp_new_i64();
28289    switch (df) {
28290    case DF_BYTE:
28291        eval_zero_or_big = 0x0101010101010101ULL;
28292        eval_big = 0x8080808080808080ULL;
28293        break;
28294    case DF_HALF:
28295        eval_zero_or_big = 0x0001000100010001ULL;
28296        eval_big = 0x8000800080008000ULL;
28297        break;
28298    case DF_WORD:
28299        eval_zero_or_big = 0x0000000100000001ULL;
28300        eval_big = 0x8000000080000000ULL;
28301        break;
28302    case DF_DOUBLE:
28303        eval_zero_or_big = 0x0000000000000001ULL;
28304        eval_big = 0x8000000000000000ULL;
28305        break;
28306    }
28307    tcg_gen_subi_i64(t0, msa_wr_d[wt << 1], eval_zero_or_big);
28308    tcg_gen_andc_i64(t0, t0, msa_wr_d[wt << 1]);
28309    tcg_gen_andi_i64(t0, t0, eval_big);
28310    tcg_gen_subi_i64(t1, msa_wr_d[(wt << 1) + 1], eval_zero_or_big);
28311    tcg_gen_andc_i64(t1, t1, msa_wr_d[(wt << 1) + 1]);
28312    tcg_gen_andi_i64(t1, t1, eval_big);
28313    tcg_gen_or_i64(t0, t0, t1);
28314    /* if all bits are zero then all elements are not zero */
28315    /* if some bit is non-zero then some element is zero */
28316    tcg_gen_setcondi_i64(TCG_COND_NE, t0, t0, 0);
28317    tcg_gen_trunc_i64_tl(tresult, t0);
28318    tcg_temp_free_i64(t0);
28319    tcg_temp_free_i64(t1);
28320}
28321
28322static void gen_msa_branch(CPUMIPSState *env, DisasContext *ctx, uint32_t op1)
28323{
28324    uint8_t df = (ctx->opcode >> 21) & 0x3;
28325    uint8_t wt = (ctx->opcode >> 16) & 0x1f;
28326    int64_t s16 = (int16_t)ctx->opcode;
28327
28328    check_msa_access(ctx);
28329
28330    if (ctx->hflags & MIPS_HFLAG_BMASK) {
28331        generate_exception_end(ctx, EXCP_RI);
28332        return;
28333    }
28334    switch (op1) {
28335    case OPC_BZ_V:
28336    case OPC_BNZ_V:
28337        {
28338            TCGv_i64 t0 = tcg_temp_new_i64();
28339            tcg_gen_or_i64(t0, msa_wr_d[wt << 1], msa_wr_d[(wt << 1) + 1]);
28340            tcg_gen_setcondi_i64((op1 == OPC_BZ_V) ?
28341                    TCG_COND_EQ : TCG_COND_NE, t0, t0, 0);
28342            tcg_gen_trunc_i64_tl(bcond, t0);
28343            tcg_temp_free_i64(t0);
28344        }
28345        break;
28346    case OPC_BZ_B:
28347    case OPC_BZ_H:
28348    case OPC_BZ_W:
28349    case OPC_BZ_D:
28350        gen_check_zero_element(bcond, df, wt);
28351        break;
28352    case OPC_BNZ_B:
28353    case OPC_BNZ_H:
28354    case OPC_BNZ_W:
28355    case OPC_BNZ_D:
28356        gen_check_zero_element(bcond, df, wt);
28357        tcg_gen_setcondi_tl(TCG_COND_EQ, bcond, bcond, 0);
28358        break;
28359    }
28360
28361    ctx->btarget = ctx->base.pc_next + (s16 << 2) + 4;
28362
28363    ctx->hflags |= MIPS_HFLAG_BC;
28364    ctx->hflags |= MIPS_HFLAG_BDS32;
28365}
28366
28367static void gen_msa_i8(CPUMIPSState *env, DisasContext *ctx)
28368{
28369#define MASK_MSA_I8(op)    (MASK_MSA_MINOR(op) | (op & (0x03 << 24)))
28370    uint8_t i8 = (ctx->opcode >> 16) & 0xff;
28371    uint8_t ws = (ctx->opcode >> 11) & 0x1f;
28372    uint8_t wd = (ctx->opcode >> 6) & 0x1f;
28373
28374    TCGv_i32 twd = tcg_const_i32(wd);
28375    TCGv_i32 tws = tcg_const_i32(ws);
28376    TCGv_i32 ti8 = tcg_const_i32(i8);
28377
28378    switch (MASK_MSA_I8(ctx->opcode)) {
28379    case OPC_ANDI_B:
28380        gen_helper_msa_andi_b(cpu_env, twd, tws, ti8);
28381        break;
28382    case OPC_ORI_B:
28383        gen_helper_msa_ori_b(cpu_env, twd, tws, ti8);
28384        break;
28385    case OPC_NORI_B:
28386        gen_helper_msa_nori_b(cpu_env, twd, tws, ti8);
28387        break;
28388    case OPC_XORI_B:
28389        gen_helper_msa_xori_b(cpu_env, twd, tws, ti8);
28390        break;
28391    case OPC_BMNZI_B:
28392        gen_helper_msa_bmnzi_b(cpu_env, twd, tws, ti8);
28393        break;
28394    case OPC_BMZI_B:
28395        gen_helper_msa_bmzi_b(cpu_env, twd, tws, ti8);
28396        break;
28397    case OPC_BSELI_B:
28398        gen_helper_msa_bseli_b(cpu_env, twd, tws, ti8);
28399        break;
28400    case OPC_SHF_B:
28401    case OPC_SHF_H:
28402    case OPC_SHF_W:
28403        {
28404            uint8_t df = (ctx->opcode >> 24) & 0x3;
28405            if (df == DF_DOUBLE) {
28406                generate_exception_end(ctx, EXCP_RI);
28407            } else {
28408                TCGv_i32 tdf = tcg_const_i32(df);
28409                gen_helper_msa_shf_df(cpu_env, tdf, twd, tws, ti8);
28410                tcg_temp_free_i32(tdf);
28411            }
28412        }
28413        break;
28414    default:
28415        MIPS_INVAL("MSA instruction");
28416        generate_exception_end(ctx, EXCP_RI);
28417        break;
28418    }
28419
28420    tcg_temp_free_i32(twd);
28421    tcg_temp_free_i32(tws);
28422    tcg_temp_free_i32(ti8);
28423}
28424
28425static void gen_msa_i5(CPUMIPSState *env, DisasContext *ctx)
28426{
28427#define MASK_MSA_I5(op)    (MASK_MSA_MINOR(op) | (op & (0x7 << 23)))
28428    uint8_t df = (ctx->opcode >> 21) & 0x3;
28429    int8_t s5 = (int8_t) sextract32(ctx->opcode, 16, 5);
28430    uint8_t u5 = (ctx->opcode >> 16) & 0x1f;
28431    uint8_t ws = (ctx->opcode >> 11) & 0x1f;
28432    uint8_t wd = (ctx->opcode >> 6) & 0x1f;
28433
28434    TCGv_i32 tdf = tcg_const_i32(df);
28435    TCGv_i32 twd = tcg_const_i32(wd);
28436    TCGv_i32 tws = tcg_const_i32(ws);
28437    TCGv_i32 timm = tcg_temp_new_i32();
28438    tcg_gen_movi_i32(timm, u5);
28439
28440    switch (MASK_MSA_I5(ctx->opcode)) {
28441    case OPC_ADDVI_df:
28442        gen_helper_msa_addvi_df(cpu_env, tdf, twd, tws, timm);
28443        break;
28444    case OPC_SUBVI_df:
28445        gen_helper_msa_subvi_df(cpu_env, tdf, twd, tws, timm);
28446        break;
28447    case OPC_MAXI_S_df:
28448        tcg_gen_movi_i32(timm, s5);
28449        gen_helper_msa_maxi_s_df(cpu_env, tdf, twd, tws, timm);
28450        break;
28451    case OPC_MAXI_U_df:
28452        gen_helper_msa_maxi_u_df(cpu_env, tdf, twd, tws, timm);
28453        break;
28454    case OPC_MINI_S_df:
28455        tcg_gen_movi_i32(timm, s5);
28456        gen_helper_msa_mini_s_df(cpu_env, tdf, twd, tws, timm);
28457        break;
28458    case OPC_MINI_U_df:
28459        gen_helper_msa_mini_u_df(cpu_env, tdf, twd, tws, timm);
28460        break;
28461    case OPC_CEQI_df:
28462        tcg_gen_movi_i32(timm, s5);
28463        gen_helper_msa_ceqi_df(cpu_env, tdf, twd, tws, timm);
28464        break;
28465    case OPC_CLTI_S_df:
28466        tcg_gen_movi_i32(timm, s5);
28467        gen_helper_msa_clti_s_df(cpu_env, tdf, twd, tws, timm);
28468        break;
28469    case OPC_CLTI_U_df:
28470        gen_helper_msa_clti_u_df(cpu_env, tdf, twd, tws, timm);
28471        break;
28472    case OPC_CLEI_S_df:
28473        tcg_gen_movi_i32(timm, s5);
28474        gen_helper_msa_clei_s_df(cpu_env, tdf, twd, tws, timm);
28475        break;
28476    case OPC_CLEI_U_df:
28477        gen_helper_msa_clei_u_df(cpu_env, tdf, twd, tws, timm);
28478        break;
28479    case OPC_LDI_df:
28480        {
28481            int32_t s10 = sextract32(ctx->opcode, 11, 10);
28482            tcg_gen_movi_i32(timm, s10);
28483            gen_helper_msa_ldi_df(cpu_env, tdf, twd, timm);
28484        }
28485        break;
28486    default:
28487        MIPS_INVAL("MSA instruction");
28488        generate_exception_end(ctx, EXCP_RI);
28489        break;
28490    }
28491
28492    tcg_temp_free_i32(tdf);
28493    tcg_temp_free_i32(twd);
28494    tcg_temp_free_i32(tws);
28495    tcg_temp_free_i32(timm);
28496}
28497
28498static void gen_msa_bit(CPUMIPSState *env, DisasContext *ctx)
28499{
28500#define MASK_MSA_BIT(op)    (MASK_MSA_MINOR(op) | (op & (0x7 << 23)))
28501    uint8_t dfm = (ctx->opcode >> 16) & 0x7f;
28502    uint32_t df = 0, m = 0;
28503    uint8_t ws = (ctx->opcode >> 11) & 0x1f;
28504    uint8_t wd = (ctx->opcode >> 6) & 0x1f;
28505
28506    TCGv_i32 tdf;
28507    TCGv_i32 tm;
28508    TCGv_i32 twd;
28509    TCGv_i32 tws;
28510
28511    if ((dfm & 0x40) == 0x00) {
28512        m = dfm & 0x3f;
28513        df = DF_DOUBLE;
28514    } else if ((dfm & 0x60) == 0x40) {
28515        m = dfm & 0x1f;
28516        df = DF_WORD;
28517    } else if ((dfm & 0x70) == 0x60) {
28518        m = dfm & 0x0f;
28519        df = DF_HALF;
28520    } else if ((dfm & 0x78) == 0x70) {
28521        m = dfm & 0x7;
28522        df = DF_BYTE;
28523    } else {
28524        generate_exception_end(ctx, EXCP_RI);
28525        return;
28526    }
28527
28528    tdf = tcg_const_i32(df);
28529    tm  = tcg_const_i32(m);
28530    twd = tcg_const_i32(wd);
28531    tws = tcg_const_i32(ws);
28532
28533    switch (MASK_MSA_BIT(ctx->opcode)) {
28534    case OPC_SLLI_df:
28535        gen_helper_msa_slli_df(cpu_env, tdf, twd, tws, tm);
28536        break;
28537    case OPC_SRAI_df:
28538        gen_helper_msa_srai_df(cpu_env, tdf, twd, tws, tm);
28539        break;
28540    case OPC_SRLI_df:
28541        gen_helper_msa_srli_df(cpu_env, tdf, twd, tws, tm);
28542        break;
28543    case OPC_BCLRI_df:
28544        gen_helper_msa_bclri_df(cpu_env, tdf, twd, tws, tm);
28545        break;
28546    case OPC_BSETI_df:
28547        gen_helper_msa_bseti_df(cpu_env, tdf, twd, tws, tm);
28548        break;
28549    case OPC_BNEGI_df:
28550        gen_helper_msa_bnegi_df(cpu_env, tdf, twd, tws, tm);
28551        break;
28552    case OPC_BINSLI_df:
28553        gen_helper_msa_binsli_df(cpu_env, tdf, twd, tws, tm);
28554        break;
28555    case OPC_BINSRI_df:
28556        gen_helper_msa_binsri_df(cpu_env, tdf, twd, tws, tm);
28557        break;
28558    case OPC_SAT_S_df:
28559        gen_helper_msa_sat_s_df(cpu_env, tdf, twd, tws, tm);
28560        break;
28561    case OPC_SAT_U_df:
28562        gen_helper_msa_sat_u_df(cpu_env, tdf, twd, tws, tm);
28563        break;
28564    case OPC_SRARI_df:
28565        gen_helper_msa_srari_df(cpu_env, tdf, twd, tws, tm);
28566        break;
28567    case OPC_SRLRI_df:
28568        gen_helper_msa_srlri_df(cpu_env, tdf, twd, tws, tm);
28569        break;
28570    default:
28571        MIPS_INVAL("MSA instruction");
28572        generate_exception_end(ctx, EXCP_RI);
28573        break;
28574    }
28575
28576    tcg_temp_free_i32(tdf);
28577    tcg_temp_free_i32(tm);
28578    tcg_temp_free_i32(twd);
28579    tcg_temp_free_i32(tws);
28580}
28581
28582static void gen_msa_3r(CPUMIPSState *env, DisasContext *ctx)
28583{
28584#define MASK_MSA_3R(op)    (MASK_MSA_MINOR(op) | (op & (0x7 << 23)))
28585    uint8_t df = (ctx->opcode >> 21) & 0x3;
28586    uint8_t wt = (ctx->opcode >> 16) & 0x1f;
28587    uint8_t ws = (ctx->opcode >> 11) & 0x1f;
28588    uint8_t wd = (ctx->opcode >> 6) & 0x1f;
28589
28590    TCGv_i32 tdf = tcg_const_i32(df);
28591    TCGv_i32 twd = tcg_const_i32(wd);
28592    TCGv_i32 tws = tcg_const_i32(ws);
28593    TCGv_i32 twt = tcg_const_i32(wt);
28594
28595    switch (MASK_MSA_3R(ctx->opcode)) {
28596    case OPC_BINSL_df:
28597        switch (df) {
28598        case DF_BYTE:
28599            gen_helper_msa_binsl_b(cpu_env, twd, tws, twt);
28600            break;
28601        case DF_HALF:
28602            gen_helper_msa_binsl_h(cpu_env, twd, tws, twt);
28603            break;
28604        case DF_WORD:
28605            gen_helper_msa_binsl_w(cpu_env, twd, tws, twt);
28606            break;
28607        case DF_DOUBLE:
28608            gen_helper_msa_binsl_d(cpu_env, twd, tws, twt);
28609            break;
28610        }
28611        break;
28612    case OPC_BINSR_df:
28613        switch (df) {
28614        case DF_BYTE:
28615            gen_helper_msa_binsr_b(cpu_env, twd, tws, twt);
28616            break;
28617        case DF_HALF:
28618            gen_helper_msa_binsr_h(cpu_env, twd, tws, twt);
28619            break;
28620        case DF_WORD:
28621            gen_helper_msa_binsr_w(cpu_env, twd, tws, twt);
28622            break;
28623        case DF_DOUBLE:
28624            gen_helper_msa_binsr_d(cpu_env, twd, tws, twt);
28625            break;
28626        }
28627        break;
28628    case OPC_BCLR_df:
28629        switch (df) {
28630        case DF_BYTE:
28631            gen_helper_msa_bclr_b(cpu_env, twd, tws, twt);
28632            break;
28633        case DF_HALF:
28634            gen_helper_msa_bclr_h(cpu_env, twd, tws, twt);
28635            break;
28636        case DF_WORD:
28637            gen_helper_msa_bclr_w(cpu_env, twd, tws, twt);
28638            break;
28639        case DF_DOUBLE:
28640            gen_helper_msa_bclr_d(cpu_env, twd, tws, twt);
28641            break;
28642        }
28643        break;
28644    case OPC_BNEG_df:
28645        switch (df) {
28646        case DF_BYTE:
28647            gen_helper_msa_bneg_b(cpu_env, twd, tws, twt);
28648            break;
28649        case DF_HALF:
28650            gen_helper_msa_bneg_h(cpu_env, twd, tws, twt);
28651            break;
28652        case DF_WORD:
28653            gen_helper_msa_bneg_w(cpu_env, twd, tws, twt);
28654            break;
28655        case DF_DOUBLE:
28656            gen_helper_msa_bneg_d(cpu_env, twd, tws, twt);
28657            break;
28658        }
28659        break;
28660    case OPC_BSET_df:
28661        switch (df) {
28662        case DF_BYTE:
28663            gen_helper_msa_bset_b(cpu_env, twd, tws, twt);
28664            break;
28665        case DF_HALF:
28666            gen_helper_msa_bset_h(cpu_env, twd, tws, twt);
28667            break;
28668        case DF_WORD:
28669            gen_helper_msa_bset_w(cpu_env, twd, tws, twt);
28670            break;
28671        case DF_DOUBLE:
28672            gen_helper_msa_bset_d(cpu_env, twd, tws, twt);
28673            break;
28674        }
28675        break;
28676    case OPC_ADD_A_df:
28677        switch (df) {
28678        case DF_BYTE:
28679            gen_helper_msa_add_a_b(cpu_env, twd, tws, twt);
28680            break;
28681        case DF_HALF:
28682            gen_helper_msa_add_a_h(cpu_env, twd, tws, twt);
28683            break;
28684        case DF_WORD:
28685            gen_helper_msa_add_a_w(cpu_env, twd, tws, twt);
28686            break;
28687        case DF_DOUBLE:
28688            gen_helper_msa_add_a_d(cpu_env, twd, tws, twt);
28689            break;
28690        }
28691        break;
28692    case OPC_ADDS_A_df:
28693        switch (df) {
28694        case DF_BYTE:
28695            gen_helper_msa_adds_a_b(cpu_env, twd, tws, twt);
28696            break;
28697        case DF_HALF:
28698            gen_helper_msa_adds_a_h(cpu_env, twd, tws, twt);
28699            break;
28700        case DF_WORD:
28701            gen_helper_msa_adds_a_w(cpu_env, twd, tws, twt);
28702            break;
28703        case DF_DOUBLE:
28704            gen_helper_msa_adds_a_d(cpu_env, twd, tws, twt);
28705            break;
28706        }
28707        break;
28708    case OPC_ADDS_S_df:
28709        switch (df) {
28710        case DF_BYTE:
28711            gen_helper_msa_adds_s_b(cpu_env, twd, tws, twt);
28712            break;
28713        case DF_HALF:
28714            gen_helper_msa_adds_s_h(cpu_env, twd, tws, twt);
28715            break;
28716        case DF_WORD:
28717            gen_helper_msa_adds_s_w(cpu_env, twd, tws, twt);
28718            break;
28719        case DF_DOUBLE:
28720            gen_helper_msa_adds_s_d(cpu_env, twd, tws, twt);
28721            break;
28722        }
28723        break;
28724    case OPC_ADDS_U_df:
28725        switch (df) {
28726        case DF_BYTE:
28727            gen_helper_msa_adds_u_b(cpu_env, twd, tws, twt);
28728            break;
28729        case DF_HALF:
28730            gen_helper_msa_adds_u_h(cpu_env, twd, tws, twt);
28731            break;
28732        case DF_WORD:
28733            gen_helper_msa_adds_u_w(cpu_env, twd, tws, twt);
28734            break;
28735        case DF_DOUBLE:
28736            gen_helper_msa_adds_u_d(cpu_env, twd, tws, twt);
28737            break;
28738        }
28739        break;
28740    case OPC_ADDV_df:
28741        switch (df) {
28742        case DF_BYTE:
28743            gen_helper_msa_addv_b(cpu_env, twd, tws, twt);
28744            break;
28745        case DF_HALF:
28746            gen_helper_msa_addv_h(cpu_env, twd, tws, twt);
28747            break;
28748        case DF_WORD:
28749            gen_helper_msa_addv_w(cpu_env, twd, tws, twt);
28750            break;
28751        case DF_DOUBLE:
28752            gen_helper_msa_addv_d(cpu_env, twd, tws, twt);
28753            break;
28754        }
28755        break;
28756    case OPC_AVE_S_df:
28757        switch (df) {
28758        case DF_BYTE:
28759            gen_helper_msa_ave_s_b(cpu_env, twd, tws, twt);
28760            break;
28761        case DF_HALF:
28762            gen_helper_msa_ave_s_h(cpu_env, twd, tws, twt);
28763            break;
28764        case DF_WORD:
28765            gen_helper_msa_ave_s_w(cpu_env, twd, tws, twt);
28766            break;
28767        case DF_DOUBLE:
28768            gen_helper_msa_ave_s_d(cpu_env, twd, tws, twt);
28769            break;
28770        }
28771        break;
28772    case OPC_AVE_U_df:
28773        switch (df) {
28774        case DF_BYTE:
28775            gen_helper_msa_ave_u_b(cpu_env, twd, tws, twt);
28776            break;
28777        case DF_HALF:
28778            gen_helper_msa_ave_u_h(cpu_env, twd, tws, twt);
28779            break;
28780        case DF_WORD:
28781            gen_helper_msa_ave_u_w(cpu_env, twd, tws, twt);
28782            break;
28783        case DF_DOUBLE:
28784            gen_helper_msa_ave_u_d(cpu_env, twd, tws, twt);
28785            break;
28786        }
28787        break;
28788    case OPC_AVER_S_df:
28789        switch (df) {
28790        case DF_BYTE:
28791            gen_helper_msa_aver_s_b(cpu_env, twd, tws, twt);
28792            break;
28793        case DF_HALF:
28794            gen_helper_msa_aver_s_h(cpu_env, twd, tws, twt);
28795            break;
28796        case DF_WORD:
28797            gen_helper_msa_aver_s_w(cpu_env, twd, tws, twt);
28798            break;
28799        case DF_DOUBLE:
28800            gen_helper_msa_aver_s_d(cpu_env, twd, tws, twt);
28801            break;
28802        }
28803        break;
28804    case OPC_AVER_U_df:
28805        switch (df) {
28806        case DF_BYTE:
28807            gen_helper_msa_aver_u_b(cpu_env, twd, tws, twt);
28808            break;
28809        case DF_HALF:
28810            gen_helper_msa_aver_u_h(cpu_env, twd, tws, twt);
28811            break;
28812        case DF_WORD:
28813            gen_helper_msa_aver_u_w(cpu_env, twd, tws, twt);
28814            break;
28815        case DF_DOUBLE:
28816            gen_helper_msa_aver_u_d(cpu_env, twd, tws, twt);
28817            break;
28818        }
28819        break;
28820    case OPC_CEQ_df:
28821        switch (df) {
28822        case DF_BYTE:
28823            gen_helper_msa_ceq_b(cpu_env, twd, tws, twt);
28824            break;
28825        case DF_HALF:
28826            gen_helper_msa_ceq_h(cpu_env, twd, tws, twt);
28827            break;
28828        case DF_WORD:
28829            gen_helper_msa_ceq_w(cpu_env, twd, tws, twt);
28830            break;
28831        case DF_DOUBLE:
28832            gen_helper_msa_ceq_d(cpu_env, twd, tws, twt);
28833            break;
28834        }
28835        break;
28836    case OPC_CLE_S_df:
28837        switch (df) {
28838        case DF_BYTE:
28839            gen_helper_msa_cle_s_b(cpu_env, twd, tws, twt);
28840            break;
28841        case DF_HALF:
28842            gen_helper_msa_cle_s_h(cpu_env, twd, tws, twt);
28843            break;
28844        case DF_WORD:
28845            gen_helper_msa_cle_s_w(cpu_env, twd, tws, twt);
28846            break;
28847        case DF_DOUBLE:
28848            gen_helper_msa_cle_s_d(cpu_env, twd, tws, twt);
28849            break;
28850        }
28851        break;
28852    case OPC_CLE_U_df:
28853        switch (df) {
28854        case DF_BYTE:
28855            gen_helper_msa_cle_u_b(cpu_env, twd, tws, twt);
28856            break;
28857        case DF_HALF:
28858            gen_helper_msa_cle_u_h(cpu_env, twd, tws, twt);
28859            break;
28860        case DF_WORD:
28861            gen_helper_msa_cle_u_w(cpu_env, twd, tws, twt);
28862            break;
28863        case DF_DOUBLE:
28864            gen_helper_msa_cle_u_d(cpu_env, twd, tws, twt);
28865            break;
28866        }
28867        break;
28868    case OPC_CLT_S_df:
28869        switch (df) {
28870        case DF_BYTE:
28871            gen_helper_msa_clt_s_b(cpu_env, twd, tws, twt);
28872            break;
28873        case DF_HALF:
28874            gen_helper_msa_clt_s_h(cpu_env, twd, tws, twt);
28875            break;
28876        case DF_WORD:
28877            gen_helper_msa_clt_s_w(cpu_env, twd, tws, twt);
28878            break;
28879        case DF_DOUBLE:
28880            gen_helper_msa_clt_s_d(cpu_env, twd, tws, twt);
28881            break;
28882        }
28883        break;
28884    case OPC_CLT_U_df:
28885        switch (df) {
28886        case DF_BYTE:
28887            gen_helper_msa_clt_u_b(cpu_env, twd, tws, twt);
28888            break;
28889        case DF_HALF:
28890            gen_helper_msa_clt_u_h(cpu_env, twd, tws, twt);
28891            break;
28892        case DF_WORD:
28893            gen_helper_msa_clt_u_w(cpu_env, twd, tws, twt);
28894            break;
28895        case DF_DOUBLE:
28896            gen_helper_msa_clt_u_d(cpu_env, twd, tws, twt);
28897            break;
28898        }
28899        break;
28900    case OPC_DIV_S_df:
28901        switch (df) {
28902        case DF_BYTE:
28903            gen_helper_msa_div_s_b(cpu_env, twd, tws, twt);
28904            break;
28905        case DF_HALF:
28906            gen_helper_msa_div_s_h(cpu_env, twd, tws, twt);
28907            break;
28908        case DF_WORD:
28909            gen_helper_msa_div_s_w(cpu_env, twd, tws, twt);
28910            break;
28911        case DF_DOUBLE:
28912            gen_helper_msa_div_s_d(cpu_env, twd, tws, twt);
28913            break;
28914        }
28915        break;
28916    case OPC_DIV_U_df:
28917        switch (df) {
28918        case DF_BYTE:
28919            gen_helper_msa_div_u_b(cpu_env, twd, tws, twt);
28920            break;
28921        case DF_HALF:
28922            gen_helper_msa_div_u_h(cpu_env, twd, tws, twt);
28923            break;
28924        case DF_WORD:
28925            gen_helper_msa_div_u_w(cpu_env, twd, tws, twt);
28926            break;
28927        case DF_DOUBLE:
28928            gen_helper_msa_div_u_d(cpu_env, twd, tws, twt);
28929            break;
28930        }
28931        break;
28932    case OPC_MAX_A_df:
28933        switch (df) {
28934        case DF_BYTE:
28935            gen_helper_msa_max_a_b(cpu_env, twd, tws, twt);
28936            break;
28937        case DF_HALF:
28938            gen_helper_msa_max_a_h(cpu_env, twd, tws, twt);
28939            break;
28940        case DF_WORD:
28941            gen_helper_msa_max_a_w(cpu_env, twd, tws, twt);
28942            break;
28943        case DF_DOUBLE:
28944            gen_helper_msa_max_a_d(cpu_env, twd, tws, twt);
28945            break;
28946        }
28947        break;
28948    case OPC_MAX_S_df:
28949        switch (df) {
28950        case DF_BYTE:
28951            gen_helper_msa_max_s_b(cpu_env, twd, tws, twt);
28952            break;
28953        case DF_HALF:
28954            gen_helper_msa_max_s_h(cpu_env, twd, tws, twt);
28955            break;
28956        case DF_WORD:
28957            gen_helper_msa_max_s_w(cpu_env, twd, tws, twt);
28958            break;
28959        case DF_DOUBLE:
28960            gen_helper_msa_max_s_d(cpu_env, twd, tws, twt);
28961            break;
28962        }
28963        break;
28964    case OPC_MAX_U_df:
28965        switch (df) {
28966        case DF_BYTE:
28967            gen_helper_msa_max_u_b(cpu_env, twd, tws, twt);
28968            break;
28969        case DF_HALF:
28970            gen_helper_msa_max_u_h(cpu_env, twd, tws, twt);
28971            break;
28972        case DF_WORD:
28973            gen_helper_msa_max_u_w(cpu_env, twd, tws, twt);
28974            break;
28975        case DF_DOUBLE:
28976            gen_helper_msa_max_u_d(cpu_env, twd, tws, twt);
28977            break;
28978        }
28979        break;
28980    case OPC_MIN_A_df:
28981        switch (df) {
28982        case DF_BYTE:
28983            gen_helper_msa_min_a_b(cpu_env, twd, tws, twt);
28984            break;
28985        case DF_HALF:
28986            gen_helper_msa_min_a_h(cpu_env, twd, tws, twt);
28987            break;
28988        case DF_WORD:
28989            gen_helper_msa_min_a_w(cpu_env, twd, tws, twt);
28990            break;
28991        case DF_DOUBLE:
28992            gen_helper_msa_min_a_d(cpu_env, twd, tws, twt);
28993            break;
28994        }
28995        break;
28996    case OPC_MIN_S_df:
28997        switch (df) {
28998        case DF_BYTE:
28999            gen_helper_msa_min_s_b(cpu_env, twd, tws, twt);
29000            break;
29001        case DF_HALF:
29002            gen_helper_msa_min_s_h(cpu_env, twd, tws, twt);
29003            break;
29004        case DF_WORD:
29005            gen_helper_msa_min_s_w(cpu_env, twd, tws, twt);
29006            break;
29007        case DF_DOUBLE:
29008            gen_helper_msa_min_s_d(cpu_env, twd, tws, twt);
29009            break;
29010        }
29011        break;
29012    case OPC_MIN_U_df:
29013        switch (df) {
29014        case DF_BYTE:
29015            gen_helper_msa_min_u_b(cpu_env, twd, tws, twt);
29016            break;
29017        case DF_HALF:
29018            gen_helper_msa_min_u_h(cpu_env, twd, tws, twt);
29019            break;
29020        case DF_WORD:
29021            gen_helper_msa_min_u_w(cpu_env, twd, tws, twt);
29022            break;
29023        case DF_DOUBLE:
29024            gen_helper_msa_min_u_d(cpu_env, twd, tws, twt);
29025            break;
29026        }
29027        break;
29028    case OPC_MOD_S_df:
29029        switch (df) {
29030        case DF_BYTE:
29031            gen_helper_msa_mod_s_b(cpu_env, twd, tws, twt);
29032            break;
29033        case DF_HALF:
29034            gen_helper_msa_mod_s_h(cpu_env, twd, tws, twt);
29035            break;
29036        case DF_WORD:
29037            gen_helper_msa_mod_s_w(cpu_env, twd, tws, twt);
29038            break;
29039        case DF_DOUBLE:
29040            gen_helper_msa_mod_s_d(cpu_env, twd, tws, twt);
29041            break;
29042        }
29043        break;
29044    case OPC_MOD_U_df:
29045        switch (df) {
29046        case DF_BYTE:
29047            gen_helper_msa_mod_u_b(cpu_env, twd, tws, twt);
29048            break;
29049        case DF_HALF:
29050            gen_helper_msa_mod_u_h(cpu_env, twd, tws, twt);
29051            break;
29052        case DF_WORD:
29053            gen_helper_msa_mod_u_w(cpu_env, twd, tws, twt);
29054            break;
29055        case DF_DOUBLE:
29056            gen_helper_msa_mod_u_d(cpu_env, twd, tws, twt);
29057            break;
29058        }
29059        break;
29060    case OPC_ASUB_S_df:
29061        switch (df) {
29062        case DF_BYTE:
29063            gen_helper_msa_asub_s_b(cpu_env, twd, tws, twt);
29064            break;
29065        case DF_HALF:
29066            gen_helper_msa_asub_s_h(cpu_env, twd, tws, twt);
29067            break;
29068        case DF_WORD:
29069            gen_helper_msa_asub_s_w(cpu_env, twd, tws, twt);
29070            break;
29071        case DF_DOUBLE:
29072            gen_helper_msa_asub_s_d(cpu_env, twd, tws, twt);
29073            break;
29074        }
29075        break;
29076    case OPC_ASUB_U_df:
29077        switch (df) {
29078        case DF_BYTE:
29079            gen_helper_msa_asub_u_b(cpu_env, twd, tws, twt);
29080            break;
29081        case DF_HALF:
29082            gen_helper_msa_asub_u_h(cpu_env, twd, tws, twt);
29083            break;
29084        case DF_WORD:
29085            gen_helper_msa_asub_u_w(cpu_env, twd, tws, twt);
29086            break;
29087        case DF_DOUBLE:
29088            gen_helper_msa_asub_u_d(cpu_env, twd, tws, twt);
29089            break;
29090        }
29091        break;
29092    case OPC_ILVEV_df:
29093        switch (df) {
29094        case DF_BYTE:
29095            gen_helper_msa_ilvev_b(cpu_env, twd, tws, twt);
29096            break;
29097        case DF_HALF:
29098            gen_helper_msa_ilvev_h(cpu_env, twd, tws, twt);
29099            break;
29100        case DF_WORD:
29101            gen_helper_msa_ilvev_w(cpu_env, twd, tws, twt);
29102            break;
29103        case DF_DOUBLE:
29104            gen_helper_msa_ilvev_d(cpu_env, twd, tws, twt);
29105            break;
29106        }
29107        break;
29108    case OPC_ILVOD_df:
29109        switch (df) {
29110        case DF_BYTE:
29111            gen_helper_msa_ilvod_b(cpu_env, twd, tws, twt);
29112            break;
29113        case DF_HALF:
29114            gen_helper_msa_ilvod_h(cpu_env, twd, tws, twt);
29115            break;
29116        case DF_WORD:
29117            gen_helper_msa_ilvod_w(cpu_env, twd, tws, twt);
29118            break;
29119        case DF_DOUBLE:
29120            gen_helper_msa_ilvod_d(cpu_env, twd, tws, twt);
29121            break;
29122        }
29123        break;
29124    case OPC_ILVL_df:
29125        switch (df) {
29126        case DF_BYTE:
29127            gen_helper_msa_ilvl_b(cpu_env, twd, tws, twt);
29128            break;
29129        case DF_HALF:
29130            gen_helper_msa_ilvl_h(cpu_env, twd, tws, twt);
29131            break;
29132        case DF_WORD:
29133            gen_helper_msa_ilvl_w(cpu_env, twd, tws, twt);
29134            break;
29135        case DF_DOUBLE:
29136            gen_helper_msa_ilvl_d(cpu_env, twd, tws, twt);
29137            break;
29138        }
29139        break;
29140    case OPC_ILVR_df:
29141        switch (df) {
29142        case DF_BYTE:
29143            gen_helper_msa_ilvr_b(cpu_env, twd, tws, twt);
29144            break;
29145        case DF_HALF:
29146            gen_helper_msa_ilvr_h(cpu_env, twd, tws, twt);
29147            break;
29148        case DF_WORD:
29149            gen_helper_msa_ilvr_w(cpu_env, twd, tws, twt);
29150            break;
29151        case DF_DOUBLE:
29152            gen_helper_msa_ilvr_d(cpu_env, twd, tws, twt);
29153            break;
29154        }
29155        break;
29156    case OPC_PCKEV_df:
29157        switch (df) {
29158        case DF_BYTE:
29159            gen_helper_msa_pckev_b(cpu_env, twd, tws, twt);
29160            break;
29161        case DF_HALF:
29162            gen_helper_msa_pckev_h(cpu_env, twd, tws, twt);
29163            break;
29164        case DF_WORD:
29165            gen_helper_msa_pckev_w(cpu_env, twd, tws, twt);
29166            break;
29167        case DF_DOUBLE:
29168            gen_helper_msa_pckev_d(cpu_env, twd, tws, twt);
29169            break;
29170        }
29171        break;
29172    case OPC_PCKOD_df:
29173        switch (df) {
29174        case DF_BYTE:
29175            gen_helper_msa_pckod_b(cpu_env, twd, tws, twt);
29176            break;
29177        case DF_HALF:
29178            gen_helper_msa_pckod_h(cpu_env, twd, tws, twt);
29179            break;
29180        case DF_WORD:
29181            gen_helper_msa_pckod_w(cpu_env, twd, tws, twt);
29182            break;
29183        case DF_DOUBLE:
29184            gen_helper_msa_pckod_d(cpu_env, twd, tws, twt);
29185            break;
29186        }
29187        break;
29188    case OPC_SLL_df:
29189        switch (df) {
29190        case DF_BYTE:
29191            gen_helper_msa_sll_b(cpu_env, twd, tws, twt);
29192            break;
29193        case DF_HALF:
29194            gen_helper_msa_sll_h(cpu_env, twd, tws, twt);
29195            break;
29196        case DF_WORD:
29197            gen_helper_msa_sll_w(cpu_env, twd, tws, twt);
29198            break;
29199        case DF_DOUBLE:
29200            gen_helper_msa_sll_d(cpu_env, twd, tws, twt);
29201            break;
29202        }
29203        break;
29204    case OPC_SRA_df:
29205        switch (df) {
29206        case DF_BYTE:
29207            gen_helper_msa_sra_b(cpu_env, twd, tws, twt);
29208            break;
29209        case DF_HALF:
29210            gen_helper_msa_sra_h(cpu_env, twd, tws, twt);
29211            break;
29212        case DF_WORD:
29213            gen_helper_msa_sra_w(cpu_env, twd, tws, twt);
29214            break;
29215        case DF_DOUBLE:
29216            gen_helper_msa_sra_d(cpu_env, twd, tws, twt);
29217            break;
29218        }
29219        break;
29220    case OPC_SRAR_df:
29221        switch (df) {
29222        case DF_BYTE:
29223            gen_helper_msa_srar_b(cpu_env, twd, tws, twt);
29224            break;
29225        case DF_HALF:
29226            gen_helper_msa_srar_h(cpu_env, twd, tws, twt);
29227            break;
29228        case DF_WORD:
29229            gen_helper_msa_srar_w(cpu_env, twd, tws, twt);
29230            break;
29231        case DF_DOUBLE:
29232            gen_helper_msa_srar_d(cpu_env, twd, tws, twt);
29233            break;
29234        }
29235        break;
29236    case OPC_SRL_df:
29237        switch (df) {
29238        case DF_BYTE:
29239            gen_helper_msa_srl_b(cpu_env, twd, tws, twt);
29240            break;
29241        case DF_HALF:
29242            gen_helper_msa_srl_h(cpu_env, twd, tws, twt);
29243            break;
29244        case DF_WORD:
29245            gen_helper_msa_srl_w(cpu_env, twd, tws, twt);
29246            break;
29247        case DF_DOUBLE:
29248            gen_helper_msa_srl_d(cpu_env, twd, tws, twt);
29249            break;
29250        }
29251        break;
29252    case OPC_SRLR_df:
29253        switch (df) {
29254        case DF_BYTE:
29255            gen_helper_msa_srlr_b(cpu_env, twd, tws, twt);
29256            break;
29257        case DF_HALF:
29258            gen_helper_msa_srlr_h(cpu_env, twd, tws, twt);
29259            break;
29260        case DF_WORD:
29261            gen_helper_msa_srlr_w(cpu_env, twd, tws, twt);
29262            break;
29263        case DF_DOUBLE:
29264            gen_helper_msa_srlr_d(cpu_env, twd, tws, twt);
29265            break;
29266        }
29267        break;
29268    case OPC_SUBS_S_df:
29269        gen_helper_msa_subs_s_df(cpu_env, tdf, twd, tws, twt);
29270        break;
29271    case OPC_MULV_df:
29272        gen_helper_msa_mulv_df(cpu_env, tdf, twd, tws, twt);
29273        break;
29274    case OPC_SLD_df:
29275        gen_helper_msa_sld_df(cpu_env, tdf, twd, tws, twt);
29276        break;
29277    case OPC_VSHF_df:
29278        gen_helper_msa_vshf_df(cpu_env, tdf, twd, tws, twt);
29279        break;
29280    case OPC_SUBV_df:
29281        gen_helper_msa_subv_df(cpu_env, tdf, twd, tws, twt);
29282        break;
29283    case OPC_SUBS_U_df:
29284        gen_helper_msa_subs_u_df(cpu_env, tdf, twd, tws, twt);
29285        break;
29286    case OPC_MADDV_df:
29287        gen_helper_msa_maddv_df(cpu_env, tdf, twd, tws, twt);
29288        break;
29289    case OPC_SPLAT_df:
29290        gen_helper_msa_splat_df(cpu_env, tdf, twd, tws, twt);
29291        break;
29292    case OPC_SUBSUS_U_df:
29293        gen_helper_msa_subsus_u_df(cpu_env, tdf, twd, tws, twt);
29294        break;
29295    case OPC_MSUBV_df:
29296        gen_helper_msa_msubv_df(cpu_env, tdf, twd, tws, twt);
29297        break;
29298    case OPC_SUBSUU_S_df:
29299        gen_helper_msa_subsuu_s_df(cpu_env, tdf, twd, tws, twt);
29300        break;
29301
29302    case OPC_DOTP_S_df:
29303    case OPC_DOTP_U_df:
29304    case OPC_DPADD_S_df:
29305    case OPC_DPADD_U_df:
29306    case OPC_DPSUB_S_df:
29307    case OPC_HADD_S_df:
29308    case OPC_DPSUB_U_df:
29309    case OPC_HADD_U_df:
29310    case OPC_HSUB_S_df:
29311    case OPC_HSUB_U_df:
29312        if (df == DF_BYTE) {
29313            generate_exception_end(ctx, EXCP_RI);
29314            break;
29315        }
29316        switch (MASK_MSA_3R(ctx->opcode)) {
29317        case OPC_HADD_S_df:
29318            switch (df) {
29319            case DF_HALF:
29320                gen_helper_msa_hadd_s_h(cpu_env, twd, tws, twt);
29321                break;
29322            case DF_WORD:
29323                gen_helper_msa_hadd_s_w(cpu_env, twd, tws, twt);
29324                break;
29325            case DF_DOUBLE:
29326                gen_helper_msa_hadd_s_d(cpu_env, twd, tws, twt);
29327                break;
29328            }
29329            break;
29330        case OPC_HADD_U_df:
29331            switch (df) {
29332            case DF_HALF:
29333                gen_helper_msa_hadd_u_h(cpu_env, twd, tws, twt);
29334                break;
29335            case DF_WORD:
29336                gen_helper_msa_hadd_u_w(cpu_env, twd, tws, twt);
29337                break;
29338            case DF_DOUBLE:
29339                gen_helper_msa_hadd_u_d(cpu_env, twd, tws, twt);
29340                break;
29341            }
29342            break;
29343        case OPC_HSUB_S_df:
29344            switch (df) {
29345            case DF_HALF:
29346                gen_helper_msa_hsub_s_h(cpu_env, twd, tws, twt);
29347                break;
29348            case DF_WORD:
29349                gen_helper_msa_hsub_s_w(cpu_env, twd, tws, twt);
29350                break;
29351            case DF_DOUBLE:
29352                gen_helper_msa_hsub_s_d(cpu_env, twd, tws, twt);
29353                break;
29354            }
29355            break;
29356        case OPC_HSUB_U_df:
29357            switch (df) {
29358            case DF_HALF:
29359                gen_helper_msa_hsub_u_h(cpu_env, twd, tws, twt);
29360                break;
29361            case DF_WORD:
29362                gen_helper_msa_hsub_u_w(cpu_env, twd, tws, twt);
29363                break;
29364            case DF_DOUBLE:
29365                gen_helper_msa_hsub_u_d(cpu_env, twd, tws, twt);
29366                break;
29367            }
29368            break;
29369        case OPC_DOTP_S_df:
29370            gen_helper_msa_dotp_s_df(cpu_env, tdf, twd, tws, twt);
29371            break;
29372        case OPC_DOTP_U_df:
29373            gen_helper_msa_dotp_u_df(cpu_env, tdf, twd, tws, twt);
29374            break;
29375        case OPC_DPADD_S_df:
29376            gen_helper_msa_dpadd_s_df(cpu_env, tdf, twd, tws, twt);
29377            break;
29378        case OPC_DPADD_U_df:
29379            gen_helper_msa_dpadd_u_df(cpu_env, tdf, twd, tws, twt);
29380            break;
29381        case OPC_DPSUB_S_df:
29382            gen_helper_msa_dpsub_s_df(cpu_env, tdf, twd, tws, twt);
29383            break;
29384        case OPC_DPSUB_U_df:
29385            gen_helper_msa_dpsub_u_df(cpu_env, tdf, twd, tws, twt);
29386            break;
29387        }
29388        break;
29389    default:
29390        MIPS_INVAL("MSA instruction");
29391        generate_exception_end(ctx, EXCP_RI);
29392        break;
29393    }
29394    tcg_temp_free_i32(twd);
29395    tcg_temp_free_i32(tws);
29396    tcg_temp_free_i32(twt);
29397    tcg_temp_free_i32(tdf);
29398}
29399
29400static void gen_msa_elm_3e(CPUMIPSState *env, DisasContext *ctx)
29401{
29402#define MASK_MSA_ELM_DF3E(op)   (MASK_MSA_MINOR(op) | (op & (0x3FF << 16)))
29403    uint8_t source = (ctx->opcode >> 11) & 0x1f;
29404    uint8_t dest = (ctx->opcode >> 6) & 0x1f;
29405    TCGv telm = tcg_temp_new();
29406    TCGv_i32 tsr = tcg_const_i32(source);
29407    TCGv_i32 tdt = tcg_const_i32(dest);
29408
29409    switch (MASK_MSA_ELM_DF3E(ctx->opcode)) {
29410    case OPC_CTCMSA:
29411        gen_load_gpr(telm, source);
29412        gen_helper_msa_ctcmsa(cpu_env, telm, tdt);
29413        break;
29414    case OPC_CFCMSA:
29415        gen_helper_msa_cfcmsa(telm, cpu_env, tsr);
29416        gen_store_gpr(telm, dest);
29417        break;
29418    case OPC_MOVE_V:
29419        gen_helper_msa_move_v(cpu_env, tdt, tsr);
29420        break;
29421    default:
29422        MIPS_INVAL("MSA instruction");
29423        generate_exception_end(ctx, EXCP_RI);
29424        break;
29425    }
29426
29427    tcg_temp_free(telm);
29428    tcg_temp_free_i32(tdt);
29429    tcg_temp_free_i32(tsr);
29430}
29431
29432static void gen_msa_elm_df(CPUMIPSState *env, DisasContext *ctx, uint32_t df,
29433        uint32_t n)
29434{
29435#define MASK_MSA_ELM(op)    (MASK_MSA_MINOR(op) | (op & (0xf << 22)))
29436    uint8_t ws = (ctx->opcode >> 11) & 0x1f;
29437    uint8_t wd = (ctx->opcode >> 6) & 0x1f;
29438
29439    TCGv_i32 tws = tcg_const_i32(ws);
29440    TCGv_i32 twd = tcg_const_i32(wd);
29441    TCGv_i32 tn  = tcg_const_i32(n);
29442    TCGv_i32 tdf = tcg_const_i32(df);
29443
29444    switch (MASK_MSA_ELM(ctx->opcode)) {
29445    case OPC_SLDI_df:
29446        gen_helper_msa_sldi_df(cpu_env, tdf, twd, tws, tn);
29447        break;
29448    case OPC_SPLATI_df:
29449        gen_helper_msa_splati_df(cpu_env, tdf, twd, tws, tn);
29450        break;
29451    case OPC_INSVE_df:
29452        gen_helper_msa_insve_df(cpu_env, tdf, twd, tws, tn);
29453        break;
29454    case OPC_COPY_S_df:
29455    case OPC_COPY_U_df:
29456    case OPC_INSERT_df:
29457#if !defined(TARGET_MIPS64)
29458        /* Double format valid only for MIPS64 */
29459        if (df == DF_DOUBLE) {
29460            generate_exception_end(ctx, EXCP_RI);
29461            break;
29462        }
29463        if ((MASK_MSA_ELM(ctx->opcode) == OPC_COPY_U_df) &&
29464              (df == DF_WORD)) {
29465            generate_exception_end(ctx, EXCP_RI);
29466            break;
29467        }
29468#endif
29469        switch (MASK_MSA_ELM(ctx->opcode)) {
29470        case OPC_COPY_S_df:
29471            if (likely(wd != 0)) {
29472                switch (df) {
29473                case DF_BYTE:
29474                    gen_helper_msa_copy_s_b(cpu_env, twd, tws, tn);
29475                    break;
29476                case DF_HALF:
29477                    gen_helper_msa_copy_s_h(cpu_env, twd, tws, tn);
29478                    break;
29479                case DF_WORD:
29480                    gen_helper_msa_copy_s_w(cpu_env, twd, tws, tn);
29481                    break;
29482#if defined(TARGET_MIPS64)
29483                case DF_DOUBLE:
29484                    gen_helper_msa_copy_s_d(cpu_env, twd, tws, tn);
29485                    break;
29486#endif
29487                default:
29488                    assert(0);
29489                }
29490            }
29491            break;
29492        case OPC_COPY_U_df:
29493            if (likely(wd != 0)) {
29494                switch (df) {
29495                case DF_BYTE:
29496                    gen_helper_msa_copy_u_b(cpu_env, twd, tws, tn);
29497                    break;
29498                case DF_HALF:
29499                    gen_helper_msa_copy_u_h(cpu_env, twd, tws, tn);
29500                    break;
29501#if defined(TARGET_MIPS64)
29502                case DF_WORD:
29503                    gen_helper_msa_copy_u_w(cpu_env, twd, tws, tn);
29504                    break;
29505#endif
29506                default:
29507                    assert(0);
29508                }
29509            }
29510            break;
29511        case OPC_INSERT_df:
29512            switch (df) {
29513            case DF_BYTE:
29514                gen_helper_msa_insert_b(cpu_env, twd, tws, tn);
29515                break;
29516            case DF_HALF:
29517                gen_helper_msa_insert_h(cpu_env, twd, tws, tn);
29518                break;
29519            case DF_WORD:
29520                gen_helper_msa_insert_w(cpu_env, twd, tws, tn);
29521                break;
29522#if defined(TARGET_MIPS64)
29523            case DF_DOUBLE:
29524                gen_helper_msa_insert_d(cpu_env, twd, tws, tn);
29525                break;
29526#endif
29527            default:
29528                assert(0);
29529            }
29530            break;
29531        }
29532        break;
29533    default:
29534        MIPS_INVAL("MSA instruction");
29535        generate_exception_end(ctx, EXCP_RI);
29536    }
29537    tcg_temp_free_i32(twd);
29538    tcg_temp_free_i32(tws);
29539    tcg_temp_free_i32(tn);
29540    tcg_temp_free_i32(tdf);
29541}
29542
29543static void gen_msa_elm(CPUMIPSState *env, DisasContext *ctx)
29544{
29545    uint8_t dfn = (ctx->opcode >> 16) & 0x3f;
29546    uint32_t df = 0, n = 0;
29547
29548    if ((dfn & 0x30) == 0x00) {
29549        n = dfn & 0x0f;
29550        df = DF_BYTE;
29551    } else if ((dfn & 0x38) == 0x20) {
29552        n = dfn & 0x07;
29553        df = DF_HALF;
29554    } else if ((dfn & 0x3c) == 0x30) {
29555        n = dfn & 0x03;
29556        df = DF_WORD;
29557    } else if ((dfn & 0x3e) == 0x38) {
29558        n = dfn & 0x01;
29559        df = DF_DOUBLE;
29560    } else if (dfn == 0x3E) {
29561        /* CTCMSA, CFCMSA, MOVE.V */
29562        gen_msa_elm_3e(env, ctx);
29563        return;
29564    } else {
29565        generate_exception_end(ctx, EXCP_RI);
29566        return;
29567    }
29568
29569    gen_msa_elm_df(env, ctx, df, n);
29570}
29571
29572static void gen_msa_3rf(CPUMIPSState *env, DisasContext *ctx)
29573{
29574#define MASK_MSA_3RF(op)    (MASK_MSA_MINOR(op) | (op & (0xf << 22)))
29575    uint8_t df = (ctx->opcode >> 21) & 0x1;
29576    uint8_t wt = (ctx->opcode >> 16) & 0x1f;
29577    uint8_t ws = (ctx->opcode >> 11) & 0x1f;
29578    uint8_t wd = (ctx->opcode >> 6) & 0x1f;
29579
29580    TCGv_i32 twd = tcg_const_i32(wd);
29581    TCGv_i32 tws = tcg_const_i32(ws);
29582    TCGv_i32 twt = tcg_const_i32(wt);
29583    TCGv_i32 tdf = tcg_temp_new_i32();
29584
29585    /* adjust df value for floating-point instruction */
29586    tcg_gen_movi_i32(tdf, df + 2);
29587
29588    switch (MASK_MSA_3RF(ctx->opcode)) {
29589    case OPC_FCAF_df:
29590        gen_helper_msa_fcaf_df(cpu_env, tdf, twd, tws, twt);
29591        break;
29592    case OPC_FADD_df:
29593        gen_helper_msa_fadd_df(cpu_env, tdf, twd, tws, twt);
29594        break;
29595    case OPC_FCUN_df:
29596        gen_helper_msa_fcun_df(cpu_env, tdf, twd, tws, twt);
29597        break;
29598    case OPC_FSUB_df:
29599        gen_helper_msa_fsub_df(cpu_env, tdf, twd, tws, twt);
29600        break;
29601    case OPC_FCOR_df:
29602        gen_helper_msa_fcor_df(cpu_env, tdf, twd, tws, twt);
29603        break;
29604    case OPC_FCEQ_df:
29605        gen_helper_msa_fceq_df(cpu_env, tdf, twd, tws, twt);
29606        break;
29607    case OPC_FMUL_df:
29608        gen_helper_msa_fmul_df(cpu_env, tdf, twd, tws, twt);
29609        break;
29610    case OPC_FCUNE_df:
29611        gen_helper_msa_fcune_df(cpu_env, tdf, twd, tws, twt);
29612        break;
29613    case OPC_FCUEQ_df:
29614        gen_helper_msa_fcueq_df(cpu_env, tdf, twd, tws, twt);
29615        break;
29616    case OPC_FDIV_df:
29617        gen_helper_msa_fdiv_df(cpu_env, tdf, twd, tws, twt);
29618        break;
29619    case OPC_FCNE_df:
29620        gen_helper_msa_fcne_df(cpu_env, tdf, twd, tws, twt);
29621        break;
29622    case OPC_FCLT_df:
29623        gen_helper_msa_fclt_df(cpu_env, tdf, twd, tws, twt);
29624        break;
29625    case OPC_FMADD_df:
29626        gen_helper_msa_fmadd_df(cpu_env, tdf, twd, tws, twt);
29627        break;
29628    case OPC_MUL_Q_df:
29629        tcg_gen_movi_i32(tdf, df + 1);
29630        gen_helper_msa_mul_q_df(cpu_env, tdf, twd, tws, twt);
29631        break;
29632    case OPC_FCULT_df:
29633        gen_helper_msa_fcult_df(cpu_env, tdf, twd, tws, twt);
29634        break;
29635    case OPC_FMSUB_df:
29636        gen_helper_msa_fmsub_df(cpu_env, tdf, twd, tws, twt);
29637        break;
29638    case OPC_MADD_Q_df:
29639        tcg_gen_movi_i32(tdf, df + 1);
29640        gen_helper_msa_madd_q_df(cpu_env, tdf, twd, tws, twt);
29641        break;
29642    case OPC_FCLE_df:
29643        gen_helper_msa_fcle_df(cpu_env, tdf, twd, tws, twt);
29644        break;
29645    case OPC_MSUB_Q_df:
29646        tcg_gen_movi_i32(tdf, df + 1);
29647        gen_helper_msa_msub_q_df(cpu_env, tdf, twd, tws, twt);
29648        break;
29649    case OPC_FCULE_df:
29650        gen_helper_msa_fcule_df(cpu_env, tdf, twd, tws, twt);
29651        break;
29652    case OPC_FEXP2_df:
29653        gen_helper_msa_fexp2_df(cpu_env, tdf, twd, tws, twt);
29654        break;
29655    case OPC_FSAF_df:
29656        gen_helper_msa_fsaf_df(cpu_env, tdf, twd, tws, twt);
29657        break;
29658    case OPC_FEXDO_df:
29659        gen_helper_msa_fexdo_df(cpu_env, tdf, twd, tws, twt);
29660        break;
29661    case OPC_FSUN_df:
29662        gen_helper_msa_fsun_df(cpu_env, tdf, twd, tws, twt);
29663        break;
29664    case OPC_FSOR_df:
29665        gen_helper_msa_fsor_df(cpu_env, tdf, twd, tws, twt);
29666        break;
29667    case OPC_FSEQ_df:
29668        gen_helper_msa_fseq_df(cpu_env, tdf, twd, tws, twt);
29669        break;
29670    case OPC_FTQ_df:
29671        gen_helper_msa_ftq_df(cpu_env, tdf, twd, tws, twt);
29672        break;
29673    case OPC_FSUNE_df:
29674        gen_helper_msa_fsune_df(cpu_env, tdf, twd, tws, twt);
29675        break;
29676    case OPC_FSUEQ_df:
29677        gen_helper_msa_fsueq_df(cpu_env, tdf, twd, tws, twt);
29678        break;
29679    case OPC_FSNE_df:
29680        gen_helper_msa_fsne_df(cpu_env, tdf, twd, tws, twt);
29681        break;
29682    case OPC_FSLT_df:
29683        gen_helper_msa_fslt_df(cpu_env, tdf, twd, tws, twt);
29684        break;
29685    case OPC_FMIN_df:
29686        gen_helper_msa_fmin_df(cpu_env, tdf, twd, tws, twt);
29687        break;
29688    case OPC_MULR_Q_df:
29689        tcg_gen_movi_i32(tdf, df + 1);
29690        gen_helper_msa_mulr_q_df(cpu_env, tdf, twd, tws, twt);
29691        break;
29692    case OPC_FSULT_df:
29693        gen_helper_msa_fsult_df(cpu_env, tdf, twd, tws, twt);
29694        break;
29695    case OPC_FMIN_A_df:
29696        gen_helper_msa_fmin_a_df(cpu_env, tdf, twd, tws, twt);
29697        break;
29698    case OPC_MADDR_Q_df:
29699        tcg_gen_movi_i32(tdf, df + 1);
29700        gen_helper_msa_maddr_q_df(cpu_env, tdf, twd, tws, twt);
29701        break;
29702    case OPC_FSLE_df:
29703        gen_helper_msa_fsle_df(cpu_env, tdf, twd, tws, twt);
29704        break;
29705    case OPC_FMAX_df:
29706        gen_helper_msa_fmax_df(cpu_env, tdf, twd, tws, twt);
29707        break;
29708    case OPC_MSUBR_Q_df:
29709        tcg_gen_movi_i32(tdf, df + 1);
29710        gen_helper_msa_msubr_q_df(cpu_env, tdf, twd, tws, twt);
29711        break;
29712    case OPC_FSULE_df:
29713        gen_helper_msa_fsule_df(cpu_env, tdf, twd, tws, twt);
29714        break;
29715    case OPC_FMAX_A_df:
29716        gen_helper_msa_fmax_a_df(cpu_env, tdf, twd, tws, twt);
29717        break;
29718    default:
29719        MIPS_INVAL("MSA instruction");
29720        generate_exception_end(ctx, EXCP_RI);
29721        break;
29722    }
29723
29724    tcg_temp_free_i32(twd);
29725    tcg_temp_free_i32(tws);
29726    tcg_temp_free_i32(twt);
29727    tcg_temp_free_i32(tdf);
29728}
29729
29730static void gen_msa_2r(CPUMIPSState *env, DisasContext *ctx)
29731{
29732#define MASK_MSA_2R(op)     (MASK_MSA_MINOR(op) | (op & (0x1f << 21)) | \
29733                            (op & (0x7 << 18)))
29734    uint8_t wt = (ctx->opcode >> 16) & 0x1f;
29735    uint8_t ws = (ctx->opcode >> 11) & 0x1f;
29736    uint8_t wd = (ctx->opcode >> 6) & 0x1f;
29737    uint8_t df = (ctx->opcode >> 16) & 0x3;
29738    TCGv_i32 twd = tcg_const_i32(wd);
29739    TCGv_i32 tws = tcg_const_i32(ws);
29740    TCGv_i32 twt = tcg_const_i32(wt);
29741    TCGv_i32 tdf = tcg_const_i32(df);
29742
29743    switch (MASK_MSA_2R(ctx->opcode)) {
29744    case OPC_FILL_df:
29745#if !defined(TARGET_MIPS64)
29746        /* Double format valid only for MIPS64 */
29747        if (df == DF_DOUBLE) {
29748            generate_exception_end(ctx, EXCP_RI);
29749            break;
29750        }
29751#endif
29752        gen_helper_msa_fill_df(cpu_env, tdf, twd, tws); /* trs */
29753        break;
29754    case OPC_NLOC_df:
29755        switch (df) {
29756        case DF_BYTE:
29757            gen_helper_msa_nloc_b(cpu_env, twd, tws);
29758            break;
29759        case DF_HALF:
29760            gen_helper_msa_nloc_h(cpu_env, twd, tws);
29761            break;
29762        case DF_WORD:
29763            gen_helper_msa_nloc_w(cpu_env, twd, tws);
29764            break;
29765        case DF_DOUBLE:
29766            gen_helper_msa_nloc_d(cpu_env, twd, tws);
29767            break;
29768        }
29769        break;
29770    case OPC_NLZC_df:
29771        switch (df) {
29772        case DF_BYTE:
29773            gen_helper_msa_nlzc_b(cpu_env, twd, tws);
29774            break;
29775        case DF_HALF:
29776            gen_helper_msa_nlzc_h(cpu_env, twd, tws);
29777            break;
29778        case DF_WORD:
29779            gen_helper_msa_nlzc_w(cpu_env, twd, tws);
29780            break;
29781        case DF_DOUBLE:
29782            gen_helper_msa_nlzc_d(cpu_env, twd, tws);
29783            break;
29784        }
29785        break;
29786    case OPC_PCNT_df:
29787        switch (df) {
29788        case DF_BYTE:
29789            gen_helper_msa_pcnt_b(cpu_env, twd, tws);
29790            break;
29791        case DF_HALF:
29792            gen_helper_msa_pcnt_h(cpu_env, twd, tws);
29793            break;
29794        case DF_WORD:
29795            gen_helper_msa_pcnt_w(cpu_env, twd, tws);
29796            break;
29797        case DF_DOUBLE:
29798            gen_helper_msa_pcnt_d(cpu_env, twd, tws);
29799            break;
29800        }
29801        break;
29802    default:
29803        MIPS_INVAL("MSA instruction");
29804        generate_exception_end(ctx, EXCP_RI);
29805        break;
29806    }
29807
29808    tcg_temp_free_i32(twd);
29809    tcg_temp_free_i32(tws);
29810    tcg_temp_free_i32(twt);
29811    tcg_temp_free_i32(tdf);
29812}
29813
29814static void gen_msa_2rf(CPUMIPSState *env, DisasContext *ctx)
29815{
29816#define MASK_MSA_2RF(op)    (MASK_MSA_MINOR(op) | (op & (0x1f << 21)) | \
29817                            (op & (0xf << 17)))
29818    uint8_t wt = (ctx->opcode >> 16) & 0x1f;
29819    uint8_t ws = (ctx->opcode >> 11) & 0x1f;
29820    uint8_t wd = (ctx->opcode >> 6) & 0x1f;
29821    uint8_t df = (ctx->opcode >> 16) & 0x1;
29822    TCGv_i32 twd = tcg_const_i32(wd);
29823    TCGv_i32 tws = tcg_const_i32(ws);
29824    TCGv_i32 twt = tcg_const_i32(wt);
29825    /* adjust df value for floating-point instruction */
29826    TCGv_i32 tdf = tcg_const_i32(df + 2);
29827
29828    switch (MASK_MSA_2RF(ctx->opcode)) {
29829    case OPC_FCLASS_df:
29830        gen_helper_msa_fclass_df(cpu_env, tdf, twd, tws);
29831        break;
29832    case OPC_FTRUNC_S_df:
29833        gen_helper_msa_ftrunc_s_df(cpu_env, tdf, twd, tws);
29834        break;
29835    case OPC_FTRUNC_U_df:
29836        gen_helper_msa_ftrunc_u_df(cpu_env, tdf, twd, tws);
29837        break;
29838    case OPC_FSQRT_df:
29839        gen_helper_msa_fsqrt_df(cpu_env, tdf, twd, tws);
29840        break;
29841    case OPC_FRSQRT_df:
29842        gen_helper_msa_frsqrt_df(cpu_env, tdf, twd, tws);
29843        break;
29844    case OPC_FRCP_df:
29845        gen_helper_msa_frcp_df(cpu_env, tdf, twd, tws);
29846        break;
29847    case OPC_FRINT_df:
29848        gen_helper_msa_frint_df(cpu_env, tdf, twd, tws);
29849        break;
29850    case OPC_FLOG2_df:
29851        gen_helper_msa_flog2_df(cpu_env, tdf, twd, tws);
29852        break;
29853    case OPC_FEXUPL_df:
29854        gen_helper_msa_fexupl_df(cpu_env, tdf, twd, tws);
29855        break;
29856    case OPC_FEXUPR_df:
29857        gen_helper_msa_fexupr_df(cpu_env, tdf, twd, tws);
29858        break;
29859    case OPC_FFQL_df:
29860        gen_helper_msa_ffql_df(cpu_env, tdf, twd, tws);
29861        break;
29862    case OPC_FFQR_df:
29863        gen_helper_msa_ffqr_df(cpu_env, tdf, twd, tws);
29864        break;
29865    case OPC_FTINT_S_df:
29866        gen_helper_msa_ftint_s_df(cpu_env, tdf, twd, tws);
29867        break;
29868    case OPC_FTINT_U_df:
29869        gen_helper_msa_ftint_u_df(cpu_env, tdf, twd, tws);
29870        break;
29871    case OPC_FFINT_S_df:
29872        gen_helper_msa_ffint_s_df(cpu_env, tdf, twd, tws);
29873        break;
29874    case OPC_FFINT_U_df:
29875        gen_helper_msa_ffint_u_df(cpu_env, tdf, twd, tws);
29876        break;
29877    }
29878
29879    tcg_temp_free_i32(twd);
29880    tcg_temp_free_i32(tws);
29881    tcg_temp_free_i32(twt);
29882    tcg_temp_free_i32(tdf);
29883}
29884
29885static void gen_msa_vec_v(CPUMIPSState *env, DisasContext *ctx)
29886{
29887#define MASK_MSA_VEC(op)    (MASK_MSA_MINOR(op) | (op & (0x1f << 21)))
29888    uint8_t wt = (ctx->opcode >> 16) & 0x1f;
29889    uint8_t ws = (ctx->opcode >> 11) & 0x1f;
29890    uint8_t wd = (ctx->opcode >> 6) & 0x1f;
29891    TCGv_i32 twd = tcg_const_i32(wd);
29892    TCGv_i32 tws = tcg_const_i32(ws);
29893    TCGv_i32 twt = tcg_const_i32(wt);
29894
29895    switch (MASK_MSA_VEC(ctx->opcode)) {
29896    case OPC_AND_V:
29897        gen_helper_msa_and_v(cpu_env, twd, tws, twt);
29898        break;
29899    case OPC_OR_V:
29900        gen_helper_msa_or_v(cpu_env, twd, tws, twt);
29901        break;
29902    case OPC_NOR_V:
29903        gen_helper_msa_nor_v(cpu_env, twd, tws, twt);
29904        break;
29905    case OPC_XOR_V:
29906        gen_helper_msa_xor_v(cpu_env, twd, tws, twt);
29907        break;
29908    case OPC_BMNZ_V:
29909        gen_helper_msa_bmnz_v(cpu_env, twd, tws, twt);
29910        break;
29911    case OPC_BMZ_V:
29912        gen_helper_msa_bmz_v(cpu_env, twd, tws, twt);
29913        break;
29914    case OPC_BSEL_V:
29915        gen_helper_msa_bsel_v(cpu_env, twd, tws, twt);
29916        break;
29917    default:
29918        MIPS_INVAL("MSA instruction");
29919        generate_exception_end(ctx, EXCP_RI);
29920        break;
29921    }
29922
29923    tcg_temp_free_i32(twd);
29924    tcg_temp_free_i32(tws);
29925    tcg_temp_free_i32(twt);
29926}
29927
29928static void gen_msa_vec(CPUMIPSState *env, DisasContext *ctx)
29929{
29930    switch (MASK_MSA_VEC(ctx->opcode)) {
29931    case OPC_AND_V:
29932    case OPC_OR_V:
29933    case OPC_NOR_V:
29934    case OPC_XOR_V:
29935    case OPC_BMNZ_V:
29936    case OPC_BMZ_V:
29937    case OPC_BSEL_V:
29938        gen_msa_vec_v(env, ctx);
29939        break;
29940    case OPC_MSA_2R:
29941        gen_msa_2r(env, ctx);
29942        break;
29943    case OPC_MSA_2RF:
29944        gen_msa_2rf(env, ctx);
29945        break;
29946    default:
29947        MIPS_INVAL("MSA instruction");
29948        generate_exception_end(ctx, EXCP_RI);
29949        break;
29950    }
29951}
29952
29953static void gen_msa(CPUMIPSState *env, DisasContext *ctx)
29954{
29955    uint32_t opcode = ctx->opcode;
29956    check_insn(ctx, ASE_MSA);
29957    check_msa_access(ctx);
29958
29959    switch (MASK_MSA_MINOR(opcode)) {
29960    case OPC_MSA_I8_00:
29961    case OPC_MSA_I8_01:
29962    case OPC_MSA_I8_02:
29963        gen_msa_i8(env, ctx);
29964        break;
29965    case OPC_MSA_I5_06:
29966    case OPC_MSA_I5_07:
29967        gen_msa_i5(env, ctx);
29968        break;
29969    case OPC_MSA_BIT_09:
29970    case OPC_MSA_BIT_0A:
29971        gen_msa_bit(env, ctx);
29972        break;
29973    case OPC_MSA_3R_0D:
29974    case OPC_MSA_3R_0E:
29975    case OPC_MSA_3R_0F:
29976    case OPC_MSA_3R_10:
29977    case OPC_MSA_3R_11:
29978    case OPC_MSA_3R_12:
29979    case OPC_MSA_3R_13:
29980    case OPC_MSA_3R_14:
29981    case OPC_MSA_3R_15:
29982        gen_msa_3r(env, ctx);
29983        break;
29984    case OPC_MSA_ELM:
29985        gen_msa_elm(env, ctx);
29986        break;
29987    case OPC_MSA_3RF_1A:
29988    case OPC_MSA_3RF_1B:
29989    case OPC_MSA_3RF_1C:
29990        gen_msa_3rf(env, ctx);
29991        break;
29992    case OPC_MSA_VEC:
29993        gen_msa_vec(env, ctx);
29994        break;
29995    case OPC_LD_B:
29996    case OPC_LD_H:
29997    case OPC_LD_W:
29998    case OPC_LD_D:
29999    case OPC_ST_B:
30000    case OPC_ST_H:
30001    case OPC_ST_W:
30002    case OPC_ST_D:
30003        {
30004            int32_t s10 = sextract32(ctx->opcode, 16, 10);
30005            uint8_t rs = (ctx->opcode >> 11) & 0x1f;
30006            uint8_t wd = (ctx->opcode >> 6) & 0x1f;
30007            uint8_t df = (ctx->opcode >> 0) & 0x3;
30008
30009            TCGv_i32 twd = tcg_const_i32(wd);
30010            TCGv taddr = tcg_temp_new();
30011            gen_base_offset_addr(ctx, taddr, rs, s10 << df);
30012
30013            switch (MASK_MSA_MINOR(opcode)) {
30014            case OPC_LD_B:
30015                gen_helper_msa_ld_b(cpu_env, twd, taddr);
30016                break;
30017            case OPC_LD_H:
30018                gen_helper_msa_ld_h(cpu_env, twd, taddr);
30019                break;
30020            case OPC_LD_W:
30021                gen_helper_msa_ld_w(cpu_env, twd, taddr);
30022                break;
30023            case OPC_LD_D:
30024                gen_helper_msa_ld_d(cpu_env, twd, taddr);
30025                break;
30026            case OPC_ST_B:
30027                gen_helper_msa_st_b(cpu_env, twd, taddr);
30028                break;
30029            case OPC_ST_H:
30030                gen_helper_msa_st_h(cpu_env, twd, taddr);
30031                break;
30032            case OPC_ST_W:
30033                gen_helper_msa_st_w(cpu_env, twd, taddr);
30034                break;
30035            case OPC_ST_D:
30036                gen_helper_msa_st_d(cpu_env, twd, taddr);
30037                break;
30038            }
30039
30040            tcg_temp_free_i32(twd);
30041            tcg_temp_free(taddr);
30042        }
30043        break;
30044    default:
30045        MIPS_INVAL("MSA instruction");
30046        generate_exception_end(ctx, EXCP_RI);
30047        break;
30048    }
30049
30050}
30051
30052static void decode_opc(CPUMIPSState *env, DisasContext *ctx)
30053{
30054    int32_t offset;
30055    int rs, rt, rd, sa;
30056    uint32_t op, op1;
30057    int16_t imm;
30058
30059    /* make sure instructions are on a word boundary */
30060    if (ctx->base.pc_next & 0x3) {
30061        env->CP0_BadVAddr = ctx->base.pc_next;
30062        generate_exception_err(ctx, EXCP_AdEL, EXCP_INST_NOTAVAIL);
30063        return;
30064    }
30065
30066    /* Handle blikely not taken case */
30067    if ((ctx->hflags & MIPS_HFLAG_BMASK_BASE) == MIPS_HFLAG_BL) {
30068        TCGLabel *l1 = gen_new_label();
30069
30070        tcg_gen_brcondi_tl(TCG_COND_NE, bcond, 0, l1);
30071        tcg_gen_movi_i32(hflags, ctx->hflags & ~MIPS_HFLAG_BMASK);
30072        gen_goto_tb(ctx, 1, ctx->base.pc_next + 4);
30073        gen_set_label(l1);
30074    }
30075
30076    op = MASK_OP_MAJOR(ctx->opcode);
30077    rs = (ctx->opcode >> 21) & 0x1f;
30078    rt = (ctx->opcode >> 16) & 0x1f;
30079    rd = (ctx->opcode >> 11) & 0x1f;
30080    sa = (ctx->opcode >> 6) & 0x1f;
30081    imm = (int16_t)ctx->opcode;
30082    switch (op) {
30083    case OPC_SPECIAL:
30084        decode_opc_special(env, ctx);
30085        break;
30086    case OPC_SPECIAL2:
30087#if defined(TARGET_MIPS64)
30088        if ((ctx->insn_flags & INSN_R5900) && (ctx->insn_flags & ASE_MMI)) {
30089            decode_mmi(env, ctx);
30090#else
30091        if (ctx->insn_flags & ASE_MXU) {
30092            decode_opc_mxu(env, ctx);
30093#endif
30094        } else {
30095            decode_opc_special2_legacy(env, ctx);
30096        }
30097        break;
30098    case OPC_SPECIAL3:
30099#if defined(TARGET_MIPS64)
30100        if (ctx->insn_flags & INSN_R5900) {
30101            decode_mmi_sq(env, ctx);    /* MMI_OPC_SQ */
30102        } else {
30103            decode_opc_special3(env, ctx);
30104        }
30105#else
30106        decode_opc_special3(env, ctx);
30107#endif
30108        break;
30109    case OPC_REGIMM:
30110        op1 = MASK_REGIMM(ctx->opcode);
30111        switch (op1) {
30112        case OPC_BLTZL: /* REGIMM branches */
30113        case OPC_BGEZL:
30114        case OPC_BLTZALL:
30115        case OPC_BGEZALL:
30116            check_insn(ctx, ISA_MIPS2);
30117            check_insn_opc_removed(ctx, ISA_MIPS32R6);
30118            /* Fallthrough */
30119        case OPC_BLTZ:
30120        case OPC_BGEZ:
30121            gen_compute_branch(ctx, op1, 4, rs, -1, imm << 2, 4);
30122            break;
30123        case OPC_BLTZAL:
30124        case OPC_BGEZAL:
30125            if (ctx->insn_flags & ISA_MIPS32R6) {
30126                if (rs == 0) {
30127                    /* OPC_NAL, OPC_BAL */
30128                    gen_compute_branch(ctx, op1, 4, 0, -1, imm << 2, 4);
30129                } else {
30130                    generate_exception_end(ctx, EXCP_RI);
30131                }
30132            } else {
30133                gen_compute_branch(ctx, op1, 4, rs, -1, imm << 2, 4);
30134            }
30135            break;
30136        case OPC_TGEI: /* REGIMM traps */
30137        case OPC_TGEIU:
30138        case OPC_TLTI:
30139        case OPC_TLTIU:
30140        case OPC_TEQI:
30141
30142        case OPC_TNEI:
30143            check_insn(ctx, ISA_MIPS2);
30144            check_insn_opc_removed(ctx, ISA_MIPS32R6);
30145            gen_trap(ctx, op1, rs, -1, imm);
30146            break;
30147        case OPC_SIGRIE:
30148            check_insn(ctx, ISA_MIPS32R6);
30149            generate_exception_end(ctx, EXCP_RI);
30150            break;
30151        case OPC_SYNCI:
30152            check_insn(ctx, ISA_MIPS32R2);
30153            /*
30154             * Break the TB to be able to sync copied instructions
30155             * immediately.
30156             */
30157            ctx->base.is_jmp = DISAS_STOP;
30158            break;
30159        case OPC_BPOSGE32:    /* MIPS DSP branch */
30160#if defined(TARGET_MIPS64)
30161        case OPC_BPOSGE64:
30162#endif
30163            check_dsp(ctx);
30164            gen_compute_branch(ctx, op1, 4, -1, -2, (int32_t)imm << 2, 4);
30165            break;
30166#if defined(TARGET_MIPS64)
30167        case OPC_DAHI:
30168            check_insn(ctx, ISA_MIPS32R6);
30169            check_mips_64(ctx);
30170            if (rs != 0) {
30171                tcg_gen_addi_tl(cpu_gpr[rs], cpu_gpr[rs], (int64_t)imm << 32);
30172            }
30173            break;
30174        case OPC_DATI:
30175            check_insn(ctx, ISA_MIPS32R6);
30176            check_mips_64(ctx);
30177            if (rs != 0) {
30178                tcg_gen_addi_tl(cpu_gpr[rs], cpu_gpr[rs], (int64_t)imm << 48);
30179            }
30180            break;
30181#endif
30182        default:            /* Invalid */
30183            MIPS_INVAL("regimm");
30184            generate_exception_end(ctx, EXCP_RI);
30185            break;
30186        }
30187        break;
30188    case OPC_CP0:
30189        check_cp0_enabled(ctx);
30190        op1 = MASK_CP0(ctx->opcode);
30191        switch (op1) {
30192        case OPC_MFC0:
30193        case OPC_MTC0:
30194        case OPC_MFTR:
30195        case OPC_MTTR:
30196        case OPC_MFHC0:
30197        case OPC_MTHC0:
30198#if defined(TARGET_MIPS64)
30199        case OPC_DMFC0:
30200        case OPC_DMTC0:
30201#endif
30202#ifndef CONFIG_USER_ONLY
30203            gen_cp0(env, ctx, op1, rt, rd);
30204#endif /* !CONFIG_USER_ONLY */
30205            break;
30206        case OPC_C0:
30207        case OPC_C0_1:
30208        case OPC_C0_2:
30209        case OPC_C0_3:
30210        case OPC_C0_4:
30211        case OPC_C0_5:
30212        case OPC_C0_6:
30213        case OPC_C0_7:
30214        case OPC_C0_8:
30215        case OPC_C0_9:
30216        case OPC_C0_A:
30217        case OPC_C0_B:
30218        case OPC_C0_C:
30219        case OPC_C0_D:
30220        case OPC_C0_E:
30221        case OPC_C0_F:
30222#ifndef CONFIG_USER_ONLY
30223            gen_cp0(env, ctx, MASK_C0(ctx->opcode), rt, rd);
30224#endif /* !CONFIG_USER_ONLY */
30225            break;
30226        case OPC_MFMC0:
30227#ifndef CONFIG_USER_ONLY
30228            {
30229                uint32_t op2;
30230                TCGv t0 = tcg_temp_new();
30231
30232                op2 = MASK_MFMC0(ctx->opcode);
30233                switch (op2) {
30234                case OPC_DMT:
30235                    check_cp0_mt(ctx);
30236                    gen_helper_dmt(t0);
30237                    gen_store_gpr(t0, rt);
30238                    break;
30239                case OPC_EMT:
30240                    check_cp0_mt(ctx);
30241                    gen_helper_emt(t0);
30242                    gen_store_gpr(t0, rt);
30243                    break;
30244                case OPC_DVPE:
30245                    check_cp0_mt(ctx);
30246                    gen_helper_dvpe(t0, cpu_env);
30247                    gen_store_gpr(t0, rt);
30248                    break;
30249                case OPC_EVPE:
30250                    check_cp0_mt(ctx);
30251                    gen_helper_evpe(t0, cpu_env);
30252                    gen_store_gpr(t0, rt);
30253                    break;
30254                case OPC_DVP:
30255                    check_insn(ctx, ISA_MIPS32R6);
30256                    if (ctx->vp) {
30257                        gen_helper_dvp(t0, cpu_env);
30258                        gen_store_gpr(t0, rt);
30259                    }
30260                    break;
30261                case OPC_EVP:
30262                    check_insn(ctx, ISA_MIPS32R6);
30263                    if (ctx->vp) {
30264                        gen_helper_evp(t0, cpu_env);
30265                        gen_store_gpr(t0, rt);
30266                    }
30267                    break;
30268                case OPC_DI:
30269                    check_insn(ctx, ISA_MIPS32R2);
30270                    save_cpu_state(ctx, 1);
30271                    gen_helper_di(t0, cpu_env);
30272                    gen_store_gpr(t0, rt);
30273                    /*
30274                     * Stop translation as we may have switched
30275                     * the execution mode.
30276                     */
30277                    ctx->base.is_jmp = DISAS_STOP;
30278                    break;
30279                case OPC_EI:
30280                    check_insn(ctx, ISA_MIPS32R2);
30281                    save_cpu_state(ctx, 1);
30282                    gen_helper_ei(t0, cpu_env);
30283                    gen_store_gpr(t0, rt);
30284                    /*
30285                     * DISAS_STOP isn't sufficient, we need to ensure we break
30286                     * out of translated code to check for pending interrupts.
30287                     */
30288                    gen_save_pc(ctx->base.pc_next + 4);
30289                    ctx->base.is_jmp = DISAS_EXIT;
30290                    break;
30291                default:            /* Invalid */
30292                    MIPS_INVAL("mfmc0");
30293                    generate_exception_end(ctx, EXCP_RI);
30294                    break;
30295                }
30296                tcg_temp_free(t0);
30297            }
30298#endif /* !CONFIG_USER_ONLY */
30299            break;
30300        case OPC_RDPGPR:
30301            check_insn(ctx, ISA_MIPS32R2);
30302            gen_load_srsgpr(rt, rd);
30303            break;
30304        case OPC_WRPGPR:
30305            check_insn(ctx, ISA_MIPS32R2);
30306            gen_store_srsgpr(rt, rd);
30307            break;
30308        default:
30309            MIPS_INVAL("cp0");
30310            generate_exception_end(ctx, EXCP_RI);
30311            break;
30312        }
30313        break;
30314    case OPC_BOVC: /* OPC_BEQZALC, OPC_BEQC, OPC_ADDI */
30315        if (ctx->insn_flags & ISA_MIPS32R6) {
30316            /* OPC_BOVC, OPC_BEQZALC, OPC_BEQC */
30317            gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
30318        } else {
30319            /* OPC_ADDI */
30320            /* Arithmetic with immediate opcode */
30321            gen_arith_imm(ctx, op, rt, rs, imm);
30322        }
30323        break;
30324    case OPC_ADDIU:
30325         gen_arith_imm(ctx, op, rt, rs, imm);
30326         break;
30327    case OPC_SLTI: /* Set on less than with immediate opcode */
30328    case OPC_SLTIU:
30329         gen_slt_imm(ctx, op, rt, rs, imm);
30330         break;
30331    case OPC_ANDI: /* Arithmetic with immediate opcode */
30332    case OPC_LUI: /* OPC_AUI */
30333    case OPC_ORI:
30334    case OPC_XORI:
30335         gen_logic_imm(ctx, op, rt, rs, imm);
30336         break;
30337    case OPC_J: /* Jump */
30338    case OPC_JAL:
30339         offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 2;
30340         gen_compute_branch(ctx, op, 4, rs, rt, offset, 4);
30341         break;
30342    /* Branch */
30343    case OPC_BLEZC: /* OPC_BGEZC, OPC_BGEC, OPC_BLEZL */
30344        if (ctx->insn_flags & ISA_MIPS32R6) {
30345            if (rt == 0) {
30346                generate_exception_end(ctx, EXCP_RI);
30347                break;
30348            }
30349            /* OPC_BLEZC, OPC_BGEZC, OPC_BGEC */
30350            gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
30351        } else {
30352            /* OPC_BLEZL */
30353            gen_compute_branch(ctx, op, 4, rs, rt, imm << 2, 4);
30354        }
30355        break;
30356    case OPC_BGTZC: /* OPC_BLTZC, OPC_BLTC, OPC_BGTZL */
30357        if (ctx->insn_flags & ISA_MIPS32R6) {
30358            if (rt == 0) {
30359                generate_exception_end(ctx, EXCP_RI);
30360                break;
30361            }
30362            /* OPC_BGTZC, OPC_BLTZC, OPC_BLTC */
30363            gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
30364        } else {
30365            /* OPC_BGTZL */
30366            gen_compute_branch(ctx, op, 4, rs, rt, imm << 2, 4);
30367        }
30368        break;
30369    case OPC_BLEZALC: /* OPC_BGEZALC, OPC_BGEUC, OPC_BLEZ */
30370        if (rt == 0) {
30371            /* OPC_BLEZ */
30372            gen_compute_branch(ctx, op, 4, rs, rt, imm << 2, 4);
30373        } else {
30374            check_insn(ctx, ISA_MIPS32R6);
30375            /* OPC_BLEZALC, OPC_BGEZALC, OPC_BGEUC */
30376            gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
30377        }
30378        break;
30379    case OPC_BGTZALC: /* OPC_BLTZALC, OPC_BLTUC, OPC_BGTZ */
30380        if (rt == 0) {
30381            /* OPC_BGTZ */
30382            gen_compute_branch(ctx, op, 4, rs, rt, imm << 2, 4);
30383        } else {
30384            check_insn(ctx, ISA_MIPS32R6);
30385            /* OPC_BGTZALC, OPC_BLTZALC, OPC_BLTUC */
30386            gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
30387        }
30388        break;
30389    case OPC_BEQL:
30390    case OPC_BNEL:
30391        check_insn(ctx, ISA_MIPS2);
30392         check_insn_opc_removed(ctx, ISA_MIPS32R6);
30393        /* Fallthrough */
30394    case OPC_BEQ:
30395    case OPC_BNE:
30396         gen_compute_branch(ctx, op, 4, rs, rt, imm << 2, 4);
30397         break;
30398    case OPC_LL: /* Load and stores */
30399        check_insn(ctx, ISA_MIPS2);
30400        if (ctx->insn_flags & INSN_R5900) {
30401            check_insn_opc_user_only(ctx, INSN_R5900);
30402        }
30403        /* Fallthrough */
30404    case OPC_LWL:
30405    case OPC_LWR:
30406        check_insn_opc_removed(ctx, ISA_MIPS32R6);
30407         /* Fallthrough */
30408    case OPC_LB:
30409    case OPC_LH:
30410    case OPC_LW:
30411    case OPC_LWPC:
30412    case OPC_LBU:
30413    case OPC_LHU:
30414         gen_ld(ctx, op, rt, rs, imm);
30415         break;
30416    case OPC_SWL:
30417    case OPC_SWR:
30418        check_insn_opc_removed(ctx, ISA_MIPS32R6);
30419        /* fall through */
30420    case OPC_SB:
30421    case OPC_SH:
30422    case OPC_SW:
30423         gen_st(ctx, op, rt, rs, imm);
30424         break;
30425    case OPC_SC:
30426        check_insn(ctx, ISA_MIPS2);
30427         check_insn_opc_removed(ctx, ISA_MIPS32R6);
30428        if (ctx->insn_flags & INSN_R5900) {
30429            check_insn_opc_user_only(ctx, INSN_R5900);
30430        }
30431        gen_st_cond(ctx, rt, rs, imm, MO_TESL, false);
30432        break;
30433    case OPC_CACHE:
30434        check_insn_opc_removed(ctx, ISA_MIPS32R6);
30435        check_cp0_enabled(ctx);
30436        check_insn(ctx, ISA_MIPS3 | ISA_MIPS32);
30437        if (ctx->hflags & MIPS_HFLAG_ITC_CACHE) {
30438            gen_cache_operation(ctx, rt, rs, imm);
30439        }
30440        /* Treat as NOP. */
30441        break;
30442    case OPC_PREF:
30443        check_insn_opc_removed(ctx, ISA_MIPS32R6);
30444        if (ctx->insn_flags & INSN_R5900) {
30445            /* Treat as NOP. */
30446        } else {
30447            check_insn(ctx, ISA_MIPS4 | ISA_MIPS32);
30448            /* Treat as NOP. */
30449        }
30450        break;
30451
30452    /* Floating point (COP1). */
30453    case OPC_LWC1:
30454    case OPC_LDC1:
30455    case OPC_SWC1:
30456    case OPC_SDC1:
30457        gen_cop1_ldst(ctx, op, rt, rs, imm);
30458        break;
30459
30460    case OPC_CP1:
30461        op1 = MASK_CP1(ctx->opcode);
30462
30463        switch (op1) {
30464        case OPC_MFHC1:
30465        case OPC_MTHC1:
30466            check_cp1_enabled(ctx);
30467            check_insn(ctx, ISA_MIPS32R2);
30468            /* fall through */
30469        case OPC_MFC1:
30470        case OPC_CFC1:
30471        case OPC_MTC1:
30472        case OPC_CTC1:
30473            check_cp1_enabled(ctx);
30474            gen_cp1(ctx, op1, rt, rd);
30475            break;
30476#if defined(TARGET_MIPS64)
30477        case OPC_DMFC1:
30478        case OPC_DMTC1:
30479            check_cp1_enabled(ctx);
30480            check_insn(ctx, ISA_MIPS3);
30481            check_mips_64(ctx);
30482            gen_cp1(ctx, op1, rt, rd);
30483            break;
30484#endif
30485        case OPC_BC1EQZ: /* OPC_BC1ANY2 */
30486            check_cp1_enabled(ctx);
30487            if (ctx->insn_flags & ISA_MIPS32R6) {
30488                /* OPC_BC1EQZ */
30489                gen_compute_branch1_r6(ctx, MASK_CP1(ctx->opcode),
30490                                       rt, imm << 2, 4);
30491            } else {
30492                /* OPC_BC1ANY2 */
30493                check_cop1x(ctx);
30494                check_insn(ctx, ASE_MIPS3D);
30495                gen_compute_branch1(ctx, MASK_BC1(ctx->opcode),
30496                                    (rt >> 2) & 0x7, imm << 2);
30497            }
30498            break;
30499        case OPC_BC1NEZ:
30500            check_cp1_enabled(ctx);
30501            check_insn(ctx, ISA_MIPS32R6);
30502            gen_compute_branch1_r6(ctx, MASK_CP1(ctx->opcode),
30503                                   rt, imm << 2, 4);
30504            break;
30505        case OPC_BC1ANY4:
30506            check_cp1_enabled(ctx);
30507            check_insn_opc_removed(ctx, ISA_MIPS32R6);
30508            check_cop1x(ctx);
30509            check_insn(ctx, ASE_MIPS3D);
30510            /* fall through */
30511        case OPC_BC1:
30512            check_cp1_enabled(ctx);
30513            check_insn_opc_removed(ctx, ISA_MIPS32R6);
30514            gen_compute_branch1(ctx, MASK_BC1(ctx->opcode),
30515                                (rt >> 2) & 0x7, imm << 2);
30516            break;
30517        case OPC_PS_FMT:
30518            check_ps(ctx);
30519            /* fall through */
30520        case OPC_S_FMT:
30521        case OPC_D_FMT:
30522            check_cp1_enabled(ctx);
30523            gen_farith(ctx, ctx->opcode & FOP(0x3f, 0x1f), rt, rd, sa,
30524                       (imm >> 8) & 0x7);
30525            break;
30526        case OPC_W_FMT:
30527        case OPC_L_FMT:
30528        {
30529            int r6_op = ctx->opcode & FOP(0x3f, 0x1f);
30530            check_cp1_enabled(ctx);
30531            if (ctx->insn_flags & ISA_MIPS32R6) {
30532                switch (r6_op) {
30533                case R6_OPC_CMP_AF_S:
30534                case R6_OPC_CMP_UN_S:
30535                case R6_OPC_CMP_EQ_S:
30536                case R6_OPC_CMP_UEQ_S:
30537                case R6_OPC_CMP_LT_S:
30538                case R6_OPC_CMP_ULT_S:
30539                case R6_OPC_CMP_LE_S:
30540                case R6_OPC_CMP_ULE_S:
30541                case R6_OPC_CMP_SAF_S:
30542                case R6_OPC_CMP_SUN_S:
30543                case R6_OPC_CMP_SEQ_S:
30544                case R6_OPC_CMP_SEUQ_S:
30545                case R6_OPC_CMP_SLT_S:
30546                case R6_OPC_CMP_SULT_S:
30547                case R6_OPC_CMP_SLE_S:
30548                case R6_OPC_CMP_SULE_S:
30549                case R6_OPC_CMP_OR_S:
30550                case R6_OPC_CMP_UNE_S:
30551                case R6_OPC_CMP_NE_S:
30552                case R6_OPC_CMP_SOR_S:
30553                case R6_OPC_CMP_SUNE_S:
30554                case R6_OPC_CMP_SNE_S:
30555                    gen_r6_cmp_s(ctx, ctx->opcode & 0x1f, rt, rd, sa);
30556                    break;
30557                case R6_OPC_CMP_AF_D:
30558                case R6_OPC_CMP_UN_D:
30559                case R6_OPC_CMP_EQ_D:
30560                case R6_OPC_CMP_UEQ_D:
30561                case R6_OPC_CMP_LT_D:
30562                case R6_OPC_CMP_ULT_D:
30563                case R6_OPC_CMP_LE_D:
30564                case R6_OPC_CMP_ULE_D:
30565                case R6_OPC_CMP_SAF_D:
30566                case R6_OPC_CMP_SUN_D:
30567                case R6_OPC_CMP_SEQ_D:
30568                case R6_OPC_CMP_SEUQ_D:
30569                case R6_OPC_CMP_SLT_D:
30570                case R6_OPC_CMP_SULT_D:
30571                case R6_OPC_CMP_SLE_D:
30572                case R6_OPC_CMP_SULE_D:
30573                case R6_OPC_CMP_OR_D:
30574                case R6_OPC_CMP_UNE_D:
30575                case R6_OPC_CMP_NE_D:
30576                case R6_OPC_CMP_SOR_D:
30577                case R6_OPC_CMP_SUNE_D:
30578                case R6_OPC_CMP_SNE_D:
30579                    gen_r6_cmp_d(ctx, ctx->opcode & 0x1f, rt, rd, sa);
30580                    break;
30581                default:
30582                    gen_farith(ctx, ctx->opcode & FOP(0x3f, 0x1f),
30583                               rt, rd, sa, (imm >> 8) & 0x7);
30584
30585                    break;
30586                }
30587            } else {
30588                gen_farith(ctx, ctx->opcode & FOP(0x3f, 0x1f), rt, rd, sa,
30589                           (imm >> 8) & 0x7);
30590            }
30591            break;
30592        }
30593        case OPC_BZ_V:
30594        case OPC_BNZ_V:
30595        case OPC_BZ_B:
30596        case OPC_BZ_H:
30597        case OPC_BZ_W:
30598        case OPC_BZ_D:
30599        case OPC_BNZ_B:
30600        case OPC_BNZ_H:
30601        case OPC_BNZ_W:
30602        case OPC_BNZ_D:
30603            check_insn(ctx, ASE_MSA);
30604            gen_msa_branch(env, ctx, op1);
30605            break;
30606        default:
30607            MIPS_INVAL("cp1");
30608            generate_exception_end(ctx, EXCP_RI);
30609            break;
30610        }
30611        break;
30612
30613    /* Compact branches [R6] and COP2 [non-R6] */
30614    case OPC_BC: /* OPC_LWC2 */
30615    case OPC_BALC: /* OPC_SWC2 */
30616        if (ctx->insn_flags & ISA_MIPS32R6) {
30617            /* OPC_BC, OPC_BALC */
30618            gen_compute_compact_branch(ctx, op, 0, 0,
30619                                       sextract32(ctx->opcode << 2, 0, 28));
30620        } else {
30621            /* OPC_LWC2, OPC_SWC2 */
30622            /* COP2: Not implemented. */
30623            generate_exception_err(ctx, EXCP_CpU, 2);
30624        }
30625        break;
30626    case OPC_BEQZC: /* OPC_JIC, OPC_LDC2 */
30627    case OPC_BNEZC: /* OPC_JIALC, OPC_SDC2 */
30628        if (ctx->insn_flags & ISA_MIPS32R6) {
30629            if (rs != 0) {
30630                /* OPC_BEQZC, OPC_BNEZC */
30631                gen_compute_compact_branch(ctx, op, rs, 0,
30632                                           sextract32(ctx->opcode << 2, 0, 23));
30633            } else {
30634                /* OPC_JIC, OPC_JIALC */
30635                gen_compute_compact_branch(ctx, op, 0, rt, imm);
30636            }
30637        } else {
30638            /* OPC_LWC2, OPC_SWC2 */
30639            /* COP2: Not implemented. */
30640            generate_exception_err(ctx, EXCP_CpU, 2);
30641        }
30642        break;
30643    case OPC_CP2:
30644        check_insn(ctx, INSN_LOONGSON2F);
30645        /* Note that these instructions use different fields.  */
30646        gen_loongson_multimedia(ctx, sa, rd, rt);
30647        break;
30648
30649    case OPC_CP3:
30650        check_insn_opc_removed(ctx, ISA_MIPS32R6);
30651        if (ctx->CP0_Config1 & (1 << CP0C1_FP)) {
30652            check_cp1_enabled(ctx);
30653            op1 = MASK_CP3(ctx->opcode);
30654            switch (op1) {
30655            case OPC_LUXC1:
30656            case OPC_SUXC1:
30657                check_insn(ctx, ISA_MIPS5 | ISA_MIPS32R2);
30658                /* Fallthrough */
30659            case OPC_LWXC1:
30660            case OPC_LDXC1:
30661            case OPC_SWXC1:
30662            case OPC_SDXC1:
30663                check_insn(ctx, ISA_MIPS4 | ISA_MIPS32R2);
30664                gen_flt3_ldst(ctx, op1, sa, rd, rs, rt);
30665                break;
30666            case OPC_PREFX:
30667                check_insn(ctx, ISA_MIPS4 | ISA_MIPS32R2);
30668                /* Treat as NOP. */
30669                break;
30670            case OPC_ALNV_PS:
30671                check_insn(ctx, ISA_MIPS5 | ISA_MIPS32R2);
30672                /* Fallthrough */
30673            case OPC_MADD_S:
30674            case OPC_MADD_D:
30675            case OPC_MADD_PS:
30676            case OPC_MSUB_S:
30677            case OPC_MSUB_D:
30678            case OPC_MSUB_PS:
30679            case OPC_NMADD_S:
30680            case OPC_NMADD_D:
30681            case OPC_NMADD_PS:
30682            case OPC_NMSUB_S:
30683            case OPC_NMSUB_D:
30684            case OPC_NMSUB_PS:
30685                check_insn(ctx, ISA_MIPS4 | ISA_MIPS32R2);
30686                gen_flt3_arith(ctx, op1, sa, rs, rd, rt);
30687                break;
30688            default:
30689                MIPS_INVAL("cp3");
30690                generate_exception_end(ctx, EXCP_RI);
30691                break;
30692            }
30693        } else {
30694            generate_exception_err(ctx, EXCP_CpU, 1);
30695        }
30696        break;
30697
30698#if defined(TARGET_MIPS64)
30699    /* MIPS64 opcodes */
30700    case OPC_LLD:
30701        if (ctx->insn_flags & INSN_R5900) {
30702            check_insn_opc_user_only(ctx, INSN_R5900);
30703        }
30704        /* fall through */
30705    case OPC_LDL:
30706    case OPC_LDR:
30707        check_insn_opc_removed(ctx, ISA_MIPS32R6);
30708        /* fall through */
30709    case OPC_LWU:
30710    case OPC_LD:
30711        check_insn(ctx, ISA_MIPS3);
30712        check_mips_64(ctx);
30713        gen_ld(ctx, op, rt, rs, imm);
30714        break;
30715    case OPC_SDL:
30716    case OPC_SDR:
30717        check_insn_opc_removed(ctx, ISA_MIPS32R6);
30718        /* fall through */
30719    case OPC_SD:
30720        check_insn(ctx, ISA_MIPS3);
30721        check_mips_64(ctx);
30722        gen_st(ctx, op, rt, rs, imm);
30723        break;
30724    case OPC_SCD:
30725        check_insn_opc_removed(ctx, ISA_MIPS32R6);
30726        check_insn(ctx, ISA_MIPS3);
30727        if (ctx->insn_flags & INSN_R5900) {
30728            check_insn_opc_user_only(ctx, INSN_R5900);
30729        }
30730        check_mips_64(ctx);
30731        gen_st_cond(ctx, rt, rs, imm, MO_TEQ, false);
30732        break;
30733    case OPC_BNVC: /* OPC_BNEZALC, OPC_BNEC, OPC_DADDI */
30734        if (ctx->insn_flags & ISA_MIPS32R6) {
30735            /* OPC_BNVC, OPC_BNEZALC, OPC_BNEC */
30736            gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
30737        } else {
30738            /* OPC_DADDI */
30739            check_insn(ctx, ISA_MIPS3);
30740            check_mips_64(ctx);
30741            gen_arith_imm(ctx, op, rt, rs, imm);
30742        }
30743        break;
30744    case OPC_DADDIU:
30745        check_insn(ctx, ISA_MIPS3);
30746        check_mips_64(ctx);
30747        gen_arith_imm(ctx, op, rt, rs, imm);
30748        break;
30749#else
30750    case OPC_BNVC: /* OPC_BNEZALC, OPC_BNEC */
30751        if (ctx->insn_flags & ISA_MIPS32R6) {
30752            gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
30753        } else {
30754            MIPS_INVAL("major opcode");
30755            generate_exception_end(ctx, EXCP_RI);
30756        }
30757        break;
30758#endif
30759    case OPC_DAUI: /* OPC_JALX */
30760        if (ctx->insn_flags & ISA_MIPS32R6) {
30761#if defined(TARGET_MIPS64)
30762            /* OPC_DAUI */
30763            check_mips_64(ctx);
30764            if (rs == 0) {
30765                generate_exception(ctx, EXCP_RI);
30766            } else if (rt != 0) {
30767                TCGv t0 = tcg_temp_new();
30768                gen_load_gpr(t0, rs);
30769                tcg_gen_addi_tl(cpu_gpr[rt], t0, imm << 16);
30770                tcg_temp_free(t0);
30771            }
30772#else
30773            generate_exception_end(ctx, EXCP_RI);
30774            MIPS_INVAL("major opcode");
30775#endif
30776        } else {
30777            /* OPC_JALX */
30778            check_insn(ctx, ASE_MIPS16 | ASE_MICROMIPS);
30779            offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 2;
30780            gen_compute_branch(ctx, op, 4, rs, rt, offset, 4);
30781        }
30782        break;
30783    case OPC_MSA: /* OPC_MDMX */
30784        if (ctx->insn_flags & INSN_R5900) {
30785#if defined(TARGET_MIPS64)
30786            gen_mmi_lq(env, ctx);    /* MMI_OPC_LQ */
30787#endif
30788        } else {
30789            /* MDMX: Not implemented. */
30790            gen_msa(env, ctx);
30791        }
30792        break;
30793    case OPC_PCREL:
30794        check_insn(ctx, ISA_MIPS32R6);
30795        gen_pcrel(ctx, ctx->opcode, ctx->base.pc_next, rs);
30796        break;
30797    default:            /* Invalid */
30798        MIPS_INVAL("major opcode");
30799        generate_exception_end(ctx, EXCP_RI);
30800        break;
30801    }
30802}
30803
30804static void mips_tr_init_disas_context(DisasContextBase *dcbase, CPUState *cs)
30805{
30806    DisasContext *ctx = container_of(dcbase, DisasContext, base);
30807    CPUMIPSState *env = cs->env_ptr;
30808
30809    ctx->page_start = ctx->base.pc_first & TARGET_PAGE_MASK;
30810    ctx->saved_pc = -1;
30811    ctx->insn_flags = env->insn_flags;
30812    ctx->CP0_Config1 = env->CP0_Config1;
30813    ctx->CP0_Config2 = env->CP0_Config2;
30814    ctx->CP0_Config3 = env->CP0_Config3;
30815    ctx->CP0_Config5 = env->CP0_Config5;
30816    ctx->btarget = 0;
30817    ctx->kscrexist = (env->CP0_Config4 >> CP0C4_KScrExist) & 0xff;
30818    ctx->rxi = (env->CP0_Config3 >> CP0C3_RXI) & 1;
30819    ctx->ie = (env->CP0_Config4 >> CP0C4_IE) & 3;
30820    ctx->bi = (env->CP0_Config3 >> CP0C3_BI) & 1;
30821    ctx->bp = (env->CP0_Config3 >> CP0C3_BP) & 1;
30822    ctx->PAMask = env->PAMask;
30823    ctx->mvh = (env->CP0_Config5 >> CP0C5_MVH) & 1;
30824    ctx->eva = (env->CP0_Config5 >> CP0C5_EVA) & 1;
30825    ctx->sc = (env->CP0_Config3 >> CP0C3_SC) & 1;
30826    ctx->CP0_LLAddr_shift = env->CP0_LLAddr_shift;
30827    ctx->cmgcr = (env->CP0_Config3 >> CP0C3_CMGCR) & 1;
30828    /* Restore delay slot state from the tb context.  */
30829    ctx->hflags = (uint32_t)ctx->base.tb->flags; /* FIXME: maybe use 64 bits? */
30830    ctx->ulri = (env->CP0_Config3 >> CP0C3_ULRI) & 1;
30831    ctx->ps = ((env->active_fpu.fcr0 >> FCR0_PS) & 1) ||
30832             (env->insn_flags & (INSN_LOONGSON2E | INSN_LOONGSON2F));
30833    ctx->vp = (env->CP0_Config5 >> CP0C5_VP) & 1;
30834    ctx->mrp = (env->CP0_Config5 >> CP0C5_MRP) & 1;
30835    ctx->nan2008 = (env->active_fpu.fcr31 >> FCR31_NAN2008) & 1;
30836    ctx->abs2008 = (env->active_fpu.fcr31 >> FCR31_ABS2008) & 1;
30837    ctx->mi = (env->CP0_Config5 >> CP0C5_MI) & 1;
30838    ctx->gi = (env->CP0_Config5 >> CP0C5_GI) & 3;
30839    restore_cpu_state(env, ctx);
30840#ifdef CONFIG_USER_ONLY
30841        ctx->mem_idx = MIPS_HFLAG_UM;
30842#else
30843        ctx->mem_idx = hflags_mmu_index(ctx->hflags);
30844#endif
30845    ctx->default_tcg_memop_mask = (ctx->insn_flags & ISA_MIPS32R6) ?
30846                                  MO_UNALN : MO_ALIGN;
30847
30848    LOG_DISAS("\ntb %p idx %d hflags %04x\n", ctx->base.tb, ctx->mem_idx,
30849              ctx->hflags);
30850}
30851
30852static void mips_tr_tb_start(DisasContextBase *dcbase, CPUState *cs)
30853{
30854}
30855
30856static void mips_tr_insn_start(DisasContextBase *dcbase, CPUState *cs)
30857{
30858    DisasContext *ctx = container_of(dcbase, DisasContext, base);
30859
30860    tcg_gen_insn_start(ctx->base.pc_next, ctx->hflags & MIPS_HFLAG_BMASK,
30861                       ctx->btarget);
30862}
30863
30864static bool mips_tr_breakpoint_check(DisasContextBase *dcbase, CPUState *cs,
30865                                     const CPUBreakpoint *bp)
30866{
30867    DisasContext *ctx = container_of(dcbase, DisasContext, base);
30868
30869    save_cpu_state(ctx, 1);
30870    ctx->base.is_jmp = DISAS_NORETURN;
30871    gen_helper_raise_exception_debug(cpu_env);
30872    /*
30873     * The address covered by the breakpoint must be included in
30874     * [tb->pc, tb->pc + tb->size) in order to for it to be
30875     * properly cleared -- thus we increment the PC here so that
30876     * the logic setting tb->size below does the right thing.
30877     */
30878    ctx->base.pc_next += 4;
30879    return true;
30880}
30881
30882static void mips_tr_translate_insn(DisasContextBase *dcbase, CPUState *cs)
30883{
30884    CPUMIPSState *env = cs->env_ptr;
30885    DisasContext *ctx = container_of(dcbase, DisasContext, base);
30886    int insn_bytes;
30887    int is_slot;
30888
30889    is_slot = ctx->hflags & MIPS_HFLAG_BMASK;
30890    if (ctx->insn_flags & ISA_NANOMIPS32) {
30891        ctx->opcode = cpu_lduw_code(env, ctx->base.pc_next);
30892        insn_bytes = decode_nanomips_opc(env, ctx);
30893    } else if (!(ctx->hflags & MIPS_HFLAG_M16)) {
30894        ctx->opcode = cpu_ldl_code(env, ctx->base.pc_next);
30895        insn_bytes = 4;
30896        decode_opc(env, ctx);
30897    } else if (ctx->insn_flags & ASE_MICROMIPS) {
30898        ctx->opcode = cpu_lduw_code(env, ctx->base.pc_next);
30899        insn_bytes = decode_micromips_opc(env, ctx);
30900    } else if (ctx->insn_flags & ASE_MIPS16) {
30901        ctx->opcode = cpu_lduw_code(env, ctx->base.pc_next);
30902        insn_bytes = decode_mips16_opc(env, ctx);
30903    } else {
30904        generate_exception_end(ctx, EXCP_RI);
30905        g_assert(ctx->base.is_jmp == DISAS_NORETURN);
30906        return;
30907    }
30908
30909    if (ctx->hflags & MIPS_HFLAG_BMASK) {
30910        if (!(ctx->hflags & (MIPS_HFLAG_BDS16 | MIPS_HFLAG_BDS32 |
30911                             MIPS_HFLAG_FBNSLOT))) {
30912            /*
30913             * Force to generate branch as there is neither delay nor
30914             * forbidden slot.
30915             */
30916            is_slot = 1;
30917        }
30918        if ((ctx->hflags & MIPS_HFLAG_M16) &&
30919            (ctx->hflags & MIPS_HFLAG_FBNSLOT)) {
30920            /*
30921             * Force to generate branch as microMIPS R6 doesn't restrict
30922             * branches in the forbidden slot.
30923             */
30924            is_slot = 1;
30925        }
30926    }
30927    if (is_slot) {
30928        gen_branch(ctx, insn_bytes);
30929    }
30930    ctx->base.pc_next += insn_bytes;
30931
30932    if (ctx->base.is_jmp != DISAS_NEXT) {
30933        return;
30934    }
30935    /*
30936     * Execute a branch and its delay slot as a single instruction.
30937     * This is what GDB expects and is consistent with what the
30938     * hardware does (e.g. if a delay slot instruction faults, the
30939     * reported PC is the PC of the branch).
30940     */
30941    if (ctx->base.singlestep_enabled &&
30942        (ctx->hflags & MIPS_HFLAG_BMASK) == 0) {
30943        ctx->base.is_jmp = DISAS_TOO_MANY;
30944    }
30945    if (ctx->base.pc_next - ctx->page_start >= TARGET_PAGE_SIZE) {
30946        ctx->base.is_jmp = DISAS_TOO_MANY;
30947    }
30948}
30949
30950static void mips_tr_tb_stop(DisasContextBase *dcbase, CPUState *cs)
30951{
30952    DisasContext *ctx = container_of(dcbase, DisasContext, base);
30953
30954    if (ctx->base.singlestep_enabled && ctx->base.is_jmp != DISAS_NORETURN) {
30955        save_cpu_state(ctx, ctx->base.is_jmp != DISAS_EXIT);
30956        gen_helper_raise_exception_debug(cpu_env);
30957    } else {
30958        switch (ctx->base.is_jmp) {
30959        case DISAS_STOP:
30960            gen_save_pc(ctx->base.pc_next);
30961            tcg_gen_lookup_and_goto_ptr();
30962            break;
30963        case DISAS_NEXT:
30964        case DISAS_TOO_MANY:
30965            save_cpu_state(ctx, 0);
30966            gen_goto_tb(ctx, 0, ctx->base.pc_next);
30967            break;
30968        case DISAS_EXIT:
30969            tcg_gen_exit_tb(NULL, 0);
30970            break;
30971        case DISAS_NORETURN:
30972            break;
30973        default:
30974            g_assert_not_reached();
30975        }
30976    }
30977}
30978
30979static void mips_tr_disas_log(const DisasContextBase *dcbase, CPUState *cs)
30980{
30981    qemu_log("IN: %s\n", lookup_symbol(dcbase->pc_first));
30982    log_target_disas(cs, dcbase->pc_first, dcbase->tb->size);
30983}
30984
30985static const TranslatorOps mips_tr_ops = {
30986    .init_disas_context = mips_tr_init_disas_context,
30987    .tb_start           = mips_tr_tb_start,
30988    .insn_start         = mips_tr_insn_start,
30989    .breakpoint_check   = mips_tr_breakpoint_check,
30990    .translate_insn     = mips_tr_translate_insn,
30991    .tb_stop            = mips_tr_tb_stop,
30992    .disas_log          = mips_tr_disas_log,
30993};
30994
30995void gen_intermediate_code(CPUState *cs, TranslationBlock *tb, int max_insns)
30996{
30997    DisasContext ctx;
30998
30999    translator_loop(&mips_tr_ops, &ctx.base, cs, tb, max_insns);
31000}
31001
31002static void fpu_dump_state(CPUMIPSState *env, FILE * f, int flags)
31003{
31004    int i;
31005    int is_fpu64 = !!(env->hflags & MIPS_HFLAG_F64);
31006
31007#define printfpr(fp)                                                    \
31008    do {                                                                \
31009        if (is_fpu64)                                                   \
31010            qemu_fprintf(f, "w:%08x d:%016" PRIx64                      \
31011                         " fd:%13g fs:%13g psu: %13g\n",                \
31012                         (fp)->w[FP_ENDIAN_IDX], (fp)->d,               \
31013                         (double)(fp)->fd,                              \
31014                         (double)(fp)->fs[FP_ENDIAN_IDX],               \
31015                         (double)(fp)->fs[!FP_ENDIAN_IDX]);             \
31016        else {                                                          \
31017            fpr_t tmp;                                                  \
31018            tmp.w[FP_ENDIAN_IDX] = (fp)->w[FP_ENDIAN_IDX];              \
31019            tmp.w[!FP_ENDIAN_IDX] = ((fp) + 1)->w[FP_ENDIAN_IDX];       \
31020            qemu_fprintf(f, "w:%08x d:%016" PRIx64                      \
31021                         " fd:%13g fs:%13g psu:%13g\n",                 \
31022                         tmp.w[FP_ENDIAN_IDX], tmp.d,                   \
31023                         (double)tmp.fd,                                \
31024                         (double)tmp.fs[FP_ENDIAN_IDX],                 \
31025                         (double)tmp.fs[!FP_ENDIAN_IDX]);               \
31026        }                                                               \
31027    } while (0)
31028
31029
31030    qemu_fprintf(f,
31031                 "CP1 FCR0 0x%08x  FCR31 0x%08x  SR.FR %d  fp_status 0x%02x\n",
31032                 env->active_fpu.fcr0, env->active_fpu.fcr31, is_fpu64,
31033                 get_float_exception_flags(&env->active_fpu.fp_status));
31034    for (i = 0; i < 32; (is_fpu64) ? i++ : (i += 2)) {
31035        qemu_fprintf(f, "%3s: ", fregnames[i]);
31036        printfpr(&env->active_fpu.fpr[i]);
31037    }
31038
31039#undef printfpr
31040}
31041
31042void mips_cpu_dump_state(CPUState *cs, FILE *f, int flags)
31043{
31044    MIPSCPU *cpu = MIPS_CPU(cs);
31045    CPUMIPSState *env = &cpu->env;
31046    int i;
31047
31048    qemu_fprintf(f, "pc=0x" TARGET_FMT_lx " HI=0x" TARGET_FMT_lx
31049                 " LO=0x" TARGET_FMT_lx " ds %04x "
31050                 TARGET_FMT_lx " " TARGET_FMT_ld "\n",
31051                 env->active_tc.PC, env->active_tc.HI[0], env->active_tc.LO[0],
31052                 env->hflags, env->btarget, env->bcond);
31053    for (i = 0; i < 32; i++) {
31054        if ((i & 3) == 0) {
31055            qemu_fprintf(f, "GPR%02d:", i);
31056        }
31057        qemu_fprintf(f, " %s " TARGET_FMT_lx,
31058                     regnames[i], env->active_tc.gpr[i]);
31059        if ((i & 3) == 3) {
31060            qemu_fprintf(f, "\n");
31061        }
31062    }
31063
31064    qemu_fprintf(f, "CP0 Status  0x%08x Cause   0x%08x EPC    0x"
31065                 TARGET_FMT_lx "\n",
31066                 env->CP0_Status, env->CP0_Cause, env->CP0_EPC);
31067    qemu_fprintf(f, "    Config0 0x%08x Config1 0x%08x LLAddr 0x%016"
31068                 PRIx64 "\n",
31069                 env->CP0_Config0, env->CP0_Config1, env->CP0_LLAddr);
31070    qemu_fprintf(f, "    Config2 0x%08x Config3 0x%08x\n",
31071                 env->CP0_Config2, env->CP0_Config3);
31072    qemu_fprintf(f, "    Config4 0x%08x Config5 0x%08x\n",
31073                 env->CP0_Config4, env->CP0_Config5);
31074    if ((flags & CPU_DUMP_FPU) && (env->hflags & MIPS_HFLAG_FPU)) {
31075        fpu_dump_state(env, f, flags);
31076    }
31077}
31078
31079void mips_tcg_init(void)
31080{
31081    int i;
31082
31083    cpu_gpr[0] = NULL;
31084    for (i = 1; i < 32; i++)
31085        cpu_gpr[i] = tcg_global_mem_new(cpu_env,
31086                                        offsetof(CPUMIPSState,
31087                                                 active_tc.gpr[i]),
31088                                        regnames[i]);
31089
31090    for (i = 0; i < 32; i++) {
31091        int off = offsetof(CPUMIPSState, active_fpu.fpr[i].wr.d[0]);
31092        msa_wr_d[i * 2] =
31093                tcg_global_mem_new_i64(cpu_env, off, msaregnames[i * 2]);
31094        /*
31095         * The scalar floating-point unit (FPU) registers are mapped on
31096         * the MSA vector registers.
31097         */
31098        fpu_f64[i] = msa_wr_d[i * 2];
31099        off = offsetof(CPUMIPSState, active_fpu.fpr[i].wr.d[1]);
31100        msa_wr_d[i * 2 + 1] =
31101                tcg_global_mem_new_i64(cpu_env, off, msaregnames[i * 2 + 1]);
31102    }
31103
31104    cpu_PC = tcg_global_mem_new(cpu_env,
31105                                offsetof(CPUMIPSState, active_tc.PC), "PC");
31106    for (i = 0; i < MIPS_DSP_ACC; i++) {
31107        cpu_HI[i] = tcg_global_mem_new(cpu_env,
31108                                       offsetof(CPUMIPSState, active_tc.HI[i]),
31109                                       regnames_HI[i]);
31110        cpu_LO[i] = tcg_global_mem_new(cpu_env,
31111                                       offsetof(CPUMIPSState, active_tc.LO[i]),
31112                                       regnames_LO[i]);
31113    }
31114    cpu_dspctrl = tcg_global_mem_new(cpu_env,
31115                                     offsetof(CPUMIPSState,
31116                                              active_tc.DSPControl),
31117                                     "DSPControl");
31118    bcond = tcg_global_mem_new(cpu_env,
31119                               offsetof(CPUMIPSState, bcond), "bcond");
31120    btarget = tcg_global_mem_new(cpu_env,
31121                                 offsetof(CPUMIPSState, btarget), "btarget");
31122    hflags = tcg_global_mem_new_i32(cpu_env,
31123                                    offsetof(CPUMIPSState, hflags), "hflags");
31124
31125    fpu_fcr0 = tcg_global_mem_new_i32(cpu_env,
31126                                      offsetof(CPUMIPSState, active_fpu.fcr0),
31127                                      "fcr0");
31128    fpu_fcr31 = tcg_global_mem_new_i32(cpu_env,
31129                                       offsetof(CPUMIPSState, active_fpu.fcr31),
31130                                       "fcr31");
31131    cpu_lladdr = tcg_global_mem_new(cpu_env, offsetof(CPUMIPSState, lladdr),
31132                                    "lladdr");
31133    cpu_llval = tcg_global_mem_new(cpu_env, offsetof(CPUMIPSState, llval),
31134                                   "llval");
31135
31136#if defined(TARGET_MIPS64)
31137    cpu_mmr[0] = NULL;
31138    for (i = 1; i < 32; i++) {
31139        cpu_mmr[i] = tcg_global_mem_new_i64(cpu_env,
31140                                            offsetof(CPUMIPSState,
31141                                                     active_tc.mmr[i]),
31142                                            regnames[i]);
31143    }
31144#endif
31145
31146#if !defined(TARGET_MIPS64)
31147    for (i = 0; i < NUMBER_OF_MXU_REGISTERS - 1; i++) {
31148        mxu_gpr[i] = tcg_global_mem_new(cpu_env,
31149                                        offsetof(CPUMIPSState,
31150                                                 active_tc.mxu_gpr[i]),
31151                                        mxuregnames[i]);
31152    }
31153
31154    mxu_CR = tcg_global_mem_new(cpu_env,
31155                                offsetof(CPUMIPSState, active_tc.mxu_cr),
31156                                mxuregnames[NUMBER_OF_MXU_REGISTERS - 1]);
31157#endif
31158}
31159
31160#include "translate_init.inc.c"
31161
31162void cpu_mips_realize_env(CPUMIPSState *env)
31163{
31164    env->exception_base = (int32_t)0xBFC00000;
31165
31166#ifndef CONFIG_USER_ONLY
31167    mmu_init(env, env->cpu_model);
31168#endif
31169    fpu_init(env, env->cpu_model);
31170    mvp_init(env, env->cpu_model);
31171}
31172
31173bool cpu_supports_cps_smp(const char *cpu_type)
31174{
31175    const MIPSCPUClass *mcc = MIPS_CPU_CLASS(object_class_by_name(cpu_type));
31176    return (mcc->cpu_def->CP0_Config3 & (1 << CP0C3_CMGCR)) != 0;
31177}
31178
31179bool cpu_supports_isa(const char *cpu_type, uint64_t isa)
31180{
31181    const MIPSCPUClass *mcc = MIPS_CPU_CLASS(object_class_by_name(cpu_type));
31182    return (mcc->cpu_def->insn_flags & isa) != 0;
31183}
31184
31185void cpu_set_exception_base(int vp_index, target_ulong address)
31186{
31187    MIPSCPU *vp = MIPS_CPU(qemu_get_cpu(vp_index));
31188    vp->env.exception_base = address;
31189}
31190
31191void cpu_state_reset(CPUMIPSState *env)
31192{
31193    CPUState *cs = env_cpu(env);
31194
31195    /* Reset registers to their default values */
31196    env->CP0_PRid = env->cpu_model->CP0_PRid;
31197    env->CP0_Config0 = env->cpu_model->CP0_Config0;
31198#ifdef TARGET_WORDS_BIGENDIAN
31199    env->CP0_Config0 |= (1 << CP0C0_BE);
31200#endif
31201    env->CP0_Config1 = env->cpu_model->CP0_Config1;
31202    env->CP0_Config2 = env->cpu_model->CP0_Config2;
31203    env->CP0_Config3 = env->cpu_model->CP0_Config3;
31204    env->CP0_Config4 = env->cpu_model->CP0_Config4;
31205    env->CP0_Config4_rw_bitmask = env->cpu_model->CP0_Config4_rw_bitmask;
31206    env->CP0_Config5 = env->cpu_model->CP0_Config5;
31207    env->CP0_Config5_rw_bitmask = env->cpu_model->CP0_Config5_rw_bitmask;
31208    env->CP0_Config6 = env->cpu_model->CP0_Config6;
31209    env->CP0_Config7 = env->cpu_model->CP0_Config7;
31210    env->CP0_LLAddr_rw_bitmask = env->cpu_model->CP0_LLAddr_rw_bitmask
31211                                 << env->cpu_model->CP0_LLAddr_shift;
31212    env->CP0_LLAddr_shift = env->cpu_model->CP0_LLAddr_shift;
31213    env->SYNCI_Step = env->cpu_model->SYNCI_Step;
31214    env->CCRes = env->cpu_model->CCRes;
31215    env->CP0_Status_rw_bitmask = env->cpu_model->CP0_Status_rw_bitmask;
31216    env->CP0_TCStatus_rw_bitmask = env->cpu_model->CP0_TCStatus_rw_bitmask;
31217    env->CP0_SRSCtl = env->cpu_model->CP0_SRSCtl;
31218    env->current_tc = 0;
31219    env->SEGBITS = env->cpu_model->SEGBITS;
31220    env->SEGMask = (target_ulong)((1ULL << env->cpu_model->SEGBITS) - 1);
31221#if defined(TARGET_MIPS64)
31222    if (env->cpu_model->insn_flags & ISA_MIPS3) {
31223        env->SEGMask |= 3ULL << 62;
31224    }
31225#endif
31226    env->PABITS = env->cpu_model->PABITS;
31227    env->CP0_SRSConf0_rw_bitmask = env->cpu_model->CP0_SRSConf0_rw_bitmask;
31228    env->CP0_SRSConf0 = env->cpu_model->CP0_SRSConf0;
31229    env->CP0_SRSConf1_rw_bitmask = env->cpu_model->CP0_SRSConf1_rw_bitmask;
31230    env->CP0_SRSConf1 = env->cpu_model->CP0_SRSConf1;
31231    env->CP0_SRSConf2_rw_bitmask = env->cpu_model->CP0_SRSConf2_rw_bitmask;
31232    env->CP0_SRSConf2 = env->cpu_model->CP0_SRSConf2;
31233    env->CP0_SRSConf3_rw_bitmask = env->cpu_model->CP0_SRSConf3_rw_bitmask;
31234    env->CP0_SRSConf3 = env->cpu_model->CP0_SRSConf3;
31235    env->CP0_SRSConf4_rw_bitmask = env->cpu_model->CP0_SRSConf4_rw_bitmask;
31236    env->CP0_SRSConf4 = env->cpu_model->CP0_SRSConf4;
31237    env->CP0_PageGrain_rw_bitmask = env->cpu_model->CP0_PageGrain_rw_bitmask;
31238    env->CP0_PageGrain = env->cpu_model->CP0_PageGrain;
31239    env->CP0_EBaseWG_rw_bitmask = env->cpu_model->CP0_EBaseWG_rw_bitmask;
31240    env->active_fpu.fcr0 = env->cpu_model->CP1_fcr0;
31241    env->active_fpu.fcr31_rw_bitmask = env->cpu_model->CP1_fcr31_rw_bitmask;
31242    env->active_fpu.fcr31 = env->cpu_model->CP1_fcr31;
31243    env->msair = env->cpu_model->MSAIR;
31244    env->insn_flags = env->cpu_model->insn_flags;
31245
31246#if defined(CONFIG_USER_ONLY)
31247    env->CP0_Status = (MIPS_HFLAG_UM << CP0St_KSU);
31248# ifdef TARGET_MIPS64
31249    /* Enable 64-bit register mode.  */
31250    env->CP0_Status |= (1 << CP0St_PX);
31251# endif
31252# ifdef TARGET_ABI_MIPSN64
31253    /* Enable 64-bit address mode.  */
31254    env->CP0_Status |= (1 << CP0St_UX);
31255# endif
31256    /*
31257     * Enable access to the CPUNum, SYNCI_Step, CC, and CCRes RDHWR
31258     * hardware registers.
31259     */
31260    env->CP0_HWREna |= 0x0000000F;
31261    if (env->CP0_Config1 & (1 << CP0C1_FP)) {
31262        env->CP0_Status |= (1 << CP0St_CU1);
31263    }
31264    if (env->CP0_Config3 & (1 << CP0C3_DSPP)) {
31265        env->CP0_Status |= (1 << CP0St_MX);
31266    }
31267# if defined(TARGET_MIPS64)
31268    /* For MIPS64, init FR bit to 1 if FPU unit is there and bit is writable. */
31269    if ((env->CP0_Config1 & (1 << CP0C1_FP)) &&
31270        (env->CP0_Status_rw_bitmask & (1 << CP0St_FR))) {
31271        env->CP0_Status |= (1 << CP0St_FR);
31272    }
31273# endif
31274#else
31275    if (env->hflags & MIPS_HFLAG_BMASK) {
31276        /*
31277         * If the exception was raised from a delay slot,
31278         * come back to the jump.
31279         */
31280        env->CP0_ErrorEPC = (env->active_tc.PC
31281                             - (env->hflags & MIPS_HFLAG_B16 ? 2 : 4));
31282    } else {
31283        env->CP0_ErrorEPC = env->active_tc.PC;
31284    }
31285    env->active_tc.PC = env->exception_base;
31286    env->CP0_Random = env->tlb->nb_tlb - 1;
31287    env->tlb->tlb_in_use = env->tlb->nb_tlb;
31288    env->CP0_Wired = 0;
31289    env->CP0_GlobalNumber = (cs->cpu_index & 0xFF) << CP0GN_VPId;
31290    env->CP0_EBase = (cs->cpu_index & 0x3FF);
31291    if (mips_um_ksegs_enabled()) {
31292        env->CP0_EBase |= 0x40000000;
31293    } else {
31294        env->CP0_EBase |= (int32_t)0x80000000;
31295    }
31296    if (env->CP0_Config3 & (1 << CP0C3_CMGCR)) {
31297        env->CP0_CMGCRBase = 0x1fbf8000 >> 4;
31298    }
31299    env->CP0_EntryHi_ASID_mask = (env->CP0_Config5 & (1 << CP0C5_MI)) ?
31300            0x0 : (env->CP0_Config4 & (1 << CP0C4_AE)) ? 0x3ff : 0xff;
31301    env->CP0_Status = (1 << CP0St_BEV) | (1 << CP0St_ERL);
31302    /*
31303     * Vectored interrupts not implemented, timer on int 7,
31304     * no performance counters.
31305     */
31306    env->CP0_IntCtl = 0xe0000000;
31307    {
31308        int i;
31309
31310        for (i = 0; i < 7; i++) {
31311            env->CP0_WatchLo[i] = 0;
31312            env->CP0_WatchHi[i] = 0x80000000;
31313        }
31314        env->CP0_WatchLo[7] = 0;
31315        env->CP0_WatchHi[7] = 0;
31316    }
31317    /* Count register increments in debug mode, EJTAG version 1 */
31318    env->CP0_Debug = (1 << CP0DB_CNT) | (0x1 << CP0DB_VER);
31319
31320    cpu_mips_store_count(env, 1);
31321
31322    if (env->CP0_Config3 & (1 << CP0C3_MT)) {
31323        int i;
31324
31325        /* Only TC0 on VPE 0 starts as active.  */
31326        for (i = 0; i < ARRAY_SIZE(env->tcs); i++) {
31327            env->tcs[i].CP0_TCBind = cs->cpu_index << CP0TCBd_CurVPE;
31328            env->tcs[i].CP0_TCHalt = 1;
31329        }
31330        env->active_tc.CP0_TCHalt = 1;
31331        cs->halted = 1;
31332
31333        if (cs->cpu_index == 0) {
31334            /* VPE0 starts up enabled.  */
31335            env->mvp->CP0_MVPControl |= (1 << CP0MVPCo_EVP);
31336            env->CP0_VPEConf0 |= (1 << CP0VPEC0_MVP) | (1 << CP0VPEC0_VPA);
31337
31338            /* TC0 starts up unhalted.  */
31339            cs->halted = 0;
31340            env->active_tc.CP0_TCHalt = 0;
31341            env->tcs[0].CP0_TCHalt = 0;
31342            /* With thread 0 active.  */
31343            env->active_tc.CP0_TCStatus = (1 << CP0TCSt_A);
31344            env->tcs[0].CP0_TCStatus = (1 << CP0TCSt_A);
31345        }
31346    }
31347
31348    /*
31349     * Configure default legacy segmentation control. We use this regardless of
31350     * whether segmentation control is presented to the guest.
31351     */
31352    /* KSeg3 (seg0 0xE0000000..0xFFFFFFFF) */
31353    env->CP0_SegCtl0 =   (CP0SC_AM_MK << CP0SC_AM);
31354    /* KSeg2 (seg1 0xC0000000..0xDFFFFFFF) */
31355    env->CP0_SegCtl0 |= ((CP0SC_AM_MSK << CP0SC_AM)) << 16;
31356    /* KSeg1 (seg2 0xA0000000..0x9FFFFFFF) */
31357    env->CP0_SegCtl1 =   (0 << CP0SC_PA) | (CP0SC_AM_UK << CP0SC_AM) |
31358                         (2 << CP0SC_C);
31359    /* KSeg0 (seg3 0x80000000..0x9FFFFFFF) */
31360    env->CP0_SegCtl1 |= ((0 << CP0SC_PA) | (CP0SC_AM_UK << CP0SC_AM) |
31361                         (3 << CP0SC_C)) << 16;
31362    /* USeg (seg4 0x40000000..0x7FFFFFFF) */
31363    env->CP0_SegCtl2 =   (2 << CP0SC_PA) | (CP0SC_AM_MUSK << CP0SC_AM) |
31364                         (1 << CP0SC_EU) | (2 << CP0SC_C);
31365    /* USeg (seg5 0x00000000..0x3FFFFFFF) */
31366    env->CP0_SegCtl2 |= ((0 << CP0SC_PA) | (CP0SC_AM_MUSK << CP0SC_AM) |
31367                         (1 << CP0SC_EU) | (2 << CP0SC_C)) << 16;
31368    /* XKPhys (note, SegCtl2.XR = 0, so XAM won't be used) */
31369    env->CP0_SegCtl1 |= (CP0SC_AM_UK << CP0SC1_XAM);
31370#endif
31371    if ((env->insn_flags & ISA_MIPS32R6) &&
31372        (env->active_fpu.fcr0 & (1 << FCR0_F64))) {
31373        /* Status.FR = 0 mode in 64-bit FPU not allowed in R6 */
31374        env->CP0_Status |= (1 << CP0St_FR);
31375    }
31376
31377    if (env->insn_flags & ISA_MIPS32R6) {
31378        /* PTW  =  1 */
31379        env->CP0_PWSize = 0x40;
31380        /* GDI  = 12 */
31381        /* UDI  = 12 */
31382        /* MDI  = 12 */
31383        /* PRI  = 12 */
31384        /* PTEI =  2 */
31385        env->CP0_PWField = 0x0C30C302;
31386    } else {
31387        /* GDI  =  0 */
31388        /* UDI  =  0 */
31389        /* MDI  =  0 */
31390        /* PRI  =  0 */
31391        /* PTEI =  2 */
31392        env->CP0_PWField = 0x02;
31393    }
31394
31395    if (env->CP0_Config3 & (1 << CP0C3_ISA) & (1 << (CP0C3_ISA + 1))) {
31396        /*  microMIPS on reset when Config3.ISA is 3 */
31397        env->hflags |= MIPS_HFLAG_M16;
31398    }
31399
31400    /* MSA */
31401    if (env->CP0_Config3 & (1 << CP0C3_MSAP)) {
31402        msa_reset(env);
31403    }
31404
31405    compute_hflags(env);
31406    restore_fp_status(env);
31407    restore_pamask(env);
31408    cs->exception_index = EXCP_NONE;
31409
31410    if (semihosting_get_argc()) {
31411        /* UHI interface can be used to obtain argc and argv */
31412        env->active_tc.gpr[4] = -1;
31413    }
31414}
31415
31416void restore_state_to_opc(CPUMIPSState *env, TranslationBlock *tb,
31417                          target_ulong *data)
31418{
31419    env->active_tc.PC = data[0];
31420    env->hflags &= ~MIPS_HFLAG_BMASK;
31421    env->hflags |= data[1];
31422    switch (env->hflags & MIPS_HFLAG_BMASK_BASE) {
31423    case MIPS_HFLAG_BR:
31424        break;
31425    case MIPS_HFLAG_BC:
31426    case MIPS_HFLAG_BL:
31427    case MIPS_HFLAG_B:
31428        env->btarget = data[2];
31429        break;
31430    }
31431}
31432