qemu/target/mips/translate.c
<<
>>
Prefs
   1/*
   2 *  MIPS emulation for QEMU - main translation routines
   3 *
   4 *  Copyright (c) 2004-2005 Jocelyn Mayer
   5 *  Copyright (c) 2006 Marius Groeger (FPU operations)
   6 *  Copyright (c) 2006 Thiemo Seufer (MIPS32R2 support)
   7 *  Copyright (c) 2009 CodeSourcery (MIPS16 and microMIPS support)
   8 *  Copyright (c) 2012 Jia Liu & Dongxue Zhang (MIPS ASE DSP support)
   9 *
  10 * This library is free software; you can redistribute it and/or
  11 * modify it under the terms of the GNU Lesser General Public
  12 * License as published by the Free Software Foundation; either
  13 * version 2 of the License, or (at your option) any later version.
  14 *
  15 * This library is distributed in the hope that it will be useful,
  16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
  17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  18 * Lesser General Public License for more details.
  19 *
  20 * You should have received a copy of the GNU Lesser General Public
  21 * License along with this library; if not, see <http://www.gnu.org/licenses/>.
  22 */
  23
  24#include "qemu/osdep.h"
  25#include "cpu.h"
  26#include "internal.h"
  27#include "disas/disas.h"
  28#include "exec/exec-all.h"
  29#include "tcg-op.h"
  30#include "exec/cpu_ldst.h"
  31#include "hw/mips/cpudevs.h"
  32
  33#include "exec/helper-proto.h"
  34#include "exec/helper-gen.h"
  35#include "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
 392    /* Loongson 2E */
 393    OPC_MULT_G_2E   = 0x18 | OPC_SPECIAL3,
 394    OPC_MULTU_G_2E  = 0x19 | OPC_SPECIAL3,
 395    OPC_DIV_G_2E    = 0x1A | OPC_SPECIAL3,
 396    OPC_DIVU_G_2E   = 0x1B | OPC_SPECIAL3,
 397    OPC_DMULT_G_2E  = 0x1C | OPC_SPECIAL3,
 398    OPC_DMULTU_G_2E = 0x1D | OPC_SPECIAL3,
 399    OPC_DDIV_G_2E   = 0x1E | OPC_SPECIAL3,
 400    OPC_DDIVU_G_2E  = 0x1F | OPC_SPECIAL3,
 401    OPC_MOD_G_2E    = 0x22 | OPC_SPECIAL3,
 402    OPC_MODU_G_2E   = 0x23 | OPC_SPECIAL3,
 403    OPC_DMOD_G_2E   = 0x26 | OPC_SPECIAL3,
 404    OPC_DMODU_G_2E  = 0x27 | OPC_SPECIAL3,
 405
 406    /* MIPS DSP Load */
 407    OPC_LX_DSP         = 0x0A | OPC_SPECIAL3,
 408    /* MIPS DSP Arithmetic */
 409    OPC_ADDU_QB_DSP    = 0x10 | OPC_SPECIAL3,
 410    OPC_ADDU_OB_DSP    = 0x14 | OPC_SPECIAL3,
 411    OPC_ABSQ_S_PH_DSP  = 0x12 | OPC_SPECIAL3,
 412    OPC_ABSQ_S_QH_DSP  = 0x16 | OPC_SPECIAL3,
 413    /* OPC_ADDUH_QB_DSP is same as OPC_MULT_G_2E.  */
 414    /* OPC_ADDUH_QB_DSP   = 0x18 | OPC_SPECIAL3,  */
 415    OPC_CMPU_EQ_QB_DSP = 0x11 | OPC_SPECIAL3,
 416    OPC_CMPU_EQ_OB_DSP = 0x15 | OPC_SPECIAL3,
 417    /* MIPS DSP GPR-Based Shift Sub-class */
 418    OPC_SHLL_QB_DSP    = 0x13 | OPC_SPECIAL3,
 419    OPC_SHLL_OB_DSP    = 0x17 | OPC_SPECIAL3,
 420    /* MIPS DSP Multiply Sub-class insns */
 421    /* OPC_MUL_PH_DSP is same as OPC_ADDUH_QB_DSP.  */
 422    /* OPC_MUL_PH_DSP     = 0x18 | OPC_SPECIAL3,  */
 423    OPC_DPA_W_PH_DSP   = 0x30 | OPC_SPECIAL3,
 424    OPC_DPAQ_W_QH_DSP  = 0x34 | OPC_SPECIAL3,
 425    /* DSP Bit/Manipulation Sub-class */
 426    OPC_INSV_DSP       = 0x0C | OPC_SPECIAL3,
 427    OPC_DINSV_DSP      = 0x0D | OPC_SPECIAL3,
 428    /* MIPS DSP Append Sub-class */
 429    OPC_APPEND_DSP     = 0x31 | OPC_SPECIAL3,
 430    OPC_DAPPEND_DSP    = 0x35 | OPC_SPECIAL3,
 431    /* MIPS DSP Accumulator and DSPControl Access Sub-class */
 432    OPC_EXTR_W_DSP     = 0x38 | OPC_SPECIAL3,
 433    OPC_DEXTR_W_DSP    = 0x3C | OPC_SPECIAL3,
 434
 435    /* EVA */
 436    OPC_LWLE           = 0x19 | OPC_SPECIAL3,
 437    OPC_LWRE           = 0x1A | OPC_SPECIAL3,
 438    OPC_CACHEE         = 0x1B | OPC_SPECIAL3,
 439    OPC_SBE            = 0x1C | OPC_SPECIAL3,
 440    OPC_SHE            = 0x1D | OPC_SPECIAL3,
 441    OPC_SCE            = 0x1E | OPC_SPECIAL3,
 442    OPC_SWE            = 0x1F | OPC_SPECIAL3,
 443    OPC_SWLE           = 0x21 | OPC_SPECIAL3,
 444    OPC_SWRE           = 0x22 | OPC_SPECIAL3,
 445    OPC_PREFE          = 0x23 | OPC_SPECIAL3,
 446    OPC_LBUE           = 0x28 | OPC_SPECIAL3,
 447    OPC_LHUE           = 0x29 | OPC_SPECIAL3,
 448    OPC_LBE            = 0x2C | OPC_SPECIAL3,
 449    OPC_LHE            = 0x2D | OPC_SPECIAL3,
 450    OPC_LLE            = 0x2E | OPC_SPECIAL3,
 451    OPC_LWE            = 0x2F | OPC_SPECIAL3,
 452
 453    /* R6 */
 454    R6_OPC_PREF        = 0x35 | OPC_SPECIAL3,
 455    R6_OPC_CACHE       = 0x25 | OPC_SPECIAL3,
 456    R6_OPC_LL          = 0x36 | OPC_SPECIAL3,
 457    R6_OPC_SC          = 0x26 | OPC_SPECIAL3,
 458    R6_OPC_LLD         = 0x37 | OPC_SPECIAL3,
 459    R6_OPC_SCD         = 0x27 | OPC_SPECIAL3,
 460};
 461
 462/* BSHFL opcodes */
 463#define MASK_BSHFL(op)     MASK_SPECIAL3(op) | (op & (0x1F << 6))
 464
 465enum {
 466    OPC_WSBH      = (0x02 << 6) | OPC_BSHFL,
 467    OPC_SEB       = (0x10 << 6) | OPC_BSHFL,
 468    OPC_SEH       = (0x18 << 6) | OPC_BSHFL,
 469    OPC_ALIGN     = (0x08 << 6) | OPC_BSHFL, /* 010.bp (010.00 to 010.11) */
 470    OPC_ALIGN_1   = (0x09 << 6) | OPC_BSHFL,
 471    OPC_ALIGN_2   = (0x0A << 6) | OPC_BSHFL,
 472    OPC_ALIGN_3   = (0x0B << 6) | OPC_BSHFL,
 473    OPC_BITSWAP   = (0x00 << 6) | OPC_BSHFL  /* 00000 */
 474};
 475
 476/* DBSHFL opcodes */
 477#define MASK_DBSHFL(op)    MASK_SPECIAL3(op) | (op & (0x1F << 6))
 478
 479enum {
 480    OPC_DSBH       = (0x02 << 6) | OPC_DBSHFL,
 481    OPC_DSHD       = (0x05 << 6) | OPC_DBSHFL,
 482    OPC_DALIGN     = (0x08 << 6) | OPC_DBSHFL, /* 01.bp (01.000 to 01.111) */
 483    OPC_DALIGN_1   = (0x09 << 6) | OPC_DBSHFL,
 484    OPC_DALIGN_2   = (0x0A << 6) | OPC_DBSHFL,
 485    OPC_DALIGN_3   = (0x0B << 6) | OPC_DBSHFL,
 486    OPC_DALIGN_4   = (0x0C << 6) | OPC_DBSHFL,
 487    OPC_DALIGN_5   = (0x0D << 6) | OPC_DBSHFL,
 488    OPC_DALIGN_6   = (0x0E << 6) | OPC_DBSHFL,
 489    OPC_DALIGN_7   = (0x0F << 6) | OPC_DBSHFL,
 490    OPC_DBITSWAP   = (0x00 << 6) | OPC_DBSHFL, /* 00000 */
 491};
 492
 493/* MIPS DSP REGIMM opcodes */
 494enum {
 495    OPC_BPOSGE32 = (0x1C << 16) | OPC_REGIMM,
 496    OPC_BPOSGE64 = (0x1D << 16) | OPC_REGIMM,
 497};
 498
 499#define MASK_LX(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
 500/* MIPS DSP Load */
 501enum {
 502    OPC_LBUX = (0x06 << 6) | OPC_LX_DSP,
 503    OPC_LHX  = (0x04 << 6) | OPC_LX_DSP,
 504    OPC_LWX  = (0x00 << 6) | OPC_LX_DSP,
 505    OPC_LDX = (0x08 << 6) | OPC_LX_DSP,
 506};
 507
 508#define MASK_ADDU_QB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
 509enum {
 510    /* MIPS DSP Arithmetic Sub-class */
 511    OPC_ADDQ_PH        = (0x0A << 6) | OPC_ADDU_QB_DSP,
 512    OPC_ADDQ_S_PH      = (0x0E << 6) | OPC_ADDU_QB_DSP,
 513    OPC_ADDQ_S_W       = (0x16 << 6) | OPC_ADDU_QB_DSP,
 514    OPC_ADDU_QB        = (0x00 << 6) | OPC_ADDU_QB_DSP,
 515    OPC_ADDU_S_QB      = (0x04 << 6) | OPC_ADDU_QB_DSP,
 516    OPC_ADDU_PH        = (0x08 << 6) | OPC_ADDU_QB_DSP,
 517    OPC_ADDU_S_PH      = (0x0C << 6) | OPC_ADDU_QB_DSP,
 518    OPC_SUBQ_PH        = (0x0B << 6) | OPC_ADDU_QB_DSP,
 519    OPC_SUBQ_S_PH      = (0x0F << 6) | OPC_ADDU_QB_DSP,
 520    OPC_SUBQ_S_W       = (0x17 << 6) | OPC_ADDU_QB_DSP,
 521    OPC_SUBU_QB        = (0x01 << 6) | OPC_ADDU_QB_DSP,
 522    OPC_SUBU_S_QB      = (0x05 << 6) | OPC_ADDU_QB_DSP,
 523    OPC_SUBU_PH        = (0x09 << 6) | OPC_ADDU_QB_DSP,
 524    OPC_SUBU_S_PH      = (0x0D << 6) | OPC_ADDU_QB_DSP,
 525    OPC_ADDSC          = (0x10 << 6) | OPC_ADDU_QB_DSP,
 526    OPC_ADDWC          = (0x11 << 6) | OPC_ADDU_QB_DSP,
 527    OPC_MODSUB         = (0x12 << 6) | OPC_ADDU_QB_DSP,
 528    OPC_RADDU_W_QB     = (0x14 << 6) | OPC_ADDU_QB_DSP,
 529    /* MIPS DSP Multiply Sub-class insns */
 530    OPC_MULEU_S_PH_QBL = (0x06 << 6) | OPC_ADDU_QB_DSP,
 531    OPC_MULEU_S_PH_QBR = (0x07 << 6) | OPC_ADDU_QB_DSP,
 532    OPC_MULQ_RS_PH     = (0x1F << 6) | OPC_ADDU_QB_DSP,
 533    OPC_MULEQ_S_W_PHL  = (0x1C << 6) | OPC_ADDU_QB_DSP,
 534    OPC_MULEQ_S_W_PHR  = (0x1D << 6) | OPC_ADDU_QB_DSP,
 535    OPC_MULQ_S_PH      = (0x1E << 6) | OPC_ADDU_QB_DSP,
 536};
 537
 538#define OPC_ADDUH_QB_DSP OPC_MULT_G_2E
 539#define MASK_ADDUH_QB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
 540enum {
 541    /* MIPS DSP Arithmetic Sub-class */
 542    OPC_ADDUH_QB   = (0x00 << 6) | OPC_ADDUH_QB_DSP,
 543    OPC_ADDUH_R_QB = (0x02 << 6) | OPC_ADDUH_QB_DSP,
 544    OPC_ADDQH_PH   = (0x08 << 6) | OPC_ADDUH_QB_DSP,
 545    OPC_ADDQH_R_PH = (0x0A << 6) | OPC_ADDUH_QB_DSP,
 546    OPC_ADDQH_W    = (0x10 << 6) | OPC_ADDUH_QB_DSP,
 547    OPC_ADDQH_R_W  = (0x12 << 6) | OPC_ADDUH_QB_DSP,
 548    OPC_SUBUH_QB   = (0x01 << 6) | OPC_ADDUH_QB_DSP,
 549    OPC_SUBUH_R_QB = (0x03 << 6) | OPC_ADDUH_QB_DSP,
 550    OPC_SUBQH_PH   = (0x09 << 6) | OPC_ADDUH_QB_DSP,
 551    OPC_SUBQH_R_PH = (0x0B << 6) | OPC_ADDUH_QB_DSP,
 552    OPC_SUBQH_W    = (0x11 << 6) | OPC_ADDUH_QB_DSP,
 553    OPC_SUBQH_R_W  = (0x13 << 6) | OPC_ADDUH_QB_DSP,
 554    /* MIPS DSP Multiply Sub-class insns */
 555    OPC_MUL_PH     = (0x0C << 6) | OPC_ADDUH_QB_DSP,
 556    OPC_MUL_S_PH   = (0x0E << 6) | OPC_ADDUH_QB_DSP,
 557    OPC_MULQ_S_W   = (0x16 << 6) | OPC_ADDUH_QB_DSP,
 558    OPC_MULQ_RS_W  = (0x17 << 6) | OPC_ADDUH_QB_DSP,
 559};
 560
 561#define MASK_ABSQ_S_PH(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
 562enum {
 563    /* MIPS DSP Arithmetic Sub-class */
 564    OPC_ABSQ_S_QB       = (0x01 << 6) | OPC_ABSQ_S_PH_DSP,
 565    OPC_ABSQ_S_PH       = (0x09 << 6) | OPC_ABSQ_S_PH_DSP,
 566    OPC_ABSQ_S_W        = (0x11 << 6) | OPC_ABSQ_S_PH_DSP,
 567    OPC_PRECEQ_W_PHL    = (0x0C << 6) | OPC_ABSQ_S_PH_DSP,
 568    OPC_PRECEQ_W_PHR    = (0x0D << 6) | OPC_ABSQ_S_PH_DSP,
 569    OPC_PRECEQU_PH_QBL  = (0x04 << 6) | OPC_ABSQ_S_PH_DSP,
 570    OPC_PRECEQU_PH_QBR  = (0x05 << 6) | OPC_ABSQ_S_PH_DSP,
 571    OPC_PRECEQU_PH_QBLA = (0x06 << 6) | OPC_ABSQ_S_PH_DSP,
 572    OPC_PRECEQU_PH_QBRA = (0x07 << 6) | OPC_ABSQ_S_PH_DSP,
 573    OPC_PRECEU_PH_QBL   = (0x1C << 6) | OPC_ABSQ_S_PH_DSP,
 574    OPC_PRECEU_PH_QBR   = (0x1D << 6) | OPC_ABSQ_S_PH_DSP,
 575    OPC_PRECEU_PH_QBLA  = (0x1E << 6) | OPC_ABSQ_S_PH_DSP,
 576    OPC_PRECEU_PH_QBRA  = (0x1F << 6) | OPC_ABSQ_S_PH_DSP,
 577    /* DSP Bit/Manipulation Sub-class */
 578    OPC_BITREV          = (0x1B << 6) | OPC_ABSQ_S_PH_DSP,
 579    OPC_REPL_QB         = (0x02 << 6) | OPC_ABSQ_S_PH_DSP,
 580    OPC_REPLV_QB        = (0x03 << 6) | OPC_ABSQ_S_PH_DSP,
 581    OPC_REPL_PH         = (0x0A << 6) | OPC_ABSQ_S_PH_DSP,
 582    OPC_REPLV_PH        = (0x0B << 6) | OPC_ABSQ_S_PH_DSP,
 583};
 584
 585#define MASK_CMPU_EQ_QB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
 586enum {
 587    /* MIPS DSP Arithmetic Sub-class */
 588    OPC_PRECR_QB_PH      = (0x0D << 6) | OPC_CMPU_EQ_QB_DSP,
 589    OPC_PRECRQ_QB_PH     = (0x0C << 6) | OPC_CMPU_EQ_QB_DSP,
 590    OPC_PRECR_SRA_PH_W   = (0x1E << 6) | OPC_CMPU_EQ_QB_DSP,
 591    OPC_PRECR_SRA_R_PH_W = (0x1F << 6) | OPC_CMPU_EQ_QB_DSP,
 592    OPC_PRECRQ_PH_W      = (0x14 << 6) | OPC_CMPU_EQ_QB_DSP,
 593    OPC_PRECRQ_RS_PH_W   = (0x15 << 6) | OPC_CMPU_EQ_QB_DSP,
 594    OPC_PRECRQU_S_QB_PH  = (0x0F << 6) | OPC_CMPU_EQ_QB_DSP,
 595    /* DSP Compare-Pick Sub-class */
 596    OPC_CMPU_EQ_QB       = (0x00 << 6) | OPC_CMPU_EQ_QB_DSP,
 597    OPC_CMPU_LT_QB       = (0x01 << 6) | OPC_CMPU_EQ_QB_DSP,
 598    OPC_CMPU_LE_QB       = (0x02 << 6) | OPC_CMPU_EQ_QB_DSP,
 599    OPC_CMPGU_EQ_QB      = (0x04 << 6) | OPC_CMPU_EQ_QB_DSP,
 600    OPC_CMPGU_LT_QB      = (0x05 << 6) | OPC_CMPU_EQ_QB_DSP,
 601    OPC_CMPGU_LE_QB      = (0x06 << 6) | OPC_CMPU_EQ_QB_DSP,
 602    OPC_CMPGDU_EQ_QB     = (0x18 << 6) | OPC_CMPU_EQ_QB_DSP,
 603    OPC_CMPGDU_LT_QB     = (0x19 << 6) | OPC_CMPU_EQ_QB_DSP,
 604    OPC_CMPGDU_LE_QB     = (0x1A << 6) | OPC_CMPU_EQ_QB_DSP,
 605    OPC_CMP_EQ_PH        = (0x08 << 6) | OPC_CMPU_EQ_QB_DSP,
 606    OPC_CMP_LT_PH        = (0x09 << 6) | OPC_CMPU_EQ_QB_DSP,
 607    OPC_CMP_LE_PH        = (0x0A << 6) | OPC_CMPU_EQ_QB_DSP,
 608    OPC_PICK_QB          = (0x03 << 6) | OPC_CMPU_EQ_QB_DSP,
 609    OPC_PICK_PH          = (0x0B << 6) | OPC_CMPU_EQ_QB_DSP,
 610    OPC_PACKRL_PH        = (0x0E << 6) | OPC_CMPU_EQ_QB_DSP,
 611};
 612
 613#define MASK_SHLL_QB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
 614enum {
 615    /* MIPS DSP GPR-Based Shift Sub-class */
 616    OPC_SHLL_QB    = (0x00 << 6) | OPC_SHLL_QB_DSP,
 617    OPC_SHLLV_QB   = (0x02 << 6) | OPC_SHLL_QB_DSP,
 618    OPC_SHLL_PH    = (0x08 << 6) | OPC_SHLL_QB_DSP,
 619    OPC_SHLLV_PH   = (0x0A << 6) | OPC_SHLL_QB_DSP,
 620    OPC_SHLL_S_PH  = (0x0C << 6) | OPC_SHLL_QB_DSP,
 621    OPC_SHLLV_S_PH = (0x0E << 6) | OPC_SHLL_QB_DSP,
 622    OPC_SHLL_S_W   = (0x14 << 6) | OPC_SHLL_QB_DSP,
 623    OPC_SHLLV_S_W  = (0x16 << 6) | OPC_SHLL_QB_DSP,
 624    OPC_SHRL_QB    = (0x01 << 6) | OPC_SHLL_QB_DSP,
 625    OPC_SHRLV_QB   = (0x03 << 6) | OPC_SHLL_QB_DSP,
 626    OPC_SHRL_PH    = (0x19 << 6) | OPC_SHLL_QB_DSP,
 627    OPC_SHRLV_PH   = (0x1B << 6) | OPC_SHLL_QB_DSP,
 628    OPC_SHRA_QB    = (0x04 << 6) | OPC_SHLL_QB_DSP,
 629    OPC_SHRA_R_QB  = (0x05 << 6) | OPC_SHLL_QB_DSP,
 630    OPC_SHRAV_QB   = (0x06 << 6) | OPC_SHLL_QB_DSP,
 631    OPC_SHRAV_R_QB = (0x07 << 6) | OPC_SHLL_QB_DSP,
 632    OPC_SHRA_PH    = (0x09 << 6) | OPC_SHLL_QB_DSP,
 633    OPC_SHRAV_PH   = (0x0B << 6) | OPC_SHLL_QB_DSP,
 634    OPC_SHRA_R_PH  = (0x0D << 6) | OPC_SHLL_QB_DSP,
 635    OPC_SHRAV_R_PH = (0x0F << 6) | OPC_SHLL_QB_DSP,
 636    OPC_SHRA_R_W   = (0x15 << 6) | OPC_SHLL_QB_DSP,
 637    OPC_SHRAV_R_W  = (0x17 << 6) | OPC_SHLL_QB_DSP,
 638};
 639
 640#define MASK_DPA_W_PH(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
 641enum {
 642    /* MIPS DSP Multiply Sub-class insns */
 643    OPC_DPAU_H_QBL    = (0x03 << 6) | OPC_DPA_W_PH_DSP,
 644    OPC_DPAU_H_QBR    = (0x07 << 6) | OPC_DPA_W_PH_DSP,
 645    OPC_DPSU_H_QBL    = (0x0B << 6) | OPC_DPA_W_PH_DSP,
 646    OPC_DPSU_H_QBR    = (0x0F << 6) | OPC_DPA_W_PH_DSP,
 647    OPC_DPA_W_PH      = (0x00 << 6) | OPC_DPA_W_PH_DSP,
 648    OPC_DPAX_W_PH     = (0x08 << 6) | OPC_DPA_W_PH_DSP,
 649    OPC_DPAQ_S_W_PH   = (0x04 << 6) | OPC_DPA_W_PH_DSP,
 650    OPC_DPAQX_S_W_PH  = (0x18 << 6) | OPC_DPA_W_PH_DSP,
 651    OPC_DPAQX_SA_W_PH = (0x1A << 6) | OPC_DPA_W_PH_DSP,
 652    OPC_DPS_W_PH      = (0x01 << 6) | OPC_DPA_W_PH_DSP,
 653    OPC_DPSX_W_PH     = (0x09 << 6) | OPC_DPA_W_PH_DSP,
 654    OPC_DPSQ_S_W_PH   = (0x05 << 6) | OPC_DPA_W_PH_DSP,
 655    OPC_DPSQX_S_W_PH  = (0x19 << 6) | OPC_DPA_W_PH_DSP,
 656    OPC_DPSQX_SA_W_PH = (0x1B << 6) | OPC_DPA_W_PH_DSP,
 657    OPC_MULSAQ_S_W_PH = (0x06 << 6) | OPC_DPA_W_PH_DSP,
 658    OPC_DPAQ_SA_L_W   = (0x0C << 6) | OPC_DPA_W_PH_DSP,
 659    OPC_DPSQ_SA_L_W   = (0x0D << 6) | OPC_DPA_W_PH_DSP,
 660    OPC_MAQ_S_W_PHL   = (0x14 << 6) | OPC_DPA_W_PH_DSP,
 661    OPC_MAQ_S_W_PHR   = (0x16 << 6) | OPC_DPA_W_PH_DSP,
 662    OPC_MAQ_SA_W_PHL  = (0x10 << 6) | OPC_DPA_W_PH_DSP,
 663    OPC_MAQ_SA_W_PHR  = (0x12 << 6) | OPC_DPA_W_PH_DSP,
 664    OPC_MULSA_W_PH    = (0x02 << 6) | OPC_DPA_W_PH_DSP,
 665};
 666
 667#define MASK_INSV(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
 668enum {
 669    /* DSP Bit/Manipulation Sub-class */
 670    OPC_INSV = (0x00 << 6) | OPC_INSV_DSP,
 671};
 672
 673#define MASK_APPEND(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
 674enum {
 675    /* MIPS DSP Append Sub-class */
 676    OPC_APPEND  = (0x00 << 6) | OPC_APPEND_DSP,
 677    OPC_PREPEND = (0x01 << 6) | OPC_APPEND_DSP,
 678    OPC_BALIGN  = (0x10 << 6) | OPC_APPEND_DSP,
 679};
 680
 681#define MASK_EXTR_W(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
 682enum {
 683    /* MIPS DSP Accumulator and DSPControl Access Sub-class */
 684    OPC_EXTR_W     = (0x00 << 6) | OPC_EXTR_W_DSP,
 685    OPC_EXTR_R_W   = (0x04 << 6) | OPC_EXTR_W_DSP,
 686    OPC_EXTR_RS_W  = (0x06 << 6) | OPC_EXTR_W_DSP,
 687    OPC_EXTR_S_H   = (0x0E << 6) | OPC_EXTR_W_DSP,
 688    OPC_EXTRV_S_H  = (0x0F << 6) | OPC_EXTR_W_DSP,
 689    OPC_EXTRV_W    = (0x01 << 6) | OPC_EXTR_W_DSP,
 690    OPC_EXTRV_R_W  = (0x05 << 6) | OPC_EXTR_W_DSP,
 691    OPC_EXTRV_RS_W = (0x07 << 6) | OPC_EXTR_W_DSP,
 692    OPC_EXTP       = (0x02 << 6) | OPC_EXTR_W_DSP,
 693    OPC_EXTPV      = (0x03 << 6) | OPC_EXTR_W_DSP,
 694    OPC_EXTPDP     = (0x0A << 6) | OPC_EXTR_W_DSP,
 695    OPC_EXTPDPV    = (0x0B << 6) | OPC_EXTR_W_DSP,
 696    OPC_SHILO      = (0x1A << 6) | OPC_EXTR_W_DSP,
 697    OPC_SHILOV     = (0x1B << 6) | OPC_EXTR_W_DSP,
 698    OPC_MTHLIP     = (0x1F << 6) | OPC_EXTR_W_DSP,
 699    OPC_WRDSP      = (0x13 << 6) | OPC_EXTR_W_DSP,
 700    OPC_RDDSP      = (0x12 << 6) | OPC_EXTR_W_DSP,
 701};
 702
 703#define MASK_ABSQ_S_QH(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
 704enum {
 705    /* MIPS DSP Arithmetic Sub-class */
 706    OPC_PRECEQ_L_PWL    = (0x14 << 6) | OPC_ABSQ_S_QH_DSP,
 707    OPC_PRECEQ_L_PWR    = (0x15 << 6) | OPC_ABSQ_S_QH_DSP,
 708    OPC_PRECEQ_PW_QHL   = (0x0C << 6) | OPC_ABSQ_S_QH_DSP,
 709    OPC_PRECEQ_PW_QHR   = (0x0D << 6) | OPC_ABSQ_S_QH_DSP,
 710    OPC_PRECEQ_PW_QHLA  = (0x0E << 6) | OPC_ABSQ_S_QH_DSP,
 711    OPC_PRECEQ_PW_QHRA  = (0x0F << 6) | OPC_ABSQ_S_QH_DSP,
 712    OPC_PRECEQU_QH_OBL  = (0x04 << 6) | OPC_ABSQ_S_QH_DSP,
 713    OPC_PRECEQU_QH_OBR  = (0x05 << 6) | OPC_ABSQ_S_QH_DSP,
 714    OPC_PRECEQU_QH_OBLA = (0x06 << 6) | OPC_ABSQ_S_QH_DSP,
 715    OPC_PRECEQU_QH_OBRA = (0x07 << 6) | OPC_ABSQ_S_QH_DSP,
 716    OPC_PRECEU_QH_OBL   = (0x1C << 6) | OPC_ABSQ_S_QH_DSP,
 717    OPC_PRECEU_QH_OBR   = (0x1D << 6) | OPC_ABSQ_S_QH_DSP,
 718    OPC_PRECEU_QH_OBLA  = (0x1E << 6) | OPC_ABSQ_S_QH_DSP,
 719    OPC_PRECEU_QH_OBRA  = (0x1F << 6) | OPC_ABSQ_S_QH_DSP,
 720    OPC_ABSQ_S_OB       = (0x01 << 6) | OPC_ABSQ_S_QH_DSP,
 721    OPC_ABSQ_S_PW       = (0x11 << 6) | OPC_ABSQ_S_QH_DSP,
 722    OPC_ABSQ_S_QH       = (0x09 << 6) | OPC_ABSQ_S_QH_DSP,
 723    /* DSP Bit/Manipulation Sub-class */
 724    OPC_REPL_OB         = (0x02 << 6) | OPC_ABSQ_S_QH_DSP,
 725    OPC_REPL_PW         = (0x12 << 6) | OPC_ABSQ_S_QH_DSP,
 726    OPC_REPL_QH         = (0x0A << 6) | OPC_ABSQ_S_QH_DSP,
 727    OPC_REPLV_OB        = (0x03 << 6) | OPC_ABSQ_S_QH_DSP,
 728    OPC_REPLV_PW        = (0x13 << 6) | OPC_ABSQ_S_QH_DSP,
 729    OPC_REPLV_QH        = (0x0B << 6) | OPC_ABSQ_S_QH_DSP,
 730};
 731
 732#define MASK_ADDU_OB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
 733enum {
 734    /* MIPS DSP Multiply Sub-class insns */
 735    OPC_MULEQ_S_PW_QHL = (0x1C << 6) | OPC_ADDU_OB_DSP,
 736    OPC_MULEQ_S_PW_QHR = (0x1D << 6) | OPC_ADDU_OB_DSP,
 737    OPC_MULEU_S_QH_OBL = (0x06 << 6) | OPC_ADDU_OB_DSP,
 738    OPC_MULEU_S_QH_OBR = (0x07 << 6) | OPC_ADDU_OB_DSP,
 739    OPC_MULQ_RS_QH     = (0x1F << 6) | OPC_ADDU_OB_DSP,
 740    /* MIPS DSP Arithmetic Sub-class */
 741    OPC_RADDU_L_OB     = (0x14 << 6) | OPC_ADDU_OB_DSP,
 742    OPC_SUBQ_PW        = (0x13 << 6) | OPC_ADDU_OB_DSP,
 743    OPC_SUBQ_S_PW      = (0x17 << 6) | OPC_ADDU_OB_DSP,
 744    OPC_SUBQ_QH        = (0x0B << 6) | OPC_ADDU_OB_DSP,
 745    OPC_SUBQ_S_QH      = (0x0F << 6) | OPC_ADDU_OB_DSP,
 746    OPC_SUBU_OB        = (0x01 << 6) | OPC_ADDU_OB_DSP,
 747    OPC_SUBU_S_OB      = (0x05 << 6) | OPC_ADDU_OB_DSP,
 748    OPC_SUBU_QH        = (0x09 << 6) | OPC_ADDU_OB_DSP,
 749    OPC_SUBU_S_QH      = (0x0D << 6) | OPC_ADDU_OB_DSP,
 750    OPC_SUBUH_OB       = (0x19 << 6) | OPC_ADDU_OB_DSP,
 751    OPC_SUBUH_R_OB     = (0x1B << 6) | OPC_ADDU_OB_DSP,
 752    OPC_ADDQ_PW        = (0x12 << 6) | OPC_ADDU_OB_DSP,
 753    OPC_ADDQ_S_PW      = (0x16 << 6) | OPC_ADDU_OB_DSP,
 754    OPC_ADDQ_QH        = (0x0A << 6) | OPC_ADDU_OB_DSP,
 755    OPC_ADDQ_S_QH      = (0x0E << 6) | OPC_ADDU_OB_DSP,
 756    OPC_ADDU_OB        = (0x00 << 6) | OPC_ADDU_OB_DSP,
 757    OPC_ADDU_S_OB      = (0x04 << 6) | OPC_ADDU_OB_DSP,
 758    OPC_ADDU_QH        = (0x08 << 6) | OPC_ADDU_OB_DSP,
 759    OPC_ADDU_S_QH      = (0x0C << 6) | OPC_ADDU_OB_DSP,
 760    OPC_ADDUH_OB       = (0x18 << 6) | OPC_ADDU_OB_DSP,
 761    OPC_ADDUH_R_OB     = (0x1A << 6) | OPC_ADDU_OB_DSP,
 762};
 763
 764#define MASK_CMPU_EQ_OB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
 765enum {
 766    /* DSP Compare-Pick Sub-class */
 767    OPC_CMP_EQ_PW         = (0x10 << 6) | OPC_CMPU_EQ_OB_DSP,
 768    OPC_CMP_LT_PW         = (0x11 << 6) | OPC_CMPU_EQ_OB_DSP,
 769    OPC_CMP_LE_PW         = (0x12 << 6) | OPC_CMPU_EQ_OB_DSP,
 770    OPC_CMP_EQ_QH         = (0x08 << 6) | OPC_CMPU_EQ_OB_DSP,
 771    OPC_CMP_LT_QH         = (0x09 << 6) | OPC_CMPU_EQ_OB_DSP,
 772    OPC_CMP_LE_QH         = (0x0A << 6) | OPC_CMPU_EQ_OB_DSP,
 773    OPC_CMPGDU_EQ_OB      = (0x18 << 6) | OPC_CMPU_EQ_OB_DSP,
 774    OPC_CMPGDU_LT_OB      = (0x19 << 6) | OPC_CMPU_EQ_OB_DSP,
 775    OPC_CMPGDU_LE_OB      = (0x1A << 6) | OPC_CMPU_EQ_OB_DSP,
 776    OPC_CMPGU_EQ_OB       = (0x04 << 6) | OPC_CMPU_EQ_OB_DSP,
 777    OPC_CMPGU_LT_OB       = (0x05 << 6) | OPC_CMPU_EQ_OB_DSP,
 778    OPC_CMPGU_LE_OB       = (0x06 << 6) | OPC_CMPU_EQ_OB_DSP,
 779    OPC_CMPU_EQ_OB        = (0x00 << 6) | OPC_CMPU_EQ_OB_DSP,
 780    OPC_CMPU_LT_OB        = (0x01 << 6) | OPC_CMPU_EQ_OB_DSP,
 781    OPC_CMPU_LE_OB        = (0x02 << 6) | OPC_CMPU_EQ_OB_DSP,
 782    OPC_PACKRL_PW         = (0x0E << 6) | OPC_CMPU_EQ_OB_DSP,
 783    OPC_PICK_OB           = (0x03 << 6) | OPC_CMPU_EQ_OB_DSP,
 784    OPC_PICK_PW           = (0x13 << 6) | OPC_CMPU_EQ_OB_DSP,
 785    OPC_PICK_QH           = (0x0B << 6) | OPC_CMPU_EQ_OB_DSP,
 786    /* MIPS DSP Arithmetic Sub-class */
 787    OPC_PRECR_OB_QH       = (0x0D << 6) | OPC_CMPU_EQ_OB_DSP,
 788    OPC_PRECR_SRA_QH_PW   = (0x1E << 6) | OPC_CMPU_EQ_OB_DSP,
 789    OPC_PRECR_SRA_R_QH_PW = (0x1F << 6) | OPC_CMPU_EQ_OB_DSP,
 790    OPC_PRECRQ_OB_QH      = (0x0C << 6) | OPC_CMPU_EQ_OB_DSP,
 791    OPC_PRECRQ_PW_L       = (0x1C << 6) | OPC_CMPU_EQ_OB_DSP,
 792    OPC_PRECRQ_QH_PW      = (0x14 << 6) | OPC_CMPU_EQ_OB_DSP,
 793    OPC_PRECRQ_RS_QH_PW   = (0x15 << 6) | OPC_CMPU_EQ_OB_DSP,
 794    OPC_PRECRQU_S_OB_QH   = (0x0F << 6) | OPC_CMPU_EQ_OB_DSP,
 795};
 796
 797#define MASK_DAPPEND(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
 798enum {
 799    /* DSP Append Sub-class */
 800    OPC_DAPPEND  = (0x00 << 6) | OPC_DAPPEND_DSP,
 801    OPC_PREPENDD = (0x03 << 6) | OPC_DAPPEND_DSP,
 802    OPC_PREPENDW = (0x01 << 6) | OPC_DAPPEND_DSP,
 803    OPC_DBALIGN  = (0x10 << 6) | OPC_DAPPEND_DSP,
 804};
 805
 806#define MASK_DEXTR_W(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
 807enum {
 808    /* MIPS DSP Accumulator and DSPControl Access Sub-class */
 809    OPC_DMTHLIP     = (0x1F << 6) | OPC_DEXTR_W_DSP,
 810    OPC_DSHILO      = (0x1A << 6) | OPC_DEXTR_W_DSP,
 811    OPC_DEXTP       = (0x02 << 6) | OPC_DEXTR_W_DSP,
 812    OPC_DEXTPDP     = (0x0A << 6) | OPC_DEXTR_W_DSP,
 813    OPC_DEXTPDPV    = (0x0B << 6) | OPC_DEXTR_W_DSP,
 814    OPC_DEXTPV      = (0x03 << 6) | OPC_DEXTR_W_DSP,
 815    OPC_DEXTR_L     = (0x10 << 6) | OPC_DEXTR_W_DSP,
 816    OPC_DEXTR_R_L   = (0x14 << 6) | OPC_DEXTR_W_DSP,
 817    OPC_DEXTR_RS_L  = (0x16 << 6) | OPC_DEXTR_W_DSP,
 818    OPC_DEXTR_W     = (0x00 << 6) | OPC_DEXTR_W_DSP,
 819    OPC_DEXTR_R_W   = (0x04 << 6) | OPC_DEXTR_W_DSP,
 820    OPC_DEXTR_RS_W  = (0x06 << 6) | OPC_DEXTR_W_DSP,
 821    OPC_DEXTR_S_H   = (0x0E << 6) | OPC_DEXTR_W_DSP,
 822    OPC_DEXTRV_L    = (0x11 << 6) | OPC_DEXTR_W_DSP,
 823    OPC_DEXTRV_R_L  = (0x15 << 6) | OPC_DEXTR_W_DSP,
 824    OPC_DEXTRV_RS_L = (0x17 << 6) | OPC_DEXTR_W_DSP,
 825    OPC_DEXTRV_S_H  = (0x0F << 6) | OPC_DEXTR_W_DSP,
 826    OPC_DEXTRV_W    = (0x01 << 6) | OPC_DEXTR_W_DSP,
 827    OPC_DEXTRV_R_W  = (0x05 << 6) | OPC_DEXTR_W_DSP,
 828    OPC_DEXTRV_RS_W = (0x07 << 6) | OPC_DEXTR_W_DSP,
 829    OPC_DSHILOV     = (0x1B << 6) | OPC_DEXTR_W_DSP,
 830};
 831
 832#define MASK_DINSV(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
 833enum {
 834    /* DSP Bit/Manipulation Sub-class */
 835    OPC_DINSV = (0x00 << 6) | OPC_DINSV_DSP,
 836};
 837
 838#define MASK_DPAQ_W_QH(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
 839enum {
 840    /* MIPS DSP Multiply Sub-class insns */
 841    OPC_DMADD         = (0x19 << 6) | OPC_DPAQ_W_QH_DSP,
 842    OPC_DMADDU        = (0x1D << 6) | OPC_DPAQ_W_QH_DSP,
 843    OPC_DMSUB         = (0x1B << 6) | OPC_DPAQ_W_QH_DSP,
 844    OPC_DMSUBU        = (0x1F << 6) | OPC_DPAQ_W_QH_DSP,
 845    OPC_DPA_W_QH      = (0x00 << 6) | OPC_DPAQ_W_QH_DSP,
 846    OPC_DPAQ_S_W_QH   = (0x04 << 6) | OPC_DPAQ_W_QH_DSP,
 847    OPC_DPAQ_SA_L_PW  = (0x0C << 6) | OPC_DPAQ_W_QH_DSP,
 848    OPC_DPAU_H_OBL    = (0x03 << 6) | OPC_DPAQ_W_QH_DSP,
 849    OPC_DPAU_H_OBR    = (0x07 << 6) | OPC_DPAQ_W_QH_DSP,
 850    OPC_DPS_W_QH      = (0x01 << 6) | OPC_DPAQ_W_QH_DSP,
 851    OPC_DPSQ_S_W_QH   = (0x05 << 6) | OPC_DPAQ_W_QH_DSP,
 852    OPC_DPSQ_SA_L_PW  = (0x0D << 6) | OPC_DPAQ_W_QH_DSP,
 853    OPC_DPSU_H_OBL    = (0x0B << 6) | OPC_DPAQ_W_QH_DSP,
 854    OPC_DPSU_H_OBR    = (0x0F << 6) | OPC_DPAQ_W_QH_DSP,
 855    OPC_MAQ_S_L_PWL   = (0x1C << 6) | OPC_DPAQ_W_QH_DSP,
 856    OPC_MAQ_S_L_PWR   = (0x1E << 6) | OPC_DPAQ_W_QH_DSP,
 857    OPC_MAQ_S_W_QHLL  = (0x14 << 6) | OPC_DPAQ_W_QH_DSP,
 858    OPC_MAQ_SA_W_QHLL = (0x10 << 6) | OPC_DPAQ_W_QH_DSP,
 859    OPC_MAQ_S_W_QHLR  = (0x15 << 6) | OPC_DPAQ_W_QH_DSP,
 860    OPC_MAQ_SA_W_QHLR = (0x11 << 6) | OPC_DPAQ_W_QH_DSP,
 861    OPC_MAQ_S_W_QHRL  = (0x16 << 6) | OPC_DPAQ_W_QH_DSP,
 862    OPC_MAQ_SA_W_QHRL = (0x12 << 6) | OPC_DPAQ_W_QH_DSP,
 863    OPC_MAQ_S_W_QHRR  = (0x17 << 6) | OPC_DPAQ_W_QH_DSP,
 864    OPC_MAQ_SA_W_QHRR = (0x13 << 6) | OPC_DPAQ_W_QH_DSP,
 865    OPC_MULSAQ_S_L_PW = (0x0E << 6) | OPC_DPAQ_W_QH_DSP,
 866    OPC_MULSAQ_S_W_QH = (0x06 << 6) | OPC_DPAQ_W_QH_DSP,
 867};
 868
 869#define MASK_SHLL_OB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
 870enum {
 871    /* MIPS DSP GPR-Based Shift Sub-class */
 872    OPC_SHLL_PW    = (0x10 << 6) | OPC_SHLL_OB_DSP,
 873    OPC_SHLL_S_PW  = (0x14 << 6) | OPC_SHLL_OB_DSP,
 874    OPC_SHLLV_OB   = (0x02 << 6) | OPC_SHLL_OB_DSP,
 875    OPC_SHLLV_PW   = (0x12 << 6) | OPC_SHLL_OB_DSP,
 876    OPC_SHLLV_S_PW = (0x16 << 6) | OPC_SHLL_OB_DSP,
 877    OPC_SHLLV_QH   = (0x0A << 6) | OPC_SHLL_OB_DSP,
 878    OPC_SHLLV_S_QH = (0x0E << 6) | OPC_SHLL_OB_DSP,
 879    OPC_SHRA_PW    = (0x11 << 6) | OPC_SHLL_OB_DSP,
 880    OPC_SHRA_R_PW  = (0x15 << 6) | OPC_SHLL_OB_DSP,
 881    OPC_SHRAV_OB   = (0x06 << 6) | OPC_SHLL_OB_DSP,
 882    OPC_SHRAV_R_OB = (0x07 << 6) | OPC_SHLL_OB_DSP,
 883    OPC_SHRAV_PW   = (0x13 << 6) | OPC_SHLL_OB_DSP,
 884    OPC_SHRAV_R_PW = (0x17 << 6) | OPC_SHLL_OB_DSP,
 885    OPC_SHRAV_QH   = (0x0B << 6) | OPC_SHLL_OB_DSP,
 886    OPC_SHRAV_R_QH = (0x0F << 6) | OPC_SHLL_OB_DSP,
 887    OPC_SHRLV_OB   = (0x03 << 6) | OPC_SHLL_OB_DSP,
 888    OPC_SHRLV_QH   = (0x1B << 6) | OPC_SHLL_OB_DSP,
 889    OPC_SHLL_OB    = (0x00 << 6) | OPC_SHLL_OB_DSP,
 890    OPC_SHLL_QH    = (0x08 << 6) | OPC_SHLL_OB_DSP,
 891    OPC_SHLL_S_QH  = (0x0C << 6) | OPC_SHLL_OB_DSP,
 892    OPC_SHRA_OB    = (0x04 << 6) | OPC_SHLL_OB_DSP,
 893    OPC_SHRA_R_OB  = (0x05 << 6) | OPC_SHLL_OB_DSP,
 894    OPC_SHRA_QH    = (0x09 << 6) | OPC_SHLL_OB_DSP,
 895    OPC_SHRA_R_QH  = (0x0D << 6) | OPC_SHLL_OB_DSP,
 896    OPC_SHRL_OB    = (0x01 << 6) | OPC_SHLL_OB_DSP,
 897    OPC_SHRL_QH    = (0x19 << 6) | OPC_SHLL_OB_DSP,
 898};
 899
 900/* Coprocessor 0 (rs field) */
 901#define MASK_CP0(op)       MASK_OP_MAJOR(op) | (op & (0x1F << 21))
 902
 903enum {
 904    OPC_MFC0     = (0x00 << 21) | OPC_CP0,
 905    OPC_DMFC0    = (0x01 << 21) | OPC_CP0,
 906    OPC_MFHC0    = (0x02 << 21) | OPC_CP0,
 907    OPC_MTC0     = (0x04 << 21) | OPC_CP0,
 908    OPC_DMTC0    = (0x05 << 21) | OPC_CP0,
 909    OPC_MTHC0    = (0x06 << 21) | OPC_CP0,
 910    OPC_MFTR     = (0x08 << 21) | OPC_CP0,
 911    OPC_RDPGPR   = (0x0A << 21) | OPC_CP0,
 912    OPC_MFMC0    = (0x0B << 21) | OPC_CP0,
 913    OPC_MTTR     = (0x0C << 21) | OPC_CP0,
 914    OPC_WRPGPR   = (0x0E << 21) | OPC_CP0,
 915    OPC_C0       = (0x10 << 21) | OPC_CP0,
 916    OPC_C0_1     = (0x11 << 21) | OPC_CP0,
 917    OPC_C0_2     = (0x12 << 21) | OPC_CP0,
 918    OPC_C0_3     = (0x13 << 21) | OPC_CP0,
 919    OPC_C0_4     = (0x14 << 21) | OPC_CP0,
 920    OPC_C0_5     = (0x15 << 21) | OPC_CP0,
 921    OPC_C0_6     = (0x16 << 21) | OPC_CP0,
 922    OPC_C0_7     = (0x17 << 21) | OPC_CP0,
 923    OPC_C0_8     = (0x18 << 21) | OPC_CP0,
 924    OPC_C0_9     = (0x19 << 21) | OPC_CP0,
 925    OPC_C0_A     = (0x1A << 21) | OPC_CP0,
 926    OPC_C0_B     = (0x1B << 21) | OPC_CP0,
 927    OPC_C0_C     = (0x1C << 21) | OPC_CP0,
 928    OPC_C0_D     = (0x1D << 21) | OPC_CP0,
 929    OPC_C0_E     = (0x1E << 21) | OPC_CP0,
 930    OPC_C0_F     = (0x1F << 21) | OPC_CP0,
 931};
 932
 933/* MFMC0 opcodes */
 934#define MASK_MFMC0(op)     MASK_CP0(op) | (op & 0xFFFF)
 935
 936enum {
 937    OPC_DMT      = 0x01 | (0 << 5) | (0x0F << 6) | (0x01 << 11) | OPC_MFMC0,
 938    OPC_EMT      = 0x01 | (1 << 5) | (0x0F << 6) | (0x01 << 11) | OPC_MFMC0,
 939    OPC_DVPE     = 0x01 | (0 << 5) | OPC_MFMC0,
 940    OPC_EVPE     = 0x01 | (1 << 5) | OPC_MFMC0,
 941    OPC_DI       = (0 << 5) | (0x0C << 11) | OPC_MFMC0,
 942    OPC_EI       = (1 << 5) | (0x0C << 11) | OPC_MFMC0,
 943    OPC_DVP      = 0x04 | (0 << 3) | (1 << 5) | (0 << 11) | OPC_MFMC0,
 944    OPC_EVP      = 0x04 | (0 << 3) | (0 << 5) | (0 << 11) | OPC_MFMC0,
 945};
 946
 947/* Coprocessor 0 (with rs == C0) */
 948#define MASK_C0(op)        MASK_CP0(op) | (op & 0x3F)
 949
 950enum {
 951    OPC_TLBR     = 0x01 | OPC_C0,
 952    OPC_TLBWI    = 0x02 | OPC_C0,
 953    OPC_TLBINV   = 0x03 | OPC_C0,
 954    OPC_TLBINVF  = 0x04 | OPC_C0,
 955    OPC_TLBWR    = 0x06 | OPC_C0,
 956    OPC_TLBP     = 0x08 | OPC_C0,
 957    OPC_RFE      = 0x10 | OPC_C0,
 958    OPC_ERET     = 0x18 | OPC_C0,
 959    OPC_DERET    = 0x1F | OPC_C0,
 960    OPC_WAIT     = 0x20 | OPC_C0,
 961};
 962
 963/* Coprocessor 1 (rs field) */
 964#define MASK_CP1(op)       MASK_OP_MAJOR(op) | (op & (0x1F << 21))
 965
 966/* Values for the fmt field in FP instructions */
 967enum {
 968    /* 0 - 15 are reserved */
 969    FMT_S = 16,          /* single fp */
 970    FMT_D = 17,          /* double fp */
 971    FMT_E = 18,          /* extended fp */
 972    FMT_Q = 19,          /* quad fp */
 973    FMT_W = 20,          /* 32-bit fixed */
 974    FMT_L = 21,          /* 64-bit fixed */
 975    FMT_PS = 22,         /* paired single fp */
 976    /* 23 - 31 are reserved */
 977};
 978
 979enum {
 980    OPC_MFC1     = (0x00 << 21) | OPC_CP1,
 981    OPC_DMFC1    = (0x01 << 21) | OPC_CP1,
 982    OPC_CFC1     = (0x02 << 21) | OPC_CP1,
 983    OPC_MFHC1    = (0x03 << 21) | OPC_CP1,
 984    OPC_MTC1     = (0x04 << 21) | OPC_CP1,
 985    OPC_DMTC1    = (0x05 << 21) | OPC_CP1,
 986    OPC_CTC1     = (0x06 << 21) | OPC_CP1,
 987    OPC_MTHC1    = (0x07 << 21) | OPC_CP1,
 988    OPC_BC1      = (0x08 << 21) | OPC_CP1, /* bc */
 989    OPC_BC1ANY2  = (0x09 << 21) | OPC_CP1,
 990    OPC_BC1ANY4  = (0x0A << 21) | OPC_CP1,
 991    OPC_BZ_V     = (0x0B << 21) | OPC_CP1,
 992    OPC_BNZ_V    = (0x0F << 21) | OPC_CP1,
 993    OPC_S_FMT    = (FMT_S << 21) | OPC_CP1,
 994    OPC_D_FMT    = (FMT_D << 21) | OPC_CP1,
 995    OPC_E_FMT    = (FMT_E << 21) | OPC_CP1,
 996    OPC_Q_FMT    = (FMT_Q << 21) | OPC_CP1,
 997    OPC_W_FMT    = (FMT_W << 21) | OPC_CP1,
 998    OPC_L_FMT    = (FMT_L << 21) | OPC_CP1,
 999    OPC_PS_FMT   = (FMT_PS << 21) | OPC_CP1,
1000    OPC_BC1EQZ   = (0x09 << 21) | OPC_CP1,
1001    OPC_BC1NEZ   = (0x0D << 21) | OPC_CP1,
1002    OPC_BZ_B     = (0x18 << 21) | OPC_CP1,
1003    OPC_BZ_H     = (0x19 << 21) | OPC_CP1,
1004    OPC_BZ_W     = (0x1A << 21) | OPC_CP1,
1005    OPC_BZ_D     = (0x1B << 21) | OPC_CP1,
1006    OPC_BNZ_B    = (0x1C << 21) | OPC_CP1,
1007    OPC_BNZ_H    = (0x1D << 21) | OPC_CP1,
1008    OPC_BNZ_W    = (0x1E << 21) | OPC_CP1,
1009    OPC_BNZ_D    = (0x1F << 21) | OPC_CP1,
1010};
1011
1012#define MASK_CP1_FUNC(op)       MASK_CP1(op) | (op & 0x3F)
1013#define MASK_BC1(op)            MASK_CP1(op) | (op & (0x3 << 16))
1014
1015enum {
1016    OPC_BC1F     = (0x00 << 16) | OPC_BC1,
1017    OPC_BC1T     = (0x01 << 16) | OPC_BC1,
1018    OPC_BC1FL    = (0x02 << 16) | OPC_BC1,
1019    OPC_BC1TL    = (0x03 << 16) | OPC_BC1,
1020};
1021
1022enum {
1023    OPC_BC1FANY2     = (0x00 << 16) | OPC_BC1ANY2,
1024    OPC_BC1TANY2     = (0x01 << 16) | OPC_BC1ANY2,
1025};
1026
1027enum {
1028    OPC_BC1FANY4     = (0x00 << 16) | OPC_BC1ANY4,
1029    OPC_BC1TANY4     = (0x01 << 16) | OPC_BC1ANY4,
1030};
1031
1032#define MASK_CP2(op)       MASK_OP_MAJOR(op) | (op & (0x1F << 21))
1033
1034enum {
1035    OPC_MFC2    = (0x00 << 21) | OPC_CP2,
1036    OPC_DMFC2   = (0x01 << 21) | OPC_CP2,
1037    OPC_CFC2    = (0x02 << 21) | OPC_CP2,
1038    OPC_MFHC2   = (0x03 << 21) | OPC_CP2,
1039    OPC_MTC2    = (0x04 << 21) | OPC_CP2,
1040    OPC_DMTC2   = (0x05 << 21) | OPC_CP2,
1041    OPC_CTC2    = (0x06 << 21) | OPC_CP2,
1042    OPC_MTHC2   = (0x07 << 21) | OPC_CP2,
1043    OPC_BC2     = (0x08 << 21) | OPC_CP2,
1044    OPC_BC2EQZ  = (0x09 << 21) | OPC_CP2,
1045    OPC_BC2NEZ  = (0x0D << 21) | OPC_CP2,
1046};
1047
1048#define MASK_LMI(op)  (MASK_OP_MAJOR(op) | (op & (0x1F << 21)) | (op & 0x1F))
1049
1050enum {
1051    OPC_PADDSH  = (24 << 21) | (0x00) | OPC_CP2,
1052    OPC_PADDUSH = (25 << 21) | (0x00) | OPC_CP2,
1053    OPC_PADDH   = (26 << 21) | (0x00) | OPC_CP2,
1054    OPC_PADDW   = (27 << 21) | (0x00) | OPC_CP2,
1055    OPC_PADDSB  = (28 << 21) | (0x00) | OPC_CP2,
1056    OPC_PADDUSB = (29 << 21) | (0x00) | OPC_CP2,
1057    OPC_PADDB   = (30 << 21) | (0x00) | OPC_CP2,
1058    OPC_PADDD   = (31 << 21) | (0x00) | OPC_CP2,
1059
1060    OPC_PSUBSH  = (24 << 21) | (0x01) | OPC_CP2,
1061    OPC_PSUBUSH = (25 << 21) | (0x01) | OPC_CP2,
1062    OPC_PSUBH   = (26 << 21) | (0x01) | OPC_CP2,
1063    OPC_PSUBW   = (27 << 21) | (0x01) | OPC_CP2,
1064    OPC_PSUBSB  = (28 << 21) | (0x01) | OPC_CP2,
1065    OPC_PSUBUSB = (29 << 21) | (0x01) | OPC_CP2,
1066    OPC_PSUBB   = (30 << 21) | (0x01) | OPC_CP2,
1067    OPC_PSUBD   = (31 << 21) | (0x01) | OPC_CP2,
1068
1069    OPC_PSHUFH   = (24 << 21) | (0x02) | OPC_CP2,
1070    OPC_PACKSSWH = (25 << 21) | (0x02) | OPC_CP2,
1071    OPC_PACKSSHB = (26 << 21) | (0x02) | OPC_CP2,
1072    OPC_PACKUSHB = (27 << 21) | (0x02) | OPC_CP2,
1073    OPC_XOR_CP2  = (28 << 21) | (0x02) | OPC_CP2,
1074    OPC_NOR_CP2  = (29 << 21) | (0x02) | OPC_CP2,
1075    OPC_AND_CP2  = (30 << 21) | (0x02) | OPC_CP2,
1076    OPC_PANDN    = (31 << 21) | (0x02) | OPC_CP2,
1077
1078    OPC_PUNPCKLHW = (24 << 21) | (0x03) | OPC_CP2,
1079    OPC_PUNPCKHHW = (25 << 21) | (0x03) | OPC_CP2,
1080    OPC_PUNPCKLBH = (26 << 21) | (0x03) | OPC_CP2,
1081    OPC_PUNPCKHBH = (27 << 21) | (0x03) | OPC_CP2,
1082    OPC_PINSRH_0  = (28 << 21) | (0x03) | OPC_CP2,
1083    OPC_PINSRH_1  = (29 << 21) | (0x03) | OPC_CP2,
1084    OPC_PINSRH_2  = (30 << 21) | (0x03) | OPC_CP2,
1085    OPC_PINSRH_3  = (31 << 21) | (0x03) | OPC_CP2,
1086
1087    OPC_PAVGH   = (24 << 21) | (0x08) | OPC_CP2,
1088    OPC_PAVGB   = (25 << 21) | (0x08) | OPC_CP2,
1089    OPC_PMAXSH  = (26 << 21) | (0x08) | OPC_CP2,
1090    OPC_PMINSH  = (27 << 21) | (0x08) | OPC_CP2,
1091    OPC_PMAXUB  = (28 << 21) | (0x08) | OPC_CP2,
1092    OPC_PMINUB  = (29 << 21) | (0x08) | OPC_CP2,
1093
1094    OPC_PCMPEQW = (24 << 21) | (0x09) | OPC_CP2,
1095    OPC_PCMPGTW = (25 << 21) | (0x09) | OPC_CP2,
1096    OPC_PCMPEQH = (26 << 21) | (0x09) | OPC_CP2,
1097    OPC_PCMPGTH = (27 << 21) | (0x09) | OPC_CP2,
1098    OPC_PCMPEQB = (28 << 21) | (0x09) | OPC_CP2,
1099    OPC_PCMPGTB = (29 << 21) | (0x09) | OPC_CP2,
1100
1101    OPC_PSLLW   = (24 << 21) | (0x0A) | OPC_CP2,
1102    OPC_PSLLH   = (25 << 21) | (0x0A) | OPC_CP2,
1103    OPC_PMULLH  = (26 << 21) | (0x0A) | OPC_CP2,
1104    OPC_PMULHH  = (27 << 21) | (0x0A) | OPC_CP2,
1105    OPC_PMULUW  = (28 << 21) | (0x0A) | OPC_CP2,
1106    OPC_PMULHUH = (29 << 21) | (0x0A) | OPC_CP2,
1107
1108    OPC_PSRLW     = (24 << 21) | (0x0B) | OPC_CP2,
1109    OPC_PSRLH     = (25 << 21) | (0x0B) | OPC_CP2,
1110    OPC_PSRAW     = (26 << 21) | (0x0B) | OPC_CP2,
1111    OPC_PSRAH     = (27 << 21) | (0x0B) | OPC_CP2,
1112    OPC_PUNPCKLWD = (28 << 21) | (0x0B) | OPC_CP2,
1113    OPC_PUNPCKHWD = (29 << 21) | (0x0B) | OPC_CP2,
1114
1115    OPC_ADDU_CP2 = (24 << 21) | (0x0C) | OPC_CP2,
1116    OPC_OR_CP2   = (25 << 21) | (0x0C) | OPC_CP2,
1117    OPC_ADD_CP2  = (26 << 21) | (0x0C) | OPC_CP2,
1118    OPC_DADD_CP2 = (27 << 21) | (0x0C) | OPC_CP2,
1119    OPC_SEQU_CP2 = (28 << 21) | (0x0C) | OPC_CP2,
1120    OPC_SEQ_CP2  = (29 << 21) | (0x0C) | OPC_CP2,
1121
1122    OPC_SUBU_CP2 = (24 << 21) | (0x0D) | OPC_CP2,
1123    OPC_PASUBUB  = (25 << 21) | (0x0D) | OPC_CP2,
1124    OPC_SUB_CP2  = (26 << 21) | (0x0D) | OPC_CP2,
1125    OPC_DSUB_CP2 = (27 << 21) | (0x0D) | OPC_CP2,
1126    OPC_SLTU_CP2 = (28 << 21) | (0x0D) | OPC_CP2,
1127    OPC_SLT_CP2  = (29 << 21) | (0x0D) | OPC_CP2,
1128
1129    OPC_SLL_CP2  = (24 << 21) | (0x0E) | OPC_CP2,
1130    OPC_DSLL_CP2 = (25 << 21) | (0x0E) | OPC_CP2,
1131    OPC_PEXTRH   = (26 << 21) | (0x0E) | OPC_CP2,
1132    OPC_PMADDHW  = (27 << 21) | (0x0E) | OPC_CP2,
1133    OPC_SLEU_CP2 = (28 << 21) | (0x0E) | OPC_CP2,
1134    OPC_SLE_CP2  = (29 << 21) | (0x0E) | OPC_CP2,
1135
1136    OPC_SRL_CP2  = (24 << 21) | (0x0F) | OPC_CP2,
1137    OPC_DSRL_CP2 = (25 << 21) | (0x0F) | OPC_CP2,
1138    OPC_SRA_CP2  = (26 << 21) | (0x0F) | OPC_CP2,
1139    OPC_DSRA_CP2 = (27 << 21) | (0x0F) | OPC_CP2,
1140    OPC_BIADD    = (28 << 21) | (0x0F) | OPC_CP2,
1141    OPC_PMOVMSKB = (29 << 21) | (0x0F) | OPC_CP2,
1142};
1143
1144
1145#define MASK_CP3(op)       MASK_OP_MAJOR(op) | (op & 0x3F)
1146
1147enum {
1148    OPC_LWXC1   = 0x00 | OPC_CP3,
1149    OPC_LDXC1   = 0x01 | OPC_CP3,
1150    OPC_LUXC1   = 0x05 | OPC_CP3,
1151    OPC_SWXC1   = 0x08 | OPC_CP3,
1152    OPC_SDXC1   = 0x09 | OPC_CP3,
1153    OPC_SUXC1   = 0x0D | OPC_CP3,
1154    OPC_PREFX   = 0x0F | OPC_CP3,
1155    OPC_ALNV_PS = 0x1E | OPC_CP3,
1156    OPC_MADD_S  = 0x20 | OPC_CP3,
1157    OPC_MADD_D  = 0x21 | OPC_CP3,
1158    OPC_MADD_PS = 0x26 | OPC_CP3,
1159    OPC_MSUB_S  = 0x28 | OPC_CP3,
1160    OPC_MSUB_D  = 0x29 | OPC_CP3,
1161    OPC_MSUB_PS = 0x2E | OPC_CP3,
1162    OPC_NMADD_S = 0x30 | OPC_CP3,
1163    OPC_NMADD_D = 0x31 | OPC_CP3,
1164    OPC_NMADD_PS= 0x36 | OPC_CP3,
1165    OPC_NMSUB_S = 0x38 | OPC_CP3,
1166    OPC_NMSUB_D = 0x39 | OPC_CP3,
1167    OPC_NMSUB_PS= 0x3E | OPC_CP3,
1168};
1169
1170/* MSA Opcodes */
1171#define MASK_MSA_MINOR(op)    (MASK_OP_MAJOR(op) | (op & 0x3F))
1172enum {
1173    OPC_MSA_I8_00   = 0x00 | OPC_MSA,
1174    OPC_MSA_I8_01   = 0x01 | OPC_MSA,
1175    OPC_MSA_I8_02   = 0x02 | OPC_MSA,
1176    OPC_MSA_I5_06   = 0x06 | OPC_MSA,
1177    OPC_MSA_I5_07   = 0x07 | OPC_MSA,
1178    OPC_MSA_BIT_09  = 0x09 | OPC_MSA,
1179    OPC_MSA_BIT_0A  = 0x0A | OPC_MSA,
1180    OPC_MSA_3R_0D   = 0x0D | OPC_MSA,
1181    OPC_MSA_3R_0E   = 0x0E | OPC_MSA,
1182    OPC_MSA_3R_0F   = 0x0F | OPC_MSA,
1183    OPC_MSA_3R_10   = 0x10 | OPC_MSA,
1184    OPC_MSA_3R_11   = 0x11 | OPC_MSA,
1185    OPC_MSA_3R_12   = 0x12 | OPC_MSA,
1186    OPC_MSA_3R_13   = 0x13 | OPC_MSA,
1187    OPC_MSA_3R_14   = 0x14 | OPC_MSA,
1188    OPC_MSA_3R_15   = 0x15 | OPC_MSA,
1189    OPC_MSA_ELM     = 0x19 | OPC_MSA,
1190    OPC_MSA_3RF_1A  = 0x1A | OPC_MSA,
1191    OPC_MSA_3RF_1B  = 0x1B | OPC_MSA,
1192    OPC_MSA_3RF_1C  = 0x1C | OPC_MSA,
1193    OPC_MSA_VEC     = 0x1E | OPC_MSA,
1194
1195    /* MI10 instruction */
1196    OPC_LD_B    = (0x20) | OPC_MSA,
1197    OPC_LD_H    = (0x21) | OPC_MSA,
1198    OPC_LD_W    = (0x22) | OPC_MSA,
1199    OPC_LD_D    = (0x23) | OPC_MSA,
1200    OPC_ST_B    = (0x24) | OPC_MSA,
1201    OPC_ST_H    = (0x25) | OPC_MSA,
1202    OPC_ST_W    = (0x26) | OPC_MSA,
1203    OPC_ST_D    = (0x27) | OPC_MSA,
1204};
1205
1206enum {
1207    /* I5 instruction df(bits 22..21) = _b, _h, _w, _d */
1208    OPC_ADDVI_df    = (0x0 << 23) | OPC_MSA_I5_06,
1209    OPC_CEQI_df     = (0x0 << 23) | OPC_MSA_I5_07,
1210    OPC_SUBVI_df    = (0x1 << 23) | OPC_MSA_I5_06,
1211    OPC_MAXI_S_df   = (0x2 << 23) | OPC_MSA_I5_06,
1212    OPC_CLTI_S_df   = (0x2 << 23) | OPC_MSA_I5_07,
1213    OPC_MAXI_U_df   = (0x3 << 23) | OPC_MSA_I5_06,
1214    OPC_CLTI_U_df   = (0x3 << 23) | OPC_MSA_I5_07,
1215    OPC_MINI_S_df   = (0x4 << 23) | OPC_MSA_I5_06,
1216    OPC_CLEI_S_df   = (0x4 << 23) | OPC_MSA_I5_07,
1217    OPC_MINI_U_df   = (0x5 << 23) | OPC_MSA_I5_06,
1218    OPC_CLEI_U_df   = (0x5 << 23) | OPC_MSA_I5_07,
1219    OPC_LDI_df      = (0x6 << 23) | OPC_MSA_I5_07,
1220
1221    /* I8 instruction */
1222    OPC_ANDI_B  = (0x0 << 24) | OPC_MSA_I8_00,
1223    OPC_BMNZI_B = (0x0 << 24) | OPC_MSA_I8_01,
1224    OPC_SHF_B   = (0x0 << 24) | OPC_MSA_I8_02,
1225    OPC_ORI_B   = (0x1 << 24) | OPC_MSA_I8_00,
1226    OPC_BMZI_B  = (0x1 << 24) | OPC_MSA_I8_01,
1227    OPC_SHF_H   = (0x1 << 24) | OPC_MSA_I8_02,
1228    OPC_NORI_B  = (0x2 << 24) | OPC_MSA_I8_00,
1229    OPC_BSELI_B = (0x2 << 24) | OPC_MSA_I8_01,
1230    OPC_SHF_W   = (0x2 << 24) | OPC_MSA_I8_02,
1231    OPC_XORI_B  = (0x3 << 24) | OPC_MSA_I8_00,
1232
1233    /* VEC/2R/2RF instruction */
1234    OPC_AND_V   = (0x00 << 21) | OPC_MSA_VEC,
1235    OPC_OR_V    = (0x01 << 21) | OPC_MSA_VEC,
1236    OPC_NOR_V   = (0x02 << 21) | OPC_MSA_VEC,
1237    OPC_XOR_V   = (0x03 << 21) | OPC_MSA_VEC,
1238    OPC_BMNZ_V  = (0x04 << 21) | OPC_MSA_VEC,
1239    OPC_BMZ_V   = (0x05 << 21) | OPC_MSA_VEC,
1240    OPC_BSEL_V  = (0x06 << 21) | OPC_MSA_VEC,
1241
1242    OPC_MSA_2R      = (0x18 << 21) | OPC_MSA_VEC,
1243    OPC_MSA_2RF     = (0x19 << 21) | OPC_MSA_VEC,
1244
1245    /* 2R instruction df(bits 17..16) = _b, _h, _w, _d */
1246    OPC_FILL_df = (0x00 << 18) | OPC_MSA_2R,
1247    OPC_PCNT_df = (0x01 << 18) | OPC_MSA_2R,
1248    OPC_NLOC_df = (0x02 << 18) | OPC_MSA_2R,
1249    OPC_NLZC_df = (0x03 << 18) | OPC_MSA_2R,
1250
1251    /* 2RF instruction df(bit 16) = _w, _d */
1252    OPC_FCLASS_df   = (0x00 << 17) | OPC_MSA_2RF,
1253    OPC_FTRUNC_S_df = (0x01 << 17) | OPC_MSA_2RF,
1254    OPC_FTRUNC_U_df = (0x02 << 17) | OPC_MSA_2RF,
1255    OPC_FSQRT_df    = (0x03 << 17) | OPC_MSA_2RF,
1256    OPC_FRSQRT_df   = (0x04 << 17) | OPC_MSA_2RF,
1257    OPC_FRCP_df     = (0x05 << 17) | OPC_MSA_2RF,
1258    OPC_FRINT_df    = (0x06 << 17) | OPC_MSA_2RF,
1259    OPC_FLOG2_df    = (0x07 << 17) | OPC_MSA_2RF,
1260    OPC_FEXUPL_df   = (0x08 << 17) | OPC_MSA_2RF,
1261    OPC_FEXUPR_df   = (0x09 << 17) | OPC_MSA_2RF,
1262    OPC_FFQL_df     = (0x0A << 17) | OPC_MSA_2RF,
1263    OPC_FFQR_df     = (0x0B << 17) | OPC_MSA_2RF,
1264    OPC_FTINT_S_df  = (0x0C << 17) | OPC_MSA_2RF,
1265    OPC_FTINT_U_df  = (0x0D << 17) | OPC_MSA_2RF,
1266    OPC_FFINT_S_df  = (0x0E << 17) | OPC_MSA_2RF,
1267    OPC_FFINT_U_df  = (0x0F << 17) | OPC_MSA_2RF,
1268
1269    /* 3R instruction df(bits 22..21) = _b, _h, _w, d */
1270    OPC_SLL_df      = (0x0 << 23) | OPC_MSA_3R_0D,
1271    OPC_ADDV_df     = (0x0 << 23) | OPC_MSA_3R_0E,
1272    OPC_CEQ_df      = (0x0 << 23) | OPC_MSA_3R_0F,
1273    OPC_ADD_A_df    = (0x0 << 23) | OPC_MSA_3R_10,
1274    OPC_SUBS_S_df   = (0x0 << 23) | OPC_MSA_3R_11,
1275    OPC_MULV_df     = (0x0 << 23) | OPC_MSA_3R_12,
1276    OPC_DOTP_S_df   = (0x0 << 23) | OPC_MSA_3R_13,
1277    OPC_SLD_df      = (0x0 << 23) | OPC_MSA_3R_14,
1278    OPC_VSHF_df     = (0x0 << 23) | OPC_MSA_3R_15,
1279    OPC_SRA_df      = (0x1 << 23) | OPC_MSA_3R_0D,
1280    OPC_SUBV_df     = (0x1 << 23) | OPC_MSA_3R_0E,
1281    OPC_ADDS_A_df   = (0x1 << 23) | OPC_MSA_3R_10,
1282    OPC_SUBS_U_df   = (0x1 << 23) | OPC_MSA_3R_11,
1283    OPC_MADDV_df    = (0x1 << 23) | OPC_MSA_3R_12,
1284    OPC_DOTP_U_df   = (0x1 << 23) | OPC_MSA_3R_13,
1285    OPC_SPLAT_df    = (0x1 << 23) | OPC_MSA_3R_14,
1286    OPC_SRAR_df     = (0x1 << 23) | OPC_MSA_3R_15,
1287    OPC_SRL_df      = (0x2 << 23) | OPC_MSA_3R_0D,
1288    OPC_MAX_S_df    = (0x2 << 23) | OPC_MSA_3R_0E,
1289    OPC_CLT_S_df    = (0x2 << 23) | OPC_MSA_3R_0F,
1290    OPC_ADDS_S_df   = (0x2 << 23) | OPC_MSA_3R_10,
1291    OPC_SUBSUS_U_df = (0x2 << 23) | OPC_MSA_3R_11,
1292    OPC_MSUBV_df    = (0x2 << 23) | OPC_MSA_3R_12,
1293    OPC_DPADD_S_df  = (0x2 << 23) | OPC_MSA_3R_13,
1294    OPC_PCKEV_df    = (0x2 << 23) | OPC_MSA_3R_14,
1295    OPC_SRLR_df     = (0x2 << 23) | OPC_MSA_3R_15,
1296    OPC_BCLR_df     = (0x3 << 23) | OPC_MSA_3R_0D,
1297    OPC_MAX_U_df    = (0x3 << 23) | OPC_MSA_3R_0E,
1298    OPC_CLT_U_df    = (0x3 << 23) | OPC_MSA_3R_0F,
1299    OPC_ADDS_U_df   = (0x3 << 23) | OPC_MSA_3R_10,
1300    OPC_SUBSUU_S_df = (0x3 << 23) | OPC_MSA_3R_11,
1301    OPC_DPADD_U_df  = (0x3 << 23) | OPC_MSA_3R_13,
1302    OPC_PCKOD_df    = (0x3 << 23) | OPC_MSA_3R_14,
1303    OPC_BSET_df     = (0x4 << 23) | OPC_MSA_3R_0D,
1304    OPC_MIN_S_df    = (0x4 << 23) | OPC_MSA_3R_0E,
1305    OPC_CLE_S_df    = (0x4 << 23) | OPC_MSA_3R_0F,
1306    OPC_AVE_S_df    = (0x4 << 23) | OPC_MSA_3R_10,
1307    OPC_ASUB_S_df   = (0x4 << 23) | OPC_MSA_3R_11,
1308    OPC_DIV_S_df    = (0x4 << 23) | OPC_MSA_3R_12,
1309    OPC_DPSUB_S_df  = (0x4 << 23) | OPC_MSA_3R_13,
1310    OPC_ILVL_df     = (0x4 << 23) | OPC_MSA_3R_14,
1311    OPC_HADD_S_df   = (0x4 << 23) | OPC_MSA_3R_15,
1312    OPC_BNEG_df     = (0x5 << 23) | OPC_MSA_3R_0D,
1313    OPC_MIN_U_df    = (0x5 << 23) | OPC_MSA_3R_0E,
1314    OPC_CLE_U_df    = (0x5 << 23) | OPC_MSA_3R_0F,
1315    OPC_AVE_U_df    = (0x5 << 23) | OPC_MSA_3R_10,
1316    OPC_ASUB_U_df   = (0x5 << 23) | OPC_MSA_3R_11,
1317    OPC_DIV_U_df    = (0x5 << 23) | OPC_MSA_3R_12,
1318    OPC_DPSUB_U_df  = (0x5 << 23) | OPC_MSA_3R_13,
1319    OPC_ILVR_df     = (0x5 << 23) | OPC_MSA_3R_14,
1320    OPC_HADD_U_df   = (0x5 << 23) | OPC_MSA_3R_15,
1321    OPC_BINSL_df    = (0x6 << 23) | OPC_MSA_3R_0D,
1322    OPC_MAX_A_df    = (0x6 << 23) | OPC_MSA_3R_0E,
1323    OPC_AVER_S_df   = (0x6 << 23) | OPC_MSA_3R_10,
1324    OPC_MOD_S_df    = (0x6 << 23) | OPC_MSA_3R_12,
1325    OPC_ILVEV_df    = (0x6 << 23) | OPC_MSA_3R_14,
1326    OPC_HSUB_S_df   = (0x6 << 23) | OPC_MSA_3R_15,
1327    OPC_BINSR_df    = (0x7 << 23) | OPC_MSA_3R_0D,
1328    OPC_MIN_A_df    = (0x7 << 23) | OPC_MSA_3R_0E,
1329    OPC_AVER_U_df   = (0x7 << 23) | OPC_MSA_3R_10,
1330    OPC_MOD_U_df    = (0x7 << 23) | OPC_MSA_3R_12,
1331    OPC_ILVOD_df    = (0x7 << 23) | OPC_MSA_3R_14,
1332    OPC_HSUB_U_df   = (0x7 << 23) | OPC_MSA_3R_15,
1333
1334    /* ELM instructions df(bits 21..16) = _b, _h, _w, _d */
1335    OPC_SLDI_df     = (0x0 << 22) | (0x00 << 16) | OPC_MSA_ELM,
1336    OPC_CTCMSA      = (0x0 << 22) | (0x3E << 16) | OPC_MSA_ELM,
1337    OPC_SPLATI_df   = (0x1 << 22) | (0x00 << 16) | OPC_MSA_ELM,
1338    OPC_CFCMSA      = (0x1 << 22) | (0x3E << 16) | OPC_MSA_ELM,
1339    OPC_COPY_S_df   = (0x2 << 22) | (0x00 << 16) | OPC_MSA_ELM,
1340    OPC_MOVE_V      = (0x2 << 22) | (0x3E << 16) | OPC_MSA_ELM,
1341    OPC_COPY_U_df   = (0x3 << 22) | (0x00 << 16) | OPC_MSA_ELM,
1342    OPC_INSERT_df   = (0x4 << 22) | (0x00 << 16) | OPC_MSA_ELM,
1343    OPC_INSVE_df    = (0x5 << 22) | (0x00 << 16) | OPC_MSA_ELM,
1344
1345    /* 3RF instruction _df(bit 21) = _w, _d */
1346    OPC_FCAF_df     = (0x0 << 22) | OPC_MSA_3RF_1A,
1347    OPC_FADD_df     = (0x0 << 22) | OPC_MSA_3RF_1B,
1348    OPC_FCUN_df     = (0x1 << 22) | OPC_MSA_3RF_1A,
1349    OPC_FSUB_df     = (0x1 << 22) | OPC_MSA_3RF_1B,
1350    OPC_FCOR_df     = (0x1 << 22) | OPC_MSA_3RF_1C,
1351    OPC_FCEQ_df     = (0x2 << 22) | OPC_MSA_3RF_1A,
1352    OPC_FMUL_df     = (0x2 << 22) | OPC_MSA_3RF_1B,
1353    OPC_FCUNE_df    = (0x2 << 22) | OPC_MSA_3RF_1C,
1354    OPC_FCUEQ_df    = (0x3 << 22) | OPC_MSA_3RF_1A,
1355    OPC_FDIV_df     = (0x3 << 22) | OPC_MSA_3RF_1B,
1356    OPC_FCNE_df     = (0x3 << 22) | OPC_MSA_3RF_1C,
1357    OPC_FCLT_df     = (0x4 << 22) | OPC_MSA_3RF_1A,
1358    OPC_FMADD_df    = (0x4 << 22) | OPC_MSA_3RF_1B,
1359    OPC_MUL_Q_df    = (0x4 << 22) | OPC_MSA_3RF_1C,
1360    OPC_FCULT_df    = (0x5 << 22) | OPC_MSA_3RF_1A,
1361    OPC_FMSUB_df    = (0x5 << 22) | OPC_MSA_3RF_1B,
1362    OPC_MADD_Q_df   = (0x5 << 22) | OPC_MSA_3RF_1C,
1363    OPC_FCLE_df     = (0x6 << 22) | OPC_MSA_3RF_1A,
1364    OPC_MSUB_Q_df   = (0x6 << 22) | OPC_MSA_3RF_1C,
1365    OPC_FCULE_df    = (0x7 << 22) | OPC_MSA_3RF_1A,
1366    OPC_FEXP2_df    = (0x7 << 22) | OPC_MSA_3RF_1B,
1367    OPC_FSAF_df     = (0x8 << 22) | OPC_MSA_3RF_1A,
1368    OPC_FEXDO_df    = (0x8 << 22) | OPC_MSA_3RF_1B,
1369    OPC_FSUN_df     = (0x9 << 22) | OPC_MSA_3RF_1A,
1370    OPC_FSOR_df     = (0x9 << 22) | OPC_MSA_3RF_1C,
1371    OPC_FSEQ_df     = (0xA << 22) | OPC_MSA_3RF_1A,
1372    OPC_FTQ_df      = (0xA << 22) | OPC_MSA_3RF_1B,
1373    OPC_FSUNE_df    = (0xA << 22) | OPC_MSA_3RF_1C,
1374    OPC_FSUEQ_df    = (0xB << 22) | OPC_MSA_3RF_1A,
1375    OPC_FSNE_df     = (0xB << 22) | OPC_MSA_3RF_1C,
1376    OPC_FSLT_df     = (0xC << 22) | OPC_MSA_3RF_1A,
1377    OPC_FMIN_df     = (0xC << 22) | OPC_MSA_3RF_1B,
1378    OPC_MULR_Q_df   = (0xC << 22) | OPC_MSA_3RF_1C,
1379    OPC_FSULT_df    = (0xD << 22) | OPC_MSA_3RF_1A,
1380    OPC_FMIN_A_df   = (0xD << 22) | OPC_MSA_3RF_1B,
1381    OPC_MADDR_Q_df  = (0xD << 22) | OPC_MSA_3RF_1C,
1382    OPC_FSLE_df     = (0xE << 22) | OPC_MSA_3RF_1A,
1383    OPC_FMAX_df     = (0xE << 22) | OPC_MSA_3RF_1B,
1384    OPC_MSUBR_Q_df  = (0xE << 22) | OPC_MSA_3RF_1C,
1385    OPC_FSULE_df    = (0xF << 22) | OPC_MSA_3RF_1A,
1386    OPC_FMAX_A_df   = (0xF << 22) | OPC_MSA_3RF_1B,
1387
1388    /* BIT instruction df(bits 22..16) = _B _H _W _D */
1389    OPC_SLLI_df     = (0x0 << 23) | OPC_MSA_BIT_09,
1390    OPC_SAT_S_df    = (0x0 << 23) | OPC_MSA_BIT_0A,
1391    OPC_SRAI_df     = (0x1 << 23) | OPC_MSA_BIT_09,
1392    OPC_SAT_U_df    = (0x1 << 23) | OPC_MSA_BIT_0A,
1393    OPC_SRLI_df     = (0x2 << 23) | OPC_MSA_BIT_09,
1394    OPC_SRARI_df    = (0x2 << 23) | OPC_MSA_BIT_0A,
1395    OPC_BCLRI_df    = (0x3 << 23) | OPC_MSA_BIT_09,
1396    OPC_SRLRI_df    = (0x3 << 23) | OPC_MSA_BIT_0A,
1397    OPC_BSETI_df    = (0x4 << 23) | OPC_MSA_BIT_09,
1398    OPC_BNEGI_df    = (0x5 << 23) | OPC_MSA_BIT_09,
1399    OPC_BINSLI_df   = (0x6 << 23) | OPC_MSA_BIT_09,
1400    OPC_BINSRI_df   = (0x7 << 23) | OPC_MSA_BIT_09,
1401};
1402
1403
1404/*
1405 *
1406 *       AN OVERVIEW OF MXU EXTENSION INSTRUCTION SET
1407 *       ============================================
1408 *
1409 *
1410 * MXU (full name: MIPS eXtension/enhanced Unit) is a SIMD extension of MIPS32
1411 * instructions set. It is designed to fit the needs of signal, graphical and
1412 * video processing applications. MXU instruction set is used in Xburst family
1413 * of microprocessors by Ingenic.
1414 *
1415 * MXU unit contains 17 registers called X0-X16. X0 is always zero, and X16 is
1416 * the control register.
1417 *
1418 *
1419 *     The notation used in MXU assembler mnemonics
1420 *     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1421 *
1422 *  Register operands:
1423 *
1424 *   XRa, XRb, XRc, XRd - MXU registers
1425 *   Rb, Rc, Rd, Rs, Rt - general purpose MIPS registers
1426 *
1427 *  Non-register operands:
1428 *
1429 *   aptn1 - 1-bit accumulate add/subtract pattern
1430 *   aptn2 - 2-bit accumulate add/subtract pattern
1431 *   eptn2 - 2-bit execute add/subtract pattern
1432 *   optn2 - 2-bit operand pattern
1433 *   optn3 - 3-bit operand pattern
1434 *   sft4  - 4-bit shift amount
1435 *   strd2 - 2-bit stride amount
1436 *
1437 *  Prefixes:
1438 *
1439 *   Level of parallelism:                Operand size:
1440 *    S - single operation at a time       32 - word
1441 *    D - two operations in parallel       16 - half word
1442 *    Q - four operations in parallel       8 - byte
1443 *
1444 *  Operations:
1445 *
1446 *   ADD   - Add or subtract
1447 *   ADDC  - Add with carry-in
1448 *   ACC   - Accumulate
1449 *   ASUM  - Sum together then accumulate (add or subtract)
1450 *   ASUMC - Sum together then accumulate (add or subtract) with carry-in
1451 *   AVG   - Average between 2 operands
1452 *   ABD   - Absolute difference
1453 *   ALN   - Align data
1454 *   AND   - Logical bitwise 'and' operation
1455 *   CPS   - Copy sign
1456 *   EXTR  - Extract bits
1457 *   I2M   - Move from GPR register to MXU register
1458 *   LDD   - Load data from memory to XRF
1459 *   LDI   - Load data from memory to XRF (and increase the address base)
1460 *   LUI   - Load unsigned immediate
1461 *   MUL   - Multiply
1462 *   MULU  - Unsigned multiply
1463 *   MADD  - 64-bit operand add 32x32 product
1464 *   MSUB  - 64-bit operand subtract 32x32 product
1465 *   MAC   - Multiply and accumulate (add or subtract)
1466 *   MAD   - Multiply and add or subtract
1467 *   MAX   - Maximum between 2 operands
1468 *   MIN   - Minimum between 2 operands
1469 *   M2I   - Move from MXU register to GPR register
1470 *   MOVZ  - Move if zero
1471 *   MOVN  - Move if non-zero
1472 *   NOR   - Logical bitwise 'nor' operation
1473 *   OR    - Logical bitwise 'or' operation
1474 *   STD   - Store data from XRF to memory
1475 *   SDI   - Store data from XRF to memory (and increase the address base)
1476 *   SLT   - Set of less than comparison
1477 *   SAD   - Sum of absolute differences
1478 *   SLL   - Logical shift left
1479 *   SLR   - Logical shift right
1480 *   SAR   - Arithmetic shift right
1481 *   SAT   - Saturation
1482 *   SFL   - Shuffle
1483 *   SCOP  - Calculate x’s scope (-1, means x<0; 0, means x==0; 1, means x>0)
1484 *   XOR   - Logical bitwise 'exclusive or' operation
1485 *
1486 *  Suffixes:
1487 *
1488 *   E - Expand results
1489 *   F - Fixed point multiplication
1490 *   L - Low part result
1491 *   R - Doing rounding
1492 *   V - Variable instead of immediate
1493 *   W - Combine above L and V
1494 *
1495 *
1496 *     The list of MXU instructions grouped by functionality
1497 *     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1498 *
1499 * Load/Store instructions           Multiplication instructions
1500 * -----------------------           ---------------------------
1501 *
1502 *  S32LDD XRa, Rb, s12               S32MADD XRa, XRd, Rs, Rt
1503 *  S32STD XRa, Rb, s12               S32MADDU XRa, XRd, Rs, Rt
1504 *  S32LDDV XRa, Rb, rc, strd2        S32MSUB XRa, XRd, Rs, Rt
1505 *  S32STDV XRa, Rb, rc, strd2        S32MSUBU XRa, XRd, Rs, Rt
1506 *  S32LDI XRa, Rb, s12               S32MUL XRa, XRd, Rs, Rt
1507 *  S32SDI XRa, Rb, s12               S32MULU XRa, XRd, Rs, Rt
1508 *  S32LDIV XRa, Rb, rc, strd2        D16MUL XRa, XRb, XRc, XRd, optn2
1509 *  S32SDIV XRa, Rb, rc, strd2        D16MULE XRa, XRb, XRc, optn2
1510 *  S32LDDR XRa, Rb, s12              D16MULF XRa, XRb, XRc, optn2
1511 *  S32STDR XRa, Rb, s12              D16MAC XRa, XRb, XRc, XRd, aptn2, optn2
1512 *  S32LDDVR XRa, Rb, rc, strd2       D16MACE XRa, XRb, XRc, XRd, aptn2, optn2
1513 *  S32STDVR XRa, Rb, rc, strd2       D16MACF XRa, XRb, XRc, XRd, aptn2, optn2
1514 *  S32LDIR XRa, Rb, s12              D16MADL XRa, XRb, XRc, XRd, aptn2, optn2
1515 *  S32SDIR XRa, Rb, s12              S16MAD XRa, XRb, XRc, XRd, aptn1, optn2
1516 *  S32LDIVR XRa, Rb, rc, strd2       Q8MUL XRa, XRb, XRc, XRd
1517 *  S32SDIVR XRa, Rb, rc, strd2       Q8MULSU XRa, XRb, XRc, XRd
1518 *  S16LDD XRa, Rb, s10, eptn2        Q8MAC XRa, XRb, XRc, XRd, aptn2
1519 *  S16STD XRa, Rb, s10, eptn2        Q8MACSU XRa, XRb, XRc, XRd, aptn2
1520 *  S16LDI XRa, Rb, s10, eptn2        Q8MADL XRa, XRb, XRc, XRd, aptn2
1521 *  S16SDI XRa, Rb, s10, eptn2
1522 *  S8LDD XRa, Rb, s8, eptn3
1523 *  S8STD XRa, Rb, s8, eptn3         Addition and subtraction instructions
1524 *  S8LDI XRa, Rb, s8, eptn3         -------------------------------------
1525 *  S8SDI XRa, Rb, s8, eptn3
1526 *  LXW Rd, Rs, Rt, strd2             D32ADD XRa, XRb, XRc, XRd, eptn2
1527 *  LXH Rd, Rs, Rt, strd2             D32ADDC XRa, XRb, XRc, XRd
1528 *  LXHU Rd, Rs, Rt, strd2            D32ACC XRa, XRb, XRc, XRd, eptn2
1529 *  LXB Rd, Rs, Rt, strd2             D32ACCM XRa, XRb, XRc, XRd, eptn2
1530 *  LXBU Rd, Rs, Rt, strd2            D32ASUM XRa, XRb, XRc, XRd, eptn2
1531 *                                    S32CPS XRa, XRb, XRc
1532 *                                    Q16ADD XRa, XRb, XRc, XRd, eptn2, optn2
1533 * Comparison instructions            Q16ACC XRa, XRb, XRc, XRd, eptn2
1534 * -----------------------            Q16ACCM XRa, XRb, XRc, XRd, eptn2
1535 *                                    D16ASUM XRa, XRb, XRc, XRd, eptn2
1536 *  S32MAX XRa, XRb, XRc              D16CPS XRa, XRb,
1537 *  S32MIN XRa, XRb, XRc              D16AVG XRa, XRb, XRc
1538 *  S32SLT XRa, XRb, XRc              D16AVGR XRa, XRb, XRc
1539 *  S32MOVZ XRa, XRb, XRc             Q8ADD XRa, XRb, XRc, eptn2
1540 *  S32MOVN XRa, XRb, XRc             Q8ADDE XRa, XRb, XRc, XRd, eptn2
1541 *  D16MAX XRa, XRb, XRc              Q8ACCE XRa, XRb, XRc, XRd, eptn2
1542 *  D16MIN XRa, XRb, XRc              Q8ABD XRa, XRb, XRc
1543 *  D16SLT XRa, XRb, XRc              Q8SAD XRa, XRb, XRc, XRd
1544 *  D16MOVZ XRa, XRb, XRc             Q8AVG XRa, XRb, XRc
1545 *  D16MOVN XRa, XRb, XRc             Q8AVGR XRa, XRb, XRc
1546 *  Q8MAX XRa, XRb, XRc               D8SUM XRa, XRb, XRc, XRd
1547 *  Q8MIN XRa, XRb, XRc               D8SUMC XRa, XRb, XRc, XRd
1548 *  Q8SLT XRa, XRb, XRc
1549 *  Q8SLTU XRa, XRb, XRc
1550 *  Q8MOVZ XRa, XRb, XRc             Shift instructions
1551 *  Q8MOVN XRa, XRb, XRc             ------------------
1552 *
1553 *                                    D32SLL XRa, XRb, XRc, XRd, sft4
1554 * Bitwise instructions               D32SLR XRa, XRb, XRc, XRd, sft4
1555 * --------------------               D32SAR XRa, XRb, XRc, XRd, sft4
1556 *                                    D32SARL XRa, XRb, XRc, sft4
1557 *  S32NOR XRa, XRb, XRc              D32SLLV XRa, XRb, Rb
1558 *  S32AND XRa, XRb, XRc              D32SLRV XRa, XRb, Rb
1559 *  S32XOR XRa, XRb, XRc              D32SARV XRa, XRb, Rb
1560 *  S32OR XRa, XRb, XRc               D32SARW XRa, XRb, XRc, Rb
1561 *                                    Q16SLL XRa, XRb, XRc, XRd, sft4
1562 *                                    Q16SLR XRa, XRb, XRc, XRd, sft4
1563 * Miscellaneous instructions         Q16SAR XRa, XRb, XRc, XRd, sft4
1564 * -------------------------          Q16SLLV XRa, XRb, Rb
1565 *                                    Q16SLRV XRa, XRb, Rb
1566 *  S32SFL XRa, XRb, XRc, XRd, optn2  Q16SARV XRa, XRb, Rb
1567 *  S32ALN XRa, XRb, XRc, Rb
1568 *  S32ALNI XRa, XRb, XRc, s3
1569 *  S32LUI XRa, s8, optn3            Move instructions
1570 *  S32EXTR XRa, XRb, Rb, bits5      -----------------
1571 *  S32EXTRV XRa, XRb, Rs, Rt
1572 *  Q16SCOP XRa, XRb, XRc, XRd        S32M2I XRa, Rb
1573 *  Q16SAT XRa, XRb, XRc              S32I2M XRa, Rb
1574 *
1575 *
1576 *     The opcode organization of MXU instructions
1577 *     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1578 *
1579 * The bits 31..26 of all MXU instructions are equal to 0x1C (also referred
1580 * as opcode SPECIAL2 in the base MIPS ISA). The organization and meaning of
1581 * other bits up to the instruction level is as follows:
1582 *
1583 *              bits
1584 *             05..00
1585 *
1586 *          ┌─ 000000 ─ OPC_MXU_S32MADD
1587 *          ├─ 000001 ─ OPC_MXU_S32MADDU
1588 *          ├─ 000010 ─ <not assigned>   (non-MXU OPC_MUL)
1589 *          │
1590 *          │                               20..18
1591 *          ├─ 000011 ─ OPC_MXU__POOL00 ─┬─ 000 ─ OPC_MXU_S32MAX
1592 *          │                            ├─ 001 ─ OPC_MXU_S32MIN
1593 *          │                            ├─ 010 ─ OPC_MXU_D16MAX
1594 *          │                            ├─ 011 ─ OPC_MXU_D16MIN
1595 *          │                            ├─ 100 ─ OPC_MXU_Q8MAX
1596 *          │                            ├─ 101 ─ OPC_MXU_Q8MIN
1597 *          │                            ├─ 110 ─ OPC_MXU_Q8SLT
1598 *          │                            └─ 111 ─ OPC_MXU_Q8SLTU
1599 *          ├─ 000100 ─ OPC_MXU_S32MSUB
1600 *          ├─ 000101 ─ OPC_MXU_S32MSUBU    20..18
1601 *          ├─ 000110 ─ OPC_MXU__POOL01 ─┬─ 000 ─ OPC_MXU_S32SLT
1602 *          │                            ├─ 001 ─ OPC_MXU_D16SLT
1603 *          │                            ├─ 010 ─ OPC_MXU_D16AVG
1604 *          │                            ├─ 011 ─ OPC_MXU_D16AVGR
1605 *          │                            ├─ 100 ─ OPC_MXU_Q8AVG
1606 *          │                            ├─ 101 ─ OPC_MXU_Q8AVGR
1607 *          │                            └─ 111 ─ OPC_MXU_Q8ADD
1608 *          │
1609 *          │                               20..18
1610 *          ├─ 000111 ─ OPC_MXU__POOL02 ─┬─ 000 ─ OPC_MXU_S32CPS
1611 *          │                            ├─ 010 ─ OPC_MXU_D16CPS
1612 *          │                            ├─ 100 ─ OPC_MXU_Q8ABD
1613 *          │                            └─ 110 ─ OPC_MXU_Q16SAT
1614 *          ├─ 001000 ─ OPC_MXU_D16MUL
1615 *          │                               25..24
1616 *          ├─ 001001 ─ OPC_MXU__POOL03 ─┬─ 00 ─ OPC_MXU_D16MULF
1617 *          │                            └─ 01 ─ OPC_MXU_D16MULE
1618 *          ├─ 001010 ─ OPC_MXU_D16MAC
1619 *          ├─ 001011 ─ OPC_MXU_D16MACF
1620 *          ├─ 001100 ─ OPC_MXU_D16MADL
1621 *          ├─ 001101 ─ OPC_MXU_S16MAD
1622 *          ├─ 001110 ─ OPC_MXU_Q16ADD
1623 *          ├─ 001111 ─ OPC_MXU_D16MACE     23
1624 *          │                            ┌─ 0 ─ OPC_MXU_S32LDD
1625 *          ├─ 010000 ─ OPC_MXU__POOL04 ─┴─ 1 ─ OPC_MXU_S32LDDR
1626 *          │
1627 *          │                               23
1628 *          ├─ 010001 ─ OPC_MXU__POOL05 ─┬─ 0 ─ OPC_MXU_S32STD
1629 *          │                            └─ 1 ─ OPC_MXU_S32STDR
1630 *          │
1631 *          │                               13..10
1632 *          ├─ 010010 ─ OPC_MXU__POOL06 ─┬─ 0000 ─ OPC_MXU_S32LDDV
1633 *          │                            └─ 0001 ─ OPC_MXU_S32LDDVR
1634 *          │
1635 *          │                               13..10
1636 *          ├─ 010011 ─ OPC_MXU__POOL07 ─┬─ 0000 ─ OPC_MXU_S32STDV
1637 *          │                            └─ 0001 ─ OPC_MXU_S32STDVR
1638 *          │
1639 *          │                               23
1640 *          ├─ 010100 ─ OPC_MXU__POOL08 ─┬─ 0 ─ OPC_MXU_S32LDI
1641 *          │                            └─ 1 ─ OPC_MXU_S32LDIR
1642 *          │
1643 *          │                               23
1644 *          ├─ 010101 ─ OPC_MXU__POOL09 ─┬─ 0 ─ OPC_MXU_S32SDI
1645 *          │                            └─ 1 ─ OPC_MXU_S32SDIR
1646 *          │
1647 *          │                               13..10
1648 *          ├─ 010110 ─ OPC_MXU__POOL10 ─┬─ 0000 ─ OPC_MXU_S32LDIV
1649 *          │                            └─ 0001 ─ OPC_MXU_S32LDIVR
1650 *          │
1651 *          │                               13..10
1652 *          ├─ 010111 ─ OPC_MXU__POOL11 ─┬─ 0000 ─ OPC_MXU_S32SDIV
1653 *          │                            └─ 0001 ─ OPC_MXU_S32SDIVR
1654 *          ├─ 011000 ─ OPC_MXU_D32ADD
1655 *          │                               23..22
1656 *   MXU    ├─ 011001 ─ OPC_MXU__POOL12 ─┬─ 00 ─ OPC_MXU_D32ACC
1657 * opcodes ─┤                            ├─ 01 ─ OPC_MXU_D32ACCM
1658 *          │                            └─ 10 ─ OPC_MXU_D32ASUM
1659 *          ├─ 011010 ─ <not assigned>
1660 *          │                               23..22
1661 *          ├─ 011011 ─ OPC_MXU__POOL13 ─┬─ 00 ─ OPC_MXU_Q16ACC
1662 *          │                            ├─ 01 ─ OPC_MXU_Q16ACCM
1663 *          │                            └─ 10 ─ OPC_MXU_Q16ASUM
1664 *          │
1665 *          │                               23..22
1666 *          ├─ 011100 ─ OPC_MXU__POOL14 ─┬─ 00 ─ OPC_MXU_Q8ADDE
1667 *          │                            ├─ 01 ─ OPC_MXU_D8SUM
1668 *          ├─ 011101 ─ OPC_MXU_Q8ACCE   └─ 10 ─ OPC_MXU_D8SUMC
1669 *          ├─ 011110 ─ <not assigned>
1670 *          ├─ 011111 ─ <not assigned>
1671 *          ├─ 100000 ─ <not assigned>   (overlaps with CLZ)
1672 *          ├─ 100001 ─ <not assigned>   (overlaps with CLO)
1673 *          ├─ 100010 ─ OPC_MXU_S8LDD
1674 *          ├─ 100011 ─ OPC_MXU_S8STD       15..14
1675 *          ├─ 100100 ─ OPC_MXU_S8LDI    ┌─ 00 ─ OPC_MXU_S32MUL
1676 *          ├─ 100101 ─ OPC_MXU_S8SDI    ├─ 00 ─ OPC_MXU_S32MULU
1677 *          │                            ├─ 00 ─ OPC_MXU_S32EXTR
1678 *          ├─ 100110 ─ OPC_MXU__POOL15 ─┴─ 00 ─ OPC_MXU_S32EXTRV
1679 *          │
1680 *          │                               20..18
1681 *          ├─ 100111 ─ OPC_MXU__POOL16 ─┬─ 000 ─ OPC_MXU_D32SARW
1682 *          │                            ├─ 001 ─ OPC_MXU_S32ALN
1683 *          │                            ├─ 010 ─ OPC_MXU_S32ALNI
1684 *          │                            ├─ 011 ─ OPC_MXU_S32LUI
1685 *          │                            ├─ 100 ─ OPC_MXU_S32NOR
1686 *          │                            ├─ 101 ─ OPC_MXU_S32AND
1687 *          │                            ├─ 110 ─ OPC_MXU_S32OR
1688 *          │                            └─ 111 ─ OPC_MXU_S32XOR
1689 *          │
1690 *          │                               7..5
1691 *          ├─ 101000 ─ OPC_MXU__POOL17 ─┬─ 000 ─ OPC_MXU_LXB
1692 *          │                            ├─ 001 ─ OPC_MXU_LXH
1693 *          ├─ 101001 ─ <not assigned>   ├─ 011 ─ OPC_MXU_LXW
1694 *          ├─ 101010 ─ OPC_MXU_S16LDD   ├─ 100 ─ OPC_MXU_LXBU
1695 *          ├─ 101011 ─ OPC_MXU_S16STD   └─ 101 ─ OPC_MXU_LXHU
1696 *          ├─ 101100 ─ OPC_MXU_S16LDI
1697 *          ├─ 101101 ─ OPC_MXU_S16SDI
1698 *          ├─ 101110 ─ OPC_MXU_S32M2I
1699 *          ├─ 101111 ─ OPC_MXU_S32I2M
1700 *          ├─ 110000 ─ OPC_MXU_D32SLL
1701 *          ├─ 110001 ─ OPC_MXU_D32SLR      20..18
1702 *          ├─ 110010 ─ OPC_MXU_D32SARL  ┌─ 000 ─ OPC_MXU_D32SLLV
1703 *          ├─ 110011 ─ OPC_MXU_D32SAR   ├─ 001 ─ OPC_MXU_D32SLRV
1704 *          ├─ 110100 ─ OPC_MXU_Q16SLL   ├─ 010 ─ OPC_MXU_D32SARV
1705 *          ├─ 110101 ─ OPC_MXU_Q16SLR   ├─ 011 ─ OPC_MXU_Q16SLLV
1706 *          │                            ├─ 100 ─ OPC_MXU_Q16SLRV
1707 *          ├─ 110110 ─ OPC_MXU__POOL18 ─┴─ 101 ─ OPC_MXU_Q16SARV
1708 *          │
1709 *          ├─ 110111 ─ OPC_MXU_Q16SAR
1710 *          │                               23..22
1711 *          ├─ 111000 ─ OPC_MXU__POOL19 ─┬─ 00 ─ OPC_MXU_Q8MUL
1712 *          │                            └─ 01 ─ OPC_MXU_Q8MULSU
1713 *          │
1714 *          │                               20..18
1715 *          ├─ 111001 ─ OPC_MXU__POOL20 ─┬─ 000 ─ OPC_MXU_Q8MOVZ
1716 *          │                            ├─ 001 ─ OPC_MXU_Q8MOVN
1717 *          │                            ├─ 010 ─ OPC_MXU_D16MOVZ
1718 *          │                            ├─ 011 ─ OPC_MXU_D16MOVN
1719 *          │                            ├─ 100 ─ OPC_MXU_S32MOVZ
1720 *          │                            └─ 101 ─ OPC_MXU_S32MOVN
1721 *          │
1722 *          │                               23..22
1723 *          ├─ 111010 ─ OPC_MXU__POOL21 ─┬─ 00 ─ OPC_MXU_Q8MAC
1724 *          │                            └─ 10 ─ OPC_MXU_Q8MACSU
1725 *          ├─ 111011 ─ OPC_MXU_Q16SCOP
1726 *          ├─ 111100 ─ OPC_MXU_Q8MADL
1727 *          ├─ 111101 ─ OPC_MXU_S32SFL
1728 *          ├─ 111110 ─ OPC_MXU_Q8SAD
1729 *          └─ 111111 ─ <not assigned>   (overlaps with SDBBP)
1730 *
1731 *
1732 * Compiled after:
1733 *
1734 *   "XBurst® Instruction Set Architecture MIPS eXtension/enhanced Unit
1735 *   Programming Manual", Ingenic Semiconductor Co, Ltd., revision June 2, 2017
1736 */
1737
1738enum {
1739    OPC_MXU_S32MADD  = 0x00,
1740    OPC_MXU_S32MADDU = 0x01,
1741    OPC__MXU_MUL     = 0x02,
1742    OPC_MXU__POOL00  = 0x03,
1743    OPC_MXU_S32MSUB  = 0x04,
1744    OPC_MXU_S32MSUBU = 0x05,
1745    OPC_MXU__POOL01  = 0x06,
1746    OPC_MXU__POOL02  = 0x07,
1747    OPC_MXU_D16MUL   = 0x08,
1748    OPC_MXU__POOL03  = 0x09,
1749    OPC_MXU_D16MAC   = 0x0A,
1750    OPC_MXU_D16MACF  = 0x0B,
1751    OPC_MXU_D16MADL  = 0x0C,
1752    OPC_MXU_S16MAD   = 0x0D,
1753    OPC_MXU_Q16ADD   = 0x0E,
1754    OPC_MXU_D16MACE  = 0x0F,
1755    OPC_MXU__POOL04  = 0x10,
1756    OPC_MXU__POOL05  = 0x11,
1757    OPC_MXU__POOL06  = 0x12,
1758    OPC_MXU__POOL07  = 0x13,
1759    OPC_MXU__POOL08  = 0x14,
1760    OPC_MXU__POOL09  = 0x15,
1761    OPC_MXU__POOL10  = 0x16,
1762    OPC_MXU__POOL11  = 0x17,
1763    OPC_MXU_D32ADD   = 0x18,
1764    OPC_MXU__POOL12  = 0x19,
1765    /* not assigned 0x1A */
1766    OPC_MXU__POOL13  = 0x1B,
1767    OPC_MXU__POOL14  = 0x1C,
1768    OPC_MXU_Q8ACCE   = 0x1D,
1769    /* not assigned 0x1E */
1770    /* not assigned 0x1F */
1771    /* not assigned 0x20 */
1772    /* not assigned 0x21 */
1773    OPC_MXU_S8LDD    = 0x22,
1774    OPC_MXU_S8STD    = 0x23,
1775    OPC_MXU_S8LDI    = 0x24,
1776    OPC_MXU_S8SDI    = 0x25,
1777    OPC_MXU__POOL15  = 0x26,
1778    OPC_MXU__POOL16  = 0x27,
1779    OPC_MXU__POOL17  = 0x28,
1780    /* not assigned 0x29 */
1781    OPC_MXU_S16LDD   = 0x2A,
1782    OPC_MXU_S16STD   = 0x2B,
1783    OPC_MXU_S16LDI   = 0x2C,
1784    OPC_MXU_S16SDI   = 0x2D,
1785    OPC_MXU_S32M2I   = 0x2E,
1786    OPC_MXU_S32I2M   = 0x2F,
1787    OPC_MXU_D32SLL   = 0x30,
1788    OPC_MXU_D32SLR   = 0x31,
1789    OPC_MXU_D32SARL  = 0x32,
1790    OPC_MXU_D32SAR   = 0x33,
1791    OPC_MXU_Q16SLL   = 0x34,
1792    OPC_MXU_Q16SLR   = 0x35,
1793    OPC_MXU__POOL18  = 0x36,
1794    OPC_MXU_Q16SAR   = 0x37,
1795    OPC_MXU__POOL19  = 0x38,
1796    OPC_MXU__POOL20  = 0x39,
1797    OPC_MXU__POOL21  = 0x3A,
1798    OPC_MXU_Q16SCOP  = 0x3B,
1799    OPC_MXU_Q8MADL   = 0x3C,
1800    OPC_MXU_S32SFL   = 0x3D,
1801    OPC_MXU_Q8SAD    = 0x3E,
1802    /* not assigned 0x3F */
1803};
1804
1805
1806/*
1807 * MXU pool 00
1808 */
1809enum {
1810    OPC_MXU_S32MAX   = 0x00,
1811    OPC_MXU_S32MIN   = 0x01,
1812    OPC_MXU_D16MAX   = 0x02,
1813    OPC_MXU_D16MIN   = 0x03,
1814    OPC_MXU_Q8MAX    = 0x04,
1815    OPC_MXU_Q8MIN    = 0x05,
1816    OPC_MXU_Q8SLT    = 0x06,
1817    OPC_MXU_Q8SLTU   = 0x07,
1818};
1819
1820/*
1821 * MXU pool 01
1822 */
1823enum {
1824    OPC_MXU_S32SLT   = 0x00,
1825    OPC_MXU_D16SLT   = 0x01,
1826    OPC_MXU_D16AVG   = 0x02,
1827    OPC_MXU_D16AVGR  = 0x03,
1828    OPC_MXU_Q8AVG    = 0x04,
1829    OPC_MXU_Q8AVGR   = 0x05,
1830    OPC_MXU_Q8ADD    = 0x07,
1831};
1832
1833/*
1834 * MXU pool 02
1835 */
1836enum {
1837    OPC_MXU_S32CPS   = 0x00,
1838    OPC_MXU_D16CPS   = 0x02,
1839    OPC_MXU_Q8ABD    = 0x04,
1840    OPC_MXU_Q16SAT   = 0x06,
1841};
1842
1843/*
1844 * MXU pool 03
1845 */
1846enum {
1847    OPC_MXU_D16MULF  = 0x00,
1848    OPC_MXU_D16MULE  = 0x01,
1849};
1850
1851/*
1852 * MXU pool 04
1853 */
1854enum {
1855    OPC_MXU_S32LDD   = 0x00,
1856    OPC_MXU_S32LDDR  = 0x01,
1857};
1858
1859/*
1860 * MXU pool 05
1861 */
1862enum {
1863    OPC_MXU_S32STD   = 0x00,
1864    OPC_MXU_S32STDR  = 0x01,
1865};
1866
1867/*
1868 * MXU pool 06
1869 */
1870enum {
1871    OPC_MXU_S32LDDV  = 0x00,
1872    OPC_MXU_S32LDDVR = 0x01,
1873};
1874
1875/*
1876 * MXU pool 07
1877 */
1878enum {
1879    OPC_MXU_S32STDV  = 0x00,
1880    OPC_MXU_S32STDVR = 0x01,
1881};
1882
1883/*
1884 * MXU pool 08
1885 */
1886enum {
1887    OPC_MXU_S32LDI   = 0x00,
1888    OPC_MXU_S32LDIR  = 0x01,
1889};
1890
1891/*
1892 * MXU pool 09
1893 */
1894enum {
1895    OPC_MXU_S32SDI   = 0x00,
1896    OPC_MXU_S32SDIR  = 0x01,
1897};
1898
1899/*
1900 * MXU pool 10
1901 */
1902enum {
1903    OPC_MXU_S32LDIV  = 0x00,
1904    OPC_MXU_S32LDIVR = 0x01,
1905};
1906
1907/*
1908 * MXU pool 11
1909 */
1910enum {
1911    OPC_MXU_S32SDIV  = 0x00,
1912    OPC_MXU_S32SDIVR = 0x01,
1913};
1914
1915/*
1916 * MXU pool 12
1917 */
1918enum {
1919    OPC_MXU_D32ACC   = 0x00,
1920    OPC_MXU_D32ACCM  = 0x01,
1921    OPC_MXU_D32ASUM  = 0x02,
1922};
1923
1924/*
1925 * MXU pool 13
1926 */
1927enum {
1928    OPC_MXU_Q16ACC   = 0x00,
1929    OPC_MXU_Q16ACCM  = 0x01,
1930    OPC_MXU_Q16ASUM  = 0x02,
1931};
1932
1933/*
1934 * MXU pool 14
1935 */
1936enum {
1937    OPC_MXU_Q8ADDE   = 0x00,
1938    OPC_MXU_D8SUM    = 0x01,
1939    OPC_MXU_D8SUMC   = 0x02,
1940};
1941
1942/*
1943 * MXU pool 15
1944 */
1945enum {
1946    OPC_MXU_S32MUL   = 0x00,
1947    OPC_MXU_S32MULU  = 0x01,
1948    OPC_MXU_S32EXTR  = 0x02,
1949    OPC_MXU_S32EXTRV = 0x03,
1950};
1951
1952/*
1953 * MXU pool 16
1954 */
1955enum {
1956    OPC_MXU_D32SARW  = 0x00,
1957    OPC_MXU_S32ALN   = 0x01,
1958    OPC_MXU_S32ALNI  = 0x02,
1959    OPC_MXU_S32LUI   = 0x03,
1960    OPC_MXU_S32NOR   = 0x04,
1961    OPC_MXU_S32AND   = 0x05,
1962    OPC_MXU_S32OR    = 0x06,
1963    OPC_MXU_S32XOR   = 0x07,
1964};
1965
1966/*
1967 * MXU pool 17
1968 */
1969enum {
1970    OPC_MXU_LXB      = 0x00,
1971    OPC_MXU_LXH      = 0x01,
1972    OPC_MXU_LXW      = 0x03,
1973    OPC_MXU_LXBU     = 0x04,
1974    OPC_MXU_LXHU     = 0x05,
1975};
1976
1977/*
1978 * MXU pool 18
1979 */
1980enum {
1981    OPC_MXU_D32SLLV  = 0x00,
1982    OPC_MXU_D32SLRV  = 0x01,
1983    OPC_MXU_D32SARV  = 0x03,
1984    OPC_MXU_Q16SLLV  = 0x04,
1985    OPC_MXU_Q16SLRV  = 0x05,
1986    OPC_MXU_Q16SARV  = 0x07,
1987};
1988
1989/*
1990 * MXU pool 19
1991 */
1992enum {
1993    OPC_MXU_Q8MUL    = 0x00,
1994    OPC_MXU_Q8MULSU  = 0x01,
1995};
1996
1997/*
1998 * MXU pool 20
1999 */
2000enum {
2001    OPC_MXU_Q8MOVZ   = 0x00,
2002    OPC_MXU_Q8MOVN   = 0x01,
2003    OPC_MXU_D16MOVZ  = 0x02,
2004    OPC_MXU_D16MOVN  = 0x03,
2005    OPC_MXU_S32MOVZ  = 0x04,
2006    OPC_MXU_S32MOVN  = 0x05,
2007};
2008
2009/*
2010 * MXU pool 21
2011 */
2012enum {
2013    OPC_MXU_Q8MAC    = 0x00,
2014    OPC_MXU_Q8MACSU  = 0x01,
2015};
2016
2017/*
2018 *     Overview of the TX79-specific instruction set
2019 *     =============================================
2020 *
2021 * The R5900 and the C790 have 128-bit wide GPRs, where the upper 64 bits
2022 * are only used by the specific quadword (128-bit) LQ/SQ load/store
2023 * instructions and certain multimedia instructions (MMIs). These MMIs
2024 * configure the 128-bit data path as two 64-bit, four 32-bit, eight 16-bit
2025 * or sixteen 8-bit paths.
2026 *
2027 * Reference:
2028 *
2029 * The Toshiba TX System RISC TX79 Core Architecture manual,
2030 * https://wiki.qemu.org/File:C790.pdf
2031 *
2032 *     Three-Operand Multiply and Multiply-Add (4 instructions)
2033 *     --------------------------------------------------------
2034 * MADD    [rd,] rs, rt      Multiply/Add
2035 * MADDU   [rd,] rs, rt      Multiply/Add Unsigned
2036 * MULT    [rd,] rs, rt      Multiply (3-operand)
2037 * MULTU   [rd,] rs, rt      Multiply Unsigned (3-operand)
2038 *
2039 *     Multiply Instructions for Pipeline 1 (10 instructions)
2040 *     ------------------------------------------------------
2041 * MULT1   [rd,] rs, rt      Multiply Pipeline 1
2042 * MULTU1  [rd,] rs, rt      Multiply Unsigned Pipeline 1
2043 * DIV1    rs, rt            Divide Pipeline 1
2044 * DIVU1   rs, rt            Divide Unsigned Pipeline 1
2045 * MADD1   [rd,] rs, rt      Multiply-Add Pipeline 1
2046 * MADDU1  [rd,] rs, rt      Multiply-Add Unsigned Pipeline 1
2047 * MFHI1   rd                Move From HI1 Register
2048 * MFLO1   rd                Move From LO1 Register
2049 * MTHI1   rs                Move To HI1 Register
2050 * MTLO1   rs                Move To LO1 Register
2051 *
2052 *     Arithmetic (19 instructions)
2053 *     ----------------------------
2054 * PADDB   rd, rs, rt        Parallel Add Byte
2055 * PSUBB   rd, rs, rt        Parallel Subtract Byte
2056 * PADDH   rd, rs, rt        Parallel Add Halfword
2057 * PSUBH   rd, rs, rt        Parallel Subtract Halfword
2058 * PADDW   rd, rs, rt        Parallel Add Word
2059 * PSUBW   rd, rs, rt        Parallel Subtract Word
2060 * PADSBH  rd, rs, rt        Parallel Add/Subtract Halfword
2061 * PADDSB  rd, rs, rt        Parallel Add with Signed Saturation Byte
2062 * PSUBSB  rd, rs, rt        Parallel Subtract with Signed Saturation Byte
2063 * PADDSH  rd, rs, rt        Parallel Add with Signed Saturation Halfword
2064 * PSUBSH  rd, rs, rt        Parallel Subtract with Signed Saturation Halfword
2065 * PADDSW  rd, rs, rt        Parallel Add with Signed Saturation Word
2066 * PSUBSW  rd, rs, rt        Parallel Subtract with Signed Saturation Word
2067 * PADDUB  rd, rs, rt        Parallel Add with Unsigned saturation Byte
2068 * PSUBUB  rd, rs, rt        Parallel Subtract with Unsigned saturation Byte
2069 * PADDUH  rd, rs, rt        Parallel Add with Unsigned saturation Halfword
2070 * PSUBUH  rd, rs, rt        Parallel Subtract with Unsigned saturation Halfword
2071 * PADDUW  rd, rs, rt        Parallel Add with Unsigned saturation Word
2072 * PSUBUW  rd, rs, rt        Parallel Subtract with Unsigned saturation Word
2073 *
2074 *     Min/Max (4 instructions)
2075 *     ------------------------
2076 * PMAXH   rd, rs, rt        Parallel Maximum Halfword
2077 * PMINH   rd, rs, rt        Parallel Minimum Halfword
2078 * PMAXW   rd, rs, rt        Parallel Maximum Word
2079 * PMINW   rd, rs, rt        Parallel Minimum Word
2080 *
2081 *     Absolute (2 instructions)
2082 *     -------------------------
2083 * PABSH   rd, rt            Parallel Absolute Halfword
2084 * PABSW   rd, rt            Parallel Absolute Word
2085 *
2086 *     Logical (4 instructions)
2087 *     ------------------------
2088 * PAND    rd, rs, rt        Parallel AND
2089 * POR     rd, rs, rt        Parallel OR
2090 * PXOR    rd, rs, rt        Parallel XOR
2091 * PNOR    rd, rs, rt        Parallel NOR
2092 *
2093 *     Shift (9 instructions)
2094 *     ----------------------
2095 * PSLLH   rd, rt, sa        Parallel Shift Left Logical Halfword
2096 * PSRLH   rd, rt, sa        Parallel Shift Right Logical Halfword
2097 * PSRAH   rd, rt, sa        Parallel Shift Right Arithmetic Halfword
2098 * PSLLW   rd, rt, sa        Parallel Shift Left Logical Word
2099 * PSRLW   rd, rt, sa        Parallel Shift Right Logical Word
2100 * PSRAW   rd, rt, sa        Parallel Shift Right Arithmetic Word
2101 * PSLLVW  rd, rt, rs        Parallel Shift Left Logical Variable Word
2102 * PSRLVW  rd, rt, rs        Parallel Shift Right Logical Variable Word
2103 * PSRAVW  rd, rt, rs        Parallel Shift Right Arithmetic Variable Word
2104 *
2105 *     Compare (6 instructions)
2106 *     ------------------------
2107 * PCGTB   rd, rs, rt        Parallel Compare for Greater Than Byte
2108 * PCEQB   rd, rs, rt        Parallel Compare for Equal Byte
2109 * PCGTH   rd, rs, rt        Parallel Compare for Greater Than Halfword
2110 * PCEQH   rd, rs, rt        Parallel Compare for Equal Halfword
2111 * PCGTW   rd, rs, rt        Parallel Compare for Greater Than Word
2112 * PCEQW   rd, rs, rt        Parallel Compare for Equal Word
2113 *
2114 *     LZC (1 instruction)
2115 *     -------------------
2116 * PLZCW   rd, rs            Parallel Leading Zero or One Count Word
2117 *
2118 *     Quadword Load and Store (2 instructions)
2119 *     ----------------------------------------
2120 * LQ      rt, offset(base)  Load Quadword
2121 * SQ      rt, offset(base)  Store Quadword
2122 *
2123 *     Multiply and Divide (19 instructions)
2124 *     -------------------------------------
2125 * PMULTW  rd, rs, rt        Parallel Multiply Word
2126 * PMULTUW rd, rs, rt        Parallel Multiply Unsigned Word
2127 * PDIVW   rs, rt            Parallel Divide Word
2128 * PDIVUW  rs, rt            Parallel Divide Unsigned Word
2129 * PMADDW  rd, rs, rt        Parallel Multiply-Add Word
2130 * PMADDUW rd, rs, rt        Parallel Multiply-Add Unsigned Word
2131 * PMSUBW  rd, rs, rt        Parallel Multiply-Subtract Word
2132 * PMULTH  rd, rs, rt        Parallel Multiply Halfword
2133 * PMADDH  rd, rs, rt        Parallel Multiply-Add Halfword
2134 * PMSUBH  rd, rs, rt        Parallel Multiply-Subtract Halfword
2135 * PHMADH  rd, rs, rt        Parallel Horizontal Multiply-Add Halfword
2136 * PHMSBH  rd, rs, rt        Parallel Horizontal Multiply-Subtract Halfword
2137 * PDIVBW  rs, rt            Parallel Divide Broadcast Word
2138 * PMFHI   rd                Parallel Move From HI Register
2139 * PMFLO   rd                Parallel Move From LO Register
2140 * PMTHI   rs                Parallel Move To HI Register
2141 * PMTLO   rs                Parallel Move To LO Register
2142 * PMFHL   rd                Parallel Move From HI/LO Register
2143 * PMTHL   rs                Parallel Move To HI/LO Register
2144 *
2145 *     Pack/Extend (11 instructions)
2146 *     -----------------------------
2147 * PPAC5   rd, rt            Parallel Pack to 5 bits
2148 * PPACB   rd, rs, rt        Parallel Pack to Byte
2149 * PPACH   rd, rs, rt        Parallel Pack to Halfword
2150 * PPACW   rd, rs, rt        Parallel Pack to Word
2151 * PEXT5   rd, rt            Parallel Extend Upper from 5 bits
2152 * PEXTUB  rd, rs, rt        Parallel Extend Upper from Byte
2153 * PEXTLB  rd, rs, rt        Parallel Extend Lower from Byte
2154 * PEXTUH  rd, rs, rt        Parallel Extend Upper from Halfword
2155 * PEXTLH  rd, rs, rt        Parallel Extend Lower from Halfword
2156 * PEXTUW  rd, rs, rt        Parallel Extend Upper from Word
2157 * PEXTLW  rd, rs, rt        Parallel Extend Lower from Word
2158 *
2159 *     Others (16 instructions)
2160 *     ------------------------
2161 * PCPYH   rd, rt            Parallel Copy Halfword
2162 * PCPYLD  rd, rs, rt        Parallel Copy Lower Doubleword
2163 * PCPYUD  rd, rs, rt        Parallel Copy Upper Doubleword
2164 * PREVH   rd, rt            Parallel Reverse Halfword
2165 * PINTH   rd, rs, rt        Parallel Interleave Halfword
2166 * PINTEH  rd, rs, rt        Parallel Interleave Even Halfword
2167 * PEXEH   rd, rt            Parallel Exchange Even Halfword
2168 * PEXCH   rd, rt            Parallel Exchange Center Halfword
2169 * PEXEW   rd, rt            Parallel Exchange Even Word
2170 * PEXCW   rd, rt            Parallel Exchange Center Word
2171 * QFSRV   rd, rs, rt        Quadword Funnel Shift Right Variable
2172 * MFSA    rd                Move from Shift Amount Register
2173 * MTSA    rs                Move to Shift Amount Register
2174 * MTSAB   rs, immediate     Move Byte Count to Shift Amount Register
2175 * MTSAH   rs, immediate     Move Halfword Count to Shift Amount Register
2176 * PROT3W  rd, rt            Parallel Rotate 3 Words
2177 *
2178 *     MMI (MultiMedia Instruction) encodings
2179 *     ======================================
2180 *
2181 * MMI instructions encoding table keys:
2182 *
2183 *     *   This code is reserved for future use. An attempt to execute it
2184 *         causes a Reserved Instruction exception.
2185 *     %   This code indicates an instruction class. The instruction word
2186 *         must be further decoded by examining additional tables that show
2187 *         the values for other instruction fields.
2188 *     #   This code is reserved for the unsupported instructions DMULT,
2189 *         DMULTU, DDIV, DDIVU, LL, LLD, SC, SCD, LWC2 and SWC2. An attempt
2190 *         to execute it causes a Reserved Instruction exception.
2191 *
2192 * MMI instructions encoded by opcode field (MMI, LQ, SQ):
2193 *
2194 *  31    26                                        0
2195 * +--------+----------------------------------------+
2196 * | opcode |                                        |
2197 * +--------+----------------------------------------+
2198 *
2199 *   opcode  bits 28..26
2200 *     bits |   0   |   1   |   2   |   3   |   4   |   5   |   6   |   7
2201 *   31..29 |  000  |  001  |  010  |  011  |  100  |  101  |  110  |  111
2202 *   -------+-------+-------+-------+-------+-------+-------+-------+-------
2203 *    0 000 |SPECIAL| REGIMM|   J   |  JAL  |  BEQ  |  BNE  |  BLEZ |  BGTZ
2204 *    1 001 |  ADDI | ADDIU |  SLTI | SLTIU |  ANDI |  ORI  |  XORI |  LUI
2205 *    2 010 |  COP0 |  COP1 |   *   |   *   |  BEQL |  BNEL | BLEZL | BGTZL
2206 *    3 011 | DADDI | DADDIU|  LDL  |  LDR  |  MMI% |   *   |   LQ  |   SQ
2207 *    4 100 |   LB  |   LH  |  LWL  |   LW  |  LBU  |  LHU  |  LWR  |  LWU
2208 *    5 101 |   SB  |   SH  |  SWL  |   SW  |  SDL  |  SDR  |  SWR  | CACHE
2209 *    6 110 |   #   |  LWC1 |   #   |  PREF |   #   |  LDC1 |   #   |   LD
2210 *    7 111 |   #   |  SWC1 |   #   |   *   |   #   |  SDC1 |   #   |   SD
2211 */
2212
2213enum {
2214    MMI_OPC_CLASS_MMI = 0x1C << 26,    /* Same as OPC_SPECIAL2 */
2215    MMI_OPC_LQ        = 0x1E << 26,    /* Same as OPC_MSA */
2216    MMI_OPC_SQ        = 0x1F << 26,    /* Same as OPC_SPECIAL3 */
2217};
2218
2219/*
2220 * MMI instructions with opcode field = MMI:
2221 *
2222 *  31    26                                 5      0
2223 * +--------+-------------------------------+--------+
2224 * |   MMI  |                               |function|
2225 * +--------+-------------------------------+--------+
2226 *
2227 * function  bits 2..0
2228 *     bits |   0   |   1   |   2   |   3   |   4   |   5   |   6   |   7
2229 *     5..3 |  000  |  001  |  010  |  011  |  100  |  101  |  110  |  111
2230 *   -------+-------+-------+-------+-------+-------+-------+-------+-------
2231 *    0 000 |  MADD | MADDU |   *   |   *   | PLZCW |   *   |   *   |   *
2232 *    1 001 | MMI0% | MMI2% |   *   |   *   |   *   |   *   |   *   |   *
2233 *    2 010 | MFHI1 | MTHI1 | MFLO1 | MTLO1 |   *   |   *   |   *   |   *
2234 *    3 011 | MULT1 | MULTU1|  DIV1 | DIVU1 |   *   |   *   |   *   |   *
2235 *    4 100 | MADD1 | MADDU1|   *   |   *   |   *   |   *   |   *   |   *
2236 *    5 101 | MMI1% | MMI3% |   *   |   *   |   *   |   *   |   *   |   *
2237 *    6 110 | PMFHL | PMTHL |   *   |   *   | PSLLH |   *   | PSRLH | PSRAH
2238 *    7 111 |   *   |   *   |   *   |   *   | PSLLW |   *   | PSRLW | PSRAW
2239 */
2240
2241#define MASK_MMI(op) (MASK_OP_MAJOR(op) | ((op) & 0x3F))
2242enum {
2243    MMI_OPC_MADD       = 0x00 | MMI_OPC_CLASS_MMI, /* Same as OPC_MADD */
2244    MMI_OPC_MADDU      = 0x01 | MMI_OPC_CLASS_MMI, /* Same as OPC_MADDU */
2245    MMI_OPC_PLZCW      = 0x04 | MMI_OPC_CLASS_MMI,
2246    MMI_OPC_CLASS_MMI0 = 0x08 | MMI_OPC_CLASS_MMI,
2247    MMI_OPC_CLASS_MMI2 = 0x09 | MMI_OPC_CLASS_MMI,
2248    MMI_OPC_MFHI1      = 0x10 | MMI_OPC_CLASS_MMI, /* Same minor as OPC_MFHI */
2249    MMI_OPC_MTHI1      = 0x11 | MMI_OPC_CLASS_MMI, /* Same minor as OPC_MTHI */
2250    MMI_OPC_MFLO1      = 0x12 | MMI_OPC_CLASS_MMI, /* Same minor as OPC_MFLO */
2251    MMI_OPC_MTLO1      = 0x13 | MMI_OPC_CLASS_MMI, /* Same minor as OPC_MTLO */
2252    MMI_OPC_MULT1      = 0x18 | MMI_OPC_CLASS_MMI, /* Same minor as OPC_MULT */
2253    MMI_OPC_MULTU1     = 0x19 | MMI_OPC_CLASS_MMI, /* Same min. as OPC_MULTU */
2254    MMI_OPC_DIV1       = 0x1A | MMI_OPC_CLASS_MMI, /* Same minor as OPC_DIV  */
2255    MMI_OPC_DIVU1      = 0x1B | MMI_OPC_CLASS_MMI, /* Same minor as OPC_DIVU */
2256    MMI_OPC_MADD1      = 0x20 | MMI_OPC_CLASS_MMI,
2257    MMI_OPC_MADDU1     = 0x21 | MMI_OPC_CLASS_MMI,
2258    MMI_OPC_CLASS_MMI1 = 0x28 | MMI_OPC_CLASS_MMI,
2259    MMI_OPC_CLASS_MMI3 = 0x29 | MMI_OPC_CLASS_MMI,
2260    MMI_OPC_PMFHL      = 0x30 | MMI_OPC_CLASS_MMI,
2261    MMI_OPC_PMTHL      = 0x31 | MMI_OPC_CLASS_MMI,
2262    MMI_OPC_PSLLH      = 0x34 | MMI_OPC_CLASS_MMI,
2263    MMI_OPC_PSRLH      = 0x36 | MMI_OPC_CLASS_MMI,
2264    MMI_OPC_PSRAH      = 0x37 | MMI_OPC_CLASS_MMI,
2265    MMI_OPC_PSLLW      = 0x3C | MMI_OPC_CLASS_MMI,
2266    MMI_OPC_PSRLW      = 0x3E | MMI_OPC_CLASS_MMI,
2267    MMI_OPC_PSRAW      = 0x3F | MMI_OPC_CLASS_MMI,
2268};
2269
2270/*
2271 * MMI instructions with opcode field = MMI and bits 5..0 = MMI0:
2272 *
2273 *  31    26                        10     6 5      0
2274 * +--------+----------------------+--------+--------+
2275 * |   MMI  |                      |function|  MMI0  |
2276 * +--------+----------------------+--------+--------+
2277 *
2278 * function  bits 7..6
2279 *     bits |   0   |   1   |   2   |   3
2280 *    10..8 |   00  |   01  |   10  |   11
2281 *   -------+-------+-------+-------+-------
2282 *    0 000 | PADDW | PSUBW | PCGTW | PMAXW
2283 *    1 001 | PADDH | PSUBH | PCGTH | PMAXH
2284 *    2 010 | PADDB | PSUBB | PCGTB |   *
2285 *    3 011 |   *   |   *   |   *   |   *
2286 *    4 100 | PADDSW| PSUBSW| PEXTLW| PPACW
2287 *    5 101 | PADDSH| PSUBSH| PEXTLH| PPACH
2288 *    6 110 | PADDSB| PSUBSB| PEXTLB| PPACB
2289 *    7 111 |   *   |   *   | PEXT5 | PPAC5
2290 */
2291
2292#define MASK_MMI0(op) (MASK_OP_MAJOR(op) | ((op) & 0x7FF))
2293enum {
2294    MMI_OPC_0_PADDW  = (0x00 << 6) | MMI_OPC_CLASS_MMI0,
2295    MMI_OPC_0_PSUBW  = (0x01 << 6) | MMI_OPC_CLASS_MMI0,
2296    MMI_OPC_0_PCGTW  = (0x02 << 6) | MMI_OPC_CLASS_MMI0,
2297    MMI_OPC_0_PMAXW  = (0x03 << 6) | MMI_OPC_CLASS_MMI0,
2298    MMI_OPC_0_PADDH  = (0x04 << 6) | MMI_OPC_CLASS_MMI0,
2299    MMI_OPC_0_PSUBH  = (0x05 << 6) | MMI_OPC_CLASS_MMI0,
2300    MMI_OPC_0_PCGTH  = (0x06 << 6) | MMI_OPC_CLASS_MMI0,
2301    MMI_OPC_0_PMAXH  = (0x07 << 6) | MMI_OPC_CLASS_MMI0,
2302    MMI_OPC_0_PADDB  = (0x08 << 6) | MMI_OPC_CLASS_MMI0,
2303    MMI_OPC_0_PSUBB  = (0x09 << 6) | MMI_OPC_CLASS_MMI0,
2304    MMI_OPC_0_PCGTB  = (0x0A << 6) | MMI_OPC_CLASS_MMI0,
2305    MMI_OPC_0_PADDSW = (0x10 << 6) | MMI_OPC_CLASS_MMI0,
2306    MMI_OPC_0_PSUBSW = (0x11 << 6) | MMI_OPC_CLASS_MMI0,
2307    MMI_OPC_0_PEXTLW = (0x12 << 6) | MMI_OPC_CLASS_MMI0,
2308    MMI_OPC_0_PPACW  = (0x13 << 6) | MMI_OPC_CLASS_MMI0,
2309    MMI_OPC_0_PADDSH = (0x14 << 6) | MMI_OPC_CLASS_MMI0,
2310    MMI_OPC_0_PSUBSH = (0x15 << 6) | MMI_OPC_CLASS_MMI0,
2311    MMI_OPC_0_PEXTLH = (0x16 << 6) | MMI_OPC_CLASS_MMI0,
2312    MMI_OPC_0_PPACH  = (0x17 << 6) | MMI_OPC_CLASS_MMI0,
2313    MMI_OPC_0_PADDSB = (0x18 << 6) | MMI_OPC_CLASS_MMI0,
2314    MMI_OPC_0_PSUBSB = (0x19 << 6) | MMI_OPC_CLASS_MMI0,
2315    MMI_OPC_0_PEXTLB = (0x1A << 6) | MMI_OPC_CLASS_MMI0,
2316    MMI_OPC_0_PPACB  = (0x1B << 6) | MMI_OPC_CLASS_MMI0,
2317    MMI_OPC_0_PEXT5  = (0x1E << 6) | MMI_OPC_CLASS_MMI0,
2318    MMI_OPC_0_PPAC5  = (0x1F << 6) | MMI_OPC_CLASS_MMI0,
2319};
2320
2321/*
2322 * MMI instructions with opcode field = MMI and bits 5..0 = MMI1:
2323 *
2324 *  31    26                        10     6 5      0
2325 * +--------+----------------------+--------+--------+
2326 * |   MMI  |                      |function|  MMI1  |
2327 * +--------+----------------------+--------+--------+
2328 *
2329 * function  bits 7..6
2330 *     bits |   0   |   1   |   2   |   3
2331 *    10..8 |   00  |   01  |   10  |   11
2332 *   -------+-------+-------+-------+-------
2333 *    0 000 |   *   | PABSW | PCEQW | PMINW
2334 *    1 001 | PADSBH| PABSH | PCEQH | PMINH
2335 *    2 010 |   *   |   *   | PCEQB |   *
2336 *    3 011 |   *   |   *   |   *   |   *
2337 *    4 100 | PADDUW| PSUBUW| PEXTUW|   *
2338 *    5 101 | PADDUH| PSUBUH| PEXTUH|   *
2339 *    6 110 | PADDUB| PSUBUB| PEXTUB| QFSRV
2340 *    7 111 |   *   |   *   |   *   |   *
2341 */
2342
2343#define MASK_MMI1(op) (MASK_OP_MAJOR(op) | ((op) & 0x7FF))
2344enum {
2345    MMI_OPC_1_PABSW  = (0x01 << 6) | MMI_OPC_CLASS_MMI1,
2346    MMI_OPC_1_PCEQW  = (0x02 << 6) | MMI_OPC_CLASS_MMI1,
2347    MMI_OPC_1_PMINW  = (0x03 << 6) | MMI_OPC_CLASS_MMI1,
2348    MMI_OPC_1_PADSBH = (0x04 << 6) | MMI_OPC_CLASS_MMI1,
2349    MMI_OPC_1_PABSH  = (0x05 << 6) | MMI_OPC_CLASS_MMI1,
2350    MMI_OPC_1_PCEQH  = (0x06 << 6) | MMI_OPC_CLASS_MMI1,
2351    MMI_OPC_1_PMINH  = (0x07 << 6) | MMI_OPC_CLASS_MMI1,
2352    MMI_OPC_1_PCEQB  = (0x0A << 6) | MMI_OPC_CLASS_MMI1,
2353    MMI_OPC_1_PADDUW = (0x10 << 6) | MMI_OPC_CLASS_MMI1,
2354    MMI_OPC_1_PSUBUW = (0x11 << 6) | MMI_OPC_CLASS_MMI1,
2355    MMI_OPC_1_PEXTUW = (0x12 << 6) | MMI_OPC_CLASS_MMI1,
2356    MMI_OPC_1_PADDUH = (0x14 << 6) | MMI_OPC_CLASS_MMI1,
2357    MMI_OPC_1_PSUBUH = (0x15 << 6) | MMI_OPC_CLASS_MMI1,
2358    MMI_OPC_1_PEXTUH = (0x16 << 6) | MMI_OPC_CLASS_MMI1,
2359    MMI_OPC_1_PADDUB = (0x18 << 6) | MMI_OPC_CLASS_MMI1,
2360    MMI_OPC_1_PSUBUB = (0x19 << 6) | MMI_OPC_CLASS_MMI1,
2361    MMI_OPC_1_PEXTUB = (0x1A << 6) | MMI_OPC_CLASS_MMI1,
2362    MMI_OPC_1_QFSRV  = (0x1B << 6) | MMI_OPC_CLASS_MMI1,
2363};
2364
2365/*
2366 * MMI instructions with opcode field = MMI and bits 5..0 = MMI2:
2367 *
2368 *  31    26                        10     6 5      0
2369 * +--------+----------------------+--------+--------+
2370 * |   MMI  |                      |function|  MMI2  |
2371 * +--------+----------------------+--------+--------+
2372 *
2373 * function  bits 7..6
2374 *     bits |   0   |   1   |   2   |   3
2375 *    10..8 |   00  |   01  |   10  |   11
2376 *   -------+-------+-------+-------+-------
2377 *    0 000 | PMADDW|   *   | PSLLVW| PSRLVW
2378 *    1 001 | PMSUBW|   *   |   *   |   *
2379 *    2 010 | PMFHI | PMFLO | PINTH |   *
2380 *    3 011 | PMULTW| PDIVW | PCPYLD|   *
2381 *    4 100 | PMADDH| PHMADH|  PAND |  PXOR
2382 *    5 101 | PMSUBH| PHMSBH|   *   |   *
2383 *    6 110 |   *   |   *   | PEXEH | PREVH
2384 *    7 111 | PMULTH| PDIVBW| PEXEW | PROT3W
2385 */
2386
2387#define MASK_MMI2(op) (MASK_OP_MAJOR(op) | ((op) & 0x7FF))
2388enum {
2389    MMI_OPC_2_PMADDW = (0x00 << 6) | MMI_OPC_CLASS_MMI2,
2390    MMI_OPC_2_PSLLVW = (0x02 << 6) | MMI_OPC_CLASS_MMI2,
2391    MMI_OPC_2_PSRLVW = (0x03 << 6) | MMI_OPC_CLASS_MMI2,
2392    MMI_OPC_2_PMSUBW = (0x04 << 6) | MMI_OPC_CLASS_MMI2,
2393    MMI_OPC_2_PMFHI  = (0x08 << 6) | MMI_OPC_CLASS_MMI2,
2394    MMI_OPC_2_PMFLO  = (0x09 << 6) | MMI_OPC_CLASS_MMI2,
2395    MMI_OPC_2_PINTH  = (0x0A << 6) | MMI_OPC_CLASS_MMI2,
2396    MMI_OPC_2_PMULTW = (0x0C << 6) | MMI_OPC_CLASS_MMI2,
2397    MMI_OPC_2_PDIVW  = (0x0D << 6) | MMI_OPC_CLASS_MMI2,
2398    MMI_OPC_2_PCPYLD = (0x0E << 6) | MMI_OPC_CLASS_MMI2,
2399    MMI_OPC_2_PMADDH = (0x10 << 6) | MMI_OPC_CLASS_MMI2,
2400    MMI_OPC_2_PHMADH = (0x11 << 6) | MMI_OPC_CLASS_MMI2,
2401    MMI_OPC_2_PAND   = (0x12 << 6) | MMI_OPC_CLASS_MMI2,
2402    MMI_OPC_2_PXOR   = (0x13 << 6) | MMI_OPC_CLASS_MMI2,
2403    MMI_OPC_2_PMSUBH = (0x14 << 6) | MMI_OPC_CLASS_MMI2,
2404    MMI_OPC_2_PHMSBH = (0x15 << 6) | MMI_OPC_CLASS_MMI2,
2405    MMI_OPC_2_PEXEH  = (0x1A << 6) | MMI_OPC_CLASS_MMI2,
2406    MMI_OPC_2_PREVH  = (0x1B << 6) | MMI_OPC_CLASS_MMI2,
2407    MMI_OPC_2_PMULTH = (0x1C << 6) | MMI_OPC_CLASS_MMI2,
2408    MMI_OPC_2_PDIVBW = (0x1D << 6) | MMI_OPC_CLASS_MMI2,
2409    MMI_OPC_2_PEXEW  = (0x1E << 6) | MMI_OPC_CLASS_MMI2,
2410    MMI_OPC_2_PROT3W = (0x1F << 6) | MMI_OPC_CLASS_MMI2,
2411};
2412
2413/*
2414 * MMI instructions with opcode field = MMI and bits 5..0 = MMI3:
2415 *
2416 *  31    26                        10     6 5      0
2417 * +--------+----------------------+--------+--------+
2418 * |   MMI  |                      |function|  MMI3  |
2419 * +--------+----------------------+--------+--------+
2420 *
2421 * function  bits 7..6
2422 *     bits |   0   |   1   |   2   |   3
2423 *    10..8 |   00  |   01  |   10  |   11
2424 *   -------+-------+-------+-------+-------
2425 *    0 000 |PMADDUW|   *   |   *   | PSRAVW
2426 *    1 001 |   *   |   *   |   *   |   *
2427 *    2 010 | PMTHI | PMTLO | PINTEH|   *
2428 *    3 011 |PMULTUW| PDIVUW| PCPYUD|   *
2429 *    4 100 |   *   |   *   |  POR  |  PNOR
2430 *    5 101 |   *   |   *   |   *   |   *
2431 *    6 110 |   *   |   *   | PEXCH | PCPYH
2432 *    7 111 |   *   |   *   | PEXCW |   *
2433 */
2434
2435#define MASK_MMI3(op) (MASK_OP_MAJOR(op) | ((op) & 0x7FF))
2436enum {
2437    MMI_OPC_3_PMADDUW = (0x00 << 6) | MMI_OPC_CLASS_MMI3,
2438    MMI_OPC_3_PSRAVW  = (0x03 << 6) | MMI_OPC_CLASS_MMI3,
2439    MMI_OPC_3_PMTHI   = (0x08 << 6) | MMI_OPC_CLASS_MMI3,
2440    MMI_OPC_3_PMTLO   = (0x09 << 6) | MMI_OPC_CLASS_MMI3,
2441    MMI_OPC_3_PINTEH  = (0x0A << 6) | MMI_OPC_CLASS_MMI3,
2442    MMI_OPC_3_PMULTUW = (0x0C << 6) | MMI_OPC_CLASS_MMI3,
2443    MMI_OPC_3_PDIVUW  = (0x0D << 6) | MMI_OPC_CLASS_MMI3,
2444    MMI_OPC_3_PCPYUD  = (0x0E << 6) | MMI_OPC_CLASS_MMI3,
2445    MMI_OPC_3_POR     = (0x12 << 6) | MMI_OPC_CLASS_MMI3,
2446    MMI_OPC_3_PNOR    = (0x13 << 6) | MMI_OPC_CLASS_MMI3,
2447    MMI_OPC_3_PEXCH   = (0x1A << 6) | MMI_OPC_CLASS_MMI3,
2448    MMI_OPC_3_PCPYH   = (0x1B << 6) | MMI_OPC_CLASS_MMI3,
2449    MMI_OPC_3_PEXCW   = (0x1E << 6) | MMI_OPC_CLASS_MMI3,
2450};
2451
2452/* global register indices */
2453static TCGv cpu_gpr[32], cpu_PC;
2454static TCGv cpu_HI[MIPS_DSP_ACC], cpu_LO[MIPS_DSP_ACC];
2455static TCGv cpu_dspctrl, btarget, bcond;
2456static TCGv cpu_lladdr, cpu_llval;
2457static TCGv_i32 hflags;
2458static TCGv_i32 fpu_fcr0, fpu_fcr31;
2459static TCGv_i64 fpu_f64[32];
2460static TCGv_i64 msa_wr_d[64];
2461
2462#if defined(TARGET_MIPS64)
2463/* Upper halves of R5900's 128-bit registers: MMRs (multimedia registers) */
2464static TCGv_i64 cpu_mmr[32];
2465#endif
2466
2467#if !defined(TARGET_MIPS64)
2468/* MXU registers */
2469static TCGv mxu_gpr[NUMBER_OF_MXU_REGISTERS - 1];
2470static TCGv mxu_CR;
2471#endif
2472
2473#include "exec/gen-icount.h"
2474
2475#define gen_helper_0e0i(name, arg) do {                           \
2476    TCGv_i32 helper_tmp = tcg_const_i32(arg);                     \
2477    gen_helper_##name(cpu_env, helper_tmp);                       \
2478    tcg_temp_free_i32(helper_tmp);                                \
2479    } while(0)
2480
2481#define gen_helper_0e1i(name, arg1, arg2) do {                    \
2482    TCGv_i32 helper_tmp = tcg_const_i32(arg2);                    \
2483    gen_helper_##name(cpu_env, arg1, helper_tmp);                 \
2484    tcg_temp_free_i32(helper_tmp);                                \
2485    } while(0)
2486
2487#define gen_helper_1e0i(name, ret, arg1) do {                     \
2488    TCGv_i32 helper_tmp = tcg_const_i32(arg1);                    \
2489    gen_helper_##name(ret, cpu_env, helper_tmp);                  \
2490    tcg_temp_free_i32(helper_tmp);                                \
2491    } while(0)
2492
2493#define gen_helper_1e1i(name, ret, arg1, arg2) do {               \
2494    TCGv_i32 helper_tmp = tcg_const_i32(arg2);                    \
2495    gen_helper_##name(ret, cpu_env, arg1, helper_tmp);            \
2496    tcg_temp_free_i32(helper_tmp);                                \
2497    } while(0)
2498
2499#define gen_helper_0e2i(name, arg1, arg2, arg3) do {              \
2500    TCGv_i32 helper_tmp = tcg_const_i32(arg3);                    \
2501    gen_helper_##name(cpu_env, arg1, arg2, helper_tmp);           \
2502    tcg_temp_free_i32(helper_tmp);                                \
2503    } while(0)
2504
2505#define gen_helper_1e2i(name, ret, arg1, arg2, arg3) do {         \
2506    TCGv_i32 helper_tmp = tcg_const_i32(arg3);                    \
2507    gen_helper_##name(ret, cpu_env, arg1, arg2, helper_tmp);      \
2508    tcg_temp_free_i32(helper_tmp);                                \
2509    } while(0)
2510
2511#define gen_helper_0e3i(name, arg1, arg2, arg3, arg4) do {        \
2512    TCGv_i32 helper_tmp = tcg_const_i32(arg4);                    \
2513    gen_helper_##name(cpu_env, arg1, arg2, arg3, helper_tmp);     \
2514    tcg_temp_free_i32(helper_tmp);                                \
2515    } while(0)
2516
2517typedef struct DisasContext {
2518    DisasContextBase base;
2519    target_ulong saved_pc;
2520    target_ulong page_start;
2521    uint32_t opcode;
2522    uint64_t insn_flags;
2523    int32_t CP0_Config1;
2524    int32_t CP0_Config2;
2525    int32_t CP0_Config3;
2526    int32_t CP0_Config5;
2527    /* Routine used to access memory */
2528    int mem_idx;
2529    TCGMemOp default_tcg_memop_mask;
2530    uint32_t hflags, saved_hflags;
2531    target_ulong btarget;
2532    bool ulri;
2533    int kscrexist;
2534    bool rxi;
2535    int ie;
2536    bool bi;
2537    bool bp;
2538    uint64_t PAMask;
2539    bool mvh;
2540    bool eva;
2541    bool sc;
2542    int CP0_LLAddr_shift;
2543    bool ps;
2544    bool vp;
2545    bool cmgcr;
2546    bool mrp;
2547    bool nan2008;
2548    bool abs2008;
2549    bool saar;
2550} DisasContext;
2551
2552#define DISAS_STOP       DISAS_TARGET_0
2553#define DISAS_EXIT       DISAS_TARGET_1
2554
2555static const char * const regnames[] = {
2556    "r0", "at", "v0", "v1", "a0", "a1", "a2", "a3",
2557    "t0", "t1", "t2", "t3", "t4", "t5", "t6", "t7",
2558    "s0", "s1", "s2", "s3", "s4", "s5", "s6", "s7",
2559    "t8", "t9", "k0", "k1", "gp", "sp", "s8", "ra",
2560};
2561
2562static const char * const regnames_HI[] = {
2563    "HI0", "HI1", "HI2", "HI3",
2564};
2565
2566static const char * const regnames_LO[] = {
2567    "LO0", "LO1", "LO2", "LO3",
2568};
2569
2570static const char * const fregnames[] = {
2571    "f0",  "f1",  "f2",  "f3",  "f4",  "f5",  "f6",  "f7",
2572    "f8",  "f9",  "f10", "f11", "f12", "f13", "f14", "f15",
2573    "f16", "f17", "f18", "f19", "f20", "f21", "f22", "f23",
2574    "f24", "f25", "f26", "f27", "f28", "f29", "f30", "f31",
2575};
2576
2577static const char * const msaregnames[] = {
2578    "w0.d0",  "w0.d1",  "w1.d0",  "w1.d1",
2579    "w2.d0",  "w2.d1",  "w3.d0",  "w3.d1",
2580    "w4.d0",  "w4.d1",  "w5.d0",  "w5.d1",
2581    "w6.d0",  "w6.d1",  "w7.d0",  "w7.d1",
2582    "w8.d0",  "w8.d1",  "w9.d0",  "w9.d1",
2583    "w10.d0", "w10.d1", "w11.d0", "w11.d1",
2584    "w12.d0", "w12.d1", "w13.d0", "w13.d1",
2585    "w14.d0", "w14.d1", "w15.d0", "w15.d1",
2586    "w16.d0", "w16.d1", "w17.d0", "w17.d1",
2587    "w18.d0", "w18.d1", "w19.d0", "w19.d1",
2588    "w20.d0", "w20.d1", "w21.d0", "w21.d1",
2589    "w22.d0", "w22.d1", "w23.d0", "w23.d1",
2590    "w24.d0", "w24.d1", "w25.d0", "w25.d1",
2591    "w26.d0", "w26.d1", "w27.d0", "w27.d1",
2592    "w28.d0", "w28.d1", "w29.d0", "w29.d1",
2593    "w30.d0", "w30.d1", "w31.d0", "w31.d1",
2594};
2595
2596#if !defined(TARGET_MIPS64)
2597static const char * const mxuregnames[] = {
2598    "XR1",  "XR2",  "XR3",  "XR4",  "XR5",  "XR6",  "XR7",  "XR8",
2599    "XR9",  "XR10", "XR11", "XR12", "XR13", "XR14", "XR15", "MXU_CR",
2600};
2601#endif
2602
2603#define LOG_DISAS(...)                                                        \
2604    do {                                                                      \
2605        if (MIPS_DEBUG_DISAS) {                                               \
2606            qemu_log_mask(CPU_LOG_TB_IN_ASM, ## __VA_ARGS__);                 \
2607        }                                                                     \
2608    } while (0)
2609
2610#define MIPS_INVAL(op)                                                        \
2611    do {                                                                      \
2612        if (MIPS_DEBUG_DISAS) {                                               \
2613            qemu_log_mask(CPU_LOG_TB_IN_ASM,                                  \
2614                          TARGET_FMT_lx ": %08x Invalid %s %03x %03x %03x\n", \
2615                          ctx->base.pc_next, ctx->opcode, op,                 \
2616                          ctx->opcode >> 26, ctx->opcode & 0x3F,              \
2617                          ((ctx->opcode >> 16) & 0x1F));                      \
2618        }                                                                     \
2619    } while (0)
2620
2621/* General purpose registers moves. */
2622static inline void gen_load_gpr(TCGv t, int reg)
2623{
2624    if (reg == 0) {
2625        tcg_gen_movi_tl(t, 0);
2626    } else {
2627        tcg_gen_mov_tl(t, cpu_gpr[reg]);
2628    }
2629}
2630
2631static inline void gen_store_gpr(TCGv t, int reg)
2632{
2633    if (reg != 0) {
2634        tcg_gen_mov_tl(cpu_gpr[reg], t);
2635    }
2636}
2637
2638/* Moves to/from shadow registers. */
2639static inline void gen_load_srsgpr(int from, int to)
2640{
2641    TCGv t0 = tcg_temp_new();
2642
2643    if (from == 0) {
2644        tcg_gen_movi_tl(t0, 0);
2645    } else {
2646        TCGv_i32 t2 = tcg_temp_new_i32();
2647        TCGv_ptr addr = tcg_temp_new_ptr();
2648
2649        tcg_gen_ld_i32(t2, cpu_env, offsetof(CPUMIPSState, CP0_SRSCtl));
2650        tcg_gen_shri_i32(t2, t2, CP0SRSCtl_PSS);
2651        tcg_gen_andi_i32(t2, t2, 0xf);
2652        tcg_gen_muli_i32(t2, t2, sizeof(target_ulong) * 32);
2653        tcg_gen_ext_i32_ptr(addr, t2);
2654        tcg_gen_add_ptr(addr, cpu_env, addr);
2655
2656        tcg_gen_ld_tl(t0, addr, sizeof(target_ulong) * from);
2657        tcg_temp_free_ptr(addr);
2658        tcg_temp_free_i32(t2);
2659    }
2660    gen_store_gpr(t0, to);
2661    tcg_temp_free(t0);
2662}
2663
2664static inline void gen_store_srsgpr (int from, int to)
2665{
2666    if (to != 0) {
2667        TCGv t0 = tcg_temp_new();
2668        TCGv_i32 t2 = tcg_temp_new_i32();
2669        TCGv_ptr addr = tcg_temp_new_ptr();
2670
2671        gen_load_gpr(t0, from);
2672        tcg_gen_ld_i32(t2, cpu_env, offsetof(CPUMIPSState, CP0_SRSCtl));
2673        tcg_gen_shri_i32(t2, t2, CP0SRSCtl_PSS);
2674        tcg_gen_andi_i32(t2, t2, 0xf);
2675        tcg_gen_muli_i32(t2, t2, sizeof(target_ulong) * 32);
2676        tcg_gen_ext_i32_ptr(addr, t2);
2677        tcg_gen_add_ptr(addr, cpu_env, addr);
2678
2679        tcg_gen_st_tl(t0, addr, sizeof(target_ulong) * to);
2680        tcg_temp_free_ptr(addr);
2681        tcg_temp_free_i32(t2);
2682        tcg_temp_free(t0);
2683    }
2684}
2685
2686#if !defined(TARGET_MIPS64)
2687/* MXU General purpose registers moves. */
2688static inline void gen_load_mxu_gpr(TCGv t, unsigned int reg)
2689{
2690    if (reg == 0) {
2691        tcg_gen_movi_tl(t, 0);
2692    } else if (reg <= 15) {
2693        tcg_gen_mov_tl(t, mxu_gpr[reg - 1]);
2694    }
2695}
2696
2697static inline void gen_store_mxu_gpr(TCGv t, unsigned int reg)
2698{
2699    if (reg > 0 && reg <= 15) {
2700        tcg_gen_mov_tl(mxu_gpr[reg - 1], t);
2701    }
2702}
2703
2704/* MXU control register moves. */
2705static inline void gen_load_mxu_cr(TCGv t)
2706{
2707    tcg_gen_mov_tl(t, mxu_CR);
2708}
2709
2710static inline void gen_store_mxu_cr(TCGv t)
2711{
2712    /* TODO: Add handling of RW rules for MXU_CR. */
2713    tcg_gen_mov_tl(mxu_CR, t);
2714}
2715#endif
2716
2717
2718/* Tests */
2719static inline void gen_save_pc(target_ulong pc)
2720{
2721    tcg_gen_movi_tl(cpu_PC, pc);
2722}
2723
2724static inline void save_cpu_state(DisasContext *ctx, int do_save_pc)
2725{
2726    LOG_DISAS("hflags %08x saved %08x\n", ctx->hflags, ctx->saved_hflags);
2727    if (do_save_pc && ctx->base.pc_next != ctx->saved_pc) {
2728        gen_save_pc(ctx->base.pc_next);
2729        ctx->saved_pc = ctx->base.pc_next;
2730    }
2731    if (ctx->hflags != ctx->saved_hflags) {
2732        tcg_gen_movi_i32(hflags, ctx->hflags);
2733        ctx->saved_hflags = ctx->hflags;
2734        switch (ctx->hflags & MIPS_HFLAG_BMASK_BASE) {
2735        case MIPS_HFLAG_BR:
2736            break;
2737        case MIPS_HFLAG_BC:
2738        case MIPS_HFLAG_BL:
2739        case MIPS_HFLAG_B:
2740            tcg_gen_movi_tl(btarget, ctx->btarget);
2741            break;
2742        }
2743    }
2744}
2745
2746static inline void restore_cpu_state(CPUMIPSState *env, DisasContext *ctx)
2747{
2748    ctx->saved_hflags = ctx->hflags;
2749    switch (ctx->hflags & MIPS_HFLAG_BMASK_BASE) {
2750    case MIPS_HFLAG_BR:
2751        break;
2752    case MIPS_HFLAG_BC:
2753    case MIPS_HFLAG_BL:
2754    case MIPS_HFLAG_B:
2755        ctx->btarget = env->btarget;
2756        break;
2757    }
2758}
2759
2760static inline void generate_exception_err(DisasContext *ctx, int excp, int err)
2761{
2762    TCGv_i32 texcp = tcg_const_i32(excp);
2763    TCGv_i32 terr = tcg_const_i32(err);
2764    save_cpu_state(ctx, 1);
2765    gen_helper_raise_exception_err(cpu_env, texcp, terr);
2766    tcg_temp_free_i32(terr);
2767    tcg_temp_free_i32(texcp);
2768    ctx->base.is_jmp = DISAS_NORETURN;
2769}
2770
2771static inline void generate_exception(DisasContext *ctx, int excp)
2772{
2773    gen_helper_0e0i(raise_exception, excp);
2774}
2775
2776static inline void generate_exception_end(DisasContext *ctx, int excp)
2777{
2778    generate_exception_err(ctx, excp, 0);
2779}
2780
2781/* Floating point register moves. */
2782static void gen_load_fpr32(DisasContext *ctx, TCGv_i32 t, int reg)
2783{
2784    if (ctx->hflags & MIPS_HFLAG_FRE) {
2785        generate_exception(ctx, EXCP_RI);
2786    }
2787    tcg_gen_extrl_i64_i32(t, fpu_f64[reg]);
2788}
2789
2790static void gen_store_fpr32(DisasContext *ctx, TCGv_i32 t, int reg)
2791{
2792    TCGv_i64 t64;
2793    if (ctx->hflags & MIPS_HFLAG_FRE) {
2794        generate_exception(ctx, EXCP_RI);
2795    }
2796    t64 = tcg_temp_new_i64();
2797    tcg_gen_extu_i32_i64(t64, t);
2798    tcg_gen_deposit_i64(fpu_f64[reg], fpu_f64[reg], t64, 0, 32);
2799    tcg_temp_free_i64(t64);
2800}
2801
2802static void gen_load_fpr32h(DisasContext *ctx, TCGv_i32 t, int reg)
2803{
2804    if (ctx->hflags & MIPS_HFLAG_F64) {
2805        tcg_gen_extrh_i64_i32(t, fpu_f64[reg]);
2806    } else {
2807        gen_load_fpr32(ctx, t, reg | 1);
2808    }
2809}
2810
2811static void gen_store_fpr32h(DisasContext *ctx, TCGv_i32 t, int reg)
2812{
2813    if (ctx->hflags & MIPS_HFLAG_F64) {
2814        TCGv_i64 t64 = tcg_temp_new_i64();
2815        tcg_gen_extu_i32_i64(t64, t);
2816        tcg_gen_deposit_i64(fpu_f64[reg], fpu_f64[reg], t64, 32, 32);
2817        tcg_temp_free_i64(t64);
2818    } else {
2819        gen_store_fpr32(ctx, t, reg | 1);
2820    }
2821}
2822
2823static void gen_load_fpr64(DisasContext *ctx, TCGv_i64 t, int reg)
2824{
2825    if (ctx->hflags & MIPS_HFLAG_F64) {
2826        tcg_gen_mov_i64(t, fpu_f64[reg]);
2827    } else {
2828        tcg_gen_concat32_i64(t, fpu_f64[reg & ~1], fpu_f64[reg | 1]);
2829    }
2830}
2831
2832static void gen_store_fpr64(DisasContext *ctx, TCGv_i64 t, int reg)
2833{
2834    if (ctx->hflags & MIPS_HFLAG_F64) {
2835        tcg_gen_mov_i64(fpu_f64[reg], t);
2836    } else {
2837        TCGv_i64 t0;
2838        tcg_gen_deposit_i64(fpu_f64[reg & ~1], fpu_f64[reg & ~1], t, 0, 32);
2839        t0 = tcg_temp_new_i64();
2840        tcg_gen_shri_i64(t0, t, 32);
2841        tcg_gen_deposit_i64(fpu_f64[reg | 1], fpu_f64[reg | 1], t0, 0, 32);
2842        tcg_temp_free_i64(t0);
2843    }
2844}
2845
2846static inline int get_fp_bit(int cc)
2847{
2848    if (cc) {
2849        return 24 + cc;
2850    } else {
2851        return 23;
2852    }
2853}
2854
2855/* Addresses computation */
2856static inline void gen_op_addr_add(DisasContext *ctx, TCGv ret, TCGv arg0,
2857                                   TCGv arg1)
2858{
2859    tcg_gen_add_tl(ret, arg0, arg1);
2860
2861#if defined(TARGET_MIPS64)
2862    if (ctx->hflags & MIPS_HFLAG_AWRAP) {
2863        tcg_gen_ext32s_i64(ret, ret);
2864    }
2865#endif
2866}
2867
2868static inline void gen_op_addr_addi(DisasContext *ctx, TCGv ret, TCGv base,
2869                                    target_long ofs)
2870{
2871    tcg_gen_addi_tl(ret, base, ofs);
2872
2873#if defined(TARGET_MIPS64)
2874    if (ctx->hflags & MIPS_HFLAG_AWRAP) {
2875        tcg_gen_ext32s_i64(ret, ret);
2876    }
2877#endif
2878}
2879
2880/* Addresses computation (translation time) */
2881static target_long addr_add(DisasContext *ctx, target_long base,
2882                            target_long offset)
2883{
2884    target_long sum = base + offset;
2885
2886#if defined(TARGET_MIPS64)
2887    if (ctx->hflags & MIPS_HFLAG_AWRAP) {
2888        sum = (int32_t)sum;
2889    }
2890#endif
2891    return sum;
2892}
2893
2894/* Sign-extract the low 32-bits to a target_long.  */
2895static inline void gen_move_low32(TCGv ret, TCGv_i64 arg)
2896{
2897#if defined(TARGET_MIPS64)
2898    tcg_gen_ext32s_i64(ret, arg);
2899#else
2900    tcg_gen_extrl_i64_i32(ret, arg);
2901#endif
2902}
2903
2904/* Sign-extract the high 32-bits to a target_long.  */
2905static inline void gen_move_high32(TCGv ret, TCGv_i64 arg)
2906{
2907#if defined(TARGET_MIPS64)
2908    tcg_gen_sari_i64(ret, arg, 32);
2909#else
2910    tcg_gen_extrh_i64_i32(ret, arg);
2911#endif
2912}
2913
2914static inline void check_cp0_enabled(DisasContext *ctx)
2915{
2916    if (unlikely(!(ctx->hflags & MIPS_HFLAG_CP0))) {
2917        generate_exception_err(ctx, EXCP_CpU, 0);
2918    }
2919}
2920
2921static inline void check_cp1_enabled(DisasContext *ctx)
2922{
2923    if (unlikely(!(ctx->hflags & MIPS_HFLAG_FPU))) {
2924        generate_exception_err(ctx, EXCP_CpU, 1);
2925    }
2926}
2927
2928/*
2929 * Verify that the processor is running with COP1X instructions enabled.
2930 * This is associated with the nabla symbol in the MIPS32 and MIPS64
2931 * opcode tables.
2932 */
2933static inline void check_cop1x(DisasContext *ctx)
2934{
2935    if (unlikely(!(ctx->hflags & MIPS_HFLAG_COP1X))) {
2936        generate_exception_end(ctx, EXCP_RI);
2937    }
2938}
2939
2940/*
2941 * Verify that the processor is running with 64-bit floating-point
2942 * operations enabled.
2943 */
2944static inline void check_cp1_64bitmode(DisasContext *ctx)
2945{
2946    if (unlikely(~ctx->hflags & (MIPS_HFLAG_F64 | MIPS_HFLAG_COP1X))) {
2947        generate_exception_end(ctx, EXCP_RI);
2948    }
2949}
2950
2951/*
2952 * Verify if floating point register is valid; an operation is not defined
2953 * if bit 0 of any register specification is set and the FR bit in the
2954 * Status register equals zero, since the register numbers specify an
2955 * even-odd pair of adjacent coprocessor general registers. When the FR bit
2956 * in the Status register equals one, both even and odd register numbers
2957 * are valid. This limitation exists only for 64 bit wide (d,l,ps) registers.
2958 *
2959 * Multiple 64 bit wide registers can be checked by calling
2960 * gen_op_cp1_registers(freg1 | freg2 | ... | fregN);
2961 */
2962static inline void check_cp1_registers(DisasContext *ctx, int regs)
2963{
2964    if (unlikely(!(ctx->hflags & MIPS_HFLAG_F64) && (regs & 1))) {
2965        generate_exception_end(ctx, EXCP_RI);
2966    }
2967}
2968
2969/*
2970 * Verify that the processor is running with DSP instructions enabled.
2971 * This is enabled by CP0 Status register MX(24) bit.
2972 */
2973static inline void check_dsp(DisasContext *ctx)
2974{
2975    if (unlikely(!(ctx->hflags & MIPS_HFLAG_DSP))) {
2976        if (ctx->insn_flags & ASE_DSP) {
2977            generate_exception_end(ctx, EXCP_DSPDIS);
2978        } else {
2979            generate_exception_end(ctx, EXCP_RI);
2980        }
2981    }
2982}
2983
2984static inline void check_dsp_r2(DisasContext *ctx)
2985{
2986    if (unlikely(!(ctx->hflags & MIPS_HFLAG_DSP_R2))) {
2987        if (ctx->insn_flags & ASE_DSP) {
2988            generate_exception_end(ctx, EXCP_DSPDIS);
2989        } else {
2990            generate_exception_end(ctx, EXCP_RI);
2991        }
2992    }
2993}
2994
2995static inline void check_dsp_r3(DisasContext *ctx)
2996{
2997    if (unlikely(!(ctx->hflags & MIPS_HFLAG_DSP_R3))) {
2998        if (ctx->insn_flags & ASE_DSP) {
2999            generate_exception_end(ctx, EXCP_DSPDIS);
3000        } else {
3001            generate_exception_end(ctx, EXCP_RI);
3002        }
3003    }
3004}
3005
3006/*
3007 * This code generates a "reserved instruction" exception if the
3008 * CPU does not support the instruction set corresponding to flags.
3009 */
3010static inline void check_insn(DisasContext *ctx, uint64_t flags)
3011{
3012    if (unlikely(!(ctx->insn_flags & flags))) {
3013        generate_exception_end(ctx, EXCP_RI);
3014    }
3015}
3016
3017/*
3018 * This code generates a "reserved instruction" exception if the
3019 * CPU has corresponding flag set which indicates that the instruction
3020 * has been removed.
3021 */
3022static inline void check_insn_opc_removed(DisasContext *ctx, uint64_t flags)
3023{
3024    if (unlikely(ctx->insn_flags & flags)) {
3025        generate_exception_end(ctx, EXCP_RI);
3026    }
3027}
3028
3029/*
3030 * The Linux kernel traps certain reserved instruction exceptions to
3031 * emulate the corresponding instructions. QEMU is the kernel in user
3032 * mode, so those traps are emulated by accepting the instructions.
3033 *
3034 * A reserved instruction exception is generated for flagged CPUs if
3035 * QEMU runs in system mode.
3036 */
3037static inline void check_insn_opc_user_only(DisasContext *ctx, uint64_t flags)
3038{
3039#ifndef CONFIG_USER_ONLY
3040    check_insn_opc_removed(ctx, flags);
3041#endif
3042}
3043
3044/*
3045 * This code generates a "reserved instruction" exception if the
3046 * CPU does not support 64-bit paired-single (PS) floating point data type.
3047 */
3048static inline void check_ps(DisasContext *ctx)
3049{
3050    if (unlikely(!ctx->ps)) {
3051        generate_exception(ctx, EXCP_RI);
3052    }
3053    check_cp1_64bitmode(ctx);
3054}
3055
3056#ifdef TARGET_MIPS64
3057/*
3058 * This code generates a "reserved instruction" exception if 64-bit
3059 * instructions are not enabled.
3060 */
3061static inline void check_mips_64(DisasContext *ctx)
3062{
3063    if (unlikely(!(ctx->hflags & MIPS_HFLAG_64))) {
3064        generate_exception_end(ctx, EXCP_RI);
3065    }
3066}
3067#endif
3068
3069#ifndef CONFIG_USER_ONLY
3070static inline void check_mvh(DisasContext *ctx)
3071{
3072    if (unlikely(!ctx->mvh)) {
3073        generate_exception(ctx, EXCP_RI);
3074    }
3075}
3076#endif
3077
3078/*
3079 * This code generates a "reserved instruction" exception if the
3080 * Config5 XNP bit is set.
3081 */
3082static inline void check_xnp(DisasContext *ctx)
3083{
3084    if (unlikely(ctx->CP0_Config5 & (1 << CP0C5_XNP))) {
3085        generate_exception_end(ctx, EXCP_RI);
3086    }
3087}
3088
3089#ifndef CONFIG_USER_ONLY
3090/*
3091 * This code generates a "reserved instruction" exception if the
3092 * Config3 PW bit is NOT set.
3093 */
3094static inline void check_pw(DisasContext *ctx)
3095{
3096    if (unlikely(!(ctx->CP0_Config3 & (1 << CP0C3_PW)))) {
3097        generate_exception_end(ctx, EXCP_RI);
3098    }
3099}
3100#endif
3101
3102/*
3103 * This code generates a "reserved instruction" exception if the
3104 * Config3 MT bit is NOT set.
3105 */
3106static inline void check_mt(DisasContext *ctx)
3107{
3108    if (unlikely(!(ctx->CP0_Config3 & (1 << CP0C3_MT)))) {
3109        generate_exception_end(ctx, EXCP_RI);
3110    }
3111}
3112
3113#ifndef CONFIG_USER_ONLY
3114/*
3115 * This code generates a "coprocessor unusable" exception if CP0 is not
3116 * available, and, if that is not the case, generates a "reserved instruction"
3117 * exception if the Config5 MT bit is NOT set. This is needed for availability
3118 * control of some of MT ASE instructions.
3119 */
3120static inline void check_cp0_mt(DisasContext *ctx)
3121{
3122    if (unlikely(!(ctx->hflags & MIPS_HFLAG_CP0))) {
3123        generate_exception_err(ctx, EXCP_CpU, 0);
3124    } else {
3125        if (unlikely(!(ctx->CP0_Config3 & (1 << CP0C3_MT)))) {
3126            generate_exception_err(ctx, EXCP_RI, 0);
3127        }
3128    }
3129}
3130#endif
3131
3132/*
3133 * This code generates a "reserved instruction" exception if the
3134 * Config5 NMS bit is set.
3135 */
3136static inline void check_nms(DisasContext *ctx)
3137{
3138    if (unlikely(ctx->CP0_Config5 & (1 << CP0C5_NMS))) {
3139        generate_exception_end(ctx, EXCP_RI);
3140    }
3141}
3142
3143/*
3144 * This code generates a "reserved instruction" exception if the
3145 * Config5 NMS bit is set, and Config1 DL, Config1 IL, Config2 SL,
3146 * Config2 TL, and Config5 L2C are unset.
3147 */
3148static inline void check_nms_dl_il_sl_tl_l2c(DisasContext *ctx)
3149{
3150    if (unlikely((ctx->CP0_Config5 & (1 << CP0C5_NMS)) &&
3151                 !(ctx->CP0_Config1 & (1 << CP0C1_DL)) &&
3152                 !(ctx->CP0_Config1 & (1 << CP0C1_IL)) &&
3153                 !(ctx->CP0_Config2 & (1 << CP0C2_SL)) &&
3154                 !(ctx->CP0_Config2 & (1 << CP0C2_TL)) &&
3155                 !(ctx->CP0_Config5 & (1 << CP0C5_L2C)))) {
3156        generate_exception_end(ctx, EXCP_RI);
3157    }
3158}
3159
3160/*
3161 * This code generates a "reserved instruction" exception if the
3162 * Config5 EVA bit is NOT set.
3163 */
3164static inline void check_eva(DisasContext *ctx)
3165{
3166    if (unlikely(!(ctx->CP0_Config5 & (1 << CP0C5_EVA)))) {
3167        generate_exception_end(ctx, EXCP_RI);
3168    }
3169}
3170
3171
3172/*
3173 * Define small wrappers for gen_load_fpr* so that we have a uniform
3174 * calling interface for 32 and 64-bit FPRs.  No sense in changing
3175 * all callers for gen_load_fpr32 when we need the CTX parameter for
3176 * this one use.
3177 */
3178#define gen_ldcmp_fpr32(ctx, x, y) gen_load_fpr32(ctx, x, y)
3179#define gen_ldcmp_fpr64(ctx, x, y) gen_load_fpr64(ctx, x, y)
3180#define FOP_CONDS(type, abs, fmt, ifmt, bits)                                 \
3181static inline void gen_cmp ## type ## _ ## fmt(DisasContext *ctx, int n,      \
3182                                               int ft, int fs, int cc)        \
3183{                                                                             \
3184    TCGv_i##bits fp0 = tcg_temp_new_i##bits ();                               \
3185    TCGv_i##bits fp1 = tcg_temp_new_i##bits ();                               \
3186    switch (ifmt) {                                                           \
3187    case FMT_PS:                                                              \
3188        check_ps(ctx);                                                        \
3189        break;                                                                \
3190    case FMT_D:                                                               \
3191        if (abs) {                                                            \
3192            check_cop1x(ctx);                                                 \
3193        }                                                                     \
3194        check_cp1_registers(ctx, fs | ft);                                    \
3195        break;                                                                \
3196    case FMT_S:                                                               \
3197        if (abs) {                                                            \
3198            check_cop1x(ctx);                                                 \
3199        }                                                                     \
3200        break;                                                                \
3201    }                                                                         \
3202    gen_ldcmp_fpr##bits (ctx, fp0, fs);                                       \
3203    gen_ldcmp_fpr##bits (ctx, fp1, ft);                                       \
3204    switch (n) {                                                              \
3205    case  0:                                                                  \
3206        gen_helper_0e2i(cmp ## type ## _ ## fmt ## _f, fp0, fp1, cc);         \
3207    break;                                                                    \
3208    case  1:                                                                  \
3209        gen_helper_0e2i(cmp ## type ## _ ## fmt ## _un, fp0, fp1, cc);        \
3210    break;                                                                    \
3211    case  2:                                                                  \
3212        gen_helper_0e2i(cmp ## type ## _ ## fmt ## _eq, fp0, fp1, cc);        \
3213    break;                                                                    \
3214    case  3:                                                                  \
3215        gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ueq, fp0, fp1, cc);       \
3216    break;                                                                    \
3217    case  4:                                                                  \
3218        gen_helper_0e2i(cmp ## type ## _ ## fmt ## _olt, fp0, fp1, cc);       \
3219    break;                                                                    \
3220    case  5:                                                                  \
3221        gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ult, fp0, fp1, cc);       \
3222    break;                                                                    \
3223    case  6:                                                                  \
3224        gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ole, fp0, fp1, cc);       \
3225    break;                                                                    \
3226    case  7:                                                                  \
3227        gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ule, fp0, fp1, cc);       \
3228    break;                                                                    \
3229    case  8:                                                                  \
3230        gen_helper_0e2i(cmp ## type ## _ ## fmt ## _sf, fp0, fp1, cc);        \
3231    break;                                                                    \
3232    case  9:                                                                  \
3233        gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ngle, fp0, fp1, cc);      \
3234    break;                                                                    \
3235    case 10:                                                                  \
3236        gen_helper_0e2i(cmp ## type ## _ ## fmt ## _seq, fp0, fp1, cc);       \
3237    break;                                                                    \
3238    case 11:                                                                  \
3239        gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ngl, fp0, fp1, cc);       \
3240    break;                                                                    \
3241    case 12:                                                                  \
3242        gen_helper_0e2i(cmp ## type ## _ ## fmt ## _lt, fp0, fp1, cc);        \
3243    break;                                                                    \
3244    case 13:                                                                  \
3245        gen_helper_0e2i(cmp ## type ## _ ## fmt ## _nge, fp0, fp1, cc);       \
3246    break;                                                                    \
3247    case 14:                                                                  \
3248        gen_helper_0e2i(cmp ## type ## _ ## fmt ## _le, fp0, fp1, cc);        \
3249    break;                                                                    \
3250    case 15:                                                                  \
3251        gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ngt, fp0, fp1, cc);       \
3252    break;                                                                    \
3253    default:                                                                  \
3254        abort();                                                              \
3255    }                                                                         \
3256    tcg_temp_free_i##bits (fp0);                                              \
3257    tcg_temp_free_i##bits (fp1);                                              \
3258}
3259
3260FOP_CONDS(, 0, d, FMT_D, 64)
3261FOP_CONDS(abs, 1, d, FMT_D, 64)
3262FOP_CONDS(, 0, s, FMT_S, 32)
3263FOP_CONDS(abs, 1, s, FMT_S, 32)
3264FOP_CONDS(, 0, ps, FMT_PS, 64)
3265FOP_CONDS(abs, 1, ps, FMT_PS, 64)
3266#undef FOP_CONDS
3267
3268#define FOP_CONDNS(fmt, ifmt, bits, STORE)                              \
3269static inline void gen_r6_cmp_ ## fmt(DisasContext * ctx, int n,        \
3270                                      int ft, int fs, int fd)           \
3271{                                                                       \
3272    TCGv_i ## bits fp0 = tcg_temp_new_i ## bits();                      \
3273    TCGv_i ## bits fp1 = tcg_temp_new_i ## bits();                      \
3274    if (ifmt == FMT_D) {                                                \
3275        check_cp1_registers(ctx, fs | ft | fd);                         \
3276    }                                                                   \
3277    gen_ldcmp_fpr ## bits(ctx, fp0, fs);                                \
3278    gen_ldcmp_fpr ## bits(ctx, fp1, ft);                                \
3279    switch (n) {                                                        \
3280    case  0:                                                            \
3281        gen_helper_r6_cmp_ ## fmt ## _af(fp0, cpu_env, fp0, fp1);       \
3282        break;                                                          \
3283    case  1:                                                            \
3284        gen_helper_r6_cmp_ ## fmt ## _un(fp0, cpu_env, fp0, fp1);       \
3285        break;                                                          \
3286    case  2:                                                            \
3287        gen_helper_r6_cmp_ ## fmt ## _eq(fp0, cpu_env, fp0, fp1);       \
3288        break;                                                          \
3289    case  3:                                                            \
3290        gen_helper_r6_cmp_ ## fmt ## _ueq(fp0, cpu_env, fp0, fp1);      \
3291        break;                                                          \
3292    case  4:                                                            \
3293        gen_helper_r6_cmp_ ## fmt ## _lt(fp0, cpu_env, fp0, fp1);       \
3294        break;                                                          \
3295    case  5:                                                            \
3296        gen_helper_r6_cmp_ ## fmt ## _ult(fp0, cpu_env, fp0, fp1);      \
3297        break;                                                          \
3298    case  6:                                                            \
3299        gen_helper_r6_cmp_ ## fmt ## _le(fp0, cpu_env, fp0, fp1);       \
3300        break;                                                          \
3301    case  7:                                                            \
3302        gen_helper_r6_cmp_ ## fmt ## _ule(fp0, cpu_env, fp0, fp1);      \
3303        break;                                                          \
3304    case  8:                                                            \
3305        gen_helper_r6_cmp_ ## fmt ## _saf(fp0, cpu_env, fp0, fp1);      \
3306        break;                                                          \
3307    case  9:                                                            \
3308        gen_helper_r6_cmp_ ## fmt ## _sun(fp0, cpu_env, fp0, fp1);      \
3309        break;                                                          \
3310    case 10:                                                            \
3311        gen_helper_r6_cmp_ ## fmt ## _seq(fp0, cpu_env, fp0, fp1);      \
3312        break;                                                          \
3313    case 11:                                                            \
3314        gen_helper_r6_cmp_ ## fmt ## _sueq(fp0, cpu_env, fp0, fp1);     \
3315        break;                                                          \
3316    case 12:                                                            \
3317        gen_helper_r6_cmp_ ## fmt ## _slt(fp0, cpu_env, fp0, fp1);      \
3318        break;                                                          \
3319    case 13:                                                            \
3320        gen_helper_r6_cmp_ ## fmt ## _sult(fp0, cpu_env, fp0, fp1);     \
3321        break;                                                          \
3322    case 14:                                                            \
3323        gen_helper_r6_cmp_ ## fmt ## _sle(fp0, cpu_env, fp0, fp1);      \
3324        break;                                                          \
3325    case 15:                                                            \
3326        gen_helper_r6_cmp_ ## fmt ## _sule(fp0, cpu_env, fp0, fp1);     \
3327        break;                                                          \
3328    case 17:                                                            \
3329        gen_helper_r6_cmp_ ## fmt ## _or(fp0, cpu_env, fp0, fp1);       \
3330        break;                                                          \
3331    case 18:                                                            \
3332        gen_helper_r6_cmp_ ## fmt ## _une(fp0, cpu_env, fp0, fp1);      \
3333        break;                                                          \
3334    case 19:                                                            \
3335        gen_helper_r6_cmp_ ## fmt ## _ne(fp0, cpu_env, fp0, fp1);       \
3336        break;                                                          \
3337    case 25:                                                            \
3338        gen_helper_r6_cmp_ ## fmt ## _sor(fp0, cpu_env, fp0, fp1);      \
3339        break;                                                          \
3340    case 26:                                                            \
3341        gen_helper_r6_cmp_ ## fmt ## _sune(fp0, cpu_env, fp0, fp1);     \
3342        break;                                                          \
3343    case 27:                                                            \
3344        gen_helper_r6_cmp_ ## fmt ## _sne(fp0, cpu_env, fp0, fp1);      \
3345        break;                                                          \
3346    default:                                                            \
3347        abort();                                                        \
3348    }                                                                   \
3349    STORE;                                                              \
3350    tcg_temp_free_i ## bits (fp0);                                      \
3351    tcg_temp_free_i ## bits (fp1);                                      \
3352}
3353
3354FOP_CONDNS(d, FMT_D, 64, gen_store_fpr64(ctx, fp0, fd))
3355FOP_CONDNS(s, FMT_S, 32, gen_store_fpr32(ctx, fp0, fd))
3356#undef FOP_CONDNS
3357#undef gen_ldcmp_fpr32
3358#undef gen_ldcmp_fpr64
3359
3360/* load/store instructions. */
3361#ifdef CONFIG_USER_ONLY
3362#define OP_LD_ATOMIC(insn,fname)                                           \
3363static inline void op_ld_##insn(TCGv ret, TCGv arg1, int mem_idx,          \
3364                                DisasContext *ctx)                         \
3365{                                                                          \
3366    TCGv t0 = tcg_temp_new();                                              \
3367    tcg_gen_mov_tl(t0, arg1);                                              \
3368    tcg_gen_qemu_##fname(ret, arg1, ctx->mem_idx);                         \
3369    tcg_gen_st_tl(t0, cpu_env, offsetof(CPUMIPSState, lladdr));                \
3370    tcg_gen_st_tl(ret, cpu_env, offsetof(CPUMIPSState, llval));                \
3371    tcg_temp_free(t0);                                                     \
3372}
3373#else
3374#define OP_LD_ATOMIC(insn,fname)                                           \
3375static inline void op_ld_##insn(TCGv ret, TCGv arg1, int mem_idx,          \
3376                                DisasContext *ctx)                         \
3377{                                                                          \
3378    gen_helper_1e1i(insn, ret, arg1, mem_idx);                             \
3379}
3380#endif
3381OP_LD_ATOMIC(ll,ld32s);
3382#if defined(TARGET_MIPS64)
3383OP_LD_ATOMIC(lld,ld64);
3384#endif
3385#undef OP_LD_ATOMIC
3386
3387static void gen_base_offset_addr(DisasContext *ctx, TCGv addr,
3388                                 int base, int offset)
3389{
3390    if (base == 0) {
3391        tcg_gen_movi_tl(addr, offset);
3392    } else if (offset == 0) {
3393        gen_load_gpr(addr, base);
3394    } else {
3395        tcg_gen_movi_tl(addr, offset);
3396        gen_op_addr_add(ctx, addr, cpu_gpr[base], addr);
3397    }
3398}
3399
3400static target_ulong pc_relative_pc(DisasContext *ctx)
3401{
3402    target_ulong pc = ctx->base.pc_next;
3403
3404    if (ctx->hflags & MIPS_HFLAG_BMASK) {
3405        int branch_bytes = ctx->hflags & MIPS_HFLAG_BDS16 ? 2 : 4;
3406
3407        pc -= branch_bytes;
3408    }
3409
3410    pc &= ~(target_ulong)3;
3411    return pc;
3412}
3413
3414/* Load */
3415static void gen_ld(DisasContext *ctx, uint32_t opc,
3416                   int rt, int base, int offset)
3417{
3418    TCGv t0, t1, t2;
3419    int mem_idx = ctx->mem_idx;
3420
3421    if (rt == 0 && ctx->insn_flags & (INSN_LOONGSON2E | INSN_LOONGSON2F)) {
3422        /*
3423         * Loongson CPU uses a load to zero register for prefetch.
3424         * We emulate it as a NOP. On other CPU we must perform the
3425         * actual memory access.
3426         */
3427        return;
3428    }
3429
3430    t0 = tcg_temp_new();
3431    gen_base_offset_addr(ctx, t0, base, offset);
3432
3433    switch (opc) {
3434#if defined(TARGET_MIPS64)
3435    case OPC_LWU:
3436        tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TEUL |
3437                           ctx->default_tcg_memop_mask);
3438        gen_store_gpr(t0, rt);
3439        break;
3440    case OPC_LD:
3441        tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TEQ |
3442                           ctx->default_tcg_memop_mask);
3443        gen_store_gpr(t0, rt);
3444        break;
3445    case OPC_LLD:
3446    case R6_OPC_LLD:
3447        op_ld_lld(t0, t0, mem_idx, ctx);
3448        gen_store_gpr(t0, rt);
3449        break;
3450    case OPC_LDL:
3451        t1 = tcg_temp_new();
3452        /*
3453         * Do a byte access to possibly trigger a page
3454         * fault with the unaligned address.
3455         */
3456        tcg_gen_qemu_ld_tl(t1, t0, mem_idx, MO_UB);
3457        tcg_gen_andi_tl(t1, t0, 7);
3458#ifndef TARGET_WORDS_BIGENDIAN
3459        tcg_gen_xori_tl(t1, t1, 7);
3460#endif
3461        tcg_gen_shli_tl(t1, t1, 3);
3462        tcg_gen_andi_tl(t0, t0, ~7);
3463        tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TEQ);
3464        tcg_gen_shl_tl(t0, t0, t1);
3465        t2 = tcg_const_tl(-1);
3466        tcg_gen_shl_tl(t2, t2, t1);
3467        gen_load_gpr(t1, rt);
3468        tcg_gen_andc_tl(t1, t1, t2);
3469        tcg_temp_free(t2);
3470        tcg_gen_or_tl(t0, t0, t1);
3471        tcg_temp_free(t1);
3472        gen_store_gpr(t0, rt);
3473        break;
3474    case OPC_LDR:
3475        t1 = tcg_temp_new();
3476        /*
3477         * Do a byte access to possibly trigger a page
3478         * fault with the unaligned address.
3479         */
3480        tcg_gen_qemu_ld_tl(t1, t0, mem_idx, MO_UB);
3481        tcg_gen_andi_tl(t1, t0, 7);
3482#ifdef TARGET_WORDS_BIGENDIAN
3483        tcg_gen_xori_tl(t1, t1, 7);
3484#endif
3485        tcg_gen_shli_tl(t1, t1, 3);
3486        tcg_gen_andi_tl(t0, t0, ~7);
3487        tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TEQ);
3488        tcg_gen_shr_tl(t0, t0, t1);
3489        tcg_gen_xori_tl(t1, t1, 63);
3490        t2 = tcg_const_tl(0xfffffffffffffffeull);
3491        tcg_gen_shl_tl(t2, t2, t1);
3492        gen_load_gpr(t1, rt);
3493        tcg_gen_and_tl(t1, t1, t2);
3494        tcg_temp_free(t2);
3495        tcg_gen_or_tl(t0, t0, t1);
3496        tcg_temp_free(t1);
3497        gen_store_gpr(t0, rt);
3498        break;
3499    case OPC_LDPC:
3500        t1 = tcg_const_tl(pc_relative_pc(ctx));
3501        gen_op_addr_add(ctx, t0, t0, t1);
3502        tcg_temp_free(t1);
3503        tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TEQ);
3504        gen_store_gpr(t0, rt);
3505        break;
3506#endif
3507    case OPC_LWPC:
3508        t1 = tcg_const_tl(pc_relative_pc(ctx));
3509        gen_op_addr_add(ctx, t0, t0, t1);
3510        tcg_temp_free(t1);
3511        tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TESL);
3512        gen_store_gpr(t0, rt);
3513        break;
3514    case OPC_LWE:
3515        mem_idx = MIPS_HFLAG_UM;
3516        /* fall through */
3517    case OPC_LW:
3518        tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TESL |
3519                           ctx->default_tcg_memop_mask);
3520        gen_store_gpr(t0, rt);
3521        break;
3522    case OPC_LHE:
3523        mem_idx = MIPS_HFLAG_UM;
3524        /* fall through */
3525    case OPC_LH:
3526        tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TESW |
3527                           ctx->default_tcg_memop_mask);
3528        gen_store_gpr(t0, rt);
3529        break;
3530    case OPC_LHUE:
3531        mem_idx = MIPS_HFLAG_UM;
3532        /* fall through */
3533    case OPC_LHU:
3534        tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TEUW |
3535                           ctx->default_tcg_memop_mask);
3536        gen_store_gpr(t0, rt);
3537        break;
3538    case OPC_LBE:
3539        mem_idx = MIPS_HFLAG_UM;
3540        /* fall through */
3541    case OPC_LB:
3542        tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_SB);
3543        gen_store_gpr(t0, rt);
3544        break;
3545    case OPC_LBUE:
3546        mem_idx = MIPS_HFLAG_UM;
3547        /* fall through */
3548    case OPC_LBU:
3549        tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_UB);
3550        gen_store_gpr(t0, rt);
3551        break;
3552    case OPC_LWLE:
3553        mem_idx = MIPS_HFLAG_UM;
3554        /* fall through */
3555    case OPC_LWL:
3556        t1 = tcg_temp_new();
3557        /*
3558         * Do a byte access to possibly trigger a page
3559         * fault with the unaligned address.
3560         */
3561        tcg_gen_qemu_ld_tl(t1, t0, mem_idx, MO_UB);
3562        tcg_gen_andi_tl(t1, t0, 3);
3563#ifndef TARGET_WORDS_BIGENDIAN
3564        tcg_gen_xori_tl(t1, t1, 3);
3565#endif
3566        tcg_gen_shli_tl(t1, t1, 3);
3567        tcg_gen_andi_tl(t0, t0, ~3);
3568        tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TEUL);
3569        tcg_gen_shl_tl(t0, t0, t1);
3570        t2 = tcg_const_tl(-1);
3571        tcg_gen_shl_tl(t2, t2, t1);
3572        gen_load_gpr(t1, rt);
3573        tcg_gen_andc_tl(t1, t1, t2);
3574        tcg_temp_free(t2);
3575        tcg_gen_or_tl(t0, t0, t1);
3576        tcg_temp_free(t1);
3577        tcg_gen_ext32s_tl(t0, t0);
3578        gen_store_gpr(t0, rt);
3579        break;
3580    case OPC_LWRE:
3581        mem_idx = MIPS_HFLAG_UM;
3582        /* fall through */
3583    case OPC_LWR:
3584        t1 = tcg_temp_new();
3585        /*
3586         * Do a byte access to possibly trigger a page
3587         * fault with the unaligned address.
3588         */
3589        tcg_gen_qemu_ld_tl(t1, t0, mem_idx, MO_UB);
3590        tcg_gen_andi_tl(t1, t0, 3);
3591#ifdef TARGET_WORDS_BIGENDIAN
3592        tcg_gen_xori_tl(t1, t1, 3);
3593#endif
3594        tcg_gen_shli_tl(t1, t1, 3);
3595        tcg_gen_andi_tl(t0, t0, ~3);
3596        tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TEUL);
3597        tcg_gen_shr_tl(t0, t0, t1);
3598        tcg_gen_xori_tl(t1, t1, 31);
3599        t2 = tcg_const_tl(0xfffffffeull);
3600        tcg_gen_shl_tl(t2, t2, t1);
3601        gen_load_gpr(t1, rt);
3602        tcg_gen_and_tl(t1, t1, t2);
3603        tcg_temp_free(t2);
3604        tcg_gen_or_tl(t0, t0, t1);
3605        tcg_temp_free(t1);
3606        tcg_gen_ext32s_tl(t0, t0);
3607        gen_store_gpr(t0, rt);
3608        break;
3609    case OPC_LLE:
3610        mem_idx = MIPS_HFLAG_UM;
3611        /* fall through */
3612    case OPC_LL:
3613    case R6_OPC_LL:
3614        op_ld_ll(t0, t0, mem_idx, ctx);
3615        gen_store_gpr(t0, rt);
3616        break;
3617    }
3618    tcg_temp_free(t0);
3619}
3620
3621static void gen_llwp(DisasContext *ctx, uint32_t base, int16_t offset,
3622                    uint32_t reg1, uint32_t reg2)
3623{
3624    TCGv taddr = tcg_temp_new();
3625    TCGv_i64 tval = tcg_temp_new_i64();
3626    TCGv tmp1 = tcg_temp_new();
3627    TCGv tmp2 = tcg_temp_new();
3628
3629    gen_base_offset_addr(ctx, taddr, base, offset);
3630    tcg_gen_qemu_ld64(tval, taddr, ctx->mem_idx);
3631#ifdef TARGET_WORDS_BIGENDIAN
3632    tcg_gen_extr_i64_tl(tmp2, tmp1, tval);
3633#else
3634    tcg_gen_extr_i64_tl(tmp1, tmp2, tval);
3635#endif
3636    gen_store_gpr(tmp1, reg1);
3637    tcg_temp_free(tmp1);
3638    gen_store_gpr(tmp2, reg2);
3639    tcg_temp_free(tmp2);
3640    tcg_gen_st_i64(tval, cpu_env, offsetof(CPUMIPSState, llval_wp));
3641    tcg_temp_free_i64(tval);
3642    tcg_gen_st_tl(taddr, cpu_env, offsetof(CPUMIPSState, lladdr));
3643    tcg_temp_free(taddr);
3644}
3645
3646/* Store */
3647static void gen_st(DisasContext *ctx, uint32_t opc, int rt,
3648                   int base, int offset)
3649{
3650    TCGv t0 = tcg_temp_new();
3651    TCGv t1 = tcg_temp_new();
3652    int mem_idx = ctx->mem_idx;
3653
3654    gen_base_offset_addr(ctx, t0, base, offset);
3655    gen_load_gpr(t1, rt);
3656    switch (opc) {
3657#if defined(TARGET_MIPS64)
3658    case OPC_SD:
3659        tcg_gen_qemu_st_tl(t1, t0, mem_idx, MO_TEQ |
3660                           ctx->default_tcg_memop_mask);
3661        break;
3662    case OPC_SDL:
3663        gen_helper_0e2i(sdl, t1, t0, mem_idx);
3664        break;
3665    case OPC_SDR:
3666        gen_helper_0e2i(sdr, t1, t0, mem_idx);
3667        break;
3668#endif
3669    case OPC_SWE:
3670        mem_idx = MIPS_HFLAG_UM;
3671        /* fall through */
3672    case OPC_SW:
3673        tcg_gen_qemu_st_tl(t1, t0, mem_idx, MO_TEUL |
3674                           ctx->default_tcg_memop_mask);
3675        break;
3676    case OPC_SHE:
3677        mem_idx = MIPS_HFLAG_UM;
3678        /* fall through */
3679    case OPC_SH:
3680        tcg_gen_qemu_st_tl(t1, t0, mem_idx, MO_TEUW |
3681                           ctx->default_tcg_memop_mask);
3682        break;
3683    case OPC_SBE:
3684        mem_idx = MIPS_HFLAG_UM;
3685        /* fall through */
3686    case OPC_SB:
3687        tcg_gen_qemu_st_tl(t1, t0, mem_idx, MO_8);
3688        break;
3689    case OPC_SWLE:
3690        mem_idx = MIPS_HFLAG_UM;
3691        /* fall through */
3692    case OPC_SWL:
3693        gen_helper_0e2i(swl, t1, t0, mem_idx);
3694        break;
3695    case OPC_SWRE:
3696        mem_idx = MIPS_HFLAG_UM;
3697        /* fall through */
3698    case OPC_SWR:
3699        gen_helper_0e2i(swr, t1, t0, mem_idx);
3700        break;
3701    }
3702    tcg_temp_free(t0);
3703    tcg_temp_free(t1);
3704}
3705
3706
3707/* Store conditional */
3708static void gen_st_cond(DisasContext *ctx, int rt, int base, int offset,
3709                        TCGMemOp tcg_mo, bool eva)
3710{
3711    TCGv addr, t0, val;
3712    TCGLabel *l1 = gen_new_label();
3713    TCGLabel *done = gen_new_label();
3714
3715    t0 = tcg_temp_new();
3716    addr = tcg_temp_new();
3717    /* compare the address against that of the preceeding LL */
3718    gen_base_offset_addr(ctx, addr, base, offset);
3719    tcg_gen_brcond_tl(TCG_COND_EQ, addr, cpu_lladdr, l1);
3720    tcg_temp_free(addr);
3721    tcg_gen_movi_tl(t0, 0);
3722    gen_store_gpr(t0, rt);
3723    tcg_gen_br(done);
3724
3725    gen_set_label(l1);
3726    /* generate cmpxchg */
3727    val = tcg_temp_new();
3728    gen_load_gpr(val, rt);
3729    tcg_gen_atomic_cmpxchg_tl(t0, cpu_lladdr, cpu_llval, val,
3730                              eva ? MIPS_HFLAG_UM : ctx->mem_idx, tcg_mo);
3731    tcg_gen_setcond_tl(TCG_COND_EQ, t0, t0, cpu_llval);
3732    gen_store_gpr(t0, rt);
3733    tcg_temp_free(val);
3734
3735    gen_set_label(done);
3736    tcg_temp_free(t0);
3737}
3738
3739
3740static void gen_scwp(DisasContext *ctx, uint32_t base, int16_t offset,
3741                    uint32_t reg1, uint32_t reg2, bool eva)
3742{
3743    TCGv taddr = tcg_temp_local_new();
3744    TCGv lladdr = tcg_temp_local_new();
3745    TCGv_i64 tval = tcg_temp_new_i64();
3746    TCGv_i64 llval = tcg_temp_new_i64();
3747    TCGv_i64 val = tcg_temp_new_i64();
3748    TCGv tmp1 = tcg_temp_new();
3749    TCGv tmp2 = tcg_temp_new();
3750    TCGLabel *lab_fail = gen_new_label();
3751    TCGLabel *lab_done = gen_new_label();
3752
3753    gen_base_offset_addr(ctx, taddr, base, offset);
3754
3755    tcg_gen_ld_tl(lladdr, cpu_env, offsetof(CPUMIPSState, lladdr));
3756    tcg_gen_brcond_tl(TCG_COND_NE, taddr, lladdr, lab_fail);
3757
3758    gen_load_gpr(tmp1, reg1);
3759    gen_load_gpr(tmp2, reg2);
3760
3761#ifdef TARGET_WORDS_BIGENDIAN
3762    tcg_gen_concat_tl_i64(tval, tmp2, tmp1);
3763#else
3764    tcg_gen_concat_tl_i64(tval, tmp1, tmp2);
3765#endif
3766
3767    tcg_gen_ld_i64(llval, cpu_env, offsetof(CPUMIPSState, llval_wp));
3768    tcg_gen_atomic_cmpxchg_i64(val, taddr, llval, tval,
3769                               eva ? MIPS_HFLAG_UM : ctx->mem_idx, MO_64);
3770    if (reg1 != 0) {
3771        tcg_gen_movi_tl(cpu_gpr[reg1], 1);
3772    }
3773    tcg_gen_brcond_i64(TCG_COND_EQ, val, llval, lab_done);
3774
3775    gen_set_label(lab_fail);
3776
3777    if (reg1 != 0) {
3778        tcg_gen_movi_tl(cpu_gpr[reg1], 0);
3779    }
3780    gen_set_label(lab_done);
3781    tcg_gen_movi_tl(lladdr, -1);
3782    tcg_gen_st_tl(lladdr, cpu_env, offsetof(CPUMIPSState, lladdr));
3783}
3784
3785/* Load and store */
3786static void gen_flt_ldst(DisasContext *ctx, uint32_t opc, int ft,
3787                         TCGv t0)
3788{
3789    /*
3790     * Don't do NOP if destination is zero: we must perform the actual
3791     * memory access.
3792     */
3793    switch (opc) {
3794    case OPC_LWC1:
3795        {
3796            TCGv_i32 fp0 = tcg_temp_new_i32();
3797            tcg_gen_qemu_ld_i32(fp0, t0, ctx->mem_idx, MO_TESL |
3798                                ctx->default_tcg_memop_mask);
3799            gen_store_fpr32(ctx, fp0, ft);
3800            tcg_temp_free_i32(fp0);
3801        }
3802        break;
3803    case OPC_SWC1:
3804        {
3805            TCGv_i32 fp0 = tcg_temp_new_i32();
3806            gen_load_fpr32(ctx, fp0, ft);
3807            tcg_gen_qemu_st_i32(fp0, t0, ctx->mem_idx, MO_TEUL |
3808                                ctx->default_tcg_memop_mask);
3809            tcg_temp_free_i32(fp0);
3810        }
3811        break;
3812    case OPC_LDC1:
3813        {
3814            TCGv_i64 fp0 = tcg_temp_new_i64();
3815            tcg_gen_qemu_ld_i64(fp0, t0, ctx->mem_idx, MO_TEQ |
3816                                ctx->default_tcg_memop_mask);
3817            gen_store_fpr64(ctx, fp0, ft);
3818            tcg_temp_free_i64(fp0);
3819        }
3820        break;
3821    case OPC_SDC1:
3822        {
3823            TCGv_i64 fp0 = tcg_temp_new_i64();
3824            gen_load_fpr64(ctx, fp0, ft);
3825            tcg_gen_qemu_st_i64(fp0, t0, ctx->mem_idx, MO_TEQ |
3826                                ctx->default_tcg_memop_mask);
3827            tcg_temp_free_i64(fp0);
3828        }
3829        break;
3830    default:
3831        MIPS_INVAL("flt_ldst");
3832        generate_exception_end(ctx, EXCP_RI);
3833        break;
3834    }
3835}
3836
3837static void gen_cop1_ldst(DisasContext *ctx, uint32_t op, int rt,
3838                          int rs, int16_t imm)
3839{
3840    TCGv t0 = tcg_temp_new();
3841
3842    if (ctx->CP0_Config1 & (1 << CP0C1_FP)) {
3843        check_cp1_enabled(ctx);
3844        switch (op) {
3845        case OPC_LDC1:
3846        case OPC_SDC1:
3847            check_insn(ctx, ISA_MIPS2);
3848            /* Fallthrough */
3849        default:
3850            gen_base_offset_addr(ctx, t0, rs, imm);
3851            gen_flt_ldst(ctx, op, rt, t0);
3852        }
3853    } else {
3854        generate_exception_err(ctx, EXCP_CpU, 1);
3855    }
3856    tcg_temp_free(t0);
3857}
3858
3859/* Arithmetic with immediate operand */
3860static void gen_arith_imm(DisasContext *ctx, uint32_t opc,
3861                          int rt, int rs, int imm)
3862{
3863    target_ulong uimm = (target_long)imm; /* Sign extend to 32/64 bits */
3864
3865    if (rt == 0 && opc != OPC_ADDI && opc != OPC_DADDI) {
3866        /*
3867         * If no destination, treat it as a NOP.
3868         * For addi, we must generate the overflow exception when needed.
3869         */
3870        return;
3871    }
3872    switch (opc) {
3873    case OPC_ADDI:
3874        {
3875            TCGv t0 = tcg_temp_local_new();
3876            TCGv t1 = tcg_temp_new();
3877            TCGv t2 = tcg_temp_new();
3878            TCGLabel *l1 = gen_new_label();
3879
3880            gen_load_gpr(t1, rs);
3881            tcg_gen_addi_tl(t0, t1, uimm);
3882            tcg_gen_ext32s_tl(t0, t0);
3883
3884            tcg_gen_xori_tl(t1, t1, ~uimm);
3885            tcg_gen_xori_tl(t2, t0, uimm);
3886            tcg_gen_and_tl(t1, t1, t2);
3887            tcg_temp_free(t2);
3888            tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
3889            tcg_temp_free(t1);
3890            /* operands of same sign, result different sign */
3891            generate_exception(ctx, EXCP_OVERFLOW);
3892            gen_set_label(l1);
3893            tcg_gen_ext32s_tl(t0, t0);
3894            gen_store_gpr(t0, rt);
3895            tcg_temp_free(t0);
3896        }
3897        break;
3898    case OPC_ADDIU:
3899        if (rs != 0) {
3900            tcg_gen_addi_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
3901            tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
3902        } else {
3903            tcg_gen_movi_tl(cpu_gpr[rt], uimm);
3904        }
3905        break;
3906#if defined(TARGET_MIPS64)
3907    case OPC_DADDI:
3908        {
3909            TCGv t0 = tcg_temp_local_new();
3910            TCGv t1 = tcg_temp_new();
3911            TCGv t2 = tcg_temp_new();
3912            TCGLabel *l1 = gen_new_label();
3913
3914            gen_load_gpr(t1, rs);
3915            tcg_gen_addi_tl(t0, t1, uimm);
3916
3917            tcg_gen_xori_tl(t1, t1, ~uimm);
3918            tcg_gen_xori_tl(t2, t0, uimm);
3919            tcg_gen_and_tl(t1, t1, t2);
3920            tcg_temp_free(t2);
3921            tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
3922            tcg_temp_free(t1);
3923            /* operands of same sign, result different sign */
3924            generate_exception(ctx, EXCP_OVERFLOW);
3925            gen_set_label(l1);
3926            gen_store_gpr(t0, rt);
3927            tcg_temp_free(t0);
3928        }
3929        break;
3930    case OPC_DADDIU:
3931        if (rs != 0) {
3932            tcg_gen_addi_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
3933        } else {
3934            tcg_gen_movi_tl(cpu_gpr[rt], uimm);
3935        }
3936        break;
3937#endif
3938    }
3939}
3940
3941/* Logic with immediate operand */
3942static void gen_logic_imm(DisasContext *ctx, uint32_t opc,
3943                          int rt, int rs, int16_t imm)
3944{
3945    target_ulong uimm;
3946
3947    if (rt == 0) {
3948        /* If no destination, treat it as a NOP. */
3949        return;
3950    }
3951    uimm = (uint16_t)imm;
3952    switch (opc) {
3953    case OPC_ANDI:
3954        if (likely(rs != 0)) {
3955            tcg_gen_andi_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
3956        } else {
3957            tcg_gen_movi_tl(cpu_gpr[rt], 0);
3958        }
3959        break;
3960    case OPC_ORI:
3961        if (rs != 0) {
3962            tcg_gen_ori_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
3963        } else {
3964            tcg_gen_movi_tl(cpu_gpr[rt], uimm);
3965        }
3966        break;
3967    case OPC_XORI:
3968        if (likely(rs != 0)) {
3969            tcg_gen_xori_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
3970        } else {
3971            tcg_gen_movi_tl(cpu_gpr[rt], uimm);
3972        }
3973        break;
3974    case OPC_LUI:
3975        if (rs != 0 && (ctx->insn_flags & ISA_MIPS32R6)) {
3976            /* OPC_AUI */
3977            tcg_gen_addi_tl(cpu_gpr[rt], cpu_gpr[rs], imm << 16);
3978            tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
3979        } else {
3980            tcg_gen_movi_tl(cpu_gpr[rt], imm << 16);
3981        }
3982        break;
3983
3984    default:
3985        break;
3986    }
3987}
3988
3989/* Set on less than with immediate operand */
3990static void gen_slt_imm(DisasContext *ctx, uint32_t opc,
3991                        int rt, int rs, int16_t imm)
3992{
3993    target_ulong uimm = (target_long)imm; /* Sign extend to 32/64 bits */
3994    TCGv t0;
3995
3996    if (rt == 0) {
3997        /* If no destination, treat it as a NOP. */
3998        return;
3999    }
4000    t0 = tcg_temp_new();
4001    gen_load_gpr(t0, rs);
4002    switch (opc) {
4003    case OPC_SLTI:
4004        tcg_gen_setcondi_tl(TCG_COND_LT, cpu_gpr[rt], t0, uimm);
4005        break;
4006    case OPC_SLTIU:
4007        tcg_gen_setcondi_tl(TCG_COND_LTU, cpu_gpr[rt], t0, uimm);
4008        break;
4009    }
4010    tcg_temp_free(t0);
4011}
4012
4013/* Shifts with immediate operand */
4014static void gen_shift_imm(DisasContext *ctx, uint32_t opc,
4015                          int rt, int rs, int16_t imm)
4016{
4017    target_ulong uimm = ((uint16_t)imm) & 0x1f;
4018    TCGv t0;
4019
4020    if (rt == 0) {
4021        /* If no destination, treat it as a NOP. */
4022        return;
4023    }
4024
4025    t0 = tcg_temp_new();
4026    gen_load_gpr(t0, rs);
4027    switch (opc) {
4028    case OPC_SLL:
4029        tcg_gen_shli_tl(t0, t0, uimm);
4030        tcg_gen_ext32s_tl(cpu_gpr[rt], t0);
4031        break;
4032    case OPC_SRA:
4033        tcg_gen_sari_tl(cpu_gpr[rt], t0, uimm);
4034        break;
4035    case OPC_SRL:
4036        if (uimm != 0) {
4037            tcg_gen_ext32u_tl(t0, t0);
4038            tcg_gen_shri_tl(cpu_gpr[rt], t0, uimm);
4039        } else {
4040            tcg_gen_ext32s_tl(cpu_gpr[rt], t0);
4041        }
4042        break;
4043    case OPC_ROTR:
4044        if (uimm != 0) {
4045            TCGv_i32 t1 = tcg_temp_new_i32();
4046
4047            tcg_gen_trunc_tl_i32(t1, t0);
4048            tcg_gen_rotri_i32(t1, t1, uimm);
4049            tcg_gen_ext_i32_tl(cpu_gpr[rt], t1);
4050            tcg_temp_free_i32(t1);
4051        } else {
4052            tcg_gen_ext32s_tl(cpu_gpr[rt], t0);
4053        }
4054        break;
4055#if defined(TARGET_MIPS64)
4056    case OPC_DSLL:
4057        tcg_gen_shli_tl(cpu_gpr[rt], t0, uimm);
4058        break;
4059    case OPC_DSRA:
4060        tcg_gen_sari_tl(cpu_gpr[rt], t0, uimm);
4061        break;
4062    case OPC_DSRL:
4063        tcg_gen_shri_tl(cpu_gpr[rt], t0, uimm);
4064        break;
4065    case OPC_DROTR:
4066        if (uimm != 0) {
4067            tcg_gen_rotri_tl(cpu_gpr[rt], t0, uimm);
4068        } else {
4069            tcg_gen_mov_tl(cpu_gpr[rt], t0);
4070        }
4071        break;
4072    case OPC_DSLL32:
4073        tcg_gen_shli_tl(cpu_gpr[rt], t0, uimm + 32);
4074        break;
4075    case OPC_DSRA32:
4076        tcg_gen_sari_tl(cpu_gpr[rt], t0, uimm + 32);
4077        break;
4078    case OPC_DSRL32:
4079        tcg_gen_shri_tl(cpu_gpr[rt], t0, uimm + 32);
4080        break;
4081    case OPC_DROTR32:
4082        tcg_gen_rotri_tl(cpu_gpr[rt], t0, uimm + 32);
4083        break;
4084#endif
4085    }
4086    tcg_temp_free(t0);
4087}
4088
4089/* Arithmetic */
4090static void gen_arith(DisasContext *ctx, uint32_t opc,
4091                      int rd, int rs, int rt)
4092{
4093    if (rd == 0 && opc != OPC_ADD && opc != OPC_SUB
4094       && opc != OPC_DADD && opc != OPC_DSUB) {
4095        /*
4096         * If no destination, treat it as a NOP.
4097         * For add & sub, we must generate the overflow exception when needed.
4098         */
4099        return;
4100    }
4101
4102    switch (opc) {
4103    case OPC_ADD:
4104        {
4105            TCGv t0 = tcg_temp_local_new();
4106            TCGv t1 = tcg_temp_new();
4107            TCGv t2 = tcg_temp_new();
4108            TCGLabel *l1 = gen_new_label();
4109
4110            gen_load_gpr(t1, rs);
4111            gen_load_gpr(t2, rt);
4112            tcg_gen_add_tl(t0, t1, t2);
4113            tcg_gen_ext32s_tl(t0, t0);
4114            tcg_gen_xor_tl(t1, t1, t2);
4115            tcg_gen_xor_tl(t2, t0, t2);
4116            tcg_gen_andc_tl(t1, t2, t1);
4117            tcg_temp_free(t2);
4118            tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
4119            tcg_temp_free(t1);
4120            /* operands of same sign, result different sign */
4121            generate_exception(ctx, EXCP_OVERFLOW);
4122            gen_set_label(l1);
4123            gen_store_gpr(t0, rd);
4124            tcg_temp_free(t0);
4125        }
4126        break;
4127    case OPC_ADDU:
4128        if (rs != 0 && rt != 0) {
4129            tcg_gen_add_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
4130            tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
4131        } else if (rs == 0 && rt != 0) {
4132            tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
4133        } else if (rs != 0 && rt == 0) {
4134            tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
4135        } else {
4136            tcg_gen_movi_tl(cpu_gpr[rd], 0);
4137        }
4138        break;
4139    case OPC_SUB:
4140        {
4141            TCGv t0 = tcg_temp_local_new();
4142            TCGv t1 = tcg_temp_new();
4143            TCGv t2 = tcg_temp_new();
4144            TCGLabel *l1 = gen_new_label();
4145
4146            gen_load_gpr(t1, rs);
4147            gen_load_gpr(t2, rt);
4148            tcg_gen_sub_tl(t0, t1, t2);
4149            tcg_gen_ext32s_tl(t0, t0);
4150            tcg_gen_xor_tl(t2, t1, t2);
4151            tcg_gen_xor_tl(t1, t0, t1);
4152            tcg_gen_and_tl(t1, t1, t2);
4153            tcg_temp_free(t2);
4154            tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
4155            tcg_temp_free(t1);
4156            /*
4157             * operands of different sign, first operand and the result
4158             * of different sign
4159             */
4160            generate_exception(ctx, EXCP_OVERFLOW);
4161            gen_set_label(l1);
4162            gen_store_gpr(t0, rd);
4163            tcg_temp_free(t0);
4164        }
4165        break;
4166    case OPC_SUBU:
4167        if (rs != 0 && rt != 0) {
4168            tcg_gen_sub_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
4169            tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
4170        } else if (rs == 0 && rt != 0) {
4171            tcg_gen_neg_tl(cpu_gpr[rd], cpu_gpr[rt]);
4172            tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
4173        } else if (rs != 0 && rt == 0) {
4174            tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
4175        } else {
4176            tcg_gen_movi_tl(cpu_gpr[rd], 0);
4177        }
4178        break;
4179#if defined(TARGET_MIPS64)
4180    case OPC_DADD:
4181        {
4182            TCGv t0 = tcg_temp_local_new();
4183            TCGv t1 = tcg_temp_new();
4184            TCGv t2 = tcg_temp_new();
4185            TCGLabel *l1 = gen_new_label();
4186
4187            gen_load_gpr(t1, rs);
4188            gen_load_gpr(t2, rt);
4189            tcg_gen_add_tl(t0, t1, t2);
4190            tcg_gen_xor_tl(t1, t1, t2);
4191            tcg_gen_xor_tl(t2, t0, t2);
4192            tcg_gen_andc_tl(t1, t2, t1);
4193            tcg_temp_free(t2);
4194            tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
4195            tcg_temp_free(t1);
4196            /* operands of same sign, result different sign */
4197            generate_exception(ctx, EXCP_OVERFLOW);
4198            gen_set_label(l1);
4199            gen_store_gpr(t0, rd);
4200            tcg_temp_free(t0);
4201        }
4202        break;
4203    case OPC_DADDU:
4204        if (rs != 0 && rt != 0) {
4205            tcg_gen_add_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
4206        } else if (rs == 0 && rt != 0) {
4207            tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
4208        } else if (rs != 0 && rt == 0) {
4209            tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
4210        } else {
4211            tcg_gen_movi_tl(cpu_gpr[rd], 0);
4212        }
4213        break;
4214    case OPC_DSUB:
4215        {
4216            TCGv t0 = tcg_temp_local_new();
4217            TCGv t1 = tcg_temp_new();
4218            TCGv t2 = tcg_temp_new();
4219            TCGLabel *l1 = gen_new_label();
4220
4221            gen_load_gpr(t1, rs);
4222            gen_load_gpr(t2, rt);
4223            tcg_gen_sub_tl(t0, t1, t2);
4224            tcg_gen_xor_tl(t2, t1, t2);
4225            tcg_gen_xor_tl(t1, t0, t1);
4226            tcg_gen_and_tl(t1, t1, t2);
4227            tcg_temp_free(t2);
4228            tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
4229            tcg_temp_free(t1);
4230            /* operands of different sign, first operand and result different sign */
4231            generate_exception(ctx, EXCP_OVERFLOW);
4232            gen_set_label(l1);
4233            gen_store_gpr(t0, rd);
4234            tcg_temp_free(t0);
4235        }
4236        break;
4237    case OPC_DSUBU:
4238        if (rs != 0 && rt != 0) {
4239            tcg_gen_sub_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
4240        } else if (rs == 0 && rt != 0) {
4241            tcg_gen_neg_tl(cpu_gpr[rd], cpu_gpr[rt]);
4242        } else if (rs != 0 && rt == 0) {
4243            tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
4244        } else {
4245            tcg_gen_movi_tl(cpu_gpr[rd], 0);
4246        }
4247        break;
4248#endif
4249    case OPC_MUL:
4250        if (likely(rs != 0 && rt != 0)) {
4251            tcg_gen_mul_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
4252            tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
4253        } else {
4254            tcg_gen_movi_tl(cpu_gpr[rd], 0);
4255        }
4256        break;
4257    }
4258}
4259
4260/* Conditional move */
4261static void gen_cond_move(DisasContext *ctx, uint32_t opc,
4262                          int rd, int rs, int rt)
4263{
4264    TCGv t0, t1, t2;
4265
4266    if (rd == 0) {
4267        /* If no destination, treat it as a NOP. */
4268        return;
4269    }
4270
4271    t0 = tcg_temp_new();
4272    gen_load_gpr(t0, rt);
4273    t1 = tcg_const_tl(0);
4274    t2 = tcg_temp_new();
4275    gen_load_gpr(t2, rs);
4276    switch (opc) {
4277    case OPC_MOVN:
4278        tcg_gen_movcond_tl(TCG_COND_NE, cpu_gpr[rd], t0, t1, t2, cpu_gpr[rd]);
4279        break;
4280    case OPC_MOVZ:
4281        tcg_gen_movcond_tl(TCG_COND_EQ, cpu_gpr[rd], t0, t1, t2, cpu_gpr[rd]);
4282        break;
4283    case OPC_SELNEZ:
4284        tcg_gen_movcond_tl(TCG_COND_NE, cpu_gpr[rd], t0, t1, t2, t1);
4285        break;
4286    case OPC_SELEQZ:
4287        tcg_gen_movcond_tl(TCG_COND_EQ, cpu_gpr[rd], t0, t1, t2, t1);
4288        break;
4289    }
4290    tcg_temp_free(t2);
4291    tcg_temp_free(t1);
4292    tcg_temp_free(t0);
4293}
4294
4295/* Logic */
4296static void gen_logic(DisasContext *ctx, uint32_t opc,
4297                      int rd, int rs, int rt)
4298{
4299    if (rd == 0) {
4300        /* If no destination, treat it as a NOP. */
4301        return;
4302    }
4303
4304    switch (opc) {
4305    case OPC_AND:
4306        if (likely(rs != 0 && rt != 0)) {
4307            tcg_gen_and_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
4308        } else {
4309            tcg_gen_movi_tl(cpu_gpr[rd], 0);
4310        }
4311        break;
4312    case OPC_NOR:
4313        if (rs != 0 && rt != 0) {
4314            tcg_gen_nor_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
4315        } else if (rs == 0 && rt != 0) {
4316            tcg_gen_not_tl(cpu_gpr[rd], cpu_gpr[rt]);
4317        } else if (rs != 0 && rt == 0) {
4318            tcg_gen_not_tl(cpu_gpr[rd], cpu_gpr[rs]);
4319        } else {
4320            tcg_gen_movi_tl(cpu_gpr[rd], ~((target_ulong)0));
4321        }
4322        break;
4323    case OPC_OR:
4324        if (likely(rs != 0 && rt != 0)) {
4325            tcg_gen_or_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
4326        } else if (rs == 0 && rt != 0) {
4327            tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
4328        } else if (rs != 0 && rt == 0) {
4329            tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
4330        } else {
4331            tcg_gen_movi_tl(cpu_gpr[rd], 0);
4332        }
4333        break;
4334    case OPC_XOR:
4335        if (likely(rs != 0 && rt != 0)) {
4336            tcg_gen_xor_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
4337        } else if (rs == 0 && rt != 0) {
4338            tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
4339        } else if (rs != 0 && rt == 0) {
4340            tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
4341        } else {
4342            tcg_gen_movi_tl(cpu_gpr[rd], 0);
4343        }
4344        break;
4345    }
4346}
4347
4348/* Set on lower than */
4349static void gen_slt(DisasContext *ctx, uint32_t opc,
4350                    int rd, int rs, int rt)
4351{
4352    TCGv t0, t1;
4353
4354    if (rd == 0) {
4355        /* If no destination, treat it as a NOP. */
4356        return;
4357    }
4358
4359    t0 = tcg_temp_new();
4360    t1 = tcg_temp_new();
4361    gen_load_gpr(t0, rs);
4362    gen_load_gpr(t1, rt);
4363    switch (opc) {
4364    case OPC_SLT:
4365        tcg_gen_setcond_tl(TCG_COND_LT, cpu_gpr[rd], t0, t1);
4366        break;
4367    case OPC_SLTU:
4368        tcg_gen_setcond_tl(TCG_COND_LTU, cpu_gpr[rd], t0, t1);
4369        break;
4370    }
4371    tcg_temp_free(t0);
4372    tcg_temp_free(t1);
4373}
4374
4375/* Shifts */
4376static void gen_shift(DisasContext *ctx, uint32_t opc,
4377                      int rd, int rs, int rt)
4378{
4379    TCGv t0, t1;
4380
4381    if (rd == 0) {
4382        /*
4383         * If no destination, treat it as a NOP.
4384         * For add & sub, we must generate the overflow exception when needed.
4385         */
4386        return;
4387    }
4388
4389    t0 = tcg_temp_new();
4390    t1 = tcg_temp_new();
4391    gen_load_gpr(t0, rs);
4392    gen_load_gpr(t1, rt);
4393    switch (opc) {
4394    case OPC_SLLV:
4395        tcg_gen_andi_tl(t0, t0, 0x1f);
4396        tcg_gen_shl_tl(t0, t1, t0);
4397        tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
4398        break;
4399    case OPC_SRAV:
4400        tcg_gen_andi_tl(t0, t0, 0x1f);
4401        tcg_gen_sar_tl(cpu_gpr[rd], t1, t0);
4402        break;
4403    case OPC_SRLV:
4404        tcg_gen_ext32u_tl(t1, t1);
4405        tcg_gen_andi_tl(t0, t0, 0x1f);
4406        tcg_gen_shr_tl(t0, t1, t0);
4407        tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
4408        break;
4409    case OPC_ROTRV:
4410        {
4411            TCGv_i32 t2 = tcg_temp_new_i32();
4412            TCGv_i32 t3 = tcg_temp_new_i32();
4413
4414            tcg_gen_trunc_tl_i32(t2, t0);
4415            tcg_gen_trunc_tl_i32(t3, t1);
4416            tcg_gen_andi_i32(t2, t2, 0x1f);
4417            tcg_gen_rotr_i32(t2, t3, t2);
4418            tcg_gen_ext_i32_tl(cpu_gpr[rd], t2);
4419            tcg_temp_free_i32(t2);
4420            tcg_temp_free_i32(t3);
4421        }
4422        break;
4423#if defined(TARGET_MIPS64)
4424    case OPC_DSLLV:
4425        tcg_gen_andi_tl(t0, t0, 0x3f);
4426        tcg_gen_shl_tl(cpu_gpr[rd], t1, t0);
4427        break;
4428    case OPC_DSRAV:
4429        tcg_gen_andi_tl(t0, t0, 0x3f);
4430        tcg_gen_sar_tl(cpu_gpr[rd], t1, t0);
4431        break;
4432    case OPC_DSRLV:
4433        tcg_gen_andi_tl(t0, t0, 0x3f);
4434        tcg_gen_shr_tl(cpu_gpr[rd], t1, t0);
4435        break;
4436    case OPC_DROTRV:
4437        tcg_gen_andi_tl(t0, t0, 0x3f);
4438        tcg_gen_rotr_tl(cpu_gpr[rd], t1, t0);
4439        break;
4440#endif
4441    }
4442    tcg_temp_free(t0);
4443    tcg_temp_free(t1);
4444}
4445
4446#if defined(TARGET_MIPS64)
4447/* Copy GPR to and from TX79 HI1/LO1 register. */
4448static void gen_HILO1_tx79(DisasContext *ctx, uint32_t opc, int reg)
4449{
4450    if (reg == 0 && (opc == MMI_OPC_MFHI1 || opc == MMI_OPC_MFLO1)) {
4451        /* Treat as NOP. */
4452        return;
4453    }
4454
4455    switch (opc) {
4456    case MMI_OPC_MFHI1:
4457        tcg_gen_mov_tl(cpu_gpr[reg], cpu_HI[1]);
4458        break;
4459    case MMI_OPC_MFLO1:
4460        tcg_gen_mov_tl(cpu_gpr[reg], cpu_LO[1]);
4461        break;
4462    case MMI_OPC_MTHI1:
4463        if (reg != 0) {
4464            tcg_gen_mov_tl(cpu_HI[1], cpu_gpr[reg]);
4465        } else {
4466            tcg_gen_movi_tl(cpu_HI[1], 0);
4467        }
4468        break;
4469    case MMI_OPC_MTLO1:
4470        if (reg != 0) {
4471            tcg_gen_mov_tl(cpu_LO[1], cpu_gpr[reg]);
4472        } else {
4473            tcg_gen_movi_tl(cpu_LO[1], 0);
4474        }
4475        break;
4476    default:
4477        MIPS_INVAL("mfthilo1 TX79");
4478        generate_exception_end(ctx, EXCP_RI);
4479        break;
4480    }
4481}
4482#endif
4483
4484/* Arithmetic on HI/LO registers */
4485static void gen_HILO(DisasContext *ctx, uint32_t opc, int acc, int reg)
4486{
4487    if (reg == 0 && (opc == OPC_MFHI || opc == OPC_MFLO)) {
4488        /* Treat as NOP. */
4489        return;
4490    }
4491
4492    if (acc != 0) {
4493        check_dsp(ctx);
4494    }
4495
4496    switch (opc) {
4497    case OPC_MFHI:
4498#if defined(TARGET_MIPS64)
4499        if (acc != 0) {
4500            tcg_gen_ext32s_tl(cpu_gpr[reg], cpu_HI[acc]);
4501        } else
4502#endif
4503        {
4504            tcg_gen_mov_tl(cpu_gpr[reg], cpu_HI[acc]);
4505        }
4506        break;
4507    case OPC_MFLO:
4508#if defined(TARGET_MIPS64)
4509        if (acc != 0) {
4510            tcg_gen_ext32s_tl(cpu_gpr[reg], cpu_LO[acc]);
4511        } else
4512#endif
4513        {
4514            tcg_gen_mov_tl(cpu_gpr[reg], cpu_LO[acc]);
4515        }
4516        break;
4517    case OPC_MTHI:
4518        if (reg != 0) {
4519#if defined(TARGET_MIPS64)
4520            if (acc != 0) {
4521                tcg_gen_ext32s_tl(cpu_HI[acc], cpu_gpr[reg]);
4522            } else
4523#endif
4524            {
4525                tcg_gen_mov_tl(cpu_HI[acc], cpu_gpr[reg]);
4526            }
4527        } else {
4528            tcg_gen_movi_tl(cpu_HI[acc], 0);
4529        }
4530        break;
4531    case OPC_MTLO:
4532        if (reg != 0) {
4533#if defined(TARGET_MIPS64)
4534            if (acc != 0) {
4535                tcg_gen_ext32s_tl(cpu_LO[acc], cpu_gpr[reg]);
4536            } else
4537#endif
4538            {
4539                tcg_gen_mov_tl(cpu_LO[acc], cpu_gpr[reg]);
4540            }
4541        } else {
4542            tcg_gen_movi_tl(cpu_LO[acc], 0);
4543        }
4544        break;
4545    }
4546}
4547
4548static inline void gen_r6_ld(target_long addr, int reg, int memidx,
4549                             TCGMemOp memop)
4550{
4551    TCGv t0 = tcg_const_tl(addr);
4552    tcg_gen_qemu_ld_tl(t0, t0, memidx, memop);
4553    gen_store_gpr(t0, reg);
4554    tcg_temp_free(t0);
4555}
4556
4557static inline void gen_pcrel(DisasContext *ctx, int opc, target_ulong pc,
4558                             int rs)
4559{
4560    target_long offset;
4561    target_long addr;
4562
4563    switch (MASK_OPC_PCREL_TOP2BITS(opc)) {
4564    case OPC_ADDIUPC:
4565        if (rs != 0) {
4566            offset = sextract32(ctx->opcode << 2, 0, 21);
4567            addr = addr_add(ctx, pc, offset);
4568            tcg_gen_movi_tl(cpu_gpr[rs], addr);
4569        }
4570        break;
4571    case R6_OPC_LWPC:
4572        offset = sextract32(ctx->opcode << 2, 0, 21);
4573        addr = addr_add(ctx, pc, offset);
4574        gen_r6_ld(addr, rs, ctx->mem_idx, MO_TESL);
4575        break;
4576#if defined(TARGET_MIPS64)
4577    case OPC_LWUPC:
4578        check_mips_64(ctx);
4579        offset = sextract32(ctx->opcode << 2, 0, 21);
4580        addr = addr_add(ctx, pc, offset);
4581        gen_r6_ld(addr, rs, ctx->mem_idx, MO_TEUL);
4582        break;
4583#endif
4584    default:
4585        switch (MASK_OPC_PCREL_TOP5BITS(opc)) {
4586        case OPC_AUIPC:
4587            if (rs != 0) {
4588                offset = sextract32(ctx->opcode, 0, 16) << 16;
4589                addr = addr_add(ctx, pc, offset);
4590                tcg_gen_movi_tl(cpu_gpr[rs], addr);
4591            }
4592            break;
4593        case OPC_ALUIPC:
4594            if (rs != 0) {
4595                offset = sextract32(ctx->opcode, 0, 16) << 16;
4596                addr = ~0xFFFF & addr_add(ctx, pc, offset);
4597                tcg_gen_movi_tl(cpu_gpr[rs], addr);
4598            }
4599            break;
4600#if defined(TARGET_MIPS64)
4601        case R6_OPC_LDPC: /* bits 16 and 17 are part of immediate */
4602        case R6_OPC_LDPC + (1 << 16):
4603        case R6_OPC_LDPC + (2 << 16):
4604        case R6_OPC_LDPC + (3 << 16):
4605            check_mips_64(ctx);
4606            offset = sextract32(ctx->opcode << 3, 0, 21);
4607            addr = addr_add(ctx, (pc & ~0x7), offset);
4608            gen_r6_ld(addr, rs, ctx->mem_idx, MO_TEQ);
4609            break;
4610#endif
4611        default:
4612            MIPS_INVAL("OPC_PCREL");
4613            generate_exception_end(ctx, EXCP_RI);
4614            break;
4615        }
4616        break;
4617    }
4618}
4619
4620static void gen_r6_muldiv(DisasContext *ctx, int opc, int rd, int rs, int rt)
4621{
4622    TCGv t0, t1;
4623
4624    if (rd == 0) {
4625        /* Treat as NOP. */
4626        return;
4627    }
4628
4629    t0 = tcg_temp_new();
4630    t1 = tcg_temp_new();
4631
4632    gen_load_gpr(t0, rs);
4633    gen_load_gpr(t1, rt);
4634
4635    switch (opc) {
4636    case R6_OPC_DIV:
4637        {
4638            TCGv t2 = tcg_temp_new();
4639            TCGv t3 = tcg_temp_new();
4640            tcg_gen_ext32s_tl(t0, t0);
4641            tcg_gen_ext32s_tl(t1, t1);
4642            tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, INT_MIN);
4643            tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1);
4644            tcg_gen_and_tl(t2, t2, t3);
4645            tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
4646            tcg_gen_or_tl(t2, t2, t3);
4647            tcg_gen_movi_tl(t3, 0);
4648            tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
4649            tcg_gen_div_tl(cpu_gpr[rd], t0, t1);
4650            tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
4651            tcg_temp_free(t3);
4652            tcg_temp_free(t2);
4653        }
4654        break;
4655    case R6_OPC_MOD:
4656        {
4657            TCGv t2 = tcg_temp_new();
4658            TCGv t3 = tcg_temp_new();
4659            tcg_gen_ext32s_tl(t0, t0);
4660            tcg_gen_ext32s_tl(t1, t1);
4661            tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, INT_MIN);
4662            tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1);
4663            tcg_gen_and_tl(t2, t2, t3);
4664            tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
4665            tcg_gen_or_tl(t2, t2, t3);
4666            tcg_gen_movi_tl(t3, 0);
4667            tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
4668            tcg_gen_rem_tl(cpu_gpr[rd], t0, t1);
4669            tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
4670            tcg_temp_free(t3);
4671            tcg_temp_free(t2);
4672        }
4673        break;
4674    case R6_OPC_DIVU:
4675        {
4676            TCGv t2 = tcg_const_tl(0);
4677            TCGv t3 = tcg_const_tl(1);
4678            tcg_gen_ext32u_tl(t0, t0);
4679            tcg_gen_ext32u_tl(t1, t1);
4680            tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
4681            tcg_gen_divu_tl(cpu_gpr[rd], t0, t1);
4682            tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
4683            tcg_temp_free(t3);
4684            tcg_temp_free(t2);
4685        }
4686        break;
4687    case R6_OPC_MODU:
4688        {
4689            TCGv t2 = tcg_const_tl(0);
4690            TCGv t3 = tcg_const_tl(1);
4691            tcg_gen_ext32u_tl(t0, t0);
4692            tcg_gen_ext32u_tl(t1, t1);
4693            tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
4694            tcg_gen_remu_tl(cpu_gpr[rd], t0, t1);
4695            tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
4696            tcg_temp_free(t3);
4697            tcg_temp_free(t2);
4698        }
4699        break;
4700    case R6_OPC_MUL:
4701        {
4702            TCGv_i32 t2 = tcg_temp_new_i32();
4703            TCGv_i32 t3 = tcg_temp_new_i32();
4704            tcg_gen_trunc_tl_i32(t2, t0);
4705            tcg_gen_trunc_tl_i32(t3, t1);
4706            tcg_gen_mul_i32(t2, t2, t3);
4707            tcg_gen_ext_i32_tl(cpu_gpr[rd], t2);
4708            tcg_temp_free_i32(t2);
4709            tcg_temp_free_i32(t3);
4710        }
4711        break;
4712    case R6_OPC_MUH:
4713        {
4714            TCGv_i32 t2 = tcg_temp_new_i32();
4715            TCGv_i32 t3 = tcg_temp_new_i32();
4716            tcg_gen_trunc_tl_i32(t2, t0);
4717            tcg_gen_trunc_tl_i32(t3, t1);
4718            tcg_gen_muls2_i32(t2, t3, t2, t3);
4719            tcg_gen_ext_i32_tl(cpu_gpr[rd], t3);
4720            tcg_temp_free_i32(t2);
4721            tcg_temp_free_i32(t3);
4722        }
4723        break;
4724    case R6_OPC_MULU:
4725        {
4726            TCGv_i32 t2 = tcg_temp_new_i32();
4727            TCGv_i32 t3 = tcg_temp_new_i32();
4728            tcg_gen_trunc_tl_i32(t2, t0);
4729            tcg_gen_trunc_tl_i32(t3, t1);
4730            tcg_gen_mul_i32(t2, t2, t3);
4731            tcg_gen_ext_i32_tl(cpu_gpr[rd], t2);
4732            tcg_temp_free_i32(t2);
4733            tcg_temp_free_i32(t3);
4734        }
4735        break;
4736    case R6_OPC_MUHU:
4737        {
4738            TCGv_i32 t2 = tcg_temp_new_i32();
4739            TCGv_i32 t3 = tcg_temp_new_i32();
4740            tcg_gen_trunc_tl_i32(t2, t0);
4741            tcg_gen_trunc_tl_i32(t3, t1);
4742            tcg_gen_mulu2_i32(t2, t3, t2, t3);
4743            tcg_gen_ext_i32_tl(cpu_gpr[rd], t3);
4744            tcg_temp_free_i32(t2);
4745            tcg_temp_free_i32(t3);
4746        }
4747        break;
4748#if defined(TARGET_MIPS64)
4749    case R6_OPC_DDIV:
4750        {
4751            TCGv t2 = tcg_temp_new();
4752            TCGv t3 = tcg_temp_new();
4753            tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, -1LL << 63);
4754            tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1LL);
4755            tcg_gen_and_tl(t2, t2, t3);
4756            tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
4757            tcg_gen_or_tl(t2, t2, t3);
4758            tcg_gen_movi_tl(t3, 0);
4759            tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
4760            tcg_gen_div_tl(cpu_gpr[rd], t0, t1);
4761            tcg_temp_free(t3);
4762            tcg_temp_free(t2);
4763        }
4764        break;
4765    case R6_OPC_DMOD:
4766        {
4767            TCGv t2 = tcg_temp_new();
4768            TCGv t3 = tcg_temp_new();
4769            tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, -1LL << 63);
4770            tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1LL);
4771            tcg_gen_and_tl(t2, t2, t3);
4772            tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
4773            tcg_gen_or_tl(t2, t2, t3);
4774            tcg_gen_movi_tl(t3, 0);
4775            tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
4776            tcg_gen_rem_tl(cpu_gpr[rd], t0, t1);
4777            tcg_temp_free(t3);
4778            tcg_temp_free(t2);
4779        }
4780        break;
4781    case R6_OPC_DDIVU:
4782        {
4783            TCGv t2 = tcg_const_tl(0);
4784            TCGv t3 = tcg_const_tl(1);
4785            tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
4786            tcg_gen_divu_i64(cpu_gpr[rd], t0, t1);
4787            tcg_temp_free(t3);
4788            tcg_temp_free(t2);
4789        }
4790        break;
4791    case R6_OPC_DMODU:
4792        {
4793            TCGv t2 = tcg_const_tl(0);
4794            TCGv t3 = tcg_const_tl(1);
4795            tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
4796            tcg_gen_remu_i64(cpu_gpr[rd], t0, t1);
4797            tcg_temp_free(t3);
4798            tcg_temp_free(t2);
4799        }
4800        break;
4801    case R6_OPC_DMUL:
4802        tcg_gen_mul_i64(cpu_gpr[rd], t0, t1);
4803        break;
4804    case R6_OPC_DMUH:
4805        {
4806            TCGv t2 = tcg_temp_new();
4807            tcg_gen_muls2_i64(t2, cpu_gpr[rd], t0, t1);
4808            tcg_temp_free(t2);
4809        }
4810        break;
4811    case R6_OPC_DMULU:
4812        tcg_gen_mul_i64(cpu_gpr[rd], t0, t1);
4813        break;
4814    case R6_OPC_DMUHU:
4815        {
4816            TCGv t2 = tcg_temp_new();
4817            tcg_gen_mulu2_i64(t2, cpu_gpr[rd], t0, t1);
4818            tcg_temp_free(t2);
4819        }
4820        break;
4821#endif
4822    default:
4823        MIPS_INVAL("r6 mul/div");
4824        generate_exception_end(ctx, EXCP_RI);
4825        goto out;
4826    }
4827 out:
4828    tcg_temp_free(t0);
4829    tcg_temp_free(t1);
4830}
4831
4832#if defined(TARGET_MIPS64)
4833static void gen_div1_tx79(DisasContext *ctx, uint32_t opc, int rs, int rt)
4834{
4835    TCGv t0, t1;
4836
4837    t0 = tcg_temp_new();
4838    t1 = tcg_temp_new();
4839
4840    gen_load_gpr(t0, rs);
4841    gen_load_gpr(t1, rt);
4842
4843    switch (opc) {
4844    case MMI_OPC_DIV1:
4845        {
4846            TCGv t2 = tcg_temp_new();
4847            TCGv t3 = tcg_temp_new();
4848            tcg_gen_ext32s_tl(t0, t0);
4849            tcg_gen_ext32s_tl(t1, t1);
4850            tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, INT_MIN);
4851            tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1);
4852            tcg_gen_and_tl(t2, t2, t3);
4853            tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
4854            tcg_gen_or_tl(t2, t2, t3);
4855            tcg_gen_movi_tl(t3, 0);
4856            tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
4857            tcg_gen_div_tl(cpu_LO[1], t0, t1);
4858            tcg_gen_rem_tl(cpu_HI[1], t0, t1);
4859            tcg_gen_ext32s_tl(cpu_LO[1], cpu_LO[1]);
4860            tcg_gen_ext32s_tl(cpu_HI[1], cpu_HI[1]);
4861            tcg_temp_free(t3);
4862            tcg_temp_free(t2);
4863        }
4864        break;
4865    case MMI_OPC_DIVU1:
4866        {
4867            TCGv t2 = tcg_const_tl(0);
4868            TCGv t3 = tcg_const_tl(1);
4869            tcg_gen_ext32u_tl(t0, t0);
4870            tcg_gen_ext32u_tl(t1, t1);
4871            tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
4872            tcg_gen_divu_tl(cpu_LO[1], t0, t1);
4873            tcg_gen_remu_tl(cpu_HI[1], t0, t1);
4874            tcg_gen_ext32s_tl(cpu_LO[1], cpu_LO[1]);
4875            tcg_gen_ext32s_tl(cpu_HI[1], cpu_HI[1]);
4876            tcg_temp_free(t3);
4877            tcg_temp_free(t2);
4878        }
4879        break;
4880    default:
4881        MIPS_INVAL("div1 TX79");
4882        generate_exception_end(ctx, EXCP_RI);
4883        goto out;
4884    }
4885 out:
4886    tcg_temp_free(t0);
4887    tcg_temp_free(t1);
4888}
4889#endif
4890
4891static void gen_muldiv(DisasContext *ctx, uint32_t opc,
4892                       int acc, int rs, int rt)
4893{
4894    TCGv t0, t1;
4895
4896    t0 = tcg_temp_new();
4897    t1 = tcg_temp_new();
4898
4899    gen_load_gpr(t0, rs);
4900    gen_load_gpr(t1, rt);
4901
4902    if (acc != 0) {
4903        check_dsp(ctx);
4904    }
4905
4906    switch (opc) {
4907    case OPC_DIV:
4908        {
4909            TCGv t2 = tcg_temp_new();
4910            TCGv t3 = tcg_temp_new();
4911            tcg_gen_ext32s_tl(t0, t0);
4912            tcg_gen_ext32s_tl(t1, t1);
4913            tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, INT_MIN);
4914            tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1);
4915            tcg_gen_and_tl(t2, t2, t3);
4916            tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
4917            tcg_gen_or_tl(t2, t2, t3);
4918            tcg_gen_movi_tl(t3, 0);
4919            tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
4920            tcg_gen_div_tl(cpu_LO[acc], t0, t1);
4921            tcg_gen_rem_tl(cpu_HI[acc], t0, t1);
4922            tcg_gen_ext32s_tl(cpu_LO[acc], cpu_LO[acc]);
4923            tcg_gen_ext32s_tl(cpu_HI[acc], cpu_HI[acc]);
4924            tcg_temp_free(t3);
4925            tcg_temp_free(t2);
4926        }
4927        break;
4928    case OPC_DIVU:
4929        {
4930            TCGv t2 = tcg_const_tl(0);
4931            TCGv t3 = tcg_const_tl(1);
4932            tcg_gen_ext32u_tl(t0, t0);
4933            tcg_gen_ext32u_tl(t1, t1);
4934            tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
4935            tcg_gen_divu_tl(cpu_LO[acc], t0, t1);
4936            tcg_gen_remu_tl(cpu_HI[acc], t0, t1);
4937            tcg_gen_ext32s_tl(cpu_LO[acc], cpu_LO[acc]);
4938            tcg_gen_ext32s_tl(cpu_HI[acc], cpu_HI[acc]);
4939            tcg_temp_free(t3);
4940            tcg_temp_free(t2);
4941        }
4942        break;
4943    case OPC_MULT:
4944        {
4945            TCGv_i32 t2 = tcg_temp_new_i32();
4946            TCGv_i32 t3 = tcg_temp_new_i32();
4947            tcg_gen_trunc_tl_i32(t2, t0);
4948            tcg_gen_trunc_tl_i32(t3, t1);
4949            tcg_gen_muls2_i32(t2, t3, t2, t3);
4950            tcg_gen_ext_i32_tl(cpu_LO[acc], t2);
4951            tcg_gen_ext_i32_tl(cpu_HI[acc], t3);
4952            tcg_temp_free_i32(t2);
4953            tcg_temp_free_i32(t3);
4954        }
4955        break;
4956    case OPC_MULTU:
4957        {
4958            TCGv_i32 t2 = tcg_temp_new_i32();
4959            TCGv_i32 t3 = tcg_temp_new_i32();
4960            tcg_gen_trunc_tl_i32(t2, t0);
4961            tcg_gen_trunc_tl_i32(t3, t1);
4962            tcg_gen_mulu2_i32(t2, t3, t2, t3);
4963            tcg_gen_ext_i32_tl(cpu_LO[acc], t2);
4964            tcg_gen_ext_i32_tl(cpu_HI[acc], t3);
4965            tcg_temp_free_i32(t2);
4966            tcg_temp_free_i32(t3);
4967        }
4968        break;
4969#if defined(TARGET_MIPS64)
4970    case OPC_DDIV:
4971        {
4972            TCGv t2 = tcg_temp_new();
4973            TCGv t3 = tcg_temp_new();
4974            tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, -1LL << 63);
4975            tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1LL);
4976            tcg_gen_and_tl(t2, t2, t3);
4977            tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
4978            tcg_gen_or_tl(t2, t2, t3);
4979            tcg_gen_movi_tl(t3, 0);
4980            tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
4981            tcg_gen_div_tl(cpu_LO[acc], t0, t1);
4982            tcg_gen_rem_tl(cpu_HI[acc], t0, t1);
4983            tcg_temp_free(t3);
4984            tcg_temp_free(t2);
4985        }
4986        break;
4987    case OPC_DDIVU:
4988        {
4989            TCGv t2 = tcg_const_tl(0);
4990            TCGv t3 = tcg_const_tl(1);
4991            tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
4992            tcg_gen_divu_i64(cpu_LO[acc], t0, t1);
4993            tcg_gen_remu_i64(cpu_HI[acc], t0, t1);
4994            tcg_temp_free(t3);
4995            tcg_temp_free(t2);
4996        }
4997        break;
4998    case OPC_DMULT:
4999        tcg_gen_muls2_i64(cpu_LO[acc], cpu_HI[acc], t0, t1);
5000        break;
5001    case OPC_DMULTU:
5002        tcg_gen_mulu2_i64(cpu_LO[acc], cpu_HI[acc], t0, t1);
5003        break;
5004#endif
5005    case OPC_MADD:
5006        {
5007            TCGv_i64 t2 = tcg_temp_new_i64();
5008            TCGv_i64 t3 = tcg_temp_new_i64();
5009
5010            tcg_gen_ext_tl_i64(t2, t0);
5011            tcg_gen_ext_tl_i64(t3, t1);
5012            tcg_gen_mul_i64(t2, t2, t3);
5013            tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
5014            tcg_gen_add_i64(t2, t2, t3);
5015            tcg_temp_free_i64(t3);
5016            gen_move_low32(cpu_LO[acc], t2);
5017            gen_move_high32(cpu_HI[acc], t2);
5018            tcg_temp_free_i64(t2);
5019        }
5020        break;
5021    case OPC_MADDU:
5022        {
5023            TCGv_i64 t2 = tcg_temp_new_i64();
5024            TCGv_i64 t3 = tcg_temp_new_i64();
5025
5026            tcg_gen_ext32u_tl(t0, t0);
5027            tcg_gen_ext32u_tl(t1, t1);
5028            tcg_gen_extu_tl_i64(t2, t0);
5029            tcg_gen_extu_tl_i64(t3, t1);
5030            tcg_gen_mul_i64(t2, t2, t3);
5031            tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
5032            tcg_gen_add_i64(t2, t2, t3);
5033            tcg_temp_free_i64(t3);
5034            gen_move_low32(cpu_LO[acc], t2);
5035            gen_move_high32(cpu_HI[acc], t2);
5036            tcg_temp_free_i64(t2);
5037        }
5038        break;
5039    case OPC_MSUB:
5040        {
5041            TCGv_i64 t2 = tcg_temp_new_i64();
5042            TCGv_i64 t3 = tcg_temp_new_i64();
5043
5044            tcg_gen_ext_tl_i64(t2, t0);
5045            tcg_gen_ext_tl_i64(t3, t1);
5046            tcg_gen_mul_i64(t2, t2, t3);
5047            tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
5048            tcg_gen_sub_i64(t2, t3, t2);
5049            tcg_temp_free_i64(t3);
5050            gen_move_low32(cpu_LO[acc], t2);
5051            gen_move_high32(cpu_HI[acc], t2);
5052            tcg_temp_free_i64(t2);
5053        }
5054        break;
5055    case OPC_MSUBU:
5056        {
5057            TCGv_i64 t2 = tcg_temp_new_i64();
5058            TCGv_i64 t3 = tcg_temp_new_i64();
5059
5060            tcg_gen_ext32u_tl(t0, t0);
5061            tcg_gen_ext32u_tl(t1, t1);
5062            tcg_gen_extu_tl_i64(t2, t0);
5063            tcg_gen_extu_tl_i64(t3, t1);
5064            tcg_gen_mul_i64(t2, t2, t3);
5065            tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
5066            tcg_gen_sub_i64(t2, t3, t2);
5067            tcg_temp_free_i64(t3);
5068            gen_move_low32(cpu_LO[acc], t2);
5069            gen_move_high32(cpu_HI[acc], t2);
5070            tcg_temp_free_i64(t2);
5071        }
5072        break;
5073    default:
5074        MIPS_INVAL("mul/div");
5075        generate_exception_end(ctx, EXCP_RI);
5076        goto out;
5077    }
5078 out:
5079    tcg_temp_free(t0);
5080    tcg_temp_free(t1);
5081}
5082
5083/*
5084 * These MULT[U] and MADD[U] instructions implemented in for example
5085 * the Toshiba/Sony R5900 and the Toshiba TX19, TX39 and TX79 core
5086 * architectures are special three-operand variants with the syntax
5087 *
5088 *     MULT[U][1] rd, rs, rt
5089 *
5090 * such that
5091 *
5092 *     (rd, LO, HI) <- rs * rt
5093 *
5094 * and
5095 *
5096 *     MADD[U][1] rd, rs, rt
5097 *
5098 * such that
5099 *
5100 *     (rd, LO, HI) <- (LO, HI) + rs * rt
5101 *
5102 * where the low-order 32-bits of the result is placed into both the
5103 * GPR rd and the special register LO. The high-order 32-bits of the
5104 * result is placed into the special register HI.
5105 *
5106 * If the GPR rd is omitted in assembly language, it is taken to be 0,
5107 * which is the zero register that always reads as 0.
5108 */
5109static void gen_mul_txx9(DisasContext *ctx, uint32_t opc,
5110                         int rd, int rs, int rt)
5111{
5112    TCGv t0 = tcg_temp_new();
5113    TCGv t1 = tcg_temp_new();
5114    int acc = 0;
5115
5116    gen_load_gpr(t0, rs);
5117    gen_load_gpr(t1, rt);
5118
5119    switch (opc) {
5120    case MMI_OPC_MULT1:
5121        acc = 1;
5122        /* Fall through */
5123    case OPC_MULT:
5124        {
5125            TCGv_i32 t2 = tcg_temp_new_i32();
5126            TCGv_i32 t3 = tcg_temp_new_i32();
5127            tcg_gen_trunc_tl_i32(t2, t0);
5128            tcg_gen_trunc_tl_i32(t3, t1);
5129            tcg_gen_muls2_i32(t2, t3, t2, t3);
5130            if (rd) {
5131                tcg_gen_ext_i32_tl(cpu_gpr[rd], t2);
5132            }
5133            tcg_gen_ext_i32_tl(cpu_LO[acc], t2);
5134            tcg_gen_ext_i32_tl(cpu_HI[acc], t3);
5135            tcg_temp_free_i32(t2);
5136            tcg_temp_free_i32(t3);
5137        }
5138        break;
5139    case MMI_OPC_MULTU1:
5140        acc = 1;
5141        /* Fall through */
5142    case OPC_MULTU:
5143        {
5144            TCGv_i32 t2 = tcg_temp_new_i32();
5145            TCGv_i32 t3 = tcg_temp_new_i32();
5146            tcg_gen_trunc_tl_i32(t2, t0);
5147            tcg_gen_trunc_tl_i32(t3, t1);
5148            tcg_gen_mulu2_i32(t2, t3, t2, t3);
5149            if (rd) {
5150                tcg_gen_ext_i32_tl(cpu_gpr[rd], t2);
5151            }
5152            tcg_gen_ext_i32_tl(cpu_LO[acc], t2);
5153            tcg_gen_ext_i32_tl(cpu_HI[acc], t3);
5154            tcg_temp_free_i32(t2);
5155            tcg_temp_free_i32(t3);
5156        }
5157        break;
5158    case MMI_OPC_MADD1:
5159        acc = 1;
5160        /* Fall through */
5161    case MMI_OPC_MADD:
5162        {
5163            TCGv_i64 t2 = tcg_temp_new_i64();
5164            TCGv_i64 t3 = tcg_temp_new_i64();
5165
5166            tcg_gen_ext_tl_i64(t2, t0);
5167            tcg_gen_ext_tl_i64(t3, t1);
5168            tcg_gen_mul_i64(t2, t2, t3);
5169            tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
5170            tcg_gen_add_i64(t2, t2, t3);
5171            tcg_temp_free_i64(t3);
5172            gen_move_low32(cpu_LO[acc], t2);
5173            gen_move_high32(cpu_HI[acc], t2);
5174            if (rd) {
5175                gen_move_low32(cpu_gpr[rd], t2);
5176            }
5177            tcg_temp_free_i64(t2);
5178        }
5179        break;
5180    case MMI_OPC_MADDU1:
5181        acc = 1;
5182        /* Fall through */
5183    case MMI_OPC_MADDU:
5184        {
5185            TCGv_i64 t2 = tcg_temp_new_i64();
5186            TCGv_i64 t3 = tcg_temp_new_i64();
5187
5188            tcg_gen_ext32u_tl(t0, t0);
5189            tcg_gen_ext32u_tl(t1, t1);
5190            tcg_gen_extu_tl_i64(t2, t0);
5191            tcg_gen_extu_tl_i64(t3, t1);
5192            tcg_gen_mul_i64(t2, t2, t3);
5193            tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
5194            tcg_gen_add_i64(t2, t2, t3);
5195            tcg_temp_free_i64(t3);
5196            gen_move_low32(cpu_LO[acc], t2);
5197            gen_move_high32(cpu_HI[acc], t2);
5198            if (rd) {
5199                gen_move_low32(cpu_gpr[rd], t2);
5200            }
5201            tcg_temp_free_i64(t2);
5202        }
5203        break;
5204    default:
5205        MIPS_INVAL("mul/madd TXx9");
5206        generate_exception_end(ctx, EXCP_RI);
5207        goto out;
5208    }
5209
5210 out:
5211    tcg_temp_free(t0);
5212    tcg_temp_free(t1);
5213}
5214
5215static void gen_mul_vr54xx(DisasContext *ctx, uint32_t opc,
5216                           int rd, int rs, int rt)
5217{
5218    TCGv t0 = tcg_temp_new();
5219    TCGv t1 = tcg_temp_new();
5220
5221    gen_load_gpr(t0, rs);
5222    gen_load_gpr(t1, rt);
5223
5224    switch (opc) {
5225    case OPC_VR54XX_MULS:
5226        gen_helper_muls(t0, cpu_env, t0, t1);
5227        break;
5228    case OPC_VR54XX_MULSU:
5229        gen_helper_mulsu(t0, cpu_env, t0, t1);
5230        break;
5231    case OPC_VR54XX_MACC:
5232        gen_helper_macc(t0, cpu_env, t0, t1);
5233        break;
5234    case OPC_VR54XX_MACCU:
5235        gen_helper_maccu(t0, cpu_env, t0, t1);
5236        break;
5237    case OPC_VR54XX_MSAC:
5238        gen_helper_msac(t0, cpu_env, t0, t1);
5239        break;
5240    case OPC_VR54XX_MSACU:
5241        gen_helper_msacu(t0, cpu_env, t0, t1);
5242        break;
5243    case OPC_VR54XX_MULHI:
5244        gen_helper_mulhi(t0, cpu_env, t0, t1);
5245        break;
5246    case OPC_VR54XX_MULHIU:
5247        gen_helper_mulhiu(t0, cpu_env, t0, t1);
5248        break;
5249    case OPC_VR54XX_MULSHI:
5250        gen_helper_mulshi(t0, cpu_env, t0, t1);
5251        break;
5252    case OPC_VR54XX_MULSHIU:
5253        gen_helper_mulshiu(t0, cpu_env, t0, t1);
5254        break;
5255    case OPC_VR54XX_MACCHI:
5256        gen_helper_macchi(t0, cpu_env, t0, t1);
5257        break;
5258    case OPC_VR54XX_MACCHIU:
5259        gen_helper_macchiu(t0, cpu_env, t0, t1);
5260        break;
5261    case OPC_VR54XX_MSACHI:
5262        gen_helper_msachi(t0, cpu_env, t0, t1);
5263        break;
5264    case OPC_VR54XX_MSACHIU:
5265        gen_helper_msachiu(t0, cpu_env, t0, t1);
5266        break;
5267    default:
5268        MIPS_INVAL("mul vr54xx");
5269        generate_exception_end(ctx, EXCP_RI);
5270        goto out;
5271    }
5272    gen_store_gpr(t0, rd);
5273
5274 out:
5275    tcg_temp_free(t0);
5276    tcg_temp_free(t1);
5277}
5278
5279static void gen_cl(DisasContext *ctx, uint32_t opc,
5280                   int rd, int rs)
5281{
5282    TCGv t0;
5283
5284    if (rd == 0) {
5285        /* Treat as NOP. */
5286        return;
5287    }
5288    t0 = cpu_gpr[rd];
5289    gen_load_gpr(t0, rs);
5290
5291    switch (opc) {
5292    case OPC_CLO:
5293    case R6_OPC_CLO:
5294#if defined(TARGET_MIPS64)
5295    case OPC_DCLO:
5296    case R6_OPC_DCLO:
5297#endif
5298        tcg_gen_not_tl(t0, t0);
5299        break;
5300    }
5301
5302    switch (opc) {
5303    case OPC_CLO:
5304    case R6_OPC_CLO:
5305    case OPC_CLZ:
5306    case R6_OPC_CLZ:
5307        tcg_gen_ext32u_tl(t0, t0);
5308        tcg_gen_clzi_tl(t0, t0, TARGET_LONG_BITS);
5309        tcg_gen_subi_tl(t0, t0, TARGET_LONG_BITS - 32);
5310        break;
5311#if defined(TARGET_MIPS64)
5312    case OPC_DCLO:
5313    case R6_OPC_DCLO:
5314    case OPC_DCLZ:
5315    case R6_OPC_DCLZ:
5316        tcg_gen_clzi_i64(t0, t0, 64);
5317        break;
5318#endif
5319    }
5320}
5321
5322/* Godson integer instructions */
5323static void gen_loongson_integer(DisasContext *ctx, uint32_t opc,
5324                                 int rd, int rs, int rt)
5325{
5326    TCGv t0, t1;
5327
5328    if (rd == 0) {
5329        /* Treat as NOP. */
5330        return;
5331    }
5332
5333    switch (opc) {
5334    case OPC_MULT_G_2E:
5335    case OPC_MULT_G_2F:
5336    case OPC_MULTU_G_2E:
5337    case OPC_MULTU_G_2F:
5338#if defined(TARGET_MIPS64)
5339    case OPC_DMULT_G_2E:
5340    case OPC_DMULT_G_2F:
5341    case OPC_DMULTU_G_2E:
5342    case OPC_DMULTU_G_2F:
5343#endif
5344        t0 = tcg_temp_new();
5345        t1 = tcg_temp_new();
5346        break;
5347    default:
5348        t0 = tcg_temp_local_new();
5349        t1 = tcg_temp_local_new();
5350        break;
5351    }
5352
5353    gen_load_gpr(t0, rs);
5354    gen_load_gpr(t1, rt);
5355
5356    switch (opc) {
5357    case OPC_MULT_G_2E:
5358    case OPC_MULT_G_2F:
5359        tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
5360        tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
5361        break;
5362    case OPC_MULTU_G_2E:
5363    case OPC_MULTU_G_2F:
5364        tcg_gen_ext32u_tl(t0, t0);
5365        tcg_gen_ext32u_tl(t1, t1);
5366        tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
5367        tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
5368        break;
5369    case OPC_DIV_G_2E:
5370    case OPC_DIV_G_2F:
5371        {
5372            TCGLabel *l1 = gen_new_label();
5373            TCGLabel *l2 = gen_new_label();
5374            TCGLabel *l3 = gen_new_label();
5375            tcg_gen_ext32s_tl(t0, t0);
5376            tcg_gen_ext32s_tl(t1, t1);
5377            tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
5378            tcg_gen_movi_tl(cpu_gpr[rd], 0);
5379            tcg_gen_br(l3);
5380            gen_set_label(l1);
5381            tcg_gen_brcondi_tl(TCG_COND_NE, t0, INT_MIN, l2);
5382            tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1, l2);
5383            tcg_gen_mov_tl(cpu_gpr[rd], t0);
5384            tcg_gen_br(l3);
5385            gen_set_label(l2);
5386            tcg_gen_div_tl(cpu_gpr[rd], t0, t1);
5387            tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
5388            gen_set_label(l3);
5389        }
5390        break;
5391    case OPC_DIVU_G_2E:
5392    case OPC_DIVU_G_2F:
5393        {
5394            TCGLabel *l1 = gen_new_label();
5395            TCGLabel *l2 = gen_new_label();
5396            tcg_gen_ext32u_tl(t0, t0);
5397            tcg_gen_ext32u_tl(t1, t1);
5398            tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
5399            tcg_gen_movi_tl(cpu_gpr[rd], 0);
5400            tcg_gen_br(l2);
5401            gen_set_label(l1);
5402            tcg_gen_divu_tl(cpu_gpr[rd], t0, t1);
5403            tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
5404            gen_set_label(l2);
5405        }
5406        break;
5407    case OPC_MOD_G_2E:
5408    case OPC_MOD_G_2F:
5409        {
5410            TCGLabel *l1 = gen_new_label();
5411            TCGLabel *l2 = gen_new_label();
5412            TCGLabel *l3 = gen_new_label();
5413            tcg_gen_ext32u_tl(t0, t0);
5414            tcg_gen_ext32u_tl(t1, t1);
5415            tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
5416            tcg_gen_brcondi_tl(TCG_COND_NE, t0, INT_MIN, l2);
5417            tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1, l2);
5418            gen_set_label(l1);
5419            tcg_gen_movi_tl(cpu_gpr[rd], 0);
5420            tcg_gen_br(l3);
5421            gen_set_label(l2);
5422            tcg_gen_rem_tl(cpu_gpr[rd], t0, t1);
5423            tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
5424            gen_set_label(l3);
5425        }
5426        break;
5427    case OPC_MODU_G_2E:
5428    case OPC_MODU_G_2F:
5429        {
5430            TCGLabel *l1 = gen_new_label();
5431            TCGLabel *l2 = gen_new_label();
5432            tcg_gen_ext32u_tl(t0, t0);
5433            tcg_gen_ext32u_tl(t1, t1);
5434            tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
5435            tcg_gen_movi_tl(cpu_gpr[rd], 0);
5436            tcg_gen_br(l2);
5437            gen_set_label(l1);
5438            tcg_gen_remu_tl(cpu_gpr[rd], t0, t1);
5439            tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
5440            gen_set_label(l2);
5441        }
5442        break;
5443#if defined(TARGET_MIPS64)
5444    case OPC_DMULT_G_2E:
5445    case OPC_DMULT_G_2F:
5446        tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
5447        break;
5448    case OPC_DMULTU_G_2E:
5449    case OPC_DMULTU_G_2F:
5450        tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
5451        break;
5452    case OPC_DDIV_G_2E:
5453    case OPC_DDIV_G_2F:
5454        {
5455            TCGLabel *l1 = gen_new_label();
5456            TCGLabel *l2 = gen_new_label();
5457            TCGLabel *l3 = gen_new_label();
5458            tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
5459            tcg_gen_movi_tl(cpu_gpr[rd], 0);
5460            tcg_gen_br(l3);
5461            gen_set_label(l1);
5462            tcg_gen_brcondi_tl(TCG_COND_NE, t0, -1LL << 63, l2);
5463            tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1LL, l2);
5464            tcg_gen_mov_tl(cpu_gpr[rd], t0);
5465            tcg_gen_br(l3);
5466            gen_set_label(l2);
5467            tcg_gen_div_tl(cpu_gpr[rd], t0, t1);
5468            gen_set_label(l3);
5469        }
5470        break;
5471    case OPC_DDIVU_G_2E:
5472    case OPC_DDIVU_G_2F:
5473        {
5474            TCGLabel *l1 = gen_new_label();
5475            TCGLabel *l2 = gen_new_label();
5476            tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
5477            tcg_gen_movi_tl(cpu_gpr[rd], 0);
5478            tcg_gen_br(l2);
5479            gen_set_label(l1);
5480            tcg_gen_divu_tl(cpu_gpr[rd], t0, t1);
5481            gen_set_label(l2);
5482        }
5483        break;
5484    case OPC_DMOD_G_2E:
5485    case OPC_DMOD_G_2F:
5486        {
5487            TCGLabel *l1 = gen_new_label();
5488            TCGLabel *l2 = gen_new_label();
5489            TCGLabel *l3 = gen_new_label();
5490            tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
5491            tcg_gen_brcondi_tl(TCG_COND_NE, t0, -1LL << 63, l2);
5492            tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1LL, l2);
5493            gen_set_label(l1);
5494            tcg_gen_movi_tl(cpu_gpr[rd], 0);
5495            tcg_gen_br(l3);
5496            gen_set_label(l2);
5497            tcg_gen_rem_tl(cpu_gpr[rd], t0, t1);
5498            gen_set_label(l3);
5499        }
5500        break;
5501    case OPC_DMODU_G_2E:
5502    case OPC_DMODU_G_2F:
5503        {
5504            TCGLabel *l1 = gen_new_label();
5505            TCGLabel *l2 = gen_new_label();
5506            tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
5507            tcg_gen_movi_tl(cpu_gpr[rd], 0);
5508            tcg_gen_br(l2);
5509            gen_set_label(l1);
5510            tcg_gen_remu_tl(cpu_gpr[rd], t0, t1);
5511            gen_set_label(l2);
5512        }
5513        break;
5514#endif
5515    }
5516
5517    tcg_temp_free(t0);
5518    tcg_temp_free(t1);
5519}
5520
5521/* Loongson multimedia instructions */
5522static void gen_loongson_multimedia(DisasContext *ctx, int rd, int rs, int rt)
5523{
5524    uint32_t opc, shift_max;
5525    TCGv_i64 t0, t1;
5526
5527    opc = MASK_LMI(ctx->opcode);
5528    switch (opc) {
5529    case OPC_ADD_CP2:
5530    case OPC_SUB_CP2:
5531    case OPC_DADD_CP2:
5532    case OPC_DSUB_CP2:
5533        t0 = tcg_temp_local_new_i64();
5534        t1 = tcg_temp_local_new_i64();
5535        break;
5536    default:
5537        t0 = tcg_temp_new_i64();
5538        t1 = tcg_temp_new_i64();
5539        break;
5540    }
5541
5542    check_cp1_enabled(ctx);
5543    gen_load_fpr64(ctx, t0, rs);
5544    gen_load_fpr64(ctx, t1, rt);
5545
5546#define LMI_HELPER(UP, LO) \
5547    case OPC_##UP: gen_helper_##LO(t0, t0, t1); break
5548#define LMI_HELPER_1(UP, LO) \
5549    case OPC_##UP: gen_helper_##LO(t0, t0); break
5550#define LMI_DIRECT(UP, LO, OP) \
5551    case OPC_##UP: tcg_gen_##OP##_i64(t0, t0, t1); break
5552
5553    switch (opc) {
5554    LMI_HELPER(PADDSH, paddsh);
5555    LMI_HELPER(PADDUSH, paddush);
5556    LMI_HELPER(PADDH, paddh);
5557    LMI_HELPER(PADDW, paddw);
5558    LMI_HELPER(PADDSB, paddsb);
5559    LMI_HELPER(PADDUSB, paddusb);
5560    LMI_HELPER(PADDB, paddb);
5561
5562    LMI_HELPER(PSUBSH, psubsh);
5563    LMI_HELPER(PSUBUSH, psubush);
5564    LMI_HELPER(PSUBH, psubh);
5565    LMI_HELPER(PSUBW, psubw);
5566    LMI_HELPER(PSUBSB, psubsb);
5567    LMI_HELPER(PSUBUSB, psubusb);
5568    LMI_HELPER(PSUBB, psubb);
5569
5570    LMI_HELPER(PSHUFH, pshufh);
5571    LMI_HELPER(PACKSSWH, packsswh);
5572    LMI_HELPER(PACKSSHB, packsshb);
5573    LMI_HELPER(PACKUSHB, packushb);
5574
5575    LMI_HELPER(PUNPCKLHW, punpcklhw);
5576    LMI_HELPER(PUNPCKHHW, punpckhhw);
5577    LMI_HELPER(PUNPCKLBH, punpcklbh);
5578    LMI_HELPER(PUNPCKHBH, punpckhbh);
5579    LMI_HELPER(PUNPCKLWD, punpcklwd);
5580    LMI_HELPER(PUNPCKHWD, punpckhwd);
5581
5582    LMI_HELPER(PAVGH, pavgh);
5583    LMI_HELPER(PAVGB, pavgb);
5584    LMI_HELPER(PMAXSH, pmaxsh);
5585    LMI_HELPER(PMINSH, pminsh);
5586    LMI_HELPER(PMAXUB, pmaxub);
5587    LMI_HELPER(PMINUB, pminub);
5588
5589    LMI_HELPER(PCMPEQW, pcmpeqw);
5590    LMI_HELPER(PCMPGTW, pcmpgtw);
5591    LMI_HELPER(PCMPEQH, pcmpeqh);
5592    LMI_HELPER(PCMPGTH, pcmpgth);
5593    LMI_HELPER(PCMPEQB, pcmpeqb);
5594    LMI_HELPER(PCMPGTB, pcmpgtb);
5595
5596    LMI_HELPER(PSLLW, psllw);
5597    LMI_HELPER(PSLLH, psllh);
5598    LMI_HELPER(PSRLW, psrlw);
5599    LMI_HELPER(PSRLH, psrlh);
5600    LMI_HELPER(PSRAW, psraw);
5601    LMI_HELPER(PSRAH, psrah);
5602
5603    LMI_HELPER(PMULLH, pmullh);
5604    LMI_HELPER(PMULHH, pmulhh);
5605    LMI_HELPER(PMULHUH, pmulhuh);
5606    LMI_HELPER(PMADDHW, pmaddhw);
5607
5608    LMI_HELPER(PASUBUB, pasubub);
5609    LMI_HELPER_1(BIADD, biadd);
5610    LMI_HELPER_1(PMOVMSKB, pmovmskb);
5611
5612    LMI_DIRECT(PADDD, paddd, add);
5613    LMI_DIRECT(PSUBD, psubd, sub);
5614    LMI_DIRECT(XOR_CP2, xor, xor);
5615    LMI_DIRECT(NOR_CP2, nor, nor);
5616    LMI_DIRECT(AND_CP2, and, and);
5617    LMI_DIRECT(OR_CP2, or, or);
5618
5619    case OPC_PANDN:
5620        tcg_gen_andc_i64(t0, t1, t0);
5621        break;
5622
5623    case OPC_PINSRH_0:
5624        tcg_gen_deposit_i64(t0, t0, t1, 0, 16);
5625        break;
5626    case OPC_PINSRH_1:
5627        tcg_gen_deposit_i64(t0, t0, t1, 16, 16);
5628        break;
5629    case OPC_PINSRH_2:
5630        tcg_gen_deposit_i64(t0, t0, t1, 32, 16);
5631        break;
5632    case OPC_PINSRH_3:
5633        tcg_gen_deposit_i64(t0, t0, t1, 48, 16);
5634        break;
5635
5636    case OPC_PEXTRH:
5637        tcg_gen_andi_i64(t1, t1, 3);
5638        tcg_gen_shli_i64(t1, t1, 4);
5639        tcg_gen_shr_i64(t0, t0, t1);
5640        tcg_gen_ext16u_i64(t0, t0);
5641        break;
5642
5643    case OPC_ADDU_CP2:
5644        tcg_gen_add_i64(t0, t0, t1);
5645        tcg_gen_ext32s_i64(t0, t0);
5646        break;
5647    case OPC_SUBU_CP2:
5648        tcg_gen_sub_i64(t0, t0, t1);
5649        tcg_gen_ext32s_i64(t0, t0);
5650        break;
5651
5652    case OPC_SLL_CP2:
5653        shift_max = 32;
5654        goto do_shift;
5655    case OPC_SRL_CP2:
5656        shift_max = 32;
5657        goto do_shift;
5658    case OPC_SRA_CP2:
5659        shift_max = 32;
5660        goto do_shift;
5661    case OPC_DSLL_CP2:
5662        shift_max = 64;
5663        goto do_shift;
5664    case OPC_DSRL_CP2:
5665        shift_max = 64;
5666        goto do_shift;
5667    case OPC_DSRA_CP2:
5668        shift_max = 64;
5669        goto do_shift;
5670    do_shift:
5671        /* Make sure shift count isn't TCG undefined behaviour.  */
5672        tcg_gen_andi_i64(t1, t1, shift_max - 1);
5673
5674        switch (opc) {
5675        case OPC_SLL_CP2:
5676        case OPC_DSLL_CP2:
5677            tcg_gen_shl_i64(t0, t0, t1);
5678            break;
5679        case OPC_SRA_CP2:
5680        case OPC_DSRA_CP2:
5681            /*
5682             * Since SRA is UndefinedResult without sign-extended inputs,
5683             * we can treat SRA and DSRA the same.
5684             */
5685            tcg_gen_sar_i64(t0, t0, t1);
5686            break;
5687        case OPC_SRL_CP2:
5688            /* We want to shift in zeros for SRL; zero-extend first.  */
5689            tcg_gen_ext32u_i64(t0, t0);
5690            /* FALLTHRU */
5691        case OPC_DSRL_CP2:
5692            tcg_gen_shr_i64(t0, t0, t1);
5693            break;
5694        }
5695
5696        if (shift_max == 32) {
5697            tcg_gen_ext32s_i64(t0, t0);
5698        }
5699
5700        /* Shifts larger than MAX produce zero.  */
5701        tcg_gen_setcondi_i64(TCG_COND_LTU, t1, t1, shift_max);
5702        tcg_gen_neg_i64(t1, t1);
5703        tcg_gen_and_i64(t0, t0, t1);
5704        break;
5705
5706    case OPC_ADD_CP2:
5707    case OPC_DADD_CP2:
5708        {
5709            TCGv_i64 t2 = tcg_temp_new_i64();
5710            TCGLabel *lab = gen_new_label();
5711
5712            tcg_gen_mov_i64(t2, t0);
5713            tcg_gen_add_i64(t0, t1, t2);
5714            if (opc == OPC_ADD_CP2) {
5715                tcg_gen_ext32s_i64(t0, t0);
5716            }
5717            tcg_gen_xor_i64(t1, t1, t2);
5718            tcg_gen_xor_i64(t2, t2, t0);
5719            tcg_gen_andc_i64(t1, t2, t1);
5720            tcg_temp_free_i64(t2);
5721            tcg_gen_brcondi_i64(TCG_COND_GE, t1, 0, lab);
5722            generate_exception(ctx, EXCP_OVERFLOW);
5723            gen_set_label(lab);
5724            break;
5725        }
5726
5727    case OPC_SUB_CP2:
5728    case OPC_DSUB_CP2:
5729        {
5730            TCGv_i64 t2 = tcg_temp_new_i64();
5731            TCGLabel *lab = gen_new_label();
5732
5733            tcg_gen_mov_i64(t2, t0);
5734            tcg_gen_sub_i64(t0, t1, t2);
5735            if (opc == OPC_SUB_CP2) {
5736                tcg_gen_ext32s_i64(t0, t0);
5737            }
5738            tcg_gen_xor_i64(t1, t1, t2);
5739            tcg_gen_xor_i64(t2, t2, t0);
5740            tcg_gen_and_i64(t1, t1, t2);
5741            tcg_temp_free_i64(t2);
5742            tcg_gen_brcondi_i64(TCG_COND_GE, t1, 0, lab);
5743            generate_exception(ctx, EXCP_OVERFLOW);
5744            gen_set_label(lab);
5745            break;
5746        }
5747
5748    case OPC_PMULUW:
5749        tcg_gen_ext32u_i64(t0, t0);
5750        tcg_gen_ext32u_i64(t1, t1);
5751        tcg_gen_mul_i64(t0, t0, t1);
5752        break;
5753
5754    case OPC_SEQU_CP2:
5755    case OPC_SEQ_CP2:
5756    case OPC_SLTU_CP2:
5757    case OPC_SLT_CP2:
5758    case OPC_SLEU_CP2:
5759    case OPC_SLE_CP2:
5760        /*
5761         * ??? Document is unclear: Set FCC[CC].  Does that mean the
5762         * FD field is the CC field?
5763         */
5764    default:
5765        MIPS_INVAL("loongson_cp2");
5766        generate_exception_end(ctx, EXCP_RI);
5767        return;
5768    }
5769
5770#undef LMI_HELPER
5771#undef LMI_DIRECT
5772
5773    gen_store_fpr64(ctx, t0, rd);
5774
5775    tcg_temp_free_i64(t0);
5776    tcg_temp_free_i64(t1);
5777}
5778
5779/* Traps */
5780static void gen_trap (DisasContext *ctx, uint32_t opc,
5781                      int rs, int rt, int16_t imm)
5782{
5783    int cond;
5784    TCGv t0 = tcg_temp_new();
5785    TCGv t1 = tcg_temp_new();
5786
5787    cond = 0;
5788    /* Load needed operands */
5789    switch (opc) {
5790    case OPC_TEQ:
5791    case OPC_TGE:
5792    case OPC_TGEU:
5793    case OPC_TLT:
5794    case OPC_TLTU:
5795    case OPC_TNE:
5796        /* Compare two registers */
5797        if (rs != rt) {
5798            gen_load_gpr(t0, rs);
5799            gen_load_gpr(t1, rt);
5800            cond = 1;
5801        }
5802        break;
5803    case OPC_TEQI:
5804    case OPC_TGEI:
5805    case OPC_TGEIU:
5806    case OPC_TLTI:
5807    case OPC_TLTIU:
5808    case OPC_TNEI:
5809        /* Compare register to immediate */
5810        if (rs != 0 || imm != 0) {
5811            gen_load_gpr(t0, rs);
5812            tcg_gen_movi_tl(t1, (int32_t)imm);
5813            cond = 1;
5814        }
5815        break;
5816    }
5817    if (cond == 0) {
5818        switch (opc) {
5819        case OPC_TEQ:   /* rs == rs */
5820        case OPC_TEQI:  /* r0 == 0  */
5821        case OPC_TGE:   /* rs >= rs */
5822        case OPC_TGEI:  /* r0 >= 0  */
5823        case OPC_TGEU:  /* rs >= rs unsigned */
5824        case OPC_TGEIU: /* r0 >= 0  unsigned */
5825            /* Always trap */
5826            generate_exception_end(ctx, EXCP_TRAP);
5827            break;
5828        case OPC_TLT:   /* rs < rs           */
5829        case OPC_TLTI:  /* r0 < 0            */
5830        case OPC_TLTU:  /* rs < rs unsigned  */
5831        case OPC_TLTIU: /* r0 < 0  unsigned  */
5832        case OPC_TNE:   /* rs != rs          */
5833        case OPC_TNEI:  /* r0 != 0           */
5834            /* Never trap: treat as NOP. */
5835            break;
5836        }
5837    } else {
5838        TCGLabel *l1 = gen_new_label();
5839
5840        switch (opc) {
5841        case OPC_TEQ:
5842        case OPC_TEQI:
5843            tcg_gen_brcond_tl(TCG_COND_NE, t0, t1, l1);
5844            break;
5845        case OPC_TGE:
5846        case OPC_TGEI:
5847            tcg_gen_brcond_tl(TCG_COND_LT, t0, t1, l1);
5848            break;
5849        case OPC_TGEU:
5850        case OPC_TGEIU:
5851            tcg_gen_brcond_tl(TCG_COND_LTU, t0, t1, l1);
5852            break;
5853        case OPC_TLT:
5854        case OPC_TLTI:
5855            tcg_gen_brcond_tl(TCG_COND_GE, t0, t1, l1);
5856            break;
5857        case OPC_TLTU:
5858        case OPC_TLTIU:
5859            tcg_gen_brcond_tl(TCG_COND_GEU, t0, t1, l1);
5860            break;
5861        case OPC_TNE:
5862        case OPC_TNEI:
5863            tcg_gen_brcond_tl(TCG_COND_EQ, t0, t1, l1);
5864            break;
5865        }
5866        generate_exception(ctx, EXCP_TRAP);
5867        gen_set_label(l1);
5868    }
5869    tcg_temp_free(t0);
5870    tcg_temp_free(t1);
5871}
5872
5873static inline bool use_goto_tb(DisasContext *ctx, target_ulong dest)
5874{
5875    if (unlikely(ctx->base.singlestep_enabled)) {
5876        return false;
5877    }
5878
5879#ifndef CONFIG_USER_ONLY
5880    return (ctx->base.tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK);
5881#else
5882    return true;
5883#endif
5884}
5885
5886static inline void gen_goto_tb(DisasContext *ctx, int n, target_ulong dest)
5887{
5888    if (use_goto_tb(ctx, dest)) {
5889        tcg_gen_goto_tb(n);
5890        gen_save_pc(dest);
5891        tcg_gen_exit_tb(ctx->base.tb, n);
5892    } else {
5893        gen_save_pc(dest);
5894        if (ctx->base.singlestep_enabled) {
5895            save_cpu_state(ctx, 0);
5896            gen_helper_raise_exception_debug(cpu_env);
5897        }
5898        tcg_gen_lookup_and_goto_ptr();
5899    }
5900}
5901
5902/* Branches (before delay slot) */
5903static void gen_compute_branch (DisasContext *ctx, uint32_t opc,
5904                                int insn_bytes,
5905                                int rs, int rt, int32_t offset,
5906                                int delayslot_size)
5907{
5908    target_ulong btgt = -1;
5909    int blink = 0;
5910    int bcond_compute = 0;
5911    TCGv t0 = tcg_temp_new();
5912    TCGv t1 = tcg_temp_new();
5913
5914    if (ctx->hflags & MIPS_HFLAG_BMASK) {
5915#ifdef MIPS_DEBUG_DISAS
5916        LOG_DISAS("Branch in delay / forbidden slot at PC 0x"
5917                  TARGET_FMT_lx "\n", ctx->base.pc_next);
5918#endif
5919        generate_exception_end(ctx, EXCP_RI);
5920        goto out;
5921    }
5922
5923    /* Load needed operands */
5924    switch (opc) {
5925    case OPC_BEQ:
5926    case OPC_BEQL:
5927    case OPC_BNE:
5928    case OPC_BNEL:
5929        /* Compare two registers */
5930        if (rs != rt) {
5931            gen_load_gpr(t0, rs);
5932            gen_load_gpr(t1, rt);
5933            bcond_compute = 1;
5934        }
5935        btgt = ctx->base.pc_next + insn_bytes + offset;
5936        break;
5937    case OPC_BGEZ:
5938    case OPC_BGEZAL:
5939    case OPC_BGEZALL:
5940    case OPC_BGEZL:
5941    case OPC_BGTZ:
5942    case OPC_BGTZL:
5943    case OPC_BLEZ:
5944    case OPC_BLEZL:
5945    case OPC_BLTZ:
5946    case OPC_BLTZAL:
5947    case OPC_BLTZALL:
5948    case OPC_BLTZL:
5949        /* Compare to zero */
5950        if (rs != 0) {
5951            gen_load_gpr(t0, rs);
5952            bcond_compute = 1;
5953        }
5954        btgt = ctx->base.pc_next + insn_bytes + offset;
5955        break;
5956    case OPC_BPOSGE32:
5957#if defined(TARGET_MIPS64)
5958    case OPC_BPOSGE64:
5959        tcg_gen_andi_tl(t0, cpu_dspctrl, 0x7F);
5960#else
5961        tcg_gen_andi_tl(t0, cpu_dspctrl, 0x3F);
5962#endif
5963        bcond_compute = 1;
5964        btgt = ctx->base.pc_next + insn_bytes + offset;
5965        break;
5966    case OPC_J:
5967    case OPC_JAL:
5968    case OPC_JALX:
5969        /* Jump to immediate */
5970        btgt = ((ctx->base.pc_next + insn_bytes) & (int32_t)0xF0000000) |
5971            (uint32_t)offset;
5972        break;
5973    case OPC_JR:
5974    case OPC_JALR:
5975        /* Jump to register */
5976        if (offset != 0 && offset != 16) {
5977            /*
5978             * Hint = 0 is JR/JALR, hint 16 is JR.HB/JALR.HB, the
5979             * others are reserved.
5980             */
5981            MIPS_INVAL("jump hint");
5982            generate_exception_end(ctx, EXCP_RI);
5983            goto out;
5984        }
5985        gen_load_gpr(btarget, rs);
5986        break;
5987    default:
5988        MIPS_INVAL("branch/jump");
5989        generate_exception_end(ctx, EXCP_RI);
5990        goto out;
5991    }
5992    if (bcond_compute == 0) {
5993        /* No condition to be computed */
5994        switch (opc) {
5995        case OPC_BEQ:     /* rx == rx        */
5996        case OPC_BEQL:    /* rx == rx likely */
5997        case OPC_BGEZ:    /* 0 >= 0          */
5998        case OPC_BGEZL:   /* 0 >= 0 likely   */
5999        case OPC_BLEZ:    /* 0 <= 0          */
6000        case OPC_BLEZL:   /* 0 <= 0 likely   */
6001            /* Always take */
6002            ctx->hflags |= MIPS_HFLAG_B;
6003            break;
6004        case OPC_BGEZAL:  /* 0 >= 0          */
6005        case OPC_BGEZALL: /* 0 >= 0 likely   */
6006            /* Always take and link */
6007            blink = 31;
6008            ctx->hflags |= MIPS_HFLAG_B;
6009            break;
6010        case OPC_BNE:     /* rx != rx        */
6011        case OPC_BGTZ:    /* 0 > 0           */
6012        case OPC_BLTZ:    /* 0 < 0           */
6013            /* Treat as NOP. */
6014            goto out;
6015        case OPC_BLTZAL:  /* 0 < 0           */
6016            /*
6017             * Handle as an unconditional branch to get correct delay
6018             * slot checking.
6019             */
6020            blink = 31;
6021            btgt = ctx->base.pc_next + insn_bytes + delayslot_size;
6022            ctx->hflags |= MIPS_HFLAG_B;
6023            break;
6024        case OPC_BLTZALL: /* 0 < 0 likely */
6025            tcg_gen_movi_tl(cpu_gpr[31], ctx->base.pc_next + 8);
6026            /* Skip the instruction in the delay slot */
6027            ctx->base.pc_next += 4;
6028            goto out;
6029        case OPC_BNEL:    /* rx != rx likely */
6030        case OPC_BGTZL:   /* 0 > 0 likely */
6031        case OPC_BLTZL:   /* 0 < 0 likely */
6032            /* Skip the instruction in the delay slot */
6033            ctx->base.pc_next += 4;
6034            goto out;
6035        case OPC_J:
6036            ctx->hflags |= MIPS_HFLAG_B;
6037            break;
6038        case OPC_JALX:
6039            ctx->hflags |= MIPS_HFLAG_BX;
6040            /* Fallthrough */
6041        case OPC_JAL:
6042            blink = 31;
6043            ctx->hflags |= MIPS_HFLAG_B;
6044            break;
6045        case OPC_JR:
6046            ctx->hflags |= MIPS_HFLAG_BR;
6047            break;
6048        case OPC_JALR:
6049            blink = rt;
6050            ctx->hflags |= MIPS_HFLAG_BR;
6051            break;
6052        default:
6053            MIPS_INVAL("branch/jump");
6054            generate_exception_end(ctx, EXCP_RI);
6055            goto out;
6056        }
6057    } else {
6058        switch (opc) {
6059        case OPC_BEQ:
6060            tcg_gen_setcond_tl(TCG_COND_EQ, bcond, t0, t1);
6061            goto not_likely;
6062        case OPC_BEQL:
6063            tcg_gen_setcond_tl(TCG_COND_EQ, bcond, t0, t1);
6064            goto likely;
6065        case OPC_BNE:
6066            tcg_gen_setcond_tl(TCG_COND_NE, bcond, t0, t1);
6067            goto not_likely;
6068        case OPC_BNEL:
6069            tcg_gen_setcond_tl(TCG_COND_NE, bcond, t0, t1);
6070            goto likely;
6071        case OPC_BGEZ:
6072            tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
6073            goto not_likely;
6074        case OPC_BGEZL:
6075            tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
6076            goto likely;
6077        case OPC_BGEZAL:
6078            tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
6079            blink = 31;
6080            goto not_likely;
6081        case OPC_BGEZALL:
6082            tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
6083            blink = 31;
6084            goto likely;
6085        case OPC_BGTZ:
6086            tcg_gen_setcondi_tl(TCG_COND_GT, bcond, t0, 0);
6087            goto not_likely;
6088        case OPC_BGTZL:
6089            tcg_gen_setcondi_tl(TCG_COND_GT, bcond, t0, 0);
6090            goto likely;
6091        case OPC_BLEZ:
6092            tcg_gen_setcondi_tl(TCG_COND_LE, bcond, t0, 0);
6093            goto not_likely;
6094        case OPC_BLEZL:
6095            tcg_gen_setcondi_tl(TCG_COND_LE, bcond, t0, 0);
6096            goto likely;
6097        case OPC_BLTZ:
6098            tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
6099            goto not_likely;
6100        case OPC_BLTZL:
6101            tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
6102            goto likely;
6103        case OPC_BPOSGE32:
6104            tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 32);
6105            goto not_likely;
6106#if defined(TARGET_MIPS64)
6107        case OPC_BPOSGE64:
6108            tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 64);
6109            goto not_likely;
6110#endif
6111        case OPC_BLTZAL:
6112            tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
6113            blink = 31;
6114        not_likely:
6115            ctx->hflags |= MIPS_HFLAG_BC;
6116            break;
6117        case OPC_BLTZALL:
6118            tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
6119            blink = 31;
6120        likely:
6121            ctx->hflags |= MIPS_HFLAG_BL;
6122            break;
6123        default:
6124            MIPS_INVAL("conditional branch/jump");
6125            generate_exception_end(ctx, EXCP_RI);
6126            goto out;
6127        }
6128    }
6129
6130    ctx->btarget = btgt;
6131
6132    switch (delayslot_size) {
6133    case 2:
6134        ctx->hflags |= MIPS_HFLAG_BDS16;
6135        break;
6136    case 4:
6137        ctx->hflags |= MIPS_HFLAG_BDS32;
6138        break;
6139    }
6140
6141    if (blink > 0) {
6142        int post_delay = insn_bytes + delayslot_size;
6143        int lowbit = !!(ctx->hflags & MIPS_HFLAG_M16);
6144
6145        tcg_gen_movi_tl(cpu_gpr[blink],
6146                        ctx->base.pc_next + post_delay + lowbit);
6147    }
6148
6149 out:
6150    if (insn_bytes == 2) {
6151        ctx->hflags |= MIPS_HFLAG_B16;
6152    }
6153    tcg_temp_free(t0);
6154    tcg_temp_free(t1);
6155}
6156
6157
6158/* nanoMIPS Branches */
6159static void gen_compute_branch_nm(DisasContext *ctx, uint32_t opc,
6160                                int insn_bytes,
6161                                int rs, int rt, int32_t offset)
6162{
6163    target_ulong btgt = -1;
6164    int bcond_compute = 0;
6165    TCGv t0 = tcg_temp_new();
6166    TCGv t1 = tcg_temp_new();
6167
6168    /* Load needed operands */
6169    switch (opc) {
6170    case OPC_BEQ:
6171    case OPC_BNE:
6172        /* Compare two registers */
6173        if (rs != rt) {
6174            gen_load_gpr(t0, rs);
6175            gen_load_gpr(t1, rt);
6176            bcond_compute = 1;
6177        }
6178        btgt = ctx->base.pc_next + insn_bytes + offset;
6179        break;
6180    case OPC_BGEZAL:
6181        /* Compare to zero */
6182        if (rs != 0) {
6183            gen_load_gpr(t0, rs);
6184            bcond_compute = 1;
6185        }
6186        btgt = ctx->base.pc_next + insn_bytes + offset;
6187        break;
6188    case OPC_BPOSGE32:
6189        tcg_gen_andi_tl(t0, cpu_dspctrl, 0x3F);
6190        bcond_compute = 1;
6191        btgt = ctx->base.pc_next + insn_bytes + offset;
6192        break;
6193    case OPC_JR:
6194    case OPC_JALR:
6195        /* Jump to register */
6196        if (offset != 0 && offset != 16) {
6197            /*
6198             * Hint = 0 is JR/JALR, hint 16 is JR.HB/JALR.HB, the
6199             * others are reserved.
6200             */
6201            MIPS_INVAL("jump hint");
6202            generate_exception_end(ctx, EXCP_RI);
6203            goto out;
6204        }
6205        gen_load_gpr(btarget, rs);
6206        break;
6207    default:
6208        MIPS_INVAL("branch/jump");
6209        generate_exception_end(ctx, EXCP_RI);
6210        goto out;
6211    }
6212    if (bcond_compute == 0) {
6213        /* No condition to be computed */
6214        switch (opc) {
6215        case OPC_BEQ:     /* rx == rx        */
6216            /* Always take */
6217            ctx->hflags |= MIPS_HFLAG_B;
6218            break;
6219        case OPC_BGEZAL:  /* 0 >= 0          */
6220            /* Always take and link */
6221            tcg_gen_movi_tl(cpu_gpr[31],
6222                            ctx->base.pc_next + insn_bytes);
6223            ctx->hflags |= MIPS_HFLAG_B;
6224            break;
6225        case OPC_BNE:     /* rx != rx        */
6226            tcg_gen_movi_tl(cpu_gpr[31], ctx->base.pc_next + 8);
6227            /* Skip the instruction in the delay slot */
6228            ctx->base.pc_next += 4;
6229            goto out;
6230        case OPC_JR:
6231            ctx->hflags |= MIPS_HFLAG_BR;
6232            break;
6233        case OPC_JALR:
6234            if (rt > 0) {
6235                tcg_gen_movi_tl(cpu_gpr[rt],
6236                                ctx->base.pc_next + insn_bytes);
6237            }
6238            ctx->hflags |= MIPS_HFLAG_BR;
6239            break;
6240        default:
6241            MIPS_INVAL("branch/jump");
6242            generate_exception_end(ctx, EXCP_RI);
6243            goto out;
6244        }
6245    } else {
6246        switch (opc) {
6247        case OPC_BEQ:
6248            tcg_gen_setcond_tl(TCG_COND_EQ, bcond, t0, t1);
6249            goto not_likely;
6250        case OPC_BNE:
6251            tcg_gen_setcond_tl(TCG_COND_NE, bcond, t0, t1);
6252            goto not_likely;
6253        case OPC_BGEZAL:
6254            tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
6255            tcg_gen_movi_tl(cpu_gpr[31],
6256                            ctx->base.pc_next + insn_bytes);
6257            goto not_likely;
6258        case OPC_BPOSGE32:
6259            tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 32);
6260        not_likely:
6261            ctx->hflags |= MIPS_HFLAG_BC;
6262            break;
6263        default:
6264            MIPS_INVAL("conditional branch/jump");
6265            generate_exception_end(ctx, EXCP_RI);
6266            goto out;
6267        }
6268    }
6269
6270    ctx->btarget = btgt;
6271
6272 out:
6273    if (insn_bytes == 2) {
6274        ctx->hflags |= MIPS_HFLAG_B16;
6275    }
6276    tcg_temp_free(t0);
6277    tcg_temp_free(t1);
6278}
6279
6280
6281/* special3 bitfield operations */
6282static void gen_bitops(DisasContext *ctx, uint32_t opc, int rt,
6283                       int rs, int lsb, int msb)
6284{
6285    TCGv t0 = tcg_temp_new();
6286    TCGv t1 = tcg_temp_new();
6287
6288    gen_load_gpr(t1, rs);
6289    switch (opc) {
6290    case OPC_EXT:
6291        if (lsb + msb > 31) {
6292            goto fail;
6293        }
6294        if (msb != 31) {
6295            tcg_gen_extract_tl(t0, t1, lsb, msb + 1);
6296        } else {
6297            /*
6298             * The two checks together imply that lsb == 0,
6299             * so this is a simple sign-extension.
6300             */
6301            tcg_gen_ext32s_tl(t0, t1);
6302        }
6303        break;
6304#if defined(TARGET_MIPS64)
6305    case OPC_DEXTU:
6306        lsb += 32;
6307        goto do_dext;
6308    case OPC_DEXTM:
6309        msb += 32;
6310        goto do_dext;
6311    case OPC_DEXT:
6312    do_dext:
6313        if (lsb + msb > 63) {
6314            goto fail;
6315        }
6316        tcg_gen_extract_tl(t0, t1, lsb, msb + 1);
6317        break;
6318#endif
6319    case OPC_INS:
6320        if (lsb > msb) {
6321            goto fail;
6322        }
6323        gen_load_gpr(t0, rt);
6324        tcg_gen_deposit_tl(t0, t0, t1, lsb, msb - lsb + 1);
6325        tcg_gen_ext32s_tl(t0, t0);
6326        break;
6327#if defined(TARGET_MIPS64)
6328    case OPC_DINSU:
6329        lsb += 32;
6330        /* FALLTHRU */
6331    case OPC_DINSM:
6332        msb += 32;
6333        /* FALLTHRU */
6334    case OPC_DINS:
6335        if (lsb > msb) {
6336            goto fail;
6337        }
6338        gen_load_gpr(t0, rt);
6339        tcg_gen_deposit_tl(t0, t0, t1, lsb, msb - lsb + 1);
6340        break;
6341#endif
6342    default:
6343fail:
6344        MIPS_INVAL("bitops");
6345        generate_exception_end(ctx, EXCP_RI);
6346        tcg_temp_free(t0);
6347        tcg_temp_free(t1);
6348        return;
6349    }
6350    gen_store_gpr(t0, rt);
6351    tcg_temp_free(t0);
6352    tcg_temp_free(t1);
6353}
6354
6355static void gen_bshfl(DisasContext *ctx, uint32_t op2, int rt, int rd)
6356{
6357    TCGv t0;
6358
6359    if (rd == 0) {
6360        /* If no destination, treat it as a NOP. */
6361        return;
6362    }
6363
6364    t0 = tcg_temp_new();
6365    gen_load_gpr(t0, rt);
6366    switch (op2) {
6367    case OPC_WSBH:
6368        {
6369            TCGv t1 = tcg_temp_new();
6370            TCGv t2 = tcg_const_tl(0x00FF00FF);
6371
6372            tcg_gen_shri_tl(t1, t0, 8);
6373            tcg_gen_and_tl(t1, t1, t2);
6374            tcg_gen_and_tl(t0, t0, t2);
6375            tcg_gen_shli_tl(t0, t0, 8);
6376            tcg_gen_or_tl(t0, t0, t1);
6377            tcg_temp_free(t2);
6378            tcg_temp_free(t1);
6379            tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
6380        }
6381        break;
6382    case OPC_SEB:
6383        tcg_gen_ext8s_tl(cpu_gpr[rd], t0);
6384        break;
6385    case OPC_SEH:
6386        tcg_gen_ext16s_tl(cpu_gpr[rd], t0);
6387        break;
6388#if defined(TARGET_MIPS64)
6389    case OPC_DSBH:
6390        {
6391            TCGv t1 = tcg_temp_new();
6392            TCGv t2 = tcg_const_tl(0x00FF00FF00FF00FFULL);
6393
6394            tcg_gen_shri_tl(t1, t0, 8);
6395            tcg_gen_and_tl(t1, t1, t2);
6396            tcg_gen_and_tl(t0, t0, t2);
6397            tcg_gen_shli_tl(t0, t0, 8);
6398            tcg_gen_or_tl(cpu_gpr[rd], t0, t1);
6399            tcg_temp_free(t2);
6400            tcg_temp_free(t1);
6401        }
6402        break;
6403    case OPC_DSHD:
6404        {
6405            TCGv t1 = tcg_temp_new();
6406            TCGv t2 = tcg_const_tl(0x0000FFFF0000FFFFULL);
6407
6408            tcg_gen_shri_tl(t1, t0, 16);
6409            tcg_gen_and_tl(t1, t1, t2);
6410            tcg_gen_and_tl(t0, t0, t2);
6411            tcg_gen_shli_tl(t0, t0, 16);
6412            tcg_gen_or_tl(t0, t0, t1);
6413            tcg_gen_shri_tl(t1, t0, 32);
6414            tcg_gen_shli_tl(t0, t0, 32);
6415            tcg_gen_or_tl(cpu_gpr[rd], t0, t1);
6416            tcg_temp_free(t2);
6417            tcg_temp_free(t1);
6418        }
6419        break;
6420#endif
6421    default:
6422        MIPS_INVAL("bsfhl");
6423        generate_exception_end(ctx, EXCP_RI);
6424        tcg_temp_free(t0);
6425        return;
6426    }
6427    tcg_temp_free(t0);
6428}
6429
6430static void gen_lsa(DisasContext *ctx, int opc, int rd, int rs, int rt,
6431                    int imm2)
6432{
6433    TCGv t0;
6434    TCGv t1;
6435    if (rd == 0) {
6436        /* Treat as NOP. */
6437        return;
6438    }
6439    t0 = tcg_temp_new();
6440    t1 = tcg_temp_new();
6441    gen_load_gpr(t0, rs);
6442    gen_load_gpr(t1, rt);
6443    tcg_gen_shli_tl(t0, t0, imm2 + 1);
6444    tcg_gen_add_tl(cpu_gpr[rd], t0, t1);
6445    if (opc == OPC_LSA) {
6446        tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
6447    }
6448
6449    tcg_temp_free(t1);
6450    tcg_temp_free(t0);
6451
6452    return;
6453}
6454
6455static void gen_align_bits(DisasContext *ctx, int wordsz, int rd, int rs,
6456                           int rt, int bits)
6457{
6458    TCGv t0;
6459    if (rd == 0) {
6460        /* Treat as NOP. */
6461        return;
6462    }
6463    t0 = tcg_temp_new();
6464    if (bits == 0 || bits == wordsz) {
6465        if (bits == 0) {
6466            gen_load_gpr(t0, rt);
6467        } else {
6468            gen_load_gpr(t0, rs);
6469        }
6470        switch (wordsz) {
6471        case 32:
6472            tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
6473            break;
6474#if defined(TARGET_MIPS64)
6475        case 64:
6476            tcg_gen_mov_tl(cpu_gpr[rd], t0);
6477            break;
6478#endif
6479        }
6480    } else {
6481        TCGv t1 = tcg_temp_new();
6482        gen_load_gpr(t0, rt);
6483        gen_load_gpr(t1, rs);
6484        switch (wordsz) {
6485        case 32:
6486            {
6487                TCGv_i64 t2 = tcg_temp_new_i64();
6488                tcg_gen_concat_tl_i64(t2, t1, t0);
6489                tcg_gen_shri_i64(t2, t2, 32 - bits);
6490                gen_move_low32(cpu_gpr[rd], t2);
6491                tcg_temp_free_i64(t2);
6492            }
6493            break;
6494#if defined(TARGET_MIPS64)
6495        case 64:
6496            tcg_gen_shli_tl(t0, t0, bits);
6497            tcg_gen_shri_tl(t1, t1, 64 - bits);
6498            tcg_gen_or_tl(cpu_gpr[rd], t1, t0);
6499            break;
6500#endif
6501        }
6502        tcg_temp_free(t1);
6503    }
6504
6505    tcg_temp_free(t0);
6506}
6507
6508static void gen_align(DisasContext *ctx, int wordsz, int rd, int rs, int rt,
6509                      int bp)
6510{
6511    gen_align_bits(ctx, wordsz, rd, rs, rt, bp * 8);
6512}
6513
6514static void gen_ext(DisasContext *ctx, int wordsz, int rd, int rs, int rt,
6515                    int shift)
6516{
6517    gen_align_bits(ctx, wordsz, rd, rs, rt, wordsz - shift);
6518}
6519
6520static void gen_bitswap(DisasContext *ctx, int opc, int rd, int rt)
6521{
6522    TCGv t0;
6523    if (rd == 0) {
6524        /* Treat as NOP. */
6525        return;
6526    }
6527    t0 = tcg_temp_new();
6528    gen_load_gpr(t0, rt);
6529    switch (opc) {
6530    case OPC_BITSWAP:
6531        gen_helper_bitswap(cpu_gpr[rd], t0);
6532        break;
6533#if defined(TARGET_MIPS64)
6534    case OPC_DBITSWAP:
6535        gen_helper_dbitswap(cpu_gpr[rd], t0);
6536        break;
6537#endif
6538    }
6539    tcg_temp_free(t0);
6540}
6541
6542#ifndef CONFIG_USER_ONLY
6543/* CP0 (MMU and control) */
6544static inline void gen_mthc0_entrylo(TCGv arg, target_ulong off)
6545{
6546    TCGv_i64 t0 = tcg_temp_new_i64();
6547    TCGv_i64 t1 = tcg_temp_new_i64();
6548
6549    tcg_gen_ext_tl_i64(t0, arg);
6550    tcg_gen_ld_i64(t1, cpu_env, off);
6551#if defined(TARGET_MIPS64)
6552    tcg_gen_deposit_i64(t1, t1, t0, 30, 32);
6553#else
6554    tcg_gen_concat32_i64(t1, t1, t0);
6555#endif
6556    tcg_gen_st_i64(t1, cpu_env, off);
6557    tcg_temp_free_i64(t1);
6558    tcg_temp_free_i64(t0);
6559}
6560
6561static inline void gen_mthc0_store64(TCGv arg, target_ulong off)
6562{
6563    TCGv_i64 t0 = tcg_temp_new_i64();
6564    TCGv_i64 t1 = tcg_temp_new_i64();
6565
6566    tcg_gen_ext_tl_i64(t0, arg);
6567    tcg_gen_ld_i64(t1, cpu_env, off);
6568    tcg_gen_concat32_i64(t1, t1, t0);
6569    tcg_gen_st_i64(t1, cpu_env, off);
6570    tcg_temp_free_i64(t1);
6571    tcg_temp_free_i64(t0);
6572}
6573
6574static inline void gen_mfhc0_entrylo(TCGv arg, target_ulong off)
6575{
6576    TCGv_i64 t0 = tcg_temp_new_i64();
6577
6578    tcg_gen_ld_i64(t0, cpu_env, off);
6579#if defined(TARGET_MIPS64)
6580    tcg_gen_shri_i64(t0, t0, 30);
6581#else
6582    tcg_gen_shri_i64(t0, t0, 32);
6583#endif
6584    gen_move_low32(arg, t0);
6585    tcg_temp_free_i64(t0);
6586}
6587
6588static inline void gen_mfhc0_load64(TCGv arg, target_ulong off, int shift)
6589{
6590    TCGv_i64 t0 = tcg_temp_new_i64();
6591
6592    tcg_gen_ld_i64(t0, cpu_env, off);
6593    tcg_gen_shri_i64(t0, t0, 32 + shift);
6594    gen_move_low32(arg, t0);
6595    tcg_temp_free_i64(t0);
6596}
6597
6598static inline void gen_mfc0_load32(TCGv arg, target_ulong off)
6599{
6600    TCGv_i32 t0 = tcg_temp_new_i32();
6601
6602    tcg_gen_ld_i32(t0, cpu_env, off);
6603    tcg_gen_ext_i32_tl(arg, t0);
6604    tcg_temp_free_i32(t0);
6605}
6606
6607static inline void gen_mfc0_load64(TCGv arg, target_ulong off)
6608{
6609    tcg_gen_ld_tl(arg, cpu_env, off);
6610    tcg_gen_ext32s_tl(arg, arg);
6611}
6612
6613static inline void gen_mtc0_store32(TCGv arg, target_ulong off)
6614{
6615    TCGv_i32 t0 = tcg_temp_new_i32();
6616
6617    tcg_gen_trunc_tl_i32(t0, arg);
6618    tcg_gen_st_i32(t0, cpu_env, off);
6619    tcg_temp_free_i32(t0);
6620}
6621
6622#define CP0_CHECK(c)                            \
6623    do {                                        \
6624        if (!(c)) {                             \
6625            goto cp0_unimplemented;             \
6626        }                                       \
6627    } while (0)
6628
6629static void gen_mfhc0(DisasContext *ctx, TCGv arg, int reg, int sel)
6630{
6631    const char *register_name = "invalid";
6632
6633    switch (reg) {
6634    case CP0_REGISTER_02:
6635        switch (sel) {
6636        case 0:
6637            CP0_CHECK(ctx->hflags & MIPS_HFLAG_ELPA);
6638            gen_mfhc0_entrylo(arg, offsetof(CPUMIPSState, CP0_EntryLo0));
6639            register_name = "EntryLo0";
6640            break;
6641        default:
6642            goto cp0_unimplemented;
6643        }
6644        break;
6645    case CP0_REGISTER_03:
6646        switch (sel) {
6647        case 0:
6648            CP0_CHECK(ctx->hflags & MIPS_HFLAG_ELPA);
6649            gen_mfhc0_entrylo(arg, offsetof(CPUMIPSState, CP0_EntryLo1));
6650            register_name = "EntryLo1";
6651            break;
6652        default:
6653            goto cp0_unimplemented;
6654        }
6655        break;
6656    case CP0_REGISTER_09:
6657        switch (sel) {
6658        case 7:
6659            CP0_CHECK(ctx->saar);
6660            gen_helper_mfhc0_saar(arg, cpu_env);
6661            register_name = "SAAR";
6662            break;
6663        default:
6664            goto cp0_unimplemented;
6665        }
6666        break;
6667    case CP0_REGISTER_17:
6668        switch (sel) {
6669        case 0:
6670            gen_mfhc0_load64(arg, offsetof(CPUMIPSState, CP0_LLAddr),
6671                             ctx->CP0_LLAddr_shift);
6672            register_name = "LLAddr";
6673            break;
6674        case 1:
6675            CP0_CHECK(ctx->mrp);
6676            gen_helper_mfhc0_maar(arg, cpu_env);
6677            register_name = "MAAR";
6678            break;
6679        default:
6680            goto cp0_unimplemented;
6681        }
6682        break;
6683    case CP0_REGISTER_28:
6684        switch (sel) {
6685        case 0:
6686        case 2:
6687        case 4:
6688        case 6:
6689            gen_mfhc0_load64(arg, offsetof(CPUMIPSState, CP0_TagLo), 0);
6690            register_name = "TagLo";
6691            break;
6692        default:
6693            goto cp0_unimplemented;
6694        }
6695        break;
6696    default:
6697        goto cp0_unimplemented;
6698    }
6699    trace_mips_translate_c0("mfhc0", register_name, reg, sel);
6700    return;
6701
6702cp0_unimplemented:
6703    qemu_log_mask(LOG_UNIMP, "mfhc0 %s (reg %d sel %d)\n",
6704                  register_name, reg, sel);
6705    tcg_gen_movi_tl(arg, 0);
6706}
6707
6708static void gen_mthc0(DisasContext *ctx, TCGv arg, int reg, int sel)
6709{
6710    const char *register_name = "invalid";
6711    uint64_t mask = ctx->PAMask >> 36;
6712
6713    switch (reg) {
6714    case CP0_REGISTER_02:
6715        switch (sel) {
6716        case 0:
6717            CP0_CHECK(ctx->hflags & MIPS_HFLAG_ELPA);
6718            tcg_gen_andi_tl(arg, arg, mask);
6719            gen_mthc0_entrylo(arg, offsetof(CPUMIPSState, CP0_EntryLo0));
6720            register_name = "EntryLo0";
6721            break;
6722        default:
6723            goto cp0_unimplemented;
6724        }
6725        break;
6726    case CP0_REGISTER_03:
6727        switch (sel) {
6728        case 0:
6729            CP0_CHECK(ctx->hflags & MIPS_HFLAG_ELPA);
6730            tcg_gen_andi_tl(arg, arg, mask);
6731            gen_mthc0_entrylo(arg, offsetof(CPUMIPSState, CP0_EntryLo1));
6732            register_name = "EntryLo1";
6733            break;
6734        default:
6735            goto cp0_unimplemented;
6736        }
6737        break;
6738    case CP0_REGISTER_09:
6739        switch (sel) {
6740        case 7:
6741            CP0_CHECK(ctx->saar);
6742            gen_helper_mthc0_saar(cpu_env, arg);
6743            register_name = "SAAR";
6744            break;
6745        default:
6746            goto cp0_unimplemented;
6747        }
6748        break;
6749    case CP0_REGISTER_17:
6750        switch (sel) {
6751        case 0:
6752            /*
6753             * LLAddr is read-only (the only exception is bit 0 if LLB is
6754             * supported); the CP0_LLAddr_rw_bitmask does not seem to be
6755             * relevant for modern MIPS cores supporting MTHC0, therefore
6756             * treating MTHC0 to LLAddr as NOP.
6757             */
6758            register_name = "LLAddr";
6759            break;
6760        case 1:
6761            CP0_CHECK(ctx->mrp);
6762            gen_helper_mthc0_maar(cpu_env, arg);
6763            register_name = "MAAR";
6764            break;
6765        default:
6766            goto cp0_unimplemented;
6767        }
6768        break;
6769    case CP0_REGISTER_28:
6770        switch (sel) {
6771        case 0:
6772        case 2:
6773        case 4:
6774        case 6:
6775            tcg_gen_andi_tl(arg, arg, mask);
6776            gen_mthc0_store64(arg, offsetof(CPUMIPSState, CP0_TagLo));
6777            register_name = "TagLo";
6778            break;
6779        default:
6780            goto cp0_unimplemented;
6781        }
6782        break;
6783    default:
6784        goto cp0_unimplemented;
6785    }
6786    trace_mips_translate_c0("mthc0", register_name, reg, sel);
6787
6788cp0_unimplemented:
6789    qemu_log_mask(LOG_UNIMP, "mthc0 %s (reg %d sel %d)\n",
6790                  register_name, reg, sel);
6791}
6792
6793static inline void gen_mfc0_unimplemented(DisasContext *ctx, TCGv arg)
6794{
6795    if (ctx->insn_flags & ISA_MIPS32R6) {
6796        tcg_gen_movi_tl(arg, 0);
6797    } else {
6798        tcg_gen_movi_tl(arg, ~0);
6799    }
6800}
6801
6802static void gen_mfc0(DisasContext *ctx, TCGv arg, int reg, int sel)
6803{
6804    const char *register_name = "invalid";
6805
6806    if (sel != 0) {
6807        check_insn(ctx, ISA_MIPS32);
6808    }
6809
6810    switch (reg) {
6811    case CP0_REGISTER_00:
6812        switch (sel) {
6813        case 0:
6814            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Index));
6815            register_name = "Index";
6816            break;
6817        case 1:
6818            CP0_CHECK(ctx->insn_flags & ASE_MT);
6819            gen_helper_mfc0_mvpcontrol(arg, cpu_env);
6820            register_name = "MVPControl";
6821            break;
6822        case 2:
6823            CP0_CHECK(ctx->insn_flags & ASE_MT);
6824            gen_helper_mfc0_mvpconf0(arg, cpu_env);
6825            register_name = "MVPConf0";
6826            break;
6827        case 3:
6828            CP0_CHECK(ctx->insn_flags & ASE_MT);
6829            gen_helper_mfc0_mvpconf1(arg, cpu_env);
6830            register_name = "MVPConf1";
6831            break;
6832        case 4:
6833            CP0_CHECK(ctx->vp);
6834            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPControl));
6835            register_name = "VPControl";
6836            break;
6837        default:
6838            goto cp0_unimplemented;
6839        }
6840        break;
6841    case CP0_REGISTER_01:
6842        switch (sel) {
6843        case 0:
6844            CP0_CHECK(!(ctx->insn_flags & ISA_MIPS32R6));
6845            gen_helper_mfc0_random(arg, cpu_env);
6846            register_name = "Random";
6847            break;
6848        case 1:
6849            CP0_CHECK(ctx->insn_flags & ASE_MT);
6850            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEControl));
6851            register_name = "VPEControl";
6852            break;
6853        case 2:
6854            CP0_CHECK(ctx->insn_flags & ASE_MT);
6855            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf0));
6856            register_name = "VPEConf0";
6857            break;
6858        case 3:
6859            CP0_CHECK(ctx->insn_flags & ASE_MT);
6860            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf1));
6861            register_name = "VPEConf1";
6862            break;
6863        case 4:
6864            CP0_CHECK(ctx->insn_flags & ASE_MT);
6865            gen_mfc0_load64(arg, offsetof(CPUMIPSState, CP0_YQMask));
6866            register_name = "YQMask";
6867            break;
6868        case 5:
6869            CP0_CHECK(ctx->insn_flags & ASE_MT);
6870            gen_mfc0_load64(arg, offsetof(CPUMIPSState, CP0_VPESchedule));
6871            register_name = "VPESchedule";
6872            break;
6873        case 6:
6874            CP0_CHECK(ctx->insn_flags & ASE_MT);
6875            gen_mfc0_load64(arg, offsetof(CPUMIPSState, CP0_VPEScheFBack));
6876            register_name = "VPEScheFBack";
6877            break;
6878        case 7:
6879            CP0_CHECK(ctx->insn_flags & ASE_MT);
6880            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEOpt));
6881            register_name = "VPEOpt";
6882            break;
6883        default:
6884            goto cp0_unimplemented;
6885        }
6886        break;
6887    case CP0_REGISTER_02:
6888        switch (sel) {
6889        case 0:
6890            {
6891                TCGv_i64 tmp = tcg_temp_new_i64();
6892                tcg_gen_ld_i64(tmp, cpu_env,
6893                               offsetof(CPUMIPSState, CP0_EntryLo0));
6894#if defined(TARGET_MIPS64)
6895                if (ctx->rxi) {
6896                    /* Move RI/XI fields to bits 31:30 */
6897                    tcg_gen_shri_tl(arg, tmp, CP0EnLo_XI);
6898                    tcg_gen_deposit_tl(tmp, tmp, arg, 30, 2);
6899                }
6900#endif
6901                gen_move_low32(arg, tmp);
6902                tcg_temp_free_i64(tmp);
6903            }
6904            register_name = "EntryLo0";
6905            break;
6906        case 1:
6907            CP0_CHECK(ctx->insn_flags & ASE_MT);
6908            gen_helper_mfc0_tcstatus(arg, cpu_env);
6909            register_name = "TCStatus";
6910            break;
6911        case 2:
6912            CP0_CHECK(ctx->insn_flags & ASE_MT);
6913            gen_helper_mfc0_tcbind(arg, cpu_env);
6914            register_name = "TCBind";
6915            break;
6916        case 3:
6917            CP0_CHECK(ctx->insn_flags & ASE_MT);
6918            gen_helper_mfc0_tcrestart(arg, cpu_env);
6919            register_name = "TCRestart";
6920            break;
6921        case 4:
6922            CP0_CHECK(ctx->insn_flags & ASE_MT);
6923            gen_helper_mfc0_tchalt(arg, cpu_env);
6924            register_name = "TCHalt";
6925            break;
6926        case 5:
6927            CP0_CHECK(ctx->insn_flags & ASE_MT);
6928            gen_helper_mfc0_tccontext(arg, cpu_env);
6929            register_name = "TCContext";
6930            break;
6931        case 6:
6932            CP0_CHECK(ctx->insn_flags & ASE_MT);
6933            gen_helper_mfc0_tcschedule(arg, cpu_env);
6934            register_name = "TCSchedule";
6935            break;
6936        case 7:
6937            CP0_CHECK(ctx->insn_flags & ASE_MT);
6938            gen_helper_mfc0_tcschefback(arg, cpu_env);
6939            register_name = "TCScheFBack";
6940            break;
6941        default:
6942            goto cp0_unimplemented;
6943        }
6944        break;
6945    case CP0_REGISTER_03:
6946        switch (sel) {
6947        case 0:
6948            {
6949                TCGv_i64 tmp = tcg_temp_new_i64();
6950                tcg_gen_ld_i64(tmp, cpu_env,
6951                               offsetof(CPUMIPSState, CP0_EntryLo1));
6952#if defined(TARGET_MIPS64)
6953                if (ctx->rxi) {
6954                    /* Move RI/XI fields to bits 31:30 */
6955                    tcg_gen_shri_tl(arg, tmp, CP0EnLo_XI);
6956                    tcg_gen_deposit_tl(tmp, tmp, arg, 30, 2);
6957                }
6958#endif
6959                gen_move_low32(arg, tmp);
6960                tcg_temp_free_i64(tmp);
6961            }
6962            register_name = "EntryLo1";
6963            break;
6964        case 1:
6965            CP0_CHECK(ctx->vp);
6966            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_GlobalNumber));
6967            register_name = "GlobalNumber";
6968            break;
6969        default:
6970            goto cp0_unimplemented;
6971        }
6972        break;
6973    case CP0_REGISTER_04:
6974        switch (sel) {
6975        case 0:
6976            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_Context));
6977            tcg_gen_ext32s_tl(arg, arg);
6978            register_name = "Context";
6979            break;
6980        case 1:
6981            /* gen_helper_mfc0_contextconfig(arg); - SmartMIPS ASE */
6982            register_name = "ContextConfig";
6983            goto cp0_unimplemented;
6984        case 2:
6985            CP0_CHECK(ctx->ulri);
6986            tcg_gen_ld_tl(arg, cpu_env,
6987                          offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
6988            tcg_gen_ext32s_tl(arg, arg);
6989            register_name = "UserLocal";
6990            break;
6991        default:
6992            goto cp0_unimplemented;
6993        }
6994        break;
6995    case CP0_REGISTER_05:
6996        switch (sel) {
6997        case 0:
6998            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageMask));
6999            register_name = "PageMask";
7000            break;
7001        case 1:
7002            check_insn(ctx, ISA_MIPS32R2);
7003            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageGrain));
7004            register_name = "PageGrain";
7005            break;
7006        case 2:
7007            CP0_CHECK(ctx->sc);
7008            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_SegCtl0));
7009            tcg_gen_ext32s_tl(arg, arg);
7010            register_name = "SegCtl0";
7011            break;
7012        case 3:
7013            CP0_CHECK(ctx->sc);
7014            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_SegCtl1));
7015            tcg_gen_ext32s_tl(arg, arg);
7016            register_name = "SegCtl1";
7017            break;
7018        case 4:
7019            CP0_CHECK(ctx->sc);
7020            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_SegCtl2));
7021            tcg_gen_ext32s_tl(arg, arg);
7022            register_name = "SegCtl2";
7023            break;
7024        case 5:
7025            check_pw(ctx);
7026            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PWBase));
7027            register_name = "PWBase";
7028            break;
7029        case 6:
7030            check_pw(ctx);
7031            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PWField));
7032            register_name = "PWField";
7033            break;
7034        case 7:
7035            check_pw(ctx);
7036            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PWSize));
7037            register_name = "PWSize";
7038            break;
7039        default:
7040            goto cp0_unimplemented;
7041        }
7042        break;
7043    case CP0_REGISTER_06:
7044        switch (sel) {
7045        case 0:
7046            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Wired));
7047            register_name = "Wired";
7048            break;
7049        case 1:
7050            check_insn(ctx, ISA_MIPS32R2);
7051            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf0));
7052            register_name = "SRSConf0";
7053            break;
7054        case 2:
7055            check_insn(ctx, ISA_MIPS32R2);
7056            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf1));
7057            register_name = "SRSConf1";
7058            break;
7059        case 3:
7060            check_insn(ctx, ISA_MIPS32R2);
7061            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf2));
7062            register_name = "SRSConf2";
7063            break;
7064        case 4:
7065            check_insn(ctx, ISA_MIPS32R2);
7066            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf3));
7067            register_name = "SRSConf3";
7068            break;
7069        case 5:
7070            check_insn(ctx, ISA_MIPS32R2);
7071            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf4));
7072            register_name = "SRSConf4";
7073            break;
7074        case 6:
7075            check_pw(ctx);
7076            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PWCtl));
7077            register_name = "PWCtl";
7078            break;
7079        default:
7080            goto cp0_unimplemented;
7081        }
7082        break;
7083    case CP0_REGISTER_07:
7084        switch (sel) {
7085        case 0:
7086            check_insn(ctx, ISA_MIPS32R2);
7087            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_HWREna));
7088            register_name = "HWREna";
7089            break;
7090        default:
7091            goto cp0_unimplemented;
7092        }
7093        break;
7094    case CP0_REGISTER_08:
7095        switch (sel) {
7096        case 0:
7097            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_BadVAddr));
7098            tcg_gen_ext32s_tl(arg, arg);
7099            register_name = "BadVAddr";
7100            break;
7101        case 1:
7102            CP0_CHECK(ctx->bi);
7103            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_BadInstr));
7104            register_name = "BadInstr";
7105            break;
7106        case 2:
7107            CP0_CHECK(ctx->bp);
7108            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_BadInstrP));
7109            register_name = "BadInstrP";
7110            break;
7111        case 3:
7112            CP0_CHECK(ctx->bi);
7113            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_BadInstrX));
7114            tcg_gen_andi_tl(arg, arg, ~0xffff);
7115            register_name = "BadInstrX";
7116            break;
7117       default:
7118            goto cp0_unimplemented;
7119        }
7120        break;
7121    case CP0_REGISTER_09:
7122        switch (sel) {
7123        case 0:
7124            /* Mark as an IO operation because we read the time.  */
7125            if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
7126                gen_io_start();
7127            }
7128            gen_helper_mfc0_count(arg, cpu_env);
7129            if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
7130                gen_io_end();
7131            }
7132            /*
7133             * Break the TB to be able to take timer interrupts immediately
7134             * after reading count. DISAS_STOP isn't sufficient, we need to
7135             * ensure we break completely out of translated code.
7136             */
7137            gen_save_pc(ctx->base.pc_next + 4);
7138            ctx->base.is_jmp = DISAS_EXIT;
7139            register_name = "Count";
7140            break;
7141        case 6:
7142            CP0_CHECK(ctx->saar);
7143            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SAARI));
7144            register_name = "SAARI";
7145            break;
7146        case 7:
7147            CP0_CHECK(ctx->saar);
7148            gen_helper_mfc0_saar(arg, cpu_env);
7149            register_name = "SAAR";
7150            break;
7151        default:
7152            goto cp0_unimplemented;
7153        }
7154        break;
7155    case CP0_REGISTER_10:
7156        switch (sel) {
7157        case 0:
7158            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryHi));
7159            tcg_gen_ext32s_tl(arg, arg);
7160            register_name = "EntryHi";
7161            break;
7162        default:
7163            goto cp0_unimplemented;
7164        }
7165        break;
7166    case CP0_REGISTER_11:
7167        switch (sel) {
7168        case 0:
7169            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Compare));
7170            register_name = "Compare";
7171            break;
7172        /* 6,7 are implementation dependent */
7173        default:
7174            goto cp0_unimplemented;
7175        }
7176        break;
7177    case CP0_REGISTER_12:
7178        switch (sel) {
7179        case 0:
7180            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Status));
7181            register_name = "Status";
7182            break;
7183        case 1:
7184            check_insn(ctx, ISA_MIPS32R2);
7185            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_IntCtl));
7186            register_name = "IntCtl";
7187            break;
7188        case 2:
7189            check_insn(ctx, ISA_MIPS32R2);
7190            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSCtl));
7191            register_name = "SRSCtl";
7192            break;
7193        case 3:
7194            check_insn(ctx, ISA_MIPS32R2);
7195            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSMap));
7196            register_name = "SRSMap";
7197            break;
7198        default:
7199            goto cp0_unimplemented;
7200       }
7201        break;
7202    case CP0_REGISTER_13:
7203        switch (sel) {
7204        case 0:
7205            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Cause));
7206            register_name = "Cause";
7207            break;
7208        default:
7209            goto cp0_unimplemented;
7210       }
7211        break;
7212    case CP0_REGISTER_14:
7213        switch (sel) {
7214        case 0:
7215            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EPC));
7216            tcg_gen_ext32s_tl(arg, arg);
7217            register_name = "EPC";
7218            break;
7219        default:
7220            goto cp0_unimplemented;
7221        }
7222        break;
7223    case CP0_REGISTER_15:
7224        switch (sel) {
7225        case 0:
7226            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PRid));
7227            register_name = "PRid";
7228            break;
7229        case 1:
7230            check_insn(ctx, ISA_MIPS32R2);
7231            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EBase));
7232            tcg_gen_ext32s_tl(arg, arg);
7233            register_name = "EBase";
7234            break;
7235        case 3:
7236            check_insn(ctx, ISA_MIPS32R2);
7237            CP0_CHECK(ctx->cmgcr);
7238            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_CMGCRBase));
7239            tcg_gen_ext32s_tl(arg, arg);
7240            register_name = "CMGCRBase";
7241            break;
7242        default:
7243            goto cp0_unimplemented;
7244       }
7245        break;
7246    case CP0_REGISTER_16:
7247        switch (sel) {
7248        case 0:
7249            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config0));
7250            register_name = "Config";
7251            break;
7252        case 1:
7253            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config1));
7254            register_name = "Config1";
7255            break;
7256        case 2:
7257            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config2));
7258            register_name = "Config2";
7259            break;
7260        case 3:
7261            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config3));
7262            register_name = "Config3";
7263            break;
7264        case 4:
7265            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config4));
7266            register_name = "Config4";
7267            break;
7268        case 5:
7269            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config5));
7270            register_name = "Config5";
7271            break;
7272        /* 6,7 are implementation dependent */
7273        case 6:
7274            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config6));
7275            register_name = "Config6";
7276            break;
7277        case 7:
7278            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config7));
7279            register_name = "Config7";
7280            break;
7281        default:
7282            goto cp0_unimplemented;
7283        }
7284        break;
7285    case CP0_REGISTER_17:
7286        switch (sel) {
7287        case 0:
7288            gen_helper_mfc0_lladdr(arg, cpu_env);
7289            register_name = "LLAddr";
7290            break;
7291        case 1:
7292            CP0_CHECK(ctx->mrp);
7293            gen_helper_mfc0_maar(arg, cpu_env);
7294            register_name = "MAAR";
7295            break;
7296        case 2:
7297            CP0_CHECK(ctx->mrp);
7298            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_MAARI));
7299            register_name = "MAARI";
7300            break;
7301        default:
7302            goto cp0_unimplemented;
7303        }
7304        break;
7305    case CP0_REGISTER_18:
7306        switch (sel) {
7307        case 0:
7308        case 1:
7309        case 2:
7310        case 3:
7311        case 4:
7312        case 5:
7313        case 6:
7314        case 7:
7315            CP0_CHECK(ctx->CP0_Config1 & (1 << CP0C1_WR));
7316            gen_helper_1e0i(mfc0_watchlo, arg, sel);
7317            register_name = "WatchLo";
7318            break;
7319        default:
7320            goto cp0_unimplemented;
7321        }
7322        break;
7323    case CP0_REGISTER_19:
7324        switch (sel) {
7325        case 0:
7326        case 1:
7327        case 2:
7328        case 3:
7329        case 4:
7330        case 5:
7331        case 6:
7332        case 7:
7333            CP0_CHECK(ctx->CP0_Config1 & (1 << CP0C1_WR));
7334            gen_helper_1e0i(mfc0_watchhi, arg, sel);
7335            register_name = "WatchHi";
7336            break;
7337        default:
7338            goto cp0_unimplemented;
7339        }
7340        break;
7341    case CP0_REGISTER_20:
7342        switch (sel) {
7343        case 0:
7344#if defined(TARGET_MIPS64)
7345            check_insn(ctx, ISA_MIPS3);
7346            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_XContext));
7347            tcg_gen_ext32s_tl(arg, arg);
7348            register_name = "XContext";
7349            break;
7350#endif
7351        default:
7352            goto cp0_unimplemented;
7353        }
7354        break;
7355    case CP0_REGISTER_21:
7356       /* Officially reserved, but sel 0 is used for R1x000 framemask */
7357        CP0_CHECK(!(ctx->insn_flags & ISA_MIPS32R6));
7358        switch (sel) {
7359        case 0:
7360            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Framemask));
7361            register_name = "Framemask";
7362            break;
7363        default:
7364            goto cp0_unimplemented;
7365        }
7366        break;
7367    case CP0_REGISTER_22:
7368        tcg_gen_movi_tl(arg, 0); /* unimplemented */
7369        register_name = "'Diagnostic"; /* implementation dependent */
7370        break;
7371    case CP0_REGISTER_23:
7372        switch (sel) {
7373        case 0:
7374            gen_helper_mfc0_debug(arg, cpu_env); /* EJTAG support */
7375            register_name = "Debug";
7376            break;
7377        case 1:
7378//            gen_helper_mfc0_tracecontrol(arg); /* PDtrace support */
7379            register_name = "TraceControl";
7380            goto cp0_unimplemented;
7381        case 2:
7382//            gen_helper_mfc0_tracecontrol2(arg); /* PDtrace support */
7383            register_name = "TraceControl2";
7384            goto cp0_unimplemented;
7385        case 3:
7386//            gen_helper_mfc0_usertracedata(arg); /* PDtrace support */
7387            register_name = "UserTraceData";
7388            goto cp0_unimplemented;
7389        case 4:
7390//            gen_helper_mfc0_tracebpc(arg); /* PDtrace support */
7391            register_name = "TraceBPC";
7392            goto cp0_unimplemented;
7393        default:
7394            goto cp0_unimplemented;
7395        }
7396        break;
7397    case CP0_REGISTER_24:
7398        switch (sel) {
7399        case 0:
7400            /* EJTAG support */
7401            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_DEPC));
7402            tcg_gen_ext32s_tl(arg, arg);
7403            register_name = "DEPC";
7404            break;
7405        default:
7406            goto cp0_unimplemented;
7407        }
7408        break;
7409    case CP0_REGISTER_25:
7410        switch (sel) {
7411        case 0:
7412            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Performance0));
7413            register_name = "Performance0";
7414            break;
7415        case 1:
7416            /* gen_helper_mfc0_performance1(arg); */
7417            register_name = "Performance1";
7418            goto cp0_unimplemented;
7419        case 2:
7420            /* gen_helper_mfc0_performance2(arg); */
7421            register_name = "Performance2";
7422            goto cp0_unimplemented;
7423        case 3:
7424            /* gen_helper_mfc0_performance3(arg); */
7425            register_name = "Performance3";
7426            goto cp0_unimplemented;
7427        case 4:
7428            /* gen_helper_mfc0_performance4(arg); */
7429            register_name = "Performance4";
7430            goto cp0_unimplemented;
7431        case 5:
7432            /* gen_helper_mfc0_performance5(arg); */
7433            register_name = "Performance5";
7434            goto cp0_unimplemented;
7435        case 6:
7436            /* gen_helper_mfc0_performance6(arg); */
7437            register_name = "Performance6";
7438            goto cp0_unimplemented;
7439        case 7:
7440            /* gen_helper_mfc0_performance7(arg); */
7441            register_name = "Performance7";
7442            goto cp0_unimplemented;
7443        default:
7444            goto cp0_unimplemented;
7445        }
7446        break;
7447    case CP0_REGISTER_26:
7448        switch (sel) {
7449        case 0:
7450            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_ErrCtl));
7451            register_name = "ErrCtl";
7452            break;
7453        default:
7454            goto cp0_unimplemented;
7455        }
7456        break;
7457    case CP0_REGISTER_27:
7458        switch (sel) {
7459        case 0:
7460        case 1:
7461        case 2:
7462        case 3:
7463            tcg_gen_movi_tl(arg, 0); /* unimplemented */
7464            register_name = "CacheErr";
7465            break;
7466        default:
7467            goto cp0_unimplemented;
7468        }
7469        break;
7470    case CP0_REGISTER_28:
7471        switch (sel) {
7472        case 0:
7473        case 2:
7474        case 4:
7475        case 6:
7476            {
7477                TCGv_i64 tmp = tcg_temp_new_i64();
7478                tcg_gen_ld_i64(tmp, cpu_env, offsetof(CPUMIPSState, CP0_TagLo));
7479                gen_move_low32(arg, tmp);
7480                tcg_temp_free_i64(tmp);
7481            }
7482            register_name = "TagLo";
7483            break;
7484        case 1:
7485        case 3:
7486        case 5:
7487        case 7:
7488            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataLo));
7489            register_name = "DataLo";
7490            break;
7491        default:
7492            goto cp0_unimplemented;
7493        }
7494        break;
7495    case CP0_REGISTER_29:
7496        switch (sel) {
7497        case 0:
7498        case 2:
7499        case 4:
7500        case 6:
7501            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_TagHi));
7502            register_name = "TagHi";
7503            break;
7504        case 1:
7505        case 3:
7506        case 5:
7507        case 7:
7508            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataHi));
7509            register_name = "DataHi";
7510            break;
7511        default:
7512            goto cp0_unimplemented;
7513        }
7514        break;
7515    case CP0_REGISTER_30:
7516        switch (sel) {
7517        case 0:
7518            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_ErrorEPC));
7519            tcg_gen_ext32s_tl(arg, arg);
7520            register_name = "ErrorEPC";
7521            break;
7522        default:
7523            goto cp0_unimplemented;
7524        }
7525        break;
7526    case CP0_REGISTER_31:
7527        switch (sel) {
7528        case 0:
7529            /* EJTAG support */
7530            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DESAVE));
7531            register_name = "DESAVE";
7532            break;
7533        case 2:
7534        case 3:
7535        case 4:
7536        case 5:
7537        case 6:
7538        case 7:
7539            CP0_CHECK(ctx->kscrexist & (1 << sel));
7540            tcg_gen_ld_tl(arg, cpu_env,
7541                          offsetof(CPUMIPSState, CP0_KScratch[sel-2]));
7542            tcg_gen_ext32s_tl(arg, arg);
7543            register_name = "KScratch";
7544            break;
7545        default:
7546            goto cp0_unimplemented;
7547        }
7548        break;
7549    default:
7550       goto cp0_unimplemented;
7551    }
7552    trace_mips_translate_c0("mfc0", register_name, reg, sel);
7553    return;
7554
7555cp0_unimplemented:
7556    qemu_log_mask(LOG_UNIMP, "mfc0 %s (reg %d sel %d)\n",
7557                  register_name, reg, sel);
7558    gen_mfc0_unimplemented(ctx, arg);
7559}
7560
7561static void gen_mtc0(DisasContext *ctx, TCGv arg, int reg, int sel)
7562{
7563    const char *register_name = "invalid";
7564
7565    if (sel != 0) {
7566        check_insn(ctx, ISA_MIPS32);
7567    }
7568
7569    if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
7570        gen_io_start();
7571    }
7572
7573    switch (reg) {
7574    case CP0_REGISTER_00:
7575        switch (sel) {
7576        case 0:
7577            gen_helper_mtc0_index(cpu_env, arg);
7578            register_name = "Index";
7579            break;
7580        case 1:
7581            CP0_CHECK(ctx->insn_flags & ASE_MT);
7582            gen_helper_mtc0_mvpcontrol(cpu_env, arg);
7583            register_name = "MVPControl";
7584            break;
7585        case 2:
7586            CP0_CHECK(ctx->insn_flags & ASE_MT);
7587            /* ignored */
7588            register_name = "MVPConf0";
7589            break;
7590        case 3:
7591            CP0_CHECK(ctx->insn_flags & ASE_MT);
7592            /* ignored */
7593            register_name = "MVPConf1";
7594            break;
7595        case 4:
7596            CP0_CHECK(ctx->vp);
7597            /* ignored */
7598            register_name = "VPControl";
7599            break;
7600        default:
7601            goto cp0_unimplemented;
7602        }
7603        break;
7604    case CP0_REGISTER_01:
7605        switch (sel) {
7606        case 0:
7607            /* ignored */
7608            register_name = "Random";
7609            break;
7610        case 1:
7611            CP0_CHECK(ctx->insn_flags & ASE_MT);
7612            gen_helper_mtc0_vpecontrol(cpu_env, arg);
7613            register_name = "VPEControl";
7614            break;
7615        case 2:
7616            CP0_CHECK(ctx->insn_flags & ASE_MT);
7617            gen_helper_mtc0_vpeconf0(cpu_env, arg);
7618            register_name = "VPEConf0";
7619            break;
7620        case 3:
7621            CP0_CHECK(ctx->insn_flags & ASE_MT);
7622            gen_helper_mtc0_vpeconf1(cpu_env, arg);
7623            register_name = "VPEConf1";
7624            break;
7625        case 4:
7626            CP0_CHECK(ctx->insn_flags & ASE_MT);
7627            gen_helper_mtc0_yqmask(cpu_env, arg);
7628            register_name = "YQMask";
7629            break;
7630        case 5:
7631            CP0_CHECK(ctx->insn_flags & ASE_MT);
7632            tcg_gen_st_tl(arg, cpu_env,
7633                          offsetof(CPUMIPSState, CP0_VPESchedule));
7634            register_name = "VPESchedule";
7635            break;
7636        case 6:
7637            CP0_CHECK(ctx->insn_flags & ASE_MT);
7638            tcg_gen_st_tl(arg, cpu_env,
7639                          offsetof(CPUMIPSState, CP0_VPEScheFBack));
7640            register_name = "VPEScheFBack";
7641            break;
7642        case 7:
7643            CP0_CHECK(ctx->insn_flags & ASE_MT);
7644            gen_helper_mtc0_vpeopt(cpu_env, arg);
7645            register_name = "VPEOpt";
7646            break;
7647        default:
7648            goto cp0_unimplemented;
7649        }
7650        break;
7651    case CP0_REGISTER_02:
7652        switch (sel) {
7653        case 0:
7654            gen_helper_mtc0_entrylo0(cpu_env, arg);
7655            register_name = "EntryLo0";
7656            break;
7657        case 1:
7658            CP0_CHECK(ctx->insn_flags & ASE_MT);
7659            gen_helper_mtc0_tcstatus(cpu_env, arg);
7660            register_name = "TCStatus";
7661            break;
7662        case 2:
7663            CP0_CHECK(ctx->insn_flags & ASE_MT);
7664            gen_helper_mtc0_tcbind(cpu_env, arg);
7665            register_name = "TCBind";
7666            break;
7667        case 3:
7668            CP0_CHECK(ctx->insn_flags & ASE_MT);
7669            gen_helper_mtc0_tcrestart(cpu_env, arg);
7670            register_name = "TCRestart";
7671            break;
7672        case 4:
7673            CP0_CHECK(ctx->insn_flags & ASE_MT);
7674            gen_helper_mtc0_tchalt(cpu_env, arg);
7675            register_name = "TCHalt";
7676            break;
7677        case 5:
7678            CP0_CHECK(ctx->insn_flags & ASE_MT);
7679            gen_helper_mtc0_tccontext(cpu_env, arg);
7680            register_name = "TCContext";
7681            break;
7682        case 6:
7683            CP0_CHECK(ctx->insn_flags & ASE_MT);
7684            gen_helper_mtc0_tcschedule(cpu_env, arg);
7685            register_name = "TCSchedule";
7686            break;
7687        case 7:
7688            CP0_CHECK(ctx->insn_flags & ASE_MT);
7689            gen_helper_mtc0_tcschefback(cpu_env, arg);
7690            register_name = "TCScheFBack";
7691            break;
7692        default:
7693            goto cp0_unimplemented;
7694        }
7695        break;
7696    case CP0_REGISTER_03:
7697        switch (sel) {
7698        case 0:
7699            gen_helper_mtc0_entrylo1(cpu_env, arg);
7700            register_name = "EntryLo1";
7701            break;
7702        case 1:
7703            CP0_CHECK(ctx->vp);
7704            /* ignored */
7705            register_name = "GlobalNumber";
7706            break;
7707        default:
7708            goto cp0_unimplemented;
7709        }
7710        break;
7711    case CP0_REGISTER_04:
7712        switch (sel) {
7713        case 0:
7714            gen_helper_mtc0_context(cpu_env, arg);
7715            register_name = "Context";
7716            break;
7717        case 1:
7718//            gen_helper_mtc0_contextconfig(cpu_env, arg); /* SmartMIPS ASE */
7719            register_name = "ContextConfig";
7720            goto cp0_unimplemented;
7721        case 2:
7722            CP0_CHECK(ctx->ulri);
7723            tcg_gen_st_tl(arg, cpu_env,
7724                          offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
7725            register_name = "UserLocal";
7726            break;
7727        default:
7728            goto cp0_unimplemented;
7729        }
7730        break;
7731    case CP0_REGISTER_05:
7732        switch (sel) {
7733        case 0:
7734            gen_helper_mtc0_pagemask(cpu_env, arg);
7735            register_name = "PageMask";
7736            break;
7737        case 1:
7738            check_insn(ctx, ISA_MIPS32R2);
7739            gen_helper_mtc0_pagegrain(cpu_env, arg);
7740            register_name = "PageGrain";
7741            ctx->base.is_jmp = DISAS_STOP;
7742            break;
7743        case 2:
7744            CP0_CHECK(ctx->sc);
7745            gen_helper_mtc0_segctl0(cpu_env, arg);
7746            register_name = "SegCtl0";
7747            break;
7748        case 3:
7749            CP0_CHECK(ctx->sc);
7750            gen_helper_mtc0_segctl1(cpu_env, arg);
7751            register_name = "SegCtl1";
7752            break;
7753        case 4:
7754            CP0_CHECK(ctx->sc);
7755            gen_helper_mtc0_segctl2(cpu_env, arg);
7756            register_name = "SegCtl2";
7757            break;
7758        case 5:
7759            check_pw(ctx);
7760            gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_PWBase));
7761            register_name = "PWBase";
7762            break;
7763        case 6:
7764            check_pw(ctx);
7765            gen_helper_mtc0_pwfield(cpu_env, arg);
7766            register_name = "PWField";
7767            break;
7768        case 7:
7769            check_pw(ctx);
7770            gen_helper_mtc0_pwsize(cpu_env, arg);
7771            register_name = "PWSize";
7772            break;
7773        default:
7774            goto cp0_unimplemented;
7775        }
7776        break;
7777    case CP0_REGISTER_06:
7778        switch (sel) {
7779        case 0:
7780            gen_helper_mtc0_wired(cpu_env, arg);
7781            register_name = "Wired";
7782            break;
7783        case 1:
7784            check_insn(ctx, ISA_MIPS32R2);
7785            gen_helper_mtc0_srsconf0(cpu_env, arg);
7786            register_name = "SRSConf0";
7787            break;
7788        case 2:
7789            check_insn(ctx, ISA_MIPS32R2);
7790            gen_helper_mtc0_srsconf1(cpu_env, arg);
7791            register_name = "SRSConf1";
7792            break;
7793        case 3:
7794            check_insn(ctx, ISA_MIPS32R2);
7795            gen_helper_mtc0_srsconf2(cpu_env, arg);
7796            register_name = "SRSConf2";
7797            break;
7798        case 4:
7799            check_insn(ctx, ISA_MIPS32R2);
7800            gen_helper_mtc0_srsconf3(cpu_env, arg);
7801            register_name = "SRSConf3";
7802            break;
7803        case 5:
7804            check_insn(ctx, ISA_MIPS32R2);
7805            gen_helper_mtc0_srsconf4(cpu_env, arg);
7806            register_name = "SRSConf4";
7807            break;
7808        case 6:
7809            check_pw(ctx);
7810            gen_helper_mtc0_pwctl(cpu_env, arg);
7811            register_name = "PWCtl";
7812            break;
7813        default:
7814            goto cp0_unimplemented;
7815        }
7816        break;
7817    case CP0_REGISTER_07:
7818        switch (sel) {
7819        case 0:
7820            check_insn(ctx, ISA_MIPS32R2);
7821            gen_helper_mtc0_hwrena(cpu_env, arg);
7822            ctx->base.is_jmp = DISAS_STOP;
7823            register_name = "HWREna";
7824            break;
7825        default:
7826            goto cp0_unimplemented;
7827        }
7828        break;
7829    case CP0_REGISTER_08:
7830        switch (sel) {
7831        case 0:
7832            /* ignored */
7833            register_name = "BadVAddr";
7834            break;
7835        case 1:
7836            /* ignored */
7837            register_name = "BadInstr";
7838            break;
7839        case 2:
7840            /* ignored */
7841            register_name = "BadInstrP";
7842            break;
7843        case 3:
7844            /* ignored */
7845            register_name = "BadInstrX";
7846            break;
7847        default:
7848            goto cp0_unimplemented;
7849        }
7850        break;
7851    case CP0_REGISTER_09:
7852        switch (sel) {
7853        case 0:
7854            gen_helper_mtc0_count(cpu_env, arg);
7855            register_name = "Count";
7856            break;
7857        case 6:
7858            CP0_CHECK(ctx->saar);
7859            gen_helper_mtc0_saari(cpu_env, arg);
7860            register_name = "SAARI";
7861            break;
7862        case 7:
7863            CP0_CHECK(ctx->saar);
7864            gen_helper_mtc0_saar(cpu_env, arg);
7865            register_name = "SAAR";
7866            break;
7867        default:
7868            goto cp0_unimplemented;
7869        }
7870        break;
7871    case CP0_REGISTER_10:
7872        switch (sel) {
7873        case 0:
7874            gen_helper_mtc0_entryhi(cpu_env, arg);
7875            register_name = "EntryHi";
7876            break;
7877        default:
7878            goto cp0_unimplemented;
7879        }
7880        break;
7881    case CP0_REGISTER_11:
7882        switch (sel) {
7883        case 0:
7884            gen_helper_mtc0_compare(cpu_env, arg);
7885            register_name = "Compare";
7886            break;
7887        /* 6,7 are implementation dependent */
7888        default:
7889            goto cp0_unimplemented;
7890        }
7891        break;
7892    case CP0_REGISTER_12:
7893        switch (sel) {
7894        case 0:
7895            save_cpu_state(ctx, 1);
7896            gen_helper_mtc0_status(cpu_env, arg);
7897            /* DISAS_STOP isn't good enough here, hflags may have changed. */
7898            gen_save_pc(ctx->base.pc_next + 4);
7899            ctx->base.is_jmp = DISAS_EXIT;
7900            register_name = "Status";
7901            break;
7902        case 1:
7903            check_insn(ctx, ISA_MIPS32R2);
7904            gen_helper_mtc0_intctl(cpu_env, arg);
7905            /* Stop translation as we may have switched the execution mode */
7906            ctx->base.is_jmp = DISAS_STOP;
7907            register_name = "IntCtl";
7908            break;
7909        case 2:
7910            check_insn(ctx, ISA_MIPS32R2);
7911            gen_helper_mtc0_srsctl(cpu_env, arg);
7912            /* Stop translation as we may have switched the execution mode */
7913            ctx->base.is_jmp = DISAS_STOP;
7914            register_name = "SRSCtl";
7915            break;
7916        case 3:
7917            check_insn(ctx, ISA_MIPS32R2);
7918            gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_SRSMap));
7919            /* Stop translation as we may have switched the execution mode */
7920            ctx->base.is_jmp = DISAS_STOP;
7921            register_name = "SRSMap";
7922            break;
7923        default:
7924            goto cp0_unimplemented;
7925        }
7926        break;
7927    case CP0_REGISTER_13:
7928        switch (sel) {
7929        case 0:
7930            save_cpu_state(ctx, 1);
7931            gen_helper_mtc0_cause(cpu_env, arg);
7932            /*
7933             * Stop translation as we may have triggered an interrupt.
7934             * DISAS_STOP isn't sufficient, we need to ensure we break out of
7935             * translated code to check for pending interrupts.
7936             */
7937            gen_save_pc(ctx->base.pc_next + 4);
7938            ctx->base.is_jmp = DISAS_EXIT;
7939            register_name = "Cause";
7940            break;
7941        default:
7942            goto cp0_unimplemented;
7943        }
7944        break;
7945    case CP0_REGISTER_14:
7946        switch (sel) {
7947        case 0:
7948            tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EPC));
7949            register_name = "EPC";
7950            break;
7951        default:
7952            goto cp0_unimplemented;
7953        }
7954        break;
7955    case CP0_REGISTER_15:
7956        switch (sel) {
7957        case 0:
7958            /* ignored */
7959            register_name = "PRid";
7960            break;
7961        case 1:
7962            check_insn(ctx, ISA_MIPS32R2);
7963            gen_helper_mtc0_ebase(cpu_env, arg);
7964            register_name = "EBase";
7965            break;
7966        default:
7967            goto cp0_unimplemented;
7968        }
7969        break;
7970    case CP0_REGISTER_16:
7971        switch (sel) {
7972        case 0:
7973            gen_helper_mtc0_config0(cpu_env, arg);
7974            register_name = "Config";
7975            /* Stop translation as we may have switched the execution mode */
7976            ctx->base.is_jmp = DISAS_STOP;
7977            break;
7978        case 1:
7979            /* ignored, read only */
7980            register_name = "Config1";
7981            break;
7982        case 2:
7983            gen_helper_mtc0_config2(cpu_env, arg);
7984            register_name = "Config2";
7985            /* Stop translation as we may have switched the execution mode */
7986            ctx->base.is_jmp = DISAS_STOP;
7987            break;
7988        case 3:
7989            gen_helper_mtc0_config3(cpu_env, arg);
7990            register_name = "Config3";
7991            /* Stop translation as we may have switched the execution mode */
7992            ctx->base.is_jmp = DISAS_STOP;
7993            break;
7994        case 4:
7995            gen_helper_mtc0_config4(cpu_env, arg);
7996            register_name = "Config4";
7997            ctx->base.is_jmp = DISAS_STOP;
7998            break;
7999        case 5:
8000            gen_helper_mtc0_config5(cpu_env, arg);
8001            register_name = "Config5";
8002            /* Stop translation as we may have switched the execution mode */
8003            ctx->base.is_jmp = DISAS_STOP;
8004            break;
8005        /* 6,7 are implementation dependent */
8006        case 6:
8007            /* ignored */
8008            register_name = "Config6";
8009            break;
8010        case 7:
8011            /* ignored */
8012            register_name = "Config7";
8013            break;
8014        default:
8015            register_name = "Invalid config selector";
8016            goto cp0_unimplemented;
8017        }
8018        break;
8019    case CP0_REGISTER_17:
8020        switch (sel) {
8021        case 0:
8022            gen_helper_mtc0_lladdr(cpu_env, arg);
8023            register_name = "LLAddr";
8024            break;
8025        case 1:
8026            CP0_CHECK(ctx->mrp);
8027            gen_helper_mtc0_maar(cpu_env, arg);
8028            register_name = "MAAR";
8029            break;
8030        case 2:
8031            CP0_CHECK(ctx->mrp);
8032            gen_helper_mtc0_maari(cpu_env, arg);
8033            register_name = "MAARI";
8034            break;
8035        default:
8036            goto cp0_unimplemented;
8037        }
8038        break;
8039    case CP0_REGISTER_18:
8040        switch (sel) {
8041        case 0:
8042        case 1:
8043        case 2:
8044        case 3:
8045        case 4:
8046        case 5:
8047        case 6:
8048        case 7:
8049            CP0_CHECK(ctx->CP0_Config1 & (1 << CP0C1_WR));
8050            gen_helper_0e1i(mtc0_watchlo, arg, sel);
8051            register_name = "WatchLo";
8052            break;
8053        default:
8054            goto cp0_unimplemented;
8055        }
8056        break;
8057    case CP0_REGISTER_19:
8058        switch (sel) {
8059        case 0:
8060        case 1:
8061        case 2:
8062        case 3:
8063        case 4:
8064        case 5:
8065        case 6:
8066        case 7:
8067            CP0_CHECK(ctx->CP0_Config1 & (1 << CP0C1_WR));
8068            gen_helper_0e1i(mtc0_watchhi, arg, sel);
8069            register_name = "WatchHi";
8070            break;
8071        default:
8072            goto cp0_unimplemented;
8073        }
8074        break;
8075    case CP0_REGISTER_20:
8076        switch (sel) {
8077        case 0:
8078#if defined(TARGET_MIPS64)
8079            check_insn(ctx, ISA_MIPS3);
8080            gen_helper_mtc0_xcontext(cpu_env, arg);
8081            register_name = "XContext";
8082            break;
8083#endif
8084        default:
8085            goto cp0_unimplemented;
8086        }
8087        break;
8088    case CP0_REGISTER_21:
8089       /* Officially reserved, but sel 0 is used for R1x000 framemask */
8090        CP0_CHECK(!(ctx->insn_flags & ISA_MIPS32R6));
8091        switch (sel) {
8092        case 0:
8093            gen_helper_mtc0_framemask(cpu_env, arg);
8094            register_name = "Framemask";
8095            break;
8096        default:
8097            goto cp0_unimplemented;
8098        }
8099        break;
8100    case CP0_REGISTER_22:
8101        /* ignored */
8102        register_name = "Diagnostic"; /* implementation dependent */
8103        break;
8104    case CP0_REGISTER_23:
8105        switch (sel) {
8106        case 0:
8107            gen_helper_mtc0_debug(cpu_env, arg); /* EJTAG support */
8108            /* DISAS_STOP isn't good enough here, hflags may have changed. */
8109            gen_save_pc(ctx->base.pc_next + 4);
8110            ctx->base.is_jmp = DISAS_EXIT;
8111            register_name = "Debug";
8112            break;
8113        case 1:
8114//            gen_helper_mtc0_tracecontrol(cpu_env, arg); /* PDtrace support */
8115            register_name = "TraceControl";
8116            /* Stop translation as we may have switched the execution mode */
8117            ctx->base.is_jmp = DISAS_STOP;
8118            goto cp0_unimplemented;
8119        case 2:
8120//            gen_helper_mtc0_tracecontrol2(cpu_env, arg); /* PDtrace support */
8121            register_name = "TraceControl2";
8122            /* Stop translation as we may have switched the execution mode */
8123            ctx->base.is_jmp = DISAS_STOP;
8124            goto cp0_unimplemented;
8125        case 3:
8126            /* Stop translation as we may have switched the execution mode */
8127            ctx->base.is_jmp = DISAS_STOP;
8128//            gen_helper_mtc0_usertracedata(cpu_env, arg); /* PDtrace support */
8129            register_name = "UserTraceData";
8130            /* Stop translation as we may have switched the execution mode */
8131            ctx->base.is_jmp = DISAS_STOP;
8132            goto cp0_unimplemented;
8133        case 4:
8134//            gen_helper_mtc0_tracebpc(cpu_env, arg); /* PDtrace support */
8135            /* Stop translation as we may have switched the execution mode */
8136            ctx->base.is_jmp = DISAS_STOP;
8137            register_name = "TraceBPC";
8138            goto cp0_unimplemented;
8139        default:
8140            goto cp0_unimplemented;
8141        }
8142        break;
8143    case CP0_REGISTER_24:
8144        switch (sel) {
8145        case 0:
8146            /* EJTAG support */
8147            tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_DEPC));
8148            register_name = "DEPC";
8149            break;
8150        default:
8151            goto cp0_unimplemented;
8152        }
8153        break;
8154    case CP0_REGISTER_25:
8155        switch (sel) {
8156        case 0:
8157            gen_helper_mtc0_performance0(cpu_env, arg);
8158            register_name = "Performance0";
8159            break;
8160        case 1:
8161            /* gen_helper_mtc0_performance1(arg); */
8162            register_name = "Performance1";
8163            goto cp0_unimplemented;
8164        case 2:
8165            /* gen_helper_mtc0_performance2(arg); */
8166            register_name = "Performance2";
8167            goto cp0_unimplemented;
8168        case 3:
8169            /* gen_helper_mtc0_performance3(arg); */
8170            register_name = "Performance3";
8171            goto cp0_unimplemented;
8172        case 4:
8173            /* gen_helper_mtc0_performance4(arg); */
8174            register_name = "Performance4";
8175            goto cp0_unimplemented;
8176        case 5:
8177            /* gen_helper_mtc0_performance5(arg); */
8178            register_name = "Performance5";
8179            goto cp0_unimplemented;
8180        case 6:
8181            /* gen_helper_mtc0_performance6(arg); */
8182            register_name = "Performance6";
8183            goto cp0_unimplemented;
8184        case 7:
8185            /* gen_helper_mtc0_performance7(arg); */
8186            register_name = "Performance7";
8187            goto cp0_unimplemented;
8188        default:
8189            goto cp0_unimplemented;
8190        }
8191       break;
8192    case CP0_REGISTER_26:
8193        switch (sel) {
8194        case 0:
8195            gen_helper_mtc0_errctl(cpu_env, arg);
8196            ctx->base.is_jmp = DISAS_STOP;
8197            register_name = "ErrCtl";
8198            break;
8199        default:
8200            goto cp0_unimplemented;
8201        }
8202        break;
8203    case CP0_REGISTER_27:
8204        switch (sel) {
8205        case 0:
8206        case 1:
8207        case 2:
8208        case 3:
8209            /* ignored */
8210            register_name = "CacheErr";
8211            break;
8212        default:
8213            goto cp0_unimplemented;
8214        }
8215       break;
8216    case CP0_REGISTER_28:
8217        switch (sel) {
8218        case 0:
8219        case 2:
8220        case 4:
8221        case 6:
8222            gen_helper_mtc0_taglo(cpu_env, arg);
8223            register_name = "TagLo";
8224            break;
8225        case 1:
8226        case 3:
8227        case 5:
8228        case 7:
8229            gen_helper_mtc0_datalo(cpu_env, arg);
8230            register_name = "DataLo";
8231            break;
8232        default:
8233            goto cp0_unimplemented;
8234        }
8235        break;
8236    case CP0_REGISTER_29:
8237        switch (sel) {
8238        case 0:
8239        case 2:
8240        case 4:
8241        case 6:
8242            gen_helper_mtc0_taghi(cpu_env, arg);
8243            register_name = "TagHi";
8244            break;
8245        case 1:
8246        case 3:
8247        case 5:
8248        case 7:
8249            gen_helper_mtc0_datahi(cpu_env, arg);
8250            register_name = "DataHi";
8251            break;
8252        default:
8253            register_name = "invalid sel";
8254            goto cp0_unimplemented;
8255        }
8256       break;
8257    case CP0_REGISTER_30:
8258        switch (sel) {
8259        case 0:
8260            tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_ErrorEPC));
8261            register_name = "ErrorEPC";
8262            break;
8263        default:
8264            goto cp0_unimplemented;
8265        }
8266        break;
8267    case CP0_REGISTER_31:
8268        switch (sel) {
8269        case 0:
8270            /* EJTAG support */
8271            gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_DESAVE));
8272            register_name = "DESAVE";
8273            break;
8274        case 2:
8275        case 3:
8276        case 4:
8277        case 5:
8278        case 6:
8279        case 7:
8280            CP0_CHECK(ctx->kscrexist & (1 << sel));
8281            tcg_gen_st_tl(arg, cpu_env,
8282                          offsetof(CPUMIPSState, CP0_KScratch[sel-2]));
8283            register_name = "KScratch";
8284            break;
8285        default:
8286            goto cp0_unimplemented;
8287        }
8288        break;
8289    default:
8290       goto cp0_unimplemented;
8291    }
8292    trace_mips_translate_c0("mtc0", register_name, reg, sel);
8293
8294    /* For simplicity assume that all writes can cause interrupts.  */
8295    if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
8296        gen_io_end();
8297        /*
8298         * DISAS_STOP isn't sufficient, we need to ensure we break out of
8299         * translated code to check for pending interrupts.
8300         */
8301        gen_save_pc(ctx->base.pc_next + 4);
8302        ctx->base.is_jmp = DISAS_EXIT;
8303    }
8304    return;
8305
8306cp0_unimplemented:
8307    qemu_log_mask(LOG_UNIMP, "mtc0 %s (reg %d sel %d)\n",
8308                  register_name, reg, sel);
8309}
8310
8311#if defined(TARGET_MIPS64)
8312static void gen_dmfc0(DisasContext *ctx, TCGv arg, int reg, int sel)
8313{
8314    const char *register_name = "invalid";
8315
8316    if (sel != 0) {
8317        check_insn(ctx, ISA_MIPS64);
8318    }
8319
8320    switch (reg) {
8321    case CP0_REGISTER_00:
8322        switch (sel) {
8323        case 0:
8324            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Index));
8325            register_name = "Index";
8326            break;
8327        case 1:
8328            CP0_CHECK(ctx->insn_flags & ASE_MT);
8329            gen_helper_mfc0_mvpcontrol(arg, cpu_env);
8330            register_name = "MVPControl";
8331            break;
8332        case 2:
8333            CP0_CHECK(ctx->insn_flags & ASE_MT);
8334            gen_helper_mfc0_mvpconf0(arg, cpu_env);
8335            register_name = "MVPConf0";
8336            break;
8337        case 3:
8338            CP0_CHECK(ctx->insn_flags & ASE_MT);
8339            gen_helper_mfc0_mvpconf1(arg, cpu_env);
8340            register_name = "MVPConf1";
8341            break;
8342        case 4:
8343            CP0_CHECK(ctx->vp);
8344            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPControl));
8345            register_name = "VPControl";
8346            break;
8347        default:
8348            goto cp0_unimplemented;
8349        }
8350        break;
8351    case CP0_REGISTER_01:
8352        switch (sel) {
8353        case 0:
8354            CP0_CHECK(!(ctx->insn_flags & ISA_MIPS32R6));
8355            gen_helper_mfc0_random(arg, cpu_env);
8356            register_name = "Random";
8357            break;
8358        case 1:
8359            CP0_CHECK(ctx->insn_flags & ASE_MT);
8360            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEControl));
8361            register_name = "VPEControl";
8362            break;
8363        case 2:
8364            CP0_CHECK(ctx->insn_flags & ASE_MT);
8365            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf0));
8366            register_name = "VPEConf0";
8367            break;
8368        case 3:
8369            CP0_CHECK(ctx->insn_flags & ASE_MT);
8370            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf1));
8371            register_name = "VPEConf1";
8372            break;
8373        case 4:
8374            CP0_CHECK(ctx->insn_flags & ASE_MT);
8375            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_YQMask));
8376            register_name = "YQMask";
8377            break;
8378        case 5:
8379            CP0_CHECK(ctx->insn_flags & ASE_MT);
8380            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_VPESchedule));
8381            register_name = "VPESchedule";
8382            break;
8383        case 6:
8384            CP0_CHECK(ctx->insn_flags & ASE_MT);
8385            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_VPEScheFBack));
8386            register_name = "VPEScheFBack";
8387            break;
8388        case 7:
8389            CP0_CHECK(ctx->insn_flags & ASE_MT);
8390            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEOpt));
8391            register_name = "VPEOpt";
8392            break;
8393        default:
8394            goto cp0_unimplemented;
8395        }
8396        break;
8397    case CP0_REGISTER_02:
8398        switch (sel) {
8399        case 0:
8400            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryLo0));
8401            register_name = "EntryLo0";
8402            break;
8403        case 1:
8404            CP0_CHECK(ctx->insn_flags & ASE_MT);
8405            gen_helper_mfc0_tcstatus(arg, cpu_env);
8406            register_name = "TCStatus";
8407            break;
8408        case 2:
8409            CP0_CHECK(ctx->insn_flags & ASE_MT);
8410            gen_helper_mfc0_tcbind(arg, cpu_env);
8411            register_name = "TCBind";
8412            break;
8413        case 3:
8414            CP0_CHECK(ctx->insn_flags & ASE_MT);
8415            gen_helper_dmfc0_tcrestart(arg, cpu_env);
8416            register_name = "TCRestart";
8417            break;
8418        case 4:
8419            CP0_CHECK(ctx->insn_flags & ASE_MT);
8420            gen_helper_dmfc0_tchalt(arg, cpu_env);
8421            register_name = "TCHalt";
8422            break;
8423        case 5:
8424            CP0_CHECK(ctx->insn_flags & ASE_MT);
8425            gen_helper_dmfc0_tccontext(arg, cpu_env);
8426            register_name = "TCContext";
8427            break;
8428        case 6:
8429            CP0_CHECK(ctx->insn_flags & ASE_MT);
8430            gen_helper_dmfc0_tcschedule(arg, cpu_env);
8431            register_name = "TCSchedule";
8432            break;
8433        case 7:
8434            CP0_CHECK(ctx->insn_flags & ASE_MT);
8435            gen_helper_dmfc0_tcschefback(arg, cpu_env);
8436            register_name = "TCScheFBack";
8437            break;
8438        default:
8439            goto cp0_unimplemented;
8440        }
8441        break;
8442    case CP0_REGISTER_03:
8443        switch (sel) {
8444        case 0:
8445            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryLo1));
8446            register_name = "EntryLo1";
8447            break;
8448        case 1:
8449            CP0_CHECK(ctx->vp);
8450            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_GlobalNumber));
8451            register_name = "GlobalNumber";
8452            break;
8453        default:
8454            goto cp0_unimplemented;
8455        }
8456        break;
8457    case CP0_REGISTER_04:
8458        switch (sel) {
8459        case 0:
8460            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_Context));
8461            register_name = "Context";
8462            break;
8463        case 1:
8464//            gen_helper_dmfc0_contextconfig(arg); /* SmartMIPS ASE */
8465            register_name = "ContextConfig";
8466            goto cp0_unimplemented;
8467        case 2:
8468            CP0_CHECK(ctx->ulri);
8469            tcg_gen_ld_tl(arg, cpu_env,
8470                          offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
8471            register_name = "UserLocal";
8472            break;
8473        default:
8474            goto cp0_unimplemented;
8475        }
8476        break;
8477    case CP0_REGISTER_05:
8478        switch (sel) {
8479        case 0:
8480            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageMask));
8481            register_name = "PageMask";
8482            break;
8483        case 1:
8484            check_insn(ctx, ISA_MIPS32R2);
8485            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageGrain));
8486            register_name = "PageGrain";
8487            break;
8488        case 2:
8489            CP0_CHECK(ctx->sc);
8490            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_SegCtl0));
8491            register_name = "SegCtl0";
8492            break;
8493        case 3:
8494            CP0_CHECK(ctx->sc);
8495            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_SegCtl1));
8496            register_name = "SegCtl1";
8497            break;
8498        case 4:
8499            CP0_CHECK(ctx->sc);
8500            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_SegCtl2));
8501            register_name = "SegCtl2";
8502            break;
8503        case 5:
8504            check_pw(ctx);
8505            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_PWBase));
8506            register_name = "PWBase";
8507            break;
8508        case 6:
8509            check_pw(ctx);
8510            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_PWField));
8511            register_name = "PWField";
8512            break;
8513        case 7:
8514            check_pw(ctx);
8515            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_PWSize));
8516            register_name = "PWSize";
8517            break;
8518        default:
8519            goto cp0_unimplemented;
8520        }
8521        break;
8522    case CP0_REGISTER_06:
8523        switch (sel) {
8524        case 0:
8525            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Wired));
8526            register_name = "Wired";
8527            break;
8528        case 1:
8529            check_insn(ctx, ISA_MIPS32R2);
8530            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf0));
8531            register_name = "SRSConf0";
8532            break;
8533        case 2:
8534            check_insn(ctx, ISA_MIPS32R2);
8535            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf1));
8536            register_name = "SRSConf1";
8537            break;
8538        case 3:
8539            check_insn(ctx, ISA_MIPS32R2);
8540            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf2));
8541            register_name = "SRSConf2";
8542            break;
8543        case 4:
8544            check_insn(ctx, ISA_MIPS32R2);
8545            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf3));
8546            register_name = "SRSConf3";
8547            break;
8548        case 5:
8549            check_insn(ctx, ISA_MIPS32R2);
8550            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf4));
8551            register_name = "SRSConf4";
8552            break;
8553        case 6:
8554            check_pw(ctx);
8555            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PWCtl));
8556            register_name = "PWCtl";
8557            break;
8558        default:
8559            goto cp0_unimplemented;
8560        }
8561        break;
8562    case CP0_REGISTER_07:
8563        switch (sel) {
8564        case 0:
8565            check_insn(ctx, ISA_MIPS32R2);
8566            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_HWREna));
8567            register_name = "HWREna";
8568            break;
8569        default:
8570            goto cp0_unimplemented;
8571        }
8572        break;
8573    case CP0_REGISTER_08:
8574        switch (sel) {
8575        case 0:
8576            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_BadVAddr));
8577            register_name = "BadVAddr";
8578            break;
8579        case 1:
8580            CP0_CHECK(ctx->bi);
8581            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_BadInstr));
8582            register_name = "BadInstr";
8583            break;
8584        case 2:
8585            CP0_CHECK(ctx->bp);
8586            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_BadInstrP));
8587            register_name = "BadInstrP";
8588            break;
8589        case 3:
8590            CP0_CHECK(ctx->bi);
8591            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_BadInstrX));
8592            tcg_gen_andi_tl(arg, arg, ~0xffff);
8593            register_name = "BadInstrX";
8594            break;
8595        default:
8596            goto cp0_unimplemented;
8597        }
8598        break;
8599    case CP0_REGISTER_09:
8600        switch (sel) {
8601        case 0:
8602            /* Mark as an IO operation because we read the time.  */
8603            if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
8604                gen_io_start();
8605            }
8606            gen_helper_mfc0_count(arg, cpu_env);
8607            if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
8608                gen_io_end();
8609            }
8610            /*
8611             * Break the TB to be able to take timer interrupts immediately
8612             * after reading count. DISAS_STOP isn't sufficient, we need to
8613             * ensure we break completely out of translated code.
8614             */
8615            gen_save_pc(ctx->base.pc_next + 4);
8616            ctx->base.is_jmp = DISAS_EXIT;
8617            register_name = "Count";
8618            break;
8619        case 6:
8620            CP0_CHECK(ctx->saar);
8621            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SAARI));
8622            register_name = "SAARI";
8623            break;
8624        case 7:
8625            CP0_CHECK(ctx->saar);
8626            gen_helper_dmfc0_saar(arg, cpu_env);
8627            register_name = "SAAR";
8628            break;
8629        default:
8630            goto cp0_unimplemented;
8631        }
8632        break;
8633    case CP0_REGISTER_10:
8634        switch (sel) {
8635        case 0:
8636            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryHi));
8637            register_name = "EntryHi";
8638            break;
8639        default:
8640            goto cp0_unimplemented;
8641        }
8642        break;
8643    case CP0_REGISTER_11:
8644        switch (sel) {
8645        case 0:
8646            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Compare));
8647            register_name = "Compare";
8648            break;
8649        /* 6,7 are implementation dependent */
8650        default:
8651            goto cp0_unimplemented;
8652        }
8653        break;
8654    case CP0_REGISTER_12:
8655        switch (sel) {
8656        case 0:
8657            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Status));
8658            register_name = "Status";
8659            break;
8660        case 1:
8661            check_insn(ctx, ISA_MIPS32R2);
8662            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_IntCtl));
8663            register_name = "IntCtl";
8664            break;
8665        case 2:
8666            check_insn(ctx, ISA_MIPS32R2);
8667            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSCtl));
8668            register_name = "SRSCtl";
8669            break;
8670        case 3:
8671            check_insn(ctx, ISA_MIPS32R2);
8672            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSMap));
8673            register_name = "SRSMap";
8674            break;
8675        default:
8676            goto cp0_unimplemented;
8677        }
8678        break;
8679    case CP0_REGISTER_13:
8680        switch (sel) {
8681        case 0:
8682            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Cause));
8683            register_name = "Cause";
8684            break;
8685        default:
8686            goto cp0_unimplemented;
8687        }
8688        break;
8689    case CP0_REGISTER_14:
8690        switch (sel) {
8691        case 0:
8692            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EPC));
8693            register_name = "EPC";
8694            break;
8695        default:
8696            goto cp0_unimplemented;
8697        }
8698        break;
8699    case CP0_REGISTER_15:
8700        switch (sel) {
8701        case 0:
8702            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PRid));
8703            register_name = "PRid";
8704            break;
8705        case 1:
8706            check_insn(ctx, ISA_MIPS32R2);
8707            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EBase));
8708            register_name = "EBase";
8709            break;
8710        case 3:
8711            check_insn(ctx, ISA_MIPS32R2);
8712            CP0_CHECK(ctx->cmgcr);
8713            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_CMGCRBase));
8714            register_name = "CMGCRBase";
8715            break;
8716        default:
8717            goto cp0_unimplemented;
8718        }
8719        break;
8720    case CP0_REGISTER_16:
8721        switch (sel) {
8722        case 0:
8723            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config0));
8724            register_name = "Config";
8725            break;
8726        case 1:
8727            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config1));
8728            register_name = "Config1";
8729            break;
8730        case 2:
8731            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config2));
8732            register_name = "Config2";
8733            break;
8734        case 3:
8735            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config3));
8736            register_name = "Config3";
8737            break;
8738        case 4:
8739            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config4));
8740            register_name = "Config4";
8741            break;
8742        case 5:
8743            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config5));
8744            register_name = "Config5";
8745            break;
8746       /* 6,7 are implementation dependent */
8747        case 6:
8748            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config6));
8749            register_name = "Config6";
8750            break;
8751        case 7:
8752            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config7));
8753            register_name = "Config7";
8754            break;
8755        default:
8756            goto cp0_unimplemented;
8757        }
8758        break;
8759    case CP0_REGISTER_17:
8760        switch (sel) {
8761        case 0:
8762            gen_helper_dmfc0_lladdr(arg, cpu_env);
8763            register_name = "LLAddr";
8764            break;
8765        case 1:
8766            CP0_CHECK(ctx->mrp);
8767            gen_helper_dmfc0_maar(arg, cpu_env);
8768            register_name = "MAAR";
8769            break;
8770        case 2:
8771            CP0_CHECK(ctx->mrp);
8772            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_MAARI));
8773            register_name = "MAARI";
8774            break;
8775        default:
8776            goto cp0_unimplemented;
8777        }
8778        break;
8779    case CP0_REGISTER_18:
8780        switch (sel) {
8781        case 0:
8782        case 1:
8783        case 2:
8784        case 3:
8785        case 4:
8786        case 5:
8787        case 6:
8788        case 7:
8789            CP0_CHECK(ctx->CP0_Config1 & (1 << CP0C1_WR));
8790            gen_helper_1e0i(dmfc0_watchlo, arg, sel);
8791            register_name = "WatchLo";
8792            break;
8793        default:
8794            goto cp0_unimplemented;
8795        }
8796        break;
8797    case CP0_REGISTER_19:
8798        switch (sel) {
8799        case 0:
8800        case 1:
8801        case 2:
8802        case 3:
8803        case 4:
8804        case 5:
8805        case 6:
8806        case 7:
8807            CP0_CHECK(ctx->CP0_Config1 & (1 << CP0C1_WR));
8808            gen_helper_1e0i(mfc0_watchhi, arg, sel);
8809            register_name = "WatchHi";
8810            break;
8811        default:
8812            goto cp0_unimplemented;
8813        }
8814        break;
8815    case CP0_REGISTER_20:
8816        switch (sel) {
8817        case 0:
8818            check_insn(ctx, ISA_MIPS3);
8819            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_XContext));
8820            register_name = "XContext";
8821            break;
8822        default:
8823            goto cp0_unimplemented;
8824        }
8825        break;
8826    case CP0_REGISTER_21:
8827       /* Officially reserved, but sel 0 is used for R1x000 framemask */
8828        CP0_CHECK(!(ctx->insn_flags & ISA_MIPS32R6));
8829        switch (sel) {
8830        case 0:
8831            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Framemask));
8832            register_name = "Framemask";
8833            break;
8834        default:
8835            goto cp0_unimplemented;
8836        }
8837        break;
8838    case CP0_REGISTER_22:
8839        tcg_gen_movi_tl(arg, 0); /* unimplemented */
8840        register_name = "'Diagnostic"; /* implementation dependent */
8841        break;
8842    case CP0_REGISTER_23:
8843        switch (sel) {
8844        case 0:
8845            gen_helper_mfc0_debug(arg, cpu_env); /* EJTAG support */
8846            register_name = "Debug";
8847            break;
8848        case 1:
8849//            gen_helper_dmfc0_tracecontrol(arg, cpu_env); /* PDtrace support */
8850            register_name = "TraceControl";
8851            goto cp0_unimplemented;
8852        case 2:
8853//            gen_helper_dmfc0_tracecontrol2(arg, cpu_env); /* PDtrace support */
8854            register_name = "TraceControl2";
8855            goto cp0_unimplemented;
8856        case 3:
8857//            gen_helper_dmfc0_usertracedata(arg, cpu_env); /* PDtrace support */
8858            register_name = "UserTraceData";
8859            goto cp0_unimplemented;
8860        case 4:
8861//            gen_helper_dmfc0_tracebpc(arg, cpu_env); /* PDtrace support */
8862            register_name = "TraceBPC";
8863            goto cp0_unimplemented;
8864        default:
8865            goto cp0_unimplemented;
8866        }
8867        break;
8868    case CP0_REGISTER_24:
8869        switch (sel) {
8870        case 0:
8871            /* EJTAG support */
8872            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_DEPC));
8873            register_name = "DEPC";
8874            break;
8875        default:
8876            goto cp0_unimplemented;
8877        }
8878        break;
8879    case CP0_REGISTER_25:
8880        switch (sel) {
8881        case 0:
8882            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Performance0));
8883            register_name = "Performance0";
8884            break;
8885        case 1:
8886            /* gen_helper_dmfc0_performance1(arg); */
8887            register_name = "Performance1";
8888            goto cp0_unimplemented;
8889        case 2:
8890            /* gen_helper_dmfc0_performance2(arg); */
8891            register_name = "Performance2";
8892            goto cp0_unimplemented;
8893        case 3:
8894            /* gen_helper_dmfc0_performance3(arg); */
8895            register_name = "Performance3";
8896            goto cp0_unimplemented;
8897        case 4:
8898            /* gen_helper_dmfc0_performance4(arg); */
8899            register_name = "Performance4";
8900            goto cp0_unimplemented;
8901        case 5:
8902            /* gen_helper_dmfc0_performance5(arg); */
8903            register_name = "Performance5";
8904            goto cp0_unimplemented;
8905        case 6:
8906            /* gen_helper_dmfc0_performance6(arg); */
8907            register_name = "Performance6";
8908            goto cp0_unimplemented;
8909        case 7:
8910            /* gen_helper_dmfc0_performance7(arg); */
8911            register_name = "Performance7";
8912            goto cp0_unimplemented;
8913        default:
8914            goto cp0_unimplemented;
8915        }
8916        break;
8917    case CP0_REGISTER_26:
8918        switch (sel) {
8919        case 0:
8920            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_ErrCtl));
8921            register_name = "ErrCtl";
8922            break;
8923        default:
8924            goto cp0_unimplemented;
8925        }
8926        break;
8927    case CP0_REGISTER_27:
8928        switch (sel) {
8929        /* ignored */
8930        case 0:
8931        case 1:
8932        case 2:
8933        case 3:
8934            tcg_gen_movi_tl(arg, 0); /* unimplemented */
8935            register_name = "CacheErr";
8936            break;
8937        default:
8938            goto cp0_unimplemented;
8939        }
8940        break;
8941    case CP0_REGISTER_28:
8942        switch (sel) {
8943        case 0:
8944        case 2:
8945        case 4:
8946        case 6:
8947            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_TagLo));
8948            register_name = "TagLo";
8949            break;
8950        case 1:
8951        case 3:
8952        case 5:
8953        case 7:
8954            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataLo));
8955            register_name = "DataLo";
8956            break;
8957        default:
8958            goto cp0_unimplemented;
8959        }
8960        break;
8961    case CP0_REGISTER_29:
8962        switch (sel) {
8963        case 0:
8964        case 2:
8965        case 4:
8966        case 6:
8967            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_TagHi));
8968            register_name = "TagHi";
8969            break;
8970        case 1:
8971        case 3:
8972        case 5:
8973        case 7:
8974            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataHi));
8975            register_name = "DataHi";
8976            break;
8977        default:
8978            goto cp0_unimplemented;
8979        }
8980        break;
8981    case CP0_REGISTER_30:
8982        switch (sel) {
8983        case 0:
8984            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_ErrorEPC));
8985            register_name = "ErrorEPC";
8986            break;
8987        default:
8988            goto cp0_unimplemented;
8989        }
8990        break;
8991    case CP0_REGISTER_31:
8992        switch (sel) {
8993        case 0:
8994            /* EJTAG support */
8995            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DESAVE));
8996            register_name = "DESAVE";
8997            break;
8998        case 2:
8999        case 3:
9000        case 4:
9001        case 5:
9002        case 6:
9003        case 7:
9004            CP0_CHECK(ctx->kscrexist & (1 << sel));
9005            tcg_gen_ld_tl(arg, cpu_env,
9006                          offsetof(CPUMIPSState, CP0_KScratch[sel-2]));
9007            register_name = "KScratch";
9008            break;
9009        default:
9010            goto cp0_unimplemented;
9011        }
9012        break;
9013    default:
9014        goto cp0_unimplemented;
9015    }
9016    trace_mips_translate_c0("dmfc0", register_name, reg, sel);
9017    return;
9018
9019cp0_unimplemented:
9020    qemu_log_mask(LOG_UNIMP, "dmfc0 %s (reg %d sel %d)\n",
9021                  register_name, reg, sel);
9022    gen_mfc0_unimplemented(ctx, arg);
9023}
9024
9025static void gen_dmtc0(DisasContext *ctx, TCGv arg, int reg, int sel)
9026{
9027    const char *register_name = "invalid";
9028
9029    if (sel != 0) {
9030        check_insn(ctx, ISA_MIPS64);
9031    }
9032
9033    if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
9034        gen_io_start();
9035    }
9036
9037    switch (reg) {
9038    case CP0_REGISTER_00:
9039        switch (sel) {
9040        case 0:
9041            gen_helper_mtc0_index(cpu_env, arg);
9042            register_name = "Index";
9043            break;
9044        case 1:
9045            CP0_CHECK(ctx->insn_flags & ASE_MT);
9046            gen_helper_mtc0_mvpcontrol(cpu_env, arg);
9047            register_name = "MVPControl";
9048            break;
9049        case 2:
9050            CP0_CHECK(ctx->insn_flags & ASE_MT);
9051            /* ignored */
9052            register_name = "MVPConf0";
9053            break;
9054        case 3:
9055            CP0_CHECK(ctx->insn_flags & ASE_MT);
9056            /* ignored */
9057            register_name = "MVPConf1";
9058            break;
9059        case 4:
9060            CP0_CHECK(ctx->vp);
9061            /* ignored */
9062            register_name = "VPControl";
9063            break;
9064        default:
9065            goto cp0_unimplemented;
9066        }
9067        break;
9068    case CP0_REGISTER_01:
9069        switch (sel) {
9070        case 0:
9071            /* ignored */
9072            register_name = "Random";
9073            break;
9074        case 1:
9075            CP0_CHECK(ctx->insn_flags & ASE_MT);
9076            gen_helper_mtc0_vpecontrol(cpu_env, arg);
9077            register_name = "VPEControl";
9078            break;
9079        case 2:
9080            CP0_CHECK(ctx->insn_flags & ASE_MT);
9081            gen_helper_mtc0_vpeconf0(cpu_env, arg);
9082            register_name = "VPEConf0";
9083            break;
9084        case 3:
9085            CP0_CHECK(ctx->insn_flags & ASE_MT);
9086            gen_helper_mtc0_vpeconf1(cpu_env, arg);
9087            register_name = "VPEConf1";
9088            break;
9089        case 4:
9090            CP0_CHECK(ctx->insn_flags & ASE_MT);
9091            gen_helper_mtc0_yqmask(cpu_env, arg);
9092            register_name = "YQMask";
9093            break;
9094        case 5:
9095            CP0_CHECK(ctx->insn_flags & ASE_MT);
9096            tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_VPESchedule));
9097            register_name = "VPESchedule";
9098            break;
9099        case 6:
9100            CP0_CHECK(ctx->insn_flags & ASE_MT);
9101            tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_VPEScheFBack));
9102            register_name = "VPEScheFBack";
9103            break;
9104        case 7:
9105            CP0_CHECK(ctx->insn_flags & ASE_MT);
9106            gen_helper_mtc0_vpeopt(cpu_env, arg);
9107            register_name = "VPEOpt";
9108            break;
9109        default:
9110            goto cp0_unimplemented;
9111        }
9112        break;
9113    case CP0_REGISTER_02:
9114        switch (sel) {
9115        case 0:
9116            gen_helper_dmtc0_entrylo0(cpu_env, arg);
9117            register_name = "EntryLo0";
9118            break;
9119        case 1:
9120            CP0_CHECK(ctx->insn_flags & ASE_MT);
9121            gen_helper_mtc0_tcstatus(cpu_env, arg);
9122            register_name = "TCStatus";
9123            break;
9124        case 2:
9125            CP0_CHECK(ctx->insn_flags & ASE_MT);
9126            gen_helper_mtc0_tcbind(cpu_env, arg);
9127            register_name = "TCBind";
9128            break;
9129        case 3:
9130            CP0_CHECK(ctx->insn_flags & ASE_MT);
9131            gen_helper_mtc0_tcrestart(cpu_env, arg);
9132            register_name = "TCRestart";
9133            break;
9134        case 4:
9135            CP0_CHECK(ctx->insn_flags & ASE_MT);
9136            gen_helper_mtc0_tchalt(cpu_env, arg);
9137            register_name = "TCHalt";
9138            break;
9139        case 5:
9140            CP0_CHECK(ctx->insn_flags & ASE_MT);
9141            gen_helper_mtc0_tccontext(cpu_env, arg);
9142            register_name = "TCContext";
9143            break;
9144        case 6:
9145            CP0_CHECK(ctx->insn_flags & ASE_MT);
9146            gen_helper_mtc0_tcschedule(cpu_env, arg);
9147            register_name = "TCSchedule";
9148            break;
9149        case 7:
9150            CP0_CHECK(ctx->insn_flags & ASE_MT);
9151            gen_helper_mtc0_tcschefback(cpu_env, arg);
9152            register_name = "TCScheFBack";
9153            break;
9154        default:
9155            goto cp0_unimplemented;
9156        }
9157        break;
9158    case CP0_REGISTER_03:
9159        switch (sel) {
9160        case 0:
9161            gen_helper_dmtc0_entrylo1(cpu_env, arg);
9162            register_name = "EntryLo1";
9163            break;
9164        case 1:
9165            CP0_CHECK(ctx->vp);
9166            /* ignored */
9167            register_name = "GlobalNumber";
9168            break;
9169        default:
9170            goto cp0_unimplemented;
9171        }
9172        break;
9173    case CP0_REGISTER_04:
9174        switch (sel) {
9175        case 0:
9176            gen_helper_mtc0_context(cpu_env, arg);
9177            register_name = "Context";
9178            break;
9179        case 1:
9180//           gen_helper_mtc0_contextconfig(cpu_env, arg); /* SmartMIPS ASE */
9181            register_name = "ContextConfig";
9182            goto cp0_unimplemented;
9183        case 2:
9184            CP0_CHECK(ctx->ulri);
9185            tcg_gen_st_tl(arg, cpu_env,
9186                          offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
9187            register_name = "UserLocal";
9188            break;
9189        default:
9190            goto cp0_unimplemented;
9191        }
9192        break;
9193    case CP0_REGISTER_05:
9194        switch (sel) {
9195        case 0:
9196            gen_helper_mtc0_pagemask(cpu_env, arg);
9197            register_name = "PageMask";
9198            break;
9199        case 1:
9200            check_insn(ctx, ISA_MIPS32R2);
9201            gen_helper_mtc0_pagegrain(cpu_env, arg);
9202            register_name = "PageGrain";
9203            break;
9204        case 2:
9205            CP0_CHECK(ctx->sc);
9206            gen_helper_mtc0_segctl0(cpu_env, arg);
9207            register_name = "SegCtl0";
9208            break;
9209        case 3:
9210            CP0_CHECK(ctx->sc);
9211            gen_helper_mtc0_segctl1(cpu_env, arg);
9212            register_name = "SegCtl1";
9213            break;
9214        case 4:
9215            CP0_CHECK(ctx->sc);
9216            gen_helper_mtc0_segctl2(cpu_env, arg);
9217            register_name = "SegCtl2";
9218            break;
9219        case 5:
9220            check_pw(ctx);
9221            tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_PWBase));
9222            register_name = "PWBase";
9223            break;
9224        case 6:
9225            check_pw(ctx);
9226            gen_helper_mtc0_pwfield(cpu_env, arg);
9227            register_name = "PWField";
9228            break;
9229        case 7:
9230            check_pw(ctx);
9231            gen_helper_mtc0_pwsize(cpu_env, arg);
9232            register_name = "PWSize";
9233            break;
9234        default:
9235            goto cp0_unimplemented;
9236        }
9237        break;
9238    case CP0_REGISTER_06:
9239        switch (sel) {
9240        case 0:
9241            gen_helper_mtc0_wired(cpu_env, arg);
9242            register_name = "Wired";
9243            break;
9244        case 1:
9245            check_insn(ctx, ISA_MIPS32R2);
9246            gen_helper_mtc0_srsconf0(cpu_env, arg);
9247            register_name = "SRSConf0";
9248            break;
9249        case 2:
9250            check_insn(ctx, ISA_MIPS32R2);
9251            gen_helper_mtc0_srsconf1(cpu_env, arg);
9252            register_name = "SRSConf1";
9253            break;
9254        case 3:
9255            check_insn(ctx, ISA_MIPS32R2);
9256            gen_helper_mtc0_srsconf2(cpu_env, arg);
9257            register_name = "SRSConf2";
9258            break;
9259        case 4:
9260            check_insn(ctx, ISA_MIPS32R2);
9261            gen_helper_mtc0_srsconf3(cpu_env, arg);
9262            register_name = "SRSConf3";
9263            break;
9264        case 5:
9265            check_insn(ctx, ISA_MIPS32R2);
9266            gen_helper_mtc0_srsconf4(cpu_env, arg);
9267            register_name = "SRSConf4";
9268            break;
9269        case 6:
9270            check_pw(ctx);
9271            gen_helper_mtc0_pwctl(cpu_env, arg);
9272            register_name = "PWCtl";
9273            break;
9274        default:
9275            goto cp0_unimplemented;
9276        }
9277        break;
9278    case CP0_REGISTER_07:
9279        switch (sel) {
9280        case 0:
9281            check_insn(ctx, ISA_MIPS32R2);
9282            gen_helper_mtc0_hwrena(cpu_env, arg);
9283            ctx->base.is_jmp = DISAS_STOP;
9284            register_name = "HWREna";
9285            break;
9286        default:
9287            goto cp0_unimplemented;
9288        }
9289        break;
9290    case CP0_REGISTER_08:
9291        switch (sel) {
9292        case 0:
9293            /* ignored */
9294            register_name = "BadVAddr";
9295            break;
9296        case 1:
9297            /* ignored */
9298            register_name = "BadInstr";
9299            break;
9300        case 2:
9301            /* ignored */
9302            register_name = "BadInstrP";
9303            break;
9304        case 3:
9305            /* ignored */
9306            register_name = "BadInstrX";
9307            break;
9308        default:
9309            goto cp0_unimplemented;
9310        }
9311        break;
9312    case CP0_REGISTER_09:
9313        switch (sel) {
9314        case 0:
9315            gen_helper_mtc0_count(cpu_env, arg);
9316            register_name = "Count";
9317            break;
9318        case 6:
9319            CP0_CHECK(ctx->saar);
9320            gen_helper_mtc0_saari(cpu_env, arg);
9321            register_name = "SAARI";
9322            break;
9323        case 7:
9324            CP0_CHECK(ctx->saar);
9325            gen_helper_mtc0_saar(cpu_env, arg);
9326            register_name = "SAAR";
9327            break;
9328        default:
9329            goto cp0_unimplemented;
9330        }
9331        /* Stop translation as we may have switched the execution mode */
9332        ctx->base.is_jmp = DISAS_STOP;
9333        break;
9334    case CP0_REGISTER_10:
9335        switch (sel) {
9336        case 0:
9337            gen_helper_mtc0_entryhi(cpu_env, arg);
9338            register_name = "EntryHi";
9339            break;
9340        default:
9341            goto cp0_unimplemented;
9342        }
9343        break;
9344    case CP0_REGISTER_11:
9345        switch (sel) {
9346        case 0:
9347            gen_helper_mtc0_compare(cpu_env, arg);
9348            register_name = "Compare";
9349            break;
9350        /* 6,7 are implementation dependent */
9351        default:
9352            goto cp0_unimplemented;
9353        }
9354        /* Stop translation as we may have switched the execution mode */
9355        ctx->base.is_jmp = DISAS_STOP;
9356        break;
9357    case CP0_REGISTER_12:
9358        switch (sel) {
9359        case 0:
9360            save_cpu_state(ctx, 1);
9361            gen_helper_mtc0_status(cpu_env, arg);
9362            /* DISAS_STOP isn't good enough here, hflags may have changed. */
9363            gen_save_pc(ctx->base.pc_next + 4);
9364            ctx->base.is_jmp = DISAS_EXIT;
9365            register_name = "Status";
9366            break;
9367        case 1:
9368            check_insn(ctx, ISA_MIPS32R2);
9369            gen_helper_mtc0_intctl(cpu_env, arg);
9370            /* Stop translation as we may have switched the execution mode */
9371            ctx->base.is_jmp = DISAS_STOP;
9372            register_name = "IntCtl";
9373            break;
9374        case 2:
9375            check_insn(ctx, ISA_MIPS32R2);
9376            gen_helper_mtc0_srsctl(cpu_env, arg);
9377            /* Stop translation as we may have switched the execution mode */
9378            ctx->base.is_jmp = DISAS_STOP;
9379            register_name = "SRSCtl";
9380            break;
9381        case 3:
9382            check_insn(ctx, ISA_MIPS32R2);
9383            gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_SRSMap));
9384            /* Stop translation as we may have switched the execution mode */
9385            ctx->base.is_jmp = DISAS_STOP;
9386            register_name = "SRSMap";
9387            break;
9388        default:
9389            goto cp0_unimplemented;
9390        }
9391        break;
9392    case CP0_REGISTER_13:
9393        switch (sel) {
9394        case 0:
9395            save_cpu_state(ctx, 1);
9396            gen_helper_mtc0_cause(cpu_env, arg);
9397            /*
9398             * Stop translation as we may have triggered an interrupt.
9399             * DISAS_STOP isn't sufficient, we need to ensure we break out of
9400             * translated code to check for pending interrupts.
9401             */
9402            gen_save_pc(ctx->base.pc_next + 4);
9403            ctx->base.is_jmp = DISAS_EXIT;
9404            register_name = "Cause";
9405            break;
9406        default:
9407            goto cp0_unimplemented;
9408        }
9409        break;
9410    case CP0_REGISTER_14:
9411        switch (sel) {
9412        case 0:
9413            tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EPC));
9414            register_name = "EPC";
9415            break;
9416        default:
9417            goto cp0_unimplemented;
9418        }
9419        break;
9420    case CP0_REGISTER_15:
9421        switch (sel) {
9422        case 0:
9423            /* ignored */
9424            register_name = "PRid";
9425            break;
9426        case 1:
9427            check_insn(ctx, ISA_MIPS32R2);
9428            gen_helper_mtc0_ebase(cpu_env, arg);
9429            register_name = "EBase";
9430            break;
9431        default:
9432            goto cp0_unimplemented;
9433        }
9434        break;
9435    case CP0_REGISTER_16:
9436        switch (sel) {
9437        case 0:
9438            gen_helper_mtc0_config0(cpu_env, arg);
9439            register_name = "Config";
9440            /* Stop translation as we may have switched the execution mode */
9441            ctx->base.is_jmp = DISAS_STOP;
9442            break;
9443        case 1:
9444            /* ignored, read only */
9445            register_name = "Config1";
9446            break;
9447        case 2:
9448            gen_helper_mtc0_config2(cpu_env, arg);
9449            register_name = "Config2";
9450            /* Stop translation as we may have switched the execution mode */
9451            ctx->base.is_jmp = DISAS_STOP;
9452            break;
9453        case 3:
9454            gen_helper_mtc0_config3(cpu_env, arg);
9455            register_name = "Config3";
9456            /* Stop translation as we may have switched the execution mode */
9457            ctx->base.is_jmp = DISAS_STOP;
9458            break;
9459        case 4:
9460            /* currently ignored */
9461            register_name = "Config4";
9462            break;
9463        case 5:
9464            gen_helper_mtc0_config5(cpu_env, arg);
9465            register_name = "Config5";
9466            /* Stop translation as we may have switched the execution mode */
9467            ctx->base.is_jmp = DISAS_STOP;
9468            break;
9469        /* 6,7 are implementation dependent */
9470        default:
9471            register_name = "Invalid config selector";
9472            goto cp0_unimplemented;
9473        }
9474        break;
9475    case CP0_REGISTER_17:
9476        switch (sel) {
9477        case 0:
9478            gen_helper_mtc0_lladdr(cpu_env, arg);
9479            register_name = "LLAddr";
9480            break;
9481        case 1:
9482            CP0_CHECK(ctx->mrp);
9483            gen_helper_mtc0_maar(cpu_env, arg);
9484            register_name = "MAAR";
9485            break;
9486        case 2:
9487            CP0_CHECK(ctx->mrp);
9488            gen_helper_mtc0_maari(cpu_env, arg);
9489            register_name = "MAARI";
9490            break;
9491        default:
9492            goto cp0_unimplemented;
9493        }
9494        break;
9495    case CP0_REGISTER_18:
9496        switch (sel) {
9497        case 0:
9498        case 1:
9499        case 2:
9500        case 3:
9501        case 4:
9502        case 5:
9503        case 6:
9504        case 7:
9505            CP0_CHECK(ctx->CP0_Config1 & (1 << CP0C1_WR));
9506            gen_helper_0e1i(mtc0_watchlo, arg, sel);
9507            register_name = "WatchLo";
9508            break;
9509        default:
9510            goto cp0_unimplemented;
9511        }
9512        break;
9513    case CP0_REGISTER_19:
9514        switch (sel) {
9515        case 0:
9516        case 1:
9517        case 2:
9518        case 3:
9519        case 4:
9520        case 5:
9521        case 6:
9522        case 7:
9523            CP0_CHECK(ctx->CP0_Config1 & (1 << CP0C1_WR));
9524            gen_helper_0e1i(mtc0_watchhi, arg, sel);
9525            register_name = "WatchHi";
9526            break;
9527        default:
9528            goto cp0_unimplemented;
9529        }
9530        break;
9531    case CP0_REGISTER_20:
9532        switch (sel) {
9533        case 0:
9534            check_insn(ctx, ISA_MIPS3);
9535            gen_helper_mtc0_xcontext(cpu_env, arg);
9536            register_name = "XContext";
9537            break;
9538        default:
9539            goto cp0_unimplemented;
9540        }
9541        break;
9542    case CP0_REGISTER_21:
9543       /* Officially reserved, but sel 0 is used for R1x000 framemask */
9544        CP0_CHECK(!(ctx->insn_flags & ISA_MIPS32R6));
9545        switch (sel) {
9546        case 0:
9547            gen_helper_mtc0_framemask(cpu_env, arg);
9548            register_name = "Framemask";
9549            break;
9550        default:
9551            goto cp0_unimplemented;
9552        }
9553        break;
9554    case CP0_REGISTER_22:
9555        /* ignored */
9556        register_name = "Diagnostic"; /* implementation dependent */
9557        break;
9558    case CP0_REGISTER_23:
9559        switch (sel) {
9560        case 0:
9561            gen_helper_mtc0_debug(cpu_env, arg); /* EJTAG support */
9562            /* DISAS_STOP isn't good enough here, hflags may have changed. */
9563            gen_save_pc(ctx->base.pc_next + 4);
9564            ctx->base.is_jmp = DISAS_EXIT;
9565            register_name = "Debug";
9566            break;
9567        case 1:
9568//            gen_helper_mtc0_tracecontrol(cpu_env, arg); /* PDtrace support */
9569            /* Stop translation as we may have switched the execution mode */
9570            ctx->base.is_jmp = DISAS_STOP;
9571            register_name = "TraceControl";
9572            goto cp0_unimplemented;
9573        case 2:
9574//            gen_helper_mtc0_tracecontrol2(cpu_env, arg); /* PDtrace support */
9575            /* Stop translation as we may have switched the execution mode */
9576            ctx->base.is_jmp = DISAS_STOP;
9577            register_name = "TraceControl2";
9578            goto cp0_unimplemented;
9579        case 3:
9580//            gen_helper_mtc0_usertracedata(cpu_env, arg); /* PDtrace support */
9581            /* Stop translation as we may have switched the execution mode */
9582            ctx->base.is_jmp = DISAS_STOP;
9583            register_name = "UserTraceData";
9584            goto cp0_unimplemented;
9585        case 4:
9586//            gen_helper_mtc0_tracebpc(cpu_env, arg); /* PDtrace support */
9587            /* Stop translation as we may have switched the execution mode */
9588            ctx->base.is_jmp = DISAS_STOP;
9589            register_name = "TraceBPC";
9590            goto cp0_unimplemented;
9591        default:
9592            goto cp0_unimplemented;
9593        }
9594        break;
9595    case CP0_REGISTER_24:
9596        switch (sel) {
9597        case 0:
9598            /* EJTAG support */
9599            tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_DEPC));
9600            register_name = "DEPC";
9601            break;
9602        default:
9603            goto cp0_unimplemented;
9604        }
9605        break;
9606    case CP0_REGISTER_25:
9607        switch (sel) {
9608        case 0:
9609            gen_helper_mtc0_performance0(cpu_env, arg);
9610            register_name = "Performance0";
9611            break;
9612        case 1:
9613            /* gen_helper_mtc0_performance1(cpu_env, arg); */
9614            register_name = "Performance1";
9615            goto cp0_unimplemented;
9616        case 2:
9617            /* gen_helper_mtc0_performance2(cpu_env, arg); */
9618            register_name = "Performance2";
9619            goto cp0_unimplemented;
9620        case 3:
9621            /* gen_helper_mtc0_performance3(cpu_env, arg); */
9622            register_name = "Performance3";
9623            goto cp0_unimplemented;
9624        case 4:
9625            /* gen_helper_mtc0_performance4(cpu_env, arg); */
9626            register_name = "Performance4";
9627            goto cp0_unimplemented;
9628        case 5:
9629            /* gen_helper_mtc0_performance5(cpu_env, arg); */
9630            register_name = "Performance5";
9631            goto cp0_unimplemented;
9632        case 6:
9633            /* gen_helper_mtc0_performance6(cpu_env, arg); */
9634            register_name = "Performance6";
9635            goto cp0_unimplemented;
9636        case 7:
9637            /* gen_helper_mtc0_performance7(cpu_env, arg); */
9638            register_name = "Performance7";
9639            goto cp0_unimplemented;
9640        default:
9641            goto cp0_unimplemented;
9642        }
9643        break;
9644    case CP0_REGISTER_26:
9645        switch (sel) {
9646        case 0:
9647            gen_helper_mtc0_errctl(cpu_env, arg);
9648            ctx->base.is_jmp = DISAS_STOP;
9649            register_name = "ErrCtl";
9650            break;
9651        default:
9652            goto cp0_unimplemented;
9653        }
9654        break;
9655    case CP0_REGISTER_27:
9656        switch (sel) {
9657        case 0:
9658        case 1:
9659        case 2:
9660        case 3:
9661            /* ignored */
9662            register_name = "CacheErr";
9663            break;
9664        default:
9665            goto cp0_unimplemented;
9666        }
9667        break;
9668    case CP0_REGISTER_28:
9669        switch (sel) {
9670        case 0:
9671        case 2:
9672        case 4:
9673        case 6:
9674            gen_helper_mtc0_taglo(cpu_env, arg);
9675            register_name = "TagLo";
9676            break;
9677        case 1:
9678        case 3:
9679        case 5:
9680        case 7:
9681            gen_helper_mtc0_datalo(cpu_env, arg);
9682            register_name = "DataLo";
9683            break;
9684        default:
9685            goto cp0_unimplemented;
9686        }
9687        break;
9688    case CP0_REGISTER_29:
9689        switch (sel) {
9690        case 0:
9691        case 2:
9692        case 4:
9693        case 6:
9694            gen_helper_mtc0_taghi(cpu_env, arg);
9695            register_name = "TagHi";
9696            break;
9697        case 1:
9698        case 3:
9699        case 5:
9700        case 7:
9701            gen_helper_mtc0_datahi(cpu_env, arg);
9702            register_name = "DataHi";
9703            break;
9704        default:
9705            register_name = "invalid sel";
9706            goto cp0_unimplemented;
9707        }
9708        break;
9709    case CP0_REGISTER_30:
9710        switch (sel) {
9711        case 0:
9712            tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_ErrorEPC));
9713            register_name = "ErrorEPC";
9714            break;
9715        default:
9716            goto cp0_unimplemented;
9717        }
9718        break;
9719    case CP0_REGISTER_31:
9720        switch (sel) {
9721        case 0:
9722            /* EJTAG support */
9723            gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_DESAVE));
9724            register_name = "DESAVE";
9725            break;
9726        case 2:
9727        case 3:
9728        case 4:
9729        case 5:
9730        case 6:
9731        case 7:
9732            CP0_CHECK(ctx->kscrexist & (1 << sel));
9733            tcg_gen_st_tl(arg, cpu_env,
9734                          offsetof(CPUMIPSState, CP0_KScratch[sel-2]));
9735            register_name = "KScratch";
9736            break;
9737        default:
9738            goto cp0_unimplemented;
9739        }
9740        break;
9741    default:
9742        goto cp0_unimplemented;
9743    }
9744    trace_mips_translate_c0("dmtc0", register_name, reg, sel);
9745
9746    /* For simplicity assume that all writes can cause interrupts.  */
9747    if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
9748        gen_io_end();
9749        /*
9750         * DISAS_STOP isn't sufficient, we need to ensure we break out of
9751         * translated code to check for pending interrupts.
9752         */
9753        gen_save_pc(ctx->base.pc_next + 4);
9754        ctx->base.is_jmp = DISAS_EXIT;
9755    }
9756    return;
9757
9758cp0_unimplemented:
9759    qemu_log_mask(LOG_UNIMP, "dmtc0 %s (reg %d sel %d)\n",
9760                  register_name, reg, sel);
9761}
9762#endif /* TARGET_MIPS64 */
9763
9764static void gen_mftr(CPUMIPSState *env, DisasContext *ctx, int rt, int rd,
9765                     int u, int sel, int h)
9766{
9767    int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
9768    TCGv t0 = tcg_temp_local_new();
9769
9770    if ((env->CP0_VPEConf0 & (1 << CP0VPEC0_MVP)) == 0 &&
9771        ((env->tcs[other_tc].CP0_TCBind & (0xf << CP0TCBd_CurVPE)) !=
9772         (env->active_tc.CP0_TCBind & (0xf << CP0TCBd_CurVPE)))) {
9773        tcg_gen_movi_tl(t0, -1);
9774    } else if ((env->CP0_VPEControl & (0xff << CP0VPECo_TargTC)) >
9775               (env->mvp->CP0_MVPConf0 & (0xff << CP0MVPC0_PTC))) {
9776        tcg_gen_movi_tl(t0, -1);
9777    } else if (u == 0) {
9778        switch (rt) {
9779        case 1:
9780            switch (sel) {
9781            case 1:
9782                gen_helper_mftc0_vpecontrol(t0, cpu_env);
9783                break;
9784            case 2:
9785                gen_helper_mftc0_vpeconf0(t0, cpu_env);
9786                break;
9787            default:
9788                goto die;
9789                break;
9790            }
9791            break;
9792        case 2:
9793            switch (sel) {
9794            case 1:
9795                gen_helper_mftc0_tcstatus(t0, cpu_env);
9796                break;
9797            case 2:
9798                gen_helper_mftc0_tcbind(t0, cpu_env);
9799                break;
9800            case 3:
9801                gen_helper_mftc0_tcrestart(t0, cpu_env);
9802                break;
9803            case 4:
9804                gen_helper_mftc0_tchalt(t0, cpu_env);
9805                break;
9806            case 5:
9807                gen_helper_mftc0_tccontext(t0, cpu_env);
9808                break;
9809            case 6:
9810                gen_helper_mftc0_tcschedule(t0, cpu_env);
9811                break;
9812            case 7:
9813                gen_helper_mftc0_tcschefback(t0, cpu_env);
9814                break;
9815            default:
9816                gen_mfc0(ctx, t0, rt, sel);
9817                break;
9818            }
9819            break;
9820        case 10:
9821            switch (sel) {
9822            case 0:
9823                gen_helper_mftc0_entryhi(t0, cpu_env);
9824                break;
9825            default:
9826                gen_mfc0(ctx, t0, rt, sel);
9827                break;
9828            }
9829            break;
9830        case 12:
9831            switch (sel) {
9832            case 0:
9833                gen_helper_mftc0_status(t0, cpu_env);
9834                break;
9835            default:
9836                gen_mfc0(ctx, t0, rt, sel);
9837                break;
9838            }
9839            break;
9840        case 13:
9841            switch (sel) {
9842            case 0:
9843                gen_helper_mftc0_cause(t0, cpu_env);
9844                break;
9845            default:
9846                goto die;
9847                break;
9848            }
9849            break;
9850        case 14:
9851            switch (sel) {
9852            case 0:
9853                gen_helper_mftc0_epc(t0, cpu_env);
9854                break;
9855            default:
9856                goto die;
9857                break;
9858            }
9859            break;
9860        case 15:
9861            switch (sel) {
9862            case 1:
9863                gen_helper_mftc0_ebase(t0, cpu_env);
9864                break;
9865            default:
9866                goto die;
9867                break;
9868            }
9869            break;
9870        case 16:
9871            switch (sel) {
9872            case 0:
9873            case 1:
9874            case 2:
9875            case 3:
9876            case 4:
9877            case 5:
9878            case 6:
9879            case 7:
9880                gen_helper_mftc0_configx(t0, cpu_env, tcg_const_tl(sel));
9881                break;
9882            default:
9883                goto die;
9884                break;
9885            }
9886            break;
9887        case 23:
9888            switch (sel) {
9889            case 0:
9890                gen_helper_mftc0_debug(t0, cpu_env);
9891                break;
9892            default:
9893                gen_mfc0(ctx, t0, rt, sel);
9894                break;
9895            }
9896            break;
9897        default:
9898            gen_mfc0(ctx, t0, rt, sel);
9899        }
9900    } else switch (sel) {
9901    /* GPR registers. */
9902    case 0:
9903        gen_helper_1e0i(mftgpr, t0, rt);
9904        break;
9905    /* Auxiliary CPU registers */
9906    case 1:
9907        switch (rt) {
9908        case 0:
9909            gen_helper_1e0i(mftlo, t0, 0);
9910            break;
9911        case 1:
9912            gen_helper_1e0i(mfthi, t0, 0);
9913            break;
9914        case 2:
9915            gen_helper_1e0i(mftacx, t0, 0);
9916            break;
9917        case 4:
9918            gen_helper_1e0i(mftlo, t0, 1);
9919            break;
9920        case 5:
9921            gen_helper_1e0i(mfthi, t0, 1);
9922            break;
9923        case 6:
9924            gen_helper_1e0i(mftacx, t0, 1);
9925            break;
9926        case 8:
9927            gen_helper_1e0i(mftlo, t0, 2);
9928            break;
9929        case 9:
9930            gen_helper_1e0i(mfthi, t0, 2);
9931            break;
9932        case 10:
9933            gen_helper_1e0i(mftacx, t0, 2);
9934            break;
9935        case 12:
9936            gen_helper_1e0i(mftlo, t0, 3);
9937            break;
9938        case 13:
9939            gen_helper_1e0i(mfthi, t0, 3);
9940            break;
9941        case 14:
9942            gen_helper_1e0i(mftacx, t0, 3);
9943            break;
9944        case 16:
9945            gen_helper_mftdsp(t0, cpu_env);
9946            break;
9947        default:
9948            goto die;
9949        }
9950        break;
9951    /* Floating point (COP1). */
9952    case 2:
9953        /* XXX: For now we support only a single FPU context. */
9954        if (h == 0) {
9955            TCGv_i32 fp0 = tcg_temp_new_i32();
9956
9957            gen_load_fpr32(ctx, fp0, rt);
9958            tcg_gen_ext_i32_tl(t0, fp0);
9959            tcg_temp_free_i32(fp0);
9960        } else {
9961            TCGv_i32 fp0 = tcg_temp_new_i32();
9962
9963            gen_load_fpr32h(ctx, fp0, rt);
9964            tcg_gen_ext_i32_tl(t0, fp0);
9965            tcg_temp_free_i32(fp0);
9966        }
9967        break;
9968    case 3:
9969        /* XXX: For now we support only a single FPU context. */
9970        gen_helper_1e0i(cfc1, t0, rt);
9971        break;
9972    /* COP2: Not implemented. */
9973    case 4:
9974    case 5:
9975        /* fall through */
9976    default:
9977        goto die;
9978    }
9979    trace_mips_translate_tr("mftr", rt, u, sel, h);
9980    gen_store_gpr(t0, rd);
9981    tcg_temp_free(t0);
9982    return;
9983
9984die:
9985    tcg_temp_free(t0);
9986    LOG_DISAS("mftr (reg %d u %d sel %d h %d)\n", rt, u, sel, h);
9987    generate_exception_end(ctx, EXCP_RI);
9988}
9989
9990static void gen_mttr(CPUMIPSState *env, DisasContext *ctx, int rd, int rt,
9991                     int u, int sel, int h)
9992{
9993    int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
9994    TCGv t0 = tcg_temp_local_new();
9995
9996    gen_load_gpr(t0, rt);
9997    if ((env->CP0_VPEConf0 & (1 << CP0VPEC0_MVP)) == 0 &&
9998        ((env->tcs[other_tc].CP0_TCBind & (0xf << CP0TCBd_CurVPE)) !=
9999         (env->active_tc.CP0_TCBind & (0xf << CP0TCBd_CurVPE)))) {
10000        /* NOP */
10001        ;
10002    } else if ((env->CP0_VPEControl & (0xff << CP0VPECo_TargTC)) >
10003             (env->mvp->CP0_MVPConf0 & (0xff << CP0MVPC0_PTC))) {
10004        /* NOP */
10005        ;
10006    } else if (u == 0) {
10007        switch (rd) {
10008        case 1:
10009            switch (sel) {
10010            case 1:
10011                gen_helper_mttc0_vpecontrol(cpu_env, t0);
10012                break;
10013            case 2:
10014                gen_helper_mttc0_vpeconf0(cpu_env, t0);
10015                break;
10016            default:
10017                goto die;
10018                break;
10019            }
10020            break;
10021        case 2:
10022            switch (sel) {
10023            case 1:
10024                gen_helper_mttc0_tcstatus(cpu_env, t0);
10025                break;
10026            case 2:
10027                gen_helper_mttc0_tcbind(cpu_env, t0);
10028                break;
10029            case 3:
10030                gen_helper_mttc0_tcrestart(cpu_env, t0);
10031                break;
10032            case 4:
10033                gen_helper_mttc0_tchalt(cpu_env, t0);
10034                break;
10035            case 5:
10036                gen_helper_mttc0_tccontext(cpu_env, t0);
10037                break;
10038            case 6:
10039                gen_helper_mttc0_tcschedule(cpu_env, t0);
10040                break;
10041            case 7:
10042                gen_helper_mttc0_tcschefback(cpu_env, t0);
10043                break;
10044            default:
10045                gen_mtc0(ctx, t0, rd, sel);
10046                break;
10047            }
10048            break;
10049        case 10:
10050            switch (sel) {
10051            case 0:
10052                gen_helper_mttc0_entryhi(cpu_env, t0);
10053                break;
10054            default:
10055                gen_mtc0(ctx, t0, rd, sel);
10056                break;
10057            }
10058            break;
10059        case 12:
10060            switch (sel) {
10061            case 0:
10062                gen_helper_mttc0_status(cpu_env, t0);
10063                break;
10064            default:
10065                gen_mtc0(ctx, t0, rd, sel);
10066                break;
10067            }
10068            break;
10069        case 13:
10070            switch (sel) {
10071            case 0:
10072                gen_helper_mttc0_cause(cpu_env, t0);
10073                break;
10074            default:
10075                goto die;
10076                break;
10077            }
10078            break;
10079        case 15:
10080            switch (sel) {
10081            case 1:
10082                gen_helper_mttc0_ebase(cpu_env, t0);
10083                break;
10084            default:
10085                goto die;
10086                break;
10087            }
10088            break;
10089        case 23:
10090            switch (sel) {
10091            case 0:
10092                gen_helper_mttc0_debug(cpu_env, t0);
10093                break;
10094            default:
10095                gen_mtc0(ctx, t0, rd, sel);
10096                break;
10097            }
10098            break;
10099        default:
10100            gen_mtc0(ctx, t0, rd, sel);
10101        }
10102    } else switch (sel) {
10103    /* GPR registers. */
10104    case 0:
10105        gen_helper_0e1i(mttgpr, t0, rd);
10106        break;
10107    /* Auxiliary CPU registers */
10108    case 1:
10109        switch (rd) {
10110        case 0:
10111            gen_helper_0e1i(mttlo, t0, 0);
10112            break;
10113        case 1:
10114            gen_helper_0e1i(mtthi, t0, 0);
10115            break;
10116        case 2:
10117            gen_helper_0e1i(mttacx, t0, 0);
10118            break;
10119        case 4:
10120            gen_helper_0e1i(mttlo, t0, 1);
10121            break;
10122        case 5:
10123            gen_helper_0e1i(mtthi, t0, 1);
10124            break;
10125        case 6:
10126            gen_helper_0e1i(mttacx, t0, 1);
10127            break;
10128        case 8:
10129            gen_helper_0e1i(mttlo, t0, 2);
10130            break;
10131        case 9:
10132            gen_helper_0e1i(mtthi, t0, 2);
10133            break;
10134        case 10:
10135            gen_helper_0e1i(mttacx, t0, 2);
10136            break;
10137        case 12:
10138            gen_helper_0e1i(mttlo, t0, 3);
10139            break;
10140        case 13:
10141            gen_helper_0e1i(mtthi, t0, 3);
10142            break;
10143        case 14:
10144            gen_helper_0e1i(mttacx, t0, 3);
10145            break;
10146        case 16:
10147            gen_helper_mttdsp(cpu_env, t0);
10148            break;
10149        default:
10150            goto die;
10151        }
10152        break;
10153    /* Floating point (COP1). */
10154    case 2:
10155        /* XXX: For now we support only a single FPU context. */
10156        if (h == 0) {
10157            TCGv_i32 fp0 = tcg_temp_new_i32();
10158
10159            tcg_gen_trunc_tl_i32(fp0, t0);
10160            gen_store_fpr32(ctx, fp0, rd);
10161            tcg_temp_free_i32(fp0);
10162        } else {
10163            TCGv_i32 fp0 = tcg_temp_new_i32();
10164
10165            tcg_gen_trunc_tl_i32(fp0, t0);
10166            gen_store_fpr32h(ctx, fp0, rd);
10167            tcg_temp_free_i32(fp0);
10168        }
10169        break;
10170    case 3:
10171        /* XXX: For now we support only a single FPU context. */
10172        {
10173            TCGv_i32 fs_tmp = tcg_const_i32(rd);
10174
10175            gen_helper_0e2i(ctc1, t0, fs_tmp, rt);
10176            tcg_temp_free_i32(fs_tmp);
10177        }
10178        /* Stop translation as we may have changed hflags */
10179        ctx->base.is_jmp = DISAS_STOP;
10180        break;
10181    /* COP2: Not implemented. */
10182    case 4:
10183    case 5:
10184        /* fall through */
10185    default:
10186        goto die;
10187    }
10188    trace_mips_translate_tr("mttr", rd, u, sel, h);
10189    tcg_temp_free(t0);
10190    return;
10191
10192die:
10193    tcg_temp_free(t0);
10194    LOG_DISAS("mttr (reg %d u %d sel %d h %d)\n", rd, u, sel, h);
10195    generate_exception_end(ctx, EXCP_RI);
10196}
10197
10198static void gen_cp0(CPUMIPSState *env, DisasContext *ctx, uint32_t opc,
10199                    int rt, int rd)
10200{
10201    const char *opn = "ldst";
10202
10203    check_cp0_enabled(ctx);
10204    switch (opc) {
10205    case OPC_MFC0:
10206        if (rt == 0) {
10207            /* Treat as NOP. */
10208            return;
10209        }
10210        gen_mfc0(ctx, cpu_gpr[rt], rd, ctx->opcode & 0x7);
10211        opn = "mfc0";
10212        break;
10213    case OPC_MTC0:
10214        {
10215            TCGv t0 = tcg_temp_new();
10216
10217            gen_load_gpr(t0, rt);
10218            gen_mtc0(ctx, t0, rd, ctx->opcode & 0x7);
10219            tcg_temp_free(t0);
10220        }
10221        opn = "mtc0";
10222        break;
10223#if defined(TARGET_MIPS64)
10224    case OPC_DMFC0:
10225        check_insn(ctx, ISA_MIPS3);
10226        if (rt == 0) {
10227            /* Treat as NOP. */
10228            return;
10229        }
10230        gen_dmfc0(ctx, cpu_gpr[rt], rd, ctx->opcode & 0x7);
10231        opn = "dmfc0";
10232        break;
10233    case OPC_DMTC0:
10234        check_insn(ctx, ISA_MIPS3);
10235        {
10236            TCGv t0 = tcg_temp_new();
10237
10238            gen_load_gpr(t0, rt);
10239            gen_dmtc0(ctx, t0, rd, ctx->opcode & 0x7);
10240            tcg_temp_free(t0);
10241        }
10242        opn = "dmtc0";
10243        break;
10244#endif
10245    case OPC_MFHC0:
10246        check_mvh(ctx);
10247        if (rt == 0) {
10248            /* Treat as NOP. */
10249            return;
10250        }
10251        gen_mfhc0(ctx, cpu_gpr[rt], rd, ctx->opcode & 0x7);
10252        opn = "mfhc0";
10253        break;
10254    case OPC_MTHC0:
10255        check_mvh(ctx);
10256        {
10257            TCGv t0 = tcg_temp_new();
10258            gen_load_gpr(t0, rt);
10259            gen_mthc0(ctx, t0, rd, ctx->opcode & 0x7);
10260            tcg_temp_free(t0);
10261        }
10262        opn = "mthc0";
10263        break;
10264    case OPC_MFTR:
10265        check_cp0_enabled(ctx);
10266        if (rd == 0) {
10267            /* Treat as NOP. */
10268            return;
10269        }
10270        gen_mftr(env, ctx, rt, rd, (ctx->opcode >> 5) & 1,
10271                 ctx->opcode & 0x7, (ctx->opcode >> 4) & 1);
10272        opn = "mftr";
10273        break;
10274    case OPC_MTTR:
10275        check_cp0_enabled(ctx);
10276        gen_mttr(env, ctx, rd, rt, (ctx->opcode >> 5) & 1,
10277                 ctx->opcode & 0x7, (ctx->opcode >> 4) & 1);
10278        opn = "mttr";
10279        break;
10280    case OPC_TLBWI:
10281        opn = "tlbwi";
10282        if (!env->tlb->helper_tlbwi) {
10283            goto die;
10284        }
10285        gen_helper_tlbwi(cpu_env);
10286        break;
10287    case OPC_TLBINV:
10288        opn = "tlbinv";
10289        if (ctx->ie >= 2) {
10290            if (!env->tlb->helper_tlbinv) {
10291                goto die;
10292            }
10293            gen_helper_tlbinv(cpu_env);
10294        } /* treat as nop if TLBINV not supported */
10295        break;
10296    case OPC_TLBINVF:
10297        opn = "tlbinvf";
10298        if (ctx->ie >= 2) {
10299            if (!env->tlb->helper_tlbinvf) {
10300                goto die;
10301            }
10302            gen_helper_tlbinvf(cpu_env);
10303        } /* treat as nop if TLBINV not supported */
10304        break;
10305    case OPC_TLBWR:
10306        opn = "tlbwr";
10307        if (!env->tlb->helper_tlbwr) {
10308            goto die;
10309        }
10310        gen_helper_tlbwr(cpu_env);
10311        break;
10312    case OPC_TLBP:
10313        opn = "tlbp";
10314        if (!env->tlb->helper_tlbp) {
10315            goto die;
10316        }
10317        gen_helper_tlbp(cpu_env);
10318        break;
10319    case OPC_TLBR:
10320        opn = "tlbr";
10321        if (!env->tlb->helper_tlbr) {
10322            goto die;
10323        }
10324        gen_helper_tlbr(cpu_env);
10325        break;
10326    case OPC_ERET: /* OPC_ERETNC */
10327        if ((ctx->insn_flags & ISA_MIPS32R6) &&
10328            (ctx->hflags & MIPS_HFLAG_BMASK)) {
10329            goto die;
10330        } else {
10331            int bit_shift = (ctx->hflags & MIPS_HFLAG_M16) ? 16 : 6;
10332            if (ctx->opcode & (1 << bit_shift)) {
10333                /* OPC_ERETNC */
10334                opn = "eretnc";
10335                check_insn(ctx, ISA_MIPS32R5);
10336                gen_helper_eretnc(cpu_env);
10337            } else {
10338                /* OPC_ERET */
10339                opn = "eret";
10340                check_insn(ctx, ISA_MIPS2);
10341                gen_helper_eret(cpu_env);
10342            }
10343            ctx->base.is_jmp = DISAS_EXIT;
10344        }
10345        break;
10346    case OPC_DERET:
10347        opn = "deret";
10348        check_insn(ctx, ISA_MIPS32);
10349        if ((ctx->insn_flags & ISA_MIPS32R6) &&
10350            (ctx->hflags & MIPS_HFLAG_BMASK)) {
10351            goto die;
10352        }
10353        if (!(ctx->hflags & MIPS_HFLAG_DM)) {
10354            MIPS_INVAL(opn);
10355            generate_exception_end(ctx, EXCP_RI);
10356        } else {
10357            gen_helper_deret(cpu_env);
10358            ctx->base.is_jmp = DISAS_EXIT;
10359        }
10360        break;
10361    case OPC_WAIT:
10362        opn = "wait";
10363        check_insn(ctx, ISA_MIPS3 | ISA_MIPS32);
10364        if ((ctx->insn_flags & ISA_MIPS32R6) &&
10365            (ctx->hflags & MIPS_HFLAG_BMASK)) {
10366            goto die;
10367        }
10368        /* If we get an exception, we want to restart at next instruction */
10369        ctx->base.pc_next += 4;
10370        save_cpu_state(ctx, 1);
10371        ctx->base.pc_next -= 4;
10372        gen_helper_wait(cpu_env);
10373        ctx->base.is_jmp = DISAS_NORETURN;
10374        break;
10375    default:
10376 die:
10377        MIPS_INVAL(opn);
10378        generate_exception_end(ctx, EXCP_RI);
10379        return;
10380    }
10381    (void)opn; /* avoid a compiler warning */
10382}
10383#endif /* !CONFIG_USER_ONLY */
10384
10385/* CP1 Branches (before delay slot) */
10386static void gen_compute_branch1(DisasContext *ctx, uint32_t op,
10387                                int32_t cc, int32_t offset)
10388{
10389    target_ulong btarget;
10390    TCGv_i32 t0 = tcg_temp_new_i32();
10391
10392    if ((ctx->insn_flags & ISA_MIPS32R6) && (ctx->hflags & MIPS_HFLAG_BMASK)) {
10393        generate_exception_end(ctx, EXCP_RI);
10394        goto out;
10395    }
10396
10397    if (cc != 0) {
10398        check_insn(ctx, ISA_MIPS4 | ISA_MIPS32);
10399    }
10400
10401    btarget = ctx->base.pc_next + 4 + offset;
10402
10403    switch (op) {
10404    case OPC_BC1F:
10405        tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
10406        tcg_gen_not_i32(t0, t0);
10407        tcg_gen_andi_i32(t0, t0, 1);
10408        tcg_gen_extu_i32_tl(bcond, t0);
10409        goto not_likely;
10410    case OPC_BC1FL:
10411        tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
10412        tcg_gen_not_i32(t0, t0);
10413        tcg_gen_andi_i32(t0, t0, 1);
10414        tcg_gen_extu_i32_tl(bcond, t0);
10415        goto likely;
10416    case OPC_BC1T:
10417        tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
10418        tcg_gen_andi_i32(t0, t0, 1);
10419        tcg_gen_extu_i32_tl(bcond, t0);
10420        goto not_likely;
10421    case OPC_BC1TL:
10422        tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
10423        tcg_gen_andi_i32(t0, t0, 1);
10424        tcg_gen_extu_i32_tl(bcond, t0);
10425    likely:
10426        ctx->hflags |= MIPS_HFLAG_BL;
10427        break;
10428    case OPC_BC1FANY2:
10429        {
10430            TCGv_i32 t1 = tcg_temp_new_i32();
10431            tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
10432            tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+1));
10433            tcg_gen_nand_i32(t0, t0, t1);
10434            tcg_temp_free_i32(t1);
10435            tcg_gen_andi_i32(t0, t0, 1);
10436            tcg_gen_extu_i32_tl(bcond, t0);
10437        }
10438        goto not_likely;
10439    case OPC_BC1TANY2:
10440        {
10441            TCGv_i32 t1 = tcg_temp_new_i32();
10442            tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
10443            tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+1));
10444            tcg_gen_or_i32(t0, t0, t1);
10445            tcg_temp_free_i32(t1);
10446            tcg_gen_andi_i32(t0, t0, 1);
10447            tcg_gen_extu_i32_tl(bcond, t0);
10448        }
10449        goto not_likely;
10450    case OPC_BC1FANY4:
10451        {
10452            TCGv_i32 t1 = tcg_temp_new_i32();
10453            tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
10454            tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+1));
10455            tcg_gen_and_i32(t0, t0, t1);
10456            tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+2));
10457            tcg_gen_and_i32(t0, t0, t1);
10458            tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+3));
10459            tcg_gen_nand_i32(t0, t0, t1);
10460            tcg_temp_free_i32(t1);
10461            tcg_gen_andi_i32(t0, t0, 1);
10462            tcg_gen_extu_i32_tl(bcond, t0);
10463        }
10464        goto not_likely;
10465    case OPC_BC1TANY4:
10466        {
10467            TCGv_i32 t1 = tcg_temp_new_i32();
10468            tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
10469            tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+1));
10470            tcg_gen_or_i32(t0, t0, t1);
10471            tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+2));
10472            tcg_gen_or_i32(t0, t0, t1);
10473            tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+3));
10474            tcg_gen_or_i32(t0, t0, t1);
10475            tcg_temp_free_i32(t1);
10476            tcg_gen_andi_i32(t0, t0, 1);
10477            tcg_gen_extu_i32_tl(bcond, t0);
10478        }
10479    not_likely:
10480        ctx->hflags |= MIPS_HFLAG_BC;
10481        break;
10482    default:
10483        MIPS_INVAL("cp1 cond branch");
10484        generate_exception_end(ctx, EXCP_RI);
10485        goto out;
10486    }
10487    ctx->btarget = btarget;
10488    ctx->hflags |= MIPS_HFLAG_BDS32;
10489 out:
10490    tcg_temp_free_i32(t0);
10491}
10492
10493/* R6 CP1 Branches */
10494static void gen_compute_branch1_r6(DisasContext *ctx, uint32_t op,
10495                                   int32_t ft, int32_t offset,
10496                                   int delayslot_size)
10497{
10498    target_ulong btarget;
10499    TCGv_i64 t0 = tcg_temp_new_i64();
10500
10501    if (ctx->hflags & MIPS_HFLAG_BMASK) {
10502#ifdef MIPS_DEBUG_DISAS
10503        LOG_DISAS("Branch in delay / forbidden slot at PC 0x" TARGET_FMT_lx
10504                  "\n", ctx->base.pc_next);
10505#endif
10506        generate_exception_end(ctx, EXCP_RI);
10507        goto out;
10508    }
10509
10510    gen_load_fpr64(ctx, t0, ft);
10511    tcg_gen_andi_i64(t0, t0, 1);
10512
10513    btarget = addr_add(ctx, ctx->base.pc_next + 4, offset);
10514
10515    switch (op) {
10516    case OPC_BC1EQZ:
10517        tcg_gen_xori_i64(t0, t0, 1);
10518        ctx->hflags |= MIPS_HFLAG_BC;
10519        break;
10520    case OPC_BC1NEZ:
10521        /* t0 already set */
10522        ctx->hflags |= MIPS_HFLAG_BC;
10523        break;
10524    default:
10525        MIPS_INVAL("cp1 cond branch");
10526        generate_exception_end(ctx, EXCP_RI);
10527        goto out;
10528    }
10529
10530    tcg_gen_trunc_i64_tl(bcond, t0);
10531
10532    ctx->btarget = btarget;
10533
10534    switch (delayslot_size) {
10535    case 2:
10536        ctx->hflags |= MIPS_HFLAG_BDS16;
10537        break;
10538    case 4:
10539        ctx->hflags |= MIPS_HFLAG_BDS32;
10540        break;
10541    }
10542
10543out:
10544    tcg_temp_free_i64(t0);
10545}
10546
10547/* Coprocessor 1 (FPU) */
10548
10549#define FOP(func, fmt) (((fmt) << 21) | (func))
10550
10551enum fopcode {
10552    OPC_ADD_S = FOP(0, FMT_S),
10553    OPC_SUB_S = FOP(1, FMT_S),
10554    OPC_MUL_S = FOP(2, FMT_S),
10555    OPC_DIV_S = FOP(3, FMT_S),
10556    OPC_SQRT_S = FOP(4, FMT_S),
10557    OPC_ABS_S = FOP(5, FMT_S),
10558    OPC_MOV_S = FOP(6, FMT_S),
10559    OPC_NEG_S = FOP(7, FMT_S),
10560    OPC_ROUND_L_S = FOP(8, FMT_S),
10561    OPC_TRUNC_L_S = FOP(9, FMT_S),
10562    OPC_CEIL_L_S = FOP(10, FMT_S),
10563    OPC_FLOOR_L_S = FOP(11, FMT_S),
10564    OPC_ROUND_W_S = FOP(12, FMT_S),
10565    OPC_TRUNC_W_S = FOP(13, FMT_S),
10566    OPC_CEIL_W_S = FOP(14, FMT_S),
10567    OPC_FLOOR_W_S = FOP(15, FMT_S),
10568    OPC_SEL_S = FOP(16, FMT_S),
10569    OPC_MOVCF_S = FOP(17, FMT_S),
10570    OPC_MOVZ_S = FOP(18, FMT_S),
10571    OPC_MOVN_S = FOP(19, FMT_S),
10572    OPC_SELEQZ_S = FOP(20, FMT_S),
10573    OPC_RECIP_S = FOP(21, FMT_S),
10574    OPC_RSQRT_S = FOP(22, FMT_S),
10575    OPC_SELNEZ_S = FOP(23, FMT_S),
10576    OPC_MADDF_S = FOP(24, FMT_S),
10577    OPC_MSUBF_S = FOP(25, FMT_S),
10578    OPC_RINT_S = FOP(26, FMT_S),
10579    OPC_CLASS_S = FOP(27, FMT_S),
10580    OPC_MIN_S = FOP(28, FMT_S),
10581    OPC_RECIP2_S = FOP(28, FMT_S),
10582    OPC_MINA_S = FOP(29, FMT_S),
10583    OPC_RECIP1_S = FOP(29, FMT_S),
10584    OPC_MAX_S = FOP(30, FMT_S),
10585    OPC_RSQRT1_S = FOP(30, FMT_S),
10586    OPC_MAXA_S = FOP(31, FMT_S),
10587    OPC_RSQRT2_S = FOP(31, FMT_S),
10588    OPC_CVT_D_S = FOP(33, FMT_S),
10589    OPC_CVT_W_S = FOP(36, FMT_S),
10590    OPC_CVT_L_S = FOP(37, FMT_S),
10591    OPC_CVT_PS_S = FOP(38, FMT_S),
10592    OPC_CMP_F_S = FOP(48, FMT_S),
10593    OPC_CMP_UN_S = FOP(49, FMT_S),
10594    OPC_CMP_EQ_S = FOP(50, FMT_S),
10595    OPC_CMP_UEQ_S = FOP(51, FMT_S),
10596    OPC_CMP_OLT_S = FOP(52, FMT_S),
10597    OPC_CMP_ULT_S = FOP(53, FMT_S),
10598    OPC_CMP_OLE_S = FOP(54, FMT_S),
10599    OPC_CMP_ULE_S = FOP(55, FMT_S),
10600    OPC_CMP_SF_S = FOP(56, FMT_S),
10601    OPC_CMP_NGLE_S = FOP(57, FMT_S),
10602    OPC_CMP_SEQ_S = FOP(58, FMT_S),
10603    OPC_CMP_NGL_S = FOP(59, FMT_S),
10604    OPC_CMP_LT_S = FOP(60, FMT_S),
10605    OPC_CMP_NGE_S = FOP(61, FMT_S),
10606    OPC_CMP_LE_S = FOP(62, FMT_S),
10607    OPC_CMP_NGT_S = FOP(63, FMT_S),
10608
10609    OPC_ADD_D = FOP(0, FMT_D),
10610    OPC_SUB_D = FOP(1, FMT_D),
10611    OPC_MUL_D = FOP(2, FMT_D),
10612    OPC_DIV_D = FOP(3, FMT_D),
10613    OPC_SQRT_D = FOP(4, FMT_D),
10614    OPC_ABS_D = FOP(5, FMT_D),
10615    OPC_MOV_D = FOP(6, FMT_D),
10616    OPC_NEG_D = FOP(7, FMT_D),
10617    OPC_ROUND_L_D = FOP(8, FMT_D),
10618    OPC_TRUNC_L_D = FOP(9, FMT_D),
10619    OPC_CEIL_L_D = FOP(10, FMT_D),
10620    OPC_FLOOR_L_D = FOP(11, FMT_D),
10621    OPC_ROUND_W_D = FOP(12, FMT_D),
10622    OPC_TRUNC_W_D = FOP(13, FMT_D),
10623    OPC_CEIL_W_D = FOP(14, FMT_D),
10624    OPC_FLOOR_W_D = FOP(15, FMT_D),
10625    OPC_SEL_D = FOP(16, FMT_D),
10626    OPC_MOVCF_D = FOP(17, FMT_D),
10627    OPC_MOVZ_D = FOP(18, FMT_D),
10628    OPC_MOVN_D = FOP(19, FMT_D),
10629    OPC_SELEQZ_D = FOP(20, FMT_D),
10630    OPC_RECIP_D = FOP(21, FMT_D),
10631    OPC_RSQRT_D = FOP(22, FMT_D),
10632    OPC_SELNEZ_D = FOP(23, FMT_D),
10633    OPC_MADDF_D = FOP(24, FMT_D),
10634    OPC_MSUBF_D = FOP(25, FMT_D),
10635    OPC_RINT_D = FOP(26, FMT_D),
10636    OPC_CLASS_D = FOP(27, FMT_D),
10637    OPC_MIN_D = FOP(28, FMT_D),
10638    OPC_RECIP2_D = FOP(28, FMT_D),
10639    OPC_MINA_D = FOP(29, FMT_D),
10640    OPC_RECIP1_D = FOP(29, FMT_D),
10641    OPC_MAX_D = FOP(30, FMT_D),
10642    OPC_RSQRT1_D = FOP(30, FMT_D),
10643    OPC_MAXA_D = FOP(31, FMT_D),
10644    OPC_RSQRT2_D = FOP(31, FMT_D),
10645    OPC_CVT_S_D = FOP(32, FMT_D),
10646    OPC_CVT_W_D = FOP(36, FMT_D),
10647    OPC_CVT_L_D = FOP(37, FMT_D),
10648    OPC_CMP_F_D = FOP(48, FMT_D),
10649    OPC_CMP_UN_D = FOP(49, FMT_D),
10650    OPC_CMP_EQ_D = FOP(50, FMT_D),
10651    OPC_CMP_UEQ_D = FOP(51, FMT_D),
10652    OPC_CMP_OLT_D = FOP(52, FMT_D),
10653    OPC_CMP_ULT_D = FOP(53, FMT_D),
10654    OPC_CMP_OLE_D = FOP(54, FMT_D),
10655    OPC_CMP_ULE_D = FOP(55, FMT_D),
10656    OPC_CMP_SF_D = FOP(56, FMT_D),
10657    OPC_CMP_NGLE_D = FOP(57, FMT_D),
10658    OPC_CMP_SEQ_D = FOP(58, FMT_D),
10659    OPC_CMP_NGL_D = FOP(59, FMT_D),
10660    OPC_CMP_LT_D = FOP(60, FMT_D),
10661    OPC_CMP_NGE_D = FOP(61, FMT_D),
10662    OPC_CMP_LE_D = FOP(62, FMT_D),
10663    OPC_CMP_NGT_D = FOP(63, FMT_D),
10664
10665    OPC_CVT_S_W = FOP(32, FMT_W),
10666    OPC_CVT_D_W = FOP(33, FMT_W),
10667    OPC_CVT_S_L = FOP(32, FMT_L),
10668    OPC_CVT_D_L = FOP(33, FMT_L),
10669    OPC_CVT_PS_PW = FOP(38, FMT_W),
10670
10671    OPC_ADD_PS = FOP(0, FMT_PS),
10672    OPC_SUB_PS = FOP(1, FMT_PS),
10673    OPC_MUL_PS = FOP(2, FMT_PS),
10674    OPC_DIV_PS = FOP(3, FMT_PS),
10675    OPC_ABS_PS = FOP(5, FMT_PS),
10676    OPC_MOV_PS = FOP(6, FMT_PS),
10677    OPC_NEG_PS = FOP(7, FMT_PS),
10678    OPC_MOVCF_PS = FOP(17, FMT_PS),
10679    OPC_MOVZ_PS = FOP(18, FMT_PS),
10680    OPC_MOVN_PS = FOP(19, FMT_PS),
10681    OPC_ADDR_PS = FOP(24, FMT_PS),
10682    OPC_MULR_PS = FOP(26, FMT_PS),
10683    OPC_RECIP2_PS = FOP(28, FMT_PS),
10684    OPC_RECIP1_PS = FOP(29, FMT_PS),
10685    OPC_RSQRT1_PS = FOP(30, FMT_PS),
10686    OPC_RSQRT2_PS = FOP(31, FMT_PS),
10687
10688    OPC_CVT_S_PU = FOP(32, FMT_PS),
10689    OPC_CVT_PW_PS = FOP(36, FMT_PS),
10690    OPC_CVT_S_PL = FOP(40, FMT_PS),
10691    OPC_PLL_PS = FOP(44, FMT_PS),
10692    OPC_PLU_PS = FOP(45, FMT_PS),
10693    OPC_PUL_PS = FOP(46, FMT_PS),
10694    OPC_PUU_PS = FOP(47, FMT_PS),
10695    OPC_CMP_F_PS = FOP(48, FMT_PS),
10696    OPC_CMP_UN_PS = FOP(49, FMT_PS),
10697    OPC_CMP_EQ_PS = FOP(50, FMT_PS),
10698    OPC_CMP_UEQ_PS = FOP(51, FMT_PS),
10699    OPC_CMP_OLT_PS = FOP(52, FMT_PS),
10700    OPC_CMP_ULT_PS = FOP(53, FMT_PS),
10701    OPC_CMP_OLE_PS = FOP(54, FMT_PS),
10702    OPC_CMP_ULE_PS = FOP(55, FMT_PS),
10703    OPC_CMP_SF_PS = FOP(56, FMT_PS),
10704    OPC_CMP_NGLE_PS = FOP(57, FMT_PS),
10705    OPC_CMP_SEQ_PS = FOP(58, FMT_PS),
10706    OPC_CMP_NGL_PS = FOP(59, FMT_PS),
10707    OPC_CMP_LT_PS = FOP(60, FMT_PS),
10708    OPC_CMP_NGE_PS = FOP(61, FMT_PS),
10709    OPC_CMP_LE_PS = FOP(62, FMT_PS),
10710    OPC_CMP_NGT_PS = FOP(63, FMT_PS),
10711};
10712
10713enum r6_f_cmp_op {
10714    R6_OPC_CMP_AF_S   = FOP(0, FMT_W),
10715    R6_OPC_CMP_UN_S   = FOP(1, FMT_W),
10716    R6_OPC_CMP_EQ_S   = FOP(2, FMT_W),
10717    R6_OPC_CMP_UEQ_S  = FOP(3, FMT_W),
10718    R6_OPC_CMP_LT_S   = FOP(4, FMT_W),
10719    R6_OPC_CMP_ULT_S  = FOP(5, FMT_W),
10720    R6_OPC_CMP_LE_S   = FOP(6, FMT_W),
10721    R6_OPC_CMP_ULE_S  = FOP(7, FMT_W),
10722    R6_OPC_CMP_SAF_S  = FOP(8, FMT_W),
10723    R6_OPC_CMP_SUN_S  = FOP(9, FMT_W),
10724    R6_OPC_CMP_SEQ_S  = FOP(10, FMT_W),
10725    R6_OPC_CMP_SEUQ_S = FOP(11, FMT_W),
10726    R6_OPC_CMP_SLT_S  = FOP(12, FMT_W),
10727    R6_OPC_CMP_SULT_S = FOP(13, FMT_W),
10728    R6_OPC_CMP_SLE_S  = FOP(14, FMT_W),
10729    R6_OPC_CMP_SULE_S = FOP(15, FMT_W),
10730    R6_OPC_CMP_OR_S   = FOP(17, FMT_W),
10731    R6_OPC_CMP_UNE_S  = FOP(18, FMT_W),
10732    R6_OPC_CMP_NE_S   = FOP(19, FMT_W),
10733    R6_OPC_CMP_SOR_S  = FOP(25, FMT_W),
10734    R6_OPC_CMP_SUNE_S = FOP(26, FMT_W),
10735    R6_OPC_CMP_SNE_S  = FOP(27, FMT_W),
10736
10737    R6_OPC_CMP_AF_D   = FOP(0, FMT_L),
10738    R6_OPC_CMP_UN_D   = FOP(1, FMT_L),
10739    R6_OPC_CMP_EQ_D   = FOP(2, FMT_L),
10740    R6_OPC_CMP_UEQ_D  = FOP(3, FMT_L),
10741    R6_OPC_CMP_LT_D   = FOP(4, FMT_L),
10742    R6_OPC_CMP_ULT_D  = FOP(5, FMT_L),
10743    R6_OPC_CMP_LE_D   = FOP(6, FMT_L),
10744    R6_OPC_CMP_ULE_D  = FOP(7, FMT_L),
10745    R6_OPC_CMP_SAF_D  = FOP(8, FMT_L),
10746    R6_OPC_CMP_SUN_D  = FOP(9, FMT_L),
10747    R6_OPC_CMP_SEQ_D  = FOP(10, FMT_L),
10748    R6_OPC_CMP_SEUQ_D = FOP(11, FMT_L),
10749    R6_OPC_CMP_SLT_D  = FOP(12, FMT_L),
10750    R6_OPC_CMP_SULT_D = FOP(13, FMT_L),
10751    R6_OPC_CMP_SLE_D  = FOP(14, FMT_L),
10752    R6_OPC_CMP_SULE_D = FOP(15, FMT_L),
10753    R6_OPC_CMP_OR_D   = FOP(17, FMT_L),
10754    R6_OPC_CMP_UNE_D  = FOP(18, FMT_L),
10755    R6_OPC_CMP_NE_D   = FOP(19, FMT_L),
10756    R6_OPC_CMP_SOR_D  = FOP(25, FMT_L),
10757    R6_OPC_CMP_SUNE_D = FOP(26, FMT_L),
10758    R6_OPC_CMP_SNE_D  = FOP(27, FMT_L),
10759};
10760
10761static void gen_cp1(DisasContext *ctx, uint32_t opc, int rt, int fs)
10762{
10763    TCGv t0 = tcg_temp_new();
10764
10765    switch (opc) {
10766    case OPC_MFC1:
10767        {
10768            TCGv_i32 fp0 = tcg_temp_new_i32();
10769
10770            gen_load_fpr32(ctx, fp0, fs);
10771            tcg_gen_ext_i32_tl(t0, fp0);
10772            tcg_temp_free_i32(fp0);
10773        }
10774        gen_store_gpr(t0, rt);
10775        break;
10776    case OPC_MTC1:
10777        gen_load_gpr(t0, rt);
10778        {
10779            TCGv_i32 fp0 = tcg_temp_new_i32();
10780
10781            tcg_gen_trunc_tl_i32(fp0, t0);
10782            gen_store_fpr32(ctx, fp0, fs);
10783            tcg_temp_free_i32(fp0);
10784        }
10785        break;
10786    case OPC_CFC1:
10787        gen_helper_1e0i(cfc1, t0, fs);
10788        gen_store_gpr(t0, rt);
10789        break;
10790    case OPC_CTC1:
10791        gen_load_gpr(t0, rt);
10792        save_cpu_state(ctx, 0);
10793        {
10794            TCGv_i32 fs_tmp = tcg_const_i32(fs);
10795
10796            gen_helper_0e2i(ctc1, t0, fs_tmp, rt);
10797            tcg_temp_free_i32(fs_tmp);
10798        }
10799        /* Stop translation as we may have changed hflags */
10800        ctx->base.is_jmp = DISAS_STOP;
10801        break;
10802#if defined(TARGET_MIPS64)
10803    case OPC_DMFC1:
10804        gen_load_fpr64(ctx, t0, fs);
10805        gen_store_gpr(t0, rt);
10806        break;
10807    case OPC_DMTC1:
10808        gen_load_gpr(t0, rt);
10809        gen_store_fpr64(ctx, t0, fs);
10810        break;
10811#endif
10812    case OPC_MFHC1:
10813        {
10814            TCGv_i32 fp0 = tcg_temp_new_i32();
10815
10816            gen_load_fpr32h(ctx, fp0, fs);
10817            tcg_gen_ext_i32_tl(t0, fp0);
10818            tcg_temp_free_i32(fp0);
10819        }
10820        gen_store_gpr(t0, rt);
10821        break;
10822    case OPC_MTHC1:
10823        gen_load_gpr(t0, rt);
10824        {
10825            TCGv_i32 fp0 = tcg_temp_new_i32();
10826
10827            tcg_gen_trunc_tl_i32(fp0, t0);
10828            gen_store_fpr32h(ctx, fp0, fs);
10829            tcg_temp_free_i32(fp0);
10830        }
10831        break;
10832    default:
10833        MIPS_INVAL("cp1 move");
10834        generate_exception_end(ctx, EXCP_RI);
10835        goto out;
10836    }
10837
10838 out:
10839    tcg_temp_free(t0);
10840}
10841
10842static void gen_movci(DisasContext *ctx, int rd, int rs, int cc, int tf)
10843{
10844    TCGLabel *l1;
10845    TCGCond cond;
10846    TCGv_i32 t0;
10847
10848    if (rd == 0) {
10849        /* Treat as NOP. */
10850        return;
10851    }
10852
10853    if (tf) {
10854        cond = TCG_COND_EQ;
10855    } else {
10856        cond = TCG_COND_NE;
10857    }
10858
10859    l1 = gen_new_label();
10860    t0 = tcg_temp_new_i32();
10861    tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
10862    tcg_gen_brcondi_i32(cond, t0, 0, l1);
10863    tcg_temp_free_i32(t0);
10864    if (rs == 0) {
10865        tcg_gen_movi_tl(cpu_gpr[rd], 0);
10866    } else {
10867        tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
10868    }
10869    gen_set_label(l1);
10870}
10871
10872static inline void gen_movcf_s(DisasContext *ctx, int fs, int fd, int cc,
10873                               int tf)
10874{
10875    int cond;
10876    TCGv_i32 t0 = tcg_temp_new_i32();
10877    TCGLabel *l1 = gen_new_label();
10878
10879    if (tf) {
10880        cond = TCG_COND_EQ;
10881    } else {
10882        cond = TCG_COND_NE;
10883    }
10884
10885    tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
10886    tcg_gen_brcondi_i32(cond, t0, 0, l1);
10887    gen_load_fpr32(ctx, t0, fs);
10888    gen_store_fpr32(ctx, t0, fd);
10889    gen_set_label(l1);
10890    tcg_temp_free_i32(t0);
10891}
10892
10893static inline void gen_movcf_d(DisasContext *ctx, int fs, int fd, int cc,
10894                               int tf)
10895{
10896    int cond;
10897    TCGv_i32 t0 = tcg_temp_new_i32();
10898    TCGv_i64 fp0;
10899    TCGLabel *l1 = gen_new_label();
10900
10901    if (tf) {
10902        cond = TCG_COND_EQ;
10903    } else {
10904        cond = TCG_COND_NE;
10905    }
10906
10907    tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
10908    tcg_gen_brcondi_i32(cond, t0, 0, l1);
10909    tcg_temp_free_i32(t0);
10910    fp0 = tcg_temp_new_i64();
10911    gen_load_fpr64(ctx, fp0, fs);
10912    gen_store_fpr64(ctx, fp0, fd);
10913    tcg_temp_free_i64(fp0);
10914    gen_set_label(l1);
10915}
10916
10917static inline void gen_movcf_ps(DisasContext *ctx, int fs, int fd,
10918                                int cc, int tf)
10919{
10920    int cond;
10921    TCGv_i32 t0 = tcg_temp_new_i32();
10922    TCGLabel *l1 = gen_new_label();
10923    TCGLabel *l2 = gen_new_label();
10924
10925    if (tf) {
10926        cond = TCG_COND_EQ;
10927    } else {
10928        cond = TCG_COND_NE;
10929    }
10930
10931    tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
10932    tcg_gen_brcondi_i32(cond, t0, 0, l1);
10933    gen_load_fpr32(ctx, t0, fs);
10934    gen_store_fpr32(ctx, t0, fd);
10935    gen_set_label(l1);
10936
10937    tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc+1));
10938    tcg_gen_brcondi_i32(cond, t0, 0, l2);
10939    gen_load_fpr32h(ctx, t0, fs);
10940    gen_store_fpr32h(ctx, t0, fd);
10941    tcg_temp_free_i32(t0);
10942    gen_set_label(l2);
10943}
10944
10945static void gen_sel_s(DisasContext *ctx, enum fopcode op1, int fd, int ft,
10946                      int fs)
10947{
10948    TCGv_i32 t1 = tcg_const_i32(0);
10949    TCGv_i32 fp0 = tcg_temp_new_i32();
10950    TCGv_i32 fp1 = tcg_temp_new_i32();
10951    TCGv_i32 fp2 = tcg_temp_new_i32();
10952    gen_load_fpr32(ctx, fp0, fd);
10953    gen_load_fpr32(ctx, fp1, ft);
10954    gen_load_fpr32(ctx, fp2, fs);
10955
10956    switch (op1) {
10957    case OPC_SEL_S:
10958        tcg_gen_andi_i32(fp0, fp0, 1);
10959        tcg_gen_movcond_i32(TCG_COND_NE, fp0, fp0, t1, fp1, fp2);
10960        break;
10961    case OPC_SELEQZ_S:
10962        tcg_gen_andi_i32(fp1, fp1, 1);
10963        tcg_gen_movcond_i32(TCG_COND_EQ, fp0, fp1, t1, fp2, t1);
10964        break;
10965    case OPC_SELNEZ_S:
10966        tcg_gen_andi_i32(fp1, fp1, 1);
10967        tcg_gen_movcond_i32(TCG_COND_NE, fp0, fp1, t1, fp2, t1);
10968        break;
10969    default:
10970        MIPS_INVAL("gen_sel_s");
10971        generate_exception_end(ctx, EXCP_RI);
10972        break;
10973    }
10974
10975    gen_store_fpr32(ctx, fp0, fd);
10976    tcg_temp_free_i32(fp2);
10977    tcg_temp_free_i32(fp1);
10978    tcg_temp_free_i32(fp0);
10979    tcg_temp_free_i32(t1);
10980}
10981
10982static void gen_sel_d(DisasContext *ctx, enum fopcode op1, int fd, int ft,
10983                      int fs)
10984{
10985    TCGv_i64 t1 = tcg_const_i64(0);
10986    TCGv_i64 fp0 = tcg_temp_new_i64();
10987    TCGv_i64 fp1 = tcg_temp_new_i64();
10988    TCGv_i64 fp2 = tcg_temp_new_i64();
10989    gen_load_fpr64(ctx, fp0, fd);
10990    gen_load_fpr64(ctx, fp1, ft);
10991    gen_load_fpr64(ctx, fp2, fs);
10992
10993    switch (op1) {
10994    case OPC_SEL_D:
10995        tcg_gen_andi_i64(fp0, fp0, 1);
10996        tcg_gen_movcond_i64(TCG_COND_NE, fp0, fp0, t1, fp1, fp2);
10997        break;
10998    case OPC_SELEQZ_D:
10999        tcg_gen_andi_i64(fp1, fp1, 1);
11000        tcg_gen_movcond_i64(TCG_COND_EQ, fp0, fp1, t1, fp2, t1);
11001        break;
11002    case OPC_SELNEZ_D:
11003        tcg_gen_andi_i64(fp1, fp1, 1);
11004        tcg_gen_movcond_i64(TCG_COND_NE, fp0, fp1, t1, fp2, t1);
11005        break;
11006    default:
11007        MIPS_INVAL("gen_sel_d");
11008        generate_exception_end(ctx, EXCP_RI);
11009        break;
11010    }
11011
11012    gen_store_fpr64(ctx, fp0, fd);
11013    tcg_temp_free_i64(fp2);
11014    tcg_temp_free_i64(fp1);
11015    tcg_temp_free_i64(fp0);
11016    tcg_temp_free_i64(t1);
11017}
11018
11019static void gen_farith(DisasContext *ctx, enum fopcode op1,
11020                       int ft, int fs, int fd, int cc)
11021{
11022    uint32_t func = ctx->opcode & 0x3f;
11023    switch (op1) {
11024    case OPC_ADD_S:
11025        {
11026            TCGv_i32 fp0 = tcg_temp_new_i32();
11027            TCGv_i32 fp1 = tcg_temp_new_i32();
11028
11029            gen_load_fpr32(ctx, fp0, fs);
11030            gen_load_fpr32(ctx, fp1, ft);
11031            gen_helper_float_add_s(fp0, cpu_env, fp0, fp1);
11032            tcg_temp_free_i32(fp1);
11033            gen_store_fpr32(ctx, fp0, fd);
11034            tcg_temp_free_i32(fp0);
11035        }
11036        break;
11037    case OPC_SUB_S:
11038        {
11039            TCGv_i32 fp0 = tcg_temp_new_i32();
11040            TCGv_i32 fp1 = tcg_temp_new_i32();
11041
11042            gen_load_fpr32(ctx, fp0, fs);
11043            gen_load_fpr32(ctx, fp1, ft);
11044            gen_helper_float_sub_s(fp0, cpu_env, fp0, fp1);
11045            tcg_temp_free_i32(fp1);
11046            gen_store_fpr32(ctx, fp0, fd);
11047            tcg_temp_free_i32(fp0);
11048        }
11049        break;
11050    case OPC_MUL_S:
11051        {
11052            TCGv_i32 fp0 = tcg_temp_new_i32();
11053            TCGv_i32 fp1 = tcg_temp_new_i32();
11054
11055            gen_load_fpr32(ctx, fp0, fs);
11056            gen_load_fpr32(ctx, fp1, ft);
11057            gen_helper_float_mul_s(fp0, cpu_env, fp0, fp1);
11058            tcg_temp_free_i32(fp1);
11059            gen_store_fpr32(ctx, fp0, fd);
11060            tcg_temp_free_i32(fp0);
11061        }
11062        break;
11063    case OPC_DIV_S:
11064        {
11065            TCGv_i32 fp0 = tcg_temp_new_i32();
11066            TCGv_i32 fp1 = tcg_temp_new_i32();
11067
11068            gen_load_fpr32(ctx, fp0, fs);
11069            gen_load_fpr32(ctx, fp1, ft);
11070            gen_helper_float_div_s(fp0, cpu_env, fp0, fp1);
11071            tcg_temp_free_i32(fp1);
11072            gen_store_fpr32(ctx, fp0, fd);
11073            tcg_temp_free_i32(fp0);
11074        }
11075        break;
11076    case OPC_SQRT_S:
11077        {
11078            TCGv_i32 fp0 = tcg_temp_new_i32();
11079
11080            gen_load_fpr32(ctx, fp0, fs);
11081            gen_helper_float_sqrt_s(fp0, cpu_env, fp0);
11082            gen_store_fpr32(ctx, fp0, fd);
11083            tcg_temp_free_i32(fp0);
11084        }
11085        break;
11086    case OPC_ABS_S:
11087        {
11088            TCGv_i32 fp0 = tcg_temp_new_i32();
11089
11090            gen_load_fpr32(ctx, fp0, fs);
11091            if (ctx->abs2008) {
11092                tcg_gen_andi_i32(fp0, fp0, 0x7fffffffUL);
11093            } else {
11094                gen_helper_float_abs_s(fp0, fp0);
11095            }
11096            gen_store_fpr32(ctx, fp0, fd);
11097            tcg_temp_free_i32(fp0);
11098        }
11099        break;
11100    case OPC_MOV_S:
11101        {
11102            TCGv_i32 fp0 = tcg_temp_new_i32();
11103
11104            gen_load_fpr32(ctx, fp0, fs);
11105            gen_store_fpr32(ctx, fp0, fd);
11106            tcg_temp_free_i32(fp0);
11107        }
11108        break;
11109    case OPC_NEG_S:
11110        {
11111            TCGv_i32 fp0 = tcg_temp_new_i32();
11112
11113            gen_load_fpr32(ctx, fp0, fs);
11114            if (ctx->abs2008) {
11115                tcg_gen_xori_i32(fp0, fp0, 1UL << 31);
11116            } else {
11117                gen_helper_float_chs_s(fp0, fp0);
11118            }
11119            gen_store_fpr32(ctx, fp0, fd);
11120            tcg_temp_free_i32(fp0);
11121        }
11122        break;
11123    case OPC_ROUND_L_S:
11124        check_cp1_64bitmode(ctx);
11125        {
11126            TCGv_i32 fp32 = tcg_temp_new_i32();
11127            TCGv_i64 fp64 = tcg_temp_new_i64();
11128
11129            gen_load_fpr32(ctx, fp32, fs);
11130            if (ctx->nan2008) {
11131                gen_helper_float_round_2008_l_s(fp64, cpu_env, fp32);
11132            } else {
11133                gen_helper_float_round_l_s(fp64, cpu_env, fp32);
11134            }
11135            tcg_temp_free_i32(fp32);
11136            gen_store_fpr64(ctx, fp64, fd);
11137            tcg_temp_free_i64(fp64);
11138        }
11139        break;
11140    case OPC_TRUNC_L_S:
11141        check_cp1_64bitmode(ctx);
11142        {
11143            TCGv_i32 fp32 = tcg_temp_new_i32();
11144            TCGv_i64 fp64 = tcg_temp_new_i64();
11145
11146            gen_load_fpr32(ctx, fp32, fs);
11147            if (ctx->nan2008) {
11148                gen_helper_float_trunc_2008_l_s(fp64, cpu_env, fp32);
11149            } else {
11150                gen_helper_float_trunc_l_s(fp64, cpu_env, fp32);
11151            }
11152            tcg_temp_free_i32(fp32);
11153            gen_store_fpr64(ctx, fp64, fd);
11154            tcg_temp_free_i64(fp64);
11155        }
11156        break;
11157    case OPC_CEIL_L_S:
11158        check_cp1_64bitmode(ctx);
11159        {
11160            TCGv_i32 fp32 = tcg_temp_new_i32();
11161            TCGv_i64 fp64 = tcg_temp_new_i64();
11162
11163            gen_load_fpr32(ctx, fp32, fs);
11164            if (ctx->nan2008) {
11165                gen_helper_float_ceil_2008_l_s(fp64, cpu_env, fp32);
11166            } else {
11167                gen_helper_float_ceil_l_s(fp64, cpu_env, fp32);
11168            }
11169            tcg_temp_free_i32(fp32);
11170            gen_store_fpr64(ctx, fp64, fd);
11171            tcg_temp_free_i64(fp64);
11172        }
11173        break;
11174    case OPC_FLOOR_L_S:
11175        check_cp1_64bitmode(ctx);
11176        {
11177            TCGv_i32 fp32 = tcg_temp_new_i32();
11178            TCGv_i64 fp64 = tcg_temp_new_i64();
11179
11180            gen_load_fpr32(ctx, fp32, fs);
11181            if (ctx->nan2008) {
11182                gen_helper_float_floor_2008_l_s(fp64, cpu_env, fp32);
11183            } else {
11184                gen_helper_float_floor_l_s(fp64, cpu_env, fp32);
11185            }
11186            tcg_temp_free_i32(fp32);
11187            gen_store_fpr64(ctx, fp64, fd);
11188            tcg_temp_free_i64(fp64);
11189        }
11190        break;
11191    case OPC_ROUND_W_S:
11192        {
11193            TCGv_i32 fp0 = tcg_temp_new_i32();
11194
11195            gen_load_fpr32(ctx, fp0, fs);
11196            if (ctx->nan2008) {
11197                gen_helper_float_round_2008_w_s(fp0, cpu_env, fp0);
11198            } else {
11199                gen_helper_float_round_w_s(fp0, cpu_env, fp0);
11200            }
11201            gen_store_fpr32(ctx, fp0, fd);
11202            tcg_temp_free_i32(fp0);
11203        }
11204        break;
11205    case OPC_TRUNC_W_S:
11206        {
11207            TCGv_i32 fp0 = tcg_temp_new_i32();
11208
11209            gen_load_fpr32(ctx, fp0, fs);
11210            if (ctx->nan2008) {
11211                gen_helper_float_trunc_2008_w_s(fp0, cpu_env, fp0);
11212            } else {
11213                gen_helper_float_trunc_w_s(fp0, cpu_env, fp0);
11214            }
11215            gen_store_fpr32(ctx, fp0, fd);
11216            tcg_temp_free_i32(fp0);
11217        }
11218        break;
11219    case OPC_CEIL_W_S:
11220        {
11221            TCGv_i32 fp0 = tcg_temp_new_i32();
11222
11223            gen_load_fpr32(ctx, fp0, fs);
11224            if (ctx->nan2008) {
11225                gen_helper_float_ceil_2008_w_s(fp0, cpu_env, fp0);
11226            } else {
11227                gen_helper_float_ceil_w_s(fp0, cpu_env, fp0);
11228            }
11229            gen_store_fpr32(ctx, fp0, fd);
11230            tcg_temp_free_i32(fp0);
11231        }
11232        break;
11233    case OPC_FLOOR_W_S:
11234        {
11235            TCGv_i32 fp0 = tcg_temp_new_i32();
11236
11237            gen_load_fpr32(ctx, fp0, fs);
11238            if (ctx->nan2008) {
11239                gen_helper_float_floor_2008_w_s(fp0, cpu_env, fp0);
11240            } else {
11241                gen_helper_float_floor_w_s(fp0, cpu_env, fp0);
11242            }
11243            gen_store_fpr32(ctx, fp0, fd);
11244            tcg_temp_free_i32(fp0);
11245        }
11246        break;
11247    case OPC_SEL_S:
11248        check_insn(ctx, ISA_MIPS32R6);
11249        gen_sel_s(ctx, op1, fd, ft, fs);
11250        break;
11251    case OPC_SELEQZ_S:
11252        check_insn(ctx, ISA_MIPS32R6);
11253        gen_sel_s(ctx, op1, fd, ft, fs);
11254        break;
11255    case OPC_SELNEZ_S:
11256        check_insn(ctx, ISA_MIPS32R6);
11257        gen_sel_s(ctx, op1, fd, ft, fs);
11258        break;
11259    case OPC_MOVCF_S:
11260        check_insn_opc_removed(ctx, ISA_MIPS32R6);
11261        gen_movcf_s(ctx, fs, fd, (ft >> 2) & 0x7, ft & 0x1);
11262        break;
11263    case OPC_MOVZ_S:
11264        check_insn_opc_removed(ctx, ISA_MIPS32R6);
11265        {
11266            TCGLabel *l1 = gen_new_label();
11267            TCGv_i32 fp0;
11268
11269            if (ft != 0) {
11270                tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[ft], 0, l1);
11271            }
11272            fp0 = tcg_temp_new_i32();
11273            gen_load_fpr32(ctx, fp0, fs);
11274            gen_store_fpr32(ctx, fp0, fd);
11275            tcg_temp_free_i32(fp0);
11276            gen_set_label(l1);
11277        }
11278        break;
11279    case OPC_MOVN_S:
11280        check_insn_opc_removed(ctx, ISA_MIPS32R6);
11281        {
11282            TCGLabel *l1 = gen_new_label();
11283            TCGv_i32 fp0;
11284
11285            if (ft != 0) {
11286                tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[ft], 0, l1);
11287                fp0 = tcg_temp_new_i32();
11288                gen_load_fpr32(ctx, fp0, fs);
11289                gen_store_fpr32(ctx, fp0, fd);
11290                tcg_temp_free_i32(fp0);
11291                gen_set_label(l1);
11292            }
11293        }
11294        break;
11295    case OPC_RECIP_S:
11296        {
11297            TCGv_i32 fp0 = tcg_temp_new_i32();
11298
11299            gen_load_fpr32(ctx, fp0, fs);
11300            gen_helper_float_recip_s(fp0, cpu_env, fp0);
11301            gen_store_fpr32(ctx, fp0, fd);
11302            tcg_temp_free_i32(fp0);
11303        }
11304        break;
11305    case OPC_RSQRT_S:
11306        {
11307            TCGv_i32 fp0 = tcg_temp_new_i32();
11308
11309            gen_load_fpr32(ctx, fp0, fs);
11310            gen_helper_float_rsqrt_s(fp0, cpu_env, fp0);
11311            gen_store_fpr32(ctx, fp0, fd);
11312            tcg_temp_free_i32(fp0);
11313        }
11314        break;
11315    case OPC_MADDF_S:
11316        check_insn(ctx, ISA_MIPS32R6);
11317        {
11318            TCGv_i32 fp0 = tcg_temp_new_i32();
11319            TCGv_i32 fp1 = tcg_temp_new_i32();
11320            TCGv_i32 fp2 = tcg_temp_new_i32();
11321            gen_load_fpr32(ctx, fp0, fs);
11322            gen_load_fpr32(ctx, fp1, ft);
11323            gen_load_fpr32(ctx, fp2, fd);
11324            gen_helper_float_maddf_s(fp2, cpu_env, fp0, fp1, fp2);
11325            gen_store_fpr32(ctx, fp2, fd);
11326            tcg_temp_free_i32(fp2);
11327            tcg_temp_free_i32(fp1);
11328            tcg_temp_free_i32(fp0);
11329        }
11330        break;
11331    case OPC_MSUBF_S:
11332        check_insn(ctx, ISA_MIPS32R6);
11333        {
11334            TCGv_i32 fp0 = tcg_temp_new_i32();
11335            TCGv_i32 fp1 = tcg_temp_new_i32();
11336            TCGv_i32 fp2 = tcg_temp_new_i32();
11337            gen_load_fpr32(ctx, fp0, fs);
11338            gen_load_fpr32(ctx, fp1, ft);
11339            gen_load_fpr32(ctx, fp2, fd);
11340            gen_helper_float_msubf_s(fp2, cpu_env, fp0, fp1, fp2);
11341            gen_store_fpr32(ctx, fp2, fd);
11342            tcg_temp_free_i32(fp2);
11343            tcg_temp_free_i32(fp1);
11344            tcg_temp_free_i32(fp0);
11345        }
11346        break;
11347    case OPC_RINT_S:
11348        check_insn(ctx, ISA_MIPS32R6);
11349        {
11350            TCGv_i32 fp0 = tcg_temp_new_i32();
11351            gen_load_fpr32(ctx, fp0, fs);
11352            gen_helper_float_rint_s(fp0, cpu_env, fp0);
11353            gen_store_fpr32(ctx, fp0, fd);
11354            tcg_temp_free_i32(fp0);
11355        }
11356        break;
11357    case OPC_CLASS_S:
11358        check_insn(ctx, ISA_MIPS32R6);
11359        {
11360            TCGv_i32 fp0 = tcg_temp_new_i32();
11361            gen_load_fpr32(ctx, fp0, fs);
11362            gen_helper_float_class_s(fp0, cpu_env, fp0);
11363            gen_store_fpr32(ctx, fp0, fd);
11364            tcg_temp_free_i32(fp0);
11365        }
11366        break;
11367    case OPC_MIN_S: /* OPC_RECIP2_S */
11368        if (ctx->insn_flags & ISA_MIPS32R6) {
11369            /* OPC_MIN_S */
11370            TCGv_i32 fp0 = tcg_temp_new_i32();
11371            TCGv_i32 fp1 = tcg_temp_new_i32();
11372            TCGv_i32 fp2 = tcg_temp_new_i32();
11373            gen_load_fpr32(ctx, fp0, fs);
11374            gen_load_fpr32(ctx, fp1, ft);
11375            gen_helper_float_min_s(fp2, cpu_env, fp0, fp1);
11376            gen_store_fpr32(ctx, fp2, fd);
11377            tcg_temp_free_i32(fp2);
11378            tcg_temp_free_i32(fp1);
11379            tcg_temp_free_i32(fp0);
11380        } else {
11381            /* OPC_RECIP2_S */
11382            check_cp1_64bitmode(ctx);
11383            {
11384                TCGv_i32 fp0 = tcg_temp_new_i32();
11385                TCGv_i32 fp1 = tcg_temp_new_i32();
11386
11387                gen_load_fpr32(ctx, fp0, fs);
11388                gen_load_fpr32(ctx, fp1, ft);
11389                gen_helper_float_recip2_s(fp0, cpu_env, fp0, fp1);
11390                tcg_temp_free_i32(fp1);
11391                gen_store_fpr32(ctx, fp0, fd);
11392                tcg_temp_free_i32(fp0);
11393            }
11394        }
11395        break;
11396    case OPC_MINA_S: /* OPC_RECIP1_S */
11397        if (ctx->insn_flags & ISA_MIPS32R6) {
11398            /* OPC_MINA_S */
11399            TCGv_i32 fp0 = tcg_temp_new_i32();
11400            TCGv_i32 fp1 = tcg_temp_new_i32();
11401            TCGv_i32 fp2 = tcg_temp_new_i32();
11402            gen_load_fpr32(ctx, fp0, fs);
11403            gen_load_fpr32(ctx, fp1, ft);
11404            gen_helper_float_mina_s(fp2, cpu_env, fp0, fp1);
11405            gen_store_fpr32(ctx, fp2, fd);
11406            tcg_temp_free_i32(fp2);
11407            tcg_temp_free_i32(fp1);
11408            tcg_temp_free_i32(fp0);
11409        } else {
11410            /* OPC_RECIP1_S */
11411            check_cp1_64bitmode(ctx);
11412            {
11413                TCGv_i32 fp0 = tcg_temp_new_i32();
11414
11415                gen_load_fpr32(ctx, fp0, fs);
11416                gen_helper_float_recip1_s(fp0, cpu_env, fp0);
11417                gen_store_fpr32(ctx, fp0, fd);
11418                tcg_temp_free_i32(fp0);
11419            }
11420        }
11421        break;
11422    case OPC_MAX_S: /* OPC_RSQRT1_S */
11423        if (ctx->insn_flags & ISA_MIPS32R6) {
11424            /* OPC_MAX_S */
11425            TCGv_i32 fp0 = tcg_temp_new_i32();
11426            TCGv_i32 fp1 = tcg_temp_new_i32();
11427            gen_load_fpr32(ctx, fp0, fs);
11428            gen_load_fpr32(ctx, fp1, ft);
11429            gen_helper_float_max_s(fp1, cpu_env, fp0, fp1);
11430            gen_store_fpr32(ctx, fp1, fd);
11431            tcg_temp_free_i32(fp1);
11432            tcg_temp_free_i32(fp0);
11433        } else {
11434            /* OPC_RSQRT1_S */
11435            check_cp1_64bitmode(ctx);
11436            {
11437                TCGv_i32 fp0 = tcg_temp_new_i32();
11438
11439                gen_load_fpr32(ctx, fp0, fs);
11440                gen_helper_float_rsqrt1_s(fp0, cpu_env, fp0);
11441                gen_store_fpr32(ctx, fp0, fd);
11442                tcg_temp_free_i32(fp0);
11443            }
11444        }
11445        break;
11446    case OPC_MAXA_S: /* OPC_RSQRT2_S */
11447        if (ctx->insn_flags & ISA_MIPS32R6) {
11448            /* OPC_MAXA_S */
11449            TCGv_i32 fp0 = tcg_temp_new_i32();
11450            TCGv_i32 fp1 = tcg_temp_new_i32();
11451            gen_load_fpr32(ctx, fp0, fs);
11452            gen_load_fpr32(ctx, fp1, ft);
11453            gen_helper_float_maxa_s(fp1, cpu_env, fp0, fp1);
11454            gen_store_fpr32(ctx, fp1, fd);
11455            tcg_temp_free_i32(fp1);
11456            tcg_temp_free_i32(fp0);
11457        } else {
11458            /* OPC_RSQRT2_S */
11459            check_cp1_64bitmode(ctx);
11460            {
11461                TCGv_i32 fp0 = tcg_temp_new_i32();
11462                TCGv_i32 fp1 = tcg_temp_new_i32();
11463
11464                gen_load_fpr32(ctx, fp0, fs);
11465                gen_load_fpr32(ctx, fp1, ft);
11466                gen_helper_float_rsqrt2_s(fp0, cpu_env, fp0, fp1);
11467                tcg_temp_free_i32(fp1);
11468                gen_store_fpr32(ctx, fp0, fd);
11469                tcg_temp_free_i32(fp0);
11470            }
11471        }
11472        break;
11473    case OPC_CVT_D_S:
11474        check_cp1_registers(ctx, fd);
11475        {
11476            TCGv_i32 fp32 = tcg_temp_new_i32();
11477            TCGv_i64 fp64 = tcg_temp_new_i64();
11478
11479            gen_load_fpr32(ctx, fp32, fs);
11480            gen_helper_float_cvtd_s(fp64, cpu_env, fp32);
11481            tcg_temp_free_i32(fp32);
11482            gen_store_fpr64(ctx, fp64, fd);
11483            tcg_temp_free_i64(fp64);
11484        }
11485        break;
11486    case OPC_CVT_W_S:
11487        {
11488            TCGv_i32 fp0 = tcg_temp_new_i32();
11489
11490            gen_load_fpr32(ctx, fp0, fs);
11491            if (ctx->nan2008) {
11492                gen_helper_float_cvt_2008_w_s(fp0, cpu_env, fp0);
11493            } else {
11494                gen_helper_float_cvt_w_s(fp0, cpu_env, fp0);
11495            }
11496            gen_store_fpr32(ctx, fp0, fd);
11497            tcg_temp_free_i32(fp0);
11498        }
11499        break;
11500    case OPC_CVT_L_S:
11501        check_cp1_64bitmode(ctx);
11502        {
11503            TCGv_i32 fp32 = tcg_temp_new_i32();
11504            TCGv_i64 fp64 = tcg_temp_new_i64();
11505
11506            gen_load_fpr32(ctx, fp32, fs);
11507            if (ctx->nan2008) {
11508                gen_helper_float_cvt_2008_l_s(fp64, cpu_env, fp32);
11509            } else {
11510                gen_helper_float_cvt_l_s(fp64, cpu_env, fp32);
11511            }
11512            tcg_temp_free_i32(fp32);
11513            gen_store_fpr64(ctx, fp64, fd);
11514            tcg_temp_free_i64(fp64);
11515        }
11516        break;
11517    case OPC_CVT_PS_S:
11518        check_ps(ctx);
11519        {
11520            TCGv_i64 fp64 = tcg_temp_new_i64();
11521            TCGv_i32 fp32_0 = tcg_temp_new_i32();
11522            TCGv_i32 fp32_1 = tcg_temp_new_i32();
11523
11524            gen_load_fpr32(ctx, fp32_0, fs);
11525            gen_load_fpr32(ctx, fp32_1, ft);
11526            tcg_gen_concat_i32_i64(fp64, fp32_1, fp32_0);
11527            tcg_temp_free_i32(fp32_1);
11528            tcg_temp_free_i32(fp32_0);
11529            gen_store_fpr64(ctx, fp64, fd);
11530            tcg_temp_free_i64(fp64);
11531        }
11532        break;
11533    case OPC_CMP_F_S:
11534    case OPC_CMP_UN_S:
11535    case OPC_CMP_EQ_S:
11536    case OPC_CMP_UEQ_S:
11537    case OPC_CMP_OLT_S:
11538    case OPC_CMP_ULT_S:
11539    case OPC_CMP_OLE_S:
11540    case OPC_CMP_ULE_S:
11541    case OPC_CMP_SF_S:
11542    case OPC_CMP_NGLE_S:
11543    case OPC_CMP_SEQ_S:
11544    case OPC_CMP_NGL_S:
11545    case OPC_CMP_LT_S:
11546    case OPC_CMP_NGE_S:
11547    case OPC_CMP_LE_S:
11548    case OPC_CMP_NGT_S:
11549        check_insn_opc_removed(ctx, ISA_MIPS32R6);
11550        if (ctx->opcode & (1 << 6)) {
11551            gen_cmpabs_s(ctx, func-48, ft, fs, cc);
11552        } else {
11553            gen_cmp_s(ctx, func-48, ft, fs, cc);
11554        }
11555        break;
11556    case OPC_ADD_D:
11557        check_cp1_registers(ctx, fs | ft | fd);
11558        {
11559            TCGv_i64 fp0 = tcg_temp_new_i64();
11560            TCGv_i64 fp1 = tcg_temp_new_i64();
11561
11562            gen_load_fpr64(ctx, fp0, fs);
11563            gen_load_fpr64(ctx, fp1, ft);
11564            gen_helper_float_add_d(fp0, cpu_env, fp0, fp1);
11565            tcg_temp_free_i64(fp1);
11566            gen_store_fpr64(ctx, fp0, fd);
11567            tcg_temp_free_i64(fp0);
11568        }
11569        break;
11570    case OPC_SUB_D:
11571        check_cp1_registers(ctx, fs | ft | fd);
11572        {
11573            TCGv_i64 fp0 = tcg_temp_new_i64();
11574            TCGv_i64 fp1 = tcg_temp_new_i64();
11575
11576            gen_load_fpr64(ctx, fp0, fs);
11577            gen_load_fpr64(ctx, fp1, ft);
11578            gen_helper_float_sub_d(fp0, cpu_env, fp0, fp1);
11579            tcg_temp_free_i64(fp1);
11580            gen_store_fpr64(ctx, fp0, fd);
11581            tcg_temp_free_i64(fp0);
11582        }
11583        break;
11584    case OPC_MUL_D:
11585        check_cp1_registers(ctx, fs | ft | fd);
11586        {
11587            TCGv_i64 fp0 = tcg_temp_new_i64();
11588            TCGv_i64 fp1 = tcg_temp_new_i64();
11589
11590            gen_load_fpr64(ctx, fp0, fs);
11591            gen_load_fpr64(ctx, fp1, ft);
11592            gen_helper_float_mul_d(fp0, cpu_env, fp0, fp1);
11593            tcg_temp_free_i64(fp1);
11594            gen_store_fpr64(ctx, fp0, fd);
11595            tcg_temp_free_i64(fp0);
11596        }
11597        break;
11598    case OPC_DIV_D:
11599        check_cp1_registers(ctx, fs | ft | fd);
11600        {
11601            TCGv_i64 fp0 = tcg_temp_new_i64();
11602            TCGv_i64 fp1 = tcg_temp_new_i64();
11603
11604            gen_load_fpr64(ctx, fp0, fs);
11605            gen_load_fpr64(ctx, fp1, ft);
11606            gen_helper_float_div_d(fp0, cpu_env, fp0, fp1);
11607            tcg_temp_free_i64(fp1);
11608            gen_store_fpr64(ctx, fp0, fd);
11609            tcg_temp_free_i64(fp0);
11610        }
11611        break;
11612    case OPC_SQRT_D:
11613        check_cp1_registers(ctx, fs | fd);
11614        {
11615            TCGv_i64 fp0 = tcg_temp_new_i64();
11616
11617            gen_load_fpr64(ctx, fp0, fs);
11618            gen_helper_float_sqrt_d(fp0, cpu_env, fp0);
11619            gen_store_fpr64(ctx, fp0, fd);
11620            tcg_temp_free_i64(fp0);
11621        }
11622        break;
11623    case OPC_ABS_D:
11624        check_cp1_registers(ctx, fs | fd);
11625        {
11626            TCGv_i64 fp0 = tcg_temp_new_i64();
11627
11628            gen_load_fpr64(ctx, fp0, fs);
11629            if (ctx->abs2008) {
11630                tcg_gen_andi_i64(fp0, fp0, 0x7fffffffffffffffULL);
11631            } else {
11632                gen_helper_float_abs_d(fp0, fp0);
11633            }
11634            gen_store_fpr64(ctx, fp0, fd);
11635            tcg_temp_free_i64(fp0);
11636        }
11637        break;
11638    case OPC_MOV_D:
11639        check_cp1_registers(ctx, fs | fd);
11640        {
11641            TCGv_i64 fp0 = tcg_temp_new_i64();
11642
11643            gen_load_fpr64(ctx, fp0, fs);
11644            gen_store_fpr64(ctx, fp0, fd);
11645            tcg_temp_free_i64(fp0);
11646        }
11647        break;
11648    case OPC_NEG_D:
11649        check_cp1_registers(ctx, fs | fd);
11650        {
11651            TCGv_i64 fp0 = tcg_temp_new_i64();
11652
11653            gen_load_fpr64(ctx, fp0, fs);
11654            if (ctx->abs2008) {
11655                tcg_gen_xori_i64(fp0, fp0, 1ULL << 63);
11656            } else {
11657                gen_helper_float_chs_d(fp0, fp0);
11658            }
11659            gen_store_fpr64(ctx, fp0, fd);
11660            tcg_temp_free_i64(fp0);
11661        }
11662        break;
11663    case OPC_ROUND_L_D:
11664        check_cp1_64bitmode(ctx);
11665        {
11666            TCGv_i64 fp0 = tcg_temp_new_i64();
11667
11668            gen_load_fpr64(ctx, fp0, fs);
11669            if (ctx->nan2008) {
11670                gen_helper_float_round_2008_l_d(fp0, cpu_env, fp0);
11671            } else {
11672                gen_helper_float_round_l_d(fp0, cpu_env, fp0);
11673            }
11674            gen_store_fpr64(ctx, fp0, fd);
11675            tcg_temp_free_i64(fp0);
11676        }
11677        break;
11678    case OPC_TRUNC_L_D:
11679        check_cp1_64bitmode(ctx);
11680        {
11681            TCGv_i64 fp0 = tcg_temp_new_i64();
11682
11683            gen_load_fpr64(ctx, fp0, fs);
11684            if (ctx->nan2008) {
11685                gen_helper_float_trunc_2008_l_d(fp0, cpu_env, fp0);
11686            } else {
11687                gen_helper_float_trunc_l_d(fp0, cpu_env, fp0);
11688            }
11689            gen_store_fpr64(ctx, fp0, fd);
11690            tcg_temp_free_i64(fp0);
11691        }
11692        break;
11693    case OPC_CEIL_L_D:
11694        check_cp1_64bitmode(ctx);
11695        {
11696            TCGv_i64 fp0 = tcg_temp_new_i64();
11697
11698            gen_load_fpr64(ctx, fp0, fs);
11699            if (ctx->nan2008) {
11700                gen_helper_float_ceil_2008_l_d(fp0, cpu_env, fp0);
11701            } else {
11702                gen_helper_float_ceil_l_d(fp0, cpu_env, fp0);
11703            }
11704            gen_store_fpr64(ctx, fp0, fd);
11705            tcg_temp_free_i64(fp0);
11706        }
11707        break;
11708    case OPC_FLOOR_L_D:
11709        check_cp1_64bitmode(ctx);
11710        {
11711            TCGv_i64 fp0 = tcg_temp_new_i64();
11712
11713            gen_load_fpr64(ctx, fp0, fs);
11714            if (ctx->nan2008) {
11715                gen_helper_float_floor_2008_l_d(fp0, cpu_env, fp0);
11716            } else {
11717                gen_helper_float_floor_l_d(fp0, cpu_env, fp0);
11718            }
11719            gen_store_fpr64(ctx, fp0, fd);
11720            tcg_temp_free_i64(fp0);
11721        }
11722        break;
11723    case OPC_ROUND_W_D:
11724        check_cp1_registers(ctx, fs);
11725        {
11726            TCGv_i32 fp32 = tcg_temp_new_i32();
11727            TCGv_i64 fp64 = tcg_temp_new_i64();
11728
11729            gen_load_fpr64(ctx, fp64, fs);
11730            if (ctx->nan2008) {
11731                gen_helper_float_round_2008_w_d(fp32, cpu_env, fp64);
11732            } else {
11733                gen_helper_float_round_w_d(fp32, cpu_env, fp64);
11734            }
11735            tcg_temp_free_i64(fp64);
11736            gen_store_fpr32(ctx, fp32, fd);
11737            tcg_temp_free_i32(fp32);
11738        }
11739        break;
11740    case OPC_TRUNC_W_D:
11741        check_cp1_registers(ctx, fs);
11742        {
11743            TCGv_i32 fp32 = tcg_temp_new_i32();
11744            TCGv_i64 fp64 = tcg_temp_new_i64();
11745
11746            gen_load_fpr64(ctx, fp64, fs);
11747            if (ctx->nan2008) {
11748                gen_helper_float_trunc_2008_w_d(fp32, cpu_env, fp64);
11749            } else {
11750                gen_helper_float_trunc_w_d(fp32, cpu_env, fp64);
11751            }
11752            tcg_temp_free_i64(fp64);
11753            gen_store_fpr32(ctx, fp32, fd);
11754            tcg_temp_free_i32(fp32);
11755        }
11756        break;
11757    case OPC_CEIL_W_D:
11758        check_cp1_registers(ctx, fs);
11759        {
11760            TCGv_i32 fp32 = tcg_temp_new_i32();
11761            TCGv_i64 fp64 = tcg_temp_new_i64();
11762
11763            gen_load_fpr64(ctx, fp64, fs);
11764            if (ctx->nan2008) {
11765                gen_helper_float_ceil_2008_w_d(fp32, cpu_env, fp64);
11766            } else {
11767                gen_helper_float_ceil_w_d(fp32, cpu_env, fp64);
11768            }
11769            tcg_temp_free_i64(fp64);
11770            gen_store_fpr32(ctx, fp32, fd);
11771            tcg_temp_free_i32(fp32);
11772        }
11773        break;
11774    case OPC_FLOOR_W_D:
11775        check_cp1_registers(ctx, fs);
11776        {
11777            TCGv_i32 fp32 = tcg_temp_new_i32();
11778            TCGv_i64 fp64 = tcg_temp_new_i64();
11779
11780            gen_load_fpr64(ctx, fp64, fs);
11781            if (ctx->nan2008) {
11782                gen_helper_float_floor_2008_w_d(fp32, cpu_env, fp64);
11783            } else {
11784                gen_helper_float_floor_w_d(fp32, cpu_env, fp64);
11785            }
11786            tcg_temp_free_i64(fp64);
11787            gen_store_fpr32(ctx, fp32, fd);
11788            tcg_temp_free_i32(fp32);
11789        }
11790        break;
11791    case OPC_SEL_D:
11792        check_insn(ctx, ISA_MIPS32R6);
11793        gen_sel_d(ctx, op1, fd, ft, fs);
11794        break;
11795    case OPC_SELEQZ_D:
11796        check_insn(ctx, ISA_MIPS32R6);
11797        gen_sel_d(ctx, op1, fd, ft, fs);
11798        break;
11799    case OPC_SELNEZ_D:
11800        check_insn(ctx, ISA_MIPS32R6);
11801        gen_sel_d(ctx, op1, fd, ft, fs);
11802        break;
11803    case OPC_MOVCF_D:
11804        check_insn_opc_removed(ctx, ISA_MIPS32R6);
11805        gen_movcf_d(ctx, fs, fd, (ft >> 2) & 0x7, ft & 0x1);
11806        break;
11807    case OPC_MOVZ_D:
11808        check_insn_opc_removed(ctx, ISA_MIPS32R6);
11809        {
11810            TCGLabel *l1 = gen_new_label();
11811            TCGv_i64 fp0;
11812
11813            if (ft != 0) {
11814                tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[ft], 0, l1);
11815            }
11816            fp0 = tcg_temp_new_i64();
11817            gen_load_fpr64(ctx, fp0, fs);
11818            gen_store_fpr64(ctx, fp0, fd);
11819            tcg_temp_free_i64(fp0);
11820            gen_set_label(l1);
11821        }
11822        break;
11823    case OPC_MOVN_D:
11824        check_insn_opc_removed(ctx, ISA_MIPS32R6);
11825        {
11826            TCGLabel *l1 = gen_new_label();
11827            TCGv_i64 fp0;
11828
11829            if (ft != 0) {
11830                tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[ft], 0, l1);
11831                fp0 = tcg_temp_new_i64();
11832                gen_load_fpr64(ctx, fp0, fs);
11833                gen_store_fpr64(ctx, fp0, fd);
11834                tcg_temp_free_i64(fp0);
11835                gen_set_label(l1);
11836            }
11837        }
11838        break;
11839    case OPC_RECIP_D:
11840        check_cp1_registers(ctx, fs | fd);
11841        {
11842            TCGv_i64 fp0 = tcg_temp_new_i64();
11843
11844            gen_load_fpr64(ctx, fp0, fs);
11845            gen_helper_float_recip_d(fp0, cpu_env, fp0);
11846            gen_store_fpr64(ctx, fp0, fd);
11847            tcg_temp_free_i64(fp0);
11848        }
11849        break;
11850    case OPC_RSQRT_D:
11851        check_cp1_registers(ctx, fs | fd);
11852        {
11853            TCGv_i64 fp0 = tcg_temp_new_i64();
11854
11855            gen_load_fpr64(ctx, fp0, fs);
11856            gen_helper_float_rsqrt_d(fp0, cpu_env, fp0);
11857            gen_store_fpr64(ctx, fp0, fd);
11858            tcg_temp_free_i64(fp0);
11859        }
11860        break;
11861    case OPC_MADDF_D:
11862        check_insn(ctx, ISA_MIPS32R6);
11863        {
11864            TCGv_i64 fp0 = tcg_temp_new_i64();
11865            TCGv_i64 fp1 = tcg_temp_new_i64();
11866            TCGv_i64 fp2 = tcg_temp_new_i64();
11867            gen_load_fpr64(ctx, fp0, fs);
11868            gen_load_fpr64(ctx, fp1, ft);
11869            gen_load_fpr64(ctx, fp2, fd);
11870            gen_helper_float_maddf_d(fp2, cpu_env, fp0, fp1, fp2);
11871            gen_store_fpr64(ctx, fp2, fd);
11872            tcg_temp_free_i64(fp2);
11873            tcg_temp_free_i64(fp1);
11874            tcg_temp_free_i64(fp0);
11875        }
11876        break;
11877    case OPC_MSUBF_D:
11878        check_insn(ctx, ISA_MIPS32R6);
11879        {
11880            TCGv_i64 fp0 = tcg_temp_new_i64();
11881            TCGv_i64 fp1 = tcg_temp_new_i64();
11882            TCGv_i64 fp2 = tcg_temp_new_i64();
11883            gen_load_fpr64(ctx, fp0, fs);
11884            gen_load_fpr64(ctx, fp1, ft);
11885            gen_load_fpr64(ctx, fp2, fd);
11886            gen_helper_float_msubf_d(fp2, cpu_env, fp0, fp1, fp2);
11887            gen_store_fpr64(ctx, fp2, fd);
11888            tcg_temp_free_i64(fp2);
11889            tcg_temp_free_i64(fp1);
11890            tcg_temp_free_i64(fp0);
11891        }
11892        break;
11893    case OPC_RINT_D:
11894        check_insn(ctx, ISA_MIPS32R6);
11895        {
11896            TCGv_i64 fp0 = tcg_temp_new_i64();
11897            gen_load_fpr64(ctx, fp0, fs);
11898            gen_helper_float_rint_d(fp0, cpu_env, fp0);
11899            gen_store_fpr64(ctx, fp0, fd);
11900            tcg_temp_free_i64(fp0);
11901        }
11902        break;
11903    case OPC_CLASS_D:
11904        check_insn(ctx, ISA_MIPS32R6);
11905        {
11906            TCGv_i64 fp0 = tcg_temp_new_i64();
11907            gen_load_fpr64(ctx, fp0, fs);
11908            gen_helper_float_class_d(fp0, cpu_env, fp0);
11909            gen_store_fpr64(ctx, fp0, fd);
11910            tcg_temp_free_i64(fp0);
11911        }
11912        break;
11913    case OPC_MIN_D: /* OPC_RECIP2_D */
11914        if (ctx->insn_flags & ISA_MIPS32R6) {
11915            /* OPC_MIN_D */
11916            TCGv_i64 fp0 = tcg_temp_new_i64();
11917            TCGv_i64 fp1 = tcg_temp_new_i64();
11918            gen_load_fpr64(ctx, fp0, fs);
11919            gen_load_fpr64(ctx, fp1, ft);
11920            gen_helper_float_min_d(fp1, cpu_env, fp0, fp1);
11921            gen_store_fpr64(ctx, fp1, fd);
11922            tcg_temp_free_i64(fp1);
11923            tcg_temp_free_i64(fp0);
11924        } else {
11925            /* OPC_RECIP2_D */
11926            check_cp1_64bitmode(ctx);
11927            {
11928                TCGv_i64 fp0 = tcg_temp_new_i64();
11929                TCGv_i64 fp1 = tcg_temp_new_i64();
11930
11931                gen_load_fpr64(ctx, fp0, fs);
11932                gen_load_fpr64(ctx, fp1, ft);
11933                gen_helper_float_recip2_d(fp0, cpu_env, fp0, fp1);
11934                tcg_temp_free_i64(fp1);
11935                gen_store_fpr64(ctx, fp0, fd);
11936                tcg_temp_free_i64(fp0);
11937            }
11938        }
11939        break;
11940    case OPC_MINA_D: /* OPC_RECIP1_D */
11941        if (ctx->insn_flags & ISA_MIPS32R6) {
11942            /* OPC_MINA_D */
11943            TCGv_i64 fp0 = tcg_temp_new_i64();
11944            TCGv_i64 fp1 = tcg_temp_new_i64();
11945            gen_load_fpr64(ctx, fp0, fs);
11946            gen_load_fpr64(ctx, fp1, ft);
11947            gen_helper_float_mina_d(fp1, cpu_env, fp0, fp1);
11948            gen_store_fpr64(ctx, fp1, fd);
11949            tcg_temp_free_i64(fp1);
11950            tcg_temp_free_i64(fp0);
11951        } else {
11952            /* OPC_RECIP1_D */
11953            check_cp1_64bitmode(ctx);
11954            {
11955                TCGv_i64 fp0 = tcg_temp_new_i64();
11956
11957                gen_load_fpr64(ctx, fp0, fs);
11958                gen_helper_float_recip1_d(fp0, cpu_env, fp0);
11959                gen_store_fpr64(ctx, fp0, fd);
11960                tcg_temp_free_i64(fp0);
11961            }
11962        }
11963        break;
11964    case OPC_MAX_D: /*  OPC_RSQRT1_D */
11965        if (ctx->insn_flags & ISA_MIPS32R6) {
11966            /* OPC_MAX_D */
11967            TCGv_i64 fp0 = tcg_temp_new_i64();
11968            TCGv_i64 fp1 = tcg_temp_new_i64();
11969            gen_load_fpr64(ctx, fp0, fs);
11970            gen_load_fpr64(ctx, fp1, ft);
11971            gen_helper_float_max_d(fp1, cpu_env, fp0, fp1);
11972            gen_store_fpr64(ctx, fp1, fd);
11973            tcg_temp_free_i64(fp1);
11974            tcg_temp_free_i64(fp0);
11975        } else {
11976            /* OPC_RSQRT1_D */
11977            check_cp1_64bitmode(ctx);
11978            {
11979                TCGv_i64 fp0 = tcg_temp_new_i64();
11980
11981                gen_load_fpr64(ctx, fp0, fs);
11982                gen_helper_float_rsqrt1_d(fp0, cpu_env, fp0);
11983                gen_store_fpr64(ctx, fp0, fd);
11984                tcg_temp_free_i64(fp0);
11985            }
11986        }
11987        break;
11988    case OPC_MAXA_D: /* OPC_RSQRT2_D */
11989        if (ctx->insn_flags & ISA_MIPS32R6) {
11990            /* OPC_MAXA_D */
11991            TCGv_i64 fp0 = tcg_temp_new_i64();
11992            TCGv_i64 fp1 = tcg_temp_new_i64();
11993            gen_load_fpr64(ctx, fp0, fs);
11994            gen_load_fpr64(ctx, fp1, ft);
11995            gen_helper_float_maxa_d(fp1, cpu_env, fp0, fp1);
11996            gen_store_fpr64(ctx, fp1, fd);
11997            tcg_temp_free_i64(fp1);
11998            tcg_temp_free_i64(fp0);
11999        } else {
12000            /* OPC_RSQRT2_D */
12001            check_cp1_64bitmode(ctx);
12002            {
12003                TCGv_i64 fp0 = tcg_temp_new_i64();
12004                TCGv_i64 fp1 = tcg_temp_new_i64();
12005
12006                gen_load_fpr64(ctx, fp0, fs);
12007                gen_load_fpr64(ctx, fp1, ft);
12008                gen_helper_float_rsqrt2_d(fp0, cpu_env, fp0, fp1);
12009                tcg_temp_free_i64(fp1);
12010                gen_store_fpr64(ctx, fp0, fd);
12011                tcg_temp_free_i64(fp0);
12012            }
12013        }
12014        break;
12015    case OPC_CMP_F_D:
12016    case OPC_CMP_UN_D:
12017    case OPC_CMP_EQ_D:
12018    case OPC_CMP_UEQ_D:
12019    case OPC_CMP_OLT_D:
12020    case OPC_CMP_ULT_D:
12021    case OPC_CMP_OLE_D:
12022    case OPC_CMP_ULE_D:
12023    case OPC_CMP_SF_D:
12024    case OPC_CMP_NGLE_D:
12025    case OPC_CMP_SEQ_D:
12026    case OPC_CMP_NGL_D:
12027    case OPC_CMP_LT_D:
12028    case OPC_CMP_NGE_D:
12029    case OPC_CMP_LE_D:
12030    case OPC_CMP_NGT_D:
12031        check_insn_opc_removed(ctx, ISA_MIPS32R6);
12032        if (ctx->opcode & (1 << 6)) {
12033            gen_cmpabs_d(ctx, func-48, ft, fs, cc);
12034        } else {
12035            gen_cmp_d(ctx, func-48, ft, fs, cc);
12036        }
12037        break;
12038    case OPC_CVT_S_D:
12039        check_cp1_registers(ctx, fs);
12040        {
12041            TCGv_i32 fp32 = tcg_temp_new_i32();
12042            TCGv_i64 fp64 = tcg_temp_new_i64();
12043
12044            gen_load_fpr64(ctx, fp64, fs);
12045            gen_helper_float_cvts_d(fp32, cpu_env, fp64);
12046            tcg_temp_free_i64(fp64);
12047            gen_store_fpr32(ctx, fp32, fd);
12048            tcg_temp_free_i32(fp32);
12049        }
12050        break;
12051    case OPC_CVT_W_D:
12052        check_cp1_registers(ctx, fs);
12053        {
12054            TCGv_i32 fp32 = tcg_temp_new_i32();
12055            TCGv_i64 fp64 = tcg_temp_new_i64();
12056
12057            gen_load_fpr64(ctx, fp64, fs);
12058            if (ctx->nan2008) {
12059                gen_helper_float_cvt_2008_w_d(fp32, cpu_env, fp64);
12060            } else {
12061                gen_helper_float_cvt_w_d(fp32, cpu_env, fp64);
12062            }
12063            tcg_temp_free_i64(fp64);
12064            gen_store_fpr32(ctx, fp32, fd);
12065            tcg_temp_free_i32(fp32);
12066        }
12067        break;
12068    case OPC_CVT_L_D:
12069        check_cp1_64bitmode(ctx);
12070        {
12071            TCGv_i64 fp0 = tcg_temp_new_i64();
12072
12073            gen_load_fpr64(ctx, fp0, fs);
12074            if (ctx->nan2008) {
12075                gen_helper_float_cvt_2008_l_d(fp0, cpu_env, fp0);
12076            } else {
12077                gen_helper_float_cvt_l_d(fp0, cpu_env, fp0);
12078            }
12079            gen_store_fpr64(ctx, fp0, fd);
12080            tcg_temp_free_i64(fp0);
12081        }
12082        break;
12083    case OPC_CVT_S_W:
12084        {
12085            TCGv_i32 fp0 = tcg_temp_new_i32();
12086
12087            gen_load_fpr32(ctx, fp0, fs);
12088            gen_helper_float_cvts_w(fp0, cpu_env, fp0);
12089            gen_store_fpr32(ctx, fp0, fd);
12090            tcg_temp_free_i32(fp0);
12091        }
12092        break;
12093    case OPC_CVT_D_W:
12094        check_cp1_registers(ctx, fd);
12095        {
12096            TCGv_i32 fp32 = tcg_temp_new_i32();
12097            TCGv_i64 fp64 = tcg_temp_new_i64();
12098
12099            gen_load_fpr32(ctx, fp32, fs);
12100            gen_helper_float_cvtd_w(fp64, cpu_env, fp32);
12101            tcg_temp_free_i32(fp32);
12102            gen_store_fpr64(ctx, fp64, fd);
12103            tcg_temp_free_i64(fp64);
12104        }
12105        break;
12106    case OPC_CVT_S_L:
12107        check_cp1_64bitmode(ctx);
12108        {
12109            TCGv_i32 fp32 = tcg_temp_new_i32();
12110            TCGv_i64 fp64 = tcg_temp_new_i64();
12111
12112            gen_load_fpr64(ctx, fp64, fs);
12113            gen_helper_float_cvts_l(fp32, cpu_env, fp64);
12114            tcg_temp_free_i64(fp64);
12115            gen_store_fpr32(ctx, fp32, fd);
12116            tcg_temp_free_i32(fp32);
12117        }
12118        break;
12119    case OPC_CVT_D_L:
12120        check_cp1_64bitmode(ctx);
12121        {
12122            TCGv_i64 fp0 = tcg_temp_new_i64();
12123
12124            gen_load_fpr64(ctx, fp0, fs);
12125            gen_helper_float_cvtd_l(fp0, cpu_env, fp0);
12126            gen_store_fpr64(ctx, fp0, fd);
12127            tcg_temp_free_i64(fp0);
12128        }
12129        break;
12130    case OPC_CVT_PS_PW:
12131        check_ps(ctx);
12132        {
12133            TCGv_i64 fp0 = tcg_temp_new_i64();
12134
12135            gen_load_fpr64(ctx, fp0, fs);
12136            gen_helper_float_cvtps_pw(fp0, cpu_env, fp0);
12137            gen_store_fpr64(ctx, fp0, fd);
12138            tcg_temp_free_i64(fp0);
12139        }
12140        break;
12141    case OPC_ADD_PS:
12142        check_ps(ctx);
12143        {
12144            TCGv_i64 fp0 = tcg_temp_new_i64();
12145            TCGv_i64 fp1 = tcg_temp_new_i64();
12146
12147            gen_load_fpr64(ctx, fp0, fs);
12148            gen_load_fpr64(ctx, fp1, ft);
12149            gen_helper_float_add_ps(fp0, cpu_env, fp0, fp1);
12150            tcg_temp_free_i64(fp1);
12151            gen_store_fpr64(ctx, fp0, fd);
12152            tcg_temp_free_i64(fp0);
12153        }
12154        break;
12155    case OPC_SUB_PS:
12156        check_ps(ctx);
12157        {
12158            TCGv_i64 fp0 = tcg_temp_new_i64();
12159            TCGv_i64 fp1 = tcg_temp_new_i64();
12160
12161            gen_load_fpr64(ctx, fp0, fs);
12162            gen_load_fpr64(ctx, fp1, ft);
12163            gen_helper_float_sub_ps(fp0, cpu_env, fp0, fp1);
12164            tcg_temp_free_i64(fp1);
12165            gen_store_fpr64(ctx, fp0, fd);
12166            tcg_temp_free_i64(fp0);
12167        }
12168        break;
12169    case OPC_MUL_PS:
12170        check_ps(ctx);
12171        {
12172            TCGv_i64 fp0 = tcg_temp_new_i64();
12173            TCGv_i64 fp1 = tcg_temp_new_i64();
12174
12175            gen_load_fpr64(ctx, fp0, fs);
12176            gen_load_fpr64(ctx, fp1, ft);
12177            gen_helper_float_mul_ps(fp0, cpu_env, fp0, fp1);
12178            tcg_temp_free_i64(fp1);
12179            gen_store_fpr64(ctx, fp0, fd);
12180            tcg_temp_free_i64(fp0);
12181        }
12182        break;
12183    case OPC_ABS_PS:
12184        check_ps(ctx);
12185        {
12186            TCGv_i64 fp0 = tcg_temp_new_i64();
12187
12188            gen_load_fpr64(ctx, fp0, fs);
12189            gen_helper_float_abs_ps(fp0, fp0);
12190            gen_store_fpr64(ctx, fp0, fd);
12191            tcg_temp_free_i64(fp0);
12192        }
12193        break;
12194    case OPC_MOV_PS:
12195        check_ps(ctx);
12196        {
12197            TCGv_i64 fp0 = tcg_temp_new_i64();
12198
12199            gen_load_fpr64(ctx, fp0, fs);
12200            gen_store_fpr64(ctx, fp0, fd);
12201            tcg_temp_free_i64(fp0);
12202        }
12203        break;
12204    case OPC_NEG_PS:
12205        check_ps(ctx);
12206        {
12207            TCGv_i64 fp0 = tcg_temp_new_i64();
12208
12209            gen_load_fpr64(ctx, fp0, fs);
12210            gen_helper_float_chs_ps(fp0, fp0);
12211            gen_store_fpr64(ctx, fp0, fd);
12212            tcg_temp_free_i64(fp0);
12213        }
12214        break;
12215    case OPC_MOVCF_PS:
12216        check_ps(ctx);
12217        gen_movcf_ps(ctx, fs, fd, (ft >> 2) & 0x7, ft & 0x1);
12218        break;
12219    case OPC_MOVZ_PS:
12220        check_ps(ctx);
12221        {
12222            TCGLabel *l1 = gen_new_label();
12223            TCGv_i64 fp0;
12224
12225            if (ft != 0) {
12226                tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[ft], 0, l1);
12227            }
12228            fp0 = tcg_temp_new_i64();
12229            gen_load_fpr64(ctx, fp0, fs);
12230            gen_store_fpr64(ctx, fp0, fd);
12231            tcg_temp_free_i64(fp0);
12232            gen_set_label(l1);
12233        }
12234        break;
12235    case OPC_MOVN_PS:
12236        check_ps(ctx);
12237        {
12238            TCGLabel *l1 = gen_new_label();
12239            TCGv_i64 fp0;
12240
12241            if (ft != 0) {
12242                tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[ft], 0, l1);
12243                fp0 = tcg_temp_new_i64();
12244                gen_load_fpr64(ctx, fp0, fs);
12245                gen_store_fpr64(ctx, fp0, fd);
12246                tcg_temp_free_i64(fp0);
12247                gen_set_label(l1);
12248            }
12249        }
12250        break;
12251    case OPC_ADDR_PS:
12252        check_ps(ctx);
12253        {
12254            TCGv_i64 fp0 = tcg_temp_new_i64();
12255            TCGv_i64 fp1 = tcg_temp_new_i64();
12256
12257            gen_load_fpr64(ctx, fp0, ft);
12258            gen_load_fpr64(ctx, fp1, fs);
12259            gen_helper_float_addr_ps(fp0, cpu_env, fp0, fp1);
12260            tcg_temp_free_i64(fp1);
12261            gen_store_fpr64(ctx, fp0, fd);
12262            tcg_temp_free_i64(fp0);
12263        }
12264        break;
12265    case OPC_MULR_PS:
12266        check_ps(ctx);
12267        {
12268            TCGv_i64 fp0 = tcg_temp_new_i64();
12269            TCGv_i64 fp1 = tcg_temp_new_i64();
12270
12271            gen_load_fpr64(ctx, fp0, ft);
12272            gen_load_fpr64(ctx, fp1, fs);
12273            gen_helper_float_mulr_ps(fp0, cpu_env, fp0, fp1);
12274            tcg_temp_free_i64(fp1);
12275            gen_store_fpr64(ctx, fp0, fd);
12276            tcg_temp_free_i64(fp0);
12277        }
12278        break;
12279    case OPC_RECIP2_PS:
12280        check_ps(ctx);
12281        {
12282            TCGv_i64 fp0 = tcg_temp_new_i64();
12283            TCGv_i64 fp1 = tcg_temp_new_i64();
12284
12285            gen_load_fpr64(ctx, fp0, fs);
12286            gen_load_fpr64(ctx, fp1, ft);
12287            gen_helper_float_recip2_ps(fp0, cpu_env, fp0, fp1);
12288            tcg_temp_free_i64(fp1);
12289            gen_store_fpr64(ctx, fp0, fd);
12290            tcg_temp_free_i64(fp0);
12291        }
12292        break;
12293    case OPC_RECIP1_PS:
12294        check_ps(ctx);
12295        {
12296            TCGv_i64 fp0 = tcg_temp_new_i64();
12297
12298            gen_load_fpr64(ctx, fp0, fs);
12299            gen_helper_float_recip1_ps(fp0, cpu_env, fp0);
12300            gen_store_fpr64(ctx, fp0, fd);
12301            tcg_temp_free_i64(fp0);
12302        }
12303        break;
12304    case OPC_RSQRT1_PS:
12305        check_ps(ctx);
12306        {
12307            TCGv_i64 fp0 = tcg_temp_new_i64();
12308
12309            gen_load_fpr64(ctx, fp0, fs);
12310            gen_helper_float_rsqrt1_ps(fp0, cpu_env, fp0);
12311            gen_store_fpr64(ctx, fp0, fd);
12312            tcg_temp_free_i64(fp0);
12313        }
12314        break;
12315    case OPC_RSQRT2_PS:
12316        check_ps(ctx);
12317        {
12318            TCGv_i64 fp0 = tcg_temp_new_i64();
12319            TCGv_i64 fp1 = tcg_temp_new_i64();
12320
12321            gen_load_fpr64(ctx, fp0, fs);
12322            gen_load_fpr64(ctx, fp1, ft);
12323            gen_helper_float_rsqrt2_ps(fp0, cpu_env, fp0, fp1);
12324            tcg_temp_free_i64(fp1);
12325            gen_store_fpr64(ctx, fp0, fd);
12326            tcg_temp_free_i64(fp0);
12327        }
12328        break;
12329    case OPC_CVT_S_PU:
12330        check_cp1_64bitmode(ctx);
12331        {
12332            TCGv_i32 fp0 = tcg_temp_new_i32();
12333
12334            gen_load_fpr32h(ctx, fp0, fs);
12335            gen_helper_float_cvts_pu(fp0, cpu_env, fp0);
12336            gen_store_fpr32(ctx, fp0, fd);
12337            tcg_temp_free_i32(fp0);
12338        }
12339        break;
12340    case OPC_CVT_PW_PS:
12341        check_ps(ctx);
12342        {
12343            TCGv_i64 fp0 = tcg_temp_new_i64();
12344
12345            gen_load_fpr64(ctx, fp0, fs);
12346            gen_helper_float_cvtpw_ps(fp0, cpu_env, fp0);
12347            gen_store_fpr64(ctx, fp0, fd);
12348            tcg_temp_free_i64(fp0);
12349        }
12350        break;
12351    case OPC_CVT_S_PL:
12352        check_cp1_64bitmode(ctx);
12353        {
12354            TCGv_i32 fp0 = tcg_temp_new_i32();
12355
12356            gen_load_fpr32(ctx, fp0, fs);
12357            gen_helper_float_cvts_pl(fp0, cpu_env, fp0);
12358            gen_store_fpr32(ctx, fp0, fd);
12359            tcg_temp_free_i32(fp0);
12360        }
12361        break;
12362    case OPC_PLL_PS:
12363        check_ps(ctx);
12364        {
12365            TCGv_i32 fp0 = tcg_temp_new_i32();
12366            TCGv_i32 fp1 = tcg_temp_new_i32();
12367
12368            gen_load_fpr32(ctx, fp0, fs);
12369            gen_load_fpr32(ctx, fp1, ft);
12370            gen_store_fpr32h(ctx, fp0, fd);
12371            gen_store_fpr32(ctx, fp1, fd);
12372            tcg_temp_free_i32(fp0);
12373            tcg_temp_free_i32(fp1);
12374        }
12375        break;
12376    case OPC_PLU_PS:
12377        check_ps(ctx);
12378        {
12379            TCGv_i32 fp0 = tcg_temp_new_i32();
12380            TCGv_i32 fp1 = tcg_temp_new_i32();
12381
12382            gen_load_fpr32(ctx, fp0, fs);
12383            gen_load_fpr32h(ctx, fp1, ft);
12384            gen_store_fpr32(ctx, fp1, fd);
12385            gen_store_fpr32h(ctx, fp0, fd);
12386            tcg_temp_free_i32(fp0);
12387            tcg_temp_free_i32(fp1);
12388        }
12389        break;
12390    case OPC_PUL_PS:
12391        check_ps(ctx);
12392        {
12393            TCGv_i32 fp0 = tcg_temp_new_i32();
12394            TCGv_i32 fp1 = tcg_temp_new_i32();
12395
12396            gen_load_fpr32h(ctx, fp0, fs);
12397            gen_load_fpr32(ctx, fp1, ft);
12398            gen_store_fpr32(ctx, fp1, fd);
12399            gen_store_fpr32h(ctx, fp0, fd);
12400            tcg_temp_free_i32(fp0);
12401            tcg_temp_free_i32(fp1);
12402        }
12403        break;
12404    case OPC_PUU_PS:
12405        check_ps(ctx);
12406        {
12407            TCGv_i32 fp0 = tcg_temp_new_i32();
12408            TCGv_i32 fp1 = tcg_temp_new_i32();
12409
12410            gen_load_fpr32h(ctx, fp0, fs);
12411            gen_load_fpr32h(ctx, fp1, ft);
12412            gen_store_fpr32(ctx, fp1, fd);
12413            gen_store_fpr32h(ctx, fp0, fd);
12414            tcg_temp_free_i32(fp0);
12415            tcg_temp_free_i32(fp1);
12416        }
12417        break;
12418    case OPC_CMP_F_PS:
12419    case OPC_CMP_UN_PS:
12420    case OPC_CMP_EQ_PS:
12421    case OPC_CMP_UEQ_PS:
12422    case OPC_CMP_OLT_PS:
12423    case OPC_CMP_ULT_PS:
12424    case OPC_CMP_OLE_PS:
12425    case OPC_CMP_ULE_PS:
12426    case OPC_CMP_SF_PS:
12427    case OPC_CMP_NGLE_PS:
12428    case OPC_CMP_SEQ_PS:
12429    case OPC_CMP_NGL_PS:
12430    case OPC_CMP_LT_PS:
12431    case OPC_CMP_NGE_PS:
12432    case OPC_CMP_LE_PS:
12433    case OPC_CMP_NGT_PS:
12434        if (ctx->opcode & (1 << 6)) {
12435            gen_cmpabs_ps(ctx, func-48, ft, fs, cc);
12436        } else {
12437            gen_cmp_ps(ctx, func-48, ft, fs, cc);
12438        }
12439        break;
12440    default:
12441        MIPS_INVAL("farith");
12442        generate_exception_end(ctx, EXCP_RI);
12443        return;
12444    }
12445}
12446
12447/* Coprocessor 3 (FPU) */
12448static void gen_flt3_ldst(DisasContext *ctx, uint32_t opc,
12449                          int fd, int fs, int base, int index)
12450{
12451    TCGv t0 = tcg_temp_new();
12452
12453    if (base == 0) {
12454        gen_load_gpr(t0, index);
12455    } else if (index == 0) {
12456        gen_load_gpr(t0, base);
12457    } else {
12458        gen_op_addr_add(ctx, t0, cpu_gpr[base], cpu_gpr[index]);
12459    }
12460    /*
12461     * Don't do NOP if destination is zero: we must perform the actual
12462     * memory access.
12463     */
12464    switch (opc) {
12465    case OPC_LWXC1:
12466        check_cop1x(ctx);
12467        {
12468            TCGv_i32 fp0 = tcg_temp_new_i32();
12469
12470            tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TESL);
12471            tcg_gen_trunc_tl_i32(fp0, t0);
12472            gen_store_fpr32(ctx, fp0, fd);
12473            tcg_temp_free_i32(fp0);
12474        }
12475        break;
12476    case OPC_LDXC1:
12477        check_cop1x(ctx);
12478        check_cp1_registers(ctx, fd);
12479        {
12480            TCGv_i64 fp0 = tcg_temp_new_i64();
12481            tcg_gen_qemu_ld_i64(fp0, t0, ctx->mem_idx, MO_TEQ);
12482            gen_store_fpr64(ctx, fp0, fd);
12483            tcg_temp_free_i64(fp0);
12484        }
12485        break;
12486    case OPC_LUXC1:
12487        check_cp1_64bitmode(ctx);
12488        tcg_gen_andi_tl(t0, t0, ~0x7);
12489        {
12490            TCGv_i64 fp0 = tcg_temp_new_i64();
12491
12492            tcg_gen_qemu_ld_i64(fp0, t0, ctx->mem_idx, MO_TEQ);
12493            gen_store_fpr64(ctx, fp0, fd);
12494            tcg_temp_free_i64(fp0);
12495        }
12496        break;
12497    case OPC_SWXC1:
12498        check_cop1x(ctx);
12499        {
12500            TCGv_i32 fp0 = tcg_temp_new_i32();
12501            gen_load_fpr32(ctx, fp0, fs);
12502            tcg_gen_qemu_st_i32(fp0, t0, ctx->mem_idx, MO_TEUL);
12503            tcg_temp_free_i32(fp0);
12504        }
12505        break;
12506    case OPC_SDXC1:
12507        check_cop1x(ctx);
12508        check_cp1_registers(ctx, fs);
12509        {
12510            TCGv_i64 fp0 = tcg_temp_new_i64();
12511            gen_load_fpr64(ctx, fp0, fs);
12512            tcg_gen_qemu_st_i64(fp0, t0, ctx->mem_idx, MO_TEQ);
12513            tcg_temp_free_i64(fp0);
12514        }
12515        break;
12516    case OPC_SUXC1:
12517        check_cp1_64bitmode(ctx);
12518        tcg_gen_andi_tl(t0, t0, ~0x7);
12519        {
12520            TCGv_i64 fp0 = tcg_temp_new_i64();
12521            gen_load_fpr64(ctx, fp0, fs);
12522            tcg_gen_qemu_st_i64(fp0, t0, ctx->mem_idx, MO_TEQ);
12523            tcg_temp_free_i64(fp0);
12524        }
12525        break;
12526    }
12527    tcg_temp_free(t0);
12528}
12529
12530static void gen_flt3_arith(DisasContext *ctx, uint32_t opc,
12531                           int fd, int fr, int fs, int ft)
12532{
12533    switch (opc) {
12534    case OPC_ALNV_PS:
12535        check_ps(ctx);
12536        {
12537            TCGv t0 = tcg_temp_local_new();
12538            TCGv_i32 fp = tcg_temp_new_i32();
12539            TCGv_i32 fph = tcg_temp_new_i32();
12540            TCGLabel *l1 = gen_new_label();
12541            TCGLabel *l2 = gen_new_label();
12542
12543            gen_load_gpr(t0, fr);
12544            tcg_gen_andi_tl(t0, t0, 0x7);
12545
12546            tcg_gen_brcondi_tl(TCG_COND_NE, t0, 0, l1);
12547            gen_load_fpr32(ctx, fp, fs);
12548            gen_load_fpr32h(ctx, fph, fs);
12549            gen_store_fpr32(ctx, fp, fd);
12550            gen_store_fpr32h(ctx, fph, fd);
12551            tcg_gen_br(l2);
12552            gen_set_label(l1);
12553            tcg_gen_brcondi_tl(TCG_COND_NE, t0, 4, l2);
12554            tcg_temp_free(t0);
12555#ifdef TARGET_WORDS_BIGENDIAN
12556            gen_load_fpr32(ctx, fp, fs);
12557            gen_load_fpr32h(ctx, fph, ft);
12558            gen_store_fpr32h(ctx, fp, fd);
12559            gen_store_fpr32(ctx, fph, fd);
12560#else
12561            gen_load_fpr32h(ctx, fph, fs);
12562            gen_load_fpr32(ctx, fp, ft);
12563            gen_store_fpr32(ctx, fph, fd);
12564            gen_store_fpr32h(ctx, fp, fd);
12565#endif
12566            gen_set_label(l2);
12567            tcg_temp_free_i32(fp);
12568            tcg_temp_free_i32(fph);
12569        }
12570        break;
12571    case OPC_MADD_S:
12572        check_cop1x(ctx);
12573        {
12574            TCGv_i32 fp0 = tcg_temp_new_i32();
12575            TCGv_i32 fp1 = tcg_temp_new_i32();
12576            TCGv_i32 fp2 = tcg_temp_new_i32();
12577
12578            gen_load_fpr32(ctx, fp0, fs);
12579            gen_load_fpr32(ctx, fp1, ft);
12580            gen_load_fpr32(ctx, fp2, fr);
12581            gen_helper_float_madd_s(fp2, cpu_env, fp0, fp1, fp2);
12582            tcg_temp_free_i32(fp0);
12583            tcg_temp_free_i32(fp1);
12584            gen_store_fpr32(ctx, fp2, fd);
12585            tcg_temp_free_i32(fp2);
12586        }
12587        break;
12588    case OPC_MADD_D:
12589        check_cop1x(ctx);
12590        check_cp1_registers(ctx, fd | fs | ft | fr);
12591        {
12592            TCGv_i64 fp0 = tcg_temp_new_i64();
12593            TCGv_i64 fp1 = tcg_temp_new_i64();
12594            TCGv_i64 fp2 = tcg_temp_new_i64();
12595
12596            gen_load_fpr64(ctx, fp0, fs);
12597            gen_load_fpr64(ctx, fp1, ft);
12598            gen_load_fpr64(ctx, fp2, fr);
12599            gen_helper_float_madd_d(fp2, cpu_env, fp0, fp1, fp2);
12600            tcg_temp_free_i64(fp0);
12601            tcg_temp_free_i64(fp1);
12602            gen_store_fpr64(ctx, fp2, fd);
12603            tcg_temp_free_i64(fp2);
12604        }
12605        break;
12606    case OPC_MADD_PS:
12607        check_ps(ctx);
12608        {
12609            TCGv_i64 fp0 = tcg_temp_new_i64();
12610            TCGv_i64 fp1 = tcg_temp_new_i64();
12611            TCGv_i64 fp2 = tcg_temp_new_i64();
12612
12613            gen_load_fpr64(ctx, fp0, fs);
12614            gen_load_fpr64(ctx, fp1, ft);
12615            gen_load_fpr64(ctx, fp2, fr);
12616            gen_helper_float_madd_ps(fp2, cpu_env, fp0, fp1, fp2);
12617            tcg_temp_free_i64(fp0);
12618            tcg_temp_free_i64(fp1);
12619            gen_store_fpr64(ctx, fp2, fd);
12620            tcg_temp_free_i64(fp2);
12621        }
12622        break;
12623    case OPC_MSUB_S:
12624        check_cop1x(ctx);
12625        {
12626            TCGv_i32 fp0 = tcg_temp_new_i32();
12627            TCGv_i32 fp1 = tcg_temp_new_i32();
12628            TCGv_i32 fp2 = tcg_temp_new_i32();
12629
12630            gen_load_fpr32(ctx, fp0, fs);
12631            gen_load_fpr32(ctx, fp1, ft);
12632            gen_load_fpr32(ctx, fp2, fr);
12633            gen_helper_float_msub_s(fp2, cpu_env, fp0, fp1, fp2);
12634            tcg_temp_free_i32(fp0);
12635            tcg_temp_free_i32(fp1);
12636            gen_store_fpr32(ctx, fp2, fd);
12637            tcg_temp_free_i32(fp2);
12638        }
12639        break;
12640    case OPC_MSUB_D:
12641        check_cop1x(ctx);
12642        check_cp1_registers(ctx, fd | fs | ft | fr);
12643        {
12644            TCGv_i64 fp0 = tcg_temp_new_i64();
12645            TCGv_i64 fp1 = tcg_temp_new_i64();
12646            TCGv_i64 fp2 = tcg_temp_new_i64();
12647
12648            gen_load_fpr64(ctx, fp0, fs);
12649            gen_load_fpr64(ctx, fp1, ft);
12650            gen_load_fpr64(ctx, fp2, fr);
12651            gen_helper_float_msub_d(fp2, cpu_env, fp0, fp1, fp2);
12652            tcg_temp_free_i64(fp0);
12653            tcg_temp_free_i64(fp1);
12654            gen_store_fpr64(ctx, fp2, fd);
12655            tcg_temp_free_i64(fp2);
12656        }
12657        break;
12658    case OPC_MSUB_PS:
12659        check_ps(ctx);
12660        {
12661            TCGv_i64 fp0 = tcg_temp_new_i64();
12662            TCGv_i64 fp1 = tcg_temp_new_i64();
12663            TCGv_i64 fp2 = tcg_temp_new_i64();
12664
12665            gen_load_fpr64(ctx, fp0, fs);
12666            gen_load_fpr64(ctx, fp1, ft);
12667            gen_load_fpr64(ctx, fp2, fr);
12668            gen_helper_float_msub_ps(fp2, cpu_env, fp0, fp1, fp2);
12669            tcg_temp_free_i64(fp0);
12670            tcg_temp_free_i64(fp1);
12671            gen_store_fpr64(ctx, fp2, fd);
12672            tcg_temp_free_i64(fp2);
12673        }
12674        break;
12675    case OPC_NMADD_S:
12676        check_cop1x(ctx);
12677        {
12678            TCGv_i32 fp0 = tcg_temp_new_i32();
12679            TCGv_i32 fp1 = tcg_temp_new_i32();
12680            TCGv_i32 fp2 = tcg_temp_new_i32();
12681
12682            gen_load_fpr32(ctx, fp0, fs);
12683            gen_load_fpr32(ctx, fp1, ft);
12684            gen_load_fpr32(ctx, fp2, fr);
12685            gen_helper_float_nmadd_s(fp2, cpu_env, fp0, fp1, fp2);
12686            tcg_temp_free_i32(fp0);
12687            tcg_temp_free_i32(fp1);
12688            gen_store_fpr32(ctx, fp2, fd);
12689            tcg_temp_free_i32(fp2);
12690        }
12691        break;
12692    case OPC_NMADD_D:
12693        check_cop1x(ctx);
12694        check_cp1_registers(ctx, fd | fs | ft | fr);
12695        {
12696            TCGv_i64 fp0 = tcg_temp_new_i64();
12697            TCGv_i64 fp1 = tcg_temp_new_i64();
12698            TCGv_i64 fp2 = tcg_temp_new_i64();
12699
12700            gen_load_fpr64(ctx, fp0, fs);
12701            gen_load_fpr64(ctx, fp1, ft);
12702            gen_load_fpr64(ctx, fp2, fr);
12703            gen_helper_float_nmadd_d(fp2, cpu_env, fp0, fp1, fp2);
12704            tcg_temp_free_i64(fp0);
12705            tcg_temp_free_i64(fp1);
12706            gen_store_fpr64(ctx, fp2, fd);
12707            tcg_temp_free_i64(fp2);
12708        }
12709        break;
12710    case OPC_NMADD_PS:
12711        check_ps(ctx);
12712        {
12713            TCGv_i64 fp0 = tcg_temp_new_i64();
12714            TCGv_i64 fp1 = tcg_temp_new_i64();
12715            TCGv_i64 fp2 = tcg_temp_new_i64();
12716
12717            gen_load_fpr64(ctx, fp0, fs);
12718            gen_load_fpr64(ctx, fp1, ft);
12719            gen_load_fpr64(ctx, fp2, fr);
12720            gen_helper_float_nmadd_ps(fp2, cpu_env, fp0, fp1, fp2);
12721            tcg_temp_free_i64(fp0);
12722            tcg_temp_free_i64(fp1);
12723            gen_store_fpr64(ctx, fp2, fd);
12724            tcg_temp_free_i64(fp2);
12725        }
12726        break;
12727    case OPC_NMSUB_S:
12728        check_cop1x(ctx);
12729        {
12730            TCGv_i32 fp0 = tcg_temp_new_i32();
12731            TCGv_i32 fp1 = tcg_temp_new_i32();
12732            TCGv_i32 fp2 = tcg_temp_new_i32();
12733
12734            gen_load_fpr32(ctx, fp0, fs);
12735            gen_load_fpr32(ctx, fp1, ft);
12736            gen_load_fpr32(ctx, fp2, fr);
12737            gen_helper_float_nmsub_s(fp2, cpu_env, fp0, fp1, fp2);
12738            tcg_temp_free_i32(fp0);
12739            tcg_temp_free_i32(fp1);
12740            gen_store_fpr32(ctx, fp2, fd);
12741            tcg_temp_free_i32(fp2);
12742        }
12743        break;
12744    case OPC_NMSUB_D:
12745        check_cop1x(ctx);
12746        check_cp1_registers(ctx, fd | fs | ft | fr);
12747        {
12748            TCGv_i64 fp0 = tcg_temp_new_i64();
12749            TCGv_i64 fp1 = tcg_temp_new_i64();
12750            TCGv_i64 fp2 = tcg_temp_new_i64();
12751
12752            gen_load_fpr64(ctx, fp0, fs);
12753            gen_load_fpr64(ctx, fp1, ft);
12754            gen_load_fpr64(ctx, fp2, fr);
12755            gen_helper_float_nmsub_d(fp2, cpu_env, fp0, fp1, fp2);
12756            tcg_temp_free_i64(fp0);
12757            tcg_temp_free_i64(fp1);
12758            gen_store_fpr64(ctx, fp2, fd);
12759            tcg_temp_free_i64(fp2);
12760        }
12761        break;
12762    case OPC_NMSUB_PS:
12763        check_ps(ctx);
12764        {
12765            TCGv_i64 fp0 = tcg_temp_new_i64();
12766            TCGv_i64 fp1 = tcg_temp_new_i64();
12767            TCGv_i64 fp2 = tcg_temp_new_i64();
12768
12769            gen_load_fpr64(ctx, fp0, fs);
12770            gen_load_fpr64(ctx, fp1, ft);
12771            gen_load_fpr64(ctx, fp2, fr);
12772            gen_helper_float_nmsub_ps(fp2, cpu_env, fp0, fp1, fp2);
12773            tcg_temp_free_i64(fp0);
12774            tcg_temp_free_i64(fp1);
12775            gen_store_fpr64(ctx, fp2, fd);
12776            tcg_temp_free_i64(fp2);
12777        }
12778        break;
12779    default:
12780        MIPS_INVAL("flt3_arith");
12781        generate_exception_end(ctx, EXCP_RI);
12782        return;
12783    }
12784}
12785
12786static void gen_rdhwr(DisasContext *ctx, int rt, int rd, int sel)
12787{
12788    TCGv t0;
12789
12790#if !defined(CONFIG_USER_ONLY)
12791    /*
12792     * The Linux kernel will emulate rdhwr if it's not supported natively.
12793     * Therefore only check the ISA in system mode.
12794     */
12795    check_insn(ctx, ISA_MIPS32R2);
12796#endif
12797    t0 = tcg_temp_new();
12798
12799    switch (rd) {
12800    case 0:
12801        gen_helper_rdhwr_cpunum(t0, cpu_env);
12802        gen_store_gpr(t0, rt);
12803        break;
12804    case 1:
12805        gen_helper_rdhwr_synci_step(t0, cpu_env);
12806        gen_store_gpr(t0, rt);
12807        break;
12808    case 2:
12809        if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
12810            gen_io_start();
12811        }
12812        gen_helper_rdhwr_cc(t0, cpu_env);
12813        if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
12814            gen_io_end();
12815        }
12816        gen_store_gpr(t0, rt);
12817        /*
12818         * Break the TB to be able to take timer interrupts immediately
12819         * after reading count. DISAS_STOP isn't sufficient, we need to ensure
12820         * we break completely out of translated code.
12821         */
12822        gen_save_pc(ctx->base.pc_next + 4);
12823        ctx->base.is_jmp = DISAS_EXIT;
12824        break;
12825    case 3:
12826        gen_helper_rdhwr_ccres(t0, cpu_env);
12827        gen_store_gpr(t0, rt);
12828        break;
12829    case 4:
12830        check_insn(ctx, ISA_MIPS32R6);
12831        if (sel != 0) {
12832            /*
12833             * Performance counter registers are not implemented other than
12834             * control register 0.
12835             */
12836            generate_exception(ctx, EXCP_RI);
12837        }
12838        gen_helper_rdhwr_performance(t0, cpu_env);
12839        gen_store_gpr(t0, rt);
12840        break;
12841    case 5:
12842        check_insn(ctx, ISA_MIPS32R6);
12843        gen_helper_rdhwr_xnp(t0, cpu_env);
12844        gen_store_gpr(t0, rt);
12845        break;
12846    case 29:
12847#if defined(CONFIG_USER_ONLY)
12848        tcg_gen_ld_tl(t0, cpu_env,
12849                      offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
12850        gen_store_gpr(t0, rt);
12851        break;
12852#else
12853        if ((ctx->hflags & MIPS_HFLAG_CP0) ||
12854            (ctx->hflags & MIPS_HFLAG_HWRENA_ULR)) {
12855            tcg_gen_ld_tl(t0, cpu_env,
12856                          offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
12857            gen_store_gpr(t0, rt);
12858        } else {
12859            generate_exception_end(ctx, EXCP_RI);
12860        }
12861        break;
12862#endif
12863    default:            /* Invalid */
12864        MIPS_INVAL("rdhwr");
12865        generate_exception_end(ctx, EXCP_RI);
12866        break;
12867    }
12868    tcg_temp_free(t0);
12869}
12870
12871static inline void clear_branch_hflags(DisasContext *ctx)
12872{
12873    ctx->hflags &= ~MIPS_HFLAG_BMASK;
12874    if (ctx->base.is_jmp == DISAS_NEXT) {
12875        save_cpu_state(ctx, 0);
12876    } else {
12877        /*
12878         * It is not safe to save ctx->hflags as hflags may be changed
12879         * in execution time by the instruction in delay / forbidden slot.
12880         */
12881        tcg_gen_andi_i32(hflags, hflags, ~MIPS_HFLAG_BMASK);
12882    }
12883}
12884
12885static void gen_branch(DisasContext *ctx, int insn_bytes)
12886{
12887    if (ctx->hflags & MIPS_HFLAG_BMASK) {
12888        int proc_hflags = ctx->hflags & MIPS_HFLAG_BMASK;
12889        /* Branches completion */
12890        clear_branch_hflags(ctx);
12891        ctx->base.is_jmp = DISAS_NORETURN;
12892        /* FIXME: Need to clear can_do_io.  */
12893        switch (proc_hflags & MIPS_HFLAG_BMASK_BASE) {
12894        case MIPS_HFLAG_FBNSLOT:
12895            gen_goto_tb(ctx, 0, ctx->base.pc_next + insn_bytes);
12896            break;
12897        case MIPS_HFLAG_B:
12898            /* unconditional branch */
12899            if (proc_hflags & MIPS_HFLAG_BX) {
12900                tcg_gen_xori_i32(hflags, hflags, MIPS_HFLAG_M16);
12901            }
12902            gen_goto_tb(ctx, 0, ctx->btarget);
12903            break;
12904        case MIPS_HFLAG_BL:
12905            /* blikely taken case */
12906            gen_goto_tb(ctx, 0, ctx->btarget);
12907            break;
12908        case MIPS_HFLAG_BC:
12909            /* Conditional branch */
12910            {
12911                TCGLabel *l1 = gen_new_label();
12912
12913                tcg_gen_brcondi_tl(TCG_COND_NE, bcond, 0, l1);
12914                gen_goto_tb(ctx, 1, ctx->base.pc_next + insn_bytes);
12915                gen_set_label(l1);
12916                gen_goto_tb(ctx, 0, ctx->btarget);
12917            }
12918            break;
12919        case MIPS_HFLAG_BR:
12920            /* unconditional branch to register */
12921            if (ctx->insn_flags & (ASE_MIPS16 | ASE_MICROMIPS)) {
12922                TCGv t0 = tcg_temp_new();
12923                TCGv_i32 t1 = tcg_temp_new_i32();
12924
12925                tcg_gen_andi_tl(t0, btarget, 0x1);
12926                tcg_gen_trunc_tl_i32(t1, t0);
12927                tcg_temp_free(t0);
12928                tcg_gen_andi_i32(hflags, hflags, ~(uint32_t)MIPS_HFLAG_M16);
12929                tcg_gen_shli_i32(t1, t1, MIPS_HFLAG_M16_SHIFT);
12930                tcg_gen_or_i32(hflags, hflags, t1);
12931                tcg_temp_free_i32(t1);
12932
12933                tcg_gen_andi_tl(cpu_PC, btarget, ~(target_ulong)0x1);
12934            } else {
12935                tcg_gen_mov_tl(cpu_PC, btarget);
12936            }
12937            if (ctx->base.singlestep_enabled) {
12938                save_cpu_state(ctx, 0);
12939                gen_helper_raise_exception_debug(cpu_env);
12940            }
12941            tcg_gen_lookup_and_goto_ptr();
12942            break;
12943        default:
12944            fprintf(stderr, "unknown branch 0x%x\n", proc_hflags);
12945            abort();
12946        }
12947    }
12948}
12949
12950/* Compact Branches */
12951static void gen_compute_compact_branch(DisasContext *ctx, uint32_t opc,
12952                                       int rs, int rt, int32_t offset)
12953{
12954    int bcond_compute = 0;
12955    TCGv t0 = tcg_temp_new();
12956    TCGv t1 = tcg_temp_new();
12957    int m16_lowbit = (ctx->hflags & MIPS_HFLAG_M16) != 0;
12958
12959    if (ctx->hflags & MIPS_HFLAG_BMASK) {
12960#ifdef MIPS_DEBUG_DISAS
12961        LOG_DISAS("Branch in delay / forbidden slot at PC 0x" TARGET_FMT_lx
12962                  "\n", ctx->base.pc_next);
12963#endif
12964        generate_exception_end(ctx, EXCP_RI);
12965        goto out;
12966    }
12967
12968    /* Load needed operands and calculate btarget */
12969    switch (opc) {
12970    /* compact branch */
12971    case OPC_BOVC: /* OPC_BEQZALC, OPC_BEQC */
12972    case OPC_BNVC: /* OPC_BNEZALC, OPC_BNEC */
12973        gen_load_gpr(t0, rs);
12974        gen_load_gpr(t1, rt);
12975        bcond_compute = 1;
12976        ctx->btarget = addr_add(ctx, ctx->base.pc_next + 4, offset);
12977        if (rs <= rt && rs == 0) {
12978            /* OPC_BEQZALC, OPC_BNEZALC */
12979            tcg_gen_movi_tl(cpu_gpr[31], ctx->base.pc_next + 4 + m16_lowbit);
12980        }
12981        break;
12982    case OPC_BLEZC: /* OPC_BGEZC, OPC_BGEC */
12983    case OPC_BGTZC: /* OPC_BLTZC, OPC_BLTC */
12984        gen_load_gpr(t0, rs);
12985        gen_load_gpr(t1, rt);
12986        bcond_compute = 1;
12987        ctx->btarget = addr_add(ctx, ctx->base.pc_next + 4, offset);
12988        break;
12989    case OPC_BLEZALC: /* OPC_BGEZALC, OPC_BGEUC */
12990    case OPC_BGTZALC: /* OPC_BLTZALC, OPC_BLTUC */
12991        if (rs == 0 || rs == rt) {
12992            /* OPC_BLEZALC, OPC_BGEZALC */
12993            /* OPC_BGTZALC, OPC_BLTZALC */
12994            tcg_gen_movi_tl(cpu_gpr[31], ctx->base.pc_next + 4 + m16_lowbit);
12995        }
12996        gen_load_gpr(t0, rs);
12997        gen_load_gpr(t1, rt);
12998        bcond_compute = 1;
12999        ctx->btarget = addr_add(ctx, ctx->base.pc_next + 4, offset);
13000        break;
13001    case OPC_BC:
13002    case OPC_BALC:
13003        ctx->btarget = addr_add(ctx, ctx->base.pc_next + 4, offset);
13004        break;
13005    case OPC_BEQZC:
13006    case OPC_BNEZC:
13007        if (rs != 0) {
13008            /* OPC_BEQZC, OPC_BNEZC */
13009            gen_load_gpr(t0, rs);
13010            bcond_compute = 1;
13011            ctx->btarget = addr_add(ctx, ctx->base.pc_next + 4, offset);
13012        } else {
13013            /* OPC_JIC, OPC_JIALC */
13014            TCGv tbase = tcg_temp_new();
13015            TCGv toffset = tcg_temp_new();
13016
13017            gen_load_gpr(tbase, rt);
13018            tcg_gen_movi_tl(toffset, offset);
13019            gen_op_addr_add(ctx, btarget, tbase, toffset);
13020            tcg_temp_free(tbase);
13021            tcg_temp_free(toffset);
13022        }
13023        break;
13024    default:
13025        MIPS_INVAL("Compact branch/jump");
13026        generate_exception_end(ctx, EXCP_RI);
13027        goto out;
13028    }
13029
13030    if (bcond_compute == 0) {
13031        /* Uncoditional compact branch */
13032        switch (opc) {
13033        case OPC_JIALC:
13034            tcg_gen_movi_tl(cpu_gpr[31], ctx->base.pc_next + 4 + m16_lowbit);
13035            /* Fallthrough */
13036        case OPC_JIC:
13037            ctx->hflags |= MIPS_HFLAG_BR;
13038            break;
13039        case OPC_BALC:
13040            tcg_gen_movi_tl(cpu_gpr[31], ctx->base.pc_next + 4 + m16_lowbit);
13041            /* Fallthrough */
13042        case OPC_BC:
13043            ctx->hflags |= MIPS_HFLAG_B;
13044            break;
13045        default:
13046            MIPS_INVAL("Compact branch/jump");
13047            generate_exception_end(ctx, EXCP_RI);
13048            goto out;
13049        }
13050
13051        /* Generating branch here as compact branches don't have delay slot */
13052        gen_branch(ctx, 4);
13053    } else {
13054        /* Conditional compact branch */
13055        TCGLabel *fs = gen_new_label();
13056        save_cpu_state(ctx, 0);
13057
13058        switch (opc) {
13059        case OPC_BLEZALC: /* OPC_BGEZALC, OPC_BGEUC */
13060            if (rs == 0 && rt != 0) {
13061                /* OPC_BLEZALC */
13062                tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LE), t1, 0, fs);
13063            } else if (rs != 0 && rt != 0 && rs == rt) {
13064                /* OPC_BGEZALC */
13065                tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GE), t1, 0, fs);
13066            } else {
13067                /* OPC_BGEUC */
13068                tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_GEU), t0, t1, fs);
13069            }
13070            break;
13071        case OPC_BGTZALC: /* OPC_BLTZALC, OPC_BLTUC */
13072            if (rs == 0 && rt != 0) {
13073                /* OPC_BGTZALC */
13074                tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GT), t1, 0, fs);
13075            } else if (rs != 0 && rt != 0 && rs == rt) {
13076                /* OPC_BLTZALC */
13077                tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LT), t1, 0, fs);
13078            } else {
13079                /* OPC_BLTUC */
13080                tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_LTU), t0, t1, fs);
13081            }
13082            break;
13083        case OPC_BLEZC: /* OPC_BGEZC, OPC_BGEC */
13084            if (rs == 0 && rt != 0) {
13085                /* OPC_BLEZC */
13086                tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LE), t1, 0, fs);
13087            } else if (rs != 0 && rt != 0 && rs == rt) {
13088                /* OPC_BGEZC */
13089                tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GE), t1, 0, fs);
13090            } else {
13091                /* OPC_BGEC */
13092                tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_GE), t0, t1, fs);
13093            }
13094            break;
13095        case OPC_BGTZC: /* OPC_BLTZC, OPC_BLTC */
13096            if (rs == 0 && rt != 0) {
13097                /* OPC_BGTZC */
13098                tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GT), t1, 0, fs);
13099            } else if (rs != 0 && rt != 0 && rs == rt) {
13100                /* OPC_BLTZC */
13101                tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LT), t1, 0, fs);
13102            } else {
13103                /* OPC_BLTC */
13104                tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_LT), t0, t1, fs);
13105            }
13106            break;
13107        case OPC_BOVC: /* OPC_BEQZALC, OPC_BEQC */
13108        case OPC_BNVC: /* OPC_BNEZALC, OPC_BNEC */
13109            if (rs >= rt) {
13110                /* OPC_BOVC, OPC_BNVC */
13111                TCGv t2 = tcg_temp_new();
13112                TCGv t3 = tcg_temp_new();
13113                TCGv t4 = tcg_temp_new();
13114                TCGv input_overflow = tcg_temp_new();
13115
13116                gen_load_gpr(t0, rs);
13117                gen_load_gpr(t1, rt);
13118                tcg_gen_ext32s_tl(t2, t0);
13119                tcg_gen_setcond_tl(TCG_COND_NE, input_overflow, t2, t0);
13120                tcg_gen_ext32s_tl(t3, t1);
13121                tcg_gen_setcond_tl(TCG_COND_NE, t4, t3, t1);
13122                tcg_gen_or_tl(input_overflow, input_overflow, t4);
13123
13124                tcg_gen_add_tl(t4, t2, t3);
13125                tcg_gen_ext32s_tl(t4, t4);
13126                tcg_gen_xor_tl(t2, t2, t3);
13127                tcg_gen_xor_tl(t3, t4, t3);
13128                tcg_gen_andc_tl(t2, t3, t2);
13129                tcg_gen_setcondi_tl(TCG_COND_LT, t4, t2, 0);
13130                tcg_gen_or_tl(t4, t4, input_overflow);
13131                if (opc == OPC_BOVC) {
13132                    /* OPC_BOVC */
13133                    tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_NE), t4, 0, fs);
13134                } else {
13135                    /* OPC_BNVC */
13136                    tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_EQ), t4, 0, fs);
13137                }
13138                tcg_temp_free(input_overflow);
13139                tcg_temp_free(t4);
13140                tcg_temp_free(t3);
13141                tcg_temp_free(t2);
13142            } else if (rs < rt && rs == 0) {
13143                /* OPC_BEQZALC, OPC_BNEZALC */
13144                if (opc == OPC_BEQZALC) {
13145                    /* OPC_BEQZALC */
13146                    tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_EQ), t1, 0, fs);
13147                } else {
13148                    /* OPC_BNEZALC */
13149                    tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_NE), t1, 0, fs);
13150                }
13151            } else {
13152                /* OPC_BEQC, OPC_BNEC */
13153                if (opc == OPC_BEQC) {
13154                    /* OPC_BEQC */
13155                    tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_EQ), t0, t1, fs);
13156                } else {
13157                    /* OPC_BNEC */
13158                    tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_NE), t0, t1, fs);
13159                }
13160            }
13161            break;
13162        case OPC_BEQZC:
13163            tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_EQ), t0, 0, fs);
13164            break;
13165        case OPC_BNEZC:
13166            tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_NE), t0, 0, fs);
13167            break;
13168        default:
13169            MIPS_INVAL("Compact conditional branch/jump");
13170            generate_exception_end(ctx, EXCP_RI);
13171            goto out;
13172        }
13173
13174        /* Generating branch here as compact branches don't have delay slot */
13175        gen_goto_tb(ctx, 1, ctx->btarget);
13176        gen_set_label(fs);
13177
13178        ctx->hflags |= MIPS_HFLAG_FBNSLOT;
13179    }
13180
13181out:
13182    tcg_temp_free(t0);
13183    tcg_temp_free(t1);
13184}
13185
13186/* ISA extensions (ASEs) */
13187/* MIPS16 extension to MIPS32 */
13188
13189/* MIPS16 major opcodes */
13190enum {
13191  M16_OPC_ADDIUSP = 0x00,
13192  M16_OPC_ADDIUPC = 0x01,
13193  M16_OPC_B = 0x02,
13194  M16_OPC_JAL = 0x03,
13195  M16_OPC_BEQZ = 0x04,
13196  M16_OPC_BNEQZ = 0x05,
13197  M16_OPC_SHIFT = 0x06,
13198  M16_OPC_LD = 0x07,
13199  M16_OPC_RRIA = 0x08,
13200  M16_OPC_ADDIU8 = 0x09,
13201  M16_OPC_SLTI = 0x0a,
13202  M16_OPC_SLTIU = 0x0b,
13203  M16_OPC_I8 = 0x0c,
13204  M16_OPC_LI = 0x0d,
13205  M16_OPC_CMPI = 0x0e,
13206  M16_OPC_SD = 0x0f,
13207  M16_OPC_LB = 0x10,
13208  M16_OPC_LH = 0x11,
13209  M16_OPC_LWSP = 0x12,
13210  M16_OPC_LW = 0x13,
13211  M16_OPC_LBU = 0x14,
13212  M16_OPC_LHU = 0x15,
13213  M16_OPC_LWPC = 0x16,
13214  M16_OPC_LWU = 0x17,
13215  M16_OPC_SB = 0x18,
13216  M16_OPC_SH = 0x19,
13217  M16_OPC_SWSP = 0x1a,
13218  M16_OPC_SW = 0x1b,
13219  M16_OPC_RRR = 0x1c,
13220  M16_OPC_RR = 0x1d,
13221  M16_OPC_EXTEND = 0x1e,
13222  M16_OPC_I64 = 0x1f
13223};
13224
13225/* I8 funct field */
13226enum {
13227  I8_BTEQZ = 0x0,
13228  I8_BTNEZ = 0x1,
13229  I8_SWRASP = 0x2,
13230  I8_ADJSP = 0x3,
13231  I8_SVRS = 0x4,
13232  I8_MOV32R = 0x5,
13233  I8_MOVR32 = 0x7
13234};
13235
13236/* RRR f field */
13237enum {
13238  RRR_DADDU = 0x0,
13239  RRR_ADDU = 0x1,
13240  RRR_DSUBU = 0x2,
13241  RRR_SUBU = 0x3
13242};
13243
13244/* RR funct field */
13245enum {
13246  RR_JR = 0x00,
13247  RR_SDBBP = 0x01,
13248  RR_SLT = 0x02,
13249  RR_SLTU = 0x03,
13250  RR_SLLV = 0x04,
13251  RR_BREAK = 0x05,
13252  RR_SRLV = 0x06,
13253  RR_SRAV = 0x07,
13254  RR_DSRL = 0x08,
13255  RR_CMP = 0x0a,
13256  RR_NEG = 0x0b,
13257  RR_AND = 0x0c,
13258  RR_OR = 0x0d,
13259  RR_XOR = 0x0e,
13260  RR_NOT = 0x0f,
13261  RR_MFHI = 0x10,
13262  RR_CNVT = 0x11,
13263  RR_MFLO = 0x12,
13264  RR_DSRA = 0x13,
13265  RR_DSLLV = 0x14,
13266  RR_DSRLV = 0x16,
13267  RR_DSRAV = 0x17,
13268  RR_MULT = 0x18,
13269  RR_MULTU = 0x19,
13270  RR_DIV = 0x1a,
13271  RR_DIVU = 0x1b,
13272  RR_DMULT = 0x1c,
13273  RR_DMULTU = 0x1d,
13274  RR_DDIV = 0x1e,
13275  RR_DDIVU = 0x1f
13276};
13277
13278/* I64 funct field */
13279enum {
13280  I64_LDSP = 0x0,
13281  I64_SDSP = 0x1,
13282  I64_SDRASP = 0x2,
13283  I64_DADJSP = 0x3,
13284  I64_LDPC = 0x4,
13285  I64_DADDIU5 = 0x5,
13286  I64_DADDIUPC = 0x6,
13287  I64_DADDIUSP = 0x7
13288};
13289
13290/* RR ry field for CNVT */
13291enum {
13292  RR_RY_CNVT_ZEB = 0x0,
13293  RR_RY_CNVT_ZEH = 0x1,
13294  RR_RY_CNVT_ZEW = 0x2,
13295  RR_RY_CNVT_SEB = 0x4,
13296  RR_RY_CNVT_SEH = 0x5,
13297  RR_RY_CNVT_SEW = 0x6,
13298};
13299
13300static int xlat(int r)
13301{
13302  static int map[] = { 16, 17, 2, 3, 4, 5, 6, 7 };
13303
13304  return map[r];
13305}
13306
13307static void gen_mips16_save(DisasContext *ctx,
13308                            int xsregs, int aregs,
13309                            int do_ra, int do_s0, int do_s1,
13310                            int framesize)
13311{
13312    TCGv t0 = tcg_temp_new();
13313    TCGv t1 = tcg_temp_new();
13314    TCGv t2 = tcg_temp_new();
13315    int args, astatic;
13316
13317    switch (aregs) {
13318    case 0:
13319    case 1:
13320    case 2:
13321    case 3:
13322    case 11:
13323        args = 0;
13324        break;
13325    case 4:
13326    case 5:
13327    case 6:
13328    case 7:
13329        args = 1;
13330        break;
13331    case 8:
13332    case 9:
13333    case 10:
13334        args = 2;
13335        break;
13336    case 12:
13337    case 13:
13338        args = 3;
13339        break;
13340    case 14:
13341        args = 4;
13342        break;
13343    default:
13344        generate_exception_end(ctx, EXCP_RI);
13345        return;
13346    }
13347
13348    switch (args) {
13349    case 4:
13350        gen_base_offset_addr(ctx, t0, 29, 12);
13351        gen_load_gpr(t1, 7);
13352        tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL);
13353        /* Fall through */
13354    case 3:
13355        gen_base_offset_addr(ctx, t0, 29, 8);
13356        gen_load_gpr(t1, 6);
13357        tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL);
13358        /* Fall through */
13359    case 2:
13360        gen_base_offset_addr(ctx, t0, 29, 4);
13361        gen_load_gpr(t1, 5);
13362        tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL);
13363        /* Fall through */
13364    case 1:
13365        gen_base_offset_addr(ctx, t0, 29, 0);
13366        gen_load_gpr(t1, 4);
13367        tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL);
13368    }
13369
13370    gen_load_gpr(t0, 29);
13371
13372#define DECR_AND_STORE(reg) do {                                 \
13373        tcg_gen_movi_tl(t2, -4);                                 \
13374        gen_op_addr_add(ctx, t0, t0, t2);                        \
13375        gen_load_gpr(t1, reg);                                   \
13376        tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL); \
13377    } while (0)
13378
13379    if (do_ra) {
13380        DECR_AND_STORE(31);
13381    }
13382
13383    switch (xsregs) {
13384    case 7:
13385        DECR_AND_STORE(30);
13386        /* Fall through */
13387    case 6:
13388        DECR_AND_STORE(23);
13389        /* Fall through */
13390    case 5:
13391        DECR_AND_STORE(22);
13392        /* Fall through */
13393    case 4:
13394        DECR_AND_STORE(21);
13395        /* Fall through */
13396    case 3:
13397        DECR_AND_STORE(20);
13398        /* Fall through */
13399    case 2:
13400        DECR_AND_STORE(19);
13401        /* Fall through */
13402    case 1:
13403        DECR_AND_STORE(18);
13404    }
13405
13406    if (do_s1) {
13407        DECR_AND_STORE(17);
13408    }
13409    if (do_s0) {
13410        DECR_AND_STORE(16);
13411    }
13412
13413    switch (aregs) {
13414    case 0:
13415    case 4:
13416    case 8:
13417    case 12:
13418    case 14:
13419        astatic = 0;
13420        break;
13421    case 1:
13422    case 5:
13423    case 9:
13424    case 13:
13425        astatic = 1;
13426        break;
13427    case 2:
13428    case 6:
13429    case 10:
13430        astatic = 2;
13431        break;
13432    case 3:
13433    case 7:
13434        astatic = 3;
13435        break;
13436    case 11:
13437        astatic = 4;
13438        break;
13439    default:
13440        generate_exception_end(ctx, EXCP_RI);
13441        return;
13442    }
13443
13444    if (astatic > 0) {
13445        DECR_AND_STORE(7);
13446        if (astatic > 1) {
13447            DECR_AND_STORE(6);
13448            if (astatic > 2) {
13449                DECR_AND_STORE(5);
13450                if (astatic > 3) {
13451                    DECR_AND_STORE(4);
13452                }
13453            }
13454        }
13455    }
13456#undef DECR_AND_STORE
13457
13458    tcg_gen_movi_tl(t2, -framesize);
13459    gen_op_addr_add(ctx, cpu_gpr[29], cpu_gpr[29], t2);
13460    tcg_temp_free(t0);
13461    tcg_temp_free(t1);
13462    tcg_temp_free(t2);
13463}
13464
13465static void gen_mips16_restore(DisasContext *ctx,
13466                               int xsregs, int aregs,
13467                               int do_ra, int do_s0, int do_s1,
13468                               int framesize)
13469{
13470    int astatic;
13471    TCGv t0 = tcg_temp_new();
13472    TCGv t1 = tcg_temp_new();
13473    TCGv t2 = tcg_temp_new();
13474
13475    tcg_gen_movi_tl(t2, framesize);
13476    gen_op_addr_add(ctx, t0, cpu_gpr[29], t2);
13477
13478#define DECR_AND_LOAD(reg) do {                            \
13479        tcg_gen_movi_tl(t2, -4);                           \
13480        gen_op_addr_add(ctx, t0, t0, t2);                  \
13481        tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TESL); \
13482        gen_store_gpr(t1, reg);                            \
13483    } while (0)
13484
13485    if (do_ra) {
13486        DECR_AND_LOAD(31);
13487    }
13488
13489    switch (xsregs) {
13490    case 7:
13491        DECR_AND_LOAD(30);
13492        /* Fall through */
13493    case 6:
13494        DECR_AND_LOAD(23);
13495        /* Fall through */
13496    case 5:
13497        DECR_AND_LOAD(22);
13498        /* Fall through */
13499    case 4:
13500        DECR_AND_LOAD(21);
13501        /* Fall through */
13502    case 3:
13503        DECR_AND_LOAD(20);
13504        /* Fall through */
13505    case 2:
13506        DECR_AND_LOAD(19);
13507        /* Fall through */
13508    case 1:
13509        DECR_AND_LOAD(18);
13510    }
13511
13512    if (do_s1) {
13513        DECR_AND_LOAD(17);
13514    }
13515    if (do_s0) {
13516        DECR_AND_LOAD(16);
13517    }
13518
13519    switch (aregs) {
13520    case 0:
13521    case 4:
13522    case 8:
13523    case 12:
13524    case 14:
13525        astatic = 0;
13526        break;
13527    case 1:
13528    case 5:
13529    case 9:
13530    case 13:
13531        astatic = 1;
13532        break;
13533    case 2:
13534    case 6:
13535    case 10:
13536        astatic = 2;
13537        break;
13538    case 3:
13539    case 7:
13540        astatic = 3;
13541        break;
13542    case 11:
13543        astatic = 4;
13544        break;
13545    default:
13546        generate_exception_end(ctx, EXCP_RI);
13547        return;
13548    }
13549
13550    if (astatic > 0) {
13551        DECR_AND_LOAD(7);
13552        if (astatic > 1) {
13553            DECR_AND_LOAD(6);
13554            if (astatic > 2) {
13555                DECR_AND_LOAD(5);
13556                if (astatic > 3) {
13557                    DECR_AND_LOAD(4);
13558                }
13559            }
13560        }
13561    }
13562#undef DECR_AND_LOAD
13563
13564    tcg_gen_movi_tl(t2, framesize);
13565    gen_op_addr_add(ctx, cpu_gpr[29], cpu_gpr[29], t2);
13566    tcg_temp_free(t0);
13567    tcg_temp_free(t1);
13568    tcg_temp_free(t2);
13569}
13570
13571static void gen_addiupc(DisasContext *ctx, int rx, int imm,
13572                        int is_64_bit, int extended)
13573{
13574    TCGv t0;
13575
13576    if (extended && (ctx->hflags & MIPS_HFLAG_BMASK)) {
13577        generate_exception_end(ctx, EXCP_RI);
13578        return;
13579    }
13580
13581    t0 = tcg_temp_new();
13582
13583    tcg_gen_movi_tl(t0, pc_relative_pc(ctx));
13584    tcg_gen_addi_tl(cpu_gpr[rx], t0, imm);
13585    if (!is_64_bit) {
13586        tcg_gen_ext32s_tl(cpu_gpr[rx], cpu_gpr[rx]);
13587    }
13588
13589    tcg_temp_free(t0);
13590}
13591
13592static void gen_cache_operation(DisasContext *ctx, uint32_t op, int base,
13593                                int16_t offset)
13594{
13595    TCGv_i32 t0 = tcg_const_i32(op);
13596    TCGv t1 = tcg_temp_new();
13597    gen_base_offset_addr(ctx, t1, base, offset);
13598    gen_helper_cache(cpu_env, t1, t0);
13599}
13600
13601#if defined(TARGET_MIPS64)
13602static void decode_i64_mips16(DisasContext *ctx,
13603                              int ry, int funct, int16_t offset,
13604                              int extended)
13605{
13606    switch (funct) {
13607    case I64_LDSP:
13608        check_insn(ctx, ISA_MIPS3);
13609        check_mips_64(ctx);
13610        offset = extended ? offset : offset << 3;
13611        gen_ld(ctx, OPC_LD, ry, 29, offset);
13612        break;
13613    case I64_SDSP:
13614        check_insn(ctx, ISA_MIPS3);
13615        check_mips_64(ctx);
13616        offset = extended ? offset : offset << 3;
13617        gen_st(ctx, OPC_SD, ry, 29, offset);
13618        break;
13619    case I64_SDRASP:
13620        check_insn(ctx, ISA_MIPS3);
13621        check_mips_64(ctx);
13622        offset = extended ? offset : (ctx->opcode & 0xff) << 3;
13623        gen_st(ctx, OPC_SD, 31, 29, offset);
13624        break;
13625    case I64_DADJSP:
13626        check_insn(ctx, ISA_MIPS3);
13627        check_mips_64(ctx);
13628        offset = extended ? offset : ((int8_t)ctx->opcode) << 3;
13629        gen_arith_imm(ctx, OPC_DADDIU, 29, 29, offset);
13630        break;
13631    case I64_LDPC:
13632        check_insn(ctx, ISA_MIPS3);
13633        check_mips_64(ctx);
13634        if (extended && (ctx->hflags & MIPS_HFLAG_BMASK)) {
13635            generate_exception_end(ctx, EXCP_RI);
13636        } else {
13637            offset = extended ? offset : offset << 3;
13638            gen_ld(ctx, OPC_LDPC, ry, 0, offset);
13639        }
13640        break;
13641    case I64_DADDIU5:
13642        check_insn(ctx, ISA_MIPS3);
13643        check_mips_64(ctx);
13644        offset = extended ? offset : ((int8_t)(offset << 3)) >> 3;
13645        gen_arith_imm(ctx, OPC_DADDIU, ry, ry, offset);
13646        break;
13647    case I64_DADDIUPC:
13648        check_insn(ctx, ISA_MIPS3);
13649        check_mips_64(ctx);
13650        offset = extended ? offset : offset << 2;
13651        gen_addiupc(ctx, ry, offset, 1, extended);
13652        break;
13653    case I64_DADDIUSP:
13654        check_insn(ctx, ISA_MIPS3);
13655        check_mips_64(ctx);
13656        offset = extended ? offset : offset << 2;
13657        gen_arith_imm(ctx, OPC_DADDIU, ry, 29, offset);
13658        break;
13659    }
13660}
13661#endif
13662
13663static int decode_extended_mips16_opc(CPUMIPSState *env, DisasContext *ctx)
13664{
13665    int extend = cpu_lduw_code(env, ctx->base.pc_next + 2);
13666    int op, rx, ry, funct, sa;
13667    int16_t imm, offset;
13668
13669    ctx->opcode = (ctx->opcode << 16) | extend;
13670    op = (ctx->opcode >> 11) & 0x1f;
13671    sa = (ctx->opcode >> 22) & 0x1f;
13672    funct = (ctx->opcode >> 8) & 0x7;
13673    rx = xlat((ctx->opcode >> 8) & 0x7);
13674    ry = xlat((ctx->opcode >> 5) & 0x7);
13675    offset = imm = (int16_t) (((ctx->opcode >> 16) & 0x1f) << 11
13676                              | ((ctx->opcode >> 21) & 0x3f) << 5
13677                              | (ctx->opcode & 0x1f));
13678
13679    /*
13680     * The extended opcodes cleverly reuse the opcodes from their 16-bit
13681     * counterparts.
13682     */
13683    switch (op) {
13684    case M16_OPC_ADDIUSP:
13685        gen_arith_imm(ctx, OPC_ADDIU, rx, 29, imm);
13686        break;
13687    case M16_OPC_ADDIUPC:
13688        gen_addiupc(ctx, rx, imm, 0, 1);
13689        break;
13690    case M16_OPC_B:
13691        gen_compute_branch(ctx, OPC_BEQ, 4, 0, 0, offset << 1, 0);
13692        /* No delay slot, so just process as a normal instruction */
13693        break;
13694    case M16_OPC_BEQZ:
13695        gen_compute_branch(ctx, OPC_BEQ, 4, rx, 0, offset << 1, 0);
13696        /* No delay slot, so just process as a normal instruction */
13697        break;
13698    case M16_OPC_BNEQZ:
13699        gen_compute_branch(ctx, OPC_BNE, 4, rx, 0, offset << 1, 0);
13700        /* No delay slot, so just process as a normal instruction */
13701        break;
13702    case M16_OPC_SHIFT:
13703        switch (ctx->opcode & 0x3) {
13704        case 0x0:
13705            gen_shift_imm(ctx, OPC_SLL, rx, ry, sa);
13706            break;
13707        case 0x1:
13708#if defined(TARGET_MIPS64)
13709            check_mips_64(ctx);
13710            gen_shift_imm(ctx, OPC_DSLL, rx, ry, sa);
13711#else
13712            generate_exception_end(ctx, EXCP_RI);
13713#endif
13714            break;
13715        case 0x2:
13716            gen_shift_imm(ctx, OPC_SRL, rx, ry, sa);
13717            break;
13718        case 0x3:
13719            gen_shift_imm(ctx, OPC_SRA, rx, ry, sa);
13720            break;
13721        }
13722        break;
13723#if defined(TARGET_MIPS64)
13724    case M16_OPC_LD:
13725        check_insn(ctx, ISA_MIPS3);
13726        check_mips_64(ctx);
13727        gen_ld(ctx, OPC_LD, ry, rx, offset);
13728        break;
13729#endif
13730    case M16_OPC_RRIA:
13731        imm = ctx->opcode & 0xf;
13732        imm = imm | ((ctx->opcode >> 20) & 0x7f) << 4;
13733        imm = imm | ((ctx->opcode >> 16) & 0xf) << 11;
13734        imm = (int16_t) (imm << 1) >> 1;
13735        if ((ctx->opcode >> 4) & 0x1) {
13736#if defined(TARGET_MIPS64)
13737            check_mips_64(ctx);
13738            gen_arith_imm(ctx, OPC_DADDIU, ry, rx, imm);
13739#else
13740            generate_exception_end(ctx, EXCP_RI);
13741#endif
13742        } else {
13743            gen_arith_imm(ctx, OPC_ADDIU, ry, rx, imm);
13744        }
13745        break;
13746    case M16_OPC_ADDIU8:
13747        gen_arith_imm(ctx, OPC_ADDIU, rx, rx, imm);
13748        break;
13749    case M16_OPC_SLTI:
13750        gen_slt_imm(ctx, OPC_SLTI, 24, rx, imm);
13751        break;
13752    case M16_OPC_SLTIU:
13753        gen_slt_imm(ctx, OPC_SLTIU, 24, rx, imm);
13754        break;
13755    case M16_OPC_I8:
13756        switch (funct) {
13757        case I8_BTEQZ:
13758            gen_compute_branch(ctx, OPC_BEQ, 4, 24, 0, offset << 1, 0);
13759            break;
13760        case I8_BTNEZ:
13761            gen_compute_branch(ctx, OPC_BNE, 4, 24, 0, offset << 1, 0);
13762            break;
13763        case I8_SWRASP:
13764            gen_st(ctx, OPC_SW, 31, 29, imm);
13765            break;
13766        case I8_ADJSP:
13767            gen_arith_imm(ctx, OPC_ADDIU, 29, 29, imm);
13768            break;
13769        case I8_SVRS:
13770            check_insn(ctx, ISA_MIPS32);
13771            {
13772                int xsregs = (ctx->opcode >> 24) & 0x7;
13773                int aregs = (ctx->opcode >> 16) & 0xf;
13774                int do_ra = (ctx->opcode >> 6) & 0x1;
13775                int do_s0 = (ctx->opcode >> 5) & 0x1;
13776                int do_s1 = (ctx->opcode >> 4) & 0x1;
13777                int framesize = (((ctx->opcode >> 20) & 0xf) << 4
13778                                 | (ctx->opcode & 0xf)) << 3;
13779
13780                if (ctx->opcode & (1 << 7)) {
13781                    gen_mips16_save(ctx, xsregs, aregs,
13782                                    do_ra, do_s0, do_s1,
13783                                    framesize);
13784                } else {
13785                    gen_mips16_restore(ctx, xsregs, aregs,
13786                                       do_ra, do_s0, do_s1,
13787                                       framesize);
13788                }
13789            }
13790            break;
13791        default:
13792            generate_exception_end(ctx, EXCP_RI);
13793            break;
13794        }
13795        break;
13796    case M16_OPC_LI:
13797        tcg_gen_movi_tl(cpu_gpr[rx], (uint16_t) imm);
13798        break;
13799    case M16_OPC_CMPI:
13800        tcg_gen_xori_tl(cpu_gpr[24], cpu_gpr[rx], (uint16_t) imm);
13801        break;
13802#if defined(TARGET_MIPS64)
13803    case M16_OPC_SD:
13804        check_insn(ctx, ISA_MIPS3);
13805        check_mips_64(ctx);
13806        gen_st(ctx, OPC_SD, ry, rx, offset);
13807        break;
13808#endif
13809    case M16_OPC_LB:
13810        gen_ld(ctx, OPC_LB, ry, rx, offset);
13811        break;
13812    case M16_OPC_LH:
13813        gen_ld(ctx, OPC_LH, ry, rx, offset);
13814        break;
13815    case M16_OPC_LWSP:
13816        gen_ld(ctx, OPC_LW, rx, 29, offset);
13817        break;
13818    case M16_OPC_LW:
13819        gen_ld(ctx, OPC_LW, ry, rx, offset);
13820        break;
13821    case M16_OPC_LBU:
13822        gen_ld(ctx, OPC_LBU, ry, rx, offset);
13823        break;
13824    case M16_OPC_LHU:
13825        gen_ld(ctx, OPC_LHU, ry, rx, offset);
13826        break;
13827    case M16_OPC_LWPC:
13828        gen_ld(ctx, OPC_LWPC, rx, 0, offset);
13829        break;
13830#if defined(TARGET_MIPS64)
13831    case M16_OPC_LWU:
13832        check_insn(ctx, ISA_MIPS3);
13833        check_mips_64(ctx);
13834        gen_ld(ctx, OPC_LWU, ry, rx, offset);
13835        break;
13836#endif
13837    case M16_OPC_SB:
13838        gen_st(ctx, OPC_SB, ry, rx, offset);
13839        break;
13840    case M16_OPC_SH:
13841        gen_st(ctx, OPC_SH, ry, rx, offset);
13842        break;
13843    case M16_OPC_SWSP:
13844        gen_st(ctx, OPC_SW, rx, 29, offset);
13845        break;
13846    case M16_OPC_SW:
13847        gen_st(ctx, OPC_SW, ry, rx, offset);
13848        break;
13849#if defined(TARGET_MIPS64)
13850    case M16_OPC_I64:
13851        decode_i64_mips16(ctx, ry, funct, offset, 1);
13852        break;
13853#endif
13854    default:
13855        generate_exception_end(ctx, EXCP_RI);
13856        break;
13857    }
13858
13859    return 4;
13860}
13861
13862static inline bool is_uhi(int sdbbp_code)
13863{
13864#ifdef CONFIG_USER_ONLY
13865    return false;
13866#else
13867    return semihosting_enabled() && sdbbp_code == 1;
13868#endif
13869}
13870
13871#ifdef CONFIG_USER_ONLY
13872/* The above should dead-code away any calls to this..*/
13873static inline void gen_helper_do_semihosting(void *env)
13874{
13875    g_assert_not_reached();
13876}
13877#endif
13878
13879static int decode_mips16_opc(CPUMIPSState *env, DisasContext *ctx)
13880{
13881    int rx, ry;
13882    int sa;
13883    int op, cnvt_op, op1, offset;
13884    int funct;
13885    int n_bytes;
13886
13887    op = (ctx->opcode >> 11) & 0x1f;
13888    sa = (ctx->opcode >> 2) & 0x7;
13889    sa = sa == 0 ? 8 : sa;
13890    rx = xlat((ctx->opcode >> 8) & 0x7);
13891    cnvt_op = (ctx->opcode >> 5) & 0x7;
13892    ry = xlat((ctx->opcode >> 5) & 0x7);
13893    op1 = offset = ctx->opcode & 0x1f;
13894
13895    n_bytes = 2;
13896
13897    switch (op) {
13898    case M16_OPC_ADDIUSP:
13899        {
13900            int16_t imm = ((uint8_t) ctx->opcode) << 2;
13901
13902            gen_arith_imm(ctx, OPC_ADDIU, rx, 29, imm);
13903        }
13904        break;
13905    case M16_OPC_ADDIUPC:
13906        gen_addiupc(ctx, rx, ((uint8_t) ctx->opcode) << 2, 0, 0);
13907        break;
13908    case M16_OPC_B:
13909        offset = (ctx->opcode & 0x7ff) << 1;
13910        offset = (int16_t)(offset << 4) >> 4;
13911        gen_compute_branch(ctx, OPC_BEQ, 2, 0, 0, offset, 0);
13912        /* No delay slot, so just process as a normal instruction */
13913        break;
13914    case M16_OPC_JAL:
13915        offset = cpu_lduw_code(env, ctx->base.pc_next + 2);
13916        offset = (((ctx->opcode & 0x1f) << 21)
13917                  | ((ctx->opcode >> 5) & 0x1f) << 16
13918                  | offset) << 2;
13919        op = ((ctx->opcode >> 10) & 0x1) ? OPC_JALX : OPC_JAL;
13920        gen_compute_branch(ctx, op, 4, rx, ry, offset, 2);
13921        n_bytes = 4;
13922        break;
13923    case M16_OPC_BEQZ:
13924        gen_compute_branch(ctx, OPC_BEQ, 2, rx, 0,
13925                           ((int8_t)ctx->opcode) << 1, 0);
13926        /* No delay slot, so just process as a normal instruction */
13927        break;
13928    case M16_OPC_BNEQZ:
13929        gen_compute_branch(ctx, OPC_BNE, 2, rx, 0,
13930                           ((int8_t)ctx->opcode) << 1, 0);
13931        /* No delay slot, so just process as a normal instruction */
13932        break;
13933    case M16_OPC_SHIFT:
13934        switch (ctx->opcode & 0x3) {
13935        case 0x0:
13936            gen_shift_imm(ctx, OPC_SLL, rx, ry, sa);
13937            break;
13938        case 0x1:
13939#if defined(TARGET_MIPS64)
13940            check_insn(ctx, ISA_MIPS3);
13941            check_mips_64(ctx);
13942            gen_shift_imm(ctx, OPC_DSLL, rx, ry, sa);
13943#else
13944            generate_exception_end(ctx, EXCP_RI);
13945#endif
13946            break;
13947        case 0x2:
13948            gen_shift_imm(ctx, OPC_SRL, rx, ry, sa);
13949            break;
13950        case 0x3:
13951            gen_shift_imm(ctx, OPC_SRA, rx, ry, sa);
13952            break;
13953        }
13954        break;
13955#if defined(TARGET_MIPS64)
13956    case M16_OPC_LD:
13957        check_insn(ctx, ISA_MIPS3);
13958        check_mips_64(ctx);
13959        gen_ld(ctx, OPC_LD, ry, rx, offset << 3);
13960        break;
13961#endif
13962    case M16_OPC_RRIA:
13963        {
13964            int16_t imm = (int8_t)((ctx->opcode & 0xf) << 4) >> 4;
13965
13966            if ((ctx->opcode >> 4) & 1) {
13967#if defined(TARGET_MIPS64)
13968                check_insn(ctx, ISA_MIPS3);
13969                check_mips_64(ctx);
13970                gen_arith_imm(ctx, OPC_DADDIU, ry, rx, imm);
13971#else
13972                generate_exception_end(ctx, EXCP_RI);
13973#endif
13974            } else {
13975                gen_arith_imm(ctx, OPC_ADDIU, ry, rx, imm);
13976            }
13977        }
13978        break;
13979    case M16_OPC_ADDIU8:
13980        {
13981            int16_t imm = (int8_t) ctx->opcode;
13982
13983            gen_arith_imm(ctx, OPC_ADDIU, rx, rx, imm);
13984        }
13985        break;
13986    case M16_OPC_SLTI:
13987        {
13988            int16_t imm = (uint8_t) ctx->opcode;
13989            gen_slt_imm(ctx, OPC_SLTI, 24, rx, imm);
13990        }
13991        break;
13992    case M16_OPC_SLTIU:
13993        {
13994            int16_t imm = (uint8_t) ctx->opcode;
13995            gen_slt_imm(ctx, OPC_SLTIU, 24, rx, imm);
13996        }
13997        break;
13998    case M16_OPC_I8:
13999        {
14000            int reg32;
14001
14002            funct = (ctx->opcode >> 8) & 0x7;
14003            switch (funct) {
14004            case I8_BTEQZ:
14005                gen_compute_branch(ctx, OPC_BEQ, 2, 24, 0,
14006                                   ((int8_t)ctx->opcode) << 1, 0);
14007                break;
14008            case I8_BTNEZ:
14009                gen_compute_branch(ctx, OPC_BNE, 2, 24, 0,
14010                                   ((int8_t)ctx->opcode) << 1, 0);
14011                break;
14012            case I8_SWRASP:
14013                gen_st(ctx, OPC_SW, 31, 29, (ctx->opcode & 0xff) << 2);
14014                break;
14015            case I8_ADJSP:
14016                gen_arith_imm(ctx, OPC_ADDIU, 29, 29,
14017                              ((int8_t)ctx->opcode) << 3);
14018                break;
14019            case I8_SVRS:
14020                check_insn(ctx, ISA_MIPS32);
14021                {
14022                    int do_ra = ctx->opcode & (1 << 6);
14023                    int do_s0 = ctx->opcode & (1 << 5);
14024                    int do_s1 = ctx->opcode & (1 << 4);
14025                    int framesize = ctx->opcode & 0xf;
14026
14027                    if (framesize == 0) {
14028                        framesize = 128;
14029                    } else {
14030                        framesize = framesize << 3;
14031                    }
14032
14033                    if (ctx->opcode & (1 << 7)) {
14034                        gen_mips16_save(ctx, 0, 0,
14035                                        do_ra, do_s0, do_s1, framesize);
14036                    } else {
14037                        gen_mips16_restore(ctx, 0, 0,
14038                                           do_ra, do_s0, do_s1, framesize);
14039                    }
14040                }
14041                break;
14042            case I8_MOV32R:
14043                {
14044                    int rz = xlat(ctx->opcode & 0x7);
14045
14046                    reg32 = (((ctx->opcode >> 3) & 0x3) << 3) |
14047                        ((ctx->opcode >> 5) & 0x7);
14048                    gen_arith(ctx, OPC_ADDU, reg32, rz, 0);
14049                }
14050                break;
14051            case I8_MOVR32:
14052                reg32 = ctx->opcode & 0x1f;
14053                gen_arith(ctx, OPC_ADDU, ry, reg32, 0);
14054                break;
14055            default:
14056                generate_exception_end(ctx, EXCP_RI);
14057                break;
14058            }
14059        }
14060        break;
14061    case M16_OPC_LI:
14062        {
14063            int16_t imm = (uint8_t) ctx->opcode;
14064
14065            gen_arith_imm(ctx, OPC_ADDIU, rx, 0, imm);
14066        }
14067        break;
14068    case M16_OPC_CMPI:
14069        {
14070            int16_t imm = (uint8_t) ctx->opcode;
14071            gen_logic_imm(ctx, OPC_XORI, 24, rx, imm);
14072        }
14073        break;
14074#if defined(TARGET_MIPS64)
14075    case M16_OPC_SD:
14076        check_insn(ctx, ISA_MIPS3);
14077        check_mips_64(ctx);
14078        gen_st(ctx, OPC_SD, ry, rx, offset << 3);
14079        break;
14080#endif
14081    case M16_OPC_LB:
14082        gen_ld(ctx, OPC_LB, ry, rx, offset);
14083        break;
14084    case M16_OPC_LH:
14085        gen_ld(ctx, OPC_LH, ry, rx, offset << 1);
14086        break;
14087    case M16_OPC_LWSP:
14088        gen_ld(ctx, OPC_LW, rx, 29, ((uint8_t)ctx->opcode) << 2);
14089        break;
14090    case M16_OPC_LW:
14091        gen_ld(ctx, OPC_LW, ry, rx, offset << 2);
14092        break;
14093    case M16_OPC_LBU:
14094        gen_ld(ctx, OPC_LBU, ry, rx, offset);
14095        break;
14096    case M16_OPC_LHU:
14097        gen_ld(ctx, OPC_LHU, ry, rx, offset << 1);
14098        break;
14099    case M16_OPC_LWPC:
14100        gen_ld(ctx, OPC_LWPC, rx, 0, ((uint8_t)ctx->opcode) << 2);
14101        break;
14102#if defined(TARGET_MIPS64)
14103    case M16_OPC_LWU:
14104        check_insn(ctx, ISA_MIPS3);
14105        check_mips_64(ctx);
14106        gen_ld(ctx, OPC_LWU, ry, rx, offset << 2);
14107        break;
14108#endif
14109    case M16_OPC_SB:
14110        gen_st(ctx, OPC_SB, ry, rx, offset);
14111        break;
14112    case M16_OPC_SH:
14113        gen_st(ctx, OPC_SH, ry, rx, offset << 1);
14114        break;
14115    case M16_OPC_SWSP:
14116        gen_st(ctx, OPC_SW, rx, 29, ((uint8_t)ctx->opcode) << 2);
14117        break;
14118    case M16_OPC_SW:
14119        gen_st(ctx, OPC_SW, ry, rx, offset << 2);
14120        break;
14121    case M16_OPC_RRR:
14122        {
14123            int rz = xlat((ctx->opcode >> 2) & 0x7);
14124            int mips32_op;
14125
14126            switch (ctx->opcode & 0x3) {
14127            case RRR_ADDU:
14128                mips32_op = OPC_ADDU;
14129                break;
14130            case RRR_SUBU:
14131                mips32_op = OPC_SUBU;
14132                break;
14133#if defined(TARGET_MIPS64)
14134            case RRR_DADDU:
14135                mips32_op = OPC_DADDU;
14136                check_insn(ctx, ISA_MIPS3);
14137                check_mips_64(ctx);
14138                break;
14139            case RRR_DSUBU:
14140                mips32_op = OPC_DSUBU;
14141                check_insn(ctx, ISA_MIPS3);
14142                check_mips_64(ctx);
14143                break;
14144#endif
14145            default:
14146                generate_exception_end(ctx, EXCP_RI);
14147                goto done;
14148            }
14149
14150            gen_arith(ctx, mips32_op, rz, rx, ry);
14151        done:
14152            ;
14153        }
14154        break;
14155    case M16_OPC_RR:
14156        switch (op1) {
14157        case RR_JR:
14158            {
14159                int nd = (ctx->opcode >> 7) & 0x1;
14160                int link = (ctx->opcode >> 6) & 0x1;
14161                int ra = (ctx->opcode >> 5) & 0x1;
14162
14163                if (nd) {
14164                    check_insn(ctx, ISA_MIPS32);
14165                }
14166
14167                if (link) {
14168                    op = OPC_JALR;
14169                } else {
14170                    op = OPC_JR;
14171                }
14172
14173                gen_compute_branch(ctx, op, 2, ra ? 31 : rx, 31, 0,
14174                                   (nd ? 0 : 2));
14175            }
14176            break;
14177        case RR_SDBBP:
14178            if (is_uhi(extract32(ctx->opcode, 5, 6))) {
14179                gen_helper_do_semihosting(cpu_env);
14180            } else {
14181                /*
14182                 * XXX: not clear which exception should be raised
14183                 *      when in debug mode...
14184                 */
14185                check_insn(ctx, ISA_MIPS32);
14186                generate_exception_end(ctx, EXCP_DBp);
14187            }
14188            break;
14189        case RR_SLT:
14190            gen_slt(ctx, OPC_SLT, 24, rx, ry);
14191            break;
14192        case RR_SLTU:
14193            gen_slt(ctx, OPC_SLTU, 24, rx, ry);
14194            break;
14195        case RR_BREAK:
14196            generate_exception_end(ctx, EXCP_BREAK);
14197            break;
14198        case RR_SLLV:
14199            gen_shift(ctx, OPC_SLLV, ry, rx, ry);
14200            break;
14201        case RR_SRLV:
14202            gen_shift(ctx, OPC_SRLV, ry, rx, ry);
14203            break;
14204        case RR_SRAV:
14205            gen_shift(ctx, OPC_SRAV, ry, rx, ry);
14206            break;
14207#if defined(TARGET_MIPS64)
14208        case RR_DSRL:
14209            check_insn(ctx, ISA_MIPS3);
14210            check_mips_64(ctx);
14211            gen_shift_imm(ctx, OPC_DSRL, ry, ry, sa);
14212            break;
14213#endif
14214        case RR_CMP:
14215            gen_logic(ctx, OPC_XOR, 24, rx, ry);
14216            break;
14217        case RR_NEG:
14218            gen_arith(ctx, OPC_SUBU, rx, 0, ry);
14219            break;
14220        case RR_AND:
14221            gen_logic(ctx, OPC_AND, rx, rx, ry);
14222            break;
14223        case RR_OR:
14224            gen_logic(ctx, OPC_OR, rx, rx, ry);
14225            break;
14226        case RR_XOR:
14227            gen_logic(ctx, OPC_XOR, rx, rx, ry);
14228            break;
14229        case RR_NOT:
14230            gen_logic(ctx, OPC_NOR, rx, ry, 0);
14231            break;
14232        case RR_MFHI:
14233            gen_HILO(ctx, OPC_MFHI, 0, rx);
14234            break;
14235        case RR_CNVT:
14236            check_insn(ctx, ISA_MIPS32);
14237            switch (cnvt_op) {
14238            case RR_RY_CNVT_ZEB:
14239                tcg_gen_ext8u_tl(cpu_gpr[rx], cpu_gpr[rx]);
14240                break;
14241            case RR_RY_CNVT_ZEH:
14242                tcg_gen_ext16u_tl(cpu_gpr[rx], cpu_gpr[rx]);
14243                break;
14244            case RR_RY_CNVT_SEB:
14245                tcg_gen_ext8s_tl(cpu_gpr[rx], cpu_gpr[rx]);
14246                break;
14247            case RR_RY_CNVT_SEH:
14248                tcg_gen_ext16s_tl(cpu_gpr[rx], cpu_gpr[rx]);
14249                break;
14250#if defined (TARGET_MIPS64)
14251            case RR_RY_CNVT_ZEW:
14252                check_insn(ctx, ISA_MIPS64);
14253                check_mips_64(ctx);
14254                tcg_gen_ext32u_tl(cpu_gpr[rx], cpu_gpr[rx]);
14255                break;
14256            case RR_RY_CNVT_SEW:
14257                check_insn(ctx, ISA_MIPS64);
14258                check_mips_64(ctx);
14259                tcg_gen_ext32s_tl(cpu_gpr[rx], cpu_gpr[rx]);
14260                break;
14261#endif
14262            default:
14263                generate_exception_end(ctx, EXCP_RI);
14264                break;
14265            }
14266            break;
14267        case RR_MFLO:
14268            gen_HILO(ctx, OPC_MFLO, 0, rx);
14269            break;
14270#if defined(TARGET_MIPS64)
14271        case RR_DSRA:
14272            check_insn(ctx, ISA_MIPS3);
14273            check_mips_64(ctx);
14274            gen_shift_imm(ctx, OPC_DSRA, ry, ry, sa);
14275            break;
14276        case RR_DSLLV:
14277            check_insn(ctx, ISA_MIPS3);
14278            check_mips_64(ctx);
14279            gen_shift(ctx, OPC_DSLLV, ry, rx, ry);
14280            break;
14281        case RR_DSRLV:
14282            check_insn(ctx, ISA_MIPS3);
14283            check_mips_64(ctx);
14284            gen_shift(ctx, OPC_DSRLV, ry, rx, ry);
14285            break;
14286        case RR_DSRAV:
14287            check_insn(ctx, ISA_MIPS3);
14288            check_mips_64(ctx);
14289            gen_shift(ctx, OPC_DSRAV, ry, rx, ry);
14290            break;
14291#endif
14292        case RR_MULT:
14293            gen_muldiv(ctx, OPC_MULT, 0, rx, ry);
14294            break;
14295        case RR_MULTU:
14296            gen_muldiv(ctx, OPC_MULTU, 0, rx, ry);
14297            break;
14298        case RR_DIV:
14299            gen_muldiv(ctx, OPC_DIV, 0, rx, ry);
14300            break;
14301        case RR_DIVU:
14302            gen_muldiv(ctx, OPC_DIVU, 0, rx, ry);
14303            break;
14304#if defined(TARGET_MIPS64)
14305        case RR_DMULT:
14306            check_insn(ctx, ISA_MIPS3);
14307            check_mips_64(ctx);
14308            gen_muldiv(ctx, OPC_DMULT, 0, rx, ry);
14309            break;
14310        case RR_DMULTU:
14311            check_insn(ctx, ISA_MIPS3);
14312            check_mips_64(ctx);
14313            gen_muldiv(ctx, OPC_DMULTU, 0, rx, ry);
14314            break;
14315        case RR_DDIV:
14316            check_insn(ctx, ISA_MIPS3);
14317            check_mips_64(ctx);
14318            gen_muldiv(ctx, OPC_DDIV, 0, rx, ry);
14319            break;
14320        case RR_DDIVU:
14321            check_insn(ctx, ISA_MIPS3);
14322            check_mips_64(ctx);
14323            gen_muldiv(ctx, OPC_DDIVU, 0, rx, ry);
14324            break;
14325#endif
14326        default:
14327            generate_exception_end(ctx, EXCP_RI);
14328            break;
14329        }
14330        break;
14331    case M16_OPC_EXTEND:
14332        decode_extended_mips16_opc(env, ctx);
14333        n_bytes = 4;
14334        break;
14335#if defined(TARGET_MIPS64)
14336    case M16_OPC_I64:
14337        funct = (ctx->opcode >> 8) & 0x7;
14338        decode_i64_mips16(ctx, ry, funct, offset, 0);
14339        break;
14340#endif
14341    default:
14342        generate_exception_end(ctx, EXCP_RI);
14343        break;
14344    }
14345
14346    return n_bytes;
14347}
14348
14349/* microMIPS extension to MIPS32/MIPS64 */
14350
14351/*
14352 * microMIPS32/microMIPS64 major opcodes
14353 *
14354 * 1. MIPS Architecture for Programmers Volume II-B:
14355 *      The microMIPS32 Instruction Set (Revision 3.05)
14356 *
14357 *    Table 6.2 microMIPS32 Encoding of Major Opcode Field
14358 *
14359 * 2. MIPS Architecture For Programmers Volume II-A:
14360 *      The MIPS64 Instruction Set (Revision 3.51)
14361 */
14362
14363enum {
14364    POOL32A = 0x00,
14365    POOL16A = 0x01,
14366    LBU16 = 0x02,
14367    MOVE16 = 0x03,
14368    ADDI32 = 0x04,
14369    R6_LUI = 0x04,
14370    AUI = 0x04,
14371    LBU32 = 0x05,
14372    SB32 = 0x06,
14373    LB32 = 0x07,
14374
14375    POOL32B = 0x08,
14376    POOL16B = 0x09,
14377    LHU16 = 0x0a,
14378    ANDI16 = 0x0b,
14379    ADDIU32 = 0x0c,
14380    LHU32 = 0x0d,
14381    SH32 = 0x0e,
14382    LH32 = 0x0f,
14383
14384    POOL32I = 0x10,
14385    POOL16C = 0x11,
14386    LWSP16 = 0x12,
14387    POOL16D = 0x13,
14388    ORI32 = 0x14,
14389    POOL32F = 0x15,
14390    POOL32S = 0x16,  /* MIPS64 */
14391    DADDIU32 = 0x17, /* MIPS64 */
14392
14393    POOL32C = 0x18,
14394    LWGP16 = 0x19,
14395    LW16 = 0x1a,
14396    POOL16E = 0x1b,
14397    XORI32 = 0x1c,
14398    JALS32 = 0x1d,
14399    BOVC = 0x1d,
14400    BEQC = 0x1d,
14401    BEQZALC = 0x1d,
14402    ADDIUPC = 0x1e,
14403    PCREL = 0x1e,
14404    BNVC = 0x1f,
14405    BNEC = 0x1f,
14406    BNEZALC = 0x1f,
14407
14408    R6_BEQZC = 0x20,
14409    JIC = 0x20,
14410    POOL16F = 0x21,
14411    SB16 = 0x22,
14412    BEQZ16 = 0x23,
14413    BEQZC16 = 0x23,
14414    SLTI32 = 0x24,
14415    BEQ32 = 0x25,
14416    BC = 0x25,
14417    SWC132 = 0x26,
14418    LWC132 = 0x27,
14419
14420    /* 0x29 is reserved */
14421    RES_29 = 0x29,
14422    R6_BNEZC = 0x28,
14423    JIALC = 0x28,
14424    SH16 = 0x2a,
14425    BNEZ16 = 0x2b,
14426    BNEZC16 = 0x2b,
14427    SLTIU32 = 0x2c,
14428    BNE32 = 0x2d,
14429    BALC = 0x2d,
14430    SDC132 = 0x2e,
14431    LDC132 = 0x2f,
14432
14433    /* 0x31 is reserved */
14434    RES_31 = 0x31,
14435    BLEZALC = 0x30,
14436    BGEZALC = 0x30,
14437    BGEUC = 0x30,
14438    SWSP16 = 0x32,
14439    B16 = 0x33,
14440    BC16 = 0x33,
14441    ANDI32 = 0x34,
14442    J32 = 0x35,
14443    BGTZC = 0x35,
14444    BLTZC = 0x35,
14445    BLTC = 0x35,
14446    SD32 = 0x36, /* MIPS64 */
14447    LD32 = 0x37, /* MIPS64 */
14448
14449    /* 0x39 is reserved */
14450    RES_39 = 0x39,
14451    BGTZALC = 0x38,
14452    BLTZALC = 0x38,
14453    BLTUC = 0x38,
14454    SW16 = 0x3a,
14455    LI16 = 0x3b,
14456    JALX32 = 0x3c,
14457    JAL32 = 0x3d,
14458    BLEZC = 0x3d,
14459    BGEZC = 0x3d,
14460    BGEC = 0x3d,
14461    SW32 = 0x3e,
14462    LW32 = 0x3f
14463};
14464
14465/* PCREL Instructions perform PC-Relative address calculation. bits 20..16 */
14466enum {
14467    ADDIUPC_00 = 0x00,
14468    ADDIUPC_01 = 0x01,
14469    ADDIUPC_02 = 0x02,
14470    ADDIUPC_03 = 0x03,
14471    ADDIUPC_04 = 0x04,
14472    ADDIUPC_05 = 0x05,
14473    ADDIUPC_06 = 0x06,
14474    ADDIUPC_07 = 0x07,
14475    AUIPC = 0x1e,
14476    ALUIPC = 0x1f,
14477    LWPC_08 = 0x08,
14478    LWPC_09 = 0x09,
14479    LWPC_0A = 0x0A,
14480    LWPC_0B = 0x0B,
14481    LWPC_0C = 0x0C,
14482    LWPC_0D = 0x0D,
14483    LWPC_0E = 0x0E,
14484    LWPC_0F = 0x0F,
14485};
14486
14487/* POOL32A encoding of minor opcode field */
14488
14489enum {
14490    /*
14491     * These opcodes are distinguished only by bits 9..6; those bits are
14492     * what are recorded below.
14493     */
14494    SLL32 = 0x0,
14495    SRL32 = 0x1,
14496    SRA = 0x2,
14497    ROTR = 0x3,
14498    SELEQZ = 0x5,
14499    SELNEZ = 0x6,
14500    R6_RDHWR = 0x7,
14501
14502    SLLV = 0x0,
14503    SRLV = 0x1,
14504    SRAV = 0x2,
14505    ROTRV = 0x3,
14506    ADD = 0x4,
14507    ADDU32 = 0x5,
14508    SUB = 0x6,
14509    SUBU32 = 0x7,
14510    MUL = 0x8,
14511    AND = 0x9,
14512    OR32 = 0xa,
14513    NOR = 0xb,
14514    XOR32 = 0xc,
14515    SLT = 0xd,
14516    SLTU = 0xe,
14517
14518    MOVN = 0x0,
14519    R6_MUL  = 0x0,
14520    MOVZ = 0x1,
14521    MUH  = 0x1,
14522    MULU = 0x2,
14523    MUHU = 0x3,
14524    LWXS = 0x4,
14525    R6_DIV  = 0x4,
14526    MOD  = 0x5,
14527    R6_DIVU = 0x6,
14528    MODU = 0x7,
14529
14530    /* The following can be distinguished by their lower 6 bits. */
14531    BREAK32 = 0x07,
14532    INS = 0x0c,
14533    LSA = 0x0f,
14534    ALIGN = 0x1f,
14535    EXT = 0x2c,
14536    POOL32AXF = 0x3c,
14537    SIGRIE = 0x3f
14538};
14539
14540/* POOL32AXF encoding of minor opcode field extension */
14541
14542/*
14543 * 1. MIPS Architecture for Programmers Volume II-B:
14544 *      The microMIPS32 Instruction Set (Revision 3.05)
14545 *
14546 *    Table 6.5 POOL32Axf Encoding of Minor Opcode Extension Field
14547 *
14548 * 2. MIPS Architecture for Programmers VolumeIV-e:
14549 *      The MIPS DSP Application-Specific Extension
14550 *        to the microMIPS32 Architecture (Revision 2.34)
14551 *
14552 *    Table 5.5 POOL32Axf Encoding of Minor Opcode Extension Field
14553 */
14554
14555enum {
14556    /* bits 11..6 */
14557    TEQ = 0x00,
14558    TGE = 0x08,
14559    TGEU = 0x10,
14560    TLT = 0x20,
14561    TLTU = 0x28,
14562    TNE = 0x30,
14563
14564    MFC0 = 0x03,
14565    MTC0 = 0x0b,
14566
14567    /* begin of microMIPS32 DSP */
14568
14569    /* bits 13..12 for 0x01 */
14570    MFHI_ACC = 0x0,
14571    MFLO_ACC = 0x1,
14572    MTHI_ACC = 0x2,
14573    MTLO_ACC = 0x3,
14574
14575    /* bits 13..12 for 0x2a */
14576    MADD_ACC = 0x0,
14577    MADDU_ACC = 0x1,
14578    MSUB_ACC = 0x2,
14579    MSUBU_ACC = 0x3,
14580
14581    /* bits 13..12 for 0x32 */
14582    MULT_ACC = 0x0,
14583    MULTU_ACC = 0x1,
14584
14585    /* end of microMIPS32 DSP */
14586
14587    /* bits 15..12 for 0x2c */
14588    BITSWAP = 0x0,
14589    SEB = 0x2,
14590    SEH = 0x3,
14591    CLO = 0x4,
14592    CLZ = 0x5,
14593    RDHWR = 0x6,
14594    WSBH = 0x7,
14595    MULT = 0x8,
14596    MULTU = 0x9,
14597    DIV = 0xa,
14598    DIVU = 0xb,
14599    MADD = 0xc,
14600    MADDU = 0xd,
14601    MSUB = 0xe,
14602    MSUBU = 0xf,
14603
14604    /* bits 15..12 for 0x34 */
14605    MFC2 = 0x4,
14606    MTC2 = 0x5,
14607    MFHC2 = 0x8,
14608    MTHC2 = 0x9,
14609    CFC2 = 0xc,
14610    CTC2 = 0xd,
14611
14612    /* bits 15..12 for 0x3c */
14613    JALR = 0x0,
14614    JR = 0x0,                   /* alias */
14615    JALRC = 0x0,
14616    JRC = 0x0,
14617    JALR_HB = 0x1,
14618    JALRC_HB = 0x1,
14619    JALRS = 0x4,
14620    JALRS_HB = 0x5,
14621
14622    /* bits 15..12 for 0x05 */
14623    RDPGPR = 0xe,
14624    WRPGPR = 0xf,
14625
14626    /* bits 15..12 for 0x0d */
14627    TLBP = 0x0,
14628    TLBR = 0x1,
14629    TLBWI = 0x2,
14630    TLBWR = 0x3,
14631    TLBINV = 0x4,
14632    TLBINVF = 0x5,
14633    WAIT = 0x9,
14634    IRET = 0xd,
14635    DERET = 0xe,
14636    ERET = 0xf,
14637
14638    /* bits 15..12 for 0x15 */
14639    DMT = 0x0,
14640    DVPE = 0x1,
14641    EMT = 0x2,
14642    EVPE = 0x3,
14643
14644    /* bits 15..12 for 0x1d */
14645    DI = 0x4,
14646    EI = 0x5,
14647
14648    /* bits 15..12 for 0x2d */
14649    SYNC = 0x6,
14650    SYSCALL = 0x8,
14651    SDBBP = 0xd,
14652
14653    /* bits 15..12 for 0x35 */
14654    MFHI32 = 0x0,
14655    MFLO32 = 0x1,
14656    MTHI32 = 0x2,
14657    MTLO32 = 0x3,
14658};
14659
14660/* POOL32B encoding of minor opcode field (bits 15..12) */
14661
14662enum {
14663    LWC2 = 0x0,
14664    LWP = 0x1,
14665    LDP = 0x4,
14666    LWM32 = 0x5,
14667    CACHE = 0x6,
14668    LDM = 0x7,
14669    SWC2 = 0x8,
14670    SWP = 0x9,
14671    SDP = 0xc,
14672    SWM32 = 0xd,
14673    SDM = 0xf
14674};
14675
14676/* POOL32C encoding of minor opcode field (bits 15..12) */
14677
14678enum {
14679    LWL = 0x0,
14680    SWL = 0x8,
14681    LWR = 0x1,
14682    SWR = 0x9,
14683    PREF = 0x2,
14684    ST_EVA = 0xa,
14685    LL = 0x3,
14686    SC = 0xb,
14687    LDL = 0x4,
14688    SDL = 0xc,
14689    LDR = 0x5,
14690    SDR = 0xd,
14691    LD_EVA = 0x6,
14692    LWU = 0xe,
14693    LLD = 0x7,
14694    SCD = 0xf
14695};
14696
14697/* POOL32C LD-EVA encoding of minor opcode field (bits 11..9) */
14698
14699enum {
14700    LBUE = 0x0,
14701    LHUE = 0x1,
14702    LWLE = 0x2,
14703    LWRE = 0x3,
14704    LBE = 0x4,
14705    LHE = 0x5,
14706    LLE = 0x6,
14707    LWE = 0x7,
14708};
14709
14710/* POOL32C ST-EVA encoding of minor opcode field (bits 11..9) */
14711
14712enum {
14713    SWLE = 0x0,
14714    SWRE = 0x1,
14715    PREFE = 0x2,
14716    CACHEE = 0x3,
14717    SBE = 0x4,
14718    SHE = 0x5,
14719    SCE = 0x6,
14720    SWE = 0x7,
14721};
14722
14723/* POOL32F encoding of minor opcode field (bits 5..0) */
14724
14725enum {
14726    /* These are the bit 7..6 values */
14727    ADD_FMT = 0x0,
14728
14729    SUB_FMT = 0x1,
14730
14731    MUL_FMT = 0x2,
14732
14733    DIV_FMT = 0x3,
14734
14735    /* These are the bit 8..6 values */
14736    MOVN_FMT = 0x0,
14737    RSQRT2_FMT = 0x0,
14738    MOVF_FMT = 0x0,
14739    RINT_FMT = 0x0,
14740    SELNEZ_FMT = 0x0,
14741
14742    MOVZ_FMT = 0x1,
14743    LWXC1 = 0x1,
14744    MOVT_FMT = 0x1,
14745    CLASS_FMT = 0x1,
14746    SELEQZ_FMT = 0x1,
14747
14748    PLL_PS = 0x2,
14749    SWXC1 = 0x2,
14750    SEL_FMT = 0x2,
14751
14752    PLU_PS = 0x3,
14753    LDXC1 = 0x3,
14754
14755    MOVN_FMT_04 = 0x4,
14756    PUL_PS = 0x4,
14757    SDXC1 = 0x4,
14758    RECIP2_FMT = 0x4,
14759
14760    MOVZ_FMT_05 = 0x05,
14761    PUU_PS = 0x5,
14762    LUXC1 = 0x5,
14763
14764    CVT_PS_S = 0x6,
14765    SUXC1 = 0x6,
14766    ADDR_PS = 0x6,
14767    PREFX = 0x6,
14768    MADDF_FMT = 0x6,
14769
14770    MULR_PS = 0x7,
14771    MSUBF_FMT = 0x7,
14772
14773    MADD_S = 0x01,
14774    MADD_D = 0x09,
14775    MADD_PS = 0x11,
14776    ALNV_PS = 0x19,
14777    MSUB_S = 0x21,
14778    MSUB_D = 0x29,
14779    MSUB_PS = 0x31,
14780
14781    NMADD_S = 0x02,
14782    NMADD_D = 0x0a,
14783    NMADD_PS = 0x12,
14784    NMSUB_S = 0x22,
14785    NMSUB_D = 0x2a,
14786    NMSUB_PS = 0x32,
14787
14788    MIN_FMT = 0x3,
14789    MAX_FMT = 0xb,
14790    MINA_FMT = 0x23,
14791    MAXA_FMT = 0x2b,
14792    POOL32FXF = 0x3b,
14793
14794    CABS_COND_FMT = 0x1c,              /* MIPS3D */
14795    C_COND_FMT = 0x3c,
14796
14797    CMP_CONDN_S = 0x5,
14798    CMP_CONDN_D = 0x15
14799};
14800
14801/* POOL32Fxf encoding of minor opcode extension field */
14802
14803enum {
14804    CVT_L = 0x04,
14805    RSQRT_FMT = 0x08,
14806    FLOOR_L = 0x0c,
14807    CVT_PW_PS = 0x1c,
14808    CVT_W = 0x24,
14809    SQRT_FMT = 0x28,
14810    FLOOR_W = 0x2c,
14811    CVT_PS_PW = 0x3c,
14812    CFC1 = 0x40,
14813    RECIP_FMT = 0x48,
14814    CEIL_L = 0x4c,
14815    CTC1 = 0x60,
14816    CEIL_W = 0x6c,
14817    MFC1 = 0x80,
14818    CVT_S_PL = 0x84,
14819    TRUNC_L = 0x8c,
14820    MTC1 = 0xa0,
14821    CVT_S_PU = 0xa4,
14822    TRUNC_W = 0xac,
14823    MFHC1 = 0xc0,
14824    ROUND_L = 0xcc,
14825    MTHC1 = 0xe0,
14826    ROUND_W = 0xec,
14827
14828    MOV_FMT = 0x01,
14829    MOVF = 0x05,
14830    ABS_FMT = 0x0d,
14831    RSQRT1_FMT = 0x1d,
14832    MOVT = 0x25,
14833    NEG_FMT = 0x2d,
14834    CVT_D = 0x4d,
14835    RECIP1_FMT = 0x5d,
14836    CVT_S = 0x6d
14837};
14838
14839/* POOL32I encoding of minor opcode field (bits 25..21) */
14840
14841enum {
14842    BLTZ = 0x00,
14843    BLTZAL = 0x01,
14844    BGEZ = 0x02,
14845    BGEZAL = 0x03,
14846    BLEZ = 0x04,
14847    BNEZC = 0x05,
14848    BGTZ = 0x06,
14849    BEQZC = 0x07,
14850    TLTI = 0x08,
14851    BC1EQZC = 0x08,
14852    TGEI = 0x09,
14853    BC1NEZC = 0x09,
14854    TLTIU = 0x0a,
14855    BC2EQZC = 0x0a,
14856    TGEIU = 0x0b,
14857    BC2NEZC = 0x0a,
14858    TNEI = 0x0c,
14859    R6_SYNCI = 0x0c,
14860    LUI = 0x0d,
14861    TEQI = 0x0e,
14862    SYNCI = 0x10,
14863    BLTZALS = 0x11,
14864    BGEZALS = 0x13,
14865    BC2F = 0x14,
14866    BC2T = 0x15,
14867    BPOSGE64 = 0x1a,
14868    BPOSGE32 = 0x1b,
14869    /* These overlap and are distinguished by bit16 of the instruction */
14870    BC1F = 0x1c,
14871    BC1T = 0x1d,
14872    BC1ANY2F = 0x1c,
14873    BC1ANY2T = 0x1d,
14874    BC1ANY4F = 0x1e,
14875    BC1ANY4T = 0x1f
14876};
14877
14878/* POOL16A encoding of minor opcode field */
14879
14880enum {
14881    ADDU16 = 0x0,
14882    SUBU16 = 0x1
14883};
14884
14885/* POOL16B encoding of minor opcode field */
14886
14887enum {
14888    SLL16 = 0x0,
14889    SRL16 = 0x1
14890};
14891
14892/* POOL16C encoding of minor opcode field */
14893
14894enum {
14895    NOT16 = 0x00,
14896    XOR16 = 0x04,
14897    AND16 = 0x08,
14898    OR16 = 0x0c,
14899    LWM16 = 0x10,
14900    SWM16 = 0x14,
14901    JR16 = 0x18,
14902    JRC16 = 0x1a,
14903    JALR16 = 0x1c,
14904    JALR16S = 0x1e,
14905    MFHI16 = 0x20,
14906    MFLO16 = 0x24,
14907    BREAK16 = 0x28,
14908    SDBBP16 = 0x2c,
14909    JRADDIUSP = 0x30
14910};
14911
14912/* R6 POOL16C encoding of minor opcode field (bits 0..5) */
14913
14914enum {
14915    R6_NOT16    = 0x00,
14916    R6_AND16    = 0x01,
14917    R6_LWM16    = 0x02,
14918    R6_JRC16    = 0x03,
14919    MOVEP       = 0x04,
14920    MOVEP_05    = 0x05,
14921    MOVEP_06    = 0x06,
14922    MOVEP_07    = 0x07,
14923    R6_XOR16    = 0x08,
14924    R6_OR16     = 0x09,
14925    R6_SWM16    = 0x0a,
14926    JALRC16     = 0x0b,
14927    MOVEP_0C    = 0x0c,
14928    MOVEP_0D    = 0x0d,
14929    MOVEP_0E    = 0x0e,
14930    MOVEP_0F    = 0x0f,
14931    JRCADDIUSP  = 0x13,
14932    R6_BREAK16  = 0x1b,
14933    R6_SDBBP16  = 0x3b
14934};
14935
14936/* POOL16D encoding of minor opcode field */
14937
14938enum {
14939    ADDIUS5 = 0x0,
14940    ADDIUSP = 0x1
14941};
14942
14943/* POOL16E encoding of minor opcode field */
14944
14945enum {
14946    ADDIUR2 = 0x0,
14947    ADDIUR1SP = 0x1
14948};
14949
14950static int mmreg(int r)
14951{
14952    static const int map[] = { 16, 17, 2, 3, 4, 5, 6, 7 };
14953
14954    return map[r];
14955}
14956
14957/* Used for 16-bit store instructions.  */
14958static int mmreg2(int r)
14959{
14960    static const int map[] = { 0, 17, 2, 3, 4, 5, 6, 7 };
14961
14962    return map[r];
14963}
14964
14965#define uMIPS_RD(op) ((op >> 7) & 0x7)
14966#define uMIPS_RS(op) ((op >> 4) & 0x7)
14967#define uMIPS_RS2(op) uMIPS_RS(op)
14968#define uMIPS_RS1(op) ((op >> 1) & 0x7)
14969#define uMIPS_RD5(op) ((op >> 5) & 0x1f)
14970#define uMIPS_RS5(op) (op & 0x1f)
14971
14972/* Signed immediate */
14973#define SIMM(op, start, width)                                          \
14974    ((int32_t)(((op >> start) & ((~0U) >> (32-width)))                 \
14975               << (32-width))                                           \
14976     >> (32-width))
14977/* Zero-extended immediate */
14978#define ZIMM(op, start, width) ((op >> start) & ((~0U) >> (32-width)))
14979
14980static void gen_addiur1sp(DisasContext *ctx)
14981{
14982    int rd = mmreg(uMIPS_RD(ctx->opcode));
14983
14984    gen_arith_imm(ctx, OPC_ADDIU, rd, 29, ((ctx->opcode >> 1) & 0x3f) << 2);
14985}
14986
14987static void gen_addiur2(DisasContext *ctx)
14988{
14989    static const int decoded_imm[] = { 1, 4, 8, 12, 16, 20, 24, -1 };
14990    int rd = mmreg(uMIPS_RD(ctx->opcode));
14991    int rs = mmreg(uMIPS_RS(ctx->opcode));
14992
14993    gen_arith_imm(ctx, OPC_ADDIU, rd, rs, decoded_imm[ZIMM(ctx->opcode, 1, 3)]);
14994}
14995
14996static void gen_addiusp(DisasContext *ctx)
14997{
14998    int encoded = ZIMM(ctx->opcode, 1, 9);
14999    int decoded;
15000
15001    if (encoded <= 1) {
15002        decoded = 256 + encoded;
15003    } else if (encoded <= 255) {
15004        decoded = encoded;
15005    } else if (encoded <= 509) {
15006        decoded = encoded - 512;
15007    } else {
15008        decoded = encoded - 768;
15009    }
15010
15011    gen_arith_imm(ctx, OPC_ADDIU, 29, 29, decoded << 2);
15012}
15013
15014static void gen_addius5(DisasContext *ctx)
15015{
15016    int imm = SIMM(ctx->opcode, 1, 4);
15017    int rd = (ctx->opcode >> 5) & 0x1f;
15018
15019    gen_arith_imm(ctx, OPC_ADDIU, rd, rd, imm);
15020}
15021
15022static void gen_andi16(DisasContext *ctx)
15023{
15024    static const int decoded_imm[] = { 128, 1, 2, 3, 4, 7, 8, 15, 16,
15025                                 31, 32, 63, 64, 255, 32768, 65535 };
15026    int rd = mmreg(uMIPS_RD(ctx->opcode));
15027    int rs = mmreg(uMIPS_RS(ctx->opcode));
15028    int encoded = ZIMM(ctx->opcode, 0, 4);
15029
15030    gen_logic_imm(ctx, OPC_ANDI, rd, rs, decoded_imm[encoded]);
15031}
15032
15033static void gen_ldst_multiple(DisasContext *ctx, uint32_t opc, int reglist,
15034                              int base, int16_t offset)
15035{
15036    TCGv t0, t1;
15037    TCGv_i32 t2;
15038
15039    if (ctx->hflags & MIPS_HFLAG_BMASK) {
15040        generate_exception_end(ctx, EXCP_RI);
15041        return;
15042    }
15043
15044    t0 = tcg_temp_new();
15045
15046    gen_base_offset_addr(ctx, t0, base, offset);
15047
15048    t1 = tcg_const_tl(reglist);
15049    t2 = tcg_const_i32(ctx->mem_idx);
15050
15051    save_cpu_state(ctx, 1);
15052    switch (opc) {
15053    case LWM32:
15054        gen_helper_lwm(cpu_env, t0, t1, t2);
15055        break;
15056    case SWM32:
15057        gen_helper_swm(cpu_env, t0, t1, t2);
15058        break;
15059#ifdef TARGET_MIPS64
15060    case LDM:
15061        gen_helper_ldm(cpu_env, t0, t1, t2);
15062        break;
15063    case SDM:
15064        gen_helper_sdm(cpu_env, t0, t1, t2);
15065        break;
15066#endif
15067    }
15068    tcg_temp_free(t0);
15069    tcg_temp_free(t1);
15070    tcg_temp_free_i32(t2);
15071}
15072
15073
15074static void gen_pool16c_insn(DisasContext *ctx)
15075{
15076    int rd = mmreg((ctx->opcode >> 3) & 0x7);
15077    int rs = mmreg(ctx->opcode & 0x7);
15078
15079    switch (((ctx->opcode) >> 4) & 0x3f) {
15080    case NOT16 + 0:
15081    case NOT16 + 1:
15082    case NOT16 + 2:
15083    case NOT16 + 3:
15084        gen_logic(ctx, OPC_NOR, rd, rs, 0);
15085        break;
15086    case XOR16 + 0:
15087    case XOR16 + 1:
15088    case XOR16 + 2:
15089    case XOR16 + 3:
15090        gen_logic(ctx, OPC_XOR, rd, rd, rs);
15091        break;
15092    case AND16 + 0:
15093    case AND16 + 1:
15094    case AND16 + 2:
15095    case AND16 + 3:
15096        gen_logic(ctx, OPC_AND, rd, rd, rs);
15097        break;
15098    case OR16 + 0:
15099    case OR16 + 1:
15100    case OR16 + 2:
15101    case OR16 + 3:
15102        gen_logic(ctx, OPC_OR, rd, rd, rs);
15103        break;
15104    case LWM16 + 0:
15105    case LWM16 + 1:
15106    case LWM16 + 2:
15107    case LWM16 + 3:
15108        {
15109            static const int lwm_convert[] = { 0x11, 0x12, 0x13, 0x14 };
15110            int offset = ZIMM(ctx->opcode, 0, 4);
15111
15112            gen_ldst_multiple(ctx, LWM32, lwm_convert[(ctx->opcode >> 4) & 0x3],
15113                              29, offset << 2);
15114        }
15115        break;
15116    case SWM16 + 0:
15117    case SWM16 + 1:
15118    case SWM16 + 2:
15119    case SWM16 + 3:
15120        {
15121            static const int swm_convert[] = { 0x11, 0x12, 0x13, 0x14 };
15122            int offset = ZIMM(ctx->opcode, 0, 4);
15123
15124            gen_ldst_multiple(ctx, SWM32, swm_convert[(ctx->opcode >> 4) & 0x3],
15125                              29, offset << 2);
15126        }
15127        break;
15128    case JR16 + 0:
15129    case JR16 + 1:
15130        {
15131            int reg = ctx->opcode & 0x1f;
15132
15133            gen_compute_branch(ctx, OPC_JR, 2, reg, 0, 0, 4);
15134        }
15135        break;
15136    case JRC16 + 0:
15137    case JRC16 + 1:
15138        {
15139            int reg = ctx->opcode & 0x1f;
15140            gen_compute_branch(ctx, OPC_JR, 2, reg, 0, 0, 0);
15141            /*
15142             * Let normal delay slot handling in our caller take us
15143             * to the branch target.
15144             */
15145        }
15146        break;
15147    case JALR16 + 0:
15148    case JALR16 + 1:
15149        gen_compute_branch(ctx, OPC_JALR, 2, ctx->opcode & 0x1f, 31, 0, 4);
15150        ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
15151        break;
15152    case JALR16S + 0:
15153    case JALR16S + 1:
15154        gen_compute_branch(ctx, OPC_JALR, 2, ctx->opcode & 0x1f, 31, 0, 2);
15155        ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
15156        break;
15157    case MFHI16 + 0:
15158    case MFHI16 + 1:
15159        gen_HILO(ctx, OPC_MFHI, 0, uMIPS_RS5(ctx->opcode));
15160        break;
15161    case MFLO16 + 0:
15162    case MFLO16 + 1:
15163        gen_HILO(ctx, OPC_MFLO, 0, uMIPS_RS5(ctx->opcode));
15164        break;
15165    case BREAK16:
15166        generate_exception_end(ctx, EXCP_BREAK);
15167        break;
15168    case SDBBP16:
15169        if (is_uhi(extract32(ctx->opcode, 0, 4))) {
15170            gen_helper_do_semihosting(cpu_env);
15171        } else {
15172            /*
15173             * XXX: not clear which exception should be raised
15174             *      when in debug mode...
15175             */
15176            check_insn(ctx, ISA_MIPS32);
15177            generate_exception_end(ctx, EXCP_DBp);
15178        }
15179        break;
15180    case JRADDIUSP + 0:
15181    case JRADDIUSP + 1:
15182        {
15183            int imm = ZIMM(ctx->opcode, 0, 5);
15184            gen_compute_branch(ctx, OPC_JR, 2, 31, 0, 0, 0);
15185            gen_arith_imm(ctx, OPC_ADDIU, 29, 29, imm << 2);
15186            /*
15187             * Let normal delay slot handling in our caller take us
15188             * to the branch target.
15189             */
15190        }
15191        break;
15192    default:
15193        generate_exception_end(ctx, EXCP_RI);
15194        break;
15195    }
15196}
15197
15198static inline void gen_movep(DisasContext *ctx, int enc_dest, int enc_rt,
15199                             int enc_rs)
15200{
15201    int rd, rs, re, rt;
15202    static const int rd_enc[] = { 5, 5, 6, 4, 4, 4, 4, 4 };
15203    static const int re_enc[] = { 6, 7, 7, 21, 22, 5, 6, 7 };
15204    static const int rs_rt_enc[] = { 0, 17, 2, 3, 16, 18, 19, 20 };
15205    rd = rd_enc[enc_dest];
15206    re = re_enc[enc_dest];
15207    rs = rs_rt_enc[enc_rs];
15208    rt = rs_rt_enc[enc_rt];
15209    if (rs) {
15210        tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
15211    } else {
15212        tcg_gen_movi_tl(cpu_gpr[rd], 0);
15213    }
15214    if (rt) {
15215        tcg_gen_mov_tl(cpu_gpr[re], cpu_gpr[rt]);
15216    } else {
15217        tcg_gen_movi_tl(cpu_gpr[re], 0);
15218    }
15219}
15220
15221static void gen_pool16c_r6_insn(DisasContext *ctx)
15222{
15223    int rt = mmreg((ctx->opcode >> 7) & 0x7);
15224    int rs = mmreg((ctx->opcode >> 4) & 0x7);
15225
15226    switch (ctx->opcode & 0xf) {
15227    case R6_NOT16:
15228        gen_logic(ctx, OPC_NOR, rt, rs, 0);
15229        break;
15230    case R6_AND16:
15231        gen_logic(ctx, OPC_AND, rt, rt, rs);
15232        break;
15233    case R6_LWM16:
15234        {
15235            int lwm_converted = 0x11 + extract32(ctx->opcode, 8, 2);
15236            int offset = extract32(ctx->opcode, 4, 4);
15237            gen_ldst_multiple(ctx, LWM32, lwm_converted, 29, offset << 2);
15238        }
15239        break;
15240    case R6_JRC16: /* JRCADDIUSP */
15241        if ((ctx->opcode >> 4) & 1) {
15242            /* JRCADDIUSP */
15243            int imm = extract32(ctx->opcode, 5, 5);
15244            gen_compute_branch(ctx, OPC_JR, 2, 31, 0, 0, 0);
15245            gen_arith_imm(ctx, OPC_ADDIU, 29, 29, imm << 2);
15246        } else {
15247            /* JRC16 */
15248            rs = extract32(ctx->opcode, 5, 5);
15249            gen_compute_branch(ctx, OPC_JR, 2, rs, 0, 0, 0);
15250        }
15251        break;
15252    case MOVEP:
15253    case MOVEP_05:
15254    case MOVEP_06:
15255    case MOVEP_07:
15256    case MOVEP_0C:
15257    case MOVEP_0D:
15258    case MOVEP_0E:
15259    case MOVEP_0F:
15260        {
15261            int enc_dest = uMIPS_RD(ctx->opcode);
15262            int enc_rt = uMIPS_RS2(ctx->opcode);
15263            int enc_rs = (ctx->opcode & 3) | ((ctx->opcode >> 1) & 4);
15264            gen_movep(ctx, enc_dest, enc_rt, enc_rs);
15265        }
15266        break;
15267    case R6_XOR16:
15268        gen_logic(ctx, OPC_XOR, rt, rt, rs);
15269        break;
15270    case R6_OR16:
15271        gen_logic(ctx, OPC_OR, rt, rt, rs);
15272        break;
15273    case R6_SWM16:
15274        {
15275            int swm_converted = 0x11 + extract32(ctx->opcode, 8, 2);
15276            int offset = extract32(ctx->opcode, 4, 4);
15277            gen_ldst_multiple(ctx, SWM32, swm_converted, 29, offset << 2);
15278        }
15279        break;
15280    case JALRC16: /* BREAK16, SDBBP16 */
15281        switch (ctx->opcode & 0x3f) {
15282        case JALRC16:
15283        case JALRC16 + 0x20:
15284            /* JALRC16 */
15285            gen_compute_branch(ctx, OPC_JALR, 2, (ctx->opcode >> 5) & 0x1f,
15286                               31, 0, 0);
15287            break;
15288        case R6_BREAK16:
15289            /* BREAK16 */
15290            generate_exception(ctx, EXCP_BREAK);
15291            break;
15292        case R6_SDBBP16:
15293            /* SDBBP16 */
15294            if (is_uhi(extract32(ctx->opcode, 6, 4))) {
15295                gen_helper_do_semihosting(cpu_env);
15296            } else {
15297                if (ctx->hflags & MIPS_HFLAG_SBRI) {
15298                    generate_exception(ctx, EXCP_RI);
15299                } else {
15300                    generate_exception(ctx, EXCP_DBp);
15301                }
15302            }
15303            break;
15304        }
15305        break;
15306    default:
15307        generate_exception(ctx, EXCP_RI);
15308        break;
15309    }
15310}
15311
15312static void gen_ldxs(DisasContext *ctx, int base, int index, int rd)
15313{
15314    TCGv t0 = tcg_temp_new();
15315    TCGv t1 = tcg_temp_new();
15316
15317    gen_load_gpr(t0, base);
15318
15319    if (index != 0) {
15320        gen_load_gpr(t1, index);
15321        tcg_gen_shli_tl(t1, t1, 2);
15322        gen_op_addr_add(ctx, t0, t1, t0);
15323    }
15324
15325    tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TESL);
15326    gen_store_gpr(t1, rd);
15327
15328    tcg_temp_free(t0);
15329    tcg_temp_free(t1);
15330}
15331
15332static void gen_ldst_pair(DisasContext *ctx, uint32_t opc, int rd,
15333                          int base, int16_t offset)
15334{
15335    TCGv t0, t1;
15336
15337    if (ctx->hflags & MIPS_HFLAG_BMASK || rd == 31) {
15338        generate_exception_end(ctx, EXCP_RI);
15339        return;
15340    }
15341
15342    t0 = tcg_temp_new();
15343    t1 = tcg_temp_new();
15344
15345    gen_base_offset_addr(ctx, t0, base, offset);
15346
15347    switch (opc) {
15348    case LWP:
15349        if (rd == base) {
15350            generate_exception_end(ctx, EXCP_RI);
15351            return;
15352        }
15353        tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TESL);
15354        gen_store_gpr(t1, rd);
15355        tcg_gen_movi_tl(t1, 4);
15356        gen_op_addr_add(ctx, t0, t0, t1);
15357        tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TESL);
15358        gen_store_gpr(t1, rd + 1);
15359        break;
15360    case SWP:
15361        gen_load_gpr(t1, rd);
15362        tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL);
15363        tcg_gen_movi_tl(t1, 4);
15364        gen_op_addr_add(ctx, t0, t0, t1);
15365        gen_load_gpr(t1, rd + 1);
15366        tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL);
15367        break;
15368#ifdef TARGET_MIPS64
15369    case LDP:
15370        if (rd == base) {
15371            generate_exception_end(ctx, EXCP_RI);
15372            return;
15373        }
15374        tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TEQ);
15375        gen_store_gpr(t1, rd);
15376        tcg_gen_movi_tl(t1, 8);
15377        gen_op_addr_add(ctx, t0, t0, t1);
15378        tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TEQ);
15379        gen_store_gpr(t1, rd + 1);
15380        break;
15381    case SDP:
15382        gen_load_gpr(t1, rd);
15383        tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEQ);
15384        tcg_gen_movi_tl(t1, 8);
15385        gen_op_addr_add(ctx, t0, t0, t1);
15386        gen_load_gpr(t1, rd + 1);
15387        tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEQ);
15388        break;
15389#endif
15390    }
15391    tcg_temp_free(t0);
15392    tcg_temp_free(t1);
15393}
15394
15395static void gen_sync(int stype)
15396{
15397    TCGBar tcg_mo = TCG_BAR_SC;
15398
15399    switch (stype) {
15400    case 0x4: /* SYNC_WMB */
15401        tcg_mo |= TCG_MO_ST_ST;
15402        break;
15403    case 0x10: /* SYNC_MB */
15404        tcg_mo |= TCG_MO_ALL;
15405        break;
15406    case 0x11: /* SYNC_ACQUIRE */
15407        tcg_mo |= TCG_MO_LD_LD | TCG_MO_LD_ST;
15408        break;
15409    case 0x12: /* SYNC_RELEASE */
15410        tcg_mo |= TCG_MO_ST_ST | TCG_MO_LD_ST;
15411        break;
15412    case 0x13: /* SYNC_RMB */
15413        tcg_mo |= TCG_MO_LD_LD;
15414        break;
15415    default:
15416        tcg_mo |= TCG_MO_ALL;
15417        break;
15418    }
15419
15420    tcg_gen_mb(tcg_mo);
15421}
15422
15423static void gen_pool32axf(CPUMIPSState *env, DisasContext *ctx, int rt, int rs)
15424{
15425    int extension = (ctx->opcode >> 6) & 0x3f;
15426    int minor = (ctx->opcode >> 12) & 0xf;
15427    uint32_t mips32_op;
15428
15429    switch (extension) {
15430    case TEQ:
15431        mips32_op = OPC_TEQ;
15432        goto do_trap;
15433    case TGE:
15434        mips32_op = OPC_TGE;
15435        goto do_trap;
15436    case TGEU:
15437        mips32_op = OPC_TGEU;
15438        goto do_trap;
15439    case TLT:
15440        mips32_op = OPC_TLT;
15441        goto do_trap;
15442    case TLTU:
15443        mips32_op = OPC_TLTU;
15444        goto do_trap;
15445    case TNE:
15446        mips32_op = OPC_TNE;
15447    do_trap:
15448        gen_trap(ctx, mips32_op, rs, rt, -1);
15449        break;
15450#ifndef CONFIG_USER_ONLY
15451    case MFC0:
15452    case MFC0 + 32:
15453        check_cp0_enabled(ctx);
15454        if (rt == 0) {
15455            /* Treat as NOP. */
15456            break;
15457        }
15458        gen_mfc0(ctx, cpu_gpr[rt], rs, (ctx->opcode >> 11) & 0x7);
15459        break;
15460    case MTC0:
15461    case MTC0 + 32:
15462        check_cp0_enabled(ctx);
15463        {
15464            TCGv t0 = tcg_temp_new();
15465
15466            gen_load_gpr(t0, rt);
15467            gen_mtc0(ctx, t0, rs, (ctx->opcode >> 11) & 0x7);
15468            tcg_temp_free(t0);
15469        }
15470        break;
15471#endif
15472    case 0x2a:
15473        switch (minor & 3) {
15474        case MADD_ACC:
15475            gen_muldiv(ctx, OPC_MADD, (ctx->opcode >> 14) & 3, rs, rt);
15476            break;
15477        case MADDU_ACC:
15478            gen_muldiv(ctx, OPC_MADDU, (ctx->opcode >> 14) & 3, rs, rt);
15479            break;
15480        case MSUB_ACC:
15481            gen_muldiv(ctx, OPC_MSUB, (ctx->opcode >> 14) & 3, rs, rt);
15482            break;
15483        case MSUBU_ACC:
15484            gen_muldiv(ctx, OPC_MSUBU, (ctx->opcode >> 14) & 3, rs, rt);
15485            break;
15486        default:
15487            goto pool32axf_invalid;
15488        }
15489        break;
15490    case 0x32:
15491        switch (minor & 3) {
15492        case MULT_ACC:
15493            gen_muldiv(ctx, OPC_MULT, (ctx->opcode >> 14) & 3, rs, rt);
15494            break;
15495        case MULTU_ACC:
15496            gen_muldiv(ctx, OPC_MULTU, (ctx->opcode >> 14) & 3, rs, rt);
15497            break;
15498        default:
15499            goto pool32axf_invalid;
15500        }
15501        break;
15502    case 0x2c:
15503        switch (minor) {
15504        case BITSWAP:
15505            check_insn(ctx, ISA_MIPS32R6);
15506            gen_bitswap(ctx, OPC_BITSWAP, rs, rt);
15507            break;
15508        case SEB:
15509            gen_bshfl(ctx, OPC_SEB, rs, rt);
15510            break;
15511        case SEH:
15512            gen_bshfl(ctx, OPC_SEH, rs, rt);
15513            break;
15514        case CLO:
15515            mips32_op = OPC_CLO;
15516            goto do_cl;
15517        case CLZ:
15518            mips32_op = OPC_CLZ;
15519        do_cl:
15520            check_insn(ctx, ISA_MIPS32);
15521            gen_cl(ctx, mips32_op, rt, rs);
15522            break;
15523        case RDHWR:
15524            check_insn_opc_removed(ctx, ISA_MIPS32R6);
15525            gen_rdhwr(ctx, rt, rs, 0);
15526            break;
15527        case WSBH:
15528            gen_bshfl(ctx, OPC_WSBH, rs, rt);
15529            break;
15530        case MULT:
15531            check_insn_opc_removed(ctx, ISA_MIPS32R6);
15532            mips32_op = OPC_MULT;
15533            goto do_mul;
15534        case MULTU:
15535            check_insn_opc_removed(ctx, ISA_MIPS32R6);
15536            mips32_op = OPC_MULTU;
15537            goto do_mul;
15538        case DIV:
15539            check_insn_opc_removed(ctx, ISA_MIPS32R6);
15540            mips32_op = OPC_DIV;
15541            goto do_div;
15542        case DIVU:
15543            check_insn_opc_removed(ctx, ISA_MIPS32R6);
15544            mips32_op = OPC_DIVU;
15545            goto do_div;
15546        do_div:
15547            check_insn(ctx, ISA_MIPS32);
15548            gen_muldiv(ctx, mips32_op, 0, rs, rt);
15549            break;
15550        case MADD:
15551            check_insn_opc_removed(ctx, ISA_MIPS32R6);
15552            mips32_op = OPC_MADD;
15553            goto do_mul;
15554        case MADDU:
15555            check_insn_opc_removed(ctx, ISA_MIPS32R6);
15556            mips32_op = OPC_MADDU;
15557            goto do_mul;
15558        case MSUB:
15559            check_insn_opc_removed(ctx, ISA_MIPS32R6);
15560            mips32_op = OPC_MSUB;
15561            goto do_mul;
15562        case MSUBU:
15563            check_insn_opc_removed(ctx, ISA_MIPS32R6);
15564            mips32_op = OPC_MSUBU;
15565        do_mul:
15566            check_insn(ctx, ISA_MIPS32);
15567            gen_muldiv(ctx, mips32_op, 0, rs, rt);
15568            break;
15569        default:
15570            goto pool32axf_invalid;
15571        }
15572        break;
15573    case 0x34:
15574        switch (minor) {
15575        case MFC2:
15576        case MTC2:
15577        case MFHC2:
15578        case MTHC2:
15579        case CFC2:
15580        case CTC2:
15581            generate_exception_err(ctx, EXCP_CpU, 2);
15582            break;
15583        default:
15584            goto pool32axf_invalid;
15585        }
15586        break;
15587    case 0x3c:
15588        switch (minor) {
15589        case JALR:    /* JALRC */
15590        case JALR_HB: /* JALRC_HB */
15591            if (ctx->insn_flags & ISA_MIPS32R6) {
15592                /* JALRC, JALRC_HB */
15593                gen_compute_branch(ctx, OPC_JALR, 4, rs, rt, 0, 0);
15594            } else {
15595                /* JALR, JALR_HB */
15596                gen_compute_branch(ctx, OPC_JALR, 4, rs, rt, 0, 4);
15597                ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
15598            }
15599            break;
15600        case JALRS:
15601        case JALRS_HB:
15602            check_insn_opc_removed(ctx, ISA_MIPS32R6);
15603            gen_compute_branch(ctx, OPC_JALR, 4, rs, rt, 0, 2);
15604            ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
15605            break;
15606        default:
15607            goto pool32axf_invalid;
15608        }
15609        break;
15610    case 0x05:
15611        switch (minor) {
15612        case RDPGPR:
15613            check_cp0_enabled(ctx);
15614            check_insn(ctx, ISA_MIPS32R2);
15615            gen_load_srsgpr(rs, rt);
15616            break;
15617        case WRPGPR:
15618            check_cp0_enabled(ctx);
15619            check_insn(ctx, ISA_MIPS32R2);
15620            gen_store_srsgpr(rs, rt);
15621            break;
15622        default:
15623            goto pool32axf_invalid;
15624        }
15625        break;
15626#ifndef CONFIG_USER_ONLY
15627    case 0x0d:
15628        switch (minor) {
15629        case TLBP:
15630            mips32_op = OPC_TLBP;
15631            goto do_cp0;
15632        case TLBR:
15633            mips32_op = OPC_TLBR;
15634            goto do_cp0;
15635        case TLBWI:
15636            mips32_op = OPC_TLBWI;
15637            goto do_cp0;
15638        case TLBWR:
15639            mips32_op = OPC_TLBWR;
15640            goto do_cp0;
15641        case TLBINV:
15642            mips32_op = OPC_TLBINV;
15643            goto do_cp0;
15644        case TLBINVF:
15645            mips32_op = OPC_TLBINVF;
15646            goto do_cp0;
15647        case WAIT:
15648            mips32_op = OPC_WAIT;
15649            goto do_cp0;
15650        case DERET:
15651            mips32_op = OPC_DERET;
15652            goto do_cp0;
15653        case ERET:
15654            mips32_op = OPC_ERET;
15655        do_cp0:
15656            gen_cp0(env, ctx, mips32_op, rt, rs);
15657            break;
15658        default:
15659            goto pool32axf_invalid;
15660        }
15661        break;
15662    case 0x1d:
15663        switch (minor) {
15664        case DI:
15665            check_cp0_enabled(ctx);
15666            {
15667                TCGv t0 = tcg_temp_new();
15668
15669                save_cpu_state(ctx, 1);
15670                gen_helper_di(t0, cpu_env);
15671                gen_store_gpr(t0, rs);
15672                /* Stop translation as we may have switched the execution mode */
15673                ctx->base.is_jmp = DISAS_STOP;
15674                tcg_temp_free(t0);
15675            }
15676            break;
15677        case EI:
15678            check_cp0_enabled(ctx);
15679            {
15680                TCGv t0 = tcg_temp_new();
15681
15682                save_cpu_state(ctx, 1);
15683                gen_helper_ei(t0, cpu_env);
15684                gen_store_gpr(t0, rs);
15685                /*
15686                 * DISAS_STOP isn't sufficient, we need to ensure we break out
15687                 * of translated code to check for pending interrupts.
15688                 */
15689                gen_save_pc(ctx->base.pc_next + 4);
15690                ctx->base.is_jmp = DISAS_EXIT;
15691                tcg_temp_free(t0);
15692            }
15693            break;
15694        default:
15695            goto pool32axf_invalid;
15696        }
15697        break;
15698#endif
15699    case 0x2d:
15700        switch (minor) {
15701        case SYNC:
15702            gen_sync(extract32(ctx->opcode, 16, 5));
15703            break;
15704        case SYSCALL:
15705            generate_exception_end(ctx, EXCP_SYSCALL);
15706            break;
15707        case SDBBP:
15708            if (is_uhi(extract32(ctx->opcode, 16, 10))) {
15709                gen_helper_do_semihosting(cpu_env);
15710            } else {
15711                check_insn(ctx, ISA_MIPS32);
15712                if (ctx->hflags & MIPS_HFLAG_SBRI) {
15713                    generate_exception_end(ctx, EXCP_RI);
15714                } else {
15715                    generate_exception_end(ctx, EXCP_DBp);
15716                }
15717            }
15718            break;
15719        default:
15720            goto pool32axf_invalid;
15721        }
15722        break;
15723    case 0x01:
15724        switch (minor & 3) {
15725        case MFHI_ACC:
15726            gen_HILO(ctx, OPC_MFHI, minor >> 2, rs);
15727            break;
15728        case MFLO_ACC:
15729            gen_HILO(ctx, OPC_MFLO, minor >> 2, rs);
15730            break;
15731        case MTHI_ACC:
15732            gen_HILO(ctx, OPC_MTHI, minor >> 2, rs);
15733            break;
15734        case MTLO_ACC:
15735            gen_HILO(ctx, OPC_MTLO, minor >> 2, rs);
15736            break;
15737        default:
15738            goto pool32axf_invalid;
15739        }
15740        break;
15741    case 0x35:
15742        check_insn_opc_removed(ctx, ISA_MIPS32R6);
15743        switch (minor) {
15744        case MFHI32:
15745            gen_HILO(ctx, OPC_MFHI, 0, rs);
15746            break;
15747        case MFLO32:
15748            gen_HILO(ctx, OPC_MFLO, 0, rs);
15749            break;
15750        case MTHI32:
15751            gen_HILO(ctx, OPC_MTHI, 0, rs);
15752            break;
15753        case MTLO32:
15754            gen_HILO(ctx, OPC_MTLO, 0, rs);
15755            break;
15756        default:
15757            goto pool32axf_invalid;
15758        }
15759        break;
15760    default:
15761    pool32axf_invalid:
15762        MIPS_INVAL("pool32axf");
15763        generate_exception_end(ctx, EXCP_RI);
15764        break;
15765    }
15766}
15767
15768/*
15769 * Values for microMIPS fmt field.  Variable-width, depending on which
15770 * formats the instruction supports.
15771 */
15772enum {
15773    FMT_SD_S = 0,
15774    FMT_SD_D = 1,
15775
15776    FMT_SDPS_S = 0,
15777    FMT_SDPS_D = 1,
15778    FMT_SDPS_PS = 2,
15779
15780    FMT_SWL_S = 0,
15781    FMT_SWL_W = 1,
15782    FMT_SWL_L = 2,
15783
15784    FMT_DWL_D = 0,
15785    FMT_DWL_W = 1,
15786    FMT_DWL_L = 2
15787};
15788
15789static void gen_pool32fxf(DisasContext *ctx, int rt, int rs)
15790{
15791    int extension = (ctx->opcode >> 6) & 0x3ff;
15792    uint32_t mips32_op;
15793
15794#define FLOAT_1BIT_FMT(opc, fmt) (fmt << 8) | opc
15795#define FLOAT_2BIT_FMT(opc, fmt) (fmt << 7) | opc
15796#define COND_FLOAT_MOV(opc, cond) (cond << 7) | opc
15797
15798    switch (extension) {
15799    case FLOAT_1BIT_FMT(CFC1, 0):
15800        mips32_op = OPC_CFC1;
15801        goto do_cp1;
15802    case FLOAT_1BIT_FMT(CTC1, 0):
15803        mips32_op = OPC_CTC1;
15804        goto do_cp1;
15805    case FLOAT_1BIT_FMT(MFC1, 0):
15806        mips32_op = OPC_MFC1;
15807        goto do_cp1;
15808    case FLOAT_1BIT_FMT(MTC1, 0):
15809        mips32_op = OPC_MTC1;
15810        goto do_cp1;
15811    case FLOAT_1BIT_FMT(MFHC1, 0):
15812        mips32_op = OPC_MFHC1;
15813        goto do_cp1;
15814    case FLOAT_1BIT_FMT(MTHC1, 0):
15815        mips32_op = OPC_MTHC1;
15816    do_cp1:
15817        gen_cp1(ctx, mips32_op, rt, rs);
15818        break;
15819
15820        /* Reciprocal square root */
15821    case FLOAT_1BIT_FMT(RSQRT_FMT, FMT_SD_S):
15822        mips32_op = OPC_RSQRT_S;
15823        goto do_unaryfp;
15824    case FLOAT_1BIT_FMT(RSQRT_FMT, FMT_SD_D):
15825        mips32_op = OPC_RSQRT_D;
15826        goto do_unaryfp;
15827
15828        /* Square root */
15829    case FLOAT_1BIT_FMT(SQRT_FMT, FMT_SD_S):
15830        mips32_op = OPC_SQRT_S;
15831        goto do_unaryfp;
15832    case FLOAT_1BIT_FMT(SQRT_FMT, FMT_SD_D):
15833        mips32_op = OPC_SQRT_D;
15834        goto do_unaryfp;
15835
15836        /* Reciprocal */
15837    case FLOAT_1BIT_FMT(RECIP_FMT, FMT_SD_S):
15838        mips32_op = OPC_RECIP_S;
15839        goto do_unaryfp;
15840    case FLOAT_1BIT_FMT(RECIP_FMT, FMT_SD_D):
15841        mips32_op = OPC_RECIP_D;
15842        goto do_unaryfp;
15843
15844        /* Floor */
15845    case FLOAT_1BIT_FMT(FLOOR_L, FMT_SD_S):
15846        mips32_op = OPC_FLOOR_L_S;
15847        goto do_unaryfp;
15848    case FLOAT_1BIT_FMT(FLOOR_L, FMT_SD_D):
15849        mips32_op = OPC_FLOOR_L_D;
15850        goto do_unaryfp;
15851    case FLOAT_1BIT_FMT(FLOOR_W, FMT_SD_S):
15852        mips32_op = OPC_FLOOR_W_S;
15853        goto do_unaryfp;
15854    case FLOAT_1BIT_FMT(FLOOR_W, FMT_SD_D):
15855        mips32_op = OPC_FLOOR_W_D;
15856        goto do_unaryfp;
15857
15858        /* Ceiling */
15859    case FLOAT_1BIT_FMT(CEIL_L, FMT_SD_S):
15860        mips32_op = OPC_CEIL_L_S;
15861        goto do_unaryfp;
15862    case FLOAT_1BIT_FMT(CEIL_L, FMT_SD_D):
15863        mips32_op = OPC_CEIL_L_D;
15864        goto do_unaryfp;
15865    case FLOAT_1BIT_FMT(CEIL_W, FMT_SD_S):
15866        mips32_op = OPC_CEIL_W_S;
15867        goto do_unaryfp;
15868    case FLOAT_1BIT_FMT(CEIL_W, FMT_SD_D):
15869        mips32_op = OPC_CEIL_W_D;
15870        goto do_unaryfp;
15871
15872        /* Truncation */
15873    case FLOAT_1BIT_FMT(TRUNC_L, FMT_SD_S):
15874        mips32_op = OPC_TRUNC_L_S;
15875        goto do_unaryfp;
15876    case FLOAT_1BIT_FMT(TRUNC_L, FMT_SD_D):
15877        mips32_op = OPC_TRUNC_L_D;
15878        goto do_unaryfp;
15879    case FLOAT_1BIT_FMT(TRUNC_W, FMT_SD_S):
15880        mips32_op = OPC_TRUNC_W_S;
15881        goto do_unaryfp;
15882    case FLOAT_1BIT_FMT(TRUNC_W, FMT_SD_D):
15883        mips32_op = OPC_TRUNC_W_D;
15884        goto do_unaryfp;
15885
15886        /* Round */
15887    case FLOAT_1BIT_FMT(ROUND_L, FMT_SD_S):
15888        mips32_op = OPC_ROUND_L_S;
15889        goto do_unaryfp;
15890    case FLOAT_1BIT_FMT(ROUND_L, FMT_SD_D):
15891        mips32_op = OPC_ROUND_L_D;
15892        goto do_unaryfp;
15893    case FLOAT_1BIT_FMT(ROUND_W, FMT_SD_S):
15894        mips32_op = OPC_ROUND_W_S;
15895        goto do_unaryfp;
15896    case FLOAT_1BIT_FMT(ROUND_W, FMT_SD_D):
15897        mips32_op = OPC_ROUND_W_D;
15898        goto do_unaryfp;
15899
15900        /* Integer to floating-point conversion */
15901    case FLOAT_1BIT_FMT(CVT_L, FMT_SD_S):
15902        mips32_op = OPC_CVT_L_S;
15903        goto do_unaryfp;
15904    case FLOAT_1BIT_FMT(CVT_L, FMT_SD_D):
15905        mips32_op = OPC_CVT_L_D;
15906        goto do_unaryfp;
15907    case FLOAT_1BIT_FMT(CVT_W, FMT_SD_S):
15908        mips32_op = OPC_CVT_W_S;
15909        goto do_unaryfp;
15910    case FLOAT_1BIT_FMT(CVT_W, FMT_SD_D):
15911        mips32_op = OPC_CVT_W_D;
15912        goto do_unaryfp;
15913
15914        /* Paired-foo conversions */
15915    case FLOAT_1BIT_FMT(CVT_S_PL, 0):
15916        mips32_op = OPC_CVT_S_PL;
15917        goto do_unaryfp;
15918    case FLOAT_1BIT_FMT(CVT_S_PU, 0):
15919        mips32_op = OPC_CVT_S_PU;
15920        goto do_unaryfp;
15921    case FLOAT_1BIT_FMT(CVT_PW_PS, 0):
15922        mips32_op = OPC_CVT_PW_PS;
15923        goto do_unaryfp;
15924    case FLOAT_1BIT_FMT(CVT_PS_PW, 0):
15925        mips32_op = OPC_CVT_PS_PW;
15926        goto do_unaryfp;
15927
15928        /* Floating-point moves */
15929    case FLOAT_2BIT_FMT(MOV_FMT, FMT_SDPS_S):
15930        mips32_op = OPC_MOV_S;
15931        goto do_unaryfp;
15932    case FLOAT_2BIT_FMT(MOV_FMT, FMT_SDPS_D):
15933        mips32_op = OPC_MOV_D;
15934        goto do_unaryfp;
15935    case FLOAT_2BIT_FMT(MOV_FMT, FMT_SDPS_PS):
15936        mips32_op = OPC_MOV_PS;
15937        goto do_unaryfp;
15938
15939        /* Absolute value */
15940    case FLOAT_2BIT_FMT(ABS_FMT, FMT_SDPS_S):
15941        mips32_op = OPC_ABS_S;
15942        goto do_unaryfp;
15943    case FLOAT_2BIT_FMT(ABS_FMT, FMT_SDPS_D):
15944        mips32_op = OPC_ABS_D;
15945        goto do_unaryfp;
15946    case FLOAT_2BIT_FMT(ABS_FMT, FMT_SDPS_PS):
15947        mips32_op = OPC_ABS_PS;
15948        goto do_unaryfp;
15949
15950        /* Negation */
15951    case FLOAT_2BIT_FMT(NEG_FMT, FMT_SDPS_S):
15952        mips32_op = OPC_NEG_S;
15953        goto do_unaryfp;
15954    case FLOAT_2BIT_FMT(NEG_FMT, FMT_SDPS_D):
15955        mips32_op = OPC_NEG_D;
15956        goto do_unaryfp;
15957    case FLOAT_2BIT_FMT(NEG_FMT, FMT_SDPS_PS):
15958        mips32_op = OPC_NEG_PS;
15959        goto do_unaryfp;
15960
15961        /* Reciprocal square root step */
15962    case FLOAT_2BIT_FMT(RSQRT1_FMT, FMT_SDPS_S):
15963        mips32_op = OPC_RSQRT1_S;
15964        goto do_unaryfp;
15965    case FLOAT_2BIT_FMT(RSQRT1_FMT, FMT_SDPS_D):
15966        mips32_op = OPC_RSQRT1_D;
15967        goto do_unaryfp;
15968    case FLOAT_2BIT_FMT(RSQRT1_FMT, FMT_SDPS_PS):
15969        mips32_op = OPC_RSQRT1_PS;
15970        goto do_unaryfp;
15971
15972        /* Reciprocal step */
15973    case FLOAT_2BIT_FMT(RECIP1_FMT, FMT_SDPS_S):
15974        mips32_op = OPC_RECIP1_S;
15975        goto do_unaryfp;
15976    case FLOAT_2BIT_FMT(RECIP1_FMT, FMT_SDPS_D):
15977        mips32_op = OPC_RECIP1_S;
15978        goto do_unaryfp;
15979    case FLOAT_2BIT_FMT(RECIP1_FMT, FMT_SDPS_PS):
15980        mips32_op = OPC_RECIP1_PS;
15981        goto do_unaryfp;
15982
15983        /* Conversions from double */
15984    case FLOAT_2BIT_FMT(CVT_D, FMT_SWL_S):
15985        mips32_op = OPC_CVT_D_S;
15986        goto do_unaryfp;
15987    case FLOAT_2BIT_FMT(CVT_D, FMT_SWL_W):
15988        mips32_op = OPC_CVT_D_W;
15989        goto do_unaryfp;
15990    case FLOAT_2BIT_FMT(CVT_D, FMT_SWL_L):
15991        mips32_op = OPC_CVT_D_L;
15992        goto do_unaryfp;
15993
15994        /* Conversions from single */
15995    case FLOAT_2BIT_FMT(CVT_S, FMT_DWL_D):
15996        mips32_op = OPC_CVT_S_D;
15997        goto do_unaryfp;
15998    case FLOAT_2BIT_FMT(CVT_S, FMT_DWL_W):
15999        mips32_op = OPC_CVT_S_W;
16000        goto do_unaryfp;
16001    case FLOAT_2BIT_FMT(CVT_S, FMT_DWL_L):
16002        mips32_op = OPC_CVT_S_L;
16003    do_unaryfp:
16004        gen_farith(ctx, mips32_op, -1, rs, rt, 0);
16005        break;
16006
16007        /* Conditional moves on floating-point codes */
16008    case COND_FLOAT_MOV(MOVT, 0):
16009    case COND_FLOAT_MOV(MOVT, 1):
16010    case COND_FLOAT_MOV(MOVT, 2):
16011    case COND_FLOAT_MOV(MOVT, 3):
16012    case COND_FLOAT_MOV(MOVT, 4):
16013    case COND_FLOAT_MOV(MOVT, 5):
16014    case COND_FLOAT_MOV(MOVT, 6):
16015    case COND_FLOAT_MOV(MOVT, 7):
16016        check_insn_opc_removed(ctx, ISA_MIPS32R6);
16017        gen_movci(ctx, rt, rs, (ctx->opcode >> 13) & 0x7, 1);
16018        break;
16019    case COND_FLOAT_MOV(MOVF, 0):
16020    case COND_FLOAT_MOV(MOVF, 1):
16021    case COND_FLOAT_MOV(MOVF, 2):
16022    case COND_FLOAT_MOV(MOVF, 3):
16023    case COND_FLOAT_MOV(MOVF, 4):
16024    case COND_FLOAT_MOV(MOVF, 5):
16025    case COND_FLOAT_MOV(MOVF, 6):
16026    case COND_FLOAT_MOV(MOVF, 7):
16027        check_insn_opc_removed(ctx, ISA_MIPS32R6);
16028        gen_movci(ctx, rt, rs, (ctx->opcode >> 13) & 0x7, 0);
16029        break;
16030    default:
16031        MIPS_INVAL("pool32fxf");
16032        generate_exception_end(ctx, EXCP_RI);
16033        break;
16034    }
16035}
16036
16037static void decode_micromips32_opc(CPUMIPSState *env, DisasContext *ctx)
16038{
16039    int32_t offset;
16040    uint16_t insn;
16041    int rt, rs, rd, rr;
16042    int16_t imm;
16043    uint32_t op, minor, minor2, mips32_op;
16044    uint32_t cond, fmt, cc;
16045
16046    insn = cpu_lduw_code(env, ctx->base.pc_next + 2);
16047    ctx->opcode = (ctx->opcode << 16) | insn;
16048
16049    rt = (ctx->opcode >> 21) & 0x1f;
16050    rs = (ctx->opcode >> 16) & 0x1f;
16051    rd = (ctx->opcode >> 11) & 0x1f;
16052    rr = (ctx->opcode >> 6) & 0x1f;
16053    imm = (int16_t) ctx->opcode;
16054
16055    op = (ctx->opcode >> 26) & 0x3f;
16056    switch (op) {
16057    case POOL32A:
16058        minor = ctx->opcode & 0x3f;
16059        switch (minor) {
16060        case 0x00:
16061            minor = (ctx->opcode >> 6) & 0xf;
16062            switch (minor) {
16063            case SLL32:
16064                mips32_op = OPC_SLL;
16065                goto do_shifti;
16066            case SRA:
16067                mips32_op = OPC_SRA;
16068                goto do_shifti;
16069            case SRL32:
16070                mips32_op = OPC_SRL;
16071                goto do_shifti;
16072            case ROTR:
16073                mips32_op = OPC_ROTR;
16074            do_shifti:
16075                gen_shift_imm(ctx, mips32_op, rt, rs, rd);
16076                break;
16077            case SELEQZ:
16078                check_insn(ctx, ISA_MIPS32R6);
16079                gen_cond_move(ctx, OPC_SELEQZ, rd, rs, rt);
16080                break;
16081            case SELNEZ:
16082                check_insn(ctx, ISA_MIPS32R6);
16083                gen_cond_move(ctx, OPC_SELNEZ, rd, rs, rt);
16084                break;
16085            case R6_RDHWR:
16086                check_insn(ctx, ISA_MIPS32R6);
16087                gen_rdhwr(ctx, rt, rs, extract32(ctx->opcode, 11, 3));
16088                break;
16089            default:
16090                goto pool32a_invalid;
16091            }
16092            break;
16093        case 0x10:
16094            minor = (ctx->opcode >> 6) & 0xf;
16095            switch (minor) {
16096                /* Arithmetic */
16097            case ADD:
16098                mips32_op = OPC_ADD;
16099                goto do_arith;
16100            case ADDU32:
16101                mips32_op = OPC_ADDU;
16102                goto do_arith;
16103            case SUB:
16104                mips32_op = OPC_SUB;
16105                goto do_arith;
16106            case SUBU32:
16107                mips32_op = OPC_SUBU;
16108                goto do_arith;
16109            case MUL:
16110                check_insn_opc_removed(ctx, ISA_MIPS32R6);
16111                mips32_op = OPC_MUL;
16112            do_arith:
16113                gen_arith(ctx, mips32_op, rd, rs, rt);
16114                break;
16115                /* Shifts */
16116            case SLLV:
16117                mips32_op = OPC_SLLV;
16118                goto do_shift;
16119            case SRLV:
16120                mips32_op = OPC_SRLV;
16121                goto do_shift;
16122            case SRAV:
16123                mips32_op = OPC_SRAV;
16124                goto do_shift;
16125            case ROTRV:
16126                mips32_op = OPC_ROTRV;
16127            do_shift:
16128                gen_shift(ctx, mips32_op, rd, rs, rt);
16129                break;
16130                /* Logical operations */
16131            case AND:
16132                mips32_op = OPC_AND;
16133                goto do_logic;
16134            case OR32:
16135                mips32_op = OPC_OR;
16136                goto do_logic;
16137            case NOR:
16138                mips32_op = OPC_NOR;
16139                goto do_logic;
16140            case XOR32:
16141                mips32_op = OPC_XOR;
16142            do_logic:
16143                gen_logic(ctx, mips32_op, rd, rs, rt);
16144                break;
16145                /* Set less than */
16146            case SLT:
16147                mips32_op = OPC_SLT;
16148                goto do_slt;
16149            case SLTU:
16150                mips32_op = OPC_SLTU;
16151            do_slt:
16152                gen_slt(ctx, mips32_op, rd, rs, rt);
16153                break;
16154            default:
16155                goto pool32a_invalid;
16156            }
16157            break;
16158        case 0x18:
16159            minor = (ctx->opcode >> 6) & 0xf;
16160            switch (minor) {
16161                /* Conditional moves */
16162            case MOVN: /* MUL */
16163                if (ctx->insn_flags & ISA_MIPS32R6) {
16164                    /* MUL */
16165                    gen_r6_muldiv(ctx, R6_OPC_MUL, rd, rs, rt);
16166                } else {
16167                    /* MOVN */
16168                    gen_cond_move(ctx, OPC_MOVN, rd, rs, rt);
16169                }
16170                break;
16171            case MOVZ: /* MUH */
16172                if (ctx->insn_flags & ISA_MIPS32R6) {
16173                    /* MUH */
16174                    gen_r6_muldiv(ctx, R6_OPC_MUH, rd, rs, rt);
16175                } else {
16176                    /* MOVZ */
16177                    gen_cond_move(ctx, OPC_MOVZ, rd, rs, rt);
16178                }
16179                break;
16180            case MULU:
16181                check_insn(ctx, ISA_MIPS32R6);
16182                gen_r6_muldiv(ctx, R6_OPC_MULU, rd, rs, rt);
16183                break;
16184            case MUHU:
16185                check_insn(ctx, ISA_MIPS32R6);
16186                gen_r6_muldiv(ctx, R6_OPC_MUHU, rd, rs, rt);
16187                break;
16188            case LWXS: /* DIV */
16189                if (ctx->insn_flags & ISA_MIPS32R6) {
16190                    /* DIV */
16191                    gen_r6_muldiv(ctx, R6_OPC_DIV, rd, rs, rt);
16192                } else {
16193                    /* LWXS */
16194                    gen_ldxs(ctx, rs, rt, rd);
16195                }
16196                break;
16197            case MOD:
16198                check_insn(ctx, ISA_MIPS32R6);
16199                gen_r6_muldiv(ctx, R6_OPC_MOD, rd, rs, rt);
16200                break;
16201            case R6_DIVU:
16202                check_insn(ctx, ISA_MIPS32R6);
16203                gen_r6_muldiv(ctx, R6_OPC_DIVU, rd, rs, rt);
16204                break;
16205            case MODU:
16206                check_insn(ctx, ISA_MIPS32R6);
16207                gen_r6_muldiv(ctx, R6_OPC_MODU, rd, rs, rt);
16208                break;
16209            default:
16210                goto pool32a_invalid;
16211            }
16212            break;
16213        case INS:
16214            gen_bitops(ctx, OPC_INS, rt, rs, rr, rd);
16215            return;
16216        case LSA:
16217            check_insn(ctx, ISA_MIPS32R6);
16218            gen_lsa(ctx, OPC_LSA, rd, rs, rt,
16219                    extract32(ctx->opcode, 9, 2));
16220            break;
16221        case ALIGN:
16222            check_insn(ctx, ISA_MIPS32R6);
16223            gen_align(ctx, 32, rd, rs, rt, extract32(ctx->opcode, 9, 2));
16224            break;
16225        case EXT:
16226            gen_bitops(ctx, OPC_EXT, rt, rs, rr, rd);
16227            return;
16228        case POOL32AXF:
16229            gen_pool32axf(env, ctx, rt, rs);
16230            break;
16231        case BREAK32:
16232            generate_exception_end(ctx, EXCP_BREAK);
16233            break;
16234        case SIGRIE:
16235            check_insn(ctx, ISA_MIPS32R6);
16236            generate_exception_end(ctx, EXCP_RI);
16237            break;
16238        default:
16239        pool32a_invalid:
16240                MIPS_INVAL("pool32a");
16241                generate_exception_end(ctx, EXCP_RI);
16242                break;
16243        }
16244        break;
16245    case POOL32B:
16246        minor = (ctx->opcode >> 12) & 0xf;
16247        switch (minor) {
16248        case CACHE:
16249            check_cp0_enabled(ctx);
16250            if (ctx->hflags & MIPS_HFLAG_ITC_CACHE) {
16251                gen_cache_operation(ctx, rt, rs, imm);
16252            }
16253            break;
16254        case LWC2:
16255        case SWC2:
16256            /* COP2: Not implemented. */
16257            generate_exception_err(ctx, EXCP_CpU, 2);
16258            break;
16259#ifdef TARGET_MIPS64
16260        case LDP:
16261        case SDP:
16262            check_insn(ctx, ISA_MIPS3);
16263            check_mips_64(ctx);
16264#endif
16265            /* fall through */
16266        case LWP:
16267        case SWP:
16268            gen_ldst_pair(ctx, minor, rt, rs, SIMM(ctx->opcode, 0, 12));
16269            break;
16270#ifdef TARGET_MIPS64
16271        case LDM:
16272        case SDM:
16273            check_insn(ctx, ISA_MIPS3);
16274            check_mips_64(ctx);
16275#endif
16276            /* fall through */
16277        case LWM32:
16278        case SWM32:
16279            gen_ldst_multiple(ctx, minor, rt, rs, SIMM(ctx->opcode, 0, 12));
16280            break;
16281        default:
16282            MIPS_INVAL("pool32b");
16283            generate_exception_end(ctx, EXCP_RI);
16284            break;
16285        }
16286        break;
16287    case POOL32F:
16288        if (ctx->CP0_Config1 & (1 << CP0C1_FP)) {
16289            minor = ctx->opcode & 0x3f;
16290            check_cp1_enabled(ctx);
16291            switch (minor) {
16292            case ALNV_PS:
16293                check_insn_opc_removed(ctx, ISA_MIPS32R6);
16294                mips32_op = OPC_ALNV_PS;
16295                goto do_madd;
16296            case MADD_S:
16297                check_insn_opc_removed(ctx, ISA_MIPS32R6);
16298                mips32_op = OPC_MADD_S;
16299                goto do_madd;
16300            case MADD_D:
16301                check_insn_opc_removed(ctx, ISA_MIPS32R6);
16302                mips32_op = OPC_MADD_D;
16303                goto do_madd;
16304            case MADD_PS:
16305                check_insn_opc_removed(ctx, ISA_MIPS32R6);
16306                mips32_op = OPC_MADD_PS;
16307                goto do_madd;
16308            case MSUB_S:
16309                check_insn_opc_removed(ctx, ISA_MIPS32R6);
16310                mips32_op = OPC_MSUB_S;
16311                goto do_madd;
16312            case MSUB_D:
16313                check_insn_opc_removed(ctx, ISA_MIPS32R6);
16314                mips32_op = OPC_MSUB_D;
16315                goto do_madd;
16316            case MSUB_PS:
16317                check_insn_opc_removed(ctx, ISA_MIPS32R6);
16318                mips32_op = OPC_MSUB_PS;
16319                goto do_madd;
16320            case NMADD_S:
16321                check_insn_opc_removed(ctx, ISA_MIPS32R6);
16322                mips32_op = OPC_NMADD_S;
16323                goto do_madd;
16324            case NMADD_D:
16325                check_insn_opc_removed(ctx, ISA_MIPS32R6);
16326                mips32_op = OPC_NMADD_D;
16327                goto do_madd;
16328            case NMADD_PS:
16329                check_insn_opc_removed(ctx, ISA_MIPS32R6);
16330                mips32_op = OPC_NMADD_PS;
16331                goto do_madd;
16332            case NMSUB_S:
16333                check_insn_opc_removed(ctx, ISA_MIPS32R6);
16334                mips32_op = OPC_NMSUB_S;
16335                goto do_madd;
16336            case NMSUB_D:
16337                check_insn_opc_removed(ctx, ISA_MIPS32R6);
16338                mips32_op = OPC_NMSUB_D;
16339                goto do_madd;
16340            case NMSUB_PS:
16341                check_insn_opc_removed(ctx, ISA_MIPS32R6);
16342                mips32_op = OPC_NMSUB_PS;
16343            do_madd:
16344                gen_flt3_arith(ctx, mips32_op, rd, rr, rs, rt);
16345                break;
16346            case CABS_COND_FMT:
16347                check_insn_opc_removed(ctx, ISA_MIPS32R6);
16348                cond = (ctx->opcode >> 6) & 0xf;
16349                cc = (ctx->opcode >> 13) & 0x7;
16350                fmt = (ctx->opcode >> 10) & 0x3;
16351                switch (fmt) {
16352                case 0x0:
16353                    gen_cmpabs_s(ctx, cond, rt, rs, cc);
16354                    break;
16355                case 0x1:
16356                    gen_cmpabs_d(ctx, cond, rt, rs, cc);
16357                    break;
16358                case 0x2:
16359                    gen_cmpabs_ps(ctx, cond, rt, rs, cc);
16360                    break;
16361                default:
16362                    goto pool32f_invalid;
16363                }
16364                break;
16365            case C_COND_FMT:
16366                check_insn_opc_removed(ctx, ISA_MIPS32R6);
16367                cond = (ctx->opcode >> 6) & 0xf;
16368                cc = (ctx->opcode >> 13) & 0x7;
16369                fmt = (ctx->opcode >> 10) & 0x3;
16370                switch (fmt) {
16371                case 0x0:
16372                    gen_cmp_s(ctx, cond, rt, rs, cc);
16373                    break;
16374                case 0x1:
16375                    gen_cmp_d(ctx, cond, rt, rs, cc);
16376                    break;
16377                case 0x2:
16378                    gen_cmp_ps(ctx, cond, rt, rs, cc);
16379                    break;
16380                default:
16381                    goto pool32f_invalid;
16382                }
16383                break;
16384            case CMP_CONDN_S:
16385                check_insn(ctx, ISA_MIPS32R6);
16386                gen_r6_cmp_s(ctx, (ctx->opcode >> 6) & 0x1f, rt, rs, rd);
16387                break;
16388            case CMP_CONDN_D:
16389                check_insn(ctx, ISA_MIPS32R6);
16390                gen_r6_cmp_d(ctx, (ctx->opcode >> 6) & 0x1f, rt, rs, rd);
16391                break;
16392            case POOL32FXF:
16393                gen_pool32fxf(ctx, rt, rs);
16394                break;
16395            case 0x00:
16396                /* PLL foo */
16397                switch ((ctx->opcode >> 6) & 0x7) {
16398                case PLL_PS:
16399                    mips32_op = OPC_PLL_PS;
16400                    goto do_ps;
16401                case PLU_PS:
16402                    mips32_op = OPC_PLU_PS;
16403                    goto do_ps;
16404                case PUL_PS:
16405                    mips32_op = OPC_PUL_PS;
16406                    goto do_ps;
16407                case PUU_PS:
16408                    mips32_op = OPC_PUU_PS;
16409                    goto do_ps;
16410                case CVT_PS_S:
16411                    check_insn_opc_removed(ctx, ISA_MIPS32R6);
16412                    mips32_op = OPC_CVT_PS_S;
16413                do_ps:
16414                    gen_farith(ctx, mips32_op, rt, rs, rd, 0);
16415                    break;
16416                default:
16417                    goto pool32f_invalid;
16418                }
16419                break;
16420            case MIN_FMT:
16421                check_insn(ctx, ISA_MIPS32R6);
16422                switch ((ctx->opcode >> 9) & 0x3) {
16423                case FMT_SDPS_S:
16424                    gen_farith(ctx, OPC_MIN_S, rt, rs, rd, 0);
16425                    break;
16426                case FMT_SDPS_D:
16427                    gen_farith(ctx, OPC_MIN_D, rt, rs, rd, 0);
16428                    break;
16429                default:
16430                    goto pool32f_invalid;
16431                }
16432                break;
16433            case 0x08:
16434                /* [LS][WDU]XC1 */
16435                switch ((ctx->opcode >> 6) & 0x7) {
16436                case LWXC1:
16437                    check_insn_opc_removed(ctx, ISA_MIPS32R6);
16438                    mips32_op = OPC_LWXC1;
16439                    goto do_ldst_cp1;
16440                case SWXC1:
16441                    check_insn_opc_removed(ctx, ISA_MIPS32R6);
16442                    mips32_op = OPC_SWXC1;
16443                    goto do_ldst_cp1;
16444                case LDXC1:
16445                    check_insn_opc_removed(ctx, ISA_MIPS32R6);
16446                    mips32_op = OPC_LDXC1;
16447                    goto do_ldst_cp1;
16448                case SDXC1:
16449                    check_insn_opc_removed(ctx, ISA_MIPS32R6);
16450                    mips32_op = OPC_SDXC1;
16451                    goto do_ldst_cp1;
16452                case LUXC1:
16453                    check_insn_opc_removed(ctx, ISA_MIPS32R6);
16454                    mips32_op = OPC_LUXC1;
16455                    goto do_ldst_cp1;
16456                case SUXC1:
16457                    check_insn_opc_removed(ctx, ISA_MIPS32R6);
16458                    mips32_op = OPC_SUXC1;
16459                do_ldst_cp1:
16460                    gen_flt3_ldst(ctx, mips32_op, rd, rd, rt, rs);
16461                    break;
16462                default:
16463                    goto pool32f_invalid;
16464                }
16465                break;
16466            case MAX_FMT:
16467                check_insn(ctx, ISA_MIPS32R6);
16468                switch ((ctx->opcode >> 9) & 0x3) {
16469                case FMT_SDPS_S:
16470                    gen_farith(ctx, OPC_MAX_S, rt, rs, rd, 0);
16471                    break;
16472                case FMT_SDPS_D:
16473                    gen_farith(ctx, OPC_MAX_D, rt, rs, rd, 0);
16474                    break;
16475                default:
16476                    goto pool32f_invalid;
16477                }
16478                break;
16479            case 0x18:
16480                /* 3D insns */
16481                check_insn_opc_removed(ctx, ISA_MIPS32R6);
16482                fmt = (ctx->opcode >> 9) & 0x3;
16483                switch ((ctx->opcode >> 6) & 0x7) {
16484                case RSQRT2_FMT:
16485                    switch (fmt) {
16486                    case FMT_SDPS_S:
16487                        mips32_op = OPC_RSQRT2_S;
16488                        goto do_3d;
16489                    case FMT_SDPS_D:
16490                        mips32_op = OPC_RSQRT2_D;
16491                        goto do_3d;
16492                    case FMT_SDPS_PS:
16493                        mips32_op = OPC_RSQRT2_PS;
16494                        goto do_3d;
16495                    default:
16496                        goto pool32f_invalid;
16497                    }
16498                    break;
16499                case RECIP2_FMT:
16500                    switch (fmt) {
16501                    case FMT_SDPS_S:
16502                        mips32_op = OPC_RECIP2_S;
16503                        goto do_3d;
16504                    case FMT_SDPS_D:
16505                        mips32_op = OPC_RECIP2_D;
16506                        goto do_3d;
16507                    case FMT_SDPS_PS:
16508                        mips32_op = OPC_RECIP2_PS;
16509                        goto do_3d;
16510                    default:
16511                        goto pool32f_invalid;
16512                    }
16513                    break;
16514                case ADDR_PS:
16515                    mips32_op = OPC_ADDR_PS;
16516                    goto do_3d;
16517                case MULR_PS:
16518                    mips32_op = OPC_MULR_PS;
16519                do_3d:
16520                    gen_farith(ctx, mips32_op, rt, rs, rd, 0);
16521                    break;
16522                default:
16523                    goto pool32f_invalid;
16524                }
16525                break;
16526            case 0x20:
16527                /* MOV[FT].fmt, PREFX, RINT.fmt, CLASS.fmt*/
16528                cc = (ctx->opcode >> 13) & 0x7;
16529                fmt = (ctx->opcode >> 9) & 0x3;
16530                switch ((ctx->opcode >> 6) & 0x7) {
16531                case MOVF_FMT: /* RINT_FMT */
16532                    if (ctx->insn_flags & ISA_MIPS32R6) {
16533                        /* RINT_FMT */
16534                        switch (fmt) {
16535                        case FMT_SDPS_S:
16536                            gen_farith(ctx, OPC_RINT_S, 0, rt, rs, 0);
16537                            break;
16538                        case FMT_SDPS_D:
16539                            gen_farith(ctx, OPC_RINT_D, 0, rt, rs, 0);
16540                            break;
16541                        default:
16542                            goto pool32f_invalid;
16543                        }
16544                    } else {
16545                        /* MOVF_FMT */
16546                        switch (fmt) {
16547                        case FMT_SDPS_S:
16548                            gen_movcf_s(ctx, rs, rt, cc, 0);
16549                            break;
16550                        case FMT_SDPS_D:
16551                            gen_movcf_d(ctx, rs, rt, cc, 0);
16552                            break;
16553                        case FMT_SDPS_PS:
16554                            check_ps(ctx);
16555                            gen_movcf_ps(ctx, rs, rt, cc, 0);
16556                            break;
16557                        default:
16558                            goto pool32f_invalid;
16559                        }
16560                    }
16561                    break;
16562                case MOVT_FMT: /* CLASS_FMT */
16563                    if (ctx->insn_flags & ISA_MIPS32R6) {
16564                        /* CLASS_FMT */
16565                        switch (fmt) {
16566                        case FMT_SDPS_S:
16567                            gen_farith(ctx, OPC_CLASS_S, 0, rt, rs, 0);
16568                            break;
16569                        case FMT_SDPS_D:
16570                            gen_farith(ctx, OPC_CLASS_D, 0, rt, rs, 0);
16571                            break;
16572                        default:
16573                            goto pool32f_invalid;
16574                        }
16575                    } else {
16576                        /* MOVT_FMT */
16577                        switch (fmt) {
16578                        case FMT_SDPS_S:
16579                            gen_movcf_s(ctx, rs, rt, cc, 1);
16580                            break;
16581                        case FMT_SDPS_D:
16582                            gen_movcf_d(ctx, rs, rt, cc, 1);
16583                            break;
16584                        case FMT_SDPS_PS:
16585                            check_ps(ctx);
16586                            gen_movcf_ps(ctx, rs, rt, cc, 1);
16587                            break;
16588                        default:
16589                            goto pool32f_invalid;
16590                        }
16591                    }
16592                    break;
16593                case PREFX:
16594                    check_insn_opc_removed(ctx, ISA_MIPS32R6);
16595                    break;
16596                default:
16597                    goto pool32f_invalid;
16598                }
16599                break;
16600#define FINSN_3ARG_SDPS(prfx)                           \
16601                switch ((ctx->opcode >> 8) & 0x3) {     \
16602                case FMT_SDPS_S:                        \
16603                    mips32_op = OPC_##prfx##_S;         \
16604                    goto do_fpop;                       \
16605                case FMT_SDPS_D:                        \
16606                    mips32_op = OPC_##prfx##_D;         \
16607                    goto do_fpop;                       \
16608                case FMT_SDPS_PS:                       \
16609                    check_ps(ctx);                      \
16610                    mips32_op = OPC_##prfx##_PS;        \
16611                    goto do_fpop;                       \
16612                default:                                \
16613                    goto pool32f_invalid;               \
16614                }
16615            case MINA_FMT:
16616                check_insn(ctx, ISA_MIPS32R6);
16617                switch ((ctx->opcode >> 9) & 0x3) {
16618                case FMT_SDPS_S:
16619                    gen_farith(ctx, OPC_MINA_S, rt, rs, rd, 0);
16620                    break;
16621                case FMT_SDPS_D:
16622                    gen_farith(ctx, OPC_MINA_D, rt, rs, rd, 0);
16623                    break;
16624                default:
16625                    goto pool32f_invalid;
16626                }
16627                break;
16628            case MAXA_FMT:
16629                check_insn(ctx, ISA_MIPS32R6);
16630                switch ((ctx->opcode >> 9) & 0x3) {
16631                case FMT_SDPS_S:
16632                    gen_farith(ctx, OPC_MAXA_S, rt, rs, rd, 0);
16633                    break;
16634                case FMT_SDPS_D:
16635                    gen_farith(ctx, OPC_MAXA_D, rt, rs, rd, 0);
16636                    break;
16637                default:
16638                    goto pool32f_invalid;
16639                }
16640                break;
16641            case 0x30:
16642                /* regular FP ops */
16643                switch ((ctx->opcode >> 6) & 0x3) {
16644                case ADD_FMT:
16645                    FINSN_3ARG_SDPS(ADD);
16646                    break;
16647                case SUB_FMT:
16648                    FINSN_3ARG_SDPS(SUB);
16649                    break;
16650                case MUL_FMT:
16651                    FINSN_3ARG_SDPS(MUL);
16652                    break;
16653                case DIV_FMT:
16654                    fmt = (ctx->opcode >> 8) & 0x3;
16655                    if (fmt == 1) {
16656                        mips32_op = OPC_DIV_D;
16657                    } else if (fmt == 0) {
16658                        mips32_op = OPC_DIV_S;
16659                    } else {
16660                        goto pool32f_invalid;
16661                    }
16662                    goto do_fpop;
16663                default:
16664                    goto pool32f_invalid;
16665                }
16666                break;
16667            case 0x38:
16668                /* cmovs */
16669                switch ((ctx->opcode >> 6) & 0x7) {
16670                case MOVN_FMT: /* SELEQZ_FMT */
16671                    if (ctx->insn_flags & ISA_MIPS32R6) {
16672                        /* SELEQZ_FMT */
16673                        switch ((ctx->opcode >> 9) & 0x3) {
16674                        case FMT_SDPS_S:
16675                            gen_sel_s(ctx, OPC_SELEQZ_S, rd, rt, rs);
16676                            break;
16677                        case FMT_SDPS_D:
16678                            gen_sel_d(ctx, OPC_SELEQZ_D, rd, rt, rs);
16679                            break;
16680                        default:
16681                            goto pool32f_invalid;
16682                        }
16683                    } else {
16684                        /* MOVN_FMT */
16685                        FINSN_3ARG_SDPS(MOVN);
16686                    }
16687                    break;
16688                case MOVN_FMT_04:
16689                    check_insn_opc_removed(ctx, ISA_MIPS32R6);
16690                    FINSN_3ARG_SDPS(MOVN);
16691                    break;
16692                case MOVZ_FMT: /* SELNEZ_FMT */
16693                    if (ctx->insn_flags & ISA_MIPS32R6) {
16694                        /* SELNEZ_FMT */
16695                        switch ((ctx->opcode >> 9) & 0x3) {
16696                        case FMT_SDPS_S:
16697                            gen_sel_s(ctx, OPC_SELNEZ_S, rd, rt, rs);
16698                            break;
16699                        case FMT_SDPS_D:
16700                            gen_sel_d(ctx, OPC_SELNEZ_D, rd, rt, rs);
16701                            break;
16702                        default:
16703                            goto pool32f_invalid;
16704                        }
16705                    } else {
16706                        /* MOVZ_FMT */
16707                        FINSN_3ARG_SDPS(MOVZ);
16708                    }
16709                    break;
16710                case MOVZ_FMT_05:
16711                    check_insn_opc_removed(ctx, ISA_MIPS32R6);
16712                    FINSN_3ARG_SDPS(MOVZ);
16713                    break;
16714                case SEL_FMT:
16715                    check_insn(ctx, ISA_MIPS32R6);
16716                    switch ((ctx->opcode >> 9) & 0x3) {
16717                    case FMT_SDPS_S:
16718                        gen_sel_s(ctx, OPC_SEL_S, rd, rt, rs);
16719                        break;
16720                    case FMT_SDPS_D:
16721                        gen_sel_d(ctx, OPC_SEL_D, rd, rt, rs);
16722                        break;
16723                    default:
16724                        goto pool32f_invalid;
16725                    }
16726                    break;
16727                case MADDF_FMT:
16728                    check_insn(ctx, ISA_MIPS32R6);
16729                    switch ((ctx->opcode >> 9) & 0x3) {
16730                    case FMT_SDPS_S:
16731                        mips32_op = OPC_MADDF_S;
16732                        goto do_fpop;
16733                    case FMT_SDPS_D:
16734                        mips32_op = OPC_MADDF_D;
16735                        goto do_fpop;
16736                    default:
16737                        goto pool32f_invalid;
16738                    }
16739                    break;
16740                case MSUBF_FMT:
16741                    check_insn(ctx, ISA_MIPS32R6);
16742                    switch ((ctx->opcode >> 9) & 0x3) {
16743                    case FMT_SDPS_S:
16744                        mips32_op = OPC_MSUBF_S;
16745                        goto do_fpop;
16746                    case FMT_SDPS_D:
16747                        mips32_op = OPC_MSUBF_D;
16748                        goto do_fpop;
16749                    default:
16750                        goto pool32f_invalid;
16751                    }
16752                    break;
16753                default:
16754                    goto pool32f_invalid;
16755                }
16756                break;
16757            do_fpop:
16758                gen_farith(ctx, mips32_op, rt, rs, rd, 0);
16759                break;
16760            default:
16761            pool32f_invalid:
16762                MIPS_INVAL("pool32f");
16763                generate_exception_end(ctx, EXCP_RI);
16764                break;
16765            }
16766        } else {
16767            generate_exception_err(ctx, EXCP_CpU, 1);
16768        }
16769        break;
16770    case POOL32I:
16771        minor = (ctx->opcode >> 21) & 0x1f;
16772        switch (minor) {
16773        case BLTZ:
16774            check_insn_opc_removed(ctx, ISA_MIPS32R6);
16775            gen_compute_branch(ctx, OPC_BLTZ, 4, rs, -1, imm << 1, 4);
16776            break;
16777        case BLTZAL:
16778            check_insn_opc_removed(ctx, ISA_MIPS32R6);
16779            gen_compute_branch(ctx, OPC_BLTZAL, 4, rs, -1, imm << 1, 4);
16780            ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
16781            break;
16782        case BLTZALS:
16783            check_insn_opc_removed(ctx, ISA_MIPS32R6);
16784            gen_compute_branch(ctx, OPC_BLTZAL, 4, rs, -1, imm << 1, 2);
16785            ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
16786            break;
16787        case BGEZ:
16788            check_insn_opc_removed(ctx, ISA_MIPS32R6);
16789            gen_compute_branch(ctx, OPC_BGEZ, 4, rs, -1, imm << 1, 4);
16790            break;
16791        case BGEZAL:
16792            check_insn_opc_removed(ctx, ISA_MIPS32R6);
16793            gen_compute_branch(ctx, OPC_BGEZAL, 4, rs, -1, imm << 1, 4);
16794            ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
16795            break;
16796        case BGEZALS:
16797            check_insn_opc_removed(ctx, ISA_MIPS32R6);
16798            gen_compute_branch(ctx, OPC_BGEZAL, 4, rs, -1, imm << 1, 2);
16799            ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
16800            break;
16801        case BLEZ:
16802            check_insn_opc_removed(ctx, ISA_MIPS32R6);
16803            gen_compute_branch(ctx, OPC_BLEZ, 4, rs, -1, imm << 1, 4);
16804            break;
16805        case BGTZ:
16806            check_insn_opc_removed(ctx, ISA_MIPS32R6);
16807            gen_compute_branch(ctx, OPC_BGTZ, 4, rs, -1, imm << 1, 4);
16808            break;
16809
16810            /* Traps */
16811        case TLTI: /* BC1EQZC */
16812            if (ctx->insn_flags & ISA_MIPS32R6) {
16813                /* BC1EQZC */
16814                check_cp1_enabled(ctx);
16815                gen_compute_branch1_r6(ctx, OPC_BC1EQZ, rs, imm << 1, 0);
16816            } else {
16817                /* TLTI */
16818                mips32_op = OPC_TLTI;
16819                goto do_trapi;
16820            }
16821            break;
16822        case TGEI: /* BC1NEZC */
16823            if (ctx->insn_flags & ISA_MIPS32R6) {
16824                /* BC1NEZC */
16825                check_cp1_enabled(ctx);
16826                gen_compute_branch1_r6(ctx, OPC_BC1NEZ, rs, imm << 1, 0);
16827            } else {
16828                /* TGEI */
16829                mips32_op = OPC_TGEI;
16830                goto do_trapi;
16831            }
16832            break;
16833        case TLTIU:
16834            check_insn_opc_removed(ctx, ISA_MIPS32R6);
16835            mips32_op = OPC_TLTIU;
16836            goto do_trapi;
16837        case TGEIU:
16838            check_insn_opc_removed(ctx, ISA_MIPS32R6);
16839            mips32_op = OPC_TGEIU;
16840            goto do_trapi;
16841        case TNEI: /* SYNCI */
16842            if (ctx->insn_flags & ISA_MIPS32R6) {
16843                /* SYNCI */
16844                /*
16845                 * Break the TB to be able to sync copied instructions
16846                 * immediately.
16847                 */
16848                ctx->base.is_jmp = DISAS_STOP;
16849            } else {
16850                /* TNEI */
16851                mips32_op = OPC_TNEI;
16852                goto do_trapi;
16853            }
16854            break;
16855        case TEQI:
16856            check_insn_opc_removed(ctx, ISA_MIPS32R6);
16857            mips32_op = OPC_TEQI;
16858        do_trapi:
16859            gen_trap(ctx, mips32_op, rs, -1, imm);
16860            break;
16861
16862        case BNEZC:
16863        case BEQZC:
16864            check_insn_opc_removed(ctx, ISA_MIPS32R6);
16865            gen_compute_branch(ctx, minor == BNEZC ? OPC_BNE : OPC_BEQ,
16866                               4, rs, 0, imm << 1, 0);
16867            /*
16868             * Compact branches don't have a delay slot, so just let
16869             * the normal delay slot handling take us to the branch
16870             * target.
16871             */
16872            break;
16873        case LUI:
16874            check_insn_opc_removed(ctx, ISA_MIPS32R6);
16875            gen_logic_imm(ctx, OPC_LUI, rs, 0, imm);
16876            break;
16877        case SYNCI:
16878            check_insn_opc_removed(ctx, ISA_MIPS32R6);
16879            /*
16880             * Break the TB to be able to sync copied instructions
16881             * immediately.
16882             */
16883            ctx->base.is_jmp = DISAS_STOP;
16884            break;
16885        case BC2F:
16886        case BC2T:
16887            check_insn_opc_removed(ctx, ISA_MIPS32R6);
16888            /* COP2: Not implemented. */
16889            generate_exception_err(ctx, EXCP_CpU, 2);
16890            break;
16891        case BC1F:
16892            check_insn_opc_removed(ctx, ISA_MIPS32R6);
16893            mips32_op = (ctx->opcode & (1 << 16)) ? OPC_BC1FANY2 : OPC_BC1F;
16894            goto do_cp1branch;
16895        case BC1T:
16896            check_insn_opc_removed(ctx, ISA_MIPS32R6);
16897            mips32_op = (ctx->opcode & (1 << 16)) ? OPC_BC1TANY2 : OPC_BC1T;
16898            goto do_cp1branch;
16899        case BC1ANY4F:
16900            check_insn_opc_removed(ctx, ISA_MIPS32R6);
16901            mips32_op = OPC_BC1FANY4;
16902            goto do_cp1mips3d;
16903        case BC1ANY4T:
16904            check_insn_opc_removed(ctx, ISA_MIPS32R6);
16905            mips32_op = OPC_BC1TANY4;
16906        do_cp1mips3d:
16907            check_cop1x(ctx);
16908            check_insn(ctx, ASE_MIPS3D);
16909            /* Fall through */
16910        do_cp1branch:
16911            if (env->CP0_Config1 & (1 << CP0C1_FP)) {
16912                check_cp1_enabled(ctx);
16913                gen_compute_branch1(ctx, mips32_op,
16914                                    (ctx->opcode >> 18) & 0x7, imm << 1);
16915            } else {
16916                generate_exception_err(ctx, EXCP_CpU, 1);
16917            }
16918            break;
16919        case BPOSGE64:
16920        case BPOSGE32:
16921            /* MIPS DSP: not implemented */
16922            /* Fall through */
16923        default:
16924            MIPS_INVAL("pool32i");
16925            generate_exception_end(ctx, EXCP_RI);
16926            break;
16927        }
16928        break;
16929    case POOL32C:
16930        minor = (ctx->opcode >> 12) & 0xf;
16931        offset = sextract32(ctx->opcode, 0,
16932                            (ctx->insn_flags & ISA_MIPS32R6) ? 9 : 12);
16933        switch (minor) {
16934        case LWL:
16935            check_insn_opc_removed(ctx, ISA_MIPS32R6);
16936            mips32_op = OPC_LWL;
16937            goto do_ld_lr;
16938        case SWL:
16939            check_insn_opc_removed(ctx, ISA_MIPS32R6);
16940            mips32_op = OPC_SWL;
16941            goto do_st_lr;
16942        case LWR:
16943            check_insn_opc_removed(ctx, ISA_MIPS32R6);
16944            mips32_op = OPC_LWR;
16945            goto do_ld_lr;
16946        case SWR:
16947            check_insn_opc_removed(ctx, ISA_MIPS32R6);
16948            mips32_op = OPC_SWR;
16949            goto do_st_lr;
16950#if defined(TARGET_MIPS64)
16951        case LDL:
16952            check_insn(ctx, ISA_MIPS3);
16953            check_mips_64(ctx);
16954            check_insn_opc_removed(ctx, ISA_MIPS32R6);
16955            mips32_op = OPC_LDL;
16956            goto do_ld_lr;
16957        case SDL:
16958            check_insn(ctx, ISA_MIPS3);
16959            check_mips_64(ctx);
16960            check_insn_opc_removed(ctx, ISA_MIPS32R6);
16961            mips32_op = OPC_SDL;
16962            goto do_st_lr;
16963        case LDR:
16964            check_insn(ctx, ISA_MIPS3);
16965            check_mips_64(ctx);
16966            check_insn_opc_removed(ctx, ISA_MIPS32R6);
16967            mips32_op = OPC_LDR;
16968            goto do_ld_lr;
16969        case SDR:
16970            check_insn(ctx, ISA_MIPS3);
16971            check_mips_64(ctx);
16972            check_insn_opc_removed(ctx, ISA_MIPS32R6);
16973            mips32_op = OPC_SDR;
16974            goto do_st_lr;
16975        case LWU:
16976            check_insn(ctx, ISA_MIPS3);
16977            check_mips_64(ctx);
16978            mips32_op = OPC_LWU;
16979            goto do_ld_lr;
16980        case LLD:
16981            check_insn(ctx, ISA_MIPS3);
16982            check_mips_64(ctx);
16983            mips32_op = OPC_LLD;
16984            goto do_ld_lr;
16985#endif
16986        case LL:
16987            mips32_op = OPC_LL;
16988            goto do_ld_lr;
16989        do_ld_lr:
16990            gen_ld(ctx, mips32_op, rt, rs, offset);
16991            break;
16992        do_st_lr:
16993            gen_st(ctx, mips32_op, rt, rs, offset);
16994            break;
16995        case SC:
16996            gen_st_cond(ctx, rt, rs, offset, MO_TESL, false);
16997            break;
16998#if defined(TARGET_MIPS64)
16999        case SCD:
17000            check_insn(ctx, ISA_MIPS3);
17001            check_mips_64(ctx);
17002            gen_st_cond(ctx, rt, rs, offset, MO_TEQ, false);
17003            break;
17004#endif
17005        case LD_EVA:
17006            if (!ctx->eva) {
17007                MIPS_INVAL("pool32c ld-eva");
17008                generate_exception_end(ctx, EXCP_RI);
17009                break;
17010            }
17011            check_cp0_enabled(ctx);
17012
17013            minor2 = (ctx->opcode >> 9) & 0x7;
17014            offset = sextract32(ctx->opcode, 0, 9);
17015            switch (minor2) {
17016            case LBUE:
17017                mips32_op = OPC_LBUE;
17018                goto do_ld_lr;
17019            case LHUE:
17020                mips32_op = OPC_LHUE;
17021                goto do_ld_lr;
17022            case LWLE:
17023                check_insn_opc_removed(ctx, ISA_MIPS32R6);
17024                mips32_op = OPC_LWLE;
17025                goto do_ld_lr;
17026            case LWRE:
17027                check_insn_opc_removed(ctx, ISA_MIPS32R6);
17028                mips32_op = OPC_LWRE;
17029                goto do_ld_lr;
17030            case LBE:
17031                mips32_op = OPC_LBE;
17032                goto do_ld_lr;
17033            case LHE:
17034                mips32_op = OPC_LHE;
17035                goto do_ld_lr;
17036            case LLE:
17037                mips32_op = OPC_LLE;
17038                goto do_ld_lr;
17039            case LWE:
17040                mips32_op = OPC_LWE;
17041                goto do_ld_lr;
17042            };
17043            break;
17044        case ST_EVA:
17045            if (!ctx->eva) {
17046                MIPS_INVAL("pool32c st-eva");
17047                generate_exception_end(ctx, EXCP_RI);
17048                break;
17049            }
17050            check_cp0_enabled(ctx);
17051
17052            minor2 = (ctx->opcode >> 9) & 0x7;
17053            offset = sextract32(ctx->opcode, 0, 9);
17054            switch (minor2) {
17055            case SWLE:
17056                check_insn_opc_removed(ctx, ISA_MIPS32R6);
17057                mips32_op = OPC_SWLE;
17058                goto do_st_lr;
17059            case SWRE:
17060                check_insn_opc_removed(ctx, ISA_MIPS32R6);
17061                mips32_op = OPC_SWRE;
17062                goto do_st_lr;
17063            case PREFE:
17064                /* Treat as no-op */
17065                if ((ctx->insn_flags & ISA_MIPS32R6) && (rt >= 24)) {
17066                    /* hint codes 24-31 are reserved and signal RI */
17067                    generate_exception(ctx, EXCP_RI);
17068                }
17069                break;
17070            case CACHEE:
17071                /* Treat as no-op */
17072                if (ctx->hflags & MIPS_HFLAG_ITC_CACHE) {
17073                    gen_cache_operation(ctx, rt, rs, offset);
17074                }
17075                break;
17076            case SBE:
17077                mips32_op = OPC_SBE;
17078                goto do_st_lr;
17079            case SHE:
17080                mips32_op = OPC_SHE;
17081                goto do_st_lr;
17082            case SCE:
17083                gen_st_cond(ctx, rt, rs, offset, MO_TESL, true);
17084                break;
17085            case SWE:
17086                mips32_op = OPC_SWE;
17087                goto do_st_lr;
17088            };
17089            break;
17090        case PREF:
17091            /* Treat as no-op */
17092            if ((ctx->insn_flags & ISA_MIPS32R6) && (rt >= 24)) {
17093                /* hint codes 24-31 are reserved and signal RI */
17094                generate_exception(ctx, EXCP_RI);
17095            }
17096            break;
17097        default:
17098            MIPS_INVAL("pool32c");
17099            generate_exception_end(ctx, EXCP_RI);
17100            break;
17101        }
17102        break;
17103    case ADDI32: /* AUI, LUI */
17104        if (ctx->insn_flags & ISA_MIPS32R6) {
17105            /* AUI, LUI */
17106            gen_logic_imm(ctx, OPC_LUI, rt, rs, imm);
17107        } else {
17108            /* ADDI32 */
17109            mips32_op = OPC_ADDI;
17110            goto do_addi;
17111        }
17112        break;
17113    case ADDIU32:
17114        mips32_op = OPC_ADDIU;
17115    do_addi:
17116        gen_arith_imm(ctx, mips32_op, rt, rs, imm);
17117        break;
17118
17119        /* Logical operations */
17120    case ORI32:
17121        mips32_op = OPC_ORI;
17122        goto do_logici;
17123    case XORI32:
17124        mips32_op = OPC_XORI;
17125        goto do_logici;
17126    case ANDI32:
17127        mips32_op = OPC_ANDI;
17128    do_logici:
17129        gen_logic_imm(ctx, mips32_op, rt, rs, imm);
17130        break;
17131
17132        /* Set less than immediate */
17133    case SLTI32:
17134        mips32_op = OPC_SLTI;
17135        goto do_slti;
17136    case SLTIU32:
17137        mips32_op = OPC_SLTIU;
17138    do_slti:
17139        gen_slt_imm(ctx, mips32_op, rt, rs, imm);
17140        break;
17141    case JALX32:
17142        check_insn_opc_removed(ctx, ISA_MIPS32R6);
17143        offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 2;
17144        gen_compute_branch(ctx, OPC_JALX, 4, rt, rs, offset, 4);
17145        ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
17146        break;
17147    case JALS32: /* BOVC, BEQC, BEQZALC */
17148        if (ctx->insn_flags & ISA_MIPS32R6) {
17149            if (rs >= rt) {
17150                /* BOVC */
17151                mips32_op = OPC_BOVC;
17152            } else if (rs < rt && rs == 0) {
17153                /* BEQZALC */
17154                mips32_op = OPC_BEQZALC;
17155            } else {
17156                /* BEQC */
17157                mips32_op = OPC_BEQC;
17158            }
17159            gen_compute_compact_branch(ctx, mips32_op, rs, rt, imm << 1);
17160        } else {
17161            /* JALS32 */
17162            offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 1;
17163            gen_compute_branch(ctx, OPC_JAL, 4, rt, rs, offset, 2);
17164            ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
17165        }
17166        break;
17167    case BEQ32: /* BC */
17168        if (ctx->insn_flags & ISA_MIPS32R6) {
17169            /* BC */
17170            gen_compute_compact_branch(ctx, OPC_BC, 0, 0,
17171                                       sextract32(ctx->opcode << 1, 0, 27));
17172        } else {
17173            /* BEQ32 */
17174            gen_compute_branch(ctx, OPC_BEQ, 4, rt, rs, imm << 1, 4);
17175        }
17176        break;
17177    case BNE32: /* BALC */
17178        if (ctx->insn_flags & ISA_MIPS32R6) {
17179            /* BALC */
17180            gen_compute_compact_branch(ctx, OPC_BALC, 0, 0,
17181                                       sextract32(ctx->opcode << 1, 0, 27));
17182        } else {
17183            /* BNE32 */
17184            gen_compute_branch(ctx, OPC_BNE, 4, rt, rs, imm << 1, 4);
17185        }
17186        break;
17187    case J32: /* BGTZC, BLTZC, BLTC */
17188        if (ctx->insn_flags & ISA_MIPS32R6) {
17189            if (rs == 0 && rt != 0) {
17190                /* BGTZC */
17191                mips32_op = OPC_BGTZC;
17192            } else if (rs != 0 && rt != 0 && rs == rt) {
17193                /* BLTZC */
17194                mips32_op = OPC_BLTZC;
17195            } else {
17196                /* BLTC */
17197                mips32_op = OPC_BLTC;
17198            }
17199            gen_compute_compact_branch(ctx, mips32_op, rs, rt, imm << 1);
17200        } else {
17201            /* J32 */
17202            gen_compute_branch(ctx, OPC_J, 4, rt, rs,
17203                               (int32_t)(ctx->opcode & 0x3FFFFFF) << 1, 4);
17204        }
17205        break;
17206    case JAL32: /* BLEZC, BGEZC, BGEC */
17207        if (ctx->insn_flags & ISA_MIPS32R6) {
17208            if (rs == 0 && rt != 0) {
17209                /* BLEZC */
17210                mips32_op = OPC_BLEZC;
17211            } else if (rs != 0 && rt != 0 && rs == rt) {
17212                /* BGEZC */
17213                mips32_op = OPC_BGEZC;
17214            } else {
17215                /* BGEC */
17216                mips32_op = OPC_BGEC;
17217            }
17218            gen_compute_compact_branch(ctx, mips32_op, rs, rt, imm << 1);
17219        } else {
17220            /* JAL32 */
17221            gen_compute_branch(ctx, OPC_JAL, 4, rt, rs,
17222                               (int32_t)(ctx->opcode & 0x3FFFFFF) << 1, 4);
17223            ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
17224        }
17225        break;
17226        /* Floating point (COP1) */
17227    case LWC132:
17228        mips32_op = OPC_LWC1;
17229        goto do_cop1;
17230    case LDC132:
17231        mips32_op = OPC_LDC1;
17232        goto do_cop1;
17233    case SWC132:
17234        mips32_op = OPC_SWC1;
17235        goto do_cop1;
17236    case SDC132:
17237        mips32_op = OPC_SDC1;
17238    do_cop1:
17239        gen_cop1_ldst(ctx, mips32_op, rt, rs, imm);
17240        break;
17241    case ADDIUPC: /* PCREL: ADDIUPC, AUIPC, ALUIPC, LWPC */
17242        if (ctx->insn_flags & ISA_MIPS32R6) {
17243            /* PCREL: ADDIUPC, AUIPC, ALUIPC, LWPC */
17244            switch ((ctx->opcode >> 16) & 0x1f) {
17245            case ADDIUPC_00:
17246            case ADDIUPC_01:
17247            case ADDIUPC_02:
17248            case ADDIUPC_03:
17249            case ADDIUPC_04:
17250            case ADDIUPC_05:
17251            case ADDIUPC_06:
17252            case ADDIUPC_07:
17253                gen_pcrel(ctx, OPC_ADDIUPC, ctx->base.pc_next & ~0x3, rt);
17254                break;
17255            case AUIPC:
17256                gen_pcrel(ctx, OPC_AUIPC, ctx->base.pc_next, rt);
17257                break;
17258            case ALUIPC:
17259                gen_pcrel(ctx, OPC_ALUIPC, ctx->base.pc_next, rt);
17260                break;
17261            case LWPC_08:
17262            case LWPC_09:
17263            case LWPC_0A:
17264            case LWPC_0B:
17265            case LWPC_0C:
17266            case LWPC_0D:
17267            case LWPC_0E:
17268            case LWPC_0F:
17269                gen_pcrel(ctx, R6_OPC_LWPC, ctx->base.pc_next & ~0x3, rt);
17270                break;
17271            default:
17272                generate_exception(ctx, EXCP_RI);
17273                break;
17274            }
17275        } else {
17276            /* ADDIUPC */
17277            int reg = mmreg(ZIMM(ctx->opcode, 23, 3));
17278            offset = SIMM(ctx->opcode, 0, 23) << 2;
17279
17280            gen_addiupc(ctx, reg, offset, 0, 0);
17281        }
17282        break;
17283    case BNVC: /* BNEC, BNEZALC */
17284        check_insn(ctx, ISA_MIPS32R6);
17285        if (rs >= rt) {
17286            /* BNVC */
17287            mips32_op = OPC_BNVC;
17288        } else if (rs < rt && rs == 0) {
17289            /* BNEZALC */
17290            mips32_op = OPC_BNEZALC;
17291        } else {
17292            /* BNEC */
17293            mips32_op = OPC_BNEC;
17294        }
17295        gen_compute_compact_branch(ctx, mips32_op, rs, rt, imm << 1);
17296        break;
17297    case R6_BNEZC: /* JIALC */
17298        check_insn(ctx, ISA_MIPS32R6);
17299        if (rt != 0) {
17300            /* BNEZC */
17301            gen_compute_compact_branch(ctx, OPC_BNEZC, rt, 0,
17302                                       sextract32(ctx->opcode << 1, 0, 22));
17303        } else {
17304            /* JIALC */
17305            gen_compute_compact_branch(ctx, OPC_JIALC, 0, rs, imm);
17306        }
17307        break;
17308    case R6_BEQZC: /* JIC */
17309        check_insn(ctx, ISA_MIPS32R6);
17310        if (rt != 0) {
17311            /* BEQZC */
17312            gen_compute_compact_branch(ctx, OPC_BEQZC, rt, 0,
17313                                       sextract32(ctx->opcode << 1, 0, 22));
17314        } else {
17315            /* JIC */
17316            gen_compute_compact_branch(ctx, OPC_JIC, 0, rs, imm);
17317        }
17318        break;
17319    case BLEZALC: /* BGEZALC, BGEUC */
17320        check_insn(ctx, ISA_MIPS32R6);
17321        if (rs == 0 && rt != 0) {
17322            /* BLEZALC */
17323            mips32_op = OPC_BLEZALC;
17324        } else if (rs != 0 && rt != 0 && rs == rt) {
17325            /* BGEZALC */
17326            mips32_op = OPC_BGEZALC;
17327        } else {
17328            /* BGEUC */
17329            mips32_op = OPC_BGEUC;
17330        }
17331        gen_compute_compact_branch(ctx, mips32_op, rs, rt, imm << 1);
17332        break;
17333    case BGTZALC: /* BLTZALC, BLTUC */
17334        check_insn(ctx, ISA_MIPS32R6);
17335        if (rs == 0 && rt != 0) {
17336            /* BGTZALC */
17337            mips32_op = OPC_BGTZALC;
17338        } else if (rs != 0 && rt != 0 && rs == rt) {
17339            /* BLTZALC */
17340            mips32_op = OPC_BLTZALC;
17341        } else {
17342            /* BLTUC */
17343            mips32_op = OPC_BLTUC;
17344        }
17345        gen_compute_compact_branch(ctx, mips32_op, rs, rt, imm << 1);
17346        break;
17347        /* Loads and stores */
17348    case LB32:
17349        mips32_op = OPC_LB;
17350        goto do_ld;
17351    case LBU32:
17352        mips32_op = OPC_LBU;
17353        goto do_ld;
17354    case LH32:
17355        mips32_op = OPC_LH;
17356        goto do_ld;
17357    case LHU32:
17358        mips32_op = OPC_LHU;
17359        goto do_ld;
17360    case LW32:
17361        mips32_op = OPC_LW;
17362        goto do_ld;
17363#ifdef TARGET_MIPS64
17364    case LD32:
17365        check_insn(ctx, ISA_MIPS3);
17366        check_mips_64(ctx);
17367        mips32_op = OPC_LD;
17368        goto do_ld;
17369    case SD32:
17370        check_insn(ctx, ISA_MIPS3);
17371        check_mips_64(ctx);
17372        mips32_op = OPC_SD;
17373        goto do_st;
17374#endif
17375    case SB32:
17376        mips32_op = OPC_SB;
17377        goto do_st;
17378    case SH32:
17379        mips32_op = OPC_SH;
17380        goto do_st;
17381    case SW32:
17382        mips32_op = OPC_SW;
17383        goto do_st;
17384    do_ld:
17385        gen_ld(ctx, mips32_op, rt, rs, imm);
17386        break;
17387    do_st:
17388        gen_st(ctx, mips32_op, rt, rs, imm);
17389        break;
17390    default:
17391        generate_exception_end(ctx, EXCP_RI);
17392        break;
17393    }
17394}
17395
17396static int decode_micromips_opc(CPUMIPSState *env, DisasContext *ctx)
17397{
17398    uint32_t op;
17399
17400    /* make sure instructions are on a halfword boundary */
17401    if (ctx->base.pc_next & 0x1) {
17402        env->CP0_BadVAddr = ctx->base.pc_next;
17403        generate_exception_end(ctx, EXCP_AdEL);
17404        return 2;
17405    }
17406
17407    op = (ctx->opcode >> 10) & 0x3f;
17408    /* Enforce properly-sized instructions in a delay slot */
17409    if (ctx->hflags & MIPS_HFLAG_BDS_STRICT) {
17410        switch (op & 0x7) { /* MSB-3..MSB-5 */
17411        case 0:
17412        /* POOL32A, POOL32B, POOL32I, POOL32C */
17413        case 4:
17414        /* ADDI32, ADDIU32, ORI32, XORI32, SLTI32, SLTIU32, ANDI32, JALX32 */
17415        case 5:
17416        /* LBU32, LHU32, POOL32F, JALS32, BEQ32, BNE32, J32, JAL32 */
17417        case 6:
17418        /* SB32, SH32, ADDIUPC, SWC132, SDC132, SW32 */
17419        case 7:
17420        /* LB32, LH32, LWC132, LDC132, LW32 */
17421            if (ctx->hflags & MIPS_HFLAG_BDS16) {
17422                generate_exception_end(ctx, EXCP_RI);
17423                return 2;
17424            }
17425            break;
17426        case 1:
17427        /* POOL16A, POOL16B, POOL16C, LWGP16, POOL16F */
17428        case 2:
17429        /* LBU16, LHU16, LWSP16, LW16, SB16, SH16, SWSP16, SW16 */
17430        case 3:
17431        /* MOVE16, ANDI16, POOL16D, POOL16E, BEQZ16, BNEZ16, B16, LI16 */
17432            if (ctx->hflags & MIPS_HFLAG_BDS32) {
17433                generate_exception_end(ctx, EXCP_RI);
17434                return 2;
17435            }
17436            break;
17437        }
17438    }
17439
17440    switch (op) {
17441    case POOL16A:
17442        {
17443            int rd = mmreg(uMIPS_RD(ctx->opcode));
17444            int rs1 = mmreg(uMIPS_RS1(ctx->opcode));
17445            int rs2 = mmreg(uMIPS_RS2(ctx->opcode));
17446            uint32_t opc = 0;
17447
17448            switch (ctx->opcode & 0x1) {
17449            case ADDU16:
17450                opc = OPC_ADDU;
17451                break;
17452            case SUBU16:
17453                opc = OPC_SUBU;
17454                break;
17455            }
17456            if (ctx->insn_flags & ISA_MIPS32R6) {
17457                /*
17458                 * In the Release 6, the register number location in
17459                 * the instruction encoding has changed.
17460                 */
17461                gen_arith(ctx, opc, rs1, rd, rs2);
17462            } else {
17463                gen_arith(ctx, opc, rd, rs1, rs2);
17464            }
17465        }
17466        break;
17467    case POOL16B:
17468        {
17469            int rd = mmreg(uMIPS_RD(ctx->opcode));
17470            int rs = mmreg(uMIPS_RS(ctx->opcode));
17471            int amount = (ctx->opcode >> 1) & 0x7;
17472            uint32_t opc = 0;
17473            amount = amount == 0 ? 8 : amount;
17474
17475            switch (ctx->opcode & 0x1) {
17476            case SLL16:
17477                opc = OPC_SLL;
17478                break;
17479            case SRL16:
17480                opc = OPC_SRL;
17481                break;
17482            }
17483
17484            gen_shift_imm(ctx, opc, rd, rs, amount);
17485        }
17486        break;
17487    case POOL16C:
17488        if (ctx->insn_flags & ISA_MIPS32R6) {
17489            gen_pool16c_r6_insn(ctx);
17490        } else {
17491            gen_pool16c_insn(ctx);
17492        }
17493        break;
17494    case LWGP16:
17495        {
17496            int rd = mmreg(uMIPS_RD(ctx->opcode));
17497            int rb = 28;            /* GP */
17498            int16_t offset = SIMM(ctx->opcode, 0, 7) << 2;
17499
17500            gen_ld(ctx, OPC_LW, rd, rb, offset);
17501        }
17502        break;
17503    case POOL16F:
17504        check_insn_opc_removed(ctx, ISA_MIPS32R6);
17505        if (ctx->opcode & 1) {
17506            generate_exception_end(ctx, EXCP_RI);
17507        } else {
17508            /* MOVEP */
17509            int enc_dest = uMIPS_RD(ctx->opcode);
17510            int enc_rt = uMIPS_RS2(ctx->opcode);
17511            int enc_rs = uMIPS_RS1(ctx->opcode);
17512            gen_movep(ctx, enc_dest, enc_rt, enc_rs);
17513        }
17514        break;
17515    case LBU16:
17516        {
17517            int rd = mmreg(uMIPS_RD(ctx->opcode));
17518            int rb = mmreg(uMIPS_RS(ctx->opcode));
17519            int16_t offset = ZIMM(ctx->opcode, 0, 4);
17520            offset = (offset == 0xf ? -1 : offset);
17521
17522            gen_ld(ctx, OPC_LBU, rd, rb, offset);
17523        }
17524        break;
17525    case LHU16:
17526        {
17527            int rd = mmreg(uMIPS_RD(ctx->opcode));
17528            int rb = mmreg(uMIPS_RS(ctx->opcode));
17529            int16_t offset = ZIMM(ctx->opcode, 0, 4) << 1;
17530
17531            gen_ld(ctx, OPC_LHU, rd, rb, offset);
17532        }
17533        break;
17534    case LWSP16:
17535        {
17536            int rd = (ctx->opcode >> 5) & 0x1f;
17537            int rb = 29;            /* SP */
17538            int16_t offset = ZIMM(ctx->opcode, 0, 5) << 2;
17539
17540            gen_ld(ctx, OPC_LW, rd, rb, offset);
17541        }
17542        break;
17543    case LW16:
17544        {
17545            int rd = mmreg(uMIPS_RD(ctx->opcode));
17546            int rb = mmreg(uMIPS_RS(ctx->opcode));
17547            int16_t offset = ZIMM(ctx->opcode, 0, 4) << 2;
17548
17549            gen_ld(ctx, OPC_LW, rd, rb, offset);
17550        }
17551        break;
17552    case SB16:
17553        {
17554            int rd = mmreg2(uMIPS_RD(ctx->opcode));
17555            int rb = mmreg(uMIPS_RS(ctx->opcode));
17556            int16_t offset = ZIMM(ctx->opcode, 0, 4);
17557
17558            gen_st(ctx, OPC_SB, rd, rb, offset);
17559        }
17560        break;
17561    case SH16:
17562        {
17563            int rd = mmreg2(uMIPS_RD(ctx->opcode));
17564            int rb = mmreg(uMIPS_RS(ctx->opcode));
17565            int16_t offset = ZIMM(ctx->opcode, 0, 4) << 1;
17566
17567            gen_st(ctx, OPC_SH, rd, rb, offset);
17568        }
17569        break;
17570    case SWSP16:
17571        {
17572            int rd = (ctx->opcode >> 5) & 0x1f;
17573            int rb = 29;            /* SP */
17574            int16_t offset = ZIMM(ctx->opcode, 0, 5) << 2;
17575
17576            gen_st(ctx, OPC_SW, rd, rb, offset);
17577        }
17578        break;
17579    case SW16:
17580        {
17581            int rd = mmreg2(uMIPS_RD(ctx->opcode));
17582            int rb = mmreg(uMIPS_RS(ctx->opcode));
17583            int16_t offset = ZIMM(ctx->opcode, 0, 4) << 2;
17584
17585            gen_st(ctx, OPC_SW, rd, rb, offset);
17586        }
17587        break;
17588    case MOVE16:
17589        {
17590            int rd = uMIPS_RD5(ctx->opcode);
17591            int rs = uMIPS_RS5(ctx->opcode);
17592
17593            gen_arith(ctx, OPC_ADDU, rd, rs, 0);
17594        }
17595        break;
17596    case ANDI16:
17597        gen_andi16(ctx);
17598        break;
17599    case POOL16D:
17600        switch (ctx->opcode & 0x1) {
17601        case ADDIUS5:
17602            gen_addius5(ctx);
17603            break;
17604        case ADDIUSP:
17605            gen_addiusp(ctx);
17606            break;
17607        }
17608        break;
17609    case POOL16E:
17610        switch (ctx->opcode & 0x1) {
17611        case ADDIUR2:
17612            gen_addiur2(ctx);
17613            break;
17614        case ADDIUR1SP:
17615            gen_addiur1sp(ctx);
17616            break;
17617        }
17618        break;
17619    case B16: /* BC16 */
17620        gen_compute_branch(ctx, OPC_BEQ, 2, 0, 0,
17621                           sextract32(ctx->opcode, 0, 10) << 1,
17622                           (ctx->insn_flags & ISA_MIPS32R6) ? 0 : 4);
17623        break;
17624    case BNEZ16: /* BNEZC16 */
17625    case BEQZ16: /* BEQZC16 */
17626        gen_compute_branch(ctx, op == BNEZ16 ? OPC_BNE : OPC_BEQ, 2,
17627                           mmreg(uMIPS_RD(ctx->opcode)),
17628                           0, sextract32(ctx->opcode, 0, 7) << 1,
17629                           (ctx->insn_flags & ISA_MIPS32R6) ? 0 : 4);
17630
17631        break;
17632    case LI16:
17633        {
17634            int reg = mmreg(uMIPS_RD(ctx->opcode));
17635            int imm = ZIMM(ctx->opcode, 0, 7);
17636
17637            imm = (imm == 0x7f ? -1 : imm);
17638            tcg_gen_movi_tl(cpu_gpr[reg], imm);
17639        }
17640        break;
17641    case RES_29:
17642    case RES_31:
17643    case RES_39:
17644        generate_exception_end(ctx, EXCP_RI);
17645        break;
17646    default:
17647        decode_micromips32_opc(env, ctx);
17648        return 4;
17649    }
17650
17651    return 2;
17652}
17653
17654/*
17655 *
17656 * nanoMIPS opcodes
17657 *
17658 */
17659
17660/* MAJOR, P16, and P32 pools opcodes */
17661enum {
17662    NM_P_ADDIU      = 0x00,
17663    NM_ADDIUPC      = 0x01,
17664    NM_MOVE_BALC    = 0x02,
17665    NM_P16_MV       = 0x04,
17666    NM_LW16         = 0x05,
17667    NM_BC16         = 0x06,
17668    NM_P16_SR       = 0x07,
17669
17670    NM_POOL32A      = 0x08,
17671    NM_P_BAL        = 0x0a,
17672    NM_P16_SHIFT    = 0x0c,
17673    NM_LWSP16       = 0x0d,
17674    NM_BALC16       = 0x0e,
17675    NM_P16_4X4      = 0x0f,
17676
17677    NM_P_GP_W       = 0x10,
17678    NM_P_GP_BH      = 0x11,
17679    NM_P_J          = 0x12,
17680    NM_P16C         = 0x14,
17681    NM_LWGP16       = 0x15,
17682    NM_P16_LB       = 0x17,
17683
17684    NM_P48I         = 0x18,
17685    NM_P16_A1       = 0x1c,
17686    NM_LW4X4        = 0x1d,
17687    NM_P16_LH       = 0x1f,
17688
17689    NM_P_U12        = 0x20,
17690    NM_P_LS_U12     = 0x21,
17691    NM_P_BR1        = 0x22,
17692    NM_P16_A2       = 0x24,
17693    NM_SW16         = 0x25,
17694    NM_BEQZC16      = 0x26,
17695
17696    NM_POOL32F      = 0x28,
17697    NM_P_LS_S9      = 0x29,
17698    NM_P_BR2        = 0x2a,
17699
17700    NM_P16_ADDU     = 0x2c,
17701    NM_SWSP16       = 0x2d,
17702    NM_BNEZC16      = 0x2e,
17703    NM_MOVEP        = 0x2f,
17704
17705    NM_POOL32S      = 0x30,
17706    NM_P_BRI        = 0x32,
17707    NM_LI16         = 0x34,
17708    NM_SWGP16       = 0x35,
17709    NM_P16_BR       = 0x36,
17710
17711    NM_P_LUI        = 0x38,
17712    NM_ANDI16       = 0x3c,
17713    NM_SW4X4        = 0x3d,
17714    NM_MOVEPREV     = 0x3f,
17715};
17716
17717/* POOL32A instruction pool */
17718enum {
17719    NM_POOL32A0    = 0x00,
17720    NM_SPECIAL2    = 0x01,
17721    NM_COP2_1      = 0x02,
17722    NM_UDI         = 0x03,
17723    NM_POOL32A5    = 0x05,
17724    NM_POOL32A7    = 0x07,
17725};
17726
17727/* P.GP.W instruction pool */
17728enum {
17729    NM_ADDIUGP_W = 0x00,
17730    NM_LWGP      = 0x02,
17731    NM_SWGP      = 0x03,
17732};
17733
17734/* P48I instruction pool */
17735enum {
17736    NM_LI48        = 0x00,
17737    NM_ADDIU48     = 0x01,
17738    NM_ADDIUGP48   = 0x02,
17739    NM_ADDIUPC48   = 0x03,
17740    NM_LWPC48      = 0x0b,
17741    NM_SWPC48      = 0x0f,
17742};
17743
17744/* P.U12 instruction pool */
17745enum {
17746    NM_ORI      = 0x00,
17747    NM_XORI     = 0x01,
17748    NM_ANDI     = 0x02,
17749    NM_P_SR     = 0x03,
17750    NM_SLTI     = 0x04,
17751    NM_SLTIU    = 0x05,
17752    NM_SEQI     = 0x06,
17753    NM_ADDIUNEG = 0x08,
17754    NM_P_SHIFT  = 0x0c,
17755    NM_P_ROTX   = 0x0d,
17756    NM_P_INS    = 0x0e,
17757    NM_P_EXT    = 0x0f,
17758};
17759
17760/* POOL32F instruction pool */
17761enum {
17762    NM_POOL32F_0   = 0x00,
17763    NM_POOL32F_3   = 0x03,
17764    NM_POOL32F_5   = 0x05,
17765};
17766
17767/* POOL32S instruction pool */
17768enum {
17769    NM_POOL32S_0   = 0x00,
17770    NM_POOL32S_4   = 0x04,
17771};
17772
17773/* P.LUI instruction pool */
17774enum {
17775    NM_LUI      = 0x00,
17776    NM_ALUIPC   = 0x01,
17777};
17778
17779/* P.GP.BH instruction pool */
17780enum {
17781    NM_LBGP      = 0x00,
17782    NM_SBGP      = 0x01,
17783    NM_LBUGP     = 0x02,
17784    NM_ADDIUGP_B = 0x03,
17785    NM_P_GP_LH   = 0x04,
17786    NM_P_GP_SH   = 0x05,
17787    NM_P_GP_CP1  = 0x06,
17788};
17789
17790/* P.LS.U12 instruction pool */
17791enum {
17792    NM_LB        = 0x00,
17793    NM_SB        = 0x01,
17794    NM_LBU       = 0x02,
17795    NM_P_PREFU12 = 0x03,
17796    NM_LH        = 0x04,
17797    NM_SH        = 0x05,
17798    NM_LHU       = 0x06,
17799    NM_LWU       = 0x07,
17800    NM_LW        = 0x08,
17801    NM_SW        = 0x09,
17802    NM_LWC1      = 0x0a,
17803    NM_SWC1      = 0x0b,
17804    NM_LDC1      = 0x0e,
17805    NM_SDC1      = 0x0f,
17806};
17807
17808/* P.LS.S9 instruction pool */
17809enum {
17810    NM_P_LS_S0         = 0x00,
17811    NM_P_LS_S1         = 0x01,
17812    NM_P_LS_E0         = 0x02,
17813    NM_P_LS_WM         = 0x04,
17814    NM_P_LS_UAWM       = 0x05,
17815};
17816
17817/* P.BAL instruction pool */
17818enum {
17819    NM_BC       = 0x00,
17820    NM_BALC     = 0x01,
17821};
17822
17823/* P.J instruction pool */
17824enum {
17825    NM_JALRC    = 0x00,
17826    NM_JALRC_HB = 0x01,
17827    NM_P_BALRSC = 0x08,
17828};
17829
17830/* P.BR1 instruction pool */
17831enum {
17832    NM_BEQC     = 0x00,
17833    NM_P_BR3A   = 0x01,
17834    NM_BGEC     = 0x02,
17835    NM_BGEUC    = 0x03,
17836};
17837
17838/* P.BR2 instruction pool */
17839enum {
17840    NM_BNEC     = 0x00,
17841    NM_BLTC     = 0x02,
17842    NM_BLTUC    = 0x03,
17843};
17844
17845/* P.BRI instruction pool */
17846enum {
17847    NM_BEQIC    = 0x00,
17848    NM_BBEQZC   = 0x01,
17849    NM_BGEIC    = 0x02,
17850    NM_BGEIUC   = 0x03,
17851    NM_BNEIC    = 0x04,
17852    NM_BBNEZC   = 0x05,
17853    NM_BLTIC    = 0x06,
17854    NM_BLTIUC   = 0x07,
17855};
17856
17857/* P16.SHIFT instruction pool */
17858enum {
17859    NM_SLL16    = 0x00,
17860    NM_SRL16    = 0x01,
17861};
17862
17863/* POOL16C instruction pool */
17864enum {
17865    NM_POOL16C_0  = 0x00,
17866    NM_LWXS16     = 0x01,
17867};
17868
17869/* P16.A1 instruction pool */
17870enum {
17871    NM_ADDIUR1SP = 0x01,
17872};
17873
17874/* P16.A2 instruction pool */
17875enum {
17876    NM_ADDIUR2  = 0x00,
17877    NM_P_ADDIURS5  = 0x01,
17878};
17879
17880/* P16.ADDU instruction pool */
17881enum {
17882    NM_ADDU16     = 0x00,
17883    NM_SUBU16     = 0x01,
17884};
17885
17886/* P16.SR instruction pool */
17887enum {
17888    NM_SAVE16        = 0x00,
17889    NM_RESTORE_JRC16 = 0x01,
17890};
17891
17892/* P16.4X4 instruction pool */
17893enum {
17894    NM_ADDU4X4      = 0x00,
17895    NM_MUL4X4       = 0x01,
17896};
17897
17898/* P16.LB instruction pool */
17899enum {
17900    NM_LB16       = 0x00,
17901    NM_SB16       = 0x01,
17902    NM_LBU16      = 0x02,
17903};
17904
17905/* P16.LH  instruction pool */
17906enum {
17907    NM_LH16     = 0x00,
17908    NM_SH16     = 0x01,
17909    NM_LHU16    = 0x02,
17910};
17911
17912/* P.RI instruction pool */
17913enum {
17914    NM_SIGRIE       = 0x00,
17915    NM_P_SYSCALL    = 0x01,
17916    NM_BREAK        = 0x02,
17917    NM_SDBBP        = 0x03,
17918};
17919
17920/* POOL32A0 instruction pool */
17921enum {
17922    NM_P_TRAP   = 0x00,
17923    NM_SEB      = 0x01,
17924    NM_SLLV     = 0x02,
17925    NM_MUL      = 0x03,
17926    NM_MFC0     = 0x06,
17927    NM_MFHC0    = 0x07,
17928    NM_SEH      = 0x09,
17929    NM_SRLV     = 0x0a,
17930    NM_MUH      = 0x0b,
17931    NM_MTC0     = 0x0e,
17932    NM_MTHC0    = 0x0f,
17933    NM_SRAV     = 0x12,
17934    NM_MULU     = 0x13,
17935    NM_ROTRV    = 0x1a,
17936    NM_MUHU     = 0x1b,
17937    NM_ADD      = 0x22,
17938    NM_DIV      = 0x23,
17939    NM_ADDU     = 0x2a,
17940    NM_MOD      = 0x2b,
17941    NM_SUB      = 0x32,
17942    NM_DIVU     = 0x33,
17943    NM_RDHWR    = 0x38,
17944    NM_SUBU     = 0x3a,
17945    NM_MODU     = 0x3b,
17946    NM_P_CMOVE  = 0x42,
17947    NM_FORK     = 0x45,
17948    NM_MFTR     = 0x46,
17949    NM_MFHTR    = 0x47,
17950    NM_AND      = 0x4a,
17951    NM_YIELD    = 0x4d,
17952    NM_MTTR     = 0x4e,
17953    NM_MTHTR    = 0x4f,
17954    NM_OR       = 0x52,
17955    NM_D_E_MT_VPE = 0x56,
17956    NM_NOR      = 0x5a,
17957    NM_XOR      = 0x62,
17958    NM_SLT      = 0x6a,
17959    NM_P_SLTU   = 0x72,
17960    NM_SOV      = 0x7a,
17961};
17962
17963/* CRC32 instruction pool */
17964enum {
17965    NM_CRC32B   = 0x00,
17966    NM_CRC32H   = 0x01,
17967    NM_CRC32W   = 0x02,
17968    NM_CRC32CB  = 0x04,
17969    NM_CRC32CH  = 0x05,
17970    NM_CRC32CW  = 0x06,
17971};
17972
17973/* POOL32A5 instruction pool */
17974enum {
17975    NM_CMP_EQ_PH        = 0x00,
17976    NM_CMP_LT_PH        = 0x08,
17977    NM_CMP_LE_PH        = 0x10,
17978    NM_CMPGU_EQ_QB      = 0x18,
17979    NM_CMPGU_LT_QB      = 0x20,
17980    NM_CMPGU_LE_QB      = 0x28,
17981    NM_CMPGDU_EQ_QB     = 0x30,
17982    NM_CMPGDU_LT_QB     = 0x38,
17983    NM_CMPGDU_LE_QB     = 0x40,
17984    NM_CMPU_EQ_QB       = 0x48,
17985    NM_CMPU_LT_QB       = 0x50,
17986    NM_CMPU_LE_QB       = 0x58,
17987    NM_ADDQ_S_W         = 0x60,
17988    NM_SUBQ_S_W         = 0x68,
17989    NM_ADDSC            = 0x70,
17990    NM_ADDWC            = 0x78,
17991
17992    NM_ADDQ_S_PH   = 0x01,
17993    NM_ADDQH_R_PH  = 0x09,
17994    NM_ADDQH_R_W   = 0x11,
17995    NM_ADDU_S_QB   = 0x19,
17996    NM_ADDU_S_PH   = 0x21,
17997    NM_ADDUH_R_QB  = 0x29,
17998    NM_SHRAV_R_PH  = 0x31,
17999    NM_SHRAV_R_QB  = 0x39,
18000    NM_SUBQ_S_PH   = 0x41,
18001    NM_SUBQH_R_PH  = 0x49,
18002    NM_SUBQH_R_W   = 0x51,
18003    NM_SUBU_S_QB   = 0x59,
18004    NM_SUBU_S_PH   = 0x61,
18005    NM_SUBUH_R_QB  = 0x69,
18006    NM_SHLLV_S_PH  = 0x71,
18007    NM_PRECR_SRA_R_PH_W = 0x79,
18008
18009    NM_MULEU_S_PH_QBL   = 0x12,
18010    NM_MULEU_S_PH_QBR   = 0x1a,
18011    NM_MULQ_RS_PH       = 0x22,
18012    NM_MULQ_S_PH        = 0x2a,
18013    NM_MULQ_RS_W        = 0x32,
18014    NM_MULQ_S_W         = 0x3a,
18015    NM_APPEND           = 0x42,
18016    NM_MODSUB           = 0x52,
18017    NM_SHRAV_R_W        = 0x5a,
18018    NM_SHRLV_PH         = 0x62,
18019    NM_SHRLV_QB         = 0x6a,
18020    NM_SHLLV_QB         = 0x72,
18021    NM_SHLLV_S_W        = 0x7a,
18022
18023    NM_SHILO            = 0x03,
18024
18025    NM_MULEQ_S_W_PHL    = 0x04,
18026    NM_MULEQ_S_W_PHR    = 0x0c,
18027
18028    NM_MUL_S_PH         = 0x05,
18029    NM_PRECR_QB_PH      = 0x0d,
18030    NM_PRECRQ_QB_PH     = 0x15,
18031    NM_PRECRQ_PH_W      = 0x1d,
18032    NM_PRECRQ_RS_PH_W   = 0x25,
18033    NM_PRECRQU_S_QB_PH  = 0x2d,
18034    NM_PACKRL_PH        = 0x35,
18035    NM_PICK_QB          = 0x3d,
18036    NM_PICK_PH          = 0x45,
18037
18038    NM_SHRA_R_W         = 0x5e,
18039    NM_SHRA_R_PH        = 0x66,
18040    NM_SHLL_S_PH        = 0x76,
18041    NM_SHLL_S_W         = 0x7e,
18042
18043    NM_REPL_PH          = 0x07
18044};
18045
18046/* POOL32A7 instruction pool */
18047enum {
18048    NM_P_LSX        = 0x00,
18049    NM_LSA          = 0x01,
18050    NM_EXTW         = 0x03,
18051    NM_POOL32AXF    = 0x07,
18052};
18053
18054/* P.SR instruction pool */
18055enum {
18056    NM_PP_SR           = 0x00,
18057    NM_P_SR_F          = 0x01,
18058};
18059
18060/* P.SHIFT instruction pool */
18061enum {
18062    NM_P_SLL        = 0x00,
18063    NM_SRL          = 0x02,
18064    NM_SRA          = 0x04,
18065    NM_ROTR         = 0x06,
18066};
18067
18068/* P.ROTX instruction pool */
18069enum {
18070    NM_ROTX         = 0x00,
18071};
18072
18073/* P.INS instruction pool */
18074enum {
18075    NM_INS          = 0x00,
18076};
18077
18078/* P.EXT instruction pool */
18079enum {
18080    NM_EXT          = 0x00,
18081};
18082
18083/* POOL32F_0 (fmt) instruction pool */
18084enum {
18085    NM_RINT_S              = 0x04,
18086    NM_RINT_D              = 0x44,
18087    NM_ADD_S               = 0x06,
18088    NM_SELEQZ_S            = 0x07,
18089    NM_SELEQZ_D            = 0x47,
18090    NM_CLASS_S             = 0x0c,
18091    NM_CLASS_D             = 0x4c,
18092    NM_SUB_S               = 0x0e,
18093    NM_SELNEZ_S            = 0x0f,
18094    NM_SELNEZ_D            = 0x4f,
18095    NM_MUL_S               = 0x16,
18096    NM_SEL_S               = 0x17,
18097    NM_SEL_D               = 0x57,
18098    NM_DIV_S               = 0x1e,
18099    NM_ADD_D               = 0x26,
18100    NM_SUB_D               = 0x2e,
18101    NM_MUL_D               = 0x36,
18102    NM_MADDF_S             = 0x37,
18103    NM_MADDF_D             = 0x77,
18104    NM_DIV_D               = 0x3e,
18105    NM_MSUBF_S             = 0x3f,
18106    NM_MSUBF_D             = 0x7f,
18107};
18108
18109/* POOL32F_3  instruction pool */
18110enum {
18111    NM_MIN_FMT         = 0x00,
18112    NM_MAX_FMT         = 0x01,
18113    NM_MINA_FMT        = 0x04,
18114    NM_MAXA_FMT        = 0x05,
18115    NM_POOL32FXF       = 0x07,
18116};
18117
18118/* POOL32F_5  instruction pool */
18119enum {
18120    NM_CMP_CONDN_S     = 0x00,
18121    NM_CMP_CONDN_D     = 0x02,
18122};
18123
18124/* P.GP.LH instruction pool */
18125enum {
18126    NM_LHGP    = 0x00,
18127    NM_LHUGP   = 0x01,
18128};
18129
18130/* P.GP.SH instruction pool */
18131enum {
18132    NM_SHGP    = 0x00,
18133};
18134
18135/* P.GP.CP1 instruction pool */
18136enum {
18137    NM_LWC1GP       = 0x00,
18138    NM_SWC1GP       = 0x01,
18139    NM_LDC1GP       = 0x02,
18140    NM_SDC1GP       = 0x03,
18141};
18142
18143/* P.LS.S0 instruction pool */
18144enum {
18145    NM_LBS9     = 0x00,
18146    NM_LHS9     = 0x04,
18147    NM_LWS9     = 0x08,
18148    NM_LDS9     = 0x0c,
18149
18150    NM_SBS9     = 0x01,
18151    NM_SHS9     = 0x05,
18152    NM_SWS9     = 0x09,
18153    NM_SDS9     = 0x0d,
18154
18155    NM_LBUS9    = 0x02,
18156    NM_LHUS9    = 0x06,
18157    NM_LWC1S9   = 0x0a,
18158    NM_LDC1S9   = 0x0e,
18159
18160    NM_P_PREFS9 = 0x03,
18161    NM_LWUS9    = 0x07,
18162    NM_SWC1S9   = 0x0b,
18163    NM_SDC1S9   = 0x0f,
18164};
18165
18166/* P.LS.S1 instruction pool */
18167enum {
18168    NM_ASET_ACLR = 0x02,
18169    NM_UALH      = 0x04,
18170    NM_UASH      = 0x05,
18171    NM_CACHE     = 0x07,
18172    NM_P_LL      = 0x0a,
18173    NM_P_SC      = 0x0b,
18174};
18175
18176/* P.LS.E0 instruction pool */
18177enum {
18178    NM_LBE      = 0x00,
18179    NM_SBE      = 0x01,
18180    NM_LBUE     = 0x02,
18181    NM_P_PREFE  = 0x03,
18182    NM_LHE      = 0x04,
18183    NM_SHE      = 0x05,
18184    NM_LHUE     = 0x06,
18185    NM_CACHEE   = 0x07,
18186    NM_LWE      = 0x08,
18187    NM_SWE      = 0x09,
18188    NM_P_LLE    = 0x0a,
18189    NM_P_SCE    = 0x0b,
18190};
18191
18192/* P.PREFE instruction pool */
18193enum {
18194    NM_SYNCIE   = 0x00,
18195    NM_PREFE    = 0x01,
18196};
18197
18198/* P.LLE instruction pool */
18199enum {
18200    NM_LLE      = 0x00,
18201    NM_LLWPE    = 0x01,
18202};
18203
18204/* P.SCE instruction pool */
18205enum {
18206    NM_SCE      = 0x00,
18207    NM_SCWPE    = 0x01,
18208};
18209
18210/* P.LS.WM instruction pool */
18211enum {
18212    NM_LWM       = 0x00,
18213    NM_SWM       = 0x01,
18214};
18215
18216/* P.LS.UAWM instruction pool */
18217enum {
18218    NM_UALWM       = 0x00,
18219    NM_UASWM       = 0x01,
18220};
18221
18222/* P.BR3A instruction pool */
18223enum {
18224    NM_BC1EQZC          = 0x00,
18225    NM_BC1NEZC          = 0x01,
18226    NM_BC2EQZC          = 0x02,
18227    NM_BC2NEZC          = 0x03,
18228    NM_BPOSGE32C        = 0x04,
18229};
18230
18231/* P16.RI instruction pool */
18232enum {
18233    NM_P16_SYSCALL  = 0x01,
18234    NM_BREAK16      = 0x02,
18235    NM_SDBBP16      = 0x03,
18236};
18237
18238/* POOL16C_0 instruction pool */
18239enum {
18240    NM_POOL16C_00      = 0x00,
18241};
18242
18243/* P16.JRC instruction pool */
18244enum {
18245    NM_JRC          = 0x00,
18246    NM_JALRC16      = 0x01,
18247};
18248
18249/* P.SYSCALL instruction pool */
18250enum {
18251    NM_SYSCALL      = 0x00,
18252    NM_HYPCALL      = 0x01,
18253};
18254
18255/* P.TRAP instruction pool */
18256enum {
18257    NM_TEQ          = 0x00,
18258    NM_TNE          = 0x01,
18259};
18260
18261/* P.CMOVE instruction pool */
18262enum {
18263    NM_MOVZ            = 0x00,
18264    NM_MOVN            = 0x01,
18265};
18266
18267/* POOL32Axf instruction pool */
18268enum {
18269    NM_POOL32AXF_1 = 0x01,
18270    NM_POOL32AXF_2 = 0x02,
18271    NM_POOL32AXF_4 = 0x04,
18272    NM_POOL32AXF_5 = 0x05,
18273    NM_POOL32AXF_7 = 0x07,
18274};
18275
18276/* POOL32Axf_1 instruction pool */
18277enum {
18278    NM_POOL32AXF_1_0 = 0x00,
18279    NM_POOL32AXF_1_1 = 0x01,
18280    NM_POOL32AXF_1_3 = 0x03,
18281    NM_POOL32AXF_1_4 = 0x04,
18282    NM_POOL32AXF_1_5 = 0x05,
18283    NM_POOL32AXF_1_7 = 0x07,
18284};
18285
18286/* POOL32Axf_2 instruction pool */
18287enum {
18288    NM_POOL32AXF_2_0_7     = 0x00,
18289    NM_POOL32AXF_2_8_15    = 0x01,
18290    NM_POOL32AXF_2_16_23   = 0x02,
18291    NM_POOL32AXF_2_24_31   = 0x03,
18292};
18293
18294/* POOL32Axf_7 instruction pool */
18295enum {
18296    NM_SHRA_R_QB    = 0x0,
18297    NM_SHRL_PH      = 0x1,
18298    NM_REPL_QB      = 0x2,
18299};
18300
18301/* POOL32Axf_1_0 instruction pool */
18302enum {
18303    NM_MFHI = 0x0,
18304    NM_MFLO = 0x1,
18305    NM_MTHI = 0x2,
18306    NM_MTLO = 0x3,
18307};
18308
18309/* POOL32Axf_1_1 instruction pool */
18310enum {
18311    NM_MTHLIP = 0x0,
18312    NM_SHILOV = 0x1,
18313};
18314
18315/* POOL32Axf_1_3 instruction pool */
18316enum {
18317    NM_RDDSP    = 0x0,
18318    NM_WRDSP    = 0x1,
18319    NM_EXTP     = 0x2,
18320    NM_EXTPDP   = 0x3,
18321};
18322
18323/* POOL32Axf_1_4 instruction pool */
18324enum {
18325    NM_SHLL_QB  = 0x0,
18326    NM_SHRL_QB  = 0x1,
18327};
18328
18329/* POOL32Axf_1_5 instruction pool */
18330enum {
18331    NM_MAQ_S_W_PHR   = 0x0,
18332    NM_MAQ_S_W_PHL   = 0x1,
18333    NM_MAQ_SA_W_PHR  = 0x2,
18334    NM_MAQ_SA_W_PHL  = 0x3,
18335};
18336
18337/* POOL32Axf_1_7 instruction pool */
18338enum {
18339    NM_EXTR_W       = 0x0,
18340    NM_EXTR_R_W     = 0x1,
18341    NM_EXTR_RS_W    = 0x2,
18342    NM_EXTR_S_H     = 0x3,
18343};
18344
18345/* POOL32Axf_2_0_7 instruction pool */
18346enum {
18347    NM_DPA_W_PH     = 0x0,
18348    NM_DPAQ_S_W_PH  = 0x1,
18349    NM_DPS_W_PH     = 0x2,
18350    NM_DPSQ_S_W_PH  = 0x3,
18351    NM_BALIGN       = 0x4,
18352    NM_MADD         = 0x5,
18353    NM_MULT         = 0x6,
18354    NM_EXTRV_W      = 0x7,
18355};
18356
18357/* POOL32Axf_2_8_15 instruction pool */
18358enum {
18359    NM_DPAX_W_PH    = 0x0,
18360    NM_DPAQ_SA_L_W  = 0x1,
18361    NM_DPSX_W_PH    = 0x2,
18362    NM_DPSQ_SA_L_W  = 0x3,
18363    NM_MADDU        = 0x5,
18364    NM_MULTU        = 0x6,
18365    NM_EXTRV_R_W    = 0x7,
18366};
18367
18368/* POOL32Axf_2_16_23 instruction pool */
18369enum {
18370    NM_DPAU_H_QBL       = 0x0,
18371    NM_DPAQX_S_W_PH     = 0x1,
18372    NM_DPSU_H_QBL       = 0x2,
18373    NM_DPSQX_S_W_PH     = 0x3,
18374    NM_EXTPV            = 0x4,
18375    NM_MSUB             = 0x5,
18376    NM_MULSA_W_PH       = 0x6,
18377    NM_EXTRV_RS_W       = 0x7,
18378};
18379
18380/* POOL32Axf_2_24_31 instruction pool */
18381enum {
18382    NM_DPAU_H_QBR       = 0x0,
18383    NM_DPAQX_SA_W_PH    = 0x1,
18384    NM_DPSU_H_QBR       = 0x2,
18385    NM_DPSQX_SA_W_PH    = 0x3,
18386    NM_EXTPDPV          = 0x4,
18387    NM_MSUBU            = 0x5,
18388    NM_MULSAQ_S_W_PH    = 0x6,
18389    NM_EXTRV_S_H        = 0x7,
18390};
18391
18392/* POOL32Axf_{4, 5} instruction pool */
18393enum {
18394    NM_CLO      = 0x25,
18395    NM_CLZ      = 0x2d,
18396
18397    NM_TLBP     = 0x01,
18398    NM_TLBR     = 0x09,
18399    NM_TLBWI    = 0x11,
18400    NM_TLBWR    = 0x19,
18401    NM_TLBINV   = 0x03,
18402    NM_TLBINVF  = 0x0b,
18403    NM_DI       = 0x23,
18404    NM_EI       = 0x2b,
18405    NM_RDPGPR   = 0x70,
18406    NM_WRPGPR   = 0x78,
18407    NM_WAIT     = 0x61,
18408    NM_DERET    = 0x71,
18409    NM_ERETX    = 0x79,
18410
18411    /* nanoMIPS DSP instructions */
18412    NM_ABSQ_S_QB        = 0x00,
18413    NM_ABSQ_S_PH        = 0x08,
18414    NM_ABSQ_S_W         = 0x10,
18415    NM_PRECEQ_W_PHL     = 0x28,
18416    NM_PRECEQ_W_PHR     = 0x30,
18417    NM_PRECEQU_PH_QBL   = 0x38,
18418    NM_PRECEQU_PH_QBR   = 0x48,
18419    NM_PRECEU_PH_QBL    = 0x58,
18420    NM_PRECEU_PH_QBR    = 0x68,
18421    NM_PRECEQU_PH_QBLA  = 0x39,
18422    NM_PRECEQU_PH_QBRA  = 0x49,
18423    NM_PRECEU_PH_QBLA   = 0x59,
18424    NM_PRECEU_PH_QBRA   = 0x69,
18425    NM_REPLV_PH         = 0x01,
18426    NM_REPLV_QB         = 0x09,
18427    NM_BITREV           = 0x18,
18428    NM_INSV             = 0x20,
18429    NM_RADDU_W_QB       = 0x78,
18430
18431    NM_BITSWAP          = 0x05,
18432    NM_WSBH             = 0x3d,
18433};
18434
18435/* PP.SR instruction pool */
18436enum {
18437    NM_SAVE         = 0x00,
18438    NM_RESTORE      = 0x02,
18439    NM_RESTORE_JRC  = 0x03,
18440};
18441
18442/* P.SR.F instruction pool */
18443enum {
18444    NM_SAVEF        = 0x00,
18445    NM_RESTOREF     = 0x01,
18446};
18447
18448/* P16.SYSCALL  instruction pool */
18449enum {
18450    NM_SYSCALL16     = 0x00,
18451    NM_HYPCALL16     = 0x01,
18452};
18453
18454/* POOL16C_00 instruction pool */
18455enum {
18456    NM_NOT16           = 0x00,
18457    NM_XOR16           = 0x01,
18458    NM_AND16           = 0x02,
18459    NM_OR16            = 0x03,
18460};
18461
18462/* PP.LSX and PP.LSXS instruction pool */
18463enum {
18464    NM_LBX      = 0x00,
18465    NM_LHX      = 0x04,
18466    NM_LWX      = 0x08,
18467    NM_LDX      = 0x0c,
18468
18469    NM_SBX      = 0x01,
18470    NM_SHX      = 0x05,
18471    NM_SWX      = 0x09,
18472    NM_SDX      = 0x0d,
18473
18474    NM_LBUX     = 0x02,
18475    NM_LHUX     = 0x06,
18476    NM_LWC1X    = 0x0a,
18477    NM_LDC1X    = 0x0e,
18478
18479    NM_LWUX     = 0x07,
18480    NM_SWC1X    = 0x0b,
18481    NM_SDC1X    = 0x0f,
18482
18483    NM_LHXS     = 0x04,
18484    NM_LWXS     = 0x08,
18485    NM_LDXS     = 0x0c,
18486
18487    NM_SHXS     = 0x05,
18488    NM_SWXS     = 0x09,
18489    NM_SDXS     = 0x0d,
18490
18491    NM_LHUXS    = 0x06,
18492    NM_LWC1XS   = 0x0a,
18493    NM_LDC1XS   = 0x0e,
18494
18495    NM_LWUXS    = 0x07,
18496    NM_SWC1XS   = 0x0b,
18497    NM_SDC1XS   = 0x0f,
18498};
18499
18500/* ERETx instruction pool */
18501enum {
18502    NM_ERET     = 0x00,
18503    NM_ERETNC   = 0x01,
18504};
18505
18506/* POOL32FxF_{0, 1} insturction pool */
18507enum {
18508    NM_CFC1     = 0x40,
18509    NM_CTC1     = 0x60,
18510    NM_MFC1     = 0x80,
18511    NM_MTC1     = 0xa0,
18512    NM_MFHC1    = 0xc0,
18513    NM_MTHC1    = 0xe0,
18514
18515    NM_CVT_S_PL = 0x84,
18516    NM_CVT_S_PU = 0xa4,
18517
18518    NM_CVT_L_S     = 0x004,
18519    NM_CVT_L_D     = 0x104,
18520    NM_CVT_W_S     = 0x024,
18521    NM_CVT_W_D     = 0x124,
18522
18523    NM_RSQRT_S     = 0x008,
18524    NM_RSQRT_D     = 0x108,
18525
18526    NM_SQRT_S      = 0x028,
18527    NM_SQRT_D      = 0x128,
18528
18529    NM_RECIP_S     = 0x048,
18530    NM_RECIP_D     = 0x148,
18531
18532    NM_FLOOR_L_S   = 0x00c,
18533    NM_FLOOR_L_D   = 0x10c,
18534
18535    NM_FLOOR_W_S   = 0x02c,
18536    NM_FLOOR_W_D   = 0x12c,
18537
18538    NM_CEIL_L_S    = 0x04c,
18539    NM_CEIL_L_D    = 0x14c,
18540    NM_CEIL_W_S    = 0x06c,
18541    NM_CEIL_W_D    = 0x16c,
18542    NM_TRUNC_L_S   = 0x08c,
18543    NM_TRUNC_L_D   = 0x18c,
18544    NM_TRUNC_W_S   = 0x0ac,
18545    NM_TRUNC_W_D   = 0x1ac,
18546    NM_ROUND_L_S   = 0x0cc,
18547    NM_ROUND_L_D   = 0x1cc,
18548    NM_ROUND_W_S   = 0x0ec,
18549    NM_ROUND_W_D   = 0x1ec,
18550
18551    NM_MOV_S       = 0x01,
18552    NM_MOV_D       = 0x81,
18553    NM_ABS_S       = 0x0d,
18554    NM_ABS_D       = 0x8d,
18555    NM_NEG_S       = 0x2d,
18556    NM_NEG_D       = 0xad,
18557    NM_CVT_D_S     = 0x04d,
18558    NM_CVT_D_W     = 0x0cd,
18559    NM_CVT_D_L     = 0x14d,
18560    NM_CVT_S_D     = 0x06d,
18561    NM_CVT_S_W     = 0x0ed,
18562    NM_CVT_S_L     = 0x16d,
18563};
18564
18565/* P.LL instruction pool */
18566enum {
18567    NM_LL       = 0x00,
18568    NM_LLWP     = 0x01,
18569};
18570
18571/* P.SC instruction pool */
18572enum {
18573    NM_SC       = 0x00,
18574    NM_SCWP     = 0x01,
18575};
18576
18577/* P.DVP instruction pool */
18578enum {
18579    NM_DVP      = 0x00,
18580    NM_EVP      = 0x01,
18581};
18582
18583
18584/*
18585 *
18586 * nanoMIPS decoding engine
18587 *
18588 */
18589
18590
18591/* extraction utilities */
18592
18593#define NANOMIPS_EXTRACT_RT3(op) ((op >> 7) & 0x7)
18594#define NANOMIPS_EXTRACT_RS3(op) ((op >> 4) & 0x7)
18595#define NANOMIPS_EXTRACT_RD3(op) ((op >> 1) & 0x7)
18596#define NANOMIPS_EXTRACT_RD5(op) ((op >> 5) & 0x1f)
18597#define NANOMIPS_EXTRACT_RS5(op) (op & 0x1f)
18598
18599/* Implement nanoMIPS pseudocode decode_gpr(encoded_gpr, 'gpr3'). */
18600static inline int decode_gpr_gpr3(int r)
18601{
18602    static const int map[] = { 16, 17, 18, 19,  4,  5,  6,  7 };
18603
18604    return map[r & 0x7];
18605}
18606
18607/* Implement nanoMIPS pseudocode decode_gpr(encoded_gpr, 'gpr3.src.store'). */
18608static inline int decode_gpr_gpr3_src_store(int r)
18609{
18610    static const int map[] = {  0, 17, 18, 19,  4,  5,  6,  7 };
18611
18612    return map[r & 0x7];
18613}
18614
18615/* Implement nanoMIPS pseudocode decode_gpr(encoded_gpr, 'gpr4'). */
18616static inline int decode_gpr_gpr4(int r)
18617{
18618    static const int map[] = {  8,  9, 10, 11,  4,  5,  6,  7,
18619                               16, 17, 18, 19, 20, 21, 22, 23 };
18620
18621    return map[r & 0xf];
18622}
18623
18624/* Implement nanoMIPS pseudocode decode_gpr(encoded_gpr, 'gpr4.zero'). */
18625static inline int decode_gpr_gpr4_zero(int r)
18626{
18627    static const int map[] = {  8,  9, 10,  0,  4,  5,  6,  7,
18628                               16, 17, 18, 19, 20, 21, 22, 23 };
18629
18630    return map[r & 0xf];
18631}
18632
18633
18634static void gen_adjust_sp(DisasContext *ctx, int u)
18635{
18636    gen_op_addr_addi(ctx, cpu_gpr[29], cpu_gpr[29], u);
18637}
18638
18639static void gen_save(DisasContext *ctx, uint8_t rt, uint8_t count,
18640                     uint8_t gp, uint16_t u)
18641{
18642    int counter = 0;
18643    TCGv va = tcg_temp_new();
18644    TCGv t0 = tcg_temp_new();
18645
18646    while (counter != count) {
18647        bool use_gp = gp && (counter == count - 1);
18648        int this_rt = use_gp ? 28 : (rt & 0x10) | ((rt + counter) & 0x1f);
18649        int this_offset = -((counter + 1) << 2);
18650        gen_base_offset_addr(ctx, va, 29, this_offset);
18651        gen_load_gpr(t0, this_rt);
18652        tcg_gen_qemu_st_tl(t0, va, ctx->mem_idx,
18653                           (MO_TEUL | ctx->default_tcg_memop_mask));
18654        counter++;
18655    }
18656
18657    /* adjust stack pointer */
18658    gen_adjust_sp(ctx, -u);
18659
18660    tcg_temp_free(t0);
18661    tcg_temp_free(va);
18662}
18663
18664static void gen_restore(DisasContext *ctx, uint8_t rt, uint8_t count,
18665                        uint8_t gp, uint16_t u)
18666{
18667    int counter = 0;
18668    TCGv va = tcg_temp_new();
18669    TCGv t0 = tcg_temp_new();
18670
18671    while (counter != count) {
18672        bool use_gp = gp && (counter == count - 1);
18673        int this_rt = use_gp ? 28 : (rt & 0x10) | ((rt + counter) & 0x1f);
18674        int this_offset = u - ((counter + 1) << 2);
18675        gen_base_offset_addr(ctx, va, 29, this_offset);
18676        tcg_gen_qemu_ld_tl(t0, va, ctx->mem_idx, MO_TESL |
18677                        ctx->default_tcg_memop_mask);
18678        tcg_gen_ext32s_tl(t0, t0);
18679        gen_store_gpr(t0, this_rt);
18680        counter++;
18681    }
18682
18683    /* adjust stack pointer */
18684    gen_adjust_sp(ctx, u);
18685
18686    tcg_temp_free(t0);
18687    tcg_temp_free(va);
18688}
18689
18690static void gen_pool16c_nanomips_insn(DisasContext *ctx)
18691{
18692    int rt = decode_gpr_gpr3(NANOMIPS_EXTRACT_RT3(ctx->opcode));
18693    int rs = decode_gpr_gpr3(NANOMIPS_EXTRACT_RS3(ctx->opcode));
18694
18695    switch (extract32(ctx->opcode, 2, 2)) {
18696    case NM_NOT16:
18697        gen_logic(ctx, OPC_NOR, rt, rs, 0);
18698        break;
18699    case NM_AND16:
18700        gen_logic(ctx, OPC_AND, rt, rt, rs);
18701        break;
18702    case NM_XOR16:
18703        gen_logic(ctx, OPC_XOR, rt, rt, rs);
18704        break;
18705    case NM_OR16:
18706        gen_logic(ctx, OPC_OR, rt, rt, rs);
18707        break;
18708    }
18709}
18710
18711static void gen_pool32a0_nanomips_insn(CPUMIPSState *env, DisasContext *ctx)
18712{
18713    int rt = extract32(ctx->opcode, 21, 5);
18714    int rs = extract32(ctx->opcode, 16, 5);
18715    int rd = extract32(ctx->opcode, 11, 5);
18716
18717    switch (extract32(ctx->opcode, 3, 7)) {
18718    case NM_P_TRAP:
18719        switch (extract32(ctx->opcode, 10, 1)) {
18720        case NM_TEQ:
18721            check_nms(ctx);
18722            gen_trap(ctx, OPC_TEQ, rs, rt, -1);
18723            break;
18724        case NM_TNE:
18725            check_nms(ctx);
18726            gen_trap(ctx, OPC_TNE, rs, rt, -1);
18727            break;
18728        }
18729        break;
18730    case NM_RDHWR:
18731        check_nms(ctx);
18732        gen_rdhwr(ctx, rt, rs, extract32(ctx->opcode, 11, 3));
18733        break;
18734    case NM_SEB:
18735        check_nms(ctx);
18736        gen_bshfl(ctx, OPC_SEB, rs, rt);
18737        break;
18738    case NM_SEH:
18739        gen_bshfl(ctx, OPC_SEH, rs, rt);
18740        break;
18741    case NM_SLLV:
18742        gen_shift(ctx, OPC_SLLV, rd, rt, rs);
18743        break;
18744    case NM_SRLV:
18745        gen_shift(ctx, OPC_SRLV, rd, rt, rs);
18746        break;
18747    case NM_SRAV:
18748        gen_shift(ctx, OPC_SRAV, rd, rt, rs);
18749        break;
18750    case NM_ROTRV:
18751        gen_shift(ctx, OPC_ROTRV, rd, rt, rs);
18752        break;
18753    case NM_ADD:
18754        gen_arith(ctx, OPC_ADD, rd, rs, rt);
18755        break;
18756    case NM_ADDU:
18757        gen_arith(ctx, OPC_ADDU, rd, rs, rt);
18758        break;
18759    case NM_SUB:
18760        check_nms(ctx);
18761        gen_arith(ctx, OPC_SUB, rd, rs, rt);
18762        break;
18763    case NM_SUBU:
18764        gen_arith(ctx, OPC_SUBU, rd, rs, rt);
18765        break;
18766    case NM_P_CMOVE:
18767        switch (extract32(ctx->opcode, 10, 1)) {
18768        case NM_MOVZ:
18769            gen_cond_move(ctx, OPC_MOVZ, rd, rs, rt);
18770            break;
18771        case NM_MOVN:
18772            gen_cond_move(ctx, OPC_MOVN, rd, rs, rt);
18773            break;
18774        }
18775        break;
18776    case NM_AND:
18777        gen_logic(ctx, OPC_AND, rd, rs, rt);
18778        break;
18779    case NM_OR:
18780        gen_logic(ctx, OPC_OR, rd, rs, rt);
18781        break;
18782    case NM_NOR:
18783        gen_logic(ctx, OPC_NOR, rd, rs, rt);
18784        break;
18785    case NM_XOR:
18786        gen_logic(ctx, OPC_XOR, rd, rs, rt);
18787        break;
18788    case NM_SLT:
18789        gen_slt(ctx, OPC_SLT, rd, rs, rt);
18790        break;
18791    case NM_P_SLTU:
18792        if (rd == 0) {
18793            /* P_DVP */
18794#ifndef CONFIG_USER_ONLY
18795            TCGv t0 = tcg_temp_new();
18796            switch (extract32(ctx->opcode, 10, 1)) {
18797            case NM_DVP:
18798                if (ctx->vp) {
18799                    check_cp0_enabled(ctx);
18800                    gen_helper_dvp(t0, cpu_env);
18801                    gen_store_gpr(t0, rt);
18802                }
18803                break;
18804            case NM_EVP:
18805                if (ctx->vp) {
18806                    check_cp0_enabled(ctx);
18807                    gen_helper_evp(t0, cpu_env);
18808                    gen_store_gpr(t0, rt);
18809                }
18810                break;
18811            }
18812            tcg_temp_free(t0);
18813#endif
18814        } else {
18815            gen_slt(ctx, OPC_SLTU, rd, rs, rt);
18816        }
18817        break;
18818    case NM_SOV:
18819        {
18820            TCGv t0 = tcg_temp_new();
18821            TCGv t1 = tcg_temp_new();
18822            TCGv t2 = tcg_temp_new();
18823
18824            gen_load_gpr(t1, rs);
18825            gen_load_gpr(t2, rt);
18826            tcg_gen_add_tl(t0, t1, t2);
18827            tcg_gen_ext32s_tl(t0, t0);
18828            tcg_gen_xor_tl(t1, t1, t2);
18829            tcg_gen_xor_tl(t2, t0, t2);
18830            tcg_gen_andc_tl(t1, t2, t1);
18831
18832            /* operands of same sign, result different sign */
18833            tcg_gen_setcondi_tl(TCG_COND_LT, t0, t1, 0);
18834            gen_store_gpr(t0, rd);
18835
18836            tcg_temp_free(t0);
18837            tcg_temp_free(t1);
18838            tcg_temp_free(t2);
18839        }
18840        break;
18841    case NM_MUL:
18842        gen_r6_muldiv(ctx, R6_OPC_MUL, rd, rs, rt);
18843        break;
18844    case NM_MUH:
18845        gen_r6_muldiv(ctx, R6_OPC_MUH, rd, rs, rt);
18846        break;
18847    case NM_MULU:
18848        gen_r6_muldiv(ctx, R6_OPC_MULU, rd, rs, rt);
18849        break;
18850    case NM_MUHU:
18851        gen_r6_muldiv(ctx, R6_OPC_MUHU, rd, rs, rt);
18852        break;
18853    case NM_DIV:
18854        gen_r6_muldiv(ctx, R6_OPC_DIV, rd, rs, rt);
18855        break;
18856    case NM_MOD:
18857        gen_r6_muldiv(ctx, R6_OPC_MOD, rd, rs, rt);
18858        break;
18859    case NM_DIVU:
18860        gen_r6_muldiv(ctx, R6_OPC_DIVU, rd, rs, rt);
18861        break;
18862    case NM_MODU:
18863        gen_r6_muldiv(ctx, R6_OPC_MODU, rd, rs, rt);
18864        break;
18865#ifndef CONFIG_USER_ONLY
18866    case NM_MFC0:
18867        check_cp0_enabled(ctx);
18868        if (rt == 0) {
18869            /* Treat as NOP. */
18870            break;
18871        }
18872        gen_mfc0(ctx, cpu_gpr[rt], rs, extract32(ctx->opcode, 11, 3));
18873        break;
18874    case NM_MTC0:
18875        check_cp0_enabled(ctx);
18876        {
18877            TCGv t0 = tcg_temp_new();
18878
18879            gen_load_gpr(t0, rt);
18880            gen_mtc0(ctx, t0, rs, extract32(ctx->opcode, 11, 3));
18881            tcg_temp_free(t0);
18882        }
18883        break;
18884    case NM_D_E_MT_VPE:
18885        {
18886            uint8_t sc = extract32(ctx->opcode, 10, 1);
18887            TCGv t0 = tcg_temp_new();
18888
18889            switch (sc) {
18890            case 0:
18891                if (rs == 1) {
18892                    /* DMT */
18893                    check_cp0_mt(ctx);
18894                    gen_helper_dmt(t0);
18895                    gen_store_gpr(t0, rt);
18896                } else if (rs == 0) {
18897                    /* DVPE */
18898                    check_cp0_mt(ctx);
18899                    gen_helper_dvpe(t0, cpu_env);
18900                    gen_store_gpr(t0, rt);
18901                } else {
18902                    generate_exception_end(ctx, EXCP_RI);
18903                }
18904                break;
18905            case 1:
18906                if (rs == 1) {
18907                    /* EMT */
18908                    check_cp0_mt(ctx);
18909                    gen_helper_emt(t0);
18910                    gen_store_gpr(t0, rt);
18911                } else if (rs == 0) {
18912                    /* EVPE */
18913                    check_cp0_mt(ctx);
18914                    gen_helper_evpe(t0, cpu_env);
18915                    gen_store_gpr(t0, rt);
18916                } else {
18917                    generate_exception_end(ctx, EXCP_RI);
18918                }
18919                break;
18920            }
18921
18922            tcg_temp_free(t0);
18923        }
18924        break;
18925    case NM_FORK:
18926        check_mt(ctx);
18927        {
18928            TCGv t0 = tcg_temp_new();
18929            TCGv t1 = tcg_temp_new();
18930
18931            gen_load_gpr(t0, rt);
18932            gen_load_gpr(t1, rs);
18933            gen_helper_fork(t0, t1);
18934            tcg_temp_free(t0);
18935            tcg_temp_free(t1);
18936        }
18937        break;
18938    case NM_MFTR:
18939    case NM_MFHTR:
18940        check_cp0_enabled(ctx);
18941        if (rd == 0) {
18942            /* Treat as NOP. */
18943            return;
18944        }
18945        gen_mftr(env, ctx, rs, rt, extract32(ctx->opcode, 10, 1),
18946                 extract32(ctx->opcode, 11, 5), extract32(ctx->opcode, 3, 1));
18947        break;
18948    case NM_MTTR:
18949    case NM_MTHTR:
18950        check_cp0_enabled(ctx);
18951        gen_mttr(env, ctx, rs, rt, extract32(ctx->opcode, 10, 1),
18952                 extract32(ctx->opcode, 11, 5), extract32(ctx->opcode, 3, 1));
18953        break;
18954    case NM_YIELD:
18955        check_mt(ctx);
18956        {
18957            TCGv t0 = tcg_temp_new();
18958
18959            gen_load_gpr(t0, rs);
18960            gen_helper_yield(t0, cpu_env, t0);
18961            gen_store_gpr(t0, rt);
18962            tcg_temp_free(t0);
18963        }
18964        break;
18965#endif
18966    default:
18967        generate_exception_end(ctx, EXCP_RI);
18968        break;
18969    }
18970}
18971
18972/* dsp */
18973static void gen_pool32axf_1_5_nanomips_insn(DisasContext *ctx, uint32_t opc,
18974                                            int ret, int v1, int v2)
18975{
18976    TCGv_i32 t0;
18977    TCGv v0_t;
18978    TCGv v1_t;
18979
18980    t0 = tcg_temp_new_i32();
18981
18982    v0_t = tcg_temp_new();
18983    v1_t = tcg_temp_new();
18984
18985    tcg_gen_movi_i32(t0, v2 >> 3);
18986
18987    gen_load_gpr(v0_t, ret);
18988    gen_load_gpr(v1_t, v1);
18989
18990    switch (opc) {
18991    case NM_MAQ_S_W_PHR:
18992        check_dsp(ctx);
18993        gen_helper_maq_s_w_phr(t0, v1_t, v0_t, cpu_env);
18994        break;
18995    case NM_MAQ_S_W_PHL:
18996        check_dsp(ctx);
18997        gen_helper_maq_s_w_phl(t0, v1_t, v0_t, cpu_env);
18998        break;
18999    case NM_MAQ_SA_W_PHR:
19000        check_dsp(ctx);
19001        gen_helper_maq_sa_w_phr(t0, v1_t, v0_t, cpu_env);
19002        break;
19003    case NM_MAQ_SA_W_PHL:
19004        check_dsp(ctx);
19005        gen_helper_maq_sa_w_phl(t0, v1_t, v0_t, cpu_env);
19006        break;
19007    default:
19008        generate_exception_end(ctx, EXCP_RI);
19009        break;
19010    }
19011
19012    tcg_temp_free_i32(t0);
19013
19014    tcg_temp_free(v0_t);
19015    tcg_temp_free(v1_t);
19016}
19017
19018
19019static void gen_pool32axf_1_nanomips_insn(DisasContext *ctx, uint32_t opc,
19020                                    int ret, int v1, int v2)
19021{
19022    int16_t imm;
19023    TCGv t0 = tcg_temp_new();
19024    TCGv t1 = tcg_temp_new();
19025    TCGv v0_t = tcg_temp_new();
19026
19027    gen_load_gpr(v0_t, v1);
19028
19029    switch (opc) {
19030    case NM_POOL32AXF_1_0:
19031        check_dsp(ctx);
19032        switch (extract32(ctx->opcode, 12, 2)) {
19033        case NM_MFHI:
19034            gen_HILO(ctx, OPC_MFHI, v2 >> 3, ret);
19035            break;
19036        case NM_MFLO:
19037            gen_HILO(ctx, OPC_MFLO, v2 >> 3, ret);
19038            break;
19039        case NM_MTHI:
19040            gen_HILO(ctx, OPC_MTHI, v2 >> 3, v1);
19041            break;
19042        case NM_MTLO:
19043            gen_HILO(ctx, OPC_MTLO, v2 >> 3, v1);
19044            break;
19045        }
19046        break;
19047    case NM_POOL32AXF_1_1:
19048        check_dsp(ctx);
19049        switch (extract32(ctx->opcode, 12, 2)) {
19050        case NM_MTHLIP:
19051            tcg_gen_movi_tl(t0, v2);
19052            gen_helper_mthlip(t0, v0_t, cpu_env);
19053            break;
19054        case NM_SHILOV:
19055            tcg_gen_movi_tl(t0, v2 >> 3);
19056            gen_helper_shilo(t0, v0_t, cpu_env);
19057            break;
19058        default:
19059            generate_exception_end(ctx, EXCP_RI);
19060            break;
19061        }
19062        break;
19063    case NM_POOL32AXF_1_3:
19064        check_dsp(ctx);
19065        imm = extract32(ctx->opcode, 14, 7);
19066        switch (extract32(ctx->opcode, 12, 2)) {
19067        case NM_RDDSP:
19068            tcg_gen_movi_tl(t0, imm);
19069            gen_helper_rddsp(t0, t0, cpu_env);
19070            gen_store_gpr(t0, ret);
19071            break;
19072        case NM_WRDSP:
19073            gen_load_gpr(t0, ret);
19074            tcg_gen_movi_tl(t1, imm);
19075            gen_helper_wrdsp(t0, t1, cpu_env);
19076            break;
19077        case NM_EXTP:
19078            tcg_gen_movi_tl(t0, v2 >> 3);
19079            tcg_gen_movi_tl(t1, v1);
19080            gen_helper_extp(t0, t0, t1, cpu_env);
19081            gen_store_gpr(t0, ret);
19082            break;
19083        case NM_EXTPDP:
19084            tcg_gen_movi_tl(t0, v2 >> 3);
19085            tcg_gen_movi_tl(t1, v1);
19086            gen_helper_extpdp(t0, t0, t1, cpu_env);
19087            gen_store_gpr(t0, ret);
19088            break;
19089        }
19090        break;
19091    case NM_POOL32AXF_1_4:
19092        check_dsp(ctx);
19093        tcg_gen_movi_tl(t0, v2 >> 2);
19094        switch (extract32(ctx->opcode, 12, 1)) {
19095        case NM_SHLL_QB:
19096            gen_helper_shll_qb(t0, t0, v0_t, cpu_env);
19097            gen_store_gpr(t0, ret);
19098            break;
19099        case NM_SHRL_QB:
19100            gen_helper_shrl_qb(t0, t0, v0_t);
19101            gen_store_gpr(t0, ret);
19102            break;
19103        }
19104        break;
19105    case NM_POOL32AXF_1_5:
19106        opc = extract32(ctx->opcode, 12, 2);
19107        gen_pool32axf_1_5_nanomips_insn(ctx, opc, ret, v1, v2);
19108        break;
19109    case NM_POOL32AXF_1_7:
19110        check_dsp(ctx);
19111        tcg_gen_movi_tl(t0, v2 >> 3);
19112        tcg_gen_movi_tl(t1, v1);
19113        switch (extract32(ctx->opcode, 12, 2)) {
19114        case NM_EXTR_W:
19115            gen_helper_extr_w(t0, t0, t1, cpu_env);
19116            gen_store_gpr(t0, ret);
19117            break;
19118        case NM_EXTR_R_W:
19119            gen_helper_extr_r_w(t0, t0, t1, cpu_env);
19120            gen_store_gpr(t0, ret);
19121            break;
19122        case NM_EXTR_RS_W:
19123            gen_helper_extr_rs_w(t0, t0, t1, cpu_env);
19124            gen_store_gpr(t0, ret);
19125            break;
19126        case NM_EXTR_S_H:
19127            gen_helper_extr_s_h(t0, t0, t1, cpu_env);
19128            gen_store_gpr(t0, ret);
19129            break;
19130        }
19131        break;
19132    default:
19133        generate_exception_end(ctx, EXCP_RI);
19134        break;
19135    }
19136
19137    tcg_temp_free(t0);
19138    tcg_temp_free(t1);
19139    tcg_temp_free(v0_t);
19140}
19141
19142static void gen_pool32axf_2_multiply(DisasContext *ctx, uint32_t opc,
19143                                    TCGv v0, TCGv v1, int rd)
19144{
19145    TCGv_i32 t0;
19146
19147    t0 = tcg_temp_new_i32();
19148
19149    tcg_gen_movi_i32(t0, rd >> 3);
19150
19151    switch (opc) {
19152    case NM_POOL32AXF_2_0_7:
19153        switch (extract32(ctx->opcode, 9, 3)) {
19154        case NM_DPA_W_PH:
19155            check_dsp_r2(ctx);
19156            gen_helper_dpa_w_ph(t0, v1, v0, cpu_env);
19157            break;
19158        case NM_DPAQ_S_W_PH:
19159            check_dsp(ctx);
19160            gen_helper_dpaq_s_w_ph(t0, v1, v0, cpu_env);
19161            break;
19162        case NM_DPS_W_PH:
19163            check_dsp_r2(ctx);
19164            gen_helper_dps_w_ph(t0, v1, v0, cpu_env);
19165            break;
19166        case NM_DPSQ_S_W_PH:
19167            check_dsp(ctx);
19168            gen_helper_dpsq_s_w_ph(t0, v1, v0, cpu_env);
19169            break;
19170        default:
19171            generate_exception_end(ctx, EXCP_RI);
19172            break;
19173        }
19174        break;
19175    case NM_POOL32AXF_2_8_15:
19176        switch (extract32(ctx->opcode, 9, 3)) {
19177        case NM_DPAX_W_PH:
19178            check_dsp_r2(ctx);
19179            gen_helper_dpax_w_ph(t0, v0, v1, cpu_env);
19180            break;
19181        case NM_DPAQ_SA_L_W:
19182            check_dsp(ctx);
19183            gen_helper_dpaq_sa_l_w(t0, v0, v1, cpu_env);
19184            break;
19185        case NM_DPSX_W_PH:
19186            check_dsp_r2(ctx);
19187            gen_helper_dpsx_w_ph(t0, v0, v1, cpu_env);
19188            break;
19189        case NM_DPSQ_SA_L_W:
19190            check_dsp(ctx);
19191            gen_helper_dpsq_sa_l_w(t0, v0, v1, cpu_env);
19192            break;
19193        default:
19194            generate_exception_end(ctx, EXCP_RI);
19195            break;
19196        }
19197        break;
19198    case NM_POOL32AXF_2_16_23:
19199        switch (extract32(ctx->opcode, 9, 3)) {
19200        case NM_DPAU_H_QBL:
19201            check_dsp(ctx);
19202            gen_helper_dpau_h_qbl(t0, v0, v1, cpu_env);
19203            break;
19204        case NM_DPAQX_S_W_PH:
19205            check_dsp_r2(ctx);
19206            gen_helper_dpaqx_s_w_ph(t0, v0, v1, cpu_env);
19207            break;
19208        case NM_DPSU_H_QBL:
19209            check_dsp(ctx);
19210            gen_helper_dpsu_h_qbl(t0, v0, v1, cpu_env);
19211            break;
19212        case NM_DPSQX_S_W_PH:
19213            check_dsp_r2(ctx);
19214            gen_helper_dpsqx_s_w_ph(t0, v0, v1, cpu_env);
19215            break;
19216        case NM_MULSA_W_PH:
19217            check_dsp_r2(ctx);
19218            gen_helper_mulsa_w_ph(t0, v0, v1, cpu_env);
19219            break;
19220        default:
19221            generate_exception_end(ctx, EXCP_RI);
19222            break;
19223        }
19224        break;
19225    case NM_POOL32AXF_2_24_31:
19226        switch (extract32(ctx->opcode, 9, 3)) {
19227        case NM_DPAU_H_QBR:
19228            check_dsp(ctx);
19229            gen_helper_dpau_h_qbr(t0, v1, v0, cpu_env);
19230            break;
19231        case NM_DPAQX_SA_W_PH:
19232            check_dsp_r2(ctx);
19233            gen_helper_dpaqx_sa_w_ph(t0, v1, v0, cpu_env);
19234            break;
19235        case NM_DPSU_H_QBR:
19236            check_dsp(ctx);
19237            gen_helper_dpsu_h_qbr(t0, v1, v0, cpu_env);
19238            break;
19239        case NM_DPSQX_SA_W_PH:
19240            check_dsp_r2(ctx);
19241            gen_helper_dpsqx_sa_w_ph(t0, v1, v0, cpu_env);
19242            break;
19243        case NM_MULSAQ_S_W_PH:
19244            check_dsp(ctx);
19245            gen_helper_mulsaq_s_w_ph(t0, v1, v0, cpu_env);
19246            break;
19247        default:
19248            generate_exception_end(ctx, EXCP_RI);
19249            break;
19250        }
19251        break;
19252    default:
19253        generate_exception_end(ctx, EXCP_RI);
19254        break;
19255    }
19256
19257    tcg_temp_free_i32(t0);
19258}
19259
19260static void gen_pool32axf_2_nanomips_insn(DisasContext *ctx, uint32_t opc,
19261                                          int rt, int rs, int rd)
19262{
19263    int ret = rt;
19264    TCGv t0 = tcg_temp_new();
19265    TCGv t1 = tcg_temp_new();
19266    TCGv v0_t = tcg_temp_new();
19267    TCGv v1_t = tcg_temp_new();
19268
19269    gen_load_gpr(v0_t, rt);
19270    gen_load_gpr(v1_t, rs);
19271
19272    switch (opc) {
19273    case NM_POOL32AXF_2_0_7:
19274        switch (extract32(ctx->opcode, 9, 3)) {
19275        case NM_DPA_W_PH:
19276        case NM_DPAQ_S_W_PH:
19277        case NM_DPS_W_PH:
19278        case NM_DPSQ_S_W_PH:
19279            gen_pool32axf_2_multiply(ctx, opc, v0_t, v1_t, rd);
19280            break;
19281        case NM_BALIGN:
19282            check_dsp_r2(ctx);
19283            if (rt != 0) {
19284                gen_load_gpr(t0, rs);
19285                rd &= 3;
19286                if (rd != 0 && rd != 2) {
19287                    tcg_gen_shli_tl(cpu_gpr[ret], cpu_gpr[ret], 8 * rd);
19288                    tcg_gen_ext32u_tl(t0, t0);
19289                    tcg_gen_shri_tl(t0, t0, 8 * (4 - rd));
19290                    tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
19291                }
19292                tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]);
19293            }
19294            break;
19295        case NM_MADD:
19296            check_dsp(ctx);
19297            {
19298                int acc = extract32(ctx->opcode, 14, 2);
19299                TCGv_i64 t2 = tcg_temp_new_i64();
19300                TCGv_i64 t3 = tcg_temp_new_i64();
19301
19302                gen_load_gpr(t0, rt);
19303                gen_load_gpr(t1, rs);
19304                tcg_gen_ext_tl_i64(t2, t0);
19305                tcg_gen_ext_tl_i64(t3, t1);
19306                tcg_gen_mul_i64(t2, t2, t3);
19307                tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
19308                tcg_gen_add_i64(t2, t2, t3);
19309                tcg_temp_free_i64(t3);
19310                gen_move_low32(cpu_LO[acc], t2);
19311                gen_move_high32(cpu_HI[acc], t2);
19312                tcg_temp_free_i64(t2);
19313            }
19314            break;
19315        case NM_MULT:
19316            check_dsp(ctx);
19317            {
19318                int acc = extract32(ctx->opcode, 14, 2);
19319                TCGv_i32 t2 = tcg_temp_new_i32();
19320                TCGv_i32 t3 = tcg_temp_new_i32();
19321
19322                gen_load_gpr(t0, rs);
19323                gen_load_gpr(t1, rt);
19324                tcg_gen_trunc_tl_i32(t2, t0);
19325                tcg_gen_trunc_tl_i32(t3, t1);
19326                tcg_gen_muls2_i32(t2, t3, t2, t3);
19327                tcg_gen_ext_i32_tl(cpu_LO[acc], t2);
19328                tcg_gen_ext_i32_tl(cpu_HI[acc], t3);
19329                tcg_temp_free_i32(t2);
19330                tcg_temp_free_i32(t3);
19331            }
19332            break;
19333        case NM_EXTRV_W:
19334            check_dsp(ctx);
19335            gen_load_gpr(v1_t, rs);
19336            tcg_gen_movi_tl(t0, rd >> 3);
19337            gen_helper_extr_w(t0, t0, v1_t, cpu_env);
19338            gen_store_gpr(t0, ret);
19339            break;
19340        }
19341        break;
19342    case NM_POOL32AXF_2_8_15:
19343        switch (extract32(ctx->opcode, 9, 3)) {
19344        case NM_DPAX_W_PH:
19345        case NM_DPAQ_SA_L_W:
19346        case NM_DPSX_W_PH:
19347        case NM_DPSQ_SA_L_W:
19348            gen_pool32axf_2_multiply(ctx, opc, v0_t, v1_t, rd);
19349            break;
19350        case NM_MADDU:
19351            check_dsp(ctx);
19352            {
19353                int acc = extract32(ctx->opcode, 14, 2);
19354                TCGv_i64 t2 = tcg_temp_new_i64();
19355                TCGv_i64 t3 = tcg_temp_new_i64();
19356
19357                gen_load_gpr(t0, rs);
19358                gen_load_gpr(t1, rt);
19359                tcg_gen_ext32u_tl(t0, t0);
19360                tcg_gen_ext32u_tl(t1, t1);
19361                tcg_gen_extu_tl_i64(t2, t0);
19362                tcg_gen_extu_tl_i64(t3, t1);
19363                tcg_gen_mul_i64(t2, t2, t3);
19364                tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
19365                tcg_gen_add_i64(t2, t2, t3);
19366                tcg_temp_free_i64(t3);
19367                gen_move_low32(cpu_LO[acc], t2);
19368                gen_move_high32(cpu_HI[acc], t2);
19369                tcg_temp_free_i64(t2);
19370            }
19371            break;
19372        case NM_MULTU:
19373            check_dsp(ctx);
19374            {
19375                int acc = extract32(ctx->opcode, 14, 2);
19376                TCGv_i32 t2 = tcg_temp_new_i32();
19377                TCGv_i32 t3 = tcg_temp_new_i32();
19378
19379                gen_load_gpr(t0, rs);
19380                gen_load_gpr(t1, rt);
19381                tcg_gen_trunc_tl_i32(t2, t0);
19382                tcg_gen_trunc_tl_i32(t3, t1);
19383                tcg_gen_mulu2_i32(t2, t3, t2, t3);
19384                tcg_gen_ext_i32_tl(cpu_LO[acc], t2);
19385                tcg_gen_ext_i32_tl(cpu_HI[acc], t3);
19386                tcg_temp_free_i32(t2);
19387                tcg_temp_free_i32(t3);
19388            }
19389            break;
19390        case NM_EXTRV_R_W:
19391            check_dsp(ctx);
19392            tcg_gen_movi_tl(t0, rd >> 3);
19393            gen_helper_extr_r_w(t0, t0, v1_t, cpu_env);
19394            gen_store_gpr(t0, ret);
19395            break;
19396        default:
19397            generate_exception_end(ctx, EXCP_RI);
19398            break;
19399        }
19400        break;
19401    case NM_POOL32AXF_2_16_23:
19402        switch (extract32(ctx->opcode, 9, 3)) {
19403        case NM_DPAU_H_QBL:
19404        case NM_DPAQX_S_W_PH:
19405        case NM_DPSU_H_QBL:
19406        case NM_DPSQX_S_W_PH:
19407        case NM_MULSA_W_PH:
19408            gen_pool32axf_2_multiply(ctx, opc, v0_t, v1_t, rd);
19409            break;
19410        case NM_EXTPV:
19411            check_dsp(ctx);
19412            tcg_gen_movi_tl(t0, rd >> 3);
19413            gen_helper_extp(t0, t0, v1_t, cpu_env);
19414            gen_store_gpr(t0, ret);
19415            break;
19416        case NM_MSUB:
19417            check_dsp(ctx);
19418            {
19419                int acc = extract32(ctx->opcode, 14, 2);
19420                TCGv_i64 t2 = tcg_temp_new_i64();
19421                TCGv_i64 t3 = tcg_temp_new_i64();
19422
19423                gen_load_gpr(t0, rs);
19424                gen_load_gpr(t1, rt);
19425                tcg_gen_ext_tl_i64(t2, t0);
19426                tcg_gen_ext_tl_i64(t3, t1);
19427                tcg_gen_mul_i64(t2, t2, t3);
19428                tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
19429                tcg_gen_sub_i64(t2, t3, t2);
19430                tcg_temp_free_i64(t3);
19431                gen_move_low32(cpu_LO[acc], t2);
19432                gen_move_high32(cpu_HI[acc], t2);
19433                tcg_temp_free_i64(t2);
19434            }
19435            break;
19436        case NM_EXTRV_RS_W:
19437            check_dsp(ctx);
19438            tcg_gen_movi_tl(t0, rd >> 3);
19439            gen_helper_extr_rs_w(t0, t0, v1_t, cpu_env);
19440            gen_store_gpr(t0, ret);
19441            break;
19442        }
19443        break;
19444    case NM_POOL32AXF_2_24_31:
19445        switch (extract32(ctx->opcode, 9, 3)) {
19446        case NM_DPAU_H_QBR:
19447        case NM_DPAQX_SA_W_PH:
19448        case NM_DPSU_H_QBR:
19449        case NM_DPSQX_SA_W_PH:
19450        case NM_MULSAQ_S_W_PH:
19451            gen_pool32axf_2_multiply(ctx, opc, v0_t, v1_t, rd);
19452            break;
19453        case NM_EXTPDPV:
19454            check_dsp(ctx);
19455            tcg_gen_movi_tl(t0, rd >> 3);
19456            gen_helper_extpdp(t0, t0, v1_t, cpu_env);
19457            gen_store_gpr(t0, ret);
19458            break;
19459        case NM_MSUBU:
19460            check_dsp(ctx);
19461            {
19462                int acc = extract32(ctx->opcode, 14, 2);
19463                TCGv_i64 t2 = tcg_temp_new_i64();
19464                TCGv_i64 t3 = tcg_temp_new_i64();
19465
19466                gen_load_gpr(t0, rs);
19467                gen_load_gpr(t1, rt);
19468                tcg_gen_ext32u_tl(t0, t0);
19469                tcg_gen_ext32u_tl(t1, t1);
19470                tcg_gen_extu_tl_i64(t2, t0);
19471                tcg_gen_extu_tl_i64(t3, t1);
19472                tcg_gen_mul_i64(t2, t2, t3);
19473                tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
19474                tcg_gen_sub_i64(t2, t3, t2);
19475                tcg_temp_free_i64(t3);
19476                gen_move_low32(cpu_LO[acc], t2);
19477                gen_move_high32(cpu_HI[acc], t2);
19478                tcg_temp_free_i64(t2);
19479            }
19480            break;
19481        case NM_EXTRV_S_H:
19482            check_dsp(ctx);
19483            tcg_gen_movi_tl(t0, rd >> 3);
19484            gen_helper_extr_s_h(t0, t0, v0_t, cpu_env);
19485            gen_store_gpr(t0, ret);
19486            break;
19487        }
19488        break;
19489    default:
19490        generate_exception_end(ctx, EXCP_RI);
19491        break;
19492    }
19493
19494    tcg_temp_free(t0);
19495    tcg_temp_free(t1);
19496
19497    tcg_temp_free(v0_t);
19498    tcg_temp_free(v1_t);
19499}
19500
19501static void gen_pool32axf_4_nanomips_insn(DisasContext *ctx, uint32_t opc,
19502                                          int rt, int rs)
19503{
19504    int ret = rt;
19505    TCGv t0 = tcg_temp_new();
19506    TCGv v0_t = tcg_temp_new();
19507
19508    gen_load_gpr(v0_t, rs);
19509
19510    switch (opc) {
19511    case NM_ABSQ_S_QB:
19512        check_dsp_r2(ctx);
19513        gen_helper_absq_s_qb(v0_t, v0_t, cpu_env);
19514        gen_store_gpr(v0_t, ret);
19515        break;
19516    case NM_ABSQ_S_PH:
19517        check_dsp(ctx);
19518        gen_helper_absq_s_ph(v0_t, v0_t, cpu_env);
19519        gen_store_gpr(v0_t, ret);
19520        break;
19521    case NM_ABSQ_S_W:
19522        check_dsp(ctx);
19523        gen_helper_absq_s_w(v0_t, v0_t, cpu_env);
19524        gen_store_gpr(v0_t, ret);
19525        break;
19526    case NM_PRECEQ_W_PHL:
19527        check_dsp(ctx);
19528        tcg_gen_andi_tl(v0_t, v0_t, 0xFFFF0000);
19529        tcg_gen_ext32s_tl(v0_t, v0_t);
19530        gen_store_gpr(v0_t, ret);
19531        break;
19532    case NM_PRECEQ_W_PHR:
19533        check_dsp(ctx);
19534        tcg_gen_andi_tl(v0_t, v0_t, 0x0000FFFF);
19535        tcg_gen_shli_tl(v0_t, v0_t, 16);
19536        tcg_gen_ext32s_tl(v0_t, v0_t);
19537        gen_store_gpr(v0_t, ret);
19538        break;
19539    case NM_PRECEQU_PH_QBL:
19540        check_dsp(ctx);
19541        gen_helper_precequ_ph_qbl(v0_t, v0_t);
19542        gen_store_gpr(v0_t, ret);
19543        break;
19544    case NM_PRECEQU_PH_QBR:
19545        check_dsp(ctx);
19546        gen_helper_precequ_ph_qbr(v0_t, v0_t);
19547        gen_store_gpr(v0_t, ret);
19548        break;
19549    case NM_PRECEQU_PH_QBLA:
19550        check_dsp(ctx);
19551        gen_helper_precequ_ph_qbla(v0_t, v0_t);
19552        gen_store_gpr(v0_t, ret);
19553        break;
19554    case NM_PRECEQU_PH_QBRA:
19555        check_dsp(ctx);
19556        gen_helper_precequ_ph_qbra(v0_t, v0_t);
19557        gen_store_gpr(v0_t, ret);
19558        break;
19559    case NM_PRECEU_PH_QBL:
19560        check_dsp(ctx);
19561        gen_helper_preceu_ph_qbl(v0_t, v0_t);
19562        gen_store_gpr(v0_t, ret);
19563        break;
19564    case NM_PRECEU_PH_QBR:
19565        check_dsp(ctx);
19566        gen_helper_preceu_ph_qbr(v0_t, v0_t);
19567        gen_store_gpr(v0_t, ret);
19568        break;
19569    case NM_PRECEU_PH_QBLA:
19570        check_dsp(ctx);
19571        gen_helper_preceu_ph_qbla(v0_t, v0_t);
19572        gen_store_gpr(v0_t, ret);
19573        break;
19574    case NM_PRECEU_PH_QBRA:
19575        check_dsp(ctx);
19576        gen_helper_preceu_ph_qbra(v0_t, v0_t);
19577        gen_store_gpr(v0_t, ret);
19578        break;
19579    case NM_REPLV_PH:
19580        check_dsp(ctx);
19581        tcg_gen_ext16u_tl(v0_t, v0_t);
19582        tcg_gen_shli_tl(t0, v0_t, 16);
19583        tcg_gen_or_tl(v0_t, v0_t, t0);
19584        tcg_gen_ext32s_tl(v0_t, v0_t);
19585        gen_store_gpr(v0_t, ret);
19586        break;
19587    case NM_REPLV_QB:
19588        check_dsp(ctx);
19589        tcg_gen_ext8u_tl(v0_t, v0_t);
19590        tcg_gen_shli_tl(t0, v0_t, 8);
19591        tcg_gen_or_tl(v0_t, v0_t, t0);
19592        tcg_gen_shli_tl(t0, v0_t, 16);
19593        tcg_gen_or_tl(v0_t, v0_t, t0);
19594        tcg_gen_ext32s_tl(v0_t, v0_t);
19595        gen_store_gpr(v0_t, ret);
19596        break;
19597    case NM_BITREV:
19598        check_dsp(ctx);
19599        gen_helper_bitrev(v0_t, v0_t);
19600        gen_store_gpr(v0_t, ret);
19601        break;
19602    case NM_INSV:
19603        check_dsp(ctx);
19604        {
19605            TCGv tv0 = tcg_temp_new();
19606
19607            gen_load_gpr(tv0, rt);
19608            gen_helper_insv(v0_t, cpu_env, v0_t, tv0);
19609            gen_store_gpr(v0_t, ret);
19610            tcg_temp_free(tv0);
19611        }
19612        break;
19613    case NM_RADDU_W_QB:
19614        check_dsp(ctx);
19615        gen_helper_raddu_w_qb(v0_t, v0_t);
19616        gen_store_gpr(v0_t, ret);
19617        break;
19618    case NM_BITSWAP:
19619        gen_bitswap(ctx, OPC_BITSWAP, ret, rs);
19620        break;
19621    case NM_CLO:
19622        check_nms(ctx);
19623        gen_cl(ctx, OPC_CLO, ret, rs);
19624        break;
19625    case NM_CLZ:
19626        check_nms(ctx);
19627        gen_cl(ctx, OPC_CLZ, ret, rs);
19628        break;
19629    case NM_WSBH:
19630        gen_bshfl(ctx, OPC_WSBH, ret, rs);
19631        break;
19632    default:
19633        generate_exception_end(ctx, EXCP_RI);
19634        break;
19635    }
19636
19637    tcg_temp_free(v0_t);
19638    tcg_temp_free(t0);
19639}
19640
19641static void gen_pool32axf_7_nanomips_insn(DisasContext *ctx, uint32_t opc,
19642                                          int rt, int rs, int rd)
19643{
19644    TCGv t0 = tcg_temp_new();
19645    TCGv rs_t = tcg_temp_new();
19646
19647    gen_load_gpr(rs_t, rs);
19648
19649    switch (opc) {
19650    case NM_SHRA_R_QB:
19651        check_dsp_r2(ctx);
19652        tcg_gen_movi_tl(t0, rd >> 2);
19653        switch (extract32(ctx->opcode, 12, 1)) {
19654        case 0:
19655            /* NM_SHRA_QB */
19656            gen_helper_shra_qb(t0, t0, rs_t);
19657            gen_store_gpr(t0, rt);
19658            break;
19659        case 1:
19660            /* NM_SHRA_R_QB */
19661            gen_helper_shra_r_qb(t0, t0, rs_t);
19662            gen_store_gpr(t0, rt);
19663            break;
19664        }
19665        break;
19666    case NM_SHRL_PH:
19667        check_dsp_r2(ctx);
19668        tcg_gen_movi_tl(t0, rd >> 1);
19669        gen_helper_shrl_ph(t0, t0, rs_t);
19670        gen_store_gpr(t0, rt);
19671        break;
19672    case NM_REPL_QB:
19673        check_dsp(ctx);
19674        {
19675            int16_t imm;
19676            target_long result;
19677            imm = extract32(ctx->opcode, 13, 8);
19678            result = (uint32_t)imm << 24 |
19679                     (uint32_t)imm << 16 |
19680                     (uint32_t)imm << 8  |
19681                     (uint32_t)imm;
19682            result = (int32_t)result;
19683            tcg_gen_movi_tl(t0, result);
19684            gen_store_gpr(t0, rt);
19685        }
19686        break;
19687    default:
19688        generate_exception_end(ctx, EXCP_RI);
19689        break;
19690    }
19691    tcg_temp_free(t0);
19692    tcg_temp_free(rs_t);
19693}
19694
19695
19696static void gen_pool32axf_nanomips_insn(CPUMIPSState *env, DisasContext *ctx)
19697{
19698    int rt = extract32(ctx->opcode, 21, 5);
19699    int rs = extract32(ctx->opcode, 16, 5);
19700    int rd = extract32(ctx->opcode, 11, 5);
19701
19702    switch (extract32(ctx->opcode, 6, 3)) {
19703    case NM_POOL32AXF_1:
19704        {
19705            int32_t op1 = extract32(ctx->opcode, 9, 3);
19706            gen_pool32axf_1_nanomips_insn(ctx, op1, rt, rs, rd);
19707        }
19708        break;
19709    case NM_POOL32AXF_2:
19710        {
19711            int32_t op1 = extract32(ctx->opcode, 12, 2);
19712            gen_pool32axf_2_nanomips_insn(ctx, op1, rt, rs, rd);
19713        }
19714        break;
19715    case NM_POOL32AXF_4:
19716        {
19717            int32_t op1 = extract32(ctx->opcode, 9, 7);
19718            gen_pool32axf_4_nanomips_insn(ctx, op1, rt, rs);
19719        }
19720        break;
19721    case NM_POOL32AXF_5:
19722        switch (extract32(ctx->opcode, 9, 7)) {
19723#ifndef CONFIG_USER_ONLY
19724        case NM_TLBP:
19725            gen_cp0(env, ctx, OPC_TLBP, 0, 0);
19726            break;
19727        case NM_TLBR:
19728            gen_cp0(env, ctx, OPC_TLBR, 0, 0);
19729            break;
19730        case NM_TLBWI:
19731            gen_cp0(env, ctx, OPC_TLBWI, 0, 0);
19732            break;
19733        case NM_TLBWR:
19734            gen_cp0(env, ctx, OPC_TLBWR, 0, 0);
19735            break;
19736        case NM_TLBINV:
19737            gen_cp0(env, ctx, OPC_TLBINV, 0, 0);
19738            break;
19739        case NM_TLBINVF:
19740            gen_cp0(env, ctx, OPC_TLBINVF, 0, 0);
19741            break;
19742        case NM_DI:
19743            check_cp0_enabled(ctx);
19744            {
19745                TCGv t0 = tcg_temp_new();
19746
19747                save_cpu_state(ctx, 1);
19748                gen_helper_di(t0, cpu_env);
19749                gen_store_gpr(t0, rt);
19750            /* Stop translation as we may have switched the execution mode */
19751                ctx->base.is_jmp = DISAS_STOP;
19752                tcg_temp_free(t0);
19753            }
19754            break;
19755        case NM_EI:
19756            check_cp0_enabled(ctx);
19757            {
19758                TCGv t0 = tcg_temp_new();
19759
19760                save_cpu_state(ctx, 1);
19761                gen_helper_ei(t0, cpu_env);
19762                gen_store_gpr(t0, rt);
19763            /* Stop translation as we may have switched the execution mode */
19764                ctx->base.is_jmp = DISAS_STOP;
19765                tcg_temp_free(t0);
19766            }
19767            break;
19768        case NM_RDPGPR:
19769            gen_load_srsgpr(rs, rt);
19770            break;
19771        case NM_WRPGPR:
19772            gen_store_srsgpr(rs, rt);
19773            break;
19774        case NM_WAIT:
19775            gen_cp0(env, ctx, OPC_WAIT, 0, 0);
19776            break;
19777        case NM_DERET:
19778            gen_cp0(env, ctx, OPC_DERET, 0, 0);
19779            break;
19780        case NM_ERETX:
19781            gen_cp0(env, ctx, OPC_ERET, 0, 0);
19782            break;
19783#endif
19784        default:
19785            generate_exception_end(ctx, EXCP_RI);
19786            break;
19787        }
19788        break;
19789    case NM_POOL32AXF_7:
19790        {
19791            int32_t op1 = extract32(ctx->opcode, 9, 3);
19792            gen_pool32axf_7_nanomips_insn(ctx, op1, rt, rs, rd);
19793        }
19794        break;
19795    default:
19796        generate_exception_end(ctx, EXCP_RI);
19797        break;
19798    }
19799}
19800
19801/* Immediate Value Compact Branches */
19802static void gen_compute_imm_branch(DisasContext *ctx, uint32_t opc,
19803                                   int rt, int32_t imm, int32_t offset)
19804{
19805    TCGCond cond;
19806    int bcond_compute = 0;
19807    TCGv t0 = tcg_temp_new();
19808    TCGv t1 = tcg_temp_new();
19809
19810    gen_load_gpr(t0, rt);
19811    tcg_gen_movi_tl(t1, imm);
19812    ctx->btarget = addr_add(ctx, ctx->base.pc_next + 4, offset);
19813
19814    /* Load needed operands and calculate btarget */
19815    switch (opc) {
19816    case NM_BEQIC:
19817        if (rt == 0 && imm == 0) {
19818            /* Unconditional branch */
19819        } else if (rt == 0 && imm != 0) {
19820            /* Treat as NOP */
19821            goto out;
19822        } else {
19823            bcond_compute = 1;
19824            cond = TCG_COND_EQ;
19825        }
19826        break;
19827    case NM_BBEQZC:
19828    case NM_BBNEZC:
19829        check_nms(ctx);
19830        if (imm >= 32 && !(ctx->hflags & MIPS_HFLAG_64)) {
19831            generate_exception_end(ctx, EXCP_RI);
19832            goto out;
19833        } else if (rt == 0 && opc == NM_BBEQZC) {
19834            /* Unconditional branch */
19835        } else if (rt == 0 && opc == NM_BBNEZC) {
19836            /* Treat as NOP */
19837            goto out;
19838        } else {
19839            tcg_gen_shri_tl(t0, t0, imm);
19840            tcg_gen_andi_tl(t0, t0, 1);
19841            tcg_gen_movi_tl(t1, 0);
19842            bcond_compute = 1;
19843            if (opc == NM_BBEQZC) {
19844                cond = TCG_COND_EQ;
19845            } else {
19846                cond = TCG_COND_NE;
19847            }
19848        }
19849        break;
19850    case NM_BNEIC:
19851        if (rt == 0 && imm == 0) {
19852            /* Treat as NOP */
19853            goto out;
19854        } else if (rt == 0 && imm != 0) {
19855            /* Unconditional branch */
19856        } else {
19857            bcond_compute = 1;
19858            cond = TCG_COND_NE;
19859        }
19860        break;
19861    case NM_BGEIC:
19862        if (rt == 0 && imm == 0) {
19863            /* Unconditional branch */
19864        } else  {
19865            bcond_compute = 1;
19866            cond = TCG_COND_GE;
19867        }
19868        break;
19869    case NM_BLTIC:
19870        bcond_compute = 1;
19871        cond = TCG_COND_LT;
19872        break;
19873    case NM_BGEIUC:
19874        if (rt == 0 && imm == 0) {
19875            /* Unconditional branch */
19876        } else  {
19877            bcond_compute = 1;
19878            cond = TCG_COND_GEU;
19879        }
19880        break;
19881    case NM_BLTIUC:
19882        bcond_compute = 1;
19883        cond = TCG_COND_LTU;
19884        break;
19885    default:
19886        MIPS_INVAL("Immediate Value Compact branch");
19887        generate_exception_end(ctx, EXCP_RI);
19888        goto out;
19889    }
19890
19891    /* branch completion */
19892    clear_branch_hflags(ctx);
19893    ctx->base.is_jmp = DISAS_NORETURN;
19894
19895    if (bcond_compute == 0) {
19896        /* Uncoditional compact branch */
19897        gen_goto_tb(ctx, 0, ctx->btarget);
19898    } else {
19899        /* Conditional compact branch */
19900        TCGLabel *fs = gen_new_label();
19901
19902        tcg_gen_brcond_tl(tcg_invert_cond(cond), t0, t1, fs);
19903
19904        gen_goto_tb(ctx, 1, ctx->btarget);
19905        gen_set_label(fs);
19906
19907        gen_goto_tb(ctx, 0, ctx->base.pc_next + 4);
19908    }
19909
19910out:
19911    tcg_temp_free(t0);
19912    tcg_temp_free(t1);
19913}
19914
19915/* P.BALRSC type nanoMIPS R6 branches: BALRSC and BRSC */
19916static void gen_compute_nanomips_pbalrsc_branch(DisasContext *ctx, int rs,
19917                                                int rt)
19918{
19919    TCGv t0 = tcg_temp_new();
19920    TCGv t1 = tcg_temp_new();
19921
19922    /* load rs */
19923    gen_load_gpr(t0, rs);
19924
19925    /* link */
19926    if (rt != 0) {
19927        tcg_gen_movi_tl(cpu_gpr[rt], ctx->base.pc_next + 4);
19928    }
19929
19930    /* calculate btarget */
19931    tcg_gen_shli_tl(t0, t0, 1);
19932    tcg_gen_movi_tl(t1, ctx->base.pc_next + 4);
19933    gen_op_addr_add(ctx, btarget, t1, t0);
19934
19935    /* branch completion */
19936    clear_branch_hflags(ctx);
19937    ctx->base.is_jmp = DISAS_NORETURN;
19938
19939    /* unconditional branch to register */
19940    tcg_gen_mov_tl(cpu_PC, btarget);
19941    tcg_gen_lookup_and_goto_ptr();
19942
19943    tcg_temp_free(t0);
19944    tcg_temp_free(t1);
19945}
19946
19947/* nanoMIPS Branches */
19948static void gen_compute_compact_branch_nm(DisasContext *ctx, uint32_t opc,
19949                                       int rs, int rt, int32_t offset)
19950{
19951    int bcond_compute = 0;
19952    TCGv t0 = tcg_temp_new();
19953    TCGv t1 = tcg_temp_new();
19954
19955    /* Load needed operands and calculate btarget */
19956    switch (opc) {
19957    /* compact branch */
19958    case OPC_BGEC:
19959    case OPC_BLTC:
19960        gen_load_gpr(t0, rs);
19961        gen_load_gpr(t1, rt);
19962        bcond_compute = 1;
19963        ctx->btarget = addr_add(ctx, ctx->base.pc_next + 4, offset);
19964        break;
19965    case OPC_BGEUC:
19966    case OPC_BLTUC:
19967        if (rs == 0 || rs == rt) {
19968            /* OPC_BLEZALC, OPC_BGEZALC */
19969            /* OPC_BGTZALC, OPC_BLTZALC */
19970            tcg_gen_movi_tl(cpu_gpr[31], ctx->base.pc_next + 4);
19971        }
19972        gen_load_gpr(t0, rs);
19973        gen_load_gpr(t1, rt);
19974        bcond_compute = 1;
19975        ctx->btarget = addr_add(ctx, ctx->base.pc_next + 4, offset);
19976        break;
19977    case OPC_BC:
19978        ctx->btarget = addr_add(ctx, ctx->base.pc_next + 4, offset);
19979        break;
19980    case OPC_BEQZC:
19981        if (rs != 0) {
19982            /* OPC_BEQZC, OPC_BNEZC */
19983            gen_load_gpr(t0, rs);
19984            bcond_compute = 1;
19985            ctx->btarget = addr_add(ctx, ctx->base.pc_next + 4, offset);
19986        } else {
19987            /* OPC_JIC, OPC_JIALC */
19988            TCGv tbase = tcg_temp_new();
19989            TCGv toffset = tcg_temp_new();
19990
19991            gen_load_gpr(tbase, rt);
19992            tcg_gen_movi_tl(toffset, offset);
19993            gen_op_addr_add(ctx, btarget, tbase, toffset);
19994            tcg_temp_free(tbase);
19995            tcg_temp_free(toffset);
19996        }
19997        break;
19998    default:
19999        MIPS_INVAL("Compact branch/jump");
20000        generate_exception_end(ctx, EXCP_RI);
20001        goto out;
20002    }
20003
20004    if (bcond_compute == 0) {
20005        /* Uncoditional compact branch */
20006        switch (opc) {
20007        case OPC_BC:
20008            gen_goto_tb(ctx, 0, ctx->btarget);
20009            break;
20010        default:
20011            MIPS_INVAL("Compact branch/jump");
20012            generate_exception_end(ctx, EXCP_RI);
20013            goto out;
20014        }
20015    } else {
20016        /* Conditional compact branch */
20017        TCGLabel *fs = gen_new_label();
20018
20019        switch (opc) {
20020        case OPC_BGEUC:
20021            if (rs == 0 && rt != 0) {
20022                /* OPC_BLEZALC */
20023                tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LE), t1, 0, fs);
20024            } else if (rs != 0 && rt != 0 && rs == rt) {
20025                /* OPC_BGEZALC */
20026                tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GE), t1, 0, fs);
20027            } else {
20028                /* OPC_BGEUC */
20029                tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_GEU), t0, t1, fs);
20030            }
20031            break;
20032        case OPC_BLTUC:
20033            if (rs == 0 && rt != 0) {
20034                /* OPC_BGTZALC */
20035                tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GT), t1, 0, fs);
20036            } else if (rs != 0 && rt != 0 && rs == rt) {
20037                /* OPC_BLTZALC */
20038                tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LT), t1, 0, fs);
20039            } else {
20040                /* OPC_BLTUC */
20041                tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_LTU), t0, t1, fs);
20042            }
20043            break;
20044        case OPC_BGEC:
20045            if (rs == 0 && rt != 0) {
20046                /* OPC_BLEZC */
20047                tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LE), t1, 0, fs);
20048            } else if (rs != 0 && rt != 0 && rs == rt) {
20049                /* OPC_BGEZC */
20050                tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GE), t1, 0, fs);
20051            } else {
20052                /* OPC_BGEC */
20053                tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_GE), t0, t1, fs);
20054            }
20055            break;
20056        case OPC_BLTC:
20057            if (rs == 0 && rt != 0) {
20058                /* OPC_BGTZC */
20059                tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GT), t1, 0, fs);
20060            } else if (rs != 0 && rt != 0 && rs == rt) {
20061                /* OPC_BLTZC */
20062                tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LT), t1, 0, fs);
20063            } else {
20064                /* OPC_BLTC */
20065                tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_LT), t0, t1, fs);
20066            }
20067            break;
20068        case OPC_BEQZC:
20069            tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_EQ), t0, 0, fs);
20070            break;
20071        default:
20072            MIPS_INVAL("Compact conditional branch/jump");
20073            generate_exception_end(ctx, EXCP_RI);
20074            goto out;
20075        }
20076
20077        /* branch completion */
20078        clear_branch_hflags(ctx);
20079        ctx->base.is_jmp = DISAS_NORETURN;
20080
20081        /* Generating branch here as compact branches don't have delay slot */
20082        gen_goto_tb(ctx, 1, ctx->btarget);
20083        gen_set_label(fs);
20084
20085        gen_goto_tb(ctx, 0, ctx->base.pc_next + 4);
20086    }
20087
20088out:
20089    tcg_temp_free(t0);
20090    tcg_temp_free(t1);
20091}
20092
20093
20094/* nanoMIPS CP1 Branches */
20095static void gen_compute_branch_cp1_nm(DisasContext *ctx, uint32_t op,
20096                                   int32_t ft, int32_t offset)
20097{
20098    target_ulong btarget;
20099    TCGv_i64 t0 = tcg_temp_new_i64();
20100
20101    gen_load_fpr64(ctx, t0, ft);
20102    tcg_gen_andi_i64(t0, t0, 1);
20103
20104    btarget = addr_add(ctx, ctx->base.pc_next + 4, offset);
20105
20106    switch (op) {
20107    case NM_BC1EQZC:
20108        tcg_gen_xori_i64(t0, t0, 1);
20109        ctx->hflags |= MIPS_HFLAG_BC;
20110        break;
20111    case NM_BC1NEZC:
20112        /* t0 already set */
20113        ctx->hflags |= MIPS_HFLAG_BC;
20114        break;
20115    default:
20116        MIPS_INVAL("cp1 cond branch");
20117        generate_exception_end(ctx, EXCP_RI);
20118        goto out;
20119    }
20120
20121    tcg_gen_trunc_i64_tl(bcond, t0);
20122
20123    ctx->btarget = btarget;
20124
20125out:
20126    tcg_temp_free_i64(t0);
20127}
20128
20129
20130static void gen_p_lsx(DisasContext *ctx, int rd, int rs, int rt)
20131{
20132    TCGv t0, t1;
20133    t0 = tcg_temp_new();
20134    t1 = tcg_temp_new();
20135
20136    gen_load_gpr(t0, rs);
20137    gen_load_gpr(t1, rt);
20138
20139    if ((extract32(ctx->opcode, 6, 1)) == 1) {
20140        /* PP.LSXS instructions require shifting */
20141        switch (extract32(ctx->opcode, 7, 4)) {
20142        case NM_SHXS:
20143            check_nms(ctx);
20144            /* fall through */
20145        case NM_LHXS:
20146        case NM_LHUXS:
20147            tcg_gen_shli_tl(t0, t0, 1);
20148            break;
20149        case NM_SWXS:
20150            check_nms(ctx);
20151            /* fall through */
20152        case NM_LWXS:
20153        case NM_LWC1XS:
20154        case NM_SWC1XS:
20155            tcg_gen_shli_tl(t0, t0, 2);
20156            break;
20157        case NM_LDC1XS:
20158        case NM_SDC1XS:
20159            tcg_gen_shli_tl(t0, t0, 3);
20160            break;
20161        }
20162    }
20163    gen_op_addr_add(ctx, t0, t0, t1);
20164
20165    switch (extract32(ctx->opcode, 7, 4)) {
20166    case NM_LBX:
20167        tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx,
20168                           MO_SB);
20169        gen_store_gpr(t0, rd);
20170        break;
20171    case NM_LHX:
20172    /*case NM_LHXS:*/
20173        tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx,
20174                           MO_TESW);
20175        gen_store_gpr(t0, rd);
20176        break;
20177    case NM_LWX:
20178    /*case NM_LWXS:*/
20179        tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx,
20180                           MO_TESL);
20181        gen_store_gpr(t0, rd);
20182        break;
20183    case NM_LBUX:
20184        tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx,
20185                           MO_UB);
20186        gen_store_gpr(t0, rd);
20187        break;
20188    case NM_LHUX:
20189    /*case NM_LHUXS:*/
20190        tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx,
20191                           MO_TEUW);
20192        gen_store_gpr(t0, rd);
20193        break;
20194    case NM_SBX:
20195        check_nms(ctx);
20196        gen_load_gpr(t1, rd);
20197        tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx,
20198                           MO_8);
20199        break;
20200    case NM_SHX:
20201    /*case NM_SHXS:*/
20202        check_nms(ctx);
20203        gen_load_gpr(t1, rd);
20204        tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx,
20205                           MO_TEUW);
20206        break;
20207    case NM_SWX:
20208    /*case NM_SWXS:*/
20209        check_nms(ctx);
20210        gen_load_gpr(t1, rd);
20211        tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx,
20212                           MO_TEUL);
20213        break;
20214    case NM_LWC1X:
20215    /*case NM_LWC1XS:*/
20216    case NM_LDC1X:
20217    /*case NM_LDC1XS:*/
20218    case NM_SWC1X:
20219    /*case NM_SWC1XS:*/
20220    case NM_SDC1X:
20221    /*case NM_SDC1XS:*/
20222        if (ctx->CP0_Config1 & (1 << CP0C1_FP)) {
20223            check_cp1_enabled(ctx);
20224            switch (extract32(ctx->opcode, 7, 4)) {
20225            case NM_LWC1X:
20226            /*case NM_LWC1XS:*/
20227                gen_flt_ldst(ctx, OPC_LWC1, rd, t0);
20228                break;
20229            case NM_LDC1X:
20230            /*case NM_LDC1XS:*/
20231                gen_flt_ldst(ctx, OPC_LDC1, rd, t0);
20232                break;
20233            case NM_SWC1X:
20234            /*case NM_SWC1XS:*/
20235                gen_flt_ldst(ctx, OPC_SWC1, rd, t0);
20236                break;
20237            case NM_SDC1X:
20238            /*case NM_SDC1XS:*/
20239                gen_flt_ldst(ctx, OPC_SDC1, rd, t0);
20240                break;
20241            }
20242        } else {
20243            generate_exception_err(ctx, EXCP_CpU, 1);
20244        }
20245        break;
20246    default:
20247        generate_exception_end(ctx, EXCP_RI);
20248        break;
20249    }
20250
20251    tcg_temp_free(t0);
20252    tcg_temp_free(t1);
20253}
20254
20255static void gen_pool32f_nanomips_insn(DisasContext *ctx)
20256{
20257    int rt, rs, rd;
20258
20259    rt = extract32(ctx->opcode, 21, 5);
20260    rs = extract32(ctx->opcode, 16, 5);
20261    rd = extract32(ctx->opcode, 11, 5);
20262
20263    if (!(ctx->CP0_Config1 & (1 << CP0C1_FP))) {
20264        generate_exception_end(ctx, EXCP_RI);
20265        return;
20266    }
20267    check_cp1_enabled(ctx);
20268    switch (extract32(ctx->opcode, 0, 3)) {
20269    case NM_POOL32F_0:
20270        switch (extract32(ctx->opcode, 3, 7)) {
20271        case NM_RINT_S:
20272            gen_farith(ctx, OPC_RINT_S, 0, rt, rs, 0);
20273            break;
20274        case NM_RINT_D:
20275            gen_farith(ctx, OPC_RINT_D, 0, rt, rs, 0);
20276            break;
20277        case NM_CLASS_S:
20278            gen_farith(ctx, OPC_CLASS_S, 0, rt, rs, 0);
20279            break;
20280        case NM_CLASS_D:
20281            gen_farith(ctx, OPC_CLASS_D, 0, rt, rs, 0);
20282            break;
20283        case NM_ADD_S:
20284            gen_farith(ctx, OPC_ADD_S, rt, rs, rd, 0);
20285            break;
20286        case NM_ADD_D:
20287            gen_farith(ctx, OPC_ADD_D, rt, rs, rd, 0);
20288            break;
20289        case NM_SUB_S:
20290            gen_farith(ctx, OPC_SUB_S, rt, rs, rd, 0);
20291            break;
20292        case NM_SUB_D:
20293            gen_farith(ctx, OPC_SUB_D, rt, rs, rd, 0);
20294            break;
20295        case NM_MUL_S:
20296            gen_farith(ctx, OPC_MUL_S, rt, rs, rd, 0);
20297            break;
20298        case NM_MUL_D:
20299            gen_farith(ctx, OPC_MUL_D, rt, rs, rd, 0);
20300            break;
20301        case NM_DIV_S:
20302            gen_farith(ctx, OPC_DIV_S, rt, rs, rd, 0);
20303            break;
20304        case NM_DIV_D:
20305            gen_farith(ctx, OPC_DIV_D, rt, rs, rd, 0);
20306            break;
20307        case NM_SELEQZ_S:
20308            gen_sel_s(ctx, OPC_SELEQZ_S, rd, rt, rs);
20309            break;
20310        case NM_SELEQZ_D:
20311            gen_sel_d(ctx, OPC_SELEQZ_D, rd, rt, rs);
20312            break;
20313        case NM_SELNEZ_S:
20314            gen_sel_s(ctx, OPC_SELNEZ_S, rd, rt, rs);
20315            break;
20316        case NM_SELNEZ_D:
20317            gen_sel_d(ctx, OPC_SELNEZ_D, rd, rt, rs);
20318            break;
20319        case NM_SEL_S:
20320            gen_sel_s(ctx, OPC_SEL_S, rd, rt, rs);
20321            break;
20322        case NM_SEL_D:
20323            gen_sel_d(ctx, OPC_SEL_D, rd, rt, rs);
20324            break;
20325        case NM_MADDF_S:
20326            gen_farith(ctx, OPC_MADDF_S, rt, rs, rd, 0);
20327            break;
20328        case NM_MADDF_D:
20329            gen_farith(ctx, OPC_MADDF_D, rt, rs, rd, 0);
20330            break;
20331        case NM_MSUBF_S:
20332            gen_farith(ctx, OPC_MSUBF_S, rt, rs, rd, 0);
20333            break;
20334        case NM_MSUBF_D:
20335            gen_farith(ctx, OPC_MSUBF_D, rt, rs, rd, 0);
20336            break;
20337        default:
20338            generate_exception_end(ctx, EXCP_RI);
20339            break;
20340        }
20341        break;
20342    case NM_POOL32F_3:
20343        switch (extract32(ctx->opcode, 3, 3)) {
20344        case NM_MIN_FMT:
20345            switch (extract32(ctx->opcode, 9, 1)) {
20346            case FMT_SDPS_S:
20347                gen_farith(ctx, OPC_MIN_S, rt, rs, rd, 0);
20348                break;
20349            case FMT_SDPS_D:
20350                gen_farith(ctx, OPC_MIN_D, rt, rs, rd, 0);
20351                break;
20352            }
20353            break;
20354        case NM_MAX_FMT:
20355            switch (extract32(ctx->opcode, 9, 1)) {
20356            case FMT_SDPS_S:
20357                gen_farith(ctx, OPC_MAX_S, rt, rs, rd, 0);
20358                break;
20359            case FMT_SDPS_D:
20360                gen_farith(ctx, OPC_MAX_D, rt, rs, rd, 0);
20361                break;
20362            }
20363            break;
20364        case NM_MINA_FMT:
20365            switch (extract32(ctx->opcode, 9, 1)) {
20366            case FMT_SDPS_S:
20367                gen_farith(ctx, OPC_MINA_S, rt, rs, rd, 0);
20368                break;
20369            case FMT_SDPS_D:
20370                gen_farith(ctx, OPC_MINA_D, rt, rs, rd, 0);
20371                break;
20372            }
20373            break;
20374        case NM_MAXA_FMT:
20375            switch (extract32(ctx->opcode, 9, 1)) {
20376            case FMT_SDPS_S:
20377                gen_farith(ctx, OPC_MAXA_S, rt, rs, rd, 0);
20378                break;
20379            case FMT_SDPS_D:
20380                gen_farith(ctx, OPC_MAXA_D, rt, rs, rd, 0);
20381                break;
20382            }
20383            break;
20384        case NM_POOL32FXF:
20385            switch (extract32(ctx->opcode, 6, 8)) {
20386            case NM_CFC1:
20387                gen_cp1(ctx, OPC_CFC1, rt, rs);
20388                break;
20389            case NM_CTC1:
20390                gen_cp1(ctx, OPC_CTC1, rt, rs);
20391                break;
20392            case NM_MFC1:
20393                gen_cp1(ctx, OPC_MFC1, rt, rs);
20394                break;
20395            case NM_MTC1:
20396                gen_cp1(ctx, OPC_MTC1, rt, rs);
20397                break;
20398            case NM_MFHC1:
20399                gen_cp1(ctx, OPC_MFHC1, rt, rs);
20400                break;
20401            case NM_MTHC1:
20402                gen_cp1(ctx, OPC_MTHC1, rt, rs);
20403                break;
20404            case NM_CVT_S_PL:
20405                gen_farith(ctx, OPC_CVT_S_PL, -1, rs, rt, 0);
20406                break;
20407            case NM_CVT_S_PU:
20408                gen_farith(ctx, OPC_CVT_S_PU, -1, rs, rt, 0);
20409                break;
20410            default:
20411                switch (extract32(ctx->opcode, 6, 9)) {
20412                case NM_CVT_L_S:
20413                    gen_farith(ctx, OPC_CVT_L_S, -1, rs, rt, 0);
20414                    break;
20415                case NM_CVT_L_D:
20416                    gen_farith(ctx, OPC_CVT_L_D, -1, rs, rt, 0);
20417                    break;
20418                case NM_CVT_W_S:
20419                    gen_farith(ctx, OPC_CVT_W_S, -1, rs, rt, 0);
20420                    break;
20421                case NM_CVT_W_D:
20422                    gen_farith(ctx, OPC_CVT_W_D, -1, rs, rt, 0);
20423                    break;
20424                case NM_RSQRT_S:
20425                    gen_farith(ctx, OPC_RSQRT_S, -1, rs, rt, 0);
20426                    break;
20427                case NM_RSQRT_D:
20428                    gen_farith(ctx, OPC_RSQRT_D, -1, rs, rt, 0);
20429                    break;
20430                case NM_SQRT_S:
20431                    gen_farith(ctx, OPC_SQRT_S, -1, rs, rt, 0);
20432                    break;
20433                case NM_SQRT_D:
20434                    gen_farith(ctx, OPC_SQRT_D, -1, rs, rt, 0);
20435                    break;
20436                case NM_RECIP_S:
20437                    gen_farith(ctx, OPC_RECIP_S, -1, rs, rt, 0);
20438                    break;
20439                case NM_RECIP_D:
20440                    gen_farith(ctx, OPC_RECIP_D, -1, rs, rt, 0);
20441                    break;
20442                case NM_FLOOR_L_S:
20443                    gen_farith(ctx, OPC_FLOOR_L_S, -1, rs, rt, 0);
20444                    break;
20445                case NM_FLOOR_L_D:
20446                    gen_farith(ctx, OPC_FLOOR_L_D, -1, rs, rt, 0);
20447                    break;
20448                case NM_FLOOR_W_S:
20449                    gen_farith(ctx, OPC_FLOOR_W_S, -1, rs, rt, 0);
20450                    break;
20451                case NM_FLOOR_W_D:
20452                    gen_farith(ctx, OPC_FLOOR_W_D, -1, rs, rt, 0);
20453                    break;
20454                case NM_CEIL_L_S:
20455                    gen_farith(ctx, OPC_CEIL_L_S, -1, rs, rt, 0);
20456                    break;
20457                case NM_CEIL_L_D:
20458                    gen_farith(ctx, OPC_CEIL_L_D, -1, rs, rt, 0);
20459                    break;
20460                case NM_CEIL_W_S:
20461                    gen_farith(ctx, OPC_CEIL_W_S, -1, rs, rt, 0);
20462                    break;
20463                case NM_CEIL_W_D:
20464                    gen_farith(ctx, OPC_CEIL_W_D, -1, rs, rt, 0);
20465                    break;
20466                case NM_TRUNC_L_S:
20467                    gen_farith(ctx, OPC_TRUNC_L_S, -1, rs, rt, 0);
20468                    break;
20469                case NM_TRUNC_L_D:
20470                    gen_farith(ctx, OPC_TRUNC_L_D, -1, rs, rt, 0);
20471                    break;
20472                case NM_TRUNC_W_S:
20473                    gen_farith(ctx, OPC_TRUNC_W_S, -1, rs, rt, 0);
20474                    break;
20475                case NM_TRUNC_W_D:
20476                    gen_farith(ctx, OPC_TRUNC_W_D, -1, rs, rt, 0);
20477                    break;
20478                case NM_ROUND_L_S:
20479                    gen_farith(ctx, OPC_ROUND_L_S, -1, rs, rt, 0);
20480                    break;
20481                case NM_ROUND_L_D:
20482                    gen_farith(ctx, OPC_ROUND_L_D, -1, rs, rt, 0);
20483                    break;
20484                case NM_ROUND_W_S:
20485                    gen_farith(ctx, OPC_ROUND_W_S, -1, rs, rt, 0);
20486                    break;
20487                case NM_ROUND_W_D:
20488                    gen_farith(ctx, OPC_ROUND_W_D, -1, rs, rt, 0);
20489                    break;
20490                case NM_MOV_S:
20491                    gen_farith(ctx, OPC_MOV_S, -1, rs, rt, 0);
20492                    break;
20493                case NM_MOV_D:
20494                    gen_farith(ctx, OPC_MOV_D, -1, rs, rt, 0);
20495                    break;
20496                case NM_ABS_S:
20497                    gen_farith(ctx, OPC_ABS_S, -1, rs, rt, 0);
20498                    break;
20499                case NM_ABS_D:
20500                    gen_farith(ctx, OPC_ABS_D, -1, rs, rt, 0);
20501                    break;
20502                case NM_NEG_S:
20503                    gen_farith(ctx, OPC_NEG_S, -1, rs, rt, 0);
20504                    break;
20505                case NM_NEG_D:
20506                    gen_farith(ctx, OPC_NEG_D, -1, rs, rt, 0);
20507                    break;
20508                case NM_CVT_D_S:
20509                    gen_farith(ctx, OPC_CVT_D_S, -1, rs, rt, 0);
20510                    break;
20511                case NM_CVT_D_W:
20512                    gen_farith(ctx, OPC_CVT_D_W, -1, rs, rt, 0);
20513                    break;
20514                case NM_CVT_D_L:
20515                    gen_farith(ctx, OPC_CVT_D_L, -1, rs, rt, 0);
20516                    break;
20517                case NM_CVT_S_D:
20518                    gen_farith(ctx, OPC_CVT_S_D, -1, rs, rt, 0);
20519                    break;
20520                case NM_CVT_S_W:
20521                    gen_farith(ctx, OPC_CVT_S_W, -1, rs, rt, 0);
20522                    break;
20523                case NM_CVT_S_L:
20524                    gen_farith(ctx, OPC_CVT_S_L, -1, rs, rt, 0);
20525                    break;
20526                default:
20527                    generate_exception_end(ctx, EXCP_RI);
20528                    break;
20529                }
20530                break;
20531            }
20532            break;
20533        }
20534        break;
20535    case NM_POOL32F_5:
20536        switch (extract32(ctx->opcode, 3, 3)) {
20537        case NM_CMP_CONDN_S:
20538            gen_r6_cmp_s(ctx, extract32(ctx->opcode, 6, 5), rt, rs, rd);
20539            break;
20540        case NM_CMP_CONDN_D:
20541            gen_r6_cmp_d(ctx, extract32(ctx->opcode, 6, 5), rt, rs, rd);
20542            break;
20543        default:
20544            generate_exception_end(ctx, EXCP_RI);
20545            break;
20546        }
20547        break;
20548    default:
20549        generate_exception_end(ctx, EXCP_RI);
20550        break;
20551    }
20552}
20553
20554static void gen_pool32a5_nanomips_insn(DisasContext *ctx, int opc,
20555                                       int rd, int rs, int rt)
20556{
20557    int ret = rd;
20558    TCGv t0 = tcg_temp_new();
20559    TCGv v1_t = tcg_temp_new();
20560    TCGv v2_t = tcg_temp_new();
20561
20562    gen_load_gpr(v1_t, rs);
20563    gen_load_gpr(v2_t, rt);
20564
20565    switch (opc) {
20566    case NM_CMP_EQ_PH:
20567        check_dsp(ctx);
20568        gen_helper_cmp_eq_ph(v1_t, v2_t, cpu_env);
20569        break;
20570    case NM_CMP_LT_PH:
20571        check_dsp(ctx);
20572        gen_helper_cmp_lt_ph(v1_t, v2_t, cpu_env);
20573        break;
20574    case NM_CMP_LE_PH:
20575        check_dsp(ctx);
20576        gen_helper_cmp_le_ph(v1_t, v2_t, cpu_env);
20577        break;
20578    case NM_CMPU_EQ_QB:
20579        check_dsp(ctx);
20580        gen_helper_cmpu_eq_qb(v1_t, v2_t, cpu_env);
20581        break;
20582    case NM_CMPU_LT_QB:
20583        check_dsp(ctx);
20584        gen_helper_cmpu_lt_qb(v1_t, v2_t, cpu_env);
20585        break;
20586    case NM_CMPU_LE_QB:
20587        check_dsp(ctx);
20588        gen_helper_cmpu_le_qb(v1_t, v2_t, cpu_env);
20589        break;
20590    case NM_CMPGU_EQ_QB:
20591        check_dsp(ctx);
20592        gen_helper_cmpgu_eq_qb(v1_t, v1_t, v2_t);
20593        gen_store_gpr(v1_t, ret);
20594        break;
20595    case NM_CMPGU_LT_QB:
20596        check_dsp(ctx);
20597        gen_helper_cmpgu_lt_qb(v1_t, v1_t, v2_t);
20598        gen_store_gpr(v1_t, ret);
20599        break;
20600    case NM_CMPGU_LE_QB:
20601        check_dsp(ctx);
20602        gen_helper_cmpgu_le_qb(v1_t, v1_t, v2_t);
20603        gen_store_gpr(v1_t, ret);
20604        break;
20605    case NM_CMPGDU_EQ_QB:
20606        check_dsp_r2(ctx);
20607        gen_helper_cmpgu_eq_qb(v1_t, v1_t, v2_t);
20608        tcg_gen_deposit_tl(cpu_dspctrl, cpu_dspctrl, v1_t, 24, 4);
20609        gen_store_gpr(v1_t, ret);
20610        break;
20611    case NM_CMPGDU_LT_QB:
20612        check_dsp_r2(ctx);
20613        gen_helper_cmpgu_lt_qb(v1_t, v1_t, v2_t);
20614        tcg_gen_deposit_tl(cpu_dspctrl, cpu_dspctrl, v1_t, 24, 4);
20615        gen_store_gpr(v1_t, ret);
20616        break;
20617    case NM_CMPGDU_LE_QB:
20618        check_dsp_r2(ctx);
20619        gen_helper_cmpgu_le_qb(v1_t, v1_t, v2_t);
20620        tcg_gen_deposit_tl(cpu_dspctrl, cpu_dspctrl, v1_t, 24, 4);
20621        gen_store_gpr(v1_t, ret);
20622        break;
20623    case NM_PACKRL_PH:
20624        check_dsp(ctx);
20625        gen_helper_packrl_ph(v1_t, v1_t, v2_t);
20626        gen_store_gpr(v1_t, ret);
20627        break;
20628    case NM_PICK_QB:
20629        check_dsp(ctx);
20630        gen_helper_pick_qb(v1_t, v1_t, v2_t, cpu_env);
20631        gen_store_gpr(v1_t, ret);
20632        break;
20633    case NM_PICK_PH:
20634        check_dsp(ctx);
20635        gen_helper_pick_ph(v1_t, v1_t, v2_t, cpu_env);
20636        gen_store_gpr(v1_t, ret);
20637        break;
20638    case NM_ADDQ_S_W:
20639        check_dsp(ctx);
20640        gen_helper_addq_s_w(v1_t, v1_t, v2_t, cpu_env);
20641        gen_store_gpr(v1_t, ret);
20642        break;
20643    case NM_SUBQ_S_W:
20644        check_dsp(ctx);
20645        gen_helper_subq_s_w(v1_t, v1_t, v2_t, cpu_env);
20646        gen_store_gpr(v1_t, ret);
20647        break;
20648    case NM_ADDSC:
20649        check_dsp(ctx);
20650        gen_helper_addsc(v1_t, v1_t, v2_t, cpu_env);
20651        gen_store_gpr(v1_t, ret);
20652        break;
20653    case NM_ADDWC:
20654        check_dsp(ctx);
20655        gen_helper_addwc(v1_t, v1_t, v2_t, cpu_env);
20656        gen_store_gpr(v1_t, ret);
20657        break;
20658    case NM_ADDQ_S_PH:
20659        check_dsp(ctx);
20660        switch (extract32(ctx->opcode, 10, 1)) {
20661        case 0:
20662            /* ADDQ_PH */
20663            gen_helper_addq_ph(v1_t, v1_t, v2_t, cpu_env);
20664            gen_store_gpr(v1_t, ret);
20665            break;
20666        case 1:
20667            /* ADDQ_S_PH */
20668            gen_helper_addq_s_ph(v1_t, v1_t, v2_t, cpu_env);
20669            gen_store_gpr(v1_t, ret);
20670            break;
20671        }
20672        break;
20673    case NM_ADDQH_R_PH:
20674        check_dsp_r2(ctx);
20675        switch (extract32(ctx->opcode, 10, 1)) {
20676        case 0:
20677            /* ADDQH_PH */
20678            gen_helper_addqh_ph(v1_t, v1_t, v2_t);
20679            gen_store_gpr(v1_t, ret);
20680            break;
20681        case 1:
20682            /* ADDQH_R_PH */
20683            gen_helper_addqh_r_ph(v1_t, v1_t, v2_t);
20684            gen_store_gpr(v1_t, ret);
20685            break;
20686        }
20687        break;
20688    case NM_ADDQH_R_W:
20689        check_dsp_r2(ctx);
20690        switch (extract32(ctx->opcode, 10, 1)) {
20691        case 0:
20692            /* ADDQH_W */
20693            gen_helper_addqh_w(v1_t, v1_t, v2_t);
20694            gen_store_gpr(v1_t, ret);
20695            break;
20696        case 1:
20697            /* ADDQH_R_W */
20698            gen_helper_addqh_r_w(v1_t, v1_t, v2_t);
20699            gen_store_gpr(v1_t, ret);
20700            break;
20701        }
20702        break;
20703    case NM_ADDU_S_QB:
20704        check_dsp(ctx);
20705        switch (extract32(ctx->opcode, 10, 1)) {
20706        case 0:
20707            /* ADDU_QB */
20708            gen_helper_addu_qb(v1_t, v1_t, v2_t, cpu_env);
20709            gen_store_gpr(v1_t, ret);
20710            break;
20711        case 1:
20712            /* ADDU_S_QB */
20713            gen_helper_addu_s_qb(v1_t, v1_t, v2_t, cpu_env);
20714            gen_store_gpr(v1_t, ret);
20715            break;
20716        }
20717        break;
20718    case NM_ADDU_S_PH:
20719        check_dsp_r2(ctx);
20720        switch (extract32(ctx->opcode, 10, 1)) {
20721        case 0:
20722            /* ADDU_PH */
20723            gen_helper_addu_ph(v1_t, v1_t, v2_t, cpu_env);
20724            gen_store_gpr(v1_t, ret);
20725            break;
20726        case 1:
20727            /* ADDU_S_PH */
20728            gen_helper_addu_s_ph(v1_t, v1_t, v2_t, cpu_env);
20729            gen_store_gpr(v1_t, ret);
20730            break;
20731        }
20732        break;
20733    case NM_ADDUH_R_QB:
20734        check_dsp_r2(ctx);
20735        switch (extract32(ctx->opcode, 10, 1)) {
20736        case 0:
20737            /* ADDUH_QB */
20738            gen_helper_adduh_qb(v1_t, v1_t, v2_t);
20739            gen_store_gpr(v1_t, ret);
20740            break;
20741        case 1:
20742            /* ADDUH_R_QB */
20743            gen_helper_adduh_r_qb(v1_t, v1_t, v2_t);
20744            gen_store_gpr(v1_t, ret);
20745            break;
20746        }
20747        break;
20748    case NM_SHRAV_R_PH:
20749        check_dsp(ctx);
20750        switch (extract32(ctx->opcode, 10, 1)) {
20751        case 0:
20752            /* SHRAV_PH */
20753            gen_helper_shra_ph(v1_t, v1_t, v2_t);
20754            gen_store_gpr(v1_t, ret);
20755            break;
20756        case 1:
20757            /* SHRAV_R_PH */
20758            gen_helper_shra_r_ph(v1_t, v1_t, v2_t);
20759            gen_store_gpr(v1_t, ret);
20760            break;
20761        }
20762        break;
20763    case NM_SHRAV_R_QB:
20764        check_dsp_r2(ctx);
20765        switch (extract32(ctx->opcode, 10, 1)) {
20766        case 0:
20767            /* SHRAV_QB */
20768            gen_helper_shra_qb(v1_t, v1_t, v2_t);
20769            gen_store_gpr(v1_t, ret);
20770            break;
20771        case 1:
20772            /* SHRAV_R_QB */
20773            gen_helper_shra_r_qb(v1_t, v1_t, v2_t);
20774            gen_store_gpr(v1_t, ret);
20775            break;
20776        }
20777        break;
20778    case NM_SUBQ_S_PH:
20779        check_dsp(ctx);
20780        switch (extract32(ctx->opcode, 10, 1)) {
20781        case 0:
20782            /* SUBQ_PH */
20783            gen_helper_subq_ph(v1_t, v1_t, v2_t, cpu_env);
20784            gen_store_gpr(v1_t, ret);
20785            break;
20786        case 1:
20787            /* SUBQ_S_PH */
20788            gen_helper_subq_s_ph(v1_t, v1_t, v2_t, cpu_env);
20789            gen_store_gpr(v1_t, ret);
20790            break;
20791        }
20792        break;
20793    case NM_SUBQH_R_PH:
20794        check_dsp_r2(ctx);
20795        switch (extract32(ctx->opcode, 10, 1)) {
20796        case 0:
20797            /* SUBQH_PH */
20798            gen_helper_subqh_ph(v1_t, v1_t, v2_t);
20799            gen_store_gpr(v1_t, ret);
20800            break;
20801        case 1:
20802            /* SUBQH_R_PH */
20803            gen_helper_subqh_r_ph(v1_t, v1_t, v2_t);
20804            gen_store_gpr(v1_t, ret);
20805            break;
20806        }
20807        break;
20808    case NM_SUBQH_R_W:
20809        check_dsp_r2(ctx);
20810        switch (extract32(ctx->opcode, 10, 1)) {
20811        case 0:
20812            /* SUBQH_W */
20813            gen_helper_subqh_w(v1_t, v1_t, v2_t);
20814            gen_store_gpr(v1_t, ret);
20815            break;
20816        case 1:
20817            /* SUBQH_R_W */
20818            gen_helper_subqh_r_w(v1_t, v1_t, v2_t);
20819            gen_store_gpr(v1_t, ret);
20820            break;
20821        }
20822        break;
20823    case NM_SUBU_S_QB:
20824        check_dsp(ctx);
20825        switch (extract32(ctx->opcode, 10, 1)) {
20826        case 0:
20827            /* SUBU_QB */
20828            gen_helper_subu_qb(v1_t, v1_t, v2_t, cpu_env);
20829            gen_store_gpr(v1_t, ret);
20830            break;
20831        case 1:
20832            /* SUBU_S_QB */
20833            gen_helper_subu_s_qb(v1_t, v1_t, v2_t, cpu_env);
20834            gen_store_gpr(v1_t, ret);
20835            break;
20836        }
20837        break;
20838    case NM_SUBU_S_PH:
20839        check_dsp_r2(ctx);
20840        switch (extract32(ctx->opcode, 10, 1)) {
20841        case 0:
20842            /* SUBU_PH */
20843            gen_helper_subu_ph(v1_t, v1_t, v2_t, cpu_env);
20844            gen_store_gpr(v1_t, ret);
20845            break;
20846        case 1:
20847            /* SUBU_S_PH */
20848            gen_helper_subu_s_ph(v1_t, v1_t, v2_t, cpu_env);
20849            gen_store_gpr(v1_t, ret);
20850            break;
20851        }
20852        break;
20853    case NM_SUBUH_R_QB:
20854        check_dsp_r2(ctx);
20855        switch (extract32(ctx->opcode, 10, 1)) {
20856        case 0:
20857            /* SUBUH_QB */
20858            gen_helper_subuh_qb(v1_t, v1_t, v2_t);
20859            gen_store_gpr(v1_t, ret);
20860            break;
20861        case 1:
20862            /* SUBUH_R_QB */
20863            gen_helper_subuh_r_qb(v1_t, v1_t, v2_t);
20864            gen_store_gpr(v1_t, ret);
20865            break;
20866        }
20867        break;
20868    case NM_SHLLV_S_PH:
20869        check_dsp(ctx);
20870        switch (extract32(ctx->opcode, 10, 1)) {
20871        case 0:
20872            /* SHLLV_PH */
20873            gen_helper_shll_ph(v1_t, v1_t, v2_t, cpu_env);
20874            gen_store_gpr(v1_t, ret);
20875            break;
20876        case 1:
20877            /* SHLLV_S_PH */
20878            gen_helper_shll_s_ph(v1_t, v1_t, v2_t, cpu_env);
20879            gen_store_gpr(v1_t, ret);
20880            break;
20881        }
20882        break;
20883    case NM_PRECR_SRA_R_PH_W:
20884        check_dsp_r2(ctx);
20885        switch (extract32(ctx->opcode, 10, 1)) {
20886        case 0:
20887            /* PRECR_SRA_PH_W */
20888            {
20889                TCGv_i32 sa_t = tcg_const_i32(rd);
20890                gen_helper_precr_sra_ph_w(v1_t, sa_t, v1_t,
20891                                          cpu_gpr[rt]);
20892                gen_store_gpr(v1_t, rt);
20893                tcg_temp_free_i32(sa_t);
20894            }
20895            break;
20896        case 1:
20897            /* PRECR_SRA_R_PH_W */
20898            {
20899                TCGv_i32 sa_t = tcg_const_i32(rd);
20900                gen_helper_precr_sra_r_ph_w(v1_t, sa_t, v1_t,
20901                                            cpu_gpr[rt]);
20902                gen_store_gpr(v1_t, rt);
20903                tcg_temp_free_i32(sa_t);
20904            }
20905            break;
20906       }
20907        break;
20908    case NM_MULEU_S_PH_QBL:
20909        check_dsp(ctx);
20910        gen_helper_muleu_s_ph_qbl(v1_t, v1_t, v2_t, cpu_env);
20911        gen_store_gpr(v1_t, ret);
20912        break;
20913    case NM_MULEU_S_PH_QBR:
20914        check_dsp(ctx);
20915        gen_helper_muleu_s_ph_qbr(v1_t, v1_t, v2_t, cpu_env);
20916        gen_store_gpr(v1_t, ret);
20917        break;
20918    case NM_MULQ_RS_PH:
20919        check_dsp(ctx);
20920        gen_helper_mulq_rs_ph(v1_t, v1_t, v2_t, cpu_env);
20921        gen_store_gpr(v1_t, ret);
20922        break;
20923    case NM_MULQ_S_PH:
20924        check_dsp_r2(ctx);
20925        gen_helper_mulq_s_ph(v1_t, v1_t, v2_t, cpu_env);
20926        gen_store_gpr(v1_t, ret);
20927        break;
20928    case NM_MULQ_RS_W:
20929        check_dsp_r2(ctx);
20930        gen_helper_mulq_rs_w(v1_t, v1_t, v2_t, cpu_env);
20931        gen_store_gpr(v1_t, ret);
20932        break;
20933    case NM_MULQ_S_W:
20934        check_dsp_r2(ctx);
20935        gen_helper_mulq_s_w(v1_t, v1_t, v2_t, cpu_env);
20936        gen_store_gpr(v1_t, ret);
20937        break;
20938    case NM_APPEND:
20939        check_dsp_r2(ctx);
20940        gen_load_gpr(t0, rs);
20941        if (rd != 0) {
20942            tcg_gen_deposit_tl(cpu_gpr[rt], t0, cpu_gpr[rt], rd, 32 - rd);
20943        }
20944        tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
20945        break;
20946    case NM_MODSUB:
20947        check_dsp(ctx);
20948        gen_helper_modsub(v1_t, v1_t, v2_t);
20949        gen_store_gpr(v1_t, ret);
20950        break;
20951    case NM_SHRAV_R_W:
20952        check_dsp(ctx);
20953        gen_helper_shra_r_w(v1_t, v1_t, v2_t);
20954        gen_store_gpr(v1_t, ret);
20955        break;
20956    case NM_SHRLV_PH:
20957        check_dsp_r2(ctx);
20958        gen_helper_shrl_ph(v1_t, v1_t, v2_t);
20959        gen_store_gpr(v1_t, ret);
20960        break;
20961    case NM_SHRLV_QB:
20962        check_dsp(ctx);
20963        gen_helper_shrl_qb(v1_t, v1_t, v2_t);
20964        gen_store_gpr(v1_t, ret);
20965        break;
20966    case NM_SHLLV_QB:
20967        check_dsp(ctx);
20968        gen_helper_shll_qb(v1_t, v1_t, v2_t, cpu_env);
20969        gen_store_gpr(v1_t, ret);
20970        break;
20971    case NM_SHLLV_S_W:
20972        check_dsp(ctx);
20973        gen_helper_shll_s_w(v1_t, v1_t, v2_t, cpu_env);
20974        gen_store_gpr(v1_t, ret);
20975        break;
20976    case NM_SHILO:
20977        check_dsp(ctx);
20978        {
20979            TCGv tv0 = tcg_temp_new();
20980            TCGv tv1 = tcg_temp_new();
20981            int16_t imm = extract32(ctx->opcode, 16, 7);
20982
20983            tcg_gen_movi_tl(tv0, rd >> 3);
20984            tcg_gen_movi_tl(tv1, imm);
20985            gen_helper_shilo(tv0, tv1, cpu_env);
20986        }
20987        break;
20988    case NM_MULEQ_S_W_PHL:
20989        check_dsp(ctx);
20990        gen_helper_muleq_s_w_phl(v1_t, v1_t, v2_t, cpu_env);
20991        gen_store_gpr(v1_t, ret);
20992        break;
20993    case NM_MULEQ_S_W_PHR:
20994        check_dsp(ctx);
20995        gen_helper_muleq_s_w_phr(v1_t, v1_t, v2_t, cpu_env);
20996        gen_store_gpr(v1_t, ret);
20997        break;
20998    case NM_MUL_S_PH:
20999        check_dsp_r2(ctx);
21000        switch (extract32(ctx->opcode, 10, 1)) {
21001        case 0:
21002            /* MUL_PH */
21003            gen_helper_mul_ph(v1_t, v1_t, v2_t, cpu_env);
21004            gen_store_gpr(v1_t, ret);
21005            break;
21006        case 1:
21007            /* MUL_S_PH */
21008            gen_helper_mul_s_ph(v1_t, v1_t, v2_t, cpu_env);
21009            gen_store_gpr(v1_t, ret);
21010            break;
21011        }
21012        break;
21013    case NM_PRECR_QB_PH:
21014        check_dsp_r2(ctx);
21015        gen_helper_precr_qb_ph(v1_t, v1_t, v2_t);
21016        gen_store_gpr(v1_t, ret);
21017        break;
21018    case NM_PRECRQ_QB_PH:
21019        check_dsp(ctx);
21020        gen_helper_precrq_qb_ph(v1_t, v1_t, v2_t);
21021        gen_store_gpr(v1_t, ret);
21022        break;
21023    case NM_PRECRQ_PH_W:
21024        check_dsp(ctx);
21025        gen_helper_precrq_ph_w(v1_t, v1_t, v2_t);
21026        gen_store_gpr(v1_t, ret);
21027        break;
21028    case NM_PRECRQ_RS_PH_W:
21029        check_dsp(ctx);
21030        gen_helper_precrq_rs_ph_w(v1_t, v1_t, v2_t, cpu_env);
21031        gen_store_gpr(v1_t, ret);
21032        break;
21033    case NM_PRECRQU_S_QB_PH:
21034        check_dsp(ctx);
21035        gen_helper_precrqu_s_qb_ph(v1_t, v1_t, v2_t, cpu_env);
21036        gen_store_gpr(v1_t, ret);
21037        break;
21038    case NM_SHRA_R_W:
21039        check_dsp(ctx);
21040        tcg_gen_movi_tl(t0, rd);
21041        gen_helper_shra_r_w(v1_t, t0, v1_t);
21042        gen_store_gpr(v1_t, rt);
21043        break;
21044    case NM_SHRA_R_PH:
21045        check_dsp(ctx);
21046        tcg_gen_movi_tl(t0, rd >> 1);
21047        switch (extract32(ctx->opcode, 10, 1)) {
21048        case 0:
21049            /* SHRA_PH */
21050            gen_helper_shra_ph(v1_t, t0, v1_t);
21051            gen_store_gpr(v1_t, rt);
21052            break;
21053        case 1:
21054            /* SHRA_R_PH */
21055            gen_helper_shra_r_ph(v1_t, t0, v1_t);
21056            gen_store_gpr(v1_t, rt);
21057            break;
21058        }
21059        break;
21060    case NM_SHLL_S_PH:
21061        check_dsp(ctx);
21062        tcg_gen_movi_tl(t0, rd >> 1);
21063        switch (extract32(ctx->opcode, 10, 2)) {
21064        case 0:
21065            /* SHLL_PH */
21066            gen_helper_shll_ph(v1_t, t0, v1_t, cpu_env);
21067            gen_store_gpr(v1_t, rt);
21068            break;
21069        case 2:
21070            /* SHLL_S_PH */
21071            gen_helper_shll_s_ph(v1_t, t0, v1_t, cpu_env);
21072            gen_store_gpr(v1_t, rt);
21073            break;
21074        default:
21075            generate_exception_end(ctx, EXCP_RI);
21076            break;
21077        }
21078        break;
21079    case NM_SHLL_S_W:
21080        check_dsp(ctx);
21081        tcg_gen_movi_tl(t0, rd);
21082        gen_helper_shll_s_w(v1_t, t0, v1_t, cpu_env);
21083        gen_store_gpr(v1_t, rt);
21084        break;
21085    case NM_REPL_PH:
21086        check_dsp(ctx);
21087        {
21088            int16_t imm;
21089            imm = sextract32(ctx->opcode, 11, 11);
21090            imm = (int16_t)(imm << 6) >> 6;
21091            if (rt != 0) {
21092                tcg_gen_movi_tl(cpu_gpr[rt], dup_const(MO_16, imm));
21093            }
21094        }
21095        break;
21096    default:
21097        generate_exception_end(ctx, EXCP_RI);
21098        break;
21099    }
21100}
21101
21102static int decode_nanomips_32_48_opc(CPUMIPSState *env, DisasContext *ctx)
21103{
21104    uint16_t insn;
21105    uint32_t op;
21106    int rt, rs, rd;
21107    int offset;
21108    int imm;
21109
21110    insn = cpu_lduw_code(env, ctx->base.pc_next + 2);
21111    ctx->opcode = (ctx->opcode << 16) | insn;
21112
21113    rt = extract32(ctx->opcode, 21, 5);
21114    rs = extract32(ctx->opcode, 16, 5);
21115    rd = extract32(ctx->opcode, 11, 5);
21116
21117    op = extract32(ctx->opcode, 26, 6);
21118    switch (op) {
21119    case NM_P_ADDIU:
21120        if (rt == 0) {
21121            /* P.RI */
21122            switch (extract32(ctx->opcode, 19, 2)) {
21123            case NM_SIGRIE:
21124            default:
21125                generate_exception_end(ctx, EXCP_RI);
21126                break;
21127            case NM_P_SYSCALL:
21128                if ((extract32(ctx->opcode, 18, 1)) == NM_SYSCALL) {
21129                    generate_exception_end(ctx, EXCP_SYSCALL);
21130                } else {
21131                    generate_exception_end(ctx, EXCP_RI);
21132                }
21133                break;
21134            case NM_BREAK:
21135                generate_exception_end(ctx, EXCP_BREAK);
21136                break;
21137            case NM_SDBBP:
21138                if (is_uhi(extract32(ctx->opcode, 0, 19))) {
21139                    gen_helper_do_semihosting(cpu_env);
21140                } else {
21141                    if (ctx->hflags & MIPS_HFLAG_SBRI) {
21142                        generate_exception_end(ctx, EXCP_RI);
21143                    } else {
21144                        generate_exception_end(ctx, EXCP_DBp);
21145                    }
21146                }
21147                break;
21148            }
21149        } else {
21150            /* NM_ADDIU */
21151            imm = extract32(ctx->opcode, 0, 16);
21152            if (rs != 0) {
21153                tcg_gen_addi_tl(cpu_gpr[rt], cpu_gpr[rs], imm);
21154            } else {
21155                tcg_gen_movi_tl(cpu_gpr[rt], imm);
21156            }
21157            tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
21158        }
21159        break;
21160    case NM_ADDIUPC:
21161        if (rt != 0) {
21162            offset = sextract32(ctx->opcode, 0, 1) << 21 |
21163                     extract32(ctx->opcode, 1, 20) << 1;
21164            target_long addr = addr_add(ctx, ctx->base.pc_next + 4, offset);
21165            tcg_gen_movi_tl(cpu_gpr[rt], addr);
21166        }
21167        break;
21168    case NM_POOL32A:
21169        switch (ctx->opcode & 0x07) {
21170        case NM_POOL32A0:
21171            gen_pool32a0_nanomips_insn(env, ctx);
21172            break;
21173        case NM_POOL32A5:
21174            {
21175                int32_t op1 = extract32(ctx->opcode, 3, 7);
21176                gen_pool32a5_nanomips_insn(ctx, op1, rd, rs, rt);
21177            }
21178            break;
21179        case NM_POOL32A7:
21180            switch (extract32(ctx->opcode, 3, 3)) {
21181            case NM_P_LSX:
21182                gen_p_lsx(ctx, rd, rs, rt);
21183                break;
21184            case NM_LSA:
21185                /*
21186                 * In nanoMIPS, the shift field directly encodes the shift
21187                 * amount, meaning that the supported shift values are in
21188                 * the range 0 to 3 (instead of 1 to 4 in MIPSR6).
21189                 */
21190                gen_lsa(ctx, OPC_LSA, rd, rs, rt,
21191                        extract32(ctx->opcode, 9, 2) - 1);
21192                break;
21193            case NM_EXTW:
21194                gen_ext(ctx, 32, rd, rs, rt, extract32(ctx->opcode, 6, 5));
21195                break;
21196            case NM_POOL32AXF:
21197                gen_pool32axf_nanomips_insn(env, ctx);
21198                break;
21199            default:
21200                generate_exception_end(ctx, EXCP_RI);
21201                break;
21202            }
21203            break;
21204        default:
21205            generate_exception_end(ctx, EXCP_RI);
21206            break;
21207        }
21208        break;
21209    case NM_P_GP_W:
21210        switch (ctx->opcode & 0x03) {
21211        case NM_ADDIUGP_W:
21212            if (rt != 0) {
21213                offset = extract32(ctx->opcode, 0, 21);
21214                gen_op_addr_addi(ctx, cpu_gpr[rt], cpu_gpr[28], offset);
21215            }
21216            break;
21217        case NM_LWGP:
21218            gen_ld(ctx, OPC_LW, rt, 28, extract32(ctx->opcode, 2, 19) << 2);
21219            break;
21220        case NM_SWGP:
21221            gen_st(ctx, OPC_SW, rt, 28, extract32(ctx->opcode, 2, 19) << 2);
21222            break;
21223        default:
21224            generate_exception_end(ctx, EXCP_RI);
21225            break;
21226        }
21227        break;
21228    case NM_P48I:
21229        {
21230            insn = cpu_lduw_code(env, ctx->base.pc_next + 4);
21231            target_long addr_off = extract32(ctx->opcode, 0, 16) | insn << 16;
21232            switch (extract32(ctx->opcode, 16, 5)) {
21233            case NM_LI48:
21234                check_nms(ctx);
21235                if (rt != 0) {
21236                    tcg_gen_movi_tl(cpu_gpr[rt], addr_off);
21237                }
21238                break;
21239            case NM_ADDIU48:
21240                check_nms(ctx);
21241                if (rt != 0) {
21242                    tcg_gen_addi_tl(cpu_gpr[rt], cpu_gpr[rt], addr_off);
21243                    tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
21244                }
21245                break;
21246            case NM_ADDIUGP48:
21247                check_nms(ctx);
21248                if (rt != 0) {
21249                    gen_op_addr_addi(ctx, cpu_gpr[rt], cpu_gpr[28], addr_off);
21250                }
21251                break;
21252            case NM_ADDIUPC48:
21253                check_nms(ctx);
21254                if (rt != 0) {
21255                    target_long addr = addr_add(ctx, ctx->base.pc_next + 6,
21256                                                addr_off);
21257
21258                    tcg_gen_movi_tl(cpu_gpr[rt], addr);
21259                }
21260                break;
21261            case NM_LWPC48:
21262                check_nms(ctx);
21263                if (rt != 0) {
21264                    TCGv t0;
21265                    t0 = tcg_temp_new();
21266
21267                    target_long addr = addr_add(ctx, ctx->base.pc_next + 6,
21268                                                addr_off);
21269
21270                    tcg_gen_movi_tl(t0, addr);
21271                    tcg_gen_qemu_ld_tl(cpu_gpr[rt], t0, ctx->mem_idx, MO_TESL);
21272                    tcg_temp_free(t0);
21273                }
21274                break;
21275            case NM_SWPC48:
21276                check_nms(ctx);
21277                {
21278                    TCGv t0, t1;
21279                    t0 = tcg_temp_new();
21280                    t1 = tcg_temp_new();
21281
21282                    target_long addr = addr_add(ctx, ctx->base.pc_next + 6,
21283                                                addr_off);
21284
21285                    tcg_gen_movi_tl(t0, addr);
21286                    gen_load_gpr(t1, rt);
21287
21288                    tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL);
21289
21290                    tcg_temp_free(t0);
21291                    tcg_temp_free(t1);
21292                }
21293                break;
21294            default:
21295                generate_exception_end(ctx, EXCP_RI);
21296                break;
21297            }
21298            return 6;
21299        }
21300    case NM_P_U12:
21301        switch (extract32(ctx->opcode, 12, 4)) {
21302        case NM_ORI:
21303            gen_logic_imm(ctx, OPC_ORI, rt, rs, extract32(ctx->opcode, 0, 12));
21304            break;
21305        case NM_XORI:
21306            gen_logic_imm(ctx, OPC_XORI, rt, rs, extract32(ctx->opcode, 0, 12));
21307            break;
21308        case NM_ANDI:
21309            gen_logic_imm(ctx, OPC_ANDI, rt, rs, extract32(ctx->opcode, 0, 12));
21310            break;
21311        case NM_P_SR:
21312            switch (extract32(ctx->opcode, 20, 1)) {
21313            case NM_PP_SR:
21314                switch (ctx->opcode & 3) {
21315                case NM_SAVE:
21316                    gen_save(ctx, rt, extract32(ctx->opcode, 16, 4),
21317                             extract32(ctx->opcode, 2, 1),
21318                             extract32(ctx->opcode, 3, 9) << 3);
21319                    break;
21320                case NM_RESTORE:
21321                case NM_RESTORE_JRC:
21322                    gen_restore(ctx, rt, extract32(ctx->opcode, 16, 4),
21323                                extract32(ctx->opcode, 2, 1),
21324                                extract32(ctx->opcode, 3, 9) << 3);
21325                    if ((ctx->opcode & 3) == NM_RESTORE_JRC) {
21326                        gen_compute_branch_nm(ctx, OPC_JR, 2, 31, 0, 0);
21327                    }
21328                    break;
21329                default:
21330                    generate_exception_end(ctx, EXCP_RI);
21331                    break;
21332                }
21333                break;
21334            case NM_P_SR_F:
21335                generate_exception_end(ctx, EXCP_RI);
21336                break;
21337            }
21338            break;
21339        case NM_SLTI:
21340            gen_slt_imm(ctx, OPC_SLTI, rt, rs, extract32(ctx->opcode, 0, 12));
21341            break;
21342        case NM_SLTIU:
21343            gen_slt_imm(ctx, OPC_SLTIU, rt, rs, extract32(ctx->opcode, 0, 12));
21344            break;
21345        case NM_SEQI:
21346            {
21347                TCGv t0 = tcg_temp_new();
21348
21349                imm = extract32(ctx->opcode, 0, 12);
21350                gen_load_gpr(t0, rs);
21351                tcg_gen_setcondi_tl(TCG_COND_EQ, t0, t0, imm);
21352                gen_store_gpr(t0, rt);
21353
21354                tcg_temp_free(t0);
21355            }
21356            break;
21357        case NM_ADDIUNEG:
21358            imm = (int16_t) extract32(ctx->opcode, 0, 12);
21359            gen_arith_imm(ctx, OPC_ADDIU, rt, rs, -imm);
21360            break;
21361        case NM_P_SHIFT:
21362            {
21363                int shift = extract32(ctx->opcode, 0, 5);
21364                switch (extract32(ctx->opcode, 5, 4)) {
21365                case NM_P_SLL:
21366                    if (rt == 0 && shift == 0) {
21367                        /* NOP */
21368                    } else if (rt == 0 && shift == 3) {
21369                        /* EHB - treat as NOP */
21370                    } else if (rt == 0 && shift == 5) {
21371                        /* PAUSE - treat as NOP */
21372                    } else if (rt == 0 && shift == 6) {
21373                        /* SYNC */
21374                        gen_sync(extract32(ctx->opcode, 16, 5));
21375                    } else {
21376                        /* SLL */
21377                        gen_shift_imm(ctx, OPC_SLL, rt, rs,
21378                                      extract32(ctx->opcode, 0, 5));
21379                    }
21380                    break;
21381                case NM_SRL:
21382                    gen_shift_imm(ctx, OPC_SRL, rt, rs,
21383                                  extract32(ctx->opcode, 0, 5));
21384                    break;
21385                case NM_SRA:
21386                    gen_shift_imm(ctx, OPC_SRA, rt, rs,
21387                                  extract32(ctx->opcode, 0, 5));
21388                    break;
21389                case NM_ROTR:
21390                    gen_shift_imm(ctx, OPC_ROTR, rt, rs,
21391                                  extract32(ctx->opcode, 0, 5));
21392                    break;
21393                }
21394            }
21395            break;
21396        case NM_P_ROTX:
21397            check_nms(ctx);
21398            if (rt != 0) {
21399                TCGv t0 = tcg_temp_new();
21400                TCGv_i32 shift = tcg_const_i32(extract32(ctx->opcode, 0, 5));
21401                TCGv_i32 shiftx = tcg_const_i32(extract32(ctx->opcode, 7, 4)
21402                                                << 1);
21403                TCGv_i32 stripe = tcg_const_i32(extract32(ctx->opcode, 6, 1));
21404
21405                gen_load_gpr(t0, rs);
21406                gen_helper_rotx(cpu_gpr[rt], t0, shift, shiftx, stripe);
21407                tcg_temp_free(t0);
21408
21409                tcg_temp_free_i32(shift);
21410                tcg_temp_free_i32(shiftx);
21411                tcg_temp_free_i32(stripe);
21412            }
21413            break;
21414        case NM_P_INS:
21415            switch (((ctx->opcode >> 10) & 2) |
21416                    (extract32(ctx->opcode, 5, 1))) {
21417            case NM_INS:
21418                check_nms(ctx);
21419                gen_bitops(ctx, OPC_INS, rt, rs, extract32(ctx->opcode, 0, 5),
21420                           extract32(ctx->opcode, 6, 5));
21421                break;
21422            default:
21423                generate_exception_end(ctx, EXCP_RI);
21424                break;
21425            }
21426            break;
21427        case NM_P_EXT:
21428            switch (((ctx->opcode >> 10) & 2) |
21429                    (extract32(ctx->opcode, 5, 1))) {
21430            case NM_EXT:
21431                check_nms(ctx);
21432                gen_bitops(ctx, OPC_EXT, rt, rs, extract32(ctx->opcode, 0, 5),
21433                           extract32(ctx->opcode, 6, 5));
21434                break;
21435            default:
21436                generate_exception_end(ctx, EXCP_RI);
21437                break;
21438            }
21439            break;
21440        default:
21441            generate_exception_end(ctx, EXCP_RI);
21442            break;
21443        }
21444        break;
21445    case NM_POOL32F:
21446        gen_pool32f_nanomips_insn(ctx);
21447        break;
21448    case NM_POOL32S:
21449        break;
21450    case NM_P_LUI:
21451        switch (extract32(ctx->opcode, 1, 1)) {
21452        case NM_LUI:
21453            if (rt != 0) {
21454                tcg_gen_movi_tl(cpu_gpr[rt],
21455                                sextract32(ctx->opcode, 0, 1) << 31 |
21456                                extract32(ctx->opcode, 2, 10) << 21 |
21457                                extract32(ctx->opcode, 12, 9) << 12);
21458            }
21459            break;
21460        case NM_ALUIPC:
21461            if (rt != 0) {
21462                offset = sextract32(ctx->opcode, 0, 1) << 31 |
21463                         extract32(ctx->opcode, 2, 10) << 21 |
21464                         extract32(ctx->opcode, 12, 9) << 12;
21465                target_long addr;
21466                addr = ~0xFFF & addr_add(ctx, ctx->base.pc_next + 4, offset);
21467                tcg_gen_movi_tl(cpu_gpr[rt], addr);
21468            }
21469            break;
21470        }
21471        break;
21472    case NM_P_GP_BH:
21473        {
21474            uint32_t u = extract32(ctx->opcode, 0, 18);
21475
21476            switch (extract32(ctx->opcode, 18, 3)) {
21477            case NM_LBGP:
21478                gen_ld(ctx, OPC_LB, rt, 28, u);
21479                break;
21480            case NM_SBGP:
21481                gen_st(ctx, OPC_SB, rt, 28, u);
21482                break;
21483            case NM_LBUGP:
21484                gen_ld(ctx, OPC_LBU, rt, 28, u);
21485                break;
21486            case NM_ADDIUGP_B:
21487                if (rt != 0) {
21488                    gen_op_addr_addi(ctx, cpu_gpr[rt], cpu_gpr[28], u);
21489                }
21490                break;
21491            case NM_P_GP_LH:
21492                u &= ~1;
21493                switch (ctx->opcode & 1) {
21494                case NM_LHGP:
21495                    gen_ld(ctx, OPC_LH, rt, 28, u);
21496                    break;
21497                case NM_LHUGP:
21498                    gen_ld(ctx, OPC_LHU, rt, 28, u);
21499                    break;
21500                }
21501                break;
21502            case NM_P_GP_SH:
21503                u &= ~1;
21504                switch (ctx->opcode & 1) {
21505                case NM_SHGP:
21506                    gen_st(ctx, OPC_SH, rt, 28, u);
21507                    break;
21508                default:
21509                    generate_exception_end(ctx, EXCP_RI);
21510                    break;
21511                }
21512                break;
21513            case NM_P_GP_CP1:
21514                u &= ~0x3;
21515                switch (ctx->opcode & 0x3) {
21516                case NM_LWC1GP:
21517                    gen_cop1_ldst(ctx, OPC_LWC1, rt, 28, u);
21518                    break;
21519                case NM_LDC1GP:
21520                    gen_cop1_ldst(ctx, OPC_LDC1, rt, 28, u);
21521                    break;
21522                case NM_SWC1GP:
21523                    gen_cop1_ldst(ctx, OPC_SWC1, rt, 28, u);
21524                    break;
21525                case NM_SDC1GP:
21526                    gen_cop1_ldst(ctx, OPC_SDC1, rt, 28, u);
21527                    break;
21528                }
21529                break;
21530            default:
21531                generate_exception_end(ctx, EXCP_RI);
21532                break;
21533            }
21534        }
21535        break;
21536    case NM_P_LS_U12:
21537        {
21538            uint32_t u = extract32(ctx->opcode, 0, 12);
21539
21540            switch (extract32(ctx->opcode, 12, 4)) {
21541            case NM_P_PREFU12:
21542                if (rt == 31) {
21543                    /* SYNCI */
21544                    /*
21545                     * Break the TB to be able to sync copied instructions
21546                     * immediately.
21547                     */
21548                    ctx->base.is_jmp = DISAS_STOP;
21549                } else {
21550                    /* PREF */
21551                    /* Treat as NOP. */
21552                }
21553                break;
21554            case NM_LB:
21555                gen_ld(ctx, OPC_LB, rt, rs, u);
21556                break;
21557            case NM_LH:
21558                gen_ld(ctx, OPC_LH, rt, rs, u);
21559                break;
21560            case NM_LW:
21561                gen_ld(ctx, OPC_LW, rt, rs, u);
21562                break;
21563            case NM_LBU:
21564                gen_ld(ctx, OPC_LBU, rt, rs, u);
21565                break;
21566            case NM_LHU:
21567                gen_ld(ctx, OPC_LHU, rt, rs, u);
21568                break;
21569            case NM_SB:
21570                gen_st(ctx, OPC_SB, rt, rs, u);
21571                break;
21572            case NM_SH:
21573                gen_st(ctx, OPC_SH, rt, rs, u);
21574                break;
21575            case NM_SW:
21576                gen_st(ctx, OPC_SW, rt, rs, u);
21577                break;
21578            case NM_LWC1:
21579                gen_cop1_ldst(ctx, OPC_LWC1, rt, rs, u);
21580                break;
21581            case NM_LDC1:
21582                gen_cop1_ldst(ctx, OPC_LDC1, rt, rs, u);
21583                break;
21584            case NM_SWC1:
21585                gen_cop1_ldst(ctx, OPC_SWC1, rt, rs, u);
21586                break;
21587            case NM_SDC1:
21588                gen_cop1_ldst(ctx, OPC_SDC1, rt, rs, u);
21589                break;
21590            default:
21591                generate_exception_end(ctx, EXCP_RI);
21592                break;
21593            }
21594        }
21595        break;
21596    case NM_P_LS_S9:
21597        {
21598            int32_t s = (sextract32(ctx->opcode, 15, 1) << 8) |
21599                        extract32(ctx->opcode, 0, 8);
21600
21601            switch (extract32(ctx->opcode, 8, 3)) {
21602            case NM_P_LS_S0:
21603                switch (extract32(ctx->opcode, 11, 4)) {
21604                case NM_LBS9:
21605                    gen_ld(ctx, OPC_LB, rt, rs, s);
21606                    break;
21607                case NM_LHS9:
21608                    gen_ld(ctx, OPC_LH, rt, rs, s);
21609                    break;
21610                case NM_LWS9:
21611                    gen_ld(ctx, OPC_LW, rt, rs, s);
21612                    break;
21613                case NM_LBUS9:
21614                    gen_ld(ctx, OPC_LBU, rt, rs, s);
21615                    break;
21616                case NM_LHUS9:
21617                    gen_ld(ctx, OPC_LHU, rt, rs, s);
21618                    break;
21619                case NM_SBS9:
21620                    gen_st(ctx, OPC_SB, rt, rs, s);
21621                    break;
21622                case NM_SHS9:
21623                    gen_st(ctx, OPC_SH, rt, rs, s);
21624                    break;
21625                case NM_SWS9:
21626                    gen_st(ctx, OPC_SW, rt, rs, s);
21627                    break;
21628                case NM_LWC1S9:
21629                    gen_cop1_ldst(ctx, OPC_LWC1, rt, rs, s);
21630                    break;
21631                case NM_LDC1S9:
21632                    gen_cop1_ldst(ctx, OPC_LDC1, rt, rs, s);
21633                    break;
21634                case NM_SWC1S9:
21635                    gen_cop1_ldst(ctx, OPC_SWC1, rt, rs, s);
21636                    break;
21637                case NM_SDC1S9:
21638                    gen_cop1_ldst(ctx, OPC_SDC1, rt, rs, s);
21639                    break;
21640                case NM_P_PREFS9:
21641                    if (rt == 31) {
21642                        /* SYNCI */
21643                        /*
21644                         * Break the TB to be able to sync copied instructions
21645                         * immediately.
21646                         */
21647                        ctx->base.is_jmp = DISAS_STOP;
21648                    } else {
21649                        /* PREF */
21650                        /* Treat as NOP. */
21651                    }
21652                    break;
21653                default:
21654                    generate_exception_end(ctx, EXCP_RI);
21655                    break;
21656                }
21657                break;
21658            case NM_P_LS_S1:
21659                switch (extract32(ctx->opcode, 11, 4)) {
21660                case NM_UALH:
21661                case NM_UASH:
21662                    check_nms(ctx);
21663                    {
21664                        TCGv t0 = tcg_temp_new();
21665                        TCGv t1 = tcg_temp_new();
21666
21667                        gen_base_offset_addr(ctx, t0, rs, s);
21668
21669                        switch (extract32(ctx->opcode, 11, 4)) {
21670                        case NM_UALH:
21671                            tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TESW |
21672                                               MO_UNALN);
21673                            gen_store_gpr(t0, rt);
21674                            break;
21675                        case NM_UASH:
21676                            gen_load_gpr(t1, rt);
21677                            tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUW |
21678                                               MO_UNALN);
21679                            break;
21680                        }
21681                        tcg_temp_free(t0);
21682                        tcg_temp_free(t1);
21683                    }
21684                    break;
21685                case NM_P_LL:
21686                    switch (ctx->opcode & 0x03) {
21687                    case NM_LL:
21688                        gen_ld(ctx, OPC_LL, rt, rs, s);
21689                        break;
21690                    case NM_LLWP:
21691                        check_xnp(ctx);
21692                        gen_llwp(ctx, rs, 0, rt, extract32(ctx->opcode, 3, 5));
21693                        break;
21694                    }
21695                    break;
21696                case NM_P_SC:
21697                    switch (ctx->opcode & 0x03) {
21698                    case NM_SC:
21699                        gen_st_cond(ctx, rt, rs, s, MO_TESL, false);
21700                        break;
21701                    case NM_SCWP:
21702                        check_xnp(ctx);
21703                        gen_scwp(ctx, rs, 0, rt, extract32(ctx->opcode, 3, 5),
21704                                 false);
21705                        break;
21706                    }
21707                    break;
21708                case NM_CACHE:
21709                    check_cp0_enabled(ctx);
21710                    if (ctx->hflags & MIPS_HFLAG_ITC_CACHE) {
21711                        gen_cache_operation(ctx, rt, rs, s);
21712                    }
21713                    break;
21714                }
21715                break;
21716            case NM_P_LS_E0:
21717                switch (extract32(ctx->opcode, 11, 4)) {
21718                case NM_LBE:
21719                    check_eva(ctx);
21720                    check_cp0_enabled(ctx);
21721                    gen_ld(ctx, OPC_LBE, rt, rs, s);
21722                    break;
21723                case NM_SBE:
21724                    check_eva(ctx);
21725                    check_cp0_enabled(ctx);
21726                    gen_st(ctx, OPC_SBE, rt, rs, s);
21727                    break;
21728                case NM_LBUE:
21729                    check_eva(ctx);
21730                    check_cp0_enabled(ctx);
21731                    gen_ld(ctx, OPC_LBUE, rt, rs, s);
21732                    break;
21733                case NM_P_PREFE:
21734                    if (rt == 31) {
21735                        /* case NM_SYNCIE */
21736                        check_eva(ctx);
21737                        check_cp0_enabled(ctx);
21738                        /*
21739                         * Break the TB to be able to sync copied instructions
21740                         * immediately.
21741                         */
21742                        ctx->base.is_jmp = DISAS_STOP;
21743                    } else {
21744                        /* case NM_PREFE */
21745                        check_eva(ctx);
21746                        check_cp0_enabled(ctx);
21747                        /* Treat as NOP. */
21748                    }
21749                    break;
21750                case NM_LHE:
21751                    check_eva(ctx);
21752                    check_cp0_enabled(ctx);
21753                    gen_ld(ctx, OPC_LHE, rt, rs, s);
21754                    break;
21755                case NM_SHE:
21756                    check_eva(ctx);
21757                    check_cp0_enabled(ctx);
21758                    gen_st(ctx, OPC_SHE, rt, rs, s);
21759                    break;
21760                case NM_LHUE:
21761                    check_eva(ctx);
21762                    check_cp0_enabled(ctx);
21763                    gen_ld(ctx, OPC_LHUE, rt, rs, s);
21764                    break;
21765                case NM_CACHEE:
21766                    check_nms_dl_il_sl_tl_l2c(ctx);
21767                    gen_cache_operation(ctx, rt, rs, s);
21768                    break;
21769                case NM_LWE:
21770                    check_eva(ctx);
21771                    check_cp0_enabled(ctx);
21772                    gen_ld(ctx, OPC_LWE, rt, rs, s);
21773                    break;
21774                case NM_SWE:
21775                    check_eva(ctx);
21776                    check_cp0_enabled(ctx);
21777                    gen_st(ctx, OPC_SWE, rt, rs, s);
21778                    break;
21779                case NM_P_LLE:
21780                    switch (extract32(ctx->opcode, 2, 2)) {
21781                    case NM_LLE:
21782                        check_xnp(ctx);
21783                        check_eva(ctx);
21784                        check_cp0_enabled(ctx);
21785                        gen_ld(ctx, OPC_LLE, rt, rs, s);
21786                        break;
21787                    case NM_LLWPE:
21788                        check_xnp(ctx);
21789                        check_eva(ctx);
21790                        check_cp0_enabled(ctx);
21791                        gen_llwp(ctx, rs, 0, rt, extract32(ctx->opcode, 3, 5));
21792                        break;
21793                    default:
21794                        generate_exception_end(ctx, EXCP_RI);
21795                        break;
21796                    }
21797                    break;
21798                case NM_P_SCE:
21799                    switch (extract32(ctx->opcode, 2, 2)) {
21800                    case NM_SCE:
21801                        check_xnp(ctx);
21802                        check_eva(ctx);
21803                        check_cp0_enabled(ctx);
21804                        gen_st_cond(ctx, rt, rs, s, MO_TESL, true);
21805                        break;
21806                    case NM_SCWPE:
21807                        check_xnp(ctx);
21808                        check_eva(ctx);
21809                        check_cp0_enabled(ctx);
21810                        gen_scwp(ctx, rs, 0, rt, extract32(ctx->opcode, 3, 5),
21811                                 true);
21812                        break;
21813                    default:
21814                        generate_exception_end(ctx, EXCP_RI);
21815                        break;
21816                    }
21817                    break;
21818                }
21819                break;
21820            case NM_P_LS_WM:
21821            case NM_P_LS_UAWM:
21822                check_nms(ctx);
21823                {
21824                    int count = extract32(ctx->opcode, 12, 3);
21825                    int counter = 0;
21826
21827                    offset = sextract32(ctx->opcode, 15, 1) << 8 |
21828                             extract32(ctx->opcode, 0, 8);
21829                    TCGv va = tcg_temp_new();
21830                    TCGv t1 = tcg_temp_new();
21831                    TCGMemOp memop = (extract32(ctx->opcode, 8, 3)) ==
21832                                      NM_P_LS_UAWM ? MO_UNALN : 0;
21833
21834                    count = (count == 0) ? 8 : count;
21835                    while (counter != count) {
21836                        int this_rt = ((rt + counter) & 0x1f) | (rt & 0x10);
21837                        int this_offset = offset + (counter << 2);
21838
21839                        gen_base_offset_addr(ctx, va, rs, this_offset);
21840
21841                        switch (extract32(ctx->opcode, 11, 1)) {
21842                        case NM_LWM:
21843                            tcg_gen_qemu_ld_tl(t1, va, ctx->mem_idx,
21844                                               memop | MO_TESL);
21845                            gen_store_gpr(t1, this_rt);
21846                            if ((this_rt == rs) &&
21847                                (counter != (count - 1))) {
21848                                /* UNPREDICTABLE */
21849                            }
21850                            break;
21851                        case NM_SWM:
21852                            this_rt = (rt == 0) ? 0 : this_rt;
21853                            gen_load_gpr(t1, this_rt);
21854                            tcg_gen_qemu_st_tl(t1, va, ctx->mem_idx,
21855                                               memop | MO_TEUL);
21856                            break;
21857                        }
21858                        counter++;
21859                    }
21860                    tcg_temp_free(va);
21861                    tcg_temp_free(t1);
21862                }
21863                break;
21864            default:
21865                generate_exception_end(ctx, EXCP_RI);
21866                break;
21867            }
21868        }
21869        break;
21870    case NM_MOVE_BALC:
21871        check_nms(ctx);
21872        {
21873            TCGv t0 = tcg_temp_new();
21874            int32_t s = sextract32(ctx->opcode, 0, 1) << 21 |
21875                        extract32(ctx->opcode, 1, 20) << 1;
21876            rd = (extract32(ctx->opcode, 24, 1)) == 0 ? 4 : 5;
21877            rt = decode_gpr_gpr4_zero(extract32(ctx->opcode, 25, 1) << 3 |
21878                            extract32(ctx->opcode, 21, 3));
21879            gen_load_gpr(t0, rt);
21880            tcg_gen_mov_tl(cpu_gpr[rd], t0);
21881            gen_compute_branch_nm(ctx, OPC_BGEZAL, 4, 0, 0, s);
21882            tcg_temp_free(t0);
21883        }
21884        break;
21885    case NM_P_BAL:
21886        {
21887            int32_t s = sextract32(ctx->opcode, 0, 1) << 25 |
21888                        extract32(ctx->opcode, 1, 24) << 1;
21889
21890            if ((extract32(ctx->opcode, 25, 1)) == 0) {
21891                /* BC */
21892                gen_compute_branch_nm(ctx, OPC_BEQ, 4, 0, 0, s);
21893            } else {
21894                /* BALC */
21895                gen_compute_branch_nm(ctx, OPC_BGEZAL, 4, 0, 0, s);
21896            }
21897        }
21898        break;
21899    case NM_P_J:
21900        switch (extract32(ctx->opcode, 12, 4)) {
21901        case NM_JALRC:
21902        case NM_JALRC_HB:
21903            gen_compute_branch_nm(ctx, OPC_JALR, 4, rs, rt, 0);
21904            break;
21905        case NM_P_BALRSC:
21906            gen_compute_nanomips_pbalrsc_branch(ctx, rs, rt);
21907            break;
21908        default:
21909            generate_exception_end(ctx, EXCP_RI);
21910            break;
21911        }
21912        break;
21913    case NM_P_BR1:
21914        {
21915            int32_t s = sextract32(ctx->opcode, 0, 1) << 14 |
21916                        extract32(ctx->opcode, 1, 13) << 1;
21917            switch (extract32(ctx->opcode, 14, 2)) {
21918            case NM_BEQC:
21919                check_nms(ctx);
21920                gen_compute_branch_nm(ctx, OPC_BEQ, 4, rs, rt, s);
21921                break;
21922            case NM_P_BR3A:
21923                s = sextract32(ctx->opcode, 0, 1) << 14 |
21924                    extract32(ctx->opcode, 1, 13) << 1;
21925                check_cp1_enabled(ctx);
21926                switch (extract32(ctx->opcode, 16, 5)) {
21927                case NM_BC1EQZC:
21928                    gen_compute_branch_cp1_nm(ctx, OPC_BC1EQZ, rt, s);
21929                    break;
21930                case NM_BC1NEZC:
21931                    gen_compute_branch_cp1_nm(ctx, OPC_BC1NEZ, rt, s);
21932                    break;
21933                case NM_BPOSGE32C:
21934                    check_dsp_r3(ctx);
21935                    {
21936                        int32_t imm = extract32(ctx->opcode, 1, 13) |
21937                                      extract32(ctx->opcode, 0, 1) << 13;
21938
21939                        gen_compute_branch_nm(ctx, OPC_BPOSGE32, 4, -1, -2,
21940                                              imm);
21941                    }
21942                    break;
21943                default:
21944                    generate_exception_end(ctx, EXCP_RI);
21945                    break;
21946                }
21947                break;
21948            case NM_BGEC:
21949                if (rs == rt) {
21950                    gen_compute_compact_branch_nm(ctx, OPC_BC, rs, rt, s);
21951                } else {
21952                    gen_compute_compact_branch_nm(ctx, OPC_BGEC, rs, rt, s);
21953                }
21954                break;
21955            case NM_BGEUC:
21956                if (rs == rt || rt == 0) {
21957                    gen_compute_compact_branch_nm(ctx, OPC_BC, 0, 0, s);
21958                } else if (rs == 0) {
21959                    gen_compute_compact_branch_nm(ctx, OPC_BEQZC, rt, 0, s);
21960                } else {
21961                    gen_compute_compact_branch_nm(ctx, OPC_BGEUC, rs, rt, s);
21962                }
21963                break;
21964            }
21965        }
21966        break;
21967    case NM_P_BR2:
21968        {
21969            int32_t s = sextract32(ctx->opcode, 0, 1) << 14 |
21970                        extract32(ctx->opcode, 1, 13) << 1;
21971            switch (extract32(ctx->opcode, 14, 2)) {
21972            case NM_BNEC:
21973                check_nms(ctx);
21974                gen_compute_branch_nm(ctx, OPC_BNE, 4, rs, rt, s);
21975                break;
21976            case NM_BLTC:
21977                if (rs != 0 && rt != 0 && rs == rt) {
21978                    /* NOP */
21979                    ctx->hflags |= MIPS_HFLAG_FBNSLOT;
21980                } else {
21981                    gen_compute_compact_branch_nm(ctx, OPC_BLTC, rs, rt, s);
21982                }
21983                break;
21984            case NM_BLTUC:
21985                if (rs == 0 || rs == rt) {
21986                    /* NOP */
21987                    ctx->hflags |= MIPS_HFLAG_FBNSLOT;
21988                } else {
21989                    gen_compute_compact_branch_nm(ctx, OPC_BLTUC, rs, rt, s);
21990                }
21991                break;
21992            default:
21993                generate_exception_end(ctx, EXCP_RI);
21994                break;
21995            }
21996        }
21997        break;
21998    case NM_P_BRI:
21999        {
22000            int32_t s = sextract32(ctx->opcode, 0, 1) << 11 |
22001                        extract32(ctx->opcode, 1, 10) << 1;
22002            uint32_t u = extract32(ctx->opcode, 11, 7);
22003
22004            gen_compute_imm_branch(ctx, extract32(ctx->opcode, 18, 3),
22005                                   rt, u, s);
22006        }
22007        break;
22008    default:
22009        generate_exception_end(ctx, EXCP_RI);
22010        break;
22011    }
22012    return 4;
22013}
22014
22015static int decode_nanomips_opc(CPUMIPSState *env, DisasContext *ctx)
22016{
22017    uint32_t op;
22018    int rt = decode_gpr_gpr3(NANOMIPS_EXTRACT_RT3(ctx->opcode));
22019    int rs = decode_gpr_gpr3(NANOMIPS_EXTRACT_RS3(ctx->opcode));
22020    int rd = decode_gpr_gpr3(NANOMIPS_EXTRACT_RD3(ctx->opcode));
22021    int offset;
22022    int imm;
22023
22024    /* make sure instructions are on a halfword boundary */
22025    if (ctx->base.pc_next & 0x1) {
22026        TCGv tmp = tcg_const_tl(ctx->base.pc_next);
22027        tcg_gen_st_tl(tmp, cpu_env, offsetof(CPUMIPSState, CP0_BadVAddr));
22028        tcg_temp_free(tmp);
22029        generate_exception_end(ctx, EXCP_AdEL);
22030        return 2;
22031    }
22032
22033    op = extract32(ctx->opcode, 10, 6);
22034    switch (op) {
22035    case NM_P16_MV:
22036        rt = NANOMIPS_EXTRACT_RD5(ctx->opcode);
22037        if (rt != 0) {
22038            /* MOVE */
22039            rs = NANOMIPS_EXTRACT_RS5(ctx->opcode);
22040            gen_arith(ctx, OPC_ADDU, rt, rs, 0);
22041        } else {
22042            /* P16.RI */
22043            switch (extract32(ctx->opcode, 3, 2)) {
22044            case NM_P16_SYSCALL:
22045                if (extract32(ctx->opcode, 2, 1) == 0) {
22046                    generate_exception_end(ctx, EXCP_SYSCALL);
22047                } else {
22048                    generate_exception_end(ctx, EXCP_RI);
22049                }
22050                break;
22051            case NM_BREAK16:
22052                generate_exception_end(ctx, EXCP_BREAK);
22053                break;
22054            case NM_SDBBP16:
22055                if (is_uhi(extract32(ctx->opcode, 0, 3))) {
22056                    gen_helper_do_semihosting(cpu_env);
22057                } else {
22058                    if (ctx->hflags & MIPS_HFLAG_SBRI) {
22059                        generate_exception_end(ctx, EXCP_RI);
22060                    } else {
22061                        generate_exception_end(ctx, EXCP_DBp);
22062                    }
22063                }
22064                break;
22065            default:
22066                generate_exception_end(ctx, EXCP_RI);
22067                break;
22068            }
22069        }
22070        break;
22071    case NM_P16_SHIFT:
22072        {
22073            int shift = extract32(ctx->opcode, 0, 3);
22074            uint32_t opc = 0;
22075            shift = (shift == 0) ? 8 : shift;
22076
22077            switch (extract32(ctx->opcode, 3, 1)) {
22078            case NM_SLL16:
22079                opc = OPC_SLL;
22080                break;
22081            case NM_SRL16:
22082                opc = OPC_SRL;
22083                break;
22084            }
22085            gen_shift_imm(ctx, opc, rt, rs, shift);
22086        }
22087        break;
22088    case NM_P16C:
22089        switch (ctx->opcode & 1) {
22090        case NM_POOL16C_0:
22091            gen_pool16c_nanomips_insn(ctx);
22092            break;
22093        case NM_LWXS16:
22094            gen_ldxs(ctx, rt, rs, rd);
22095            break;
22096        }
22097        break;
22098    case NM_P16_A1:
22099        switch (extract32(ctx->opcode, 6, 1)) {
22100        case NM_ADDIUR1SP:
22101            imm = extract32(ctx->opcode, 0, 6) << 2;
22102            gen_arith_imm(ctx, OPC_ADDIU, rt, 29, imm);
22103            break;
22104        default:
22105            generate_exception_end(ctx, EXCP_RI);
22106            break;
22107        }
22108        break;
22109    case NM_P16_A2:
22110        switch (extract32(ctx->opcode, 3, 1)) {
22111        case NM_ADDIUR2:
22112            imm = extract32(ctx->opcode, 0, 3) << 2;
22113            gen_arith_imm(ctx, OPC_ADDIU, rt, rs, imm);
22114            break;
22115        case NM_P_ADDIURS5:
22116            rt = extract32(ctx->opcode, 5, 5);
22117            if (rt != 0) {
22118                /* imm = sign_extend(s[3] . s[2:0] , from_nbits = 4) */
22119                imm = (sextract32(ctx->opcode, 4, 1) << 3) |
22120                      (extract32(ctx->opcode, 0, 3));
22121                gen_arith_imm(ctx, OPC_ADDIU, rt, rt, imm);
22122            }
22123            break;
22124        }
22125        break;
22126    case NM_P16_ADDU:
22127        switch (ctx->opcode & 0x1) {
22128        case NM_ADDU16:
22129            gen_arith(ctx, OPC_ADDU, rd, rs, rt);
22130            break;
22131        case NM_SUBU16:
22132            gen_arith(ctx, OPC_SUBU, rd, rs, rt);
22133            break;
22134        }
22135        break;
22136    case NM_P16_4X4:
22137        rt = (extract32(ctx->opcode, 9, 1) << 3) |
22138              extract32(ctx->opcode, 5, 3);
22139        rs = (extract32(ctx->opcode, 4, 1) << 3) |
22140              extract32(ctx->opcode, 0, 3);
22141        rt = decode_gpr_gpr4(rt);
22142        rs = decode_gpr_gpr4(rs);
22143        switch ((extract32(ctx->opcode, 7, 2) & 0x2) |
22144                (extract32(ctx->opcode, 3, 1))) {
22145        case NM_ADDU4X4:
22146            check_nms(ctx);
22147            gen_arith(ctx, OPC_ADDU, rt, rs, rt);
22148            break;
22149        case NM_MUL4X4:
22150            check_nms(ctx);
22151            gen_r6_muldiv(ctx, R6_OPC_MUL, rt, rs, rt);
22152            break;
22153        default:
22154            generate_exception_end(ctx, EXCP_RI);
22155            break;
22156        }
22157        break;
22158    case NM_LI16:
22159        {
22160            int imm = extract32(ctx->opcode, 0, 7);
22161            imm = (imm == 0x7f ? -1 : imm);
22162            if (rt != 0) {
22163                tcg_gen_movi_tl(cpu_gpr[rt], imm);
22164            }
22165        }
22166        break;
22167    case NM_ANDI16:
22168        {
22169            uint32_t u = extract32(ctx->opcode, 0, 4);
22170            u = (u == 12) ? 0xff :
22171                (u == 13) ? 0xffff : u;
22172            gen_logic_imm(ctx, OPC_ANDI, rt, rs, u);
22173        }
22174        break;
22175    case NM_P16_LB:
22176        offset = extract32(ctx->opcode, 0, 2);
22177        switch (extract32(ctx->opcode, 2, 2)) {
22178        case NM_LB16:
22179            gen_ld(ctx, OPC_LB, rt, rs, offset);
22180            break;
22181        case NM_SB16:
22182            rt = decode_gpr_gpr3_src_store(
22183                     NANOMIPS_EXTRACT_RT3(ctx->opcode));
22184            gen_st(ctx, OPC_SB, rt, rs, offset);
22185            break;
22186        case NM_LBU16:
22187            gen_ld(ctx, OPC_LBU, rt, rs, offset);
22188            break;
22189        default:
22190            generate_exception_end(ctx, EXCP_RI);
22191            break;
22192        }
22193        break;
22194    case NM_P16_LH:
22195        offset = extract32(ctx->opcode, 1, 2) << 1;
22196        switch ((extract32(ctx->opcode, 3, 1) << 1) | (ctx->opcode & 1)) {
22197        case NM_LH16:
22198            gen_ld(ctx, OPC_LH, rt, rs, offset);
22199            break;
22200        case NM_SH16:
22201            rt = decode_gpr_gpr3_src_store(
22202                     NANOMIPS_EXTRACT_RT3(ctx->opcode));
22203            gen_st(ctx, OPC_SH, rt, rs, offset);
22204            break;
22205        case NM_LHU16:
22206            gen_ld(ctx, OPC_LHU, rt, rs, offset);
22207            break;
22208        default:
22209            generate_exception_end(ctx, EXCP_RI);
22210            break;
22211        }
22212        break;
22213    case NM_LW16:
22214        offset = extract32(ctx->opcode, 0, 4) << 2;
22215        gen_ld(ctx, OPC_LW, rt, rs, offset);
22216        break;
22217    case NM_LWSP16:
22218        rt = NANOMIPS_EXTRACT_RD5(ctx->opcode);
22219        offset = extract32(ctx->opcode, 0, 5) << 2;
22220        gen_ld(ctx, OPC_LW, rt, 29, offset);
22221        break;
22222    case NM_LW4X4:
22223        check_nms(ctx);
22224        rt = (extract32(ctx->opcode, 9, 1) << 3) |
22225             extract32(ctx->opcode, 5, 3);
22226        rs = (extract32(ctx->opcode, 4, 1) << 3) |
22227             extract32(ctx->opcode, 0, 3);
22228        offset = (extract32(ctx->opcode, 3, 1) << 3) |
22229                 (extract32(ctx->opcode, 8, 1) << 2);
22230        rt = decode_gpr_gpr4(rt);
22231        rs = decode_gpr_gpr4(rs);
22232        gen_ld(ctx, OPC_LW, rt, rs, offset);
22233        break;
22234    case NM_SW4X4:
22235        check_nms(ctx);
22236        rt = (extract32(ctx->opcode, 9, 1) << 3) |
22237             extract32(ctx->opcode, 5, 3);
22238        rs = (extract32(ctx->opcode, 4, 1) << 3) |
22239             extract32(ctx->opcode, 0, 3);
22240        offset = (extract32(ctx->opcode, 3, 1) << 3) |
22241                 (extract32(ctx->opcode, 8, 1) << 2);
22242        rt = decode_gpr_gpr4_zero(rt);
22243        rs = decode_gpr_gpr4(rs);
22244        gen_st(ctx, OPC_SW, rt, rs, offset);
22245        break;
22246    case NM_LWGP16:
22247        offset = extract32(ctx->opcode, 0, 7) << 2;
22248        gen_ld(ctx, OPC_LW, rt, 28, offset);
22249        break;
22250    case NM_SWSP16:
22251        rt = NANOMIPS_EXTRACT_RD5(ctx->opcode);
22252        offset = extract32(ctx->opcode, 0, 5) << 2;
22253        gen_st(ctx, OPC_SW, rt, 29, offset);
22254        break;
22255    case NM_SW16:
22256        rt = decode_gpr_gpr3_src_store(
22257                 NANOMIPS_EXTRACT_RT3(ctx->opcode));
22258        rs = decode_gpr_gpr3(NANOMIPS_EXTRACT_RS3(ctx->opcode));
22259        offset = extract32(ctx->opcode, 0, 4) << 2;
22260        gen_st(ctx, OPC_SW, rt, rs, offset);
22261        break;
22262    case NM_SWGP16:
22263        rt = decode_gpr_gpr3_src_store(
22264                 NANOMIPS_EXTRACT_RT3(ctx->opcode));
22265        offset = extract32(ctx->opcode, 0, 7) << 2;
22266        gen_st(ctx, OPC_SW, rt, 28, offset);
22267        break;
22268    case NM_BC16:
22269        gen_compute_branch_nm(ctx, OPC_BEQ, 2, 0, 0,
22270                           (sextract32(ctx->opcode, 0, 1) << 10) |
22271                           (extract32(ctx->opcode, 1, 9) << 1));
22272        break;
22273    case NM_BALC16:
22274        gen_compute_branch_nm(ctx, OPC_BGEZAL, 2, 0, 0,
22275                           (sextract32(ctx->opcode, 0, 1) << 10) |
22276                           (extract32(ctx->opcode, 1, 9) << 1));
22277        break;
22278    case NM_BEQZC16:
22279        gen_compute_branch_nm(ctx, OPC_BEQ, 2, rt, 0,
22280                           (sextract32(ctx->opcode, 0, 1) << 7) |
22281                           (extract32(ctx->opcode, 1, 6) << 1));
22282        break;
22283    case NM_BNEZC16:
22284        gen_compute_branch_nm(ctx, OPC_BNE, 2, rt, 0,
22285                           (sextract32(ctx->opcode, 0, 1) << 7) |
22286                           (extract32(ctx->opcode, 1, 6) << 1));
22287        break;
22288    case NM_P16_BR:
22289        switch (ctx->opcode & 0xf) {
22290        case 0:
22291            /* P16.JRC */
22292            switch (extract32(ctx->opcode, 4, 1)) {
22293            case NM_JRC:
22294                gen_compute_branch_nm(ctx, OPC_JR, 2,
22295                                   extract32(ctx->opcode, 5, 5), 0, 0);
22296                break;
22297            case NM_JALRC16:
22298                gen_compute_branch_nm(ctx, OPC_JALR, 2,
22299                                   extract32(ctx->opcode, 5, 5), 31, 0);
22300                break;
22301            }
22302            break;
22303        default:
22304            {
22305                /* P16.BRI */
22306                uint32_t opc = extract32(ctx->opcode, 4, 3) <
22307                               extract32(ctx->opcode, 7, 3) ? OPC_BEQ : OPC_BNE;
22308                gen_compute_branch_nm(ctx, opc, 2, rs, rt,
22309                                   extract32(ctx->opcode, 0, 4) << 1);
22310            }
22311            break;
22312        }
22313        break;
22314    case NM_P16_SR:
22315        {
22316            int count = extract32(ctx->opcode, 0, 4);
22317            int u = extract32(ctx->opcode, 4, 4) << 4;
22318
22319            rt = 30 + extract32(ctx->opcode, 9, 1);
22320            switch (extract32(ctx->opcode, 8, 1)) {
22321            case NM_SAVE16:
22322                gen_save(ctx, rt, count, 0, u);
22323                break;
22324            case NM_RESTORE_JRC16:
22325                gen_restore(ctx, rt, count, 0, u);
22326                gen_compute_branch_nm(ctx, OPC_JR, 2, 31, 0, 0);
22327                break;
22328            }
22329        }
22330        break;
22331    case NM_MOVEP:
22332    case NM_MOVEPREV:
22333        check_nms(ctx);
22334        {
22335            static const int gpr2reg1[] = {4, 5, 6, 7};
22336            static const int gpr2reg2[] = {5, 6, 7, 8};
22337            int re;
22338            int rd2 = extract32(ctx->opcode, 3, 1) << 1 |
22339                      extract32(ctx->opcode, 8, 1);
22340            int r1 = gpr2reg1[rd2];
22341            int r2 = gpr2reg2[rd2];
22342            int r3 = extract32(ctx->opcode, 4, 1) << 3 |
22343                     extract32(ctx->opcode, 0, 3);
22344            int r4 = extract32(ctx->opcode, 9, 1) << 3 |
22345                     extract32(ctx->opcode, 5, 3);
22346            TCGv t0 = tcg_temp_new();
22347            TCGv t1 = tcg_temp_new();
22348            if (op == NM_MOVEP) {
22349                rd = r1;
22350                re = r2;
22351                rs = decode_gpr_gpr4_zero(r3);
22352                rt = decode_gpr_gpr4_zero(r4);
22353            } else {
22354                rd = decode_gpr_gpr4(r3);
22355                re = decode_gpr_gpr4(r4);
22356                rs = r1;
22357                rt = r2;
22358            }
22359            gen_load_gpr(t0, rs);
22360            gen_load_gpr(t1, rt);
22361            tcg_gen_mov_tl(cpu_gpr[rd], t0);
22362            tcg_gen_mov_tl(cpu_gpr[re], t1);
22363            tcg_temp_free(t0);
22364            tcg_temp_free(t1);
22365        }
22366        break;
22367    default:
22368        return decode_nanomips_32_48_opc(env, ctx);
22369    }
22370
22371    return 2;
22372}
22373
22374
22375/* SmartMIPS extension to MIPS32 */
22376
22377#if defined(TARGET_MIPS64)
22378
22379/* MDMX extension to MIPS64 */
22380
22381#endif
22382
22383/* MIPSDSP functions. */
22384static void gen_mipsdsp_ld(DisasContext *ctx, uint32_t opc,
22385                           int rd, int base, int offset)
22386{
22387    TCGv t0;
22388
22389    check_dsp(ctx);
22390    t0 = tcg_temp_new();
22391
22392    if (base == 0) {
22393        gen_load_gpr(t0, offset);
22394    } else if (offset == 0) {
22395        gen_load_gpr(t0, base);
22396    } else {
22397        gen_op_addr_add(ctx, t0, cpu_gpr[base], cpu_gpr[offset]);
22398    }
22399
22400    switch (opc) {
22401    case OPC_LBUX:
22402        tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_UB);
22403        gen_store_gpr(t0, rd);
22404        break;
22405    case OPC_LHX:
22406        tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TESW);
22407        gen_store_gpr(t0, rd);
22408        break;
22409    case OPC_LWX:
22410        tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TESL);
22411        gen_store_gpr(t0, rd);
22412        break;
22413#if defined(TARGET_MIPS64)
22414    case OPC_LDX:
22415        tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEQ);
22416        gen_store_gpr(t0, rd);
22417        break;
22418#endif
22419    }
22420    tcg_temp_free(t0);
22421}
22422
22423static void gen_mipsdsp_arith(DisasContext *ctx, uint32_t op1, uint32_t op2,
22424                              int ret, int v1, int v2)
22425{
22426    TCGv v1_t;
22427    TCGv v2_t;
22428
22429    if (ret == 0) {
22430        /* Treat as NOP. */
22431        return;
22432    }
22433
22434    v1_t = tcg_temp_new();
22435    v2_t = tcg_temp_new();
22436
22437    gen_load_gpr(v1_t, v1);
22438    gen_load_gpr(v2_t, v2);
22439
22440    switch (op1) {
22441    /* OPC_MULT_G_2E is equal OPC_ADDUH_QB_DSP */
22442    case OPC_MULT_G_2E:
22443        check_dsp_r2(ctx);
22444        switch (op2) {
22445        case OPC_ADDUH_QB:
22446            gen_helper_adduh_qb(cpu_gpr[ret], v1_t, v2_t);
22447            break;
22448        case OPC_ADDUH_R_QB:
22449            gen_helper_adduh_r_qb(cpu_gpr[ret], v1_t, v2_t);
22450            break;
22451        case OPC_ADDQH_PH:
22452            gen_helper_addqh_ph(cpu_gpr[ret], v1_t, v2_t);
22453            break;
22454        case OPC_ADDQH_R_PH:
22455            gen_helper_addqh_r_ph(cpu_gpr[ret], v1_t, v2_t);
22456            break;
22457        case OPC_ADDQH_W:
22458            gen_helper_addqh_w(cpu_gpr[ret], v1_t, v2_t);
22459            break;
22460        case OPC_ADDQH_R_W:
22461            gen_helper_addqh_r_w(cpu_gpr[ret], v1_t, v2_t);
22462            break;
22463        case OPC_SUBUH_QB:
22464            gen_helper_subuh_qb(cpu_gpr[ret], v1_t, v2_t);
22465            break;
22466        case OPC_SUBUH_R_QB:
22467            gen_helper_subuh_r_qb(cpu_gpr[ret], v1_t, v2_t);
22468            break;
22469        case OPC_SUBQH_PH:
22470            gen_helper_subqh_ph(cpu_gpr[ret], v1_t, v2_t);
22471            break;
22472        case OPC_SUBQH_R_PH:
22473            gen_helper_subqh_r_ph(cpu_gpr[ret], v1_t, v2_t);
22474            break;
22475        case OPC_SUBQH_W:
22476            gen_helper_subqh_w(cpu_gpr[ret], v1_t, v2_t);
22477            break;
22478        case OPC_SUBQH_R_W:
22479            gen_helper_subqh_r_w(cpu_gpr[ret], v1_t, v2_t);
22480            break;
22481        }
22482        break;
22483    case OPC_ABSQ_S_PH_DSP:
22484        switch (op2) {
22485        case OPC_ABSQ_S_QB:
22486            check_dsp_r2(ctx);
22487            gen_helper_absq_s_qb(cpu_gpr[ret], v2_t, cpu_env);
22488            break;
22489        case OPC_ABSQ_S_PH:
22490            check_dsp(ctx);
22491            gen_helper_absq_s_ph(cpu_gpr[ret], v2_t, cpu_env);
22492            break;
22493        case OPC_ABSQ_S_W:
22494            check_dsp(ctx);
22495            gen_helper_absq_s_w(cpu_gpr[ret], v2_t, cpu_env);
22496            break;
22497        case OPC_PRECEQ_W_PHL:
22498            check_dsp(ctx);
22499            tcg_gen_andi_tl(cpu_gpr[ret], v2_t, 0xFFFF0000);
22500            tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]);
22501            break;
22502        case OPC_PRECEQ_W_PHR:
22503            check_dsp(ctx);
22504            tcg_gen_andi_tl(cpu_gpr[ret], v2_t, 0x0000FFFF);
22505            tcg_gen_shli_tl(cpu_gpr[ret], cpu_gpr[ret], 16);
22506            tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]);
22507            break;
22508        case OPC_PRECEQU_PH_QBL:
22509            check_dsp(ctx);
22510            gen_helper_precequ_ph_qbl(cpu_gpr[ret], v2_t);
22511            break;
22512        case OPC_PRECEQU_PH_QBR:
22513            check_dsp(ctx);
22514            gen_helper_precequ_ph_qbr(cpu_gpr[ret], v2_t);
22515            break;
22516        case OPC_PRECEQU_PH_QBLA:
22517            check_dsp(ctx);
22518            gen_helper_precequ_ph_qbla(cpu_gpr[ret], v2_t);
22519            break;
22520        case OPC_PRECEQU_PH_QBRA:
22521            check_dsp(ctx);
22522            gen_helper_precequ_ph_qbra(cpu_gpr[ret], v2_t);
22523            break;
22524        case OPC_PRECEU_PH_QBL:
22525            check_dsp(ctx);
22526            gen_helper_preceu_ph_qbl(cpu_gpr[ret], v2_t);
22527            break;
22528        case OPC_PRECEU_PH_QBR:
22529            check_dsp(ctx);
22530            gen_helper_preceu_ph_qbr(cpu_gpr[ret], v2_t);
22531            break;
22532        case OPC_PRECEU_PH_QBLA:
22533            check_dsp(ctx);
22534            gen_helper_preceu_ph_qbla(cpu_gpr[ret], v2_t);
22535            break;
22536        case OPC_PRECEU_PH_QBRA:
22537            check_dsp(ctx);
22538            gen_helper_preceu_ph_qbra(cpu_gpr[ret], v2_t);
22539            break;
22540        }
22541        break;
22542    case OPC_ADDU_QB_DSP:
22543        switch (op2) {
22544        case OPC_ADDQ_PH:
22545            check_dsp(ctx);
22546            gen_helper_addq_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22547            break;
22548        case OPC_ADDQ_S_PH:
22549            check_dsp(ctx);
22550            gen_helper_addq_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22551            break;
22552        case OPC_ADDQ_S_W:
22553            check_dsp(ctx);
22554            gen_helper_addq_s_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22555            break;
22556        case OPC_ADDU_QB:
22557            check_dsp(ctx);
22558            gen_helper_addu_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22559            break;
22560        case OPC_ADDU_S_QB:
22561            check_dsp(ctx);
22562            gen_helper_addu_s_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22563            break;
22564        case OPC_ADDU_PH:
22565            check_dsp_r2(ctx);
22566            gen_helper_addu_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22567            break;
22568        case OPC_ADDU_S_PH:
22569            check_dsp_r2(ctx);
22570            gen_helper_addu_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22571            break;
22572        case OPC_SUBQ_PH:
22573            check_dsp(ctx);
22574            gen_helper_subq_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22575            break;
22576        case OPC_SUBQ_S_PH:
22577            check_dsp(ctx);
22578            gen_helper_subq_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22579            break;
22580        case OPC_SUBQ_S_W:
22581            check_dsp(ctx);
22582            gen_helper_subq_s_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22583            break;
22584        case OPC_SUBU_QB:
22585            check_dsp(ctx);
22586            gen_helper_subu_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22587            break;
22588        case OPC_SUBU_S_QB:
22589            check_dsp(ctx);
22590            gen_helper_subu_s_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22591            break;
22592        case OPC_SUBU_PH:
22593            check_dsp_r2(ctx);
22594            gen_helper_subu_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22595            break;
22596        case OPC_SUBU_S_PH:
22597            check_dsp_r2(ctx);
22598            gen_helper_subu_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22599            break;
22600        case OPC_ADDSC:
22601            check_dsp(ctx);
22602            gen_helper_addsc(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22603            break;
22604        case OPC_ADDWC:
22605            check_dsp(ctx);
22606            gen_helper_addwc(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22607            break;
22608        case OPC_MODSUB:
22609            check_dsp(ctx);
22610            gen_helper_modsub(cpu_gpr[ret], v1_t, v2_t);
22611            break;
22612        case OPC_RADDU_W_QB:
22613            check_dsp(ctx);
22614            gen_helper_raddu_w_qb(cpu_gpr[ret], v1_t);
22615            break;
22616        }
22617        break;
22618    case OPC_CMPU_EQ_QB_DSP:
22619        switch (op2) {
22620        case OPC_PRECR_QB_PH:
22621            check_dsp_r2(ctx);
22622            gen_helper_precr_qb_ph(cpu_gpr[ret], v1_t, v2_t);
22623            break;
22624        case OPC_PRECRQ_QB_PH:
22625            check_dsp(ctx);
22626            gen_helper_precrq_qb_ph(cpu_gpr[ret], v1_t, v2_t);
22627            break;
22628        case OPC_PRECR_SRA_PH_W:
22629            check_dsp_r2(ctx);
22630            {
22631                TCGv_i32 sa_t = tcg_const_i32(v2);
22632                gen_helper_precr_sra_ph_w(cpu_gpr[ret], sa_t, v1_t,
22633                                          cpu_gpr[ret]);
22634                tcg_temp_free_i32(sa_t);
22635                break;
22636            }
22637        case OPC_PRECR_SRA_R_PH_W:
22638            check_dsp_r2(ctx);
22639            {
22640                TCGv_i32 sa_t = tcg_const_i32(v2);
22641                gen_helper_precr_sra_r_ph_w(cpu_gpr[ret], sa_t, v1_t,
22642                                            cpu_gpr[ret]);
22643                tcg_temp_free_i32(sa_t);
22644                break;
22645            }
22646        case OPC_PRECRQ_PH_W:
22647            check_dsp(ctx);
22648            gen_helper_precrq_ph_w(cpu_gpr[ret], v1_t, v2_t);
22649            break;
22650        case OPC_PRECRQ_RS_PH_W:
22651            check_dsp(ctx);
22652            gen_helper_precrq_rs_ph_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22653            break;
22654        case OPC_PRECRQU_S_QB_PH:
22655            check_dsp(ctx);
22656            gen_helper_precrqu_s_qb_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22657            break;
22658        }
22659        break;
22660#ifdef TARGET_MIPS64
22661    case OPC_ABSQ_S_QH_DSP:
22662        switch (op2) {
22663        case OPC_PRECEQ_L_PWL:
22664            check_dsp(ctx);
22665            tcg_gen_andi_tl(cpu_gpr[ret], v2_t, 0xFFFFFFFF00000000ull);
22666            break;
22667        case OPC_PRECEQ_L_PWR:
22668            check_dsp(ctx);
22669            tcg_gen_shli_tl(cpu_gpr[ret], v2_t, 32);
22670            break;
22671        case OPC_PRECEQ_PW_QHL:
22672            check_dsp(ctx);
22673            gen_helper_preceq_pw_qhl(cpu_gpr[ret], v2_t);
22674            break;
22675        case OPC_PRECEQ_PW_QHR:
22676            check_dsp(ctx);
22677            gen_helper_preceq_pw_qhr(cpu_gpr[ret], v2_t);
22678            break;
22679        case OPC_PRECEQ_PW_QHLA:
22680            check_dsp(ctx);
22681            gen_helper_preceq_pw_qhla(cpu_gpr[ret], v2_t);
22682            break;
22683        case OPC_PRECEQ_PW_QHRA:
22684            check_dsp(ctx);
22685            gen_helper_preceq_pw_qhra(cpu_gpr[ret], v2_t);
22686            break;
22687        case OPC_PRECEQU_QH_OBL:
22688            check_dsp(ctx);
22689            gen_helper_precequ_qh_obl(cpu_gpr[ret], v2_t);
22690            break;
22691        case OPC_PRECEQU_QH_OBR:
22692            check_dsp(ctx);
22693            gen_helper_precequ_qh_obr(cpu_gpr[ret], v2_t);
22694            break;
22695        case OPC_PRECEQU_QH_OBLA:
22696            check_dsp(ctx);
22697            gen_helper_precequ_qh_obla(cpu_gpr[ret], v2_t);
22698            break;
22699        case OPC_PRECEQU_QH_OBRA:
22700            check_dsp(ctx);
22701            gen_helper_precequ_qh_obra(cpu_gpr[ret], v2_t);
22702            break;
22703        case OPC_PRECEU_QH_OBL:
22704            check_dsp(ctx);
22705            gen_helper_preceu_qh_obl(cpu_gpr[ret], v2_t);
22706            break;
22707        case OPC_PRECEU_QH_OBR:
22708            check_dsp(ctx);
22709            gen_helper_preceu_qh_obr(cpu_gpr[ret], v2_t);
22710            break;
22711        case OPC_PRECEU_QH_OBLA:
22712            check_dsp(ctx);
22713            gen_helper_preceu_qh_obla(cpu_gpr[ret], v2_t);
22714            break;
22715        case OPC_PRECEU_QH_OBRA:
22716            check_dsp(ctx);
22717            gen_helper_preceu_qh_obra(cpu_gpr[ret], v2_t);
22718            break;
22719        case OPC_ABSQ_S_OB:
22720            check_dsp_r2(ctx);
22721            gen_helper_absq_s_ob(cpu_gpr[ret], v2_t, cpu_env);
22722            break;
22723        case OPC_ABSQ_S_PW:
22724            check_dsp(ctx);
22725            gen_helper_absq_s_pw(cpu_gpr[ret], v2_t, cpu_env);
22726            break;
22727        case OPC_ABSQ_S_QH:
22728            check_dsp(ctx);
22729            gen_helper_absq_s_qh(cpu_gpr[ret], v2_t, cpu_env);
22730            break;
22731        }
22732        break;
22733    case OPC_ADDU_OB_DSP:
22734        switch (op2) {
22735        case OPC_RADDU_L_OB:
22736            check_dsp(ctx);
22737            gen_helper_raddu_l_ob(cpu_gpr[ret], v1_t);
22738            break;
22739        case OPC_SUBQ_PW:
22740            check_dsp(ctx);
22741            gen_helper_subq_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22742            break;
22743        case OPC_SUBQ_S_PW:
22744            check_dsp(ctx);
22745            gen_helper_subq_s_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22746            break;
22747        case OPC_SUBQ_QH:
22748            check_dsp(ctx);
22749            gen_helper_subq_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22750            break;
22751        case OPC_SUBQ_S_QH:
22752            check_dsp(ctx);
22753            gen_helper_subq_s_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22754            break;
22755        case OPC_SUBU_OB:
22756            check_dsp(ctx);
22757            gen_helper_subu_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22758            break;
22759        case OPC_SUBU_S_OB:
22760            check_dsp(ctx);
22761            gen_helper_subu_s_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22762            break;
22763        case OPC_SUBU_QH:
22764            check_dsp_r2(ctx);
22765            gen_helper_subu_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22766            break;
22767        case OPC_SUBU_S_QH:
22768            check_dsp_r2(ctx);
22769            gen_helper_subu_s_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22770            break;
22771        case OPC_SUBUH_OB:
22772            check_dsp_r2(ctx);
22773            gen_helper_subuh_ob(cpu_gpr[ret], v1_t, v2_t);
22774            break;
22775        case OPC_SUBUH_R_OB:
22776            check_dsp_r2(ctx);
22777            gen_helper_subuh_r_ob(cpu_gpr[ret], v1_t, v2_t);
22778            break;
22779        case OPC_ADDQ_PW:
22780            check_dsp(ctx);
22781            gen_helper_addq_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22782            break;
22783        case OPC_ADDQ_S_PW:
22784            check_dsp(ctx);
22785            gen_helper_addq_s_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22786            break;
22787        case OPC_ADDQ_QH:
22788            check_dsp(ctx);
22789            gen_helper_addq_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22790            break;
22791        case OPC_ADDQ_S_QH:
22792            check_dsp(ctx);
22793            gen_helper_addq_s_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22794            break;
22795        case OPC_ADDU_OB:
22796            check_dsp(ctx);
22797            gen_helper_addu_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22798            break;
22799        case OPC_ADDU_S_OB:
22800            check_dsp(ctx);
22801            gen_helper_addu_s_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22802            break;
22803        case OPC_ADDU_QH:
22804            check_dsp_r2(ctx);
22805            gen_helper_addu_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22806            break;
22807        case OPC_ADDU_S_QH:
22808            check_dsp_r2(ctx);
22809            gen_helper_addu_s_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22810            break;
22811        case OPC_ADDUH_OB:
22812            check_dsp_r2(ctx);
22813            gen_helper_adduh_ob(cpu_gpr[ret], v1_t, v2_t);
22814            break;
22815        case OPC_ADDUH_R_OB:
22816            check_dsp_r2(ctx);
22817            gen_helper_adduh_r_ob(cpu_gpr[ret], v1_t, v2_t);
22818            break;
22819        }
22820        break;
22821    case OPC_CMPU_EQ_OB_DSP:
22822        switch (op2) {
22823        case OPC_PRECR_OB_QH:
22824            check_dsp_r2(ctx);
22825            gen_helper_precr_ob_qh(cpu_gpr[ret], v1_t, v2_t);
22826            break;
22827        case OPC_PRECR_SRA_QH_PW:
22828            check_dsp_r2(ctx);
22829            {
22830                TCGv_i32 ret_t = tcg_const_i32(ret);
22831                gen_helper_precr_sra_qh_pw(v2_t, v1_t, v2_t, ret_t);
22832                tcg_temp_free_i32(ret_t);
22833                break;
22834            }
22835        case OPC_PRECR_SRA_R_QH_PW:
22836            check_dsp_r2(ctx);
22837            {
22838                TCGv_i32 sa_v = tcg_const_i32(ret);
22839                gen_helper_precr_sra_r_qh_pw(v2_t, v1_t, v2_t, sa_v);
22840                tcg_temp_free_i32(sa_v);
22841                break;
22842            }
22843        case OPC_PRECRQ_OB_QH:
22844            check_dsp(ctx);
22845            gen_helper_precrq_ob_qh(cpu_gpr[ret], v1_t, v2_t);
22846            break;
22847        case OPC_PRECRQ_PW_L:
22848            check_dsp(ctx);
22849            gen_helper_precrq_pw_l(cpu_gpr[ret], v1_t, v2_t);
22850            break;
22851        case OPC_PRECRQ_QH_PW:
22852            check_dsp(ctx);
22853            gen_helper_precrq_qh_pw(cpu_gpr[ret], v1_t, v2_t);
22854            break;
22855        case OPC_PRECRQ_RS_QH_PW:
22856            check_dsp(ctx);
22857            gen_helper_precrq_rs_qh_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22858            break;
22859        case OPC_PRECRQU_S_OB_QH:
22860            check_dsp(ctx);
22861            gen_helper_precrqu_s_ob_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22862            break;
22863        }
22864        break;
22865#endif
22866    }
22867
22868    tcg_temp_free(v1_t);
22869    tcg_temp_free(v2_t);
22870}
22871
22872static void gen_mipsdsp_shift(DisasContext *ctx, uint32_t opc,
22873                              int ret, int v1, int v2)
22874{
22875    uint32_t op2;
22876    TCGv t0;
22877    TCGv v1_t;
22878    TCGv v2_t;
22879
22880    if (ret == 0) {
22881        /* Treat as NOP. */
22882        return;
22883    }
22884
22885    t0 = tcg_temp_new();
22886    v1_t = tcg_temp_new();
22887    v2_t = tcg_temp_new();
22888
22889    tcg_gen_movi_tl(t0, v1);
22890    gen_load_gpr(v1_t, v1);
22891    gen_load_gpr(v2_t, v2);
22892
22893    switch (opc) {
22894    case OPC_SHLL_QB_DSP:
22895        {
22896            op2 = MASK_SHLL_QB(ctx->opcode);
22897            switch (op2) {
22898            case OPC_SHLL_QB:
22899                check_dsp(ctx);
22900                gen_helper_shll_qb(cpu_gpr[ret], t0, v2_t, cpu_env);
22901                break;
22902            case OPC_SHLLV_QB:
22903                check_dsp(ctx);
22904                gen_helper_shll_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22905                break;
22906            case OPC_SHLL_PH:
22907                check_dsp(ctx);
22908                gen_helper_shll_ph(cpu_gpr[ret], t0, v2_t, cpu_env);
22909                break;
22910            case OPC_SHLLV_PH:
22911                check_dsp(ctx);
22912                gen_helper_shll_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22913                break;
22914            case OPC_SHLL_S_PH:
22915                check_dsp(ctx);
22916                gen_helper_shll_s_ph(cpu_gpr[ret], t0, v2_t, cpu_env);
22917                break;
22918            case OPC_SHLLV_S_PH:
22919                check_dsp(ctx);
22920                gen_helper_shll_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22921                break;
22922            case OPC_SHLL_S_W:
22923                check_dsp(ctx);
22924                gen_helper_shll_s_w(cpu_gpr[ret], t0, v2_t, cpu_env);
22925                break;
22926            case OPC_SHLLV_S_W:
22927                check_dsp(ctx);
22928                gen_helper_shll_s_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22929                break;
22930            case OPC_SHRL_QB:
22931                check_dsp(ctx);
22932                gen_helper_shrl_qb(cpu_gpr[ret], t0, v2_t);
22933                break;
22934            case OPC_SHRLV_QB:
22935                check_dsp(ctx);
22936                gen_helper_shrl_qb(cpu_gpr[ret], v1_t, v2_t);
22937                break;
22938            case OPC_SHRL_PH:
22939                check_dsp_r2(ctx);
22940                gen_helper_shrl_ph(cpu_gpr[ret], t0, v2_t);
22941                break;
22942            case OPC_SHRLV_PH:
22943                check_dsp_r2(ctx);
22944                gen_helper_shrl_ph(cpu_gpr[ret], v1_t, v2_t);
22945                break;
22946            case OPC_SHRA_QB:
22947                check_dsp_r2(ctx);
22948                gen_helper_shra_qb(cpu_gpr[ret], t0, v2_t);
22949                break;
22950            case OPC_SHRA_R_QB:
22951                check_dsp_r2(ctx);
22952                gen_helper_shra_r_qb(cpu_gpr[ret], t0, v2_t);
22953                break;
22954            case OPC_SHRAV_QB:
22955                check_dsp_r2(ctx);
22956                gen_helper_shra_qb(cpu_gpr[ret], v1_t, v2_t);
22957                break;
22958            case OPC_SHRAV_R_QB:
22959                check_dsp_r2(ctx);
22960                gen_helper_shra_r_qb(cpu_gpr[ret], v1_t, v2_t);
22961                break;
22962            case OPC_SHRA_PH:
22963                check_dsp(ctx);
22964                gen_helper_shra_ph(cpu_gpr[ret], t0, v2_t);
22965                break;
22966            case OPC_SHRA_R_PH:
22967                check_dsp(ctx);
22968                gen_helper_shra_r_ph(cpu_gpr[ret], t0, v2_t);
22969                break;
22970            case OPC_SHRAV_PH:
22971                check_dsp(ctx);
22972                gen_helper_shra_ph(cpu_gpr[ret], v1_t, v2_t);
22973                break;
22974            case OPC_SHRAV_R_PH:
22975                check_dsp(ctx);
22976                gen_helper_shra_r_ph(cpu_gpr[ret], v1_t, v2_t);
22977                break;
22978            case OPC_SHRA_R_W:
22979                check_dsp(ctx);
22980                gen_helper_shra_r_w(cpu_gpr[ret], t0, v2_t);
22981                break;
22982            case OPC_SHRAV_R_W:
22983                check_dsp(ctx);
22984                gen_helper_shra_r_w(cpu_gpr[ret], v1_t, v2_t);
22985                break;
22986            default:            /* Invalid */
22987                MIPS_INVAL("MASK SHLL.QB");
22988                generate_exception_end(ctx, EXCP_RI);
22989                break;
22990            }
22991            break;
22992        }
22993#ifdef TARGET_MIPS64
22994    case OPC_SHLL_OB_DSP:
22995        op2 = MASK_SHLL_OB(ctx->opcode);
22996        switch (op2) {
22997        case OPC_SHLL_PW:
22998            check_dsp(ctx);
22999            gen_helper_shll_pw(cpu_gpr[ret], v2_t, t0, cpu_env);
23000            break;
23001        case OPC_SHLLV_PW:
23002            check_dsp(ctx);
23003            gen_helper_shll_pw(cpu_gpr[ret], v2_t, v1_t, cpu_env);
23004            break;
23005        case OPC_SHLL_S_PW:
23006            check_dsp(ctx);
23007            gen_helper_shll_s_pw(cpu_gpr[ret], v2_t, t0, cpu_env);
23008            break;
23009        case OPC_SHLLV_S_PW:
23010            check_dsp(ctx);
23011            gen_helper_shll_s_pw(cpu_gpr[ret], v2_t, v1_t, cpu_env);
23012            break;
23013        case OPC_SHLL_OB:
23014            check_dsp(ctx);
23015            gen_helper_shll_ob(cpu_gpr[ret], v2_t, t0, cpu_env);
23016            break;
23017        case OPC_SHLLV_OB:
23018            check_dsp(ctx);
23019            gen_helper_shll_ob(cpu_gpr[ret], v2_t, v1_t, cpu_env);
23020            break;
23021        case OPC_SHLL_QH:
23022            check_dsp(ctx);
23023            gen_helper_shll_qh(cpu_gpr[ret], v2_t, t0, cpu_env);
23024            break;
23025        case OPC_SHLLV_QH:
23026            check_dsp(ctx);
23027            gen_helper_shll_qh(cpu_gpr[ret], v2_t, v1_t, cpu_env);
23028            break;
23029        case OPC_SHLL_S_QH:
23030            check_dsp(ctx);
23031            gen_helper_shll_s_qh(cpu_gpr[ret], v2_t, t0, cpu_env);
23032            break;
23033        case OPC_SHLLV_S_QH:
23034            check_dsp(ctx);
23035            gen_helper_shll_s_qh(cpu_gpr[ret], v2_t, v1_t, cpu_env);
23036            break;
23037        case OPC_SHRA_OB:
23038            check_dsp_r2(ctx);
23039            gen_helper_shra_ob(cpu_gpr[ret], v2_t, t0);
23040            break;
23041        case OPC_SHRAV_OB:
23042            check_dsp_r2(ctx);
23043            gen_helper_shra_ob(cpu_gpr[ret], v2_t, v1_t);
23044            break;
23045        case OPC_SHRA_R_OB:
23046            check_dsp_r2(ctx);
23047            gen_helper_shra_r_ob(cpu_gpr[ret], v2_t, t0);
23048            break;
23049        case OPC_SHRAV_R_OB:
23050            check_dsp_r2(ctx);
23051            gen_helper_shra_r_ob(cpu_gpr[ret], v2_t, v1_t);
23052            break;
23053        case OPC_SHRA_PW:
23054            check_dsp(ctx);
23055            gen_helper_shra_pw(cpu_gpr[ret], v2_t, t0);
23056            break;
23057        case OPC_SHRAV_PW:
23058            check_dsp(ctx);
23059            gen_helper_shra_pw(cpu_gpr[ret], v2_t, v1_t);
23060            break;
23061        case OPC_SHRA_R_PW:
23062            check_dsp(ctx);
23063            gen_helper_shra_r_pw(cpu_gpr[ret], v2_t, t0);
23064            break;
23065        case OPC_SHRAV_R_PW:
23066            check_dsp(ctx);
23067            gen_helper_shra_r_pw(cpu_gpr[ret], v2_t, v1_t);
23068            break;
23069        case OPC_SHRA_QH:
23070            check_dsp(ctx);
23071            gen_helper_shra_qh(cpu_gpr[ret], v2_t, t0);
23072            break;
23073        case OPC_SHRAV_QH:
23074            check_dsp(ctx);
23075            gen_helper_shra_qh(cpu_gpr[ret], v2_t, v1_t);
23076            break;
23077        case OPC_SHRA_R_QH:
23078            check_dsp(ctx);
23079            gen_helper_shra_r_qh(cpu_gpr[ret], v2_t, t0);
23080            break;
23081        case OPC_SHRAV_R_QH:
23082            check_dsp(ctx);
23083            gen_helper_shra_r_qh(cpu_gpr[ret], v2_t, v1_t);
23084            break;
23085        case OPC_SHRL_OB:
23086            check_dsp(ctx);
23087            gen_helper_shrl_ob(cpu_gpr[ret], v2_t, t0);
23088            break;
23089        case OPC_SHRLV_OB:
23090            check_dsp(ctx);
23091            gen_helper_shrl_ob(cpu_gpr[ret], v2_t, v1_t);
23092            break;
23093        case OPC_SHRL_QH:
23094            check_dsp_r2(ctx);
23095            gen_helper_shrl_qh(cpu_gpr[ret], v2_t, t0);
23096            break;
23097        case OPC_SHRLV_QH:
23098            check_dsp_r2(ctx);
23099            gen_helper_shrl_qh(cpu_gpr[ret], v2_t, v1_t);
23100            break;
23101        default:            /* Invalid */
23102            MIPS_INVAL("MASK SHLL.OB");
23103            generate_exception_end(ctx, EXCP_RI);
23104            break;
23105        }
23106        break;
23107#endif
23108    }
23109
23110    tcg_temp_free(t0);
23111    tcg_temp_free(v1_t);
23112    tcg_temp_free(v2_t);
23113}
23114
23115static void gen_mipsdsp_multiply(DisasContext *ctx, uint32_t op1, uint32_t op2,
23116                                 int ret, int v1, int v2, int check_ret)
23117{
23118    TCGv_i32 t0;
23119    TCGv v1_t;
23120    TCGv v2_t;
23121
23122    if ((ret == 0) && (check_ret == 1)) {
23123        /* Treat as NOP. */
23124        return;
23125    }
23126
23127    t0 = tcg_temp_new_i32();
23128    v1_t = tcg_temp_new();
23129    v2_t = tcg_temp_new();
23130
23131    tcg_gen_movi_i32(t0, ret);
23132    gen_load_gpr(v1_t, v1);
23133    gen_load_gpr(v2_t, v2);
23134
23135    switch (op1) {
23136    /*
23137     * OPC_MULT_G_2E, OPC_ADDUH_QB_DSP, OPC_MUL_PH_DSP have
23138     * the same mask and op1.
23139     */
23140    case OPC_MULT_G_2E:
23141        check_dsp_r2(ctx);
23142        switch (op2) {
23143        case  OPC_MUL_PH:
23144            gen_helper_mul_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
23145            break;
23146        case  OPC_MUL_S_PH:
23147            gen_helper_mul_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
23148            break;
23149        case OPC_MULQ_S_W:
23150            gen_helper_mulq_s_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
23151            break;
23152        case OPC_MULQ_RS_W:
23153            gen_helper_mulq_rs_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
23154            break;
23155        }
23156        break;
23157    case OPC_DPA_W_PH_DSP:
23158        switch (op2) {
23159        case OPC_DPAU_H_QBL:
23160            check_dsp(ctx);
23161            gen_helper_dpau_h_qbl(t0, v1_t, v2_t, cpu_env);
23162            break;
23163        case OPC_DPAU_H_QBR:
23164            check_dsp(ctx);
23165            gen_helper_dpau_h_qbr(t0, v1_t, v2_t, cpu_env);
23166            break;
23167        case OPC_DPSU_H_QBL:
23168            check_dsp(ctx);
23169            gen_helper_dpsu_h_qbl(t0, v1_t, v2_t, cpu_env);
23170            break;
23171        case OPC_DPSU_H_QBR:
23172            check_dsp(ctx);
23173            gen_helper_dpsu_h_qbr(t0, v1_t, v2_t, cpu_env);
23174            break;
23175        case OPC_DPA_W_PH:
23176            check_dsp_r2(ctx);
23177            gen_helper_dpa_w_ph(t0, v1_t, v2_t, cpu_env);
23178            break;
23179        case OPC_DPAX_W_PH:
23180            check_dsp_r2(ctx);
23181            gen_helper_dpax_w_ph(t0, v1_t, v2_t, cpu_env);
23182            break;
23183        case OPC_DPAQ_S_W_PH:
23184            check_dsp(ctx);
23185            gen_helper_dpaq_s_w_ph(t0, v1_t, v2_t, cpu_env);
23186            break;
23187        case OPC_DPAQX_S_W_PH:
23188            check_dsp_r2(ctx);
23189            gen_helper_dpaqx_s_w_ph(t0, v1_t, v2_t, cpu_env);
23190            break;
23191        case OPC_DPAQX_SA_W_PH:
23192            check_dsp_r2(ctx);
23193            gen_helper_dpaqx_sa_w_ph(t0, v1_t, v2_t, cpu_env);
23194            break;
23195        case OPC_DPS_W_PH:
23196            check_dsp_r2(ctx);
23197            gen_helper_dps_w_ph(t0, v1_t, v2_t, cpu_env);
23198            break;
23199        case OPC_DPSX_W_PH:
23200            check_dsp_r2(ctx);
23201            gen_helper_dpsx_w_ph(t0, v1_t, v2_t, cpu_env);
23202            break;
23203        case OPC_DPSQ_S_W_PH:
23204            check_dsp(ctx);
23205            gen_helper_dpsq_s_w_ph(t0, v1_t, v2_t, cpu_env);
23206            break;
23207        case OPC_DPSQX_S_W_PH:
23208            check_dsp_r2(ctx);
23209            gen_helper_dpsqx_s_w_ph(t0, v1_t, v2_t, cpu_env);
23210            break;
23211        case OPC_DPSQX_SA_W_PH:
23212            check_dsp_r2(ctx);
23213            gen_helper_dpsqx_sa_w_ph(t0, v1_t, v2_t, cpu_env);
23214            break;
23215        case OPC_MULSAQ_S_W_PH:
23216            check_dsp(ctx);
23217            gen_helper_mulsaq_s_w_ph(t0, v1_t, v2_t, cpu_env);
23218            break;
23219        case OPC_DPAQ_SA_L_W:
23220            check_dsp(ctx);
23221            gen_helper_dpaq_sa_l_w(t0, v1_t, v2_t, cpu_env);
23222            break;
23223        case OPC_DPSQ_SA_L_W:
23224            check_dsp(ctx);
23225            gen_helper_dpsq_sa_l_w(t0, v1_t, v2_t, cpu_env);
23226            break;
23227        case OPC_MAQ_S_W_PHL:
23228            check_dsp(ctx);
23229            gen_helper_maq_s_w_phl(t0, v1_t, v2_t, cpu_env);
23230            break;
23231        case OPC_MAQ_S_W_PHR:
23232            check_dsp(ctx);
23233            gen_helper_maq_s_w_phr(t0, v1_t, v2_t, cpu_env);
23234            break;
23235        case OPC_MAQ_SA_W_PHL:
23236            check_dsp(ctx);
23237            gen_helper_maq_sa_w_phl(t0, v1_t, v2_t, cpu_env);
23238            break;
23239        case OPC_MAQ_SA_W_PHR:
23240            check_dsp(ctx);
23241            gen_helper_maq_sa_w_phr(t0, v1_t, v2_t, cpu_env);
23242            break;
23243        case OPC_MULSA_W_PH:
23244            check_dsp_r2(ctx);
23245            gen_helper_mulsa_w_ph(t0, v1_t, v2_t, cpu_env);
23246            break;
23247        }
23248        break;
23249#ifdef TARGET_MIPS64
23250    case OPC_DPAQ_W_QH_DSP:
23251        {
23252            int ac = ret & 0x03;
23253            tcg_gen_movi_i32(t0, ac);
23254
23255            switch (op2) {
23256            case OPC_DMADD:
23257                check_dsp(ctx);
23258                gen_helper_dmadd(v1_t, v2_t, t0, cpu_env);
23259                break;
23260            case OPC_DMADDU:
23261                check_dsp(ctx);
23262                gen_helper_dmaddu(v1_t, v2_t, t0, cpu_env);
23263                break;
23264            case OPC_DMSUB:
23265                check_dsp(ctx);
23266                gen_helper_dmsub(v1_t, v2_t, t0, cpu_env);
23267                break;
23268            case OPC_DMSUBU:
23269                check_dsp(ctx);
23270                gen_helper_dmsubu(v1_t, v2_t, t0, cpu_env);
23271                break;
23272            case OPC_DPA_W_QH:
23273                check_dsp_r2(ctx);
23274                gen_helper_dpa_w_qh(v1_t, v2_t, t0, cpu_env);
23275                break;
23276            case OPC_DPAQ_S_W_QH:
23277                check_dsp(ctx);
23278                gen_helper_dpaq_s_w_qh(v1_t, v2_t, t0, cpu_env);
23279                break;
23280            case OPC_DPAQ_SA_L_PW:
23281                check_dsp(ctx);
23282                gen_helper_dpaq_sa_l_pw(v1_t, v2_t, t0, cpu_env);
23283                break;
23284            case OPC_DPAU_H_OBL:
23285                check_dsp(ctx);
23286                gen_helper_dpau_h_obl(v1_t, v2_t, t0, cpu_env);
23287                break;
23288            case OPC_DPAU_H_OBR:
23289                check_dsp(ctx);
23290                gen_helper_dpau_h_obr(v1_t, v2_t, t0, cpu_env);
23291                break;
23292            case OPC_DPS_W_QH:
23293                check_dsp_r2(ctx);
23294                gen_helper_dps_w_qh(v1_t, v2_t, t0, cpu_env);
23295                break;
23296            case OPC_DPSQ_S_W_QH:
23297                check_dsp(ctx);
23298                gen_helper_dpsq_s_w_qh(v1_t, v2_t, t0, cpu_env);
23299                break;
23300            case OPC_DPSQ_SA_L_PW:
23301                check_dsp(ctx);
23302                gen_helper_dpsq_sa_l_pw(v1_t, v2_t, t0, cpu_env);
23303                break;
23304            case OPC_DPSU_H_OBL:
23305                check_dsp(ctx);
23306                gen_helper_dpsu_h_obl(v1_t, v2_t, t0, cpu_env);
23307                break;
23308            case OPC_DPSU_H_OBR:
23309                check_dsp(ctx);
23310                gen_helper_dpsu_h_obr(v1_t, v2_t, t0, cpu_env);
23311                break;
23312            case OPC_MAQ_S_L_PWL:
23313                check_dsp(ctx);
23314                gen_helper_maq_s_l_pwl(v1_t, v2_t, t0, cpu_env);
23315                break;
23316            case OPC_MAQ_S_L_PWR:
23317                check_dsp(ctx);
23318                gen_helper_maq_s_l_pwr(v1_t, v2_t, t0, cpu_env);
23319                break;
23320            case OPC_MAQ_S_W_QHLL:
23321                check_dsp(ctx);
23322                gen_helper_maq_s_w_qhll(v1_t, v2_t, t0, cpu_env);
23323                break;
23324            case OPC_MAQ_SA_W_QHLL:
23325                check_dsp(ctx);
23326                gen_helper_maq_sa_w_qhll(v1_t, v2_t, t0, cpu_env);
23327                break;
23328            case OPC_MAQ_S_W_QHLR:
23329                check_dsp(ctx);
23330                gen_helper_maq_s_w_qhlr(v1_t, v2_t, t0, cpu_env);
23331                break;
23332            case OPC_MAQ_SA_W_QHLR:
23333                check_dsp(ctx);
23334                gen_helper_maq_sa_w_qhlr(v1_t, v2_t, t0, cpu_env);
23335                break;
23336            case OPC_MAQ_S_W_QHRL:
23337                check_dsp(ctx);
23338                gen_helper_maq_s_w_qhrl(v1_t, v2_t, t0, cpu_env);
23339                break;
23340            case OPC_MAQ_SA_W_QHRL:
23341                check_dsp(ctx);
23342                gen_helper_maq_sa_w_qhrl(v1_t, v2_t, t0, cpu_env);
23343                break;
23344            case OPC_MAQ_S_W_QHRR:
23345                check_dsp(ctx);
23346                gen_helper_maq_s_w_qhrr(v1_t, v2_t, t0, cpu_env);
23347                break;
23348            case OPC_MAQ_SA_W_QHRR:
23349                check_dsp(ctx);
23350                gen_helper_maq_sa_w_qhrr(v1_t, v2_t, t0, cpu_env);
23351                break;
23352            case OPC_MULSAQ_S_L_PW:
23353                check_dsp(ctx);
23354                gen_helper_mulsaq_s_l_pw(v1_t, v2_t, t0, cpu_env);
23355                break;
23356            case OPC_MULSAQ_S_W_QH:
23357                check_dsp(ctx);
23358                gen_helper_mulsaq_s_w_qh(v1_t, v2_t, t0, cpu_env);
23359                break;
23360            }
23361        }
23362        break;
23363#endif
23364    case OPC_ADDU_QB_DSP:
23365        switch (op2) {
23366        case OPC_MULEU_S_PH_QBL:
23367            check_dsp(ctx);
23368            gen_helper_muleu_s_ph_qbl(cpu_gpr[ret], v1_t, v2_t, cpu_env);
23369            break;
23370        case OPC_MULEU_S_PH_QBR:
23371            check_dsp(ctx);
23372            gen_helper_muleu_s_ph_qbr(cpu_gpr[ret], v1_t, v2_t, cpu_env);
23373            break;
23374        case OPC_MULQ_RS_PH:
23375            check_dsp(ctx);
23376            gen_helper_mulq_rs_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
23377            break;
23378        case OPC_MULEQ_S_W_PHL:
23379            check_dsp(ctx);
23380            gen_helper_muleq_s_w_phl(cpu_gpr[ret], v1_t, v2_t, cpu_env);
23381            break;
23382        case OPC_MULEQ_S_W_PHR:
23383            check_dsp(ctx);
23384            gen_helper_muleq_s_w_phr(cpu_gpr[ret], v1_t, v2_t, cpu_env);
23385            break;
23386        case OPC_MULQ_S_PH:
23387            check_dsp_r2(ctx);
23388            gen_helper_mulq_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
23389            break;
23390        }
23391        break;
23392#ifdef TARGET_MIPS64
23393    case OPC_ADDU_OB_DSP:
23394        switch (op2) {
23395        case OPC_MULEQ_S_PW_QHL:
23396            check_dsp(ctx);
23397            gen_helper_muleq_s_pw_qhl(cpu_gpr[ret], v1_t, v2_t, cpu_env);
23398            break;
23399        case OPC_MULEQ_S_PW_QHR:
23400            check_dsp(ctx);
23401            gen_helper_muleq_s_pw_qhr(cpu_gpr[ret], v1_t, v2_t, cpu_env);
23402            break;
23403        case OPC_MULEU_S_QH_OBL:
23404            check_dsp(ctx);
23405            gen_helper_muleu_s_qh_obl(cpu_gpr[ret], v1_t, v2_t, cpu_env);
23406            break;
23407        case OPC_MULEU_S_QH_OBR:
23408            check_dsp(ctx);
23409            gen_helper_muleu_s_qh_obr(cpu_gpr[ret], v1_t, v2_t, cpu_env);
23410            break;
23411        case OPC_MULQ_RS_QH:
23412            check_dsp(ctx);
23413            gen_helper_mulq_rs_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
23414            break;
23415        }
23416        break;
23417#endif
23418    }
23419
23420    tcg_temp_free_i32(t0);
23421    tcg_temp_free(v1_t);
23422    tcg_temp_free(v2_t);
23423}
23424
23425static void gen_mipsdsp_bitinsn(DisasContext *ctx, uint32_t op1, uint32_t op2,
23426                                int ret, int val)
23427{
23428    int16_t imm;
23429    TCGv t0;
23430    TCGv val_t;
23431
23432    if (ret == 0) {
23433        /* Treat as NOP. */
23434        return;
23435    }
23436
23437    t0 = tcg_temp_new();
23438    val_t = tcg_temp_new();
23439    gen_load_gpr(val_t, val);
23440
23441    switch (op1) {
23442    case OPC_ABSQ_S_PH_DSP:
23443        switch (op2) {
23444        case OPC_BITREV:
23445            check_dsp(ctx);
23446            gen_helper_bitrev(cpu_gpr[ret], val_t);
23447            break;
23448        case OPC_REPL_QB:
23449            check_dsp(ctx);
23450            {
23451                target_long result;
23452                imm = (ctx->opcode >> 16) & 0xFF;
23453                result = (uint32_t)imm << 24 |
23454                         (uint32_t)imm << 16 |
23455                         (uint32_t)imm << 8  |
23456                         (uint32_t)imm;
23457                result = (int32_t)result;
23458                tcg_gen_movi_tl(cpu_gpr[ret], result);
23459            }
23460            break;
23461        case OPC_REPLV_QB:
23462            check_dsp(ctx);
23463            tcg_gen_ext8u_tl(cpu_gpr[ret], val_t);
23464            tcg_gen_shli_tl(t0, cpu_gpr[ret], 8);
23465            tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
23466            tcg_gen_shli_tl(t0, cpu_gpr[ret], 16);
23467            tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
23468            tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]);
23469            break;
23470        case OPC_REPL_PH:
23471            check_dsp(ctx);
23472            {
23473                imm = (ctx->opcode >> 16) & 0x03FF;
23474                imm = (int16_t)(imm << 6) >> 6;
23475                tcg_gen_movi_tl(cpu_gpr[ret], \
23476                                (target_long)((int32_t)imm << 16 | \
23477                                (uint16_t)imm));
23478            }
23479            break;
23480        case OPC_REPLV_PH:
23481            check_dsp(ctx);
23482            tcg_gen_ext16u_tl(cpu_gpr[ret], val_t);
23483            tcg_gen_shli_tl(t0, cpu_gpr[ret], 16);
23484            tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
23485            tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]);
23486            break;
23487        }
23488        break;
23489#ifdef TARGET_MIPS64
23490    case OPC_ABSQ_S_QH_DSP:
23491        switch (op2) {
23492        case OPC_REPL_OB:
23493            check_dsp(ctx);
23494            {
23495                target_long temp;
23496
23497                imm = (ctx->opcode >> 16) & 0xFF;
23498                temp = ((uint64_t)imm << 8) | (uint64_t)imm;
23499                temp = (temp << 16) | temp;
23500                temp = (temp << 32) | temp;
23501                tcg_gen_movi_tl(cpu_gpr[ret], temp);
23502                break;
23503            }
23504        case OPC_REPL_PW:
23505            check_dsp(ctx);
23506            {
23507                target_long temp;
23508
23509                imm = (ctx->opcode >> 16) & 0x03FF;
23510                imm = (int16_t)(imm << 6) >> 6;
23511                temp = ((target_long)imm << 32) \
23512                       | ((target_long)imm & 0xFFFFFFFF);
23513                tcg_gen_movi_tl(cpu_gpr[ret], temp);
23514                break;
23515            }
23516        case OPC_REPL_QH:
23517            check_dsp(ctx);
23518            {
23519                target_long temp;
23520
23521                imm = (ctx->opcode >> 16) & 0x03FF;
23522                imm = (int16_t)(imm << 6) >> 6;
23523
23524                temp = ((uint64_t)(uint16_t)imm << 48) |
23525                       ((uint64_t)(uint16_t)imm << 32) |
23526                       ((uint64_t)(uint16_t)imm << 16) |
23527                       (uint64_t)(uint16_t)imm;
23528                tcg_gen_movi_tl(cpu_gpr[ret], temp);
23529                break;
23530            }
23531        case OPC_REPLV_OB:
23532            check_dsp(ctx);
23533            tcg_gen_ext8u_tl(cpu_gpr[ret], val_t);
23534            tcg_gen_shli_tl(t0, cpu_gpr[ret], 8);
23535            tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
23536            tcg_gen_shli_tl(t0, cpu_gpr[ret], 16);
23537            tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
23538            tcg_gen_shli_tl(t0, cpu_gpr[ret], 32);
23539            tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
23540            break;
23541        case OPC_REPLV_PW:
23542            check_dsp(ctx);
23543            tcg_gen_ext32u_i64(cpu_gpr[ret], val_t);
23544            tcg_gen_shli_tl(t0, cpu_gpr[ret], 32);
23545            tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
23546            break;
23547        case OPC_REPLV_QH:
23548            check_dsp(ctx);
23549            tcg_gen_ext16u_tl(cpu_gpr[ret], val_t);
23550            tcg_gen_shli_tl(t0, cpu_gpr[ret], 16);
23551            tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
23552            tcg_gen_shli_tl(t0, cpu_gpr[ret], 32);
23553            tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
23554            break;
23555        }
23556        break;
23557#endif
23558    }
23559    tcg_temp_free(t0);
23560    tcg_temp_free(val_t);
23561}
23562
23563static void gen_mipsdsp_add_cmp_pick(DisasContext *ctx,
23564                                     uint32_t op1, uint32_t op2,
23565                                     int ret, int v1, int v2, int check_ret)
23566{
23567    TCGv t1;
23568    TCGv v1_t;
23569    TCGv v2_t;
23570
23571    if ((ret == 0) && (check_ret == 1)) {
23572        /* Treat as NOP. */
23573        return;
23574    }
23575
23576    t1 = tcg_temp_new();
23577    v1_t = tcg_temp_new();
23578    v2_t = tcg_temp_new();
23579
23580    gen_load_gpr(v1_t, v1);
23581    gen_load_gpr(v2_t, v2);
23582
23583    switch (op1) {
23584    case OPC_CMPU_EQ_QB_DSP:
23585        switch (op2) {
23586        case OPC_CMPU_EQ_QB:
23587            check_dsp(ctx);
23588            gen_helper_cmpu_eq_qb(v1_t, v2_t, cpu_env);
23589            break;
23590        case OPC_CMPU_LT_QB:
23591            check_dsp(ctx);
23592            gen_helper_cmpu_lt_qb(v1_t, v2_t, cpu_env);
23593            break;
23594        case OPC_CMPU_LE_QB:
23595            check_dsp(ctx);
23596            gen_helper_cmpu_le_qb(v1_t, v2_t, cpu_env);
23597            break;
23598        case OPC_CMPGU_EQ_QB:
23599            check_dsp(ctx);
23600            gen_helper_cmpgu_eq_qb(cpu_gpr[ret], v1_t, v2_t);
23601            break;
23602        case OPC_CMPGU_LT_QB:
23603            check_dsp(ctx);
23604            gen_helper_cmpgu_lt_qb(cpu_gpr[ret], v1_t, v2_t);
23605            break;
23606        case OPC_CMPGU_LE_QB:
23607            check_dsp(ctx);
23608            gen_helper_cmpgu_le_qb(cpu_gpr[ret], v1_t, v2_t);
23609            break;
23610        case OPC_CMPGDU_EQ_QB:
23611            check_dsp_r2(ctx);
23612            gen_helper_cmpgu_eq_qb(t1, v1_t, v2_t);
23613            tcg_gen_mov_tl(cpu_gpr[ret], t1);
23614            tcg_gen_andi_tl(cpu_dspctrl, cpu_dspctrl, 0xF0FFFFFF);
23615            tcg_gen_shli_tl(t1, t1, 24);
23616            tcg_gen_or_tl(cpu_dspctrl, cpu_dspctrl, t1);
23617            break;
23618        case OPC_CMPGDU_LT_QB:
23619            check_dsp_r2(ctx);
23620            gen_helper_cmpgu_lt_qb(t1, v1_t, v2_t);
23621            tcg_gen_mov_tl(cpu_gpr[ret], t1);
23622            tcg_gen_andi_tl(cpu_dspctrl, cpu_dspctrl, 0xF0FFFFFF);
23623            tcg_gen_shli_tl(t1, t1, 24);
23624            tcg_gen_or_tl(cpu_dspctrl, cpu_dspctrl, t1);
23625            break;
23626        case OPC_CMPGDU_LE_QB:
23627            check_dsp_r2(ctx);
23628            gen_helper_cmpgu_le_qb(t1, v1_t, v2_t);
23629            tcg_gen_mov_tl(cpu_gpr[ret], t1);
23630            tcg_gen_andi_tl(cpu_dspctrl, cpu_dspctrl, 0xF0FFFFFF);
23631            tcg_gen_shli_tl(t1, t1, 24);
23632            tcg_gen_or_tl(cpu_dspctrl, cpu_dspctrl, t1);
23633            break;
23634        case OPC_CMP_EQ_PH:
23635            check_dsp(ctx);
23636            gen_helper_cmp_eq_ph(v1_t, v2_t, cpu_env);
23637            break;
23638        case OPC_CMP_LT_PH:
23639            check_dsp(ctx);
23640            gen_helper_cmp_lt_ph(v1_t, v2_t, cpu_env);
23641            break;
23642        case OPC_CMP_LE_PH:
23643            check_dsp(ctx);
23644            gen_helper_cmp_le_ph(v1_t, v2_t, cpu_env);
23645            break;
23646        case OPC_PICK_QB:
23647            check_dsp(ctx);
23648            gen_helper_pick_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
23649            break;
23650        case OPC_PICK_PH:
23651            check_dsp(ctx);
23652            gen_helper_pick_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
23653            break;
23654        case OPC_PACKRL_PH:
23655            check_dsp(ctx);
23656            gen_helper_packrl_ph(cpu_gpr[ret], v1_t, v2_t);
23657            break;
23658        }
23659        break;
23660#ifdef TARGET_MIPS64
23661    case OPC_CMPU_EQ_OB_DSP:
23662        switch (op2) {
23663        case OPC_CMP_EQ_PW:
23664            check_dsp(ctx);
23665            gen_helper_cmp_eq_pw(v1_t, v2_t, cpu_env);
23666            break;
23667        case OPC_CMP_LT_PW:
23668            check_dsp(ctx);
23669            gen_helper_cmp_lt_pw(v1_t, v2_t, cpu_env);
23670            break;
23671        case OPC_CMP_LE_PW:
23672            check_dsp(ctx);
23673            gen_helper_cmp_le_pw(v1_t, v2_t, cpu_env);
23674            break;
23675        case OPC_CMP_EQ_QH:
23676            check_dsp(ctx);
23677            gen_helper_cmp_eq_qh(v1_t, v2_t, cpu_env);
23678            break;
23679        case OPC_CMP_LT_QH:
23680            check_dsp(ctx);
23681            gen_helper_cmp_lt_qh(v1_t, v2_t, cpu_env);
23682            break;
23683        case OPC_CMP_LE_QH:
23684            check_dsp(ctx);
23685            gen_helper_cmp_le_qh(v1_t, v2_t, cpu_env);
23686            break;
23687        case OPC_CMPGDU_EQ_OB:
23688            check_dsp_r2(ctx);
23689            gen_helper_cmpgdu_eq_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
23690            break;
23691        case OPC_CMPGDU_LT_OB:
23692            check_dsp_r2(ctx);
23693            gen_helper_cmpgdu_lt_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
23694            break;
23695        case OPC_CMPGDU_LE_OB:
23696            check_dsp_r2(ctx);
23697            gen_helper_cmpgdu_le_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
23698            break;
23699        case OPC_CMPGU_EQ_OB:
23700            check_dsp(ctx);
23701            gen_helper_cmpgu_eq_ob(cpu_gpr[ret], v1_t, v2_t);
23702            break;
23703        case OPC_CMPGU_LT_OB:
23704            check_dsp(ctx);
23705            gen_helper_cmpgu_lt_ob(cpu_gpr[ret], v1_t, v2_t);
23706            break;
23707        case OPC_CMPGU_LE_OB:
23708            check_dsp(ctx);
23709            gen_helper_cmpgu_le_ob(cpu_gpr[ret], v1_t, v2_t);
23710            break;
23711        case OPC_CMPU_EQ_OB:
23712            check_dsp(ctx);
23713            gen_helper_cmpu_eq_ob(v1_t, v2_t, cpu_env);
23714            break;
23715        case OPC_CMPU_LT_OB:
23716            check_dsp(ctx);
23717            gen_helper_cmpu_lt_ob(v1_t, v2_t, cpu_env);
23718            break;
23719        case OPC_CMPU_LE_OB:
23720            check_dsp(ctx);
23721            gen_helper_cmpu_le_ob(v1_t, v2_t, cpu_env);
23722            break;
23723        case OPC_PACKRL_PW:
23724            check_dsp(ctx);
23725            gen_helper_packrl_pw(cpu_gpr[ret], v1_t, v2_t);
23726            break;
23727        case OPC_PICK_OB:
23728            check_dsp(ctx);
23729            gen_helper_pick_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
23730            break;
23731        case OPC_PICK_PW:
23732            check_dsp(ctx);
23733            gen_helper_pick_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
23734            break;
23735        case OPC_PICK_QH:
23736            check_dsp(ctx);
23737            gen_helper_pick_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
23738            break;
23739        }
23740        break;
23741#endif
23742    }
23743
23744    tcg_temp_free(t1);
23745    tcg_temp_free(v1_t);
23746    tcg_temp_free(v2_t);
23747}
23748
23749static void gen_mipsdsp_append(CPUMIPSState *env, DisasContext *ctx,
23750                               uint32_t op1, int rt, int rs, int sa)
23751{
23752    TCGv t0;
23753
23754    check_dsp_r2(ctx);
23755
23756    if (rt == 0) {
23757        /* Treat as NOP. */
23758        return;
23759    }
23760
23761    t0 = tcg_temp_new();
23762    gen_load_gpr(t0, rs);
23763
23764    switch (op1) {
23765    case OPC_APPEND_DSP:
23766        switch (MASK_APPEND(ctx->opcode)) {
23767        case OPC_APPEND:
23768            if (sa != 0) {
23769                tcg_gen_deposit_tl(cpu_gpr[rt], t0, cpu_gpr[rt], sa, 32 - sa);
23770            }
23771            tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
23772            break;
23773        case OPC_PREPEND:
23774            if (sa != 0) {
23775                tcg_gen_ext32u_tl(cpu_gpr[rt], cpu_gpr[rt]);
23776                tcg_gen_shri_tl(cpu_gpr[rt], cpu_gpr[rt], sa);
23777                tcg_gen_shli_tl(t0, t0, 32 - sa);
23778                tcg_gen_or_tl(cpu_gpr[rt], cpu_gpr[rt], t0);
23779            }
23780            tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
23781            break;
23782        case OPC_BALIGN:
23783            sa &= 3;
23784            if (sa != 0 && sa != 2) {
23785                tcg_gen_shli_tl(cpu_gpr[rt], cpu_gpr[rt], 8 * sa);
23786                tcg_gen_ext32u_tl(t0, t0);
23787                tcg_gen_shri_tl(t0, t0, 8 * (4 - sa));
23788                tcg_gen_or_tl(cpu_gpr[rt], cpu_gpr[rt], t0);
23789            }
23790            tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
23791            break;
23792        default:            /* Invalid */
23793            MIPS_INVAL("MASK APPEND");
23794            generate_exception_end(ctx, EXCP_RI);
23795            break;
23796        }
23797        break;
23798#ifdef TARGET_MIPS64
23799    case OPC_DAPPEND_DSP:
23800        switch (MASK_DAPPEND(ctx->opcode)) {
23801        case OPC_DAPPEND:
23802            if (sa != 0) {
23803                tcg_gen_deposit_tl(cpu_gpr[rt], t0, cpu_gpr[rt], sa, 64 - sa);
23804            }
23805            break;
23806        case OPC_PREPENDD:
23807            tcg_gen_shri_tl(cpu_gpr[rt], cpu_gpr[rt], 0x20 | sa);
23808            tcg_gen_shli_tl(t0, t0, 64 - (0x20 | sa));
23809            tcg_gen_or_tl(cpu_gpr[rt], t0, t0);
23810            break;
23811        case OPC_PREPENDW:
23812            if (sa != 0) {
23813                tcg_gen_shri_tl(cpu_gpr[rt], cpu_gpr[rt], sa);
23814                tcg_gen_shli_tl(t0, t0, 64 - sa);
23815                tcg_gen_or_tl(cpu_gpr[rt], cpu_gpr[rt], t0);
23816            }
23817            break;
23818        case OPC_DBALIGN:
23819            sa &= 7;
23820            if (sa != 0 && sa != 2 && sa != 4) {
23821                tcg_gen_shli_tl(cpu_gpr[rt], cpu_gpr[rt], 8 * sa);
23822                tcg_gen_shri_tl(t0, t0, 8 * (8 - sa));
23823                tcg_gen_or_tl(cpu_gpr[rt], cpu_gpr[rt], t0);
23824            }
23825            break;
23826        default:            /* Invalid */
23827            MIPS_INVAL("MASK DAPPEND");
23828            generate_exception_end(ctx, EXCP_RI);
23829            break;
23830        }
23831        break;
23832#endif
23833    }
23834    tcg_temp_free(t0);
23835}
23836
23837static void gen_mipsdsp_accinsn(DisasContext *ctx, uint32_t op1, uint32_t op2,
23838                                int ret, int v1, int v2, int check_ret)
23839
23840{
23841    TCGv t0;
23842    TCGv t1;
23843    TCGv v1_t;
23844    TCGv v2_t;
23845    int16_t imm;
23846
23847    if ((ret == 0) && (check_ret == 1)) {
23848        /* Treat as NOP. */
23849        return;
23850    }
23851
23852    t0 = tcg_temp_new();
23853    t1 = tcg_temp_new();
23854    v1_t = tcg_temp_new();
23855    v2_t = tcg_temp_new();
23856
23857    gen_load_gpr(v1_t, v1);
23858    gen_load_gpr(v2_t, v2);
23859
23860    switch (op1) {
23861    case OPC_EXTR_W_DSP:
23862        check_dsp(ctx);
23863        switch (op2) {
23864        case OPC_EXTR_W:
23865            tcg_gen_movi_tl(t0, v2);
23866            tcg_gen_movi_tl(t1, v1);
23867            gen_helper_extr_w(cpu_gpr[ret], t0, t1, cpu_env);
23868            break;
23869        case OPC_EXTR_R_W:
23870            tcg_gen_movi_tl(t0, v2);
23871            tcg_gen_movi_tl(t1, v1);
23872            gen_helper_extr_r_w(cpu_gpr[ret], t0, t1, cpu_env);
23873            break;
23874        case OPC_EXTR_RS_W:
23875            tcg_gen_movi_tl(t0, v2);
23876            tcg_gen_movi_tl(t1, v1);
23877            gen_helper_extr_rs_w(cpu_gpr[ret], t0, t1, cpu_env);
23878            break;
23879        case OPC_EXTR_S_H:
23880            tcg_gen_movi_tl(t0, v2);
23881            tcg_gen_movi_tl(t1, v1);
23882            gen_helper_extr_s_h(cpu_gpr[ret], t0, t1, cpu_env);
23883            break;
23884        case OPC_EXTRV_S_H:
23885            tcg_gen_movi_tl(t0, v2);
23886            gen_helper_extr_s_h(cpu_gpr[ret], t0, v1_t, cpu_env);
23887            break;
23888        case OPC_EXTRV_W:
23889            tcg_gen_movi_tl(t0, v2);
23890            gen_helper_extr_w(cpu_gpr[ret], t0, v1_t, cpu_env);
23891            break;
23892        case OPC_EXTRV_R_W:
23893            tcg_gen_movi_tl(t0, v2);
23894            gen_helper_extr_r_w(cpu_gpr[ret], t0, v1_t, cpu_env);
23895            break;
23896        case OPC_EXTRV_RS_W:
23897            tcg_gen_movi_tl(t0, v2);
23898            gen_helper_extr_rs_w(cpu_gpr[ret], t0, v1_t, cpu_env);
23899            break;
23900        case OPC_EXTP:
23901            tcg_gen_movi_tl(t0, v2);
23902            tcg_gen_movi_tl(t1, v1);
23903            gen_helper_extp(cpu_gpr[ret], t0, t1, cpu_env);
23904            break;
23905        case OPC_EXTPV:
23906            tcg_gen_movi_tl(t0, v2);
23907            gen_helper_extp(cpu_gpr[ret], t0, v1_t, cpu_env);
23908            break;
23909        case OPC_EXTPDP:
23910            tcg_gen_movi_tl(t0, v2);
23911            tcg_gen_movi_tl(t1, v1);
23912            gen_helper_extpdp(cpu_gpr[ret], t0, t1, cpu_env);
23913            break;
23914        case OPC_EXTPDPV:
23915            tcg_gen_movi_tl(t0, v2);
23916            gen_helper_extpdp(cpu_gpr[ret], t0, v1_t, cpu_env);
23917            break;
23918        case OPC_SHILO:
23919            imm = (ctx->opcode >> 20) & 0x3F;
23920            tcg_gen_movi_tl(t0, ret);
23921            tcg_gen_movi_tl(t1, imm);
23922            gen_helper_shilo(t0, t1, cpu_env);
23923            break;
23924        case OPC_SHILOV:
23925            tcg_gen_movi_tl(t0, ret);
23926            gen_helper_shilo(t0, v1_t, cpu_env);
23927            break;
23928        case OPC_MTHLIP:
23929            tcg_gen_movi_tl(t0, ret);
23930            gen_helper_mthlip(t0, v1_t, cpu_env);
23931            break;
23932        case OPC_WRDSP:
23933            imm = (ctx->opcode >> 11) & 0x3FF;
23934            tcg_gen_movi_tl(t0, imm);
23935            gen_helper_wrdsp(v1_t, t0, cpu_env);
23936            break;
23937        case OPC_RDDSP:
23938            imm = (ctx->opcode >> 16) & 0x03FF;
23939            tcg_gen_movi_tl(t0, imm);
23940            gen_helper_rddsp(cpu_gpr[ret], t0, cpu_env);
23941            break;
23942        }
23943        break;
23944#ifdef TARGET_MIPS64
23945    case OPC_DEXTR_W_DSP:
23946        check_dsp(ctx);
23947        switch (op2) {
23948        case OPC_DMTHLIP:
23949            tcg_gen_movi_tl(t0, ret);
23950            gen_helper_dmthlip(v1_t, t0, cpu_env);
23951            break;
23952        case OPC_DSHILO:
23953            {
23954                int shift = (ctx->opcode >> 19) & 0x7F;
23955                int ac = (ctx->opcode >> 11) & 0x03;
23956                tcg_gen_movi_tl(t0, shift);
23957                tcg_gen_movi_tl(t1, ac);
23958                gen_helper_dshilo(t0, t1, cpu_env);
23959                break;
23960            }
23961        case OPC_DSHILOV:
23962            {
23963                int ac = (ctx->opcode >> 11) & 0x03;
23964                tcg_gen_movi_tl(t0, ac);
23965                gen_helper_dshilo(v1_t, t0, cpu_env);
23966                break;
23967            }
23968        case OPC_DEXTP:
23969            tcg_gen_movi_tl(t0, v2);
23970            tcg_gen_movi_tl(t1, v1);
23971
23972            gen_helper_dextp(cpu_gpr[ret], t0, t1, cpu_env);
23973            break;
23974        case OPC_DEXTPV:
23975            tcg_gen_movi_tl(t0, v2);
23976            gen_helper_dextp(cpu_gpr[ret], t0, v1_t, cpu_env);
23977            break;
23978        case OPC_DEXTPDP:
23979            tcg_gen_movi_tl(t0, v2);
23980            tcg_gen_movi_tl(t1, v1);
23981            gen_helper_dextpdp(cpu_gpr[ret], t0, t1, cpu_env);
23982            break;
23983        case OPC_DEXTPDPV:
23984            tcg_gen_movi_tl(t0, v2);
23985            gen_helper_dextpdp(cpu_gpr[ret], t0, v1_t, cpu_env);
23986            break;
23987        case OPC_DEXTR_L:
23988            tcg_gen_movi_tl(t0, v2);
23989            tcg_gen_movi_tl(t1, v1);
23990            gen_helper_dextr_l(cpu_gpr[ret], t0, t1, cpu_env);
23991            break;
23992        case OPC_DEXTR_R_L:
23993            tcg_gen_movi_tl(t0, v2);
23994            tcg_gen_movi_tl(t1, v1);
23995            gen_helper_dextr_r_l(cpu_gpr[ret], t0, t1, cpu_env);
23996            break;
23997        case OPC_DEXTR_RS_L:
23998            tcg_gen_movi_tl(t0, v2);
23999            tcg_gen_movi_tl(t1, v1);
24000            gen_helper_dextr_rs_l(cpu_gpr[ret], t0, t1, cpu_env);
24001            break;
24002        case OPC_DEXTR_W:
24003            tcg_gen_movi_tl(t0, v2);
24004            tcg_gen_movi_tl(t1, v1);
24005            gen_helper_dextr_w(cpu_gpr[ret], t0, t1, cpu_env);
24006            break;
24007        case OPC_DEXTR_R_W:
24008            tcg_gen_movi_tl(t0, v2);
24009            tcg_gen_movi_tl(t1, v1);
24010            gen_helper_dextr_r_w(cpu_gpr[ret], t0, t1, cpu_env);
24011            break;
24012        case OPC_DEXTR_RS_W:
24013            tcg_gen_movi_tl(t0, v2);
24014            tcg_gen_movi_tl(t1, v1);
24015            gen_helper_dextr_rs_w(cpu_gpr[ret], t0, t1, cpu_env);
24016            break;
24017        case OPC_DEXTR_S_H:
24018            tcg_gen_movi_tl(t0, v2);
24019            tcg_gen_movi_tl(t1, v1);
24020            gen_helper_dextr_s_h(cpu_gpr[ret], t0, t1, cpu_env);
24021            break;
24022        case OPC_DEXTRV_S_H:
24023            tcg_gen_movi_tl(t0, v2);
24024            tcg_gen_movi_tl(t1, v1);
24025            gen_helper_dextr_s_h(cpu_gpr[ret], t0, t1, cpu_env);
24026            break;
24027        case OPC_DEXTRV_L:
24028            tcg_gen_movi_tl(t0, v2);
24029            gen_helper_dextr_l(cpu_gpr[ret], t0, v1_t, cpu_env);
24030            break;
24031        case OPC_DEXTRV_R_L:
24032            tcg_gen_movi_tl(t0, v2);
24033            gen_helper_dextr_r_l(cpu_gpr[ret], t0, v1_t, cpu_env);
24034            break;
24035        case OPC_DEXTRV_RS_L:
24036            tcg_gen_movi_tl(t0, v2);
24037            gen_helper_dextr_rs_l(cpu_gpr[ret], t0, v1_t, cpu_env);
24038            break;
24039        case OPC_DEXTRV_W:
24040            tcg_gen_movi_tl(t0, v2);
24041            gen_helper_dextr_w(cpu_gpr[ret], t0, v1_t, cpu_env);
24042            break;
24043        case OPC_DEXTRV_R_W:
24044            tcg_gen_movi_tl(t0, v2);
24045            gen_helper_dextr_r_w(cpu_gpr[ret], t0, v1_t, cpu_env);
24046            break;
24047        case OPC_DEXTRV_RS_W:
24048            tcg_gen_movi_tl(t0, v2);
24049            gen_helper_dextr_rs_w(cpu_gpr[ret], t0, v1_t, cpu_env);
24050            break;
24051        }
24052        break;
24053#endif
24054    }
24055
24056    tcg_temp_free(t0);
24057    tcg_temp_free(t1);
24058    tcg_temp_free(v1_t);
24059    tcg_temp_free(v2_t);
24060}
24061
24062/* End MIPSDSP functions. */
24063
24064static void decode_opc_special_r6(CPUMIPSState *env, DisasContext *ctx)
24065{
24066    int rs, rt, rd, sa;
24067    uint32_t op1, op2;
24068
24069    rs = (ctx->opcode >> 21) & 0x1f;
24070    rt = (ctx->opcode >> 16) & 0x1f;
24071    rd = (ctx->opcode >> 11) & 0x1f;
24072    sa = (ctx->opcode >> 6) & 0x1f;
24073
24074    op1 = MASK_SPECIAL(ctx->opcode);
24075    switch (op1) {
24076    case OPC_LSA:
24077        gen_lsa(ctx, op1, rd, rs, rt, extract32(ctx->opcode, 6, 2));
24078        break;
24079    case OPC_MULT:
24080    case OPC_MULTU:
24081    case OPC_DIV:
24082    case OPC_DIVU:
24083        op2 = MASK_R6_MULDIV(ctx->opcode);
24084        switch (op2) {
24085        case R6_OPC_MUL:
24086        case R6_OPC_MUH:
24087        case R6_OPC_MULU:
24088        case R6_OPC_MUHU:
24089        case R6_OPC_DIV:
24090        case R6_OPC_MOD:
24091        case R6_OPC_DIVU:
24092        case R6_OPC_MODU:
24093            gen_r6_muldiv(ctx, op2, rd, rs, rt);
24094            break;
24095        default:
24096            MIPS_INVAL("special_r6 muldiv");
24097            generate_exception_end(ctx, EXCP_RI);
24098            break;
24099        }
24100        break;
24101    case OPC_SELEQZ:
24102    case OPC_SELNEZ:
24103        gen_cond_move(ctx, op1, rd, rs, rt);
24104        break;
24105    case R6_OPC_CLO:
24106    case R6_OPC_CLZ:
24107        if (rt == 0 && sa == 1) {
24108            /*
24109             * Major opcode and function field is shared with preR6 MFHI/MTHI.
24110             * We need additionally to check other fields.
24111             */
24112            gen_cl(ctx, op1, rd, rs);
24113        } else {
24114            generate_exception_end(ctx, EXCP_RI);
24115        }
24116        break;
24117    case R6_OPC_SDBBP:
24118        if (is_uhi(extract32(ctx->opcode, 6, 20))) {
24119            gen_helper_do_semihosting(cpu_env);
24120        } else {
24121            if (ctx->hflags & MIPS_HFLAG_SBRI) {
24122                generate_exception_end(ctx, EXCP_RI);
24123            } else {
24124                generate_exception_end(ctx, EXCP_DBp);
24125            }
24126        }
24127        break;
24128#if defined(TARGET_MIPS64)
24129    case OPC_DLSA:
24130        check_mips_64(ctx);
24131        gen_lsa(ctx, op1, rd, rs, rt, extract32(ctx->opcode, 6, 2));
24132        break;
24133    case R6_OPC_DCLO:
24134    case R6_OPC_DCLZ:
24135        if (rt == 0 && sa == 1) {
24136            /*
24137             * Major opcode and function field is shared with preR6 MFHI/MTHI.
24138             * We need additionally to check other fields.
24139             */
24140            check_mips_64(ctx);
24141            gen_cl(ctx, op1, rd, rs);
24142        } else {
24143            generate_exception_end(ctx, EXCP_RI);
24144        }
24145        break;
24146    case OPC_DMULT:
24147    case OPC_DMULTU:
24148    case OPC_DDIV:
24149    case OPC_DDIVU:
24150
24151        op2 = MASK_R6_MULDIV(ctx->opcode);
24152        switch (op2) {
24153        case R6_OPC_DMUL:
24154        case R6_OPC_DMUH:
24155        case R6_OPC_DMULU:
24156        case R6_OPC_DMUHU:
24157        case R6_OPC_DDIV:
24158        case R6_OPC_DMOD:
24159        case R6_OPC_DDIVU:
24160        case R6_OPC_DMODU:
24161            check_mips_64(ctx);
24162            gen_r6_muldiv(ctx, op2, rd, rs, rt);
24163            break;
24164        default:
24165            MIPS_INVAL("special_r6 muldiv");
24166            generate_exception_end(ctx, EXCP_RI);
24167            break;
24168        }
24169        break;
24170#endif
24171    default:            /* Invalid */
24172        MIPS_INVAL("special_r6");
24173        generate_exception_end(ctx, EXCP_RI);
24174        break;
24175    }
24176}
24177
24178static void decode_opc_special_tx79(CPUMIPSState *env, DisasContext *ctx)
24179{
24180    int rs = extract32(ctx->opcode, 21, 5);
24181    int rt = extract32(ctx->opcode, 16, 5);
24182    int rd = extract32(ctx->opcode, 11, 5);
24183    uint32_t op1 = MASK_SPECIAL(ctx->opcode);
24184
24185    switch (op1) {
24186    case OPC_MOVN:         /* Conditional move */
24187    case OPC_MOVZ:
24188        gen_cond_move(ctx, op1, rd, rs, rt);
24189        break;
24190    case OPC_MFHI:          /* Move from HI/LO */
24191    case OPC_MFLO:
24192        gen_HILO(ctx, op1, 0, rd);
24193        break;
24194    case OPC_MTHI:
24195    case OPC_MTLO:          /* Move to HI/LO */
24196        gen_HILO(ctx, op1, 0, rs);
24197        break;
24198    case OPC_MULT:
24199    case OPC_MULTU:
24200        gen_mul_txx9(ctx, op1, rd, rs, rt);
24201        break;
24202    case OPC_DIV:
24203    case OPC_DIVU:
24204        gen_muldiv(ctx, op1, 0, rs, rt);
24205        break;
24206#if defined(TARGET_MIPS64)
24207    case OPC_DMULT:
24208    case OPC_DMULTU:
24209    case OPC_DDIV:
24210    case OPC_DDIVU:
24211        check_insn_opc_user_only(ctx, INSN_R5900);
24212        gen_muldiv(ctx, op1, 0, rs, rt);
24213        break;
24214#endif
24215    case OPC_JR:
24216        gen_compute_branch(ctx, op1, 4, rs, 0, 0, 4);
24217        break;
24218    default:            /* Invalid */
24219        MIPS_INVAL("special_tx79");
24220        generate_exception_end(ctx, EXCP_RI);
24221        break;
24222    }
24223}
24224
24225static void decode_opc_special_legacy(CPUMIPSState *env, DisasContext *ctx)
24226{
24227    int rs, rt, rd, sa;
24228    uint32_t op1;
24229
24230    rs = (ctx->opcode >> 21) & 0x1f;
24231    rt = (ctx->opcode >> 16) & 0x1f;
24232    rd = (ctx->opcode >> 11) & 0x1f;
24233    sa = (ctx->opcode >> 6) & 0x1f;
24234
24235    op1 = MASK_SPECIAL(ctx->opcode);
24236    switch (op1) {
24237    case OPC_MOVN:         /* Conditional move */
24238    case OPC_MOVZ:
24239        check_insn(ctx, ISA_MIPS4 | ISA_MIPS32 |
24240                   INSN_LOONGSON2E | INSN_LOONGSON2F);
24241        gen_cond_move(ctx, op1, rd, rs, rt);
24242        break;
24243    case OPC_MFHI:          /* Move from HI/LO */
24244    case OPC_MFLO:
24245        gen_HILO(ctx, op1, rs & 3, rd);
24246        break;
24247    case OPC_MTHI:
24248    case OPC_MTLO:          /* Move to HI/LO */
24249        gen_HILO(ctx, op1, rd & 3, rs);
24250        break;
24251    case OPC_MOVCI:
24252        check_insn(ctx, ISA_MIPS4 | ISA_MIPS32);
24253        if (env->CP0_Config1 & (1 << CP0C1_FP)) {
24254            check_cp1_enabled(ctx);
24255            gen_movci(ctx, rd, rs, (ctx->opcode >> 18) & 0x7,
24256                      (ctx->opcode >> 16) & 1);
24257        } else {
24258            generate_exception_err(ctx, EXCP_CpU, 1);
24259        }
24260        break;
24261    case OPC_MULT:
24262    case OPC_MULTU:
24263        if (sa) {
24264            check_insn(ctx, INSN_VR54XX);
24265            op1 = MASK_MUL_VR54XX(ctx->opcode);
24266            gen_mul_vr54xx(ctx, op1, rd, rs, rt);
24267        } else {
24268            gen_muldiv(ctx, op1, rd & 3, rs, rt);
24269        }
24270        break;
24271    case OPC_DIV:
24272    case OPC_DIVU:
24273        gen_muldiv(ctx, op1, 0, rs, rt);
24274        break;
24275#if defined(TARGET_MIPS64)
24276    case OPC_DMULT:
24277    case OPC_DMULTU:
24278    case OPC_DDIV:
24279    case OPC_DDIVU:
24280        check_insn(ctx, ISA_MIPS3);
24281        check_mips_64(ctx);
24282        gen_muldiv(ctx, op1, 0, rs, rt);
24283        break;
24284#endif
24285    case OPC_JR:
24286        gen_compute_branch(ctx, op1, 4, rs, rd, sa, 4);
24287        break;
24288    case OPC_SPIM:
24289#ifdef MIPS_STRICT_STANDARD
24290        MIPS_INVAL("SPIM");
24291        generate_exception_end(ctx, EXCP_RI);
24292#else
24293        /* Implemented as RI exception for now. */
24294        MIPS_INVAL("spim (unofficial)");
24295        generate_exception_end(ctx, EXCP_RI);
24296#endif
24297        break;
24298    default:            /* Invalid */
24299        MIPS_INVAL("special_legacy");
24300        generate_exception_end(ctx, EXCP_RI);
24301        break;
24302    }
24303}
24304
24305static void decode_opc_special(CPUMIPSState *env, DisasContext *ctx)
24306{
24307    int rs, rt, rd, sa;
24308    uint32_t op1;
24309
24310    rs = (ctx->opcode >> 21) & 0x1f;
24311    rt = (ctx->opcode >> 16) & 0x1f;
24312    rd = (ctx->opcode >> 11) & 0x1f;
24313    sa = (ctx->opcode >> 6) & 0x1f;
24314
24315    op1 = MASK_SPECIAL(ctx->opcode);
24316    switch (op1) {
24317    case OPC_SLL:          /* Shift with immediate */
24318        if (sa == 5 && rd == 0 &&
24319            rs == 0 && rt == 0) { /* PAUSE */
24320            if ((ctx->insn_flags & ISA_MIPS32R6) &&
24321                (ctx->hflags & MIPS_HFLAG_BMASK)) {
24322                generate_exception_end(ctx, EXCP_RI);
24323                break;
24324            }
24325        }
24326        /* Fallthrough */
24327    case OPC_SRA:
24328        gen_shift_imm(ctx, op1, rd, rt, sa);
24329        break;
24330    case OPC_SRL:
24331        switch ((ctx->opcode >> 21) & 0x1f) {
24332        case 1:
24333            /* rotr is decoded as srl on non-R2 CPUs */
24334            if (ctx->insn_flags & ISA_MIPS32R2) {
24335                op1 = OPC_ROTR;
24336            }
24337            /* Fallthrough */
24338        case 0:
24339            gen_shift_imm(ctx, op1, rd, rt, sa);
24340            break;
24341        default:
24342            generate_exception_end(ctx, EXCP_RI);
24343            break;
24344        }
24345        break;
24346    case OPC_ADD:
24347    case OPC_ADDU:
24348    case OPC_SUB:
24349    case OPC_SUBU:
24350        gen_arith(ctx, op1, rd, rs, rt);
24351        break;
24352    case OPC_SLLV:         /* Shifts */
24353    case OPC_SRAV:
24354        gen_shift(ctx, op1, rd, rs, rt);
24355        break;
24356    case OPC_SRLV:
24357        switch ((ctx->opcode >> 6) & 0x1f) {
24358        case 1:
24359            /* rotrv is decoded as srlv on non-R2 CPUs */
24360            if (ctx->insn_flags & ISA_MIPS32R2) {
24361                op1 = OPC_ROTRV;
24362            }
24363            /* Fallthrough */
24364        case 0:
24365            gen_shift(ctx, op1, rd, rs, rt);
24366            break;
24367        default:
24368            generate_exception_end(ctx, EXCP_RI);
24369            break;
24370        }
24371        break;
24372    case OPC_SLT:          /* Set on less than */
24373    case OPC_SLTU:
24374        gen_slt(ctx, op1, rd, rs, rt);
24375        break;
24376    case OPC_AND:          /* Logic*/
24377    case OPC_OR:
24378    case OPC_NOR:
24379    case OPC_XOR:
24380        gen_logic(ctx, op1, rd, rs, rt);
24381        break;
24382    case OPC_JALR:
24383        gen_compute_branch(ctx, op1, 4, rs, rd, sa, 4);
24384        break;
24385    case OPC_TGE: /* Traps */
24386    case OPC_TGEU:
24387    case OPC_TLT:
24388    case OPC_TLTU:
24389    case OPC_TEQ:
24390    case OPC_TNE:
24391        check_insn(ctx, ISA_MIPS2);
24392        gen_trap(ctx, op1, rs, rt, -1);
24393        break;
24394    case OPC_LSA: /* OPC_PMON */
24395        if ((ctx->insn_flags & ISA_MIPS32R6) ||
24396            (env->CP0_Config3 & (1 << CP0C3_MSAP))) {
24397            decode_opc_special_r6(env, ctx);
24398        } else {
24399            /* Pmon entry point, also R4010 selsl */
24400#ifdef MIPS_STRICT_STANDARD
24401            MIPS_INVAL("PMON / selsl");
24402            generate_exception_end(ctx, EXCP_RI);
24403#else
24404            gen_helper_0e0i(pmon, sa);
24405#endif
24406        }
24407        break;
24408    case OPC_SYSCALL:
24409        generate_exception_end(ctx, EXCP_SYSCALL);
24410        break;
24411    case OPC_BREAK:
24412        generate_exception_end(ctx, EXCP_BREAK);
24413        break;
24414    case OPC_SYNC:
24415        check_insn(ctx, ISA_MIPS2);
24416        gen_sync(extract32(ctx->opcode, 6, 5));
24417        break;
24418
24419#if defined(TARGET_MIPS64)
24420        /* MIPS64 specific opcodes */
24421    case OPC_DSLL:
24422    case OPC_DSRA:
24423    case OPC_DSLL32:
24424    case OPC_DSRA32:
24425        check_insn(ctx, ISA_MIPS3);
24426        check_mips_64(ctx);
24427        gen_shift_imm(ctx, op1, rd, rt, sa);
24428        break;
24429    case OPC_DSRL:
24430        switch ((ctx->opcode >> 21) & 0x1f) {
24431        case 1:
24432            /* drotr is decoded as dsrl on non-R2 CPUs */
24433            if (ctx->insn_flags & ISA_MIPS32R2) {
24434                op1 = OPC_DROTR;
24435            }
24436            /* Fallthrough */
24437        case 0:
24438            check_insn(ctx, ISA_MIPS3);
24439            check_mips_64(ctx);
24440            gen_shift_imm(ctx, op1, rd, rt, sa);
24441            break;
24442        default:
24443            generate_exception_end(ctx, EXCP_RI);
24444            break;
24445        }
24446        break;
24447    case OPC_DSRL32:
24448        switch ((ctx->opcode >> 21) & 0x1f) {
24449        case 1:
24450            /* drotr32 is decoded as dsrl32 on non-R2 CPUs */
24451            if (ctx->insn_flags & ISA_MIPS32R2) {
24452                op1 = OPC_DROTR32;
24453            }
24454            /* Fallthrough */
24455        case 0:
24456            check_insn(ctx, ISA_MIPS3);
24457            check_mips_64(ctx);
24458            gen_shift_imm(ctx, op1, rd, rt, sa);
24459            break;
24460        default:
24461            generate_exception_end(ctx, EXCP_RI);
24462            break;
24463        }
24464        break;
24465    case OPC_DADD:
24466    case OPC_DADDU:
24467    case OPC_DSUB:
24468    case OPC_DSUBU:
24469        check_insn(ctx, ISA_MIPS3);
24470        check_mips_64(ctx);
24471        gen_arith(ctx, op1, rd, rs, rt);
24472        break;
24473    case OPC_DSLLV:
24474    case OPC_DSRAV:
24475        check_insn(ctx, ISA_MIPS3);
24476        check_mips_64(ctx);
24477        gen_shift(ctx, op1, rd, rs, rt);
24478        break;
24479    case OPC_DSRLV:
24480        switch ((ctx->opcode >> 6) & 0x1f) {
24481        case 1:
24482            /* drotrv is decoded as dsrlv on non-R2 CPUs */
24483            if (ctx->insn_flags & ISA_MIPS32R2) {
24484                op1 = OPC_DROTRV;
24485            }
24486            /* Fallthrough */
24487        case 0:
24488            check_insn(ctx, ISA_MIPS3);
24489            check_mips_64(ctx);
24490            gen_shift(ctx, op1, rd, rs, rt);
24491            break;
24492        default:
24493            generate_exception_end(ctx, EXCP_RI);
24494            break;
24495        }
24496        break;
24497    case OPC_DLSA:
24498        if ((ctx->insn_flags & ISA_MIPS32R6) ||
24499            (env->CP0_Config3 & (1 << CP0C3_MSAP))) {
24500            decode_opc_special_r6(env, ctx);
24501        }
24502        break;
24503#endif
24504    default:
24505        if (ctx->insn_flags & ISA_MIPS32R6) {
24506            decode_opc_special_r6(env, ctx);
24507        } else if (ctx->insn_flags & INSN_R5900) {
24508            decode_opc_special_tx79(env, ctx);
24509        } else {
24510            decode_opc_special_legacy(env, ctx);
24511        }
24512    }
24513}
24514
24515
24516#if defined(TARGET_MIPS64)
24517
24518/*
24519 *
24520 *           MMI (MultiMedia Interface) ASE instructions
24521 *           ===========================================
24522 */
24523
24524/*
24525 *          MMI instructions category: data communication
24526 *          ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
24527 *
24528 *   PCPYH    PEXCH    PEXTLB   PINTH    PPACB    PEXT5    PREVH
24529 *   PCPYLD   PEXCW    PEXTLH   PINTEH   PPACH    PPAC5    PROT3W
24530 *   PCPYUD   PEXEH    PEXTLW            PPACW
24531 *            PEXEW    PEXTUB
24532 *                     PEXTUH
24533 *                     PEXTUW
24534 */
24535
24536/*
24537 *  PCPYH rd, rt
24538 *
24539 *    Parallel Copy Halfword
24540 *
24541 *   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
24542 *  +-----------+---------+---------+---------+---------+-----------+
24543 *  |    MMI    |0 0 0 0 0|   rt    |   rd    |  PCPYH  |    MMI3   |
24544 *  +-----------+---------+---------+---------+---------+-----------+
24545 */
24546static void gen_mmi_pcpyh(DisasContext *ctx)
24547{
24548    uint32_t pd, rt, rd;
24549    uint32_t opcode;
24550
24551    opcode = ctx->opcode;
24552
24553    pd = extract32(opcode, 21, 5);
24554    rt = extract32(opcode, 16, 5);
24555    rd = extract32(opcode, 11, 5);
24556
24557    if (unlikely(pd != 0)) {
24558        generate_exception_end(ctx, EXCP_RI);
24559    } else if (rd == 0) {
24560        /* nop */
24561    } else if (rt == 0) {
24562        tcg_gen_movi_i64(cpu_gpr[rd], 0);
24563        tcg_gen_movi_i64(cpu_mmr[rd], 0);
24564    } else {
24565        TCGv_i64 t0 = tcg_temp_new();
24566        TCGv_i64 t1 = tcg_temp_new();
24567        uint64_t mask = (1ULL << 16) - 1;
24568
24569        tcg_gen_andi_i64(t0, cpu_gpr[rt], mask);
24570        tcg_gen_movi_i64(t1, 0);
24571        tcg_gen_or_i64(t1, t0, t1);
24572        tcg_gen_shli_i64(t0, t0, 16);
24573        tcg_gen_or_i64(t1, t0, t1);
24574        tcg_gen_shli_i64(t0, t0, 16);
24575        tcg_gen_or_i64(t1, t0, t1);
24576        tcg_gen_shli_i64(t0, t0, 16);
24577        tcg_gen_or_i64(t1, t0, t1);
24578
24579        tcg_gen_mov_i64(cpu_gpr[rd], t1);
24580
24581        tcg_gen_andi_i64(t0, cpu_mmr[rt], mask);
24582        tcg_gen_movi_i64(t1, 0);
24583        tcg_gen_or_i64(t1, t0, t1);
24584        tcg_gen_shli_i64(t0, t0, 16);
24585        tcg_gen_or_i64(t1, t0, t1);
24586        tcg_gen_shli_i64(t0, t0, 16);
24587        tcg_gen_or_i64(t1, t0, t1);
24588        tcg_gen_shli_i64(t0, t0, 16);
24589        tcg_gen_or_i64(t1, t0, t1);
24590
24591        tcg_gen_mov_i64(cpu_mmr[rd], t1);
24592
24593        tcg_temp_free(t0);
24594        tcg_temp_free(t1);
24595    }
24596}
24597
24598/*
24599 *  PCPYLD rd, rs, rt
24600 *
24601 *    Parallel Copy Lower Doubleword
24602 *
24603 *   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
24604 *  +-----------+---------+---------+---------+---------+-----------+
24605 *  |    MMI    |   rs    |   rt    |   rd    | PCPYLD  |    MMI2   |
24606 *  +-----------+---------+---------+---------+---------+-----------+
24607 */
24608static void gen_mmi_pcpyld(DisasContext *ctx)
24609{
24610    uint32_t rs, rt, rd;
24611    uint32_t opcode;
24612
24613    opcode = ctx->opcode;
24614
24615    rs = extract32(opcode, 21, 5);
24616    rt = extract32(opcode, 16, 5);
24617    rd = extract32(opcode, 11, 5);
24618
24619    if (rd == 0) {
24620        /* nop */
24621    } else {
24622        if (rs == 0) {
24623            tcg_gen_movi_i64(cpu_mmr[rd], 0);
24624        } else {
24625            tcg_gen_mov_i64(cpu_mmr[rd], cpu_gpr[rs]);
24626        }
24627        if (rt == 0) {
24628            tcg_gen_movi_i64(cpu_gpr[rd], 0);
24629        } else {
24630            if (rd != rt) {
24631                tcg_gen_mov_i64(cpu_gpr[rd], cpu_gpr[rt]);
24632            }
24633        }
24634    }
24635}
24636
24637/*
24638 *  PCPYUD rd, rs, rt
24639 *
24640 *    Parallel Copy Upper Doubleword
24641 *
24642 *   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
24643 *  +-----------+---------+---------+---------+---------+-----------+
24644 *  |    MMI    |   rs    |   rt    |   rd    | PCPYUD  |    MMI3   |
24645 *  +-----------+---------+---------+---------+---------+-----------+
24646 */
24647static void gen_mmi_pcpyud(DisasContext *ctx)
24648{
24649    uint32_t rs, rt, rd;
24650    uint32_t opcode;
24651
24652    opcode = ctx->opcode;
24653
24654    rs = extract32(opcode, 21, 5);
24655    rt = extract32(opcode, 16, 5);
24656    rd = extract32(opcode, 11, 5);
24657
24658    if (rd == 0) {
24659        /* nop */
24660    } else {
24661        if (rs == 0) {
24662            tcg_gen_movi_i64(cpu_gpr[rd], 0);
24663        } else {
24664            tcg_gen_mov_i64(cpu_gpr[rd], cpu_mmr[rs]);
24665        }
24666        if (rt == 0) {
24667            tcg_gen_movi_i64(cpu_mmr[rd], 0);
24668        } else {
24669            if (rd != rt) {
24670                tcg_gen_mov_i64(cpu_mmr[rd], cpu_mmr[rt]);
24671            }
24672        }
24673    }
24674}
24675
24676#endif
24677
24678
24679#if !defined(TARGET_MIPS64)
24680
24681/* MXU accumulate add/subtract 1-bit pattern 'aptn1' */
24682#define MXU_APTN1_A    0
24683#define MXU_APTN1_S    1
24684
24685/* MXU accumulate add/subtract 2-bit pattern 'aptn2' */
24686#define MXU_APTN2_AA    0
24687#define MXU_APTN2_AS    1
24688#define MXU_APTN2_SA    2
24689#define MXU_APTN2_SS    3
24690
24691/* MXU execute add/subtract 2-bit pattern 'eptn2' */
24692#define MXU_EPTN2_AA    0
24693#define MXU_EPTN2_AS    1
24694#define MXU_EPTN2_SA    2
24695#define MXU_EPTN2_SS    3
24696
24697/* MXU operand getting pattern 'optn2' */
24698#define MXU_OPTN2_PTN0  0
24699#define MXU_OPTN2_PTN1  1
24700#define MXU_OPTN2_PTN2  2
24701#define MXU_OPTN2_PTN3  3
24702/* alternative naming scheme for 'optn2' */
24703#define MXU_OPTN2_WW    0
24704#define MXU_OPTN2_LW    1
24705#define MXU_OPTN2_HW    2
24706#define MXU_OPTN2_XW    3
24707
24708/* MXU operand getting pattern 'optn3' */
24709#define MXU_OPTN3_PTN0  0
24710#define MXU_OPTN3_PTN1  1
24711#define MXU_OPTN3_PTN2  2
24712#define MXU_OPTN3_PTN3  3
24713#define MXU_OPTN3_PTN4  4
24714#define MXU_OPTN3_PTN5  5
24715#define MXU_OPTN3_PTN6  6
24716#define MXU_OPTN3_PTN7  7
24717
24718
24719/*
24720 * S32I2M XRa, rb - Register move from GRF to XRF
24721 */
24722static void gen_mxu_s32i2m(DisasContext *ctx)
24723{
24724    TCGv t0;
24725    uint32_t XRa, Rb;
24726
24727    t0 = tcg_temp_new();
24728
24729    XRa = extract32(ctx->opcode, 6, 5);
24730    Rb = extract32(ctx->opcode, 16, 5);
24731
24732    gen_load_gpr(t0, Rb);
24733    if (XRa <= 15) {
24734        gen_store_mxu_gpr(t0, XRa);
24735    } else if (XRa == 16) {
24736        gen_store_mxu_cr(t0);
24737    }
24738
24739    tcg_temp_free(t0);
24740}
24741
24742/*
24743 * S32M2I XRa, rb - Register move from XRF to GRF
24744 */
24745static void gen_mxu_s32m2i(DisasContext *ctx)
24746{
24747    TCGv t0;
24748    uint32_t XRa, Rb;
24749
24750    t0 = tcg_temp_new();
24751
24752    XRa = extract32(ctx->opcode, 6, 5);
24753    Rb = extract32(ctx->opcode, 16, 5);
24754
24755    if (XRa <= 15) {
24756        gen_load_mxu_gpr(t0, XRa);
24757    } else if (XRa == 16) {
24758        gen_load_mxu_cr(t0);
24759    }
24760
24761    gen_store_gpr(t0, Rb);
24762
24763    tcg_temp_free(t0);
24764}
24765
24766/*
24767 * S8LDD XRa, Rb, s8, optn3 - Load a byte from memory to XRF
24768 */
24769static void gen_mxu_s8ldd(DisasContext *ctx)
24770{
24771    TCGv t0, t1;
24772    uint32_t XRa, Rb, s8, optn3;
24773
24774    t0 = tcg_temp_new();
24775    t1 = tcg_temp_new();
24776
24777    XRa = extract32(ctx->opcode, 6, 4);
24778    s8 = extract32(ctx->opcode, 10, 8);
24779    optn3 = extract32(ctx->opcode, 18, 3);
24780    Rb = extract32(ctx->opcode, 21, 5);
24781
24782    gen_load_gpr(t0, Rb);
24783    tcg_gen_addi_tl(t0, t0, (int8_t)s8);
24784
24785    switch (optn3) {
24786    /* XRa[7:0] = tmp8 */
24787    case MXU_OPTN3_PTN0:
24788        tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_UB);
24789        gen_load_mxu_gpr(t0, XRa);
24790        tcg_gen_deposit_tl(t0, t0, t1, 0, 8);
24791        break;
24792    /* XRa[15:8] = tmp8 */
24793    case MXU_OPTN3_PTN1:
24794        tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_UB);
24795        gen_load_mxu_gpr(t0, XRa);
24796        tcg_gen_deposit_tl(t0, t0, t1, 8, 8);
24797        break;
24798    /* XRa[23:16] = tmp8 */
24799    case MXU_OPTN3_PTN2:
24800        tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_UB);
24801        gen_load_mxu_gpr(t0, XRa);
24802        tcg_gen_deposit_tl(t0, t0, t1, 16, 8);
24803        break;
24804    /* XRa[31:24] = tmp8 */
24805    case MXU_OPTN3_PTN3:
24806        tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_UB);
24807        gen_load_mxu_gpr(t0, XRa);
24808        tcg_gen_deposit_tl(t0, t0, t1, 24, 8);
24809        break;
24810    /* XRa = {8'b0, tmp8, 8'b0, tmp8} */
24811    case MXU_OPTN3_PTN4:
24812        tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_UB);
24813        tcg_gen_deposit_tl(t0, t1, t1, 16, 16);
24814        break;
24815    /* XRa = {tmp8, 8'b0, tmp8, 8'b0} */
24816    case MXU_OPTN3_PTN5:
24817        tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_UB);
24818        tcg_gen_shli_tl(t1, t1, 8);
24819        tcg_gen_deposit_tl(t0, t1, t1, 16, 16);
24820        break;
24821    /* XRa = {{8{sign of tmp8}}, tmp8, {8{sign of tmp8}}, tmp8} */
24822    case MXU_OPTN3_PTN6:
24823        tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_SB);
24824        tcg_gen_mov_tl(t0, t1);
24825        tcg_gen_andi_tl(t0, t0, 0xFF00FFFF);
24826        tcg_gen_shli_tl(t1, t1, 16);
24827        tcg_gen_or_tl(t0, t0, t1);
24828        break;
24829    /* XRa = {tmp8, tmp8, tmp8, tmp8} */
24830    case MXU_OPTN3_PTN7:
24831        tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_UB);
24832        tcg_gen_deposit_tl(t1, t1, t1, 8, 8);
24833        tcg_gen_deposit_tl(t0, t1, t1, 16, 16);
24834        break;
24835    }
24836
24837    gen_store_mxu_gpr(t0, XRa);
24838
24839    tcg_temp_free(t0);
24840    tcg_temp_free(t1);
24841}
24842
24843/*
24844 * D16MUL XRa, XRb, XRc, XRd, optn2 - Signed 16 bit pattern multiplication
24845 */
24846static void gen_mxu_d16mul(DisasContext *ctx)
24847{
24848    TCGv t0, t1, t2, t3;
24849    uint32_t XRa, XRb, XRc, XRd, optn2;
24850
24851    t0 = tcg_temp_new();
24852    t1 = tcg_temp_new();
24853    t2 = tcg_temp_new();
24854    t3 = tcg_temp_new();
24855
24856    XRa = extract32(ctx->opcode, 6, 4);
24857    XRb = extract32(ctx->opcode, 10, 4);
24858    XRc = extract32(ctx->opcode, 14, 4);
24859    XRd = extract32(ctx->opcode, 18, 4);
24860    optn2 = extract32(ctx->opcode, 22, 2);
24861
24862    gen_load_mxu_gpr(t1, XRb);
24863    tcg_gen_sextract_tl(t0, t1, 0, 16);
24864    tcg_gen_sextract_tl(t1, t1, 16, 16);
24865    gen_load_mxu_gpr(t3, XRc);
24866    tcg_gen_sextract_tl(t2, t3, 0, 16);
24867    tcg_gen_sextract_tl(t3, t3, 16, 16);
24868
24869    switch (optn2) {
24870    case MXU_OPTN2_WW: /* XRB.H*XRC.H == lop, XRB.L*XRC.L == rop */
24871        tcg_gen_mul_tl(t3, t1, t3);
24872        tcg_gen_mul_tl(t2, t0, t2);
24873        break;
24874    case MXU_OPTN2_LW: /* XRB.L*XRC.H == lop, XRB.L*XRC.L == rop */
24875        tcg_gen_mul_tl(t3, t0, t3);
24876        tcg_gen_mul_tl(t2, t0, t2);
24877        break;
24878    case MXU_OPTN2_HW: /* XRB.H*XRC.H == lop, XRB.H*XRC.L == rop */
24879        tcg_gen_mul_tl(t3, t1, t3);
24880        tcg_gen_mul_tl(t2, t1, t2);
24881        break;
24882    case MXU_OPTN2_XW: /* XRB.L*XRC.H == lop, XRB.H*XRC.L == rop */
24883        tcg_gen_mul_tl(t3, t0, t3);
24884        tcg_gen_mul_tl(t2, t1, t2);
24885        break;
24886    }
24887    gen_store_mxu_gpr(t3, XRa);
24888    gen_store_mxu_gpr(t2, XRd);
24889
24890    tcg_temp_free(t0);
24891    tcg_temp_free(t1);
24892    tcg_temp_free(t2);
24893    tcg_temp_free(t3);
24894}
24895
24896/*
24897 * D16MAC XRa, XRb, XRc, XRd, aptn2, optn2 - Signed 16 bit pattern multiply
24898 *                                           and accumulate
24899 */
24900static void gen_mxu_d16mac(DisasContext *ctx)
24901{
24902    TCGv t0, t1, t2, t3;
24903    uint32_t XRa, XRb, XRc, XRd, optn2, aptn2;
24904
24905    t0 = tcg_temp_new();
24906    t1 = tcg_temp_new();
24907    t2 = tcg_temp_new();
24908    t3 = tcg_temp_new();
24909
24910    XRa = extract32(ctx->opcode, 6, 4);
24911    XRb = extract32(ctx->opcode, 10, 4);
24912    XRc = extract32(ctx->opcode, 14, 4);
24913    XRd = extract32(ctx->opcode, 18, 4);
24914    optn2 = extract32(ctx->opcode, 22, 2);
24915    aptn2 = extract32(ctx->opcode, 24, 2);
24916
24917    gen_load_mxu_gpr(t1, XRb);
24918    tcg_gen_sextract_tl(t0, t1, 0, 16);
24919    tcg_gen_sextract_tl(t1, t1, 16, 16);
24920
24921    gen_load_mxu_gpr(t3, XRc);
24922    tcg_gen_sextract_tl(t2, t3, 0, 16);
24923    tcg_gen_sextract_tl(t3, t3, 16, 16);
24924
24925    switch (optn2) {
24926    case MXU_OPTN2_WW: /* XRB.H*XRC.H == lop, XRB.L*XRC.L == rop */
24927        tcg_gen_mul_tl(t3, t1, t3);
24928        tcg_gen_mul_tl(t2, t0, t2);
24929        break;
24930    case MXU_OPTN2_LW: /* XRB.L*XRC.H == lop, XRB.L*XRC.L == rop */
24931        tcg_gen_mul_tl(t3, t0, t3);
24932        tcg_gen_mul_tl(t2, t0, t2);
24933        break;
24934    case MXU_OPTN2_HW: /* XRB.H*XRC.H == lop, XRB.H*XRC.L == rop */
24935        tcg_gen_mul_tl(t3, t1, t3);
24936        tcg_gen_mul_tl(t2, t1, t2);
24937        break;
24938    case MXU_OPTN2_XW: /* XRB.L*XRC.H == lop, XRB.H*XRC.L == rop */
24939        tcg_gen_mul_tl(t3, t0, t3);
24940        tcg_gen_mul_tl(t2, t1, t2);
24941        break;
24942    }
24943    gen_load_mxu_gpr(t0, XRa);
24944    gen_load_mxu_gpr(t1, XRd);
24945
24946    switch (aptn2) {
24947    case MXU_APTN2_AA:
24948        tcg_gen_add_tl(t3, t0, t3);
24949        tcg_gen_add_tl(t2, t1, t2);
24950        break;
24951    case MXU_APTN2_AS:
24952        tcg_gen_add_tl(t3, t0, t3);
24953        tcg_gen_sub_tl(t2, t1, t2);
24954        break;
24955    case MXU_APTN2_SA:
24956        tcg_gen_sub_tl(t3, t0, t3);
24957        tcg_gen_add_tl(t2, t1, t2);
24958        break;
24959    case MXU_APTN2_SS:
24960        tcg_gen_sub_tl(t3, t0, t3);
24961        tcg_gen_sub_tl(t2, t1, t2);
24962        break;
24963    }
24964    gen_store_mxu_gpr(t3, XRa);
24965    gen_store_mxu_gpr(t2, XRd);
24966
24967    tcg_temp_free(t0);
24968    tcg_temp_free(t1);
24969    tcg_temp_free(t2);
24970    tcg_temp_free(t3);
24971}
24972
24973/*
24974 * Q8MUL   XRa, XRb, XRc, XRd - Parallel unsigned 8 bit pattern multiply
24975 * Q8MULSU XRa, XRb, XRc, XRd - Parallel signed 8 bit pattern multiply
24976 */
24977static void gen_mxu_q8mul_q8mulsu(DisasContext *ctx)
24978{
24979    TCGv t0, t1, t2, t3, t4, t5, t6, t7;
24980    uint32_t XRa, XRb, XRc, XRd, sel;
24981
24982    t0 = tcg_temp_new();
24983    t1 = tcg_temp_new();
24984    t2 = tcg_temp_new();
24985    t3 = tcg_temp_new();
24986    t4 = tcg_temp_new();
24987    t5 = tcg_temp_new();
24988    t6 = tcg_temp_new();
24989    t7 = tcg_temp_new();
24990
24991    XRa = extract32(ctx->opcode, 6, 4);
24992    XRb = extract32(ctx->opcode, 10, 4);
24993    XRc = extract32(ctx->opcode, 14, 4);
24994    XRd = extract32(ctx->opcode, 18, 4);
24995    sel = extract32(ctx->opcode, 22, 2);
24996
24997    gen_load_mxu_gpr(t3, XRb);
24998    gen_load_mxu_gpr(t7, XRc);
24999
25000    if (sel == 0x2) {
25001        /* Q8MULSU */
25002        tcg_gen_ext8s_tl(t0, t3);
25003        tcg_gen_shri_tl(t3, t3, 8);
25004        tcg_gen_ext8s_tl(t1, t3);
25005        tcg_gen_shri_tl(t3, t3, 8);
25006        tcg_gen_ext8s_tl(t2, t3);
25007        tcg_gen_shri_tl(t3, t3, 8);
25008        tcg_gen_ext8s_tl(t3, t3);
25009    } else {
25010        /* Q8MUL */
25011        tcg_gen_ext8u_tl(t0, t3);
25012        tcg_gen_shri_tl(t3, t3, 8);
25013        tcg_gen_ext8u_tl(t1, t3);
25014        tcg_gen_shri_tl(t3, t3, 8);
25015        tcg_gen_ext8u_tl(t2, t3);
25016        tcg_gen_shri_tl(t3, t3, 8);
25017        tcg_gen_ext8u_tl(t3, t3);
25018    }
25019
25020    tcg_gen_ext8u_tl(t4, t7);
25021    tcg_gen_shri_tl(t7, t7, 8);
25022    tcg_gen_ext8u_tl(t5, t7);
25023    tcg_gen_shri_tl(t7, t7, 8);
25024    tcg_gen_ext8u_tl(t6, t7);
25025    tcg_gen_shri_tl(t7, t7, 8);
25026    tcg_gen_ext8u_tl(t7, t7);
25027
25028    tcg_gen_mul_tl(t0, t0, t4);
25029    tcg_gen_mul_tl(t1, t1, t5);
25030    tcg_gen_mul_tl(t2, t2, t6);
25031    tcg_gen_mul_tl(t3, t3, t7);
25032
25033    tcg_gen_andi_tl(t0, t0, 0xFFFF);
25034    tcg_gen_andi_tl(t1, t1, 0xFFFF);
25035    tcg_gen_andi_tl(t2, t2, 0xFFFF);
25036    tcg_gen_andi_tl(t3, t3, 0xFFFF);
25037
25038    tcg_gen_shli_tl(t1, t1, 16);
25039    tcg_gen_shli_tl(t3, t3, 16);
25040
25041    tcg_gen_or_tl(t0, t0, t1);
25042    tcg_gen_or_tl(t1, t2, t3);
25043
25044    gen_store_mxu_gpr(t0, XRd);
25045    gen_store_mxu_gpr(t1, XRa);
25046
25047    tcg_temp_free(t0);
25048    tcg_temp_free(t1);
25049    tcg_temp_free(t2);
25050    tcg_temp_free(t3);
25051    tcg_temp_free(t4);
25052    tcg_temp_free(t5);
25053    tcg_temp_free(t6);
25054    tcg_temp_free(t7);
25055}
25056
25057/*
25058 * S32LDD  XRa, Rb, S12 - Load a word from memory to XRF
25059 * S32LDDR XRa, Rb, S12 - Load a word from memory to XRF, reversed byte seq.
25060 */
25061static void gen_mxu_s32ldd_s32lddr(DisasContext *ctx)
25062{
25063    TCGv t0, t1;
25064    uint32_t XRa, Rb, s12, sel;
25065
25066    t0 = tcg_temp_new();
25067    t1 = tcg_temp_new();
25068
25069    XRa = extract32(ctx->opcode, 6, 4);
25070    s12 = extract32(ctx->opcode, 10, 10);
25071    sel = extract32(ctx->opcode, 20, 1);
25072    Rb = extract32(ctx->opcode, 21, 5);
25073
25074    gen_load_gpr(t0, Rb);
25075
25076    tcg_gen_movi_tl(t1, s12);
25077    tcg_gen_shli_tl(t1, t1, 2);
25078    if (s12 & 0x200) {
25079        tcg_gen_ori_tl(t1, t1, 0xFFFFF000);
25080    }
25081    tcg_gen_add_tl(t1, t0, t1);
25082    tcg_gen_qemu_ld_tl(t1, t1, ctx->mem_idx, MO_SL);
25083
25084    if (sel == 1) {
25085        /* S32LDDR */
25086        tcg_gen_bswap32_tl(t1, t1);
25087    }
25088    gen_store_mxu_gpr(t1, XRa);
25089
25090    tcg_temp_free(t0);
25091    tcg_temp_free(t1);
25092}
25093
25094
25095/*
25096 *                 MXU instruction category: logic
25097 *                 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
25098 *
25099 *               S32NOR    S32AND    S32OR    S32XOR
25100 */
25101
25102/*
25103 *  S32NOR XRa, XRb, XRc
25104 *    Update XRa with the result of logical bitwise 'nor' operation
25105 *    applied to the content of XRb and XRc.
25106 *
25107 *   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
25108 *  +-----------+---------+-----+-------+-------+-------+-----------+
25109 *  |  SPECIAL2 |0 0 0 0 0| opc |  XRc  |  XRb  |  XRa  |MXU__POOL16|
25110 *  +-----------+---------+-----+-------+-------+-------+-----------+
25111 */
25112static void gen_mxu_S32NOR(DisasContext *ctx)
25113{
25114    uint32_t pad, XRc, XRb, XRa;
25115
25116    pad = extract32(ctx->opcode, 21, 5);
25117    XRc = extract32(ctx->opcode, 14, 4);
25118    XRb = extract32(ctx->opcode, 10, 4);
25119    XRa = extract32(ctx->opcode,  6, 4);
25120
25121    if (unlikely(pad != 0)) {
25122        /* opcode padding incorrect -> do nothing */
25123    } else if (unlikely(XRa == 0)) {
25124        /* destination is zero register -> do nothing */
25125    } else if (unlikely((XRb == 0) && (XRc == 0))) {
25126        /* both operands zero registers -> just set destination to all 1s */
25127        tcg_gen_movi_i32(mxu_gpr[XRa - 1], 0xFFFFFFFF);
25128    } else if (unlikely(XRb == 0)) {
25129        /* XRb zero register -> just set destination to the negation of XRc */
25130        tcg_gen_not_i32(mxu_gpr[XRa - 1], mxu_gpr[XRc - 1]);
25131    } else if (unlikely(XRc == 0)) {
25132        /* XRa zero register -> just set destination to the negation of XRb */
25133        tcg_gen_not_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1]);
25134    } else if (unlikely(XRb == XRc)) {
25135        /* both operands same -> just set destination to the negation of XRb */
25136        tcg_gen_not_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1]);
25137    } else {
25138        /* the most general case */
25139        tcg_gen_nor_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1], mxu_gpr[XRc - 1]);
25140    }
25141}
25142
25143/*
25144 *  S32AND XRa, XRb, XRc
25145 *    Update XRa with the result of logical bitwise 'and' operation
25146 *    applied to the content of XRb and XRc.
25147 *
25148 *   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
25149 *  +-----------+---------+-----+-------+-------+-------+-----------+
25150 *  |  SPECIAL2 |0 0 0 0 0| opc |  XRc  |  XRb  |  XRa  |MXU__POOL16|
25151 *  +-----------+---------+-----+-------+-------+-------+-----------+
25152 */
25153static void gen_mxu_S32AND(DisasContext *ctx)
25154{
25155    uint32_t pad, XRc, XRb, XRa;
25156
25157    pad = extract32(ctx->opcode, 21, 5);
25158    XRc = extract32(ctx->opcode, 14, 4);
25159    XRb = extract32(ctx->opcode, 10, 4);
25160    XRa = extract32(ctx->opcode,  6, 4);
25161
25162    if (unlikely(pad != 0)) {
25163        /* opcode padding incorrect -> do nothing */
25164    } else if (unlikely(XRa == 0)) {
25165        /* destination is zero register -> do nothing */
25166    } else if (unlikely((XRb == 0) || (XRc == 0))) {
25167        /* one of operands zero register -> just set destination to all 0s */
25168        tcg_gen_movi_i32(mxu_gpr[XRa - 1], 0);
25169    } else if (unlikely(XRb == XRc)) {
25170        /* both operands same -> just set destination to one of them */
25171        tcg_gen_mov_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1]);
25172    } else {
25173        /* the most general case */
25174        tcg_gen_and_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1], mxu_gpr[XRc - 1]);
25175    }
25176}
25177
25178/*
25179 *  S32OR XRa, XRb, XRc
25180 *    Update XRa with the result of logical bitwise 'or' operation
25181 *    applied to the content of XRb and XRc.
25182 *
25183 *   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
25184 *  +-----------+---------+-----+-------+-------+-------+-----------+
25185 *  |  SPECIAL2 |0 0 0 0 0| opc |  XRc  |  XRb  |  XRa  |MXU__POOL16|
25186 *  +-----------+---------+-----+-------+-------+-------+-----------+
25187 */
25188static void gen_mxu_S32OR(DisasContext *ctx)
25189{
25190    uint32_t pad, XRc, XRb, XRa;
25191
25192    pad = extract32(ctx->opcode, 21, 5);
25193    XRc = extract32(ctx->opcode, 14, 4);
25194    XRb = extract32(ctx->opcode, 10, 4);
25195    XRa = extract32(ctx->opcode,  6, 4);
25196
25197    if (unlikely(pad != 0)) {
25198        /* opcode padding incorrect -> do nothing */
25199    } else if (unlikely(XRa == 0)) {
25200        /* destination is zero register -> do nothing */
25201    } else if (unlikely((XRb == 0) && (XRc == 0))) {
25202        /* both operands zero registers -> just set destination to all 0s */
25203        tcg_gen_movi_i32(mxu_gpr[XRa - 1], 0);
25204    } else if (unlikely(XRb == 0)) {
25205        /* XRb zero register -> just set destination to the content of XRc */
25206        tcg_gen_mov_i32(mxu_gpr[XRa - 1], mxu_gpr[XRc - 1]);
25207    } else if (unlikely(XRc == 0)) {
25208        /* XRc zero register -> just set destination to the content of XRb */
25209        tcg_gen_mov_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1]);
25210    } else if (unlikely(XRb == XRc)) {
25211        /* both operands same -> just set destination to one of them */
25212        tcg_gen_mov_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1]);
25213    } else {
25214        /* the most general case */
25215        tcg_gen_or_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1], mxu_gpr[XRc - 1]);
25216    }
25217}
25218
25219/*
25220 *  S32XOR XRa, XRb, XRc
25221 *    Update XRa with the result of logical bitwise 'xor' operation
25222 *    applied to the content of XRb and XRc.
25223 *
25224 *   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
25225 *  +-----------+---------+-----+-------+-------+-------+-----------+
25226 *  |  SPECIAL2 |0 0 0 0 0| opc |  XRc  |  XRb  |  XRa  |MXU__POOL16|
25227 *  +-----------+---------+-----+-------+-------+-------+-----------+
25228 */
25229static void gen_mxu_S32XOR(DisasContext *ctx)
25230{
25231    uint32_t pad, XRc, XRb, XRa;
25232
25233    pad = extract32(ctx->opcode, 21, 5);
25234    XRc = extract32(ctx->opcode, 14, 4);
25235    XRb = extract32(ctx->opcode, 10, 4);
25236    XRa = extract32(ctx->opcode,  6, 4);
25237
25238    if (unlikely(pad != 0)) {
25239        /* opcode padding incorrect -> do nothing */
25240    } else if (unlikely(XRa == 0)) {
25241        /* destination is zero register -> do nothing */
25242    } else if (unlikely((XRb == 0) && (XRc == 0))) {
25243        /* both operands zero registers -> just set destination to all 0s */
25244        tcg_gen_movi_i32(mxu_gpr[XRa - 1], 0);
25245    } else if (unlikely(XRb == 0)) {
25246        /* XRb zero register -> just set destination to the content of XRc */
25247        tcg_gen_mov_i32(mxu_gpr[XRa - 1], mxu_gpr[XRc - 1]);
25248    } else if (unlikely(XRc == 0)) {
25249        /* XRc zero register -> just set destination to the content of XRb */
25250        tcg_gen_mov_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1]);
25251    } else if (unlikely(XRb == XRc)) {
25252        /* both operands same -> just set destination to all 0s */
25253        tcg_gen_movi_i32(mxu_gpr[XRa - 1], 0);
25254    } else {
25255        /* the most general case */
25256        tcg_gen_xor_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1], mxu_gpr[XRc - 1]);
25257    }
25258}
25259
25260
25261/*
25262 *                   MXU instruction category max/min
25263 *                   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
25264 *
25265 *                     S32MAX     D16MAX     Q8MAX
25266 *                     S32MIN     D16MIN     Q8MIN
25267 */
25268
25269/*
25270 *  S32MAX XRa, XRb, XRc
25271 *    Update XRa with the maximum of signed 32-bit integers contained
25272 *    in XRb and XRc.
25273 *
25274 *  S32MIN XRa, XRb, XRc
25275 *    Update XRa with the minimum of signed 32-bit integers contained
25276 *    in XRb and XRc.
25277 *
25278 *   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
25279 *  +-----------+---------+-----+-------+-------+-------+-----------+
25280 *  |  SPECIAL2 |0 0 0 0 0| opc |  XRc  |  XRb  |  XRa  |MXU__POOL00|
25281 *  +-----------+---------+-----+-------+-------+-------+-----------+
25282 */
25283static void gen_mxu_S32MAX_S32MIN(DisasContext *ctx)
25284{
25285    uint32_t pad, opc, XRc, XRb, XRa;
25286
25287    pad = extract32(ctx->opcode, 21, 5);
25288    opc = extract32(ctx->opcode, 18, 3);
25289    XRc = extract32(ctx->opcode, 14, 4);
25290    XRb = extract32(ctx->opcode, 10, 4);
25291    XRa = extract32(ctx->opcode,  6, 4);
25292
25293    if (unlikely(pad != 0)) {
25294        /* opcode padding incorrect -> do nothing */
25295    } else if (unlikely(XRa == 0)) {
25296        /* destination is zero register -> do nothing */
25297    } else if (unlikely((XRb == 0) && (XRc == 0))) {
25298        /* both operands zero registers -> just set destination to zero */
25299        tcg_gen_movi_i32(mxu_gpr[XRa - 1], 0);
25300    } else if (unlikely((XRb == 0) || (XRc == 0))) {
25301        /* exactly one operand is zero register - find which one is not...*/
25302        uint32_t XRx = XRb ? XRb : XRc;
25303        /* ...and do max/min operation with one operand 0 */
25304        if (opc == OPC_MXU_S32MAX) {
25305            tcg_gen_smax_i32(mxu_gpr[XRa - 1], mxu_gpr[XRx - 1], 0);
25306        } else {
25307            tcg_gen_smin_i32(mxu_gpr[XRa - 1], mxu_gpr[XRx - 1], 0);
25308        }
25309    } else if (unlikely(XRb == XRc)) {
25310        /* both operands same -> just set destination to one of them */
25311        tcg_gen_mov_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1]);
25312    } else {
25313        /* the most general case */
25314        if (opc == OPC_MXU_S32MAX) {
25315            tcg_gen_smax_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1],
25316                                               mxu_gpr[XRc - 1]);
25317        } else {
25318            tcg_gen_smin_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1],
25319                                               mxu_gpr[XRc - 1]);
25320        }
25321    }
25322}
25323
25324/*
25325 *  D16MAX
25326 *    Update XRa with the 16-bit-wise maximums of signed integers
25327 *    contained in XRb and XRc.
25328 *
25329 *  D16MIN
25330 *    Update XRa with the 16-bit-wise minimums of signed integers
25331 *    contained in XRb and XRc.
25332 *
25333 *   1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
25334 *  +-----------+---------+-----+-------+-------+-------+-----------+
25335 *  |  SPECIAL2 |0 0 0 0 0| opc |  XRc  |  XRb  |  XRa  |MXU__POOL00|
25336 *  +-----------+---------+-----+-------+-------+-------+-----------+
25337 */
25338static void gen_mxu_D16MAX_D16MIN(DisasContext *ctx)
25339{
25340    uint32_t pad, opc, XRc, XRb, XRa;
25341
25342    pad = extract32(ctx->opcode, 21, 5);
25343    opc = extract32(ctx->opcode, 18, 3);
25344    XRc = extract32(ctx->opcode, 14, 4);
25345    XRb = extract32(ctx->opcode, 10, 4);
25346    XRa = extract32(ctx->opcode,  6, 4);
25347
25348    if (unlikely(pad != 0)) {
25349        /* opcode padding incorrect -> do nothing */
25350    } else if (unlikely(XRc == 0)) {
25351        /* destination is zero register -> do nothing */
25352    } else if (unlikely((XRb == 0) && (XRa == 0))) {
25353        /* both operands zero registers -> just set destination to zero */
25354        tcg_gen_movi_i32(mxu_gpr[XRc - 1], 0);
25355    } else if (unlikely((XRb == 0) || (XRa == 0))) {
25356        /* exactly one operand is zero register - find which one is not...*/
25357        uint32_t XRx = XRb ? XRb : XRc;
25358        /* ...and do half-word-wise max/min with one operand 0 */
25359        TCGv_i32 t0 = tcg_temp_new();
25360        TCGv_i32 t1 = tcg_const_i32(0);
25361
25362        /* the left half-word first */
25363        tcg_gen_andi_i32(t0, mxu_gpr[XRx - 1], 0xFFFF0000);
25364        if (opc == OPC_MXU_D16MAX) {
25365            tcg_gen_smax_i32(mxu_gpr[XRa - 1], t0, t1);
25366        } else {
25367            tcg_gen_smin_i32(mxu_gpr[XRa - 1], t0, t1);
25368        }
25369
25370        /* the right half-word */
25371        tcg_gen_andi_i32(t0, mxu_gpr[XRx - 1], 0x0000FFFF);
25372        /* move half-words to the leftmost position */
25373        tcg_gen_shli_i32(t0, t0, 16);
25374        /* t0 will be max/min of t0 and t1 */
25375        if (opc == OPC_MXU_D16MAX) {
25376            tcg_gen_smax_i32(t0, t0, t1);
25377        } else {
25378            tcg_gen_smin_i32(t0, t0, t1);
25379        }
25380        /* return resulting half-words to its original position */
25381        tcg_gen_shri_i32(t0, t0, 16);
25382        /* finaly update the destination */
25383        tcg_gen_or_i32(mxu_gpr[XRa - 1], mxu_gpr[XRa - 1], t0);
25384
25385        tcg_temp_free(t1);
25386        tcg_temp_free(t0);
25387    } else if (unlikely(XRb == XRc)) {
25388        /* both operands same -> just set destination to one of them */
25389        tcg_gen_mov_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1]);
25390    } else {
25391        /* the most general case */
25392        TCGv_i32 t0 = tcg_temp_new();
25393        TCGv_i32 t1 = tcg_temp_new();
25394
25395        /* the left half-word first */
25396        tcg_gen_andi_i32(t0, mxu_gpr[XRb - 1], 0xFFFF0000);
25397        tcg_gen_andi_i32(t1, mxu_gpr[XRc - 1], 0xFFFF0000);
25398        if (opc == OPC_MXU_D16MAX) {
25399            tcg_gen_smax_i32(mxu_gpr[XRa - 1], t0, t1);
25400        } else {
25401            tcg_gen_smin_i32(mxu_gpr[XRa - 1], t0, t1);
25402        }
25403
25404        /* the right half-word */
25405        tcg_gen_andi_i32(t0, mxu_gpr[XRb - 1], 0x0000FFFF);
25406        tcg_gen_andi_i32(t1, mxu_gpr[XRc - 1], 0x0000FFFF);
25407        /* move half-words to the leftmost position */
25408        tcg_gen_shli_i32(t0, t0, 16);
25409        tcg_gen_shli_i32(t1, t1, 16);
25410        /* t0 will be max/min of t0 and t1 */
25411        if (opc == OPC_MXU_D16MAX) {
25412            tcg_gen_smax_i32(t0, t0, t1);
25413        } else {
25414            tcg_gen_smin_i32(t0, t0, t1);
25415        }
25416        /* return resulting half-words to its original position */
25417        tcg_gen_shri_i32(t0, t0, 16);
25418        /* finaly update the destination */
25419        tcg_gen_or_i32(mxu_gpr[XRa - 1], mxu_gpr[XRa - 1], t0);
25420
25421        tcg_temp_free(t1);
25422        tcg_temp_free(t0);
25423    }
25424}
25425
25426/*
25427 *  Q8MAX
25428 *    Update XRa with the 8-bit-wise maximums of signed integers
25429 *    contained in XRb and XRc.
25430 *
25431 *  Q8MIN
25432 *    Update XRa with the 8-bit-wise minimums of signed integers
25433 *    contained in XRb and XRc.
25434 *
25435 *   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
25436 *  +-----------+---------+-----+-------+-------+-------+-----------+
25437 *  |  SPECIAL2 |0 0 0 0 0| opc |  XRc  |  XRb  |  XRa  |MXU__POOL00|
25438 *  +-----------+---------+-----+-------+-------+-------+-----------+
25439 */
25440static void gen_mxu_Q8MAX_Q8MIN(DisasContext *ctx)
25441{
25442    uint32_t pad, opc, XRc, XRb, XRa;
25443
25444    pad = extract32(ctx->opcode, 21, 5);
25445    opc = extract32(ctx->opcode, 18, 3);
25446    XRc = extract32(ctx->opcode, 14, 4);
25447    XRb = extract32(ctx->opcode, 10, 4);
25448    XRa = extract32(ctx->opcode,  6, 4);
25449
25450    if (unlikely(pad != 0)) {
25451        /* opcode padding incorrect -> do nothing */
25452    } else if (unlikely(XRa == 0)) {
25453        /* destination is zero register -> do nothing */
25454    } else if (unlikely((XRb == 0) && (XRc == 0))) {
25455        /* both operands zero registers -> just set destination to zero */
25456        tcg_gen_movi_i32(mxu_gpr[XRa - 1], 0);
25457    } else if (unlikely((XRb == 0) || (XRc == 0))) {
25458        /* exactly one operand is zero register - make it be the first...*/
25459        uint32_t XRx = XRb ? XRb : XRc;
25460        /* ...and do byte-wise max/min with one operand 0 */
25461        TCGv_i32 t0 = tcg_temp_new();
25462        TCGv_i32 t1 = tcg_const_i32(0);
25463        int32_t i;
25464
25465        /* the leftmost byte (byte 3) first */
25466        tcg_gen_andi_i32(t0, mxu_gpr[XRx - 1], 0xFF000000);
25467        if (opc == OPC_MXU_Q8MAX) {
25468            tcg_gen_smax_i32(mxu_gpr[XRa - 1], t0, t1);
25469        } else {
25470            tcg_gen_smin_i32(mxu_gpr[XRa - 1], t0, t1);
25471        }
25472
25473        /* bytes 2, 1, 0 */
25474        for (i = 2; i >= 0; i--) {
25475            /* extract the byte */
25476            tcg_gen_andi_i32(t0, mxu_gpr[XRx - 1], 0xFF << (8 * i));
25477            /* move the byte to the leftmost position */
25478            tcg_gen_shli_i32(t0, t0, 8 * (3 - i));
25479            /* t0 will be max/min of t0 and t1 */
25480            if (opc == OPC_MXU_Q8MAX) {
25481                tcg_gen_smax_i32(t0, t0, t1);
25482            } else {
25483                tcg_gen_smin_i32(t0, t0, t1);
25484            }
25485            /* return resulting byte to its original position */
25486            tcg_gen_shri_i32(t0, t0, 8 * (3 - i));
25487            /* finaly update the destination */
25488            tcg_gen_or_i32(mxu_gpr[XRa - 1], mxu_gpr[XRa - 1], t0);
25489        }
25490
25491        tcg_temp_free(t1);
25492        tcg_temp_free(t0);
25493    } else if (unlikely(XRb == XRc)) {
25494        /* both operands same -> just set destination to one of them */
25495        tcg_gen_mov_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1]);
25496    } else {
25497        /* the most general case */
25498        TCGv_i32 t0 = tcg_temp_new();
25499        TCGv_i32 t1 = tcg_temp_new();
25500        int32_t i;
25501
25502        /* the leftmost bytes (bytes 3) first */
25503        tcg_gen_andi_i32(t0, mxu_gpr[XRb - 1], 0xFF000000);
25504        tcg_gen_andi_i32(t1, mxu_gpr[XRc - 1], 0xFF000000);
25505        if (opc == OPC_MXU_Q8MAX) {
25506            tcg_gen_smax_i32(mxu_gpr[XRa - 1], t0, t1);
25507        } else {
25508            tcg_gen_smin_i32(mxu_gpr[XRa - 1], t0, t1);
25509        }
25510
25511        /* bytes 2, 1, 0 */
25512        for (i = 2; i >= 0; i--) {
25513            /* extract corresponding bytes */
25514            tcg_gen_andi_i32(t0, mxu_gpr[XRb - 1], 0xFF << (8 * i));
25515            tcg_gen_andi_i32(t1, mxu_gpr[XRc - 1], 0xFF << (8 * i));
25516            /* move the bytes to the leftmost position */
25517            tcg_gen_shli_i32(t0, t0, 8 * (3 - i));
25518            tcg_gen_shli_i32(t1, t1, 8 * (3 - i));
25519            /* t0 will be max/min of t0 and t1 */
25520            if (opc == OPC_MXU_Q8MAX) {
25521                tcg_gen_smax_i32(t0, t0, t1);
25522            } else {
25523                tcg_gen_smin_i32(t0, t0, t1);
25524            }
25525            /* return resulting byte to its original position */
25526            tcg_gen_shri_i32(t0, t0, 8 * (3 - i));
25527            /* finaly update the destination */
25528            tcg_gen_or_i32(mxu_gpr[XRa - 1], mxu_gpr[XRa - 1], t0);
25529        }
25530
25531        tcg_temp_free(t1);
25532        tcg_temp_free(t0);
25533    }
25534}
25535
25536
25537/*
25538 *                 MXU instruction category: align
25539 *                 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
25540 *
25541 *                       S32ALN     S32ALNI
25542 */
25543
25544/*
25545 *  S32ALNI XRc, XRb, XRa, optn3
25546 *    Arrange bytes from XRb and XRc according to one of five sets of
25547 *    rules determined by optn3, and place the result in XRa.
25548 *
25549 *   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
25550 *  +-----------+-----+---+-----+-------+-------+-------+-----------+
25551 *  |  SPECIAL2 |optn3|0 0|x x x|  XRc  |  XRb  |  XRa  |MXU__POOL16|
25552 *  +-----------+-----+---+-----+-------+-------+-------+-----------+
25553 *
25554 */
25555static void gen_mxu_S32ALNI(DisasContext *ctx)
25556{
25557    uint32_t optn3, pad, XRc, XRb, XRa;
25558
25559    optn3 = extract32(ctx->opcode,  23, 3);
25560    pad   = extract32(ctx->opcode,  21, 2);
25561    XRc   = extract32(ctx->opcode, 14, 4);
25562    XRb   = extract32(ctx->opcode, 10, 4);
25563    XRa   = extract32(ctx->opcode,  6, 4);
25564
25565    if (unlikely(pad != 0)) {
25566        /* opcode padding incorrect -> do nothing */
25567    } else if (unlikely(XRa == 0)) {
25568        /* destination is zero register -> do nothing */
25569    } else if (unlikely((XRb == 0) && (XRc == 0))) {
25570        /* both operands zero registers -> just set destination to all 0s */
25571        tcg_gen_movi_i32(mxu_gpr[XRa - 1], 0);
25572    } else if (unlikely(XRb == 0)) {
25573        /* XRb zero register -> just appropriatelly shift XRc into XRa */
25574        switch (optn3) {
25575        case MXU_OPTN3_PTN0:
25576            tcg_gen_movi_i32(mxu_gpr[XRa - 1], 0);
25577            break;
25578        case MXU_OPTN3_PTN1:
25579        case MXU_OPTN3_PTN2:
25580        case MXU_OPTN3_PTN3:
25581            tcg_gen_shri_i32(mxu_gpr[XRa - 1], mxu_gpr[XRc - 1],
25582                             8 * (4 - optn3));
25583            break;
25584        case MXU_OPTN3_PTN4:
25585            tcg_gen_mov_i32(mxu_gpr[XRa - 1], mxu_gpr[XRc - 1]);
25586            break;
25587        }
25588    } else if (unlikely(XRc == 0)) {
25589        /* XRc zero register -> just appropriatelly shift XRb into XRa */
25590        switch (optn3) {
25591        case MXU_OPTN3_PTN0:
25592            tcg_gen_mov_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1]);
25593            break;
25594        case MXU_OPTN3_PTN1:
25595        case MXU_OPTN3_PTN2:
25596        case MXU_OPTN3_PTN3:
25597            tcg_gen_shri_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1], 8 * optn3);
25598            break;
25599        case MXU_OPTN3_PTN4:
25600            tcg_gen_movi_i32(mxu_gpr[XRa - 1], 0);
25601            break;
25602        }
25603    } else if (unlikely(XRb == XRc)) {
25604        /* both operands same -> just rotation or moving from any of them */
25605        switch (optn3) {
25606        case MXU_OPTN3_PTN0:
25607        case MXU_OPTN3_PTN4:
25608            tcg_gen_mov_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1]);
25609            break;
25610        case MXU_OPTN3_PTN1:
25611        case MXU_OPTN3_PTN2:
25612        case MXU_OPTN3_PTN3:
25613            tcg_gen_rotli_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1], 8 * optn3);
25614            break;
25615        }
25616    } else {
25617        /* the most general case */
25618        switch (optn3) {
25619        case MXU_OPTN3_PTN0:
25620            {
25621                /*                                         */
25622                /*         XRb                XRc          */
25623                /*  +---------------+                      */
25624                /*  | A   B   C   D |    E   F   G   H     */
25625                /*  +-------+-------+                      */
25626                /*          |                              */
25627                /*         XRa                             */
25628                /*                                         */
25629
25630                tcg_gen_mov_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1]);
25631            }
25632            break;
25633        case MXU_OPTN3_PTN1:
25634            {
25635                /*                                         */
25636                /*         XRb                 XRc         */
25637                /*      +-------------------+              */
25638                /*    A | B   C   D       E | F   G   H    */
25639                /*      +---------+---------+              */
25640                /*                |                        */
25641                /*               XRa                       */
25642                /*                                         */
25643
25644                TCGv_i32 t0 = tcg_temp_new();
25645                TCGv_i32 t1 = tcg_temp_new();
25646
25647                tcg_gen_andi_i32(t0, mxu_gpr[XRb - 1], 0x00FFFFFF);
25648                tcg_gen_shli_i32(t0, t0, 8);
25649
25650                tcg_gen_andi_i32(t1, mxu_gpr[XRc - 1], 0xFF000000);
25651                tcg_gen_shri_i32(t1, t1, 24);
25652
25653                tcg_gen_or_i32(mxu_gpr[XRa - 1], t0, t1);
25654
25655                tcg_temp_free(t1);
25656                tcg_temp_free(t0);
25657            }
25658            break;
25659        case MXU_OPTN3_PTN2:
25660            {
25661                /*                                         */
25662                /*         XRb                 XRc         */
25663                /*          +-------------------+          */
25664                /*    A   B | C   D       E   F | G   H    */
25665                /*          +---------+---------+          */
25666                /*                    |                    */
25667                /*                   XRa                   */
25668                /*                                         */
25669
25670                TCGv_i32 t0 = tcg_temp_new();
25671                TCGv_i32 t1 = tcg_temp_new();
25672
25673                tcg_gen_andi_i32(t0, mxu_gpr[XRb - 1], 0x0000FFFF);
25674                tcg_gen_shli_i32(t0, t0, 16);
25675
25676                tcg_gen_andi_i32(t1, mxu_gpr[XRc - 1], 0xFFFF0000);
25677                tcg_gen_shri_i32(t1, t1, 16);
25678
25679                tcg_gen_or_i32(mxu_gpr[XRa - 1], t0, t1);
25680
25681                tcg_temp_free(t1);
25682                tcg_temp_free(t0);
25683            }
25684            break;
25685        case MXU_OPTN3_PTN3:
25686            {
25687                /*                                         */
25688                /*         XRb                 XRc         */
25689                /*              +-------------------+      */
25690                /*    A   B   C | D       E   F   G | H    */
25691                /*              +---------+---------+      */
25692                /*                        |                */
25693                /*                       XRa               */
25694                /*                                         */
25695
25696                TCGv_i32 t0 = tcg_temp_new();
25697                TCGv_i32 t1 = tcg_temp_new();
25698
25699                tcg_gen_andi_i32(t0, mxu_gpr[XRb - 1], 0x000000FF);
25700                tcg_gen_shli_i32(t0, t0, 24);
25701
25702                tcg_gen_andi_i32(t1, mxu_gpr[XRc - 1], 0xFFFFFF00);
25703                tcg_gen_shri_i32(t1, t1, 8);
25704
25705                tcg_gen_or_i32(mxu_gpr[XRa - 1], t0, t1);
25706
25707                tcg_temp_free(t1);
25708                tcg_temp_free(t0);
25709            }
25710            break;
25711        case MXU_OPTN3_PTN4:
25712            {
25713                /*                                         */
25714                /*         XRb                 XRc         */
25715                /*                     +---------------+   */
25716                /*    A   B   C   D    | E   F   G   H |   */
25717                /*                     +-------+-------+   */
25718                /*                             |           */
25719                /*                            XRa          */
25720                /*                                         */
25721
25722                tcg_gen_mov_i32(mxu_gpr[XRa - 1], mxu_gpr[XRc - 1]);
25723            }
25724            break;
25725        }
25726    }
25727}
25728
25729
25730/*
25731 * Decoding engine for MXU
25732 * =======================
25733 */
25734
25735/*
25736 *
25737 * Decode MXU pool00
25738 *
25739 *   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
25740 *  +-----------+---------+-----+-------+-------+-------+-----------+
25741 *  |  SPECIAL2 |0 0 0 0 0|x x x|  XRc  |  XRb  |  XRa  |MXU__POOL00|
25742 *  +-----------+---------+-----+-------+-------+-------+-----------+
25743 *
25744 */
25745static void decode_opc_mxu__pool00(CPUMIPSState *env, DisasContext *ctx)
25746{
25747    uint32_t opcode = extract32(ctx->opcode, 18, 3);
25748
25749    switch (opcode) {
25750    case OPC_MXU_S32MAX:
25751    case OPC_MXU_S32MIN:
25752        gen_mxu_S32MAX_S32MIN(ctx);
25753        break;
25754    case OPC_MXU_D16MAX:
25755    case OPC_MXU_D16MIN:
25756        gen_mxu_D16MAX_D16MIN(ctx);
25757        break;
25758    case OPC_MXU_Q8MAX:
25759    case OPC_MXU_Q8MIN:
25760        gen_mxu_Q8MAX_Q8MIN(ctx);
25761        break;
25762    case OPC_MXU_Q8SLT:
25763        /* TODO: Implement emulation of Q8SLT instruction. */
25764        MIPS_INVAL("OPC_MXU_Q8SLT");
25765        generate_exception_end(ctx, EXCP_RI);
25766        break;
25767    case OPC_MXU_Q8SLTU:
25768        /* TODO: Implement emulation of Q8SLTU instruction. */
25769        MIPS_INVAL("OPC_MXU_Q8SLTU");
25770        generate_exception_end(ctx, EXCP_RI);
25771        break;
25772    default:
25773        MIPS_INVAL("decode_opc_mxu");
25774        generate_exception_end(ctx, EXCP_RI);
25775        break;
25776    }
25777}
25778
25779/*
25780 *
25781 * Decode MXU pool01
25782 *
25783 *  S32SLT, D16SLT, D16AVG, D16AVGR, Q8AVG, Q8AVGR:
25784 *   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
25785 *  +-----------+---------+-----+-------+-------+-------+-----------+
25786 *  |  SPECIAL2 |0 0 0 0 0|x x x|  XRc  |  XRb  |  XRa  |MXU__POOL01|
25787 *  +-----------+---------+-----+-------+-------+-------+-----------+
25788 *
25789 *  Q8ADD:
25790 *   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
25791 *  +-----------+---+-----+-----+-------+-------+-------+-----------+
25792 *  |  SPECIAL2 |en2|0 0 0|x x x|  XRc  |  XRb  |  XRa  |MXU__POOL01|
25793 *  +-----------+---+-----+-----+-------+-------+-------+-----------+
25794 *
25795 */
25796static void decode_opc_mxu__pool01(CPUMIPSState *env, DisasContext *ctx)
25797{
25798    uint32_t opcode = extract32(ctx->opcode, 18, 3);
25799
25800    switch (opcode) {
25801    case OPC_MXU_S32SLT:
25802        /* TODO: Implement emulation of S32SLT instruction. */
25803        MIPS_INVAL("OPC_MXU_S32SLT");
25804        generate_exception_end(ctx, EXCP_RI);
25805        break;
25806    case OPC_MXU_D16SLT:
25807        /* TODO: Implement emulation of D16SLT instruction. */
25808        MIPS_INVAL("OPC_MXU_D16SLT");
25809        generate_exception_end(ctx, EXCP_RI);
25810        break;
25811    case OPC_MXU_D16AVG:
25812        /* TODO: Implement emulation of D16AVG instruction. */
25813        MIPS_INVAL("OPC_MXU_D16AVG");
25814        generate_exception_end(ctx, EXCP_RI);
25815        break;
25816    case OPC_MXU_D16AVGR:
25817        /* TODO: Implement emulation of D16AVGR instruction. */
25818        MIPS_INVAL("OPC_MXU_D16AVGR");
25819        generate_exception_end(ctx, EXCP_RI);
25820        break;
25821    case OPC_MXU_Q8AVG:
25822        /* TODO: Implement emulation of Q8AVG instruction. */
25823        MIPS_INVAL("OPC_MXU_Q8AVG");
25824        generate_exception_end(ctx, EXCP_RI);
25825        break;
25826    case OPC_MXU_Q8AVGR:
25827        /* TODO: Implement emulation of Q8AVGR instruction. */
25828        MIPS_INVAL("OPC_MXU_Q8AVGR");
25829        generate_exception_end(ctx, EXCP_RI);
25830        break;
25831    case OPC_MXU_Q8ADD:
25832        /* TODO: Implement emulation of Q8ADD instruction. */
25833        MIPS_INVAL("OPC_MXU_Q8ADD");
25834        generate_exception_end(ctx, EXCP_RI);
25835        break;
25836    default:
25837        MIPS_INVAL("decode_opc_mxu");
25838        generate_exception_end(ctx, EXCP_RI);
25839        break;
25840    }
25841}
25842
25843/*
25844 *
25845 * Decode MXU pool02
25846 *
25847 *   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
25848 *  +-----------+---------+-----+-------+-------+-------+-----------+
25849 *  |  SPECIAL2 |0 0 0 0 0|x x x|  XRc  |  XRb  |  XRa  |MXU__POOL02|
25850 *  +-----------+---------+-----+-------+-------+-------+-----------+
25851 *
25852 */
25853static void decode_opc_mxu__pool02(CPUMIPSState *env, DisasContext *ctx)
25854{
25855    uint32_t opcode = extract32(ctx->opcode, 18, 3);
25856
25857    switch (opcode) {
25858    case OPC_MXU_S32CPS:
25859        /* TODO: Implement emulation of S32CPS instruction. */
25860        MIPS_INVAL("OPC_MXU_S32CPS");
25861        generate_exception_end(ctx, EXCP_RI);
25862        break;
25863    case OPC_MXU_D16CPS:
25864        /* TODO: Implement emulation of D16CPS instruction. */
25865        MIPS_INVAL("OPC_MXU_D16CPS");
25866        generate_exception_end(ctx, EXCP_RI);
25867        break;
25868    case OPC_MXU_Q8ABD:
25869        /* TODO: Implement emulation of Q8ABD instruction. */
25870        MIPS_INVAL("OPC_MXU_Q8ABD");
25871        generate_exception_end(ctx, EXCP_RI);
25872        break;
25873    case OPC_MXU_Q16SAT:
25874        /* TODO: Implement emulation of Q16SAT instruction. */
25875        MIPS_INVAL("OPC_MXU_Q16SAT");
25876        generate_exception_end(ctx, EXCP_RI);
25877        break;
25878    default:
25879        MIPS_INVAL("decode_opc_mxu");
25880        generate_exception_end(ctx, EXCP_RI);
25881        break;
25882    }
25883}
25884
25885/*
25886 *
25887 * Decode MXU pool03
25888 *
25889 *  D16MULF:
25890 *   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
25891 *  +-----------+---+---+-------+-------+-------+-------+-----------+
25892 *  |  SPECIAL2 |x x|on2|0 0 0 0|  XRc  |  XRb  |  XRa  |MXU__POOL03|
25893 *  +-----------+---+---+-------+-------+-------+-------+-----------+
25894 *
25895 *  D16MULE:
25896 *   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
25897 *  +-----------+---+---+-------+-------+-------+-------+-----------+
25898 *  |  SPECIAL2 |x x|on2|   Xd  |  XRc  |  XRb  |  XRa  |MXU__POOL03|
25899 *  +-----------+---+---+-------+-------+-------+-------+-----------+
25900 *
25901 */
25902static void decode_opc_mxu__pool03(CPUMIPSState *env, DisasContext *ctx)
25903{
25904    uint32_t opcode = extract32(ctx->opcode, 24, 2);
25905
25906    switch (opcode) {
25907    case OPC_MXU_D16MULF:
25908        /* TODO: Implement emulation of D16MULF instruction. */
25909        MIPS_INVAL("OPC_MXU_D16MULF");
25910        generate_exception_end(ctx, EXCP_RI);
25911        break;
25912    case OPC_MXU_D16MULE:
25913        /* TODO: Implement emulation of D16MULE instruction. */
25914        MIPS_INVAL("OPC_MXU_D16MULE");
25915        generate_exception_end(ctx, EXCP_RI);
25916        break;
25917    default:
25918        MIPS_INVAL("decode_opc_mxu");
25919        generate_exception_end(ctx, EXCP_RI);
25920        break;
25921    }
25922}
25923
25924/*
25925 *
25926 * Decode MXU pool04
25927 *
25928 *   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
25929 *  +-----------+---------+-+-------------------+-------+-----------+
25930 *  |  SPECIAL2 |    rb   |x|        s12        |  XRa  |MXU__POOL04|
25931 *  +-----------+---------+-+-------------------+-------+-----------+
25932 *
25933 */
25934static void decode_opc_mxu__pool04(CPUMIPSState *env, DisasContext *ctx)
25935{
25936    uint32_t opcode = extract32(ctx->opcode, 20, 1);
25937
25938    switch (opcode) {
25939    case OPC_MXU_S32LDD:
25940    case OPC_MXU_S32LDDR:
25941        gen_mxu_s32ldd_s32lddr(ctx);
25942        break;
25943    default:
25944        MIPS_INVAL("decode_opc_mxu");
25945        generate_exception_end(ctx, EXCP_RI);
25946        break;
25947    }
25948}
25949
25950/*
25951 *
25952 * Decode MXU pool05
25953 *
25954 *   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
25955 *  +-----------+---------+-+-------------------+-------+-----------+
25956 *  |  SPECIAL2 |    rb   |x|        s12        |  XRa  |MXU__POOL05|
25957 *  +-----------+---------+-+-------------------+-------+-----------+
25958 *
25959 */
25960static void decode_opc_mxu__pool05(CPUMIPSState *env, DisasContext *ctx)
25961{
25962    uint32_t opcode = extract32(ctx->opcode, 20, 1);
25963
25964    switch (opcode) {
25965    case OPC_MXU_S32STD:
25966        /* TODO: Implement emulation of S32STD instruction. */
25967        MIPS_INVAL("OPC_MXU_S32STD");
25968        generate_exception_end(ctx, EXCP_RI);
25969        break;
25970    case OPC_MXU_S32STDR:
25971        /* TODO: Implement emulation of S32STDR instruction. */
25972        MIPS_INVAL("OPC_MXU_S32STDR");
25973        generate_exception_end(ctx, EXCP_RI);
25974        break;
25975    default:
25976        MIPS_INVAL("decode_opc_mxu");
25977        generate_exception_end(ctx, EXCP_RI);
25978        break;
25979    }
25980}
25981
25982/*
25983 *
25984 * Decode MXU pool06
25985 *
25986 *   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
25987 *  +-----------+---------+---------+---+-------+-------+-----------+
25988 *  |  SPECIAL2 |    rb   |    rc   |st2|x x x x|  XRa  |MXU__POOL06|
25989 *  +-----------+---------+---------+---+-------+-------+-----------+
25990 *
25991 */
25992static void decode_opc_mxu__pool06(CPUMIPSState *env, DisasContext *ctx)
25993{
25994    uint32_t opcode = extract32(ctx->opcode, 10, 4);
25995
25996    switch (opcode) {
25997    case OPC_MXU_S32LDDV:
25998        /* TODO: Implement emulation of S32LDDV instruction. */
25999        MIPS_INVAL("OPC_MXU_S32LDDV");
26000        generate_exception_end(ctx, EXCP_RI);
26001        break;
26002    case OPC_MXU_S32LDDVR:
26003        /* TODO: Implement emulation of S32LDDVR instruction. */
26004        MIPS_INVAL("OPC_MXU_S32LDDVR");
26005        generate_exception_end(ctx, EXCP_RI);
26006        break;
26007    default:
26008        MIPS_INVAL("decode_opc_mxu");
26009        generate_exception_end(ctx, EXCP_RI);
26010        break;
26011    }
26012}
26013
26014/*
26015 *
26016 * Decode MXU pool07
26017 *
26018 *   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
26019 *  +-----------+---------+---------+---+-------+-------+-----------+
26020 *  |  SPECIAL2 |    rb   |    rc   |st2|x x x x|  XRa  |MXU__POOL07|
26021 *  +-----------+---------+---------+---+-------+-------+-----------+
26022 *
26023 */
26024static void decode_opc_mxu__pool07(CPUMIPSState *env, DisasContext *ctx)
26025{
26026    uint32_t opcode = extract32(ctx->opcode, 10, 4);
26027
26028    switch (opcode) {
26029    case OPC_MXU_S32STDV:
26030        /* TODO: Implement emulation of S32TDV instruction. */
26031        MIPS_INVAL("OPC_MXU_S32TDV");
26032        generate_exception_end(ctx, EXCP_RI);
26033        break;
26034    case OPC_MXU_S32STDVR:
26035        /* TODO: Implement emulation of S32TDVR instruction. */
26036        MIPS_INVAL("OPC_MXU_S32TDVR");
26037        generate_exception_end(ctx, EXCP_RI);
26038        break;
26039    default:
26040        MIPS_INVAL("decode_opc_mxu");
26041        generate_exception_end(ctx, EXCP_RI);
26042        break;
26043    }
26044}
26045
26046/*
26047 *
26048 * Decode MXU pool08
26049 *
26050 *   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
26051 *  +-----------+---------+-+-------------------+-------+-----------+
26052 *  |  SPECIAL2 |    rb   |x|        s12        |  XRa  |MXU__POOL08|
26053 *  +-----------+---------+-+-------------------+-------+-----------+
26054 *
26055 */
26056static void decode_opc_mxu__pool08(CPUMIPSState *env, DisasContext *ctx)
26057{
26058    uint32_t opcode = extract32(ctx->opcode, 20, 1);
26059
26060    switch (opcode) {
26061    case OPC_MXU_S32LDI:
26062        /* TODO: Implement emulation of S32LDI instruction. */
26063        MIPS_INVAL("OPC_MXU_S32LDI");
26064        generate_exception_end(ctx, EXCP_RI);
26065        break;
26066    case OPC_MXU_S32LDIR:
26067        /* TODO: Implement emulation of S32LDIR instruction. */
26068        MIPS_INVAL("OPC_MXU_S32LDIR");
26069        generate_exception_end(ctx, EXCP_RI);
26070        break;
26071    default:
26072        MIPS_INVAL("decode_opc_mxu");
26073        generate_exception_end(ctx, EXCP_RI);
26074        break;
26075    }
26076}
26077
26078/*
26079 *
26080 * Decode MXU pool09
26081 *
26082 *   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
26083 *  +-----------+---------+-+-------------------+-------+-----------+
26084 *  |  SPECIAL2 |    rb   |x|        s12        |  XRa  |MXU__POOL09|
26085 *  +-----------+---------+-+-------------------+-------+-----------+
26086 *
26087 */
26088static void decode_opc_mxu__pool09(CPUMIPSState *env, DisasContext *ctx)
26089{
26090    uint32_t opcode = extract32(ctx->opcode, 5, 0);
26091
26092    switch (opcode) {
26093    case OPC_MXU_S32SDI:
26094        /* TODO: Implement emulation of S32SDI instruction. */
26095        MIPS_INVAL("OPC_MXU_S32SDI");
26096        generate_exception_end(ctx, EXCP_RI);
26097        break;
26098    case OPC_MXU_S32SDIR:
26099        /* TODO: Implement emulation of S32SDIR instruction. */
26100        MIPS_INVAL("OPC_MXU_S32SDIR");
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 pool10
26113 *
26114 *   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
26115 *  +-----------+---------+---------+---+-------+-------+-----------+
26116 *  |  SPECIAL2 |    rb   |    rc   |st2|x x x x|  XRa  |MXU__POOL10|
26117 *  +-----------+---------+---------+---+-------+-------+-----------+
26118 *
26119 */
26120static void decode_opc_mxu__pool10(CPUMIPSState *env, DisasContext *ctx)
26121{
26122    uint32_t opcode = extract32(ctx->opcode, 5, 0);
26123
26124    switch (opcode) {
26125    case OPC_MXU_S32LDIV:
26126        /* TODO: Implement emulation of S32LDIV instruction. */
26127        MIPS_INVAL("OPC_MXU_S32LDIV");
26128        generate_exception_end(ctx, EXCP_RI);
26129        break;
26130    case OPC_MXU_S32LDIVR:
26131        /* TODO: Implement emulation of S32LDIVR instruction. */
26132        MIPS_INVAL("OPC_MXU_S32LDIVR");
26133        generate_exception_end(ctx, EXCP_RI);
26134        break;
26135    default:
26136        MIPS_INVAL("decode_opc_mxu");
26137        generate_exception_end(ctx, EXCP_RI);
26138        break;
26139    }
26140}
26141
26142/*
26143 *
26144 * Decode MXU pool11
26145 *
26146 *   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
26147 *  +-----------+---------+---------+---+-------+-------+-----------+
26148 *  |  SPECIAL2 |    rb   |    rc   |st2|x x x x|  XRa  |MXU__POOL11|
26149 *  +-----------+---------+---------+---+-------+-------+-----------+
26150 *
26151 */
26152static void decode_opc_mxu__pool11(CPUMIPSState *env, DisasContext *ctx)
26153{
26154    uint32_t opcode = extract32(ctx->opcode, 10, 4);
26155
26156    switch (opcode) {
26157    case OPC_MXU_S32SDIV:
26158        /* TODO: Implement emulation of S32SDIV instruction. */
26159        MIPS_INVAL("OPC_MXU_S32SDIV");
26160        generate_exception_end(ctx, EXCP_RI);
26161        break;
26162    case OPC_MXU_S32SDIVR:
26163        /* TODO: Implement emulation of S32SDIVR instruction. */
26164        MIPS_INVAL("OPC_MXU_S32SDIVR");
26165        generate_exception_end(ctx, EXCP_RI);
26166        break;
26167    default:
26168        MIPS_INVAL("decode_opc_mxu");
26169        generate_exception_end(ctx, EXCP_RI);
26170        break;
26171    }
26172}
26173
26174/*
26175 *
26176 * Decode MXU pool12
26177 *
26178 *   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
26179 *  +-----------+---+---+-------+-------+-------+-------+-----------+
26180 *  |  SPECIAL2 |an2|x x|   Xd  |  XRc  |  XRb  |  XRa  |MXU__POOL12|
26181 *  +-----------+---+---+-------+-------+-------+-------+-----------+
26182 *
26183 */
26184static void decode_opc_mxu__pool12(CPUMIPSState *env, DisasContext *ctx)
26185{
26186    uint32_t opcode = extract32(ctx->opcode, 22, 2);
26187
26188    switch (opcode) {
26189    case OPC_MXU_D32ACC:
26190        /* TODO: Implement emulation of D32ACC instruction. */
26191        MIPS_INVAL("OPC_MXU_D32ACC");
26192        generate_exception_end(ctx, EXCP_RI);
26193        break;
26194    case OPC_MXU_D32ACCM:
26195        /* TODO: Implement emulation of D32ACCM instruction. */
26196        MIPS_INVAL("OPC_MXU_D32ACCM");
26197        generate_exception_end(ctx, EXCP_RI);
26198        break;
26199    case OPC_MXU_D32ASUM:
26200        /* TODO: Implement emulation of D32ASUM instruction. */
26201        MIPS_INVAL("OPC_MXU_D32ASUM");
26202        generate_exception_end(ctx, EXCP_RI);
26203        break;
26204    default:
26205        MIPS_INVAL("decode_opc_mxu");
26206        generate_exception_end(ctx, EXCP_RI);
26207        break;
26208    }
26209}
26210
26211/*
26212 *
26213 * Decode MXU pool13
26214 *
26215 *   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
26216 *  +-----------+---+---+-------+-------+-------+-------+-----------+
26217 *  |  SPECIAL2 |en2|x x|0 0 0 0|  XRc  |  XRb  |  XRa  |MXU__POOL13|
26218 *  +-----------+---+---+-------+-------+-------+-------+-----------+
26219 *
26220 */
26221static void decode_opc_mxu__pool13(CPUMIPSState *env, DisasContext *ctx)
26222{
26223    uint32_t opcode = extract32(ctx->opcode, 22, 2);
26224
26225    switch (opcode) {
26226    case OPC_MXU_Q16ACC:
26227        /* TODO: Implement emulation of Q16ACC instruction. */
26228        MIPS_INVAL("OPC_MXU_Q16ACC");
26229        generate_exception_end(ctx, EXCP_RI);
26230        break;
26231    case OPC_MXU_Q16ACCM:
26232        /* TODO: Implement emulation of Q16ACCM instruction. */
26233        MIPS_INVAL("OPC_MXU_Q16ACCM");
26234        generate_exception_end(ctx, EXCP_RI);
26235        break;
26236    case OPC_MXU_Q16ASUM:
26237        /* TODO: Implement emulation of Q16ASUM instruction. */
26238        MIPS_INVAL("OPC_MXU_Q16ASUM");
26239        generate_exception_end(ctx, EXCP_RI);
26240        break;
26241    default:
26242        MIPS_INVAL("decode_opc_mxu");
26243        generate_exception_end(ctx, EXCP_RI);
26244        break;
26245    }
26246}
26247
26248/*
26249 *
26250 * Decode MXU pool14
26251 *
26252 *  Q8ADDE, Q8ACCE:
26253 *   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
26254 *  +-----------+---+---+-------+-------+-------+-------+-----------+
26255 *  |  SPECIAL2 |0 0|x x|  XRd  |  XRc  |  XRb  |  XRa  |MXU__POOL14|
26256 *  +-----------+---+---+-------+-------+-------+-------+-----------+
26257 *
26258 *  D8SUM, D8SUMC:
26259 *   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
26260 *  +-----------+---+---+-------+-------+-------+-------+-----------+
26261 *  |  SPECIAL2 |en2|x x|0 0 0 0|  XRc  |  XRb  |  XRa  |MXU__POOL14|
26262 *  +-----------+---+---+-------+-------+-------+-------+-----------+
26263 *
26264 */
26265static void decode_opc_mxu__pool14(CPUMIPSState *env, DisasContext *ctx)
26266{
26267    uint32_t opcode = extract32(ctx->opcode, 22, 2);
26268
26269    switch (opcode) {
26270    case OPC_MXU_Q8ADDE:
26271        /* TODO: Implement emulation of Q8ADDE instruction. */
26272        MIPS_INVAL("OPC_MXU_Q8ADDE");
26273        generate_exception_end(ctx, EXCP_RI);
26274        break;
26275    case OPC_MXU_D8SUM:
26276        /* TODO: Implement emulation of D8SUM instruction. */
26277        MIPS_INVAL("OPC_MXU_D8SUM");
26278        generate_exception_end(ctx, EXCP_RI);
26279        break;
26280    case OPC_MXU_D8SUMC:
26281        /* TODO: Implement emulation of D8SUMC instruction. */
26282        MIPS_INVAL("OPC_MXU_D8SUMC");
26283        generate_exception_end(ctx, EXCP_RI);
26284        break;
26285    default:
26286        MIPS_INVAL("decode_opc_mxu");
26287        generate_exception_end(ctx, EXCP_RI);
26288        break;
26289    }
26290}
26291
26292/*
26293 *
26294 * Decode MXU pool15
26295 *
26296 *  S32MUL, S32MULU, S32EXTRV:
26297 *   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
26298 *  +-----------+---------+---------+---+-------+-------+-----------+
26299 *  |  SPECIAL2 |    rs   |    rt   |x x|  XRd  |  XRa  |MXU__POOL15|
26300 *  +-----------+---------+---------+---+-------+-------+-----------+
26301 *
26302 *  S32EXTR:
26303 *   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
26304 *  +-----------+---------+---------+---+-------+-------+-----------+
26305 *  |  SPECIAL2 |    rb   |   sft5  |x x|  XRd  |  XRa  |MXU__POOL15|
26306 *  +-----------+---------+---------+---+-------+-------+-----------+
26307 *
26308 */
26309static void decode_opc_mxu__pool15(CPUMIPSState *env, DisasContext *ctx)
26310{
26311    uint32_t opcode = extract32(ctx->opcode, 14, 2);
26312
26313    switch (opcode) {
26314    case OPC_MXU_S32MUL:
26315        /* TODO: Implement emulation of S32MUL instruction. */
26316        MIPS_INVAL("OPC_MXU_S32MUL");
26317        generate_exception_end(ctx, EXCP_RI);
26318        break;
26319    case OPC_MXU_S32MULU:
26320        /* TODO: Implement emulation of S32MULU instruction. */
26321        MIPS_INVAL("OPC_MXU_S32MULU");
26322        generate_exception_end(ctx, EXCP_RI);
26323        break;
26324    case OPC_MXU_S32EXTR:
26325        /* TODO: Implement emulation of S32EXTR instruction. */
26326        MIPS_INVAL("OPC_MXU_S32EXTR");
26327        generate_exception_end(ctx, EXCP_RI);
26328        break;
26329    case OPC_MXU_S32EXTRV:
26330        /* TODO: Implement emulation of S32EXTRV instruction. */
26331        MIPS_INVAL("OPC_MXU_S32EXTRV");
26332        generate_exception_end(ctx, EXCP_RI);
26333        break;
26334    default:
26335        MIPS_INVAL("decode_opc_mxu");
26336        generate_exception_end(ctx, EXCP_RI);
26337        break;
26338    }
26339}
26340
26341/*
26342 *
26343 * Decode MXU pool16
26344 *
26345 *  D32SARW:
26346 *   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
26347 *  +-----------+---------+-----+-------+-------+-------+-----------+
26348 *  |  SPECIAL2 |    rb   |x x x|  XRc  |  XRb  |  XRa  |MXU__POOL16|
26349 *  +-----------+---------+-----+-------+-------+-------+-----------+
26350 *
26351 *  S32ALN:
26352 *   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
26353 *  +-----------+---------+-----+-------+-------+-------+-----------+
26354 *  |  SPECIAL2 |    rs   |x x x|  XRc  |  XRb  |  XRa  |MXU__POOL16|
26355 *  +-----------+---------+-----+-------+-------+-------+-----------+
26356 *
26357 *  S32ALNI:
26358 *   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
26359 *  +-----------+-----+---+-----+-------+-------+-------+-----------+
26360 *  |  SPECIAL2 |  s3 |0 0|x x x|  XRc  |  XRb  |  XRa  |MXU__POOL16|
26361 *  +-----------+-----+---+-----+-------+-------+-------+-----------+
26362 *
26363 *  S32LUI:
26364 *   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
26365 *  +-----------+-----+---+-----+-------+---------------+-----------+
26366 *  |  SPECIAL2 |optn3|0 0|x x x|  XRc  |       s8      |MXU__POOL16|
26367 *  +-----------+-----+---+-----+-------+---------------+-----------+
26368 *
26369 *  S32NOR, S32AND, S32OR, S32XOR:
26370 *   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
26371 *  +-----------+---------+-----+-------+-------+-------+-----------+
26372 *  |  SPECIAL2 |0 0 0 0 0|x x x|  XRc  |  XRb  |  XRa  |MXU__POOL16|
26373 *  +-----------+---------+-----+-------+-------+-------+-----------+
26374 *
26375 */
26376static void decode_opc_mxu__pool16(CPUMIPSState *env, DisasContext *ctx)
26377{
26378    uint32_t opcode = extract32(ctx->opcode, 18, 3);
26379
26380    switch (opcode) {
26381    case OPC_MXU_D32SARW:
26382        /* TODO: Implement emulation of D32SARW instruction. */
26383        MIPS_INVAL("OPC_MXU_D32SARW");
26384        generate_exception_end(ctx, EXCP_RI);
26385        break;
26386    case OPC_MXU_S32ALN:
26387        /* TODO: Implement emulation of S32ALN instruction. */
26388        MIPS_INVAL("OPC_MXU_S32ALN");
26389        generate_exception_end(ctx, EXCP_RI);
26390        break;
26391    case OPC_MXU_S32ALNI:
26392        gen_mxu_S32ALNI(ctx);
26393        break;
26394    case OPC_MXU_S32LUI:
26395        /* TODO: Implement emulation of S32LUI instruction. */
26396        MIPS_INVAL("OPC_MXU_S32LUI");
26397        generate_exception_end(ctx, EXCP_RI);
26398        break;
26399    case OPC_MXU_S32NOR:
26400        gen_mxu_S32NOR(ctx);
26401        break;
26402    case OPC_MXU_S32AND:
26403        gen_mxu_S32AND(ctx);
26404        break;
26405    case OPC_MXU_S32OR:
26406        gen_mxu_S32OR(ctx);
26407        break;
26408    case OPC_MXU_S32XOR:
26409        gen_mxu_S32XOR(ctx);
26410        break;
26411    default:
26412        MIPS_INVAL("decode_opc_mxu");
26413        generate_exception_end(ctx, EXCP_RI);
26414        break;
26415    }
26416}
26417
26418/*
26419 *
26420 * Decode MXU pool17
26421 *
26422 *   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
26423 *  +-----------+---------+---------+---+---------+-----+-----------+
26424 *  |  SPECIAL2 |    rs   |    rt   |0 0|    rd   |x x x|MXU__POOL15|
26425 *  +-----------+---------+---------+---+---------+-----+-----------+
26426 *
26427 */
26428static void decode_opc_mxu__pool17(CPUMIPSState *env, DisasContext *ctx)
26429{
26430    uint32_t opcode = extract32(ctx->opcode, 6, 2);
26431
26432    switch (opcode) {
26433    case OPC_MXU_LXW:
26434        /* TODO: Implement emulation of LXW instruction. */
26435        MIPS_INVAL("OPC_MXU_LXW");
26436        generate_exception_end(ctx, EXCP_RI);
26437        break;
26438    case OPC_MXU_LXH:
26439        /* TODO: Implement emulation of LXH instruction. */
26440        MIPS_INVAL("OPC_MXU_LXH");
26441        generate_exception_end(ctx, EXCP_RI);
26442        break;
26443    case OPC_MXU_LXHU:
26444        /* TODO: Implement emulation of LXHU instruction. */
26445        MIPS_INVAL("OPC_MXU_LXHU");
26446        generate_exception_end(ctx, EXCP_RI);
26447        break;
26448    case OPC_MXU_LXB:
26449        /* TODO: Implement emulation of LXB instruction. */
26450        MIPS_INVAL("OPC_MXU_LXB");
26451        generate_exception_end(ctx, EXCP_RI);
26452        break;
26453    case OPC_MXU_LXBU:
26454        /* TODO: Implement emulation of LXBU instruction. */
26455        MIPS_INVAL("OPC_MXU_LXBU");
26456        generate_exception_end(ctx, EXCP_RI);
26457        break;
26458    default:
26459        MIPS_INVAL("decode_opc_mxu");
26460        generate_exception_end(ctx, EXCP_RI);
26461        break;
26462    }
26463}
26464/*
26465 *
26466 * Decode MXU pool18
26467 *
26468 *   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
26469 *  +-----------+---------+-----+-------+-------+-------+-----------+
26470 *  |  SPECIAL2 |    rb   |x x x|  XRd  |  XRa  |0 0 0 0|MXU__POOL18|
26471 *  +-----------+---------+-----+-------+-------+-------+-----------+
26472 *
26473 */
26474static void decode_opc_mxu__pool18(CPUMIPSState *env, DisasContext *ctx)
26475{
26476    uint32_t opcode = extract32(ctx->opcode, 18, 3);
26477
26478    switch (opcode) {
26479    case OPC_MXU_D32SLLV:
26480        /* TODO: Implement emulation of D32SLLV instruction. */
26481        MIPS_INVAL("OPC_MXU_D32SLLV");
26482        generate_exception_end(ctx, EXCP_RI);
26483        break;
26484    case OPC_MXU_D32SLRV:
26485        /* TODO: Implement emulation of D32SLRV instruction. */
26486        MIPS_INVAL("OPC_MXU_D32SLRV");
26487        generate_exception_end(ctx, EXCP_RI);
26488        break;
26489    case OPC_MXU_D32SARV:
26490        /* TODO: Implement emulation of D32SARV instruction. */
26491        MIPS_INVAL("OPC_MXU_D32SARV");
26492        generate_exception_end(ctx, EXCP_RI);
26493        break;
26494    case OPC_MXU_Q16SLLV:
26495        /* TODO: Implement emulation of Q16SLLV instruction. */
26496        MIPS_INVAL("OPC_MXU_Q16SLLV");
26497        generate_exception_end(ctx, EXCP_RI);
26498        break;
26499    case OPC_MXU_Q16SLRV:
26500        /* TODO: Implement emulation of Q16SLRV instruction. */
26501        MIPS_INVAL("OPC_MXU_Q16SLRV");
26502        generate_exception_end(ctx, EXCP_RI);
26503        break;
26504    case OPC_MXU_Q16SARV:
26505        /* TODO: Implement emulation of Q16SARV instruction. */
26506        MIPS_INVAL("OPC_MXU_Q16SARV");
26507        generate_exception_end(ctx, EXCP_RI);
26508        break;
26509    default:
26510        MIPS_INVAL("decode_opc_mxu");
26511        generate_exception_end(ctx, EXCP_RI);
26512        break;
26513    }
26514}
26515
26516/*
26517 *
26518 * Decode MXU pool19
26519 *
26520 *   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
26521 *  +-----------+---+---+-------+-------+-------+-------+-----------+
26522 *  |  SPECIAL2 |0 0|x x|  XRd  |  XRc  |  XRb  |  XRa  |MXU__POOL19|
26523 *  +-----------+---+---+-------+-------+-------+-------+-----------+
26524 *
26525 */
26526static void decode_opc_mxu__pool19(CPUMIPSState *env, DisasContext *ctx)
26527{
26528    uint32_t opcode = extract32(ctx->opcode, 22, 2);
26529
26530    switch (opcode) {
26531    case OPC_MXU_Q8MUL:
26532    case OPC_MXU_Q8MULSU:
26533        gen_mxu_q8mul_q8mulsu(ctx);
26534        break;
26535    default:
26536        MIPS_INVAL("decode_opc_mxu");
26537        generate_exception_end(ctx, EXCP_RI);
26538        break;
26539    }
26540}
26541
26542/*
26543 *
26544 * Decode MXU pool20
26545 *
26546 *   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
26547 *  +-----------+---------+-----+-------+-------+-------+-----------+
26548 *  |  SPECIAL2 |0 0 0 0 0|x x x|  XRc  |  XRb  |  XRa  |MXU__POOL20|
26549 *  +-----------+---------+-----+-------+-------+-------+-----------+
26550 *
26551 */
26552static void decode_opc_mxu__pool20(CPUMIPSState *env, DisasContext *ctx)
26553{
26554    uint32_t opcode = extract32(ctx->opcode, 18, 3);
26555
26556    switch (opcode) {
26557    case OPC_MXU_Q8MOVZ:
26558        /* TODO: Implement emulation of Q8MOVZ instruction. */
26559        MIPS_INVAL("OPC_MXU_Q8MOVZ");
26560        generate_exception_end(ctx, EXCP_RI);
26561        break;
26562    case OPC_MXU_Q8MOVN:
26563        /* TODO: Implement emulation of Q8MOVN instruction. */
26564        MIPS_INVAL("OPC_MXU_Q8MOVN");
26565        generate_exception_end(ctx, EXCP_RI);
26566        break;
26567    case OPC_MXU_D16MOVZ:
26568        /* TODO: Implement emulation of D16MOVZ instruction. */
26569        MIPS_INVAL("OPC_MXU_D16MOVZ");
26570        generate_exception_end(ctx, EXCP_RI);
26571        break;
26572    case OPC_MXU_D16MOVN:
26573        /* TODO: Implement emulation of D16MOVN instruction. */
26574        MIPS_INVAL("OPC_MXU_D16MOVN");
26575        generate_exception_end(ctx, EXCP_RI);
26576        break;
26577    case OPC_MXU_S32MOVZ:
26578        /* TODO: Implement emulation of S32MOVZ instruction. */
26579        MIPS_INVAL("OPC_MXU_S32MOVZ");
26580        generate_exception_end(ctx, EXCP_RI);
26581        break;
26582    case OPC_MXU_S32MOVN:
26583        /* TODO: Implement emulation of S32MOVN instruction. */
26584        MIPS_INVAL("OPC_MXU_S32MOVN");
26585        generate_exception_end(ctx, EXCP_RI);
26586        break;
26587    default:
26588        MIPS_INVAL("decode_opc_mxu");
26589        generate_exception_end(ctx, EXCP_RI);
26590        break;
26591    }
26592}
26593
26594/*
26595 *
26596 * Decode MXU pool21
26597 *
26598 *   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
26599 *  +-----------+---+---+-------+-------+-------+-------+-----------+
26600 *  |  SPECIAL2 |an2|x x|  XRd  |  XRc  |  XRb  |  XRa  |MXU__POOL21|
26601 *  +-----------+---+---+-------+-------+-------+-------+-----------+
26602 *
26603 */
26604static void decode_opc_mxu__pool21(CPUMIPSState *env, DisasContext *ctx)
26605{
26606    uint32_t opcode = extract32(ctx->opcode, 22, 2);
26607
26608    switch (opcode) {
26609    case OPC_MXU_Q8MAC:
26610        /* TODO: Implement emulation of Q8MAC instruction. */
26611        MIPS_INVAL("OPC_MXU_Q8MAC");
26612        generate_exception_end(ctx, EXCP_RI);
26613        break;
26614    case OPC_MXU_Q8MACSU:
26615        /* TODO: Implement emulation of Q8MACSU instruction. */
26616        MIPS_INVAL("OPC_MXU_Q8MACSU");
26617        generate_exception_end(ctx, EXCP_RI);
26618        break;
26619    default:
26620        MIPS_INVAL("decode_opc_mxu");
26621        generate_exception_end(ctx, EXCP_RI);
26622        break;
26623    }
26624}
26625
26626
26627/*
26628 * Main MXU decoding function
26629 *
26630 *   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
26631 *  +-----------+---------------------------------------+-----------+
26632 *  |  SPECIAL2 |                                       |x x x x x x|
26633 *  +-----------+---------------------------------------+-----------+
26634 *
26635 */
26636static void decode_opc_mxu(CPUMIPSState *env, DisasContext *ctx)
26637{
26638    /*
26639     * TODO: Investigate necessity of including handling of
26640     * CLZ, CLO, SDBB in this function, as they belong to
26641     * SPECIAL2 opcode space for regular pre-R6 MIPS ISAs.
26642     */
26643    uint32_t opcode = extract32(ctx->opcode, 0, 6);
26644
26645    if (opcode == OPC__MXU_MUL) {
26646        uint32_t  rs, rt, rd, op1;
26647
26648        rs = extract32(ctx->opcode, 21, 5);
26649        rt = extract32(ctx->opcode, 16, 5);
26650        rd = extract32(ctx->opcode, 11, 5);
26651        op1 = MASK_SPECIAL2(ctx->opcode);
26652
26653        gen_arith(ctx, op1, rd, rs, rt);
26654
26655        return;
26656    }
26657
26658    if (opcode == OPC_MXU_S32M2I) {
26659        gen_mxu_s32m2i(ctx);
26660        return;
26661    }
26662
26663    if (opcode == OPC_MXU_S32I2M) {
26664        gen_mxu_s32i2m(ctx);
26665        return;
26666    }
26667
26668    {
26669        TCGv t_mxu_cr = tcg_temp_new();
26670        TCGLabel *l_exit = gen_new_label();
26671
26672        gen_load_mxu_cr(t_mxu_cr);
26673        tcg_gen_andi_tl(t_mxu_cr, t_mxu_cr, MXU_CR_MXU_EN);
26674        tcg_gen_brcondi_tl(TCG_COND_NE, t_mxu_cr, MXU_CR_MXU_EN, l_exit);
26675
26676        switch (opcode) {
26677        case OPC_MXU_S32MADD:
26678            /* TODO: Implement emulation of S32MADD instruction. */
26679            MIPS_INVAL("OPC_MXU_S32MADD");
26680            generate_exception_end(ctx, EXCP_RI);
26681            break;
26682        case OPC_MXU_S32MADDU:
26683            /* TODO: Implement emulation of S32MADDU instruction. */
26684            MIPS_INVAL("OPC_MXU_S32MADDU");
26685            generate_exception_end(ctx, EXCP_RI);
26686            break;
26687        case OPC_MXU__POOL00:
26688            decode_opc_mxu__pool00(env, ctx);
26689            break;
26690        case OPC_MXU_S32MSUB:
26691            /* TODO: Implement emulation of S32MSUB instruction. */
26692            MIPS_INVAL("OPC_MXU_S32MSUB");
26693            generate_exception_end(ctx, EXCP_RI);
26694            break;
26695        case OPC_MXU_S32MSUBU:
26696            /* TODO: Implement emulation of S32MSUBU instruction. */
26697            MIPS_INVAL("OPC_MXU_S32MSUBU");
26698            generate_exception_end(ctx, EXCP_RI);
26699            break;
26700        case OPC_MXU__POOL01:
26701            decode_opc_mxu__pool01(env, ctx);
26702            break;
26703        case OPC_MXU__POOL02:
26704            decode_opc_mxu__pool02(env, ctx);
26705            break;
26706        case OPC_MXU_D16MUL:
26707            gen_mxu_d16mul(ctx);
26708            break;
26709        case OPC_MXU__POOL03:
26710            decode_opc_mxu__pool03(env, ctx);
26711            break;
26712        case OPC_MXU_D16MAC:
26713            gen_mxu_d16mac(ctx);
26714            break;
26715        case OPC_MXU_D16MACF:
26716            /* TODO: Implement emulation of D16MACF instruction. */
26717            MIPS_INVAL("OPC_MXU_D16MACF");
26718            generate_exception_end(ctx, EXCP_RI);
26719            break;
26720        case OPC_MXU_D16MADL:
26721            /* TODO: Implement emulation of D16MADL instruction. */
26722            MIPS_INVAL("OPC_MXU_D16MADL");
26723            generate_exception_end(ctx, EXCP_RI);
26724            break;
26725        case OPC_MXU_S16MAD:
26726            /* TODO: Implement emulation of S16MAD instruction. */
26727            MIPS_INVAL("OPC_MXU_S16MAD");
26728            generate_exception_end(ctx, EXCP_RI);
26729            break;
26730        case OPC_MXU_Q16ADD:
26731            /* TODO: Implement emulation of Q16ADD instruction. */
26732            MIPS_INVAL("OPC_MXU_Q16ADD");
26733            generate_exception_end(ctx, EXCP_RI);
26734            break;
26735        case OPC_MXU_D16MACE:
26736            /* TODO: Implement emulation of D16MACE instruction. */
26737            MIPS_INVAL("OPC_MXU_D16MACE");
26738            generate_exception_end(ctx, EXCP_RI);
26739            break;
26740        case OPC_MXU__POOL04:
26741            decode_opc_mxu__pool04(env, ctx);
26742            break;
26743        case OPC_MXU__POOL05:
26744            decode_opc_mxu__pool05(env, ctx);
26745            break;
26746        case OPC_MXU__POOL06:
26747            decode_opc_mxu__pool06(env, ctx);
26748            break;
26749        case OPC_MXU__POOL07:
26750            decode_opc_mxu__pool07(env, ctx);
26751            break;
26752        case OPC_MXU__POOL08:
26753            decode_opc_mxu__pool08(env, ctx);
26754            break;
26755        case OPC_MXU__POOL09:
26756            decode_opc_mxu__pool09(env, ctx);
26757            break;
26758        case OPC_MXU__POOL10:
26759            decode_opc_mxu__pool10(env, ctx);
26760            break;
26761        case OPC_MXU__POOL11:
26762            decode_opc_mxu__pool11(env, ctx);
26763            break;
26764        case OPC_MXU_D32ADD:
26765            /* TODO: Implement emulation of D32ADD instruction. */
26766            MIPS_INVAL("OPC_MXU_D32ADD");
26767            generate_exception_end(ctx, EXCP_RI);
26768            break;
26769        case OPC_MXU__POOL12:
26770            decode_opc_mxu__pool12(env, ctx);
26771            break;
26772        case OPC_MXU__POOL13:
26773            decode_opc_mxu__pool13(env, ctx);
26774            break;
26775        case OPC_MXU__POOL14:
26776            decode_opc_mxu__pool14(env, ctx);
26777            break;
26778        case OPC_MXU_Q8ACCE:
26779            /* TODO: Implement emulation of Q8ACCE instruction. */
26780            MIPS_INVAL("OPC_MXU_Q8ACCE");
26781            generate_exception_end(ctx, EXCP_RI);
26782            break;
26783        case OPC_MXU_S8LDD:
26784            gen_mxu_s8ldd(ctx);
26785            break;
26786        case OPC_MXU_S8STD:
26787            /* TODO: Implement emulation of S8STD instruction. */
26788            MIPS_INVAL("OPC_MXU_S8STD");
26789            generate_exception_end(ctx, EXCP_RI);
26790            break;
26791        case OPC_MXU_S8LDI:
26792            /* TODO: Implement emulation of S8LDI instruction. */
26793            MIPS_INVAL("OPC_MXU_S8LDI");
26794            generate_exception_end(ctx, EXCP_RI);
26795            break;
26796        case OPC_MXU_S8SDI:
26797            /* TODO: Implement emulation of S8SDI instruction. */
26798            MIPS_INVAL("OPC_MXU_S8SDI");
26799            generate_exception_end(ctx, EXCP_RI);
26800            break;
26801        case OPC_MXU__POOL15:
26802            decode_opc_mxu__pool15(env, ctx);
26803            break;
26804        case OPC_MXU__POOL16:
26805            decode_opc_mxu__pool16(env, ctx);
26806            break;
26807        case OPC_MXU__POOL17:
26808            decode_opc_mxu__pool17(env, ctx);
26809            break;
26810        case OPC_MXU_S16LDD:
26811            /* TODO: Implement emulation of S16LDD instruction. */
26812            MIPS_INVAL("OPC_MXU_S16LDD");
26813            generate_exception_end(ctx, EXCP_RI);
26814            break;
26815        case OPC_MXU_S16STD:
26816            /* TODO: Implement emulation of S16STD instruction. */
26817            MIPS_INVAL("OPC_MXU_S16STD");
26818            generate_exception_end(ctx, EXCP_RI);
26819            break;
26820        case OPC_MXU_S16LDI:
26821            /* TODO: Implement emulation of S16LDI instruction. */
26822            MIPS_INVAL("OPC_MXU_S16LDI");
26823            generate_exception_end(ctx, EXCP_RI);
26824            break;
26825        case OPC_MXU_S16SDI:
26826            /* TODO: Implement emulation of S16SDI instruction. */
26827            MIPS_INVAL("OPC_MXU_S16SDI");
26828            generate_exception_end(ctx, EXCP_RI);
26829            break;
26830        case OPC_MXU_D32SLL:
26831            /* TODO: Implement emulation of D32SLL instruction. */
26832            MIPS_INVAL("OPC_MXU_D32SLL");
26833            generate_exception_end(ctx, EXCP_RI);
26834            break;
26835        case OPC_MXU_D32SLR:
26836            /* TODO: Implement emulation of D32SLR instruction. */
26837            MIPS_INVAL("OPC_MXU_D32SLR");
26838            generate_exception_end(ctx, EXCP_RI);
26839            break;
26840        case OPC_MXU_D32SARL:
26841            /* TODO: Implement emulation of D32SARL instruction. */
26842            MIPS_INVAL("OPC_MXU_D32SARL");
26843            generate_exception_end(ctx, EXCP_RI);
26844            break;
26845        case OPC_MXU_D32SAR:
26846            /* TODO: Implement emulation of D32SAR instruction. */
26847            MIPS_INVAL("OPC_MXU_D32SAR");
26848            generate_exception_end(ctx, EXCP_RI);
26849            break;
26850        case OPC_MXU_Q16SLL:
26851            /* TODO: Implement emulation of Q16SLL instruction. */
26852            MIPS_INVAL("OPC_MXU_Q16SLL");
26853            generate_exception_end(ctx, EXCP_RI);
26854            break;
26855        case OPC_MXU_Q16SLR:
26856            /* TODO: Implement emulation of Q16SLR instruction. */
26857            MIPS_INVAL("OPC_MXU_Q16SLR");
26858            generate_exception_end(ctx, EXCP_RI);
26859            break;
26860        case OPC_MXU__POOL18:
26861            decode_opc_mxu__pool18(env, ctx);
26862            break;
26863        case OPC_MXU_Q16SAR:
26864            /* TODO: Implement emulation of Q16SAR instruction. */
26865            MIPS_INVAL("OPC_MXU_Q16SAR");
26866            generate_exception_end(ctx, EXCP_RI);
26867            break;
26868        case OPC_MXU__POOL19:
26869            decode_opc_mxu__pool19(env, ctx);
26870            break;
26871        case OPC_MXU__POOL20:
26872            decode_opc_mxu__pool20(env, ctx);
26873            break;
26874        case OPC_MXU__POOL21:
26875            decode_opc_mxu__pool21(env, ctx);
26876            break;
26877        case OPC_MXU_Q16SCOP:
26878            /* TODO: Implement emulation of Q16SCOP instruction. */
26879            MIPS_INVAL("OPC_MXU_Q16SCOP");
26880            generate_exception_end(ctx, EXCP_RI);
26881            break;
26882        case OPC_MXU_Q8MADL:
26883            /* TODO: Implement emulation of Q8MADL instruction. */
26884            MIPS_INVAL("OPC_MXU_Q8MADL");
26885            generate_exception_end(ctx, EXCP_RI);
26886            break;
26887        case OPC_MXU_S32SFL:
26888            /* TODO: Implement emulation of S32SFL instruction. */
26889            MIPS_INVAL("OPC_MXU_S32SFL");
26890            generate_exception_end(ctx, EXCP_RI);
26891            break;
26892        case OPC_MXU_Q8SAD:
26893            /* TODO: Implement emulation of Q8SAD instruction. */
26894            MIPS_INVAL("OPC_MXU_Q8SAD");
26895            generate_exception_end(ctx, EXCP_RI);
26896            break;
26897        default:
26898            MIPS_INVAL("decode_opc_mxu");
26899            generate_exception_end(ctx, EXCP_RI);
26900        }
26901
26902        gen_set_label(l_exit);
26903        tcg_temp_free(t_mxu_cr);
26904    }
26905}
26906
26907#endif /* !defined(TARGET_MIPS64) */
26908
26909
26910static void decode_opc_special2_legacy(CPUMIPSState *env, DisasContext *ctx)
26911{
26912    int rs, rt, rd;
26913    uint32_t op1;
26914
26915    check_insn_opc_removed(ctx, ISA_MIPS32R6);
26916
26917    rs = (ctx->opcode >> 21) & 0x1f;
26918    rt = (ctx->opcode >> 16) & 0x1f;
26919    rd = (ctx->opcode >> 11) & 0x1f;
26920
26921    op1 = MASK_SPECIAL2(ctx->opcode);
26922    switch (op1) {
26923    case OPC_MADD: /* Multiply and add/sub */
26924    case OPC_MADDU:
26925    case OPC_MSUB:
26926    case OPC_MSUBU:
26927        check_insn(ctx, ISA_MIPS32);
26928        gen_muldiv(ctx, op1, rd & 3, rs, rt);
26929        break;
26930    case OPC_MUL:
26931        gen_arith(ctx, op1, rd, rs, rt);
26932        break;
26933    case OPC_DIV_G_2F:
26934    case OPC_DIVU_G_2F:
26935    case OPC_MULT_G_2F:
26936    case OPC_MULTU_G_2F:
26937    case OPC_MOD_G_2F:
26938    case OPC_MODU_G_2F:
26939        check_insn(ctx, INSN_LOONGSON2F);
26940        gen_loongson_integer(ctx, op1, rd, rs, rt);
26941        break;
26942    case OPC_CLO:
26943    case OPC_CLZ:
26944        check_insn(ctx, ISA_MIPS32);
26945        gen_cl(ctx, op1, rd, rs);
26946        break;
26947    case OPC_SDBBP:
26948        if (is_uhi(extract32(ctx->opcode, 6, 20))) {
26949            gen_helper_do_semihosting(cpu_env);
26950        } else {
26951            /*
26952             * XXX: not clear which exception should be raised
26953             *      when in debug mode...
26954             */
26955            check_insn(ctx, ISA_MIPS32);
26956            generate_exception_end(ctx, EXCP_DBp);
26957        }
26958        break;
26959#if defined(TARGET_MIPS64)
26960    case OPC_DCLO:
26961    case OPC_DCLZ:
26962        check_insn(ctx, ISA_MIPS64);
26963        check_mips_64(ctx);
26964        gen_cl(ctx, op1, rd, rs);
26965        break;
26966    case OPC_DMULT_G_2F:
26967    case OPC_DMULTU_G_2F:
26968    case OPC_DDIV_G_2F:
26969    case OPC_DDIVU_G_2F:
26970    case OPC_DMOD_G_2F:
26971    case OPC_DMODU_G_2F:
26972        check_insn(ctx, INSN_LOONGSON2F);
26973        gen_loongson_integer(ctx, op1, rd, rs, rt);
26974        break;
26975#endif
26976    default:            /* Invalid */
26977        MIPS_INVAL("special2_legacy");
26978        generate_exception_end(ctx, EXCP_RI);
26979        break;
26980    }
26981}
26982
26983static void decode_opc_special3_r6(CPUMIPSState *env, DisasContext *ctx)
26984{
26985    int rs, rt, rd, sa;
26986    uint32_t op1, op2;
26987    int16_t imm;
26988
26989    rs = (ctx->opcode >> 21) & 0x1f;
26990    rt = (ctx->opcode >> 16) & 0x1f;
26991    rd = (ctx->opcode >> 11) & 0x1f;
26992    sa = (ctx->opcode >> 6) & 0x1f;
26993    imm = (int16_t)ctx->opcode >> 7;
26994
26995    op1 = MASK_SPECIAL3(ctx->opcode);
26996    switch (op1) {
26997    case R6_OPC_PREF:
26998        if (rt >= 24) {
26999            /* hint codes 24-31 are reserved and signal RI */
27000            generate_exception_end(ctx, EXCP_RI);
27001        }
27002        /* Treat as NOP. */
27003        break;
27004    case R6_OPC_CACHE:
27005        check_cp0_enabled(ctx);
27006        if (ctx->hflags & MIPS_HFLAG_ITC_CACHE) {
27007            gen_cache_operation(ctx, rt, rs, imm);
27008        }
27009        break;
27010    case R6_OPC_SC:
27011        gen_st_cond(ctx, rt, rs, imm, MO_TESL, false);
27012        break;
27013    case R6_OPC_LL:
27014        gen_ld(ctx, op1, rt, rs, imm);
27015        break;
27016    case OPC_BSHFL:
27017        {
27018            if (rd == 0) {
27019                /* Treat as NOP. */
27020                break;
27021            }
27022            op2 = MASK_BSHFL(ctx->opcode);
27023            switch (op2) {
27024            case OPC_ALIGN:
27025            case OPC_ALIGN_1:
27026            case OPC_ALIGN_2:
27027            case OPC_ALIGN_3:
27028                gen_align(ctx, 32, rd, rs, rt, sa & 3);
27029                break;
27030            case OPC_BITSWAP:
27031                gen_bitswap(ctx, op2, rd, rt);
27032                break;
27033            }
27034        }
27035        break;
27036#if defined(TARGET_MIPS64)
27037    case R6_OPC_SCD:
27038        gen_st_cond(ctx, rt, rs, imm, MO_TEQ, false);
27039        break;
27040    case R6_OPC_LLD:
27041        gen_ld(ctx, op1, rt, rs, imm);
27042        break;
27043    case OPC_DBSHFL:
27044        check_mips_64(ctx);
27045        {
27046            if (rd == 0) {
27047                /* Treat as NOP. */
27048                break;
27049            }
27050            op2 = MASK_DBSHFL(ctx->opcode);
27051            switch (op2) {
27052            case OPC_DALIGN:
27053            case OPC_DALIGN_1:
27054            case OPC_DALIGN_2:
27055            case OPC_DALIGN_3:
27056            case OPC_DALIGN_4:
27057            case OPC_DALIGN_5:
27058            case OPC_DALIGN_6:
27059            case OPC_DALIGN_7:
27060                gen_align(ctx, 64, rd, rs, rt, sa & 7);
27061                break;
27062            case OPC_DBITSWAP:
27063                gen_bitswap(ctx, op2, rd, rt);
27064                break;
27065            }
27066
27067        }
27068        break;
27069#endif
27070    default:            /* Invalid */
27071        MIPS_INVAL("special3_r6");
27072        generate_exception_end(ctx, EXCP_RI);
27073        break;
27074    }
27075}
27076
27077static void decode_opc_special3_legacy(CPUMIPSState *env, DisasContext *ctx)
27078{
27079    int rs, rt, rd;
27080    uint32_t op1, op2;
27081
27082    rs = (ctx->opcode >> 21) & 0x1f;
27083    rt = (ctx->opcode >> 16) & 0x1f;
27084    rd = (ctx->opcode >> 11) & 0x1f;
27085
27086    op1 = MASK_SPECIAL3(ctx->opcode);
27087    switch (op1) {
27088    case OPC_DIV_G_2E:
27089    case OPC_DIVU_G_2E:
27090    case OPC_MOD_G_2E:
27091    case OPC_MODU_G_2E:
27092    case OPC_MULT_G_2E:
27093    case OPC_MULTU_G_2E:
27094        /*
27095         * OPC_MULT_G_2E, OPC_ADDUH_QB_DSP, OPC_MUL_PH_DSP have
27096         * the same mask and op1.
27097         */
27098        if ((ctx->insn_flags & ASE_DSP_R2) && (op1 == OPC_MULT_G_2E)) {
27099            op2 = MASK_ADDUH_QB(ctx->opcode);
27100            switch (op2) {
27101            case OPC_ADDUH_QB:
27102            case OPC_ADDUH_R_QB:
27103            case OPC_ADDQH_PH:
27104            case OPC_ADDQH_R_PH:
27105            case OPC_ADDQH_W:
27106            case OPC_ADDQH_R_W:
27107            case OPC_SUBUH_QB:
27108            case OPC_SUBUH_R_QB:
27109            case OPC_SUBQH_PH:
27110            case OPC_SUBQH_R_PH:
27111            case OPC_SUBQH_W:
27112            case OPC_SUBQH_R_W:
27113                gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
27114                break;
27115            case OPC_MUL_PH:
27116            case OPC_MUL_S_PH:
27117            case OPC_MULQ_S_W:
27118            case OPC_MULQ_RS_W:
27119                gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 1);
27120                break;
27121            default:
27122                MIPS_INVAL("MASK ADDUH.QB");
27123                generate_exception_end(ctx, EXCP_RI);
27124                break;
27125            }
27126        } else if (ctx->insn_flags & INSN_LOONGSON2E) {
27127            gen_loongson_integer(ctx, op1, rd, rs, rt);
27128        } else {
27129            generate_exception_end(ctx, EXCP_RI);
27130        }
27131        break;
27132    case OPC_LX_DSP:
27133        op2 = MASK_LX(ctx->opcode);
27134        switch (op2) {
27135#if defined(TARGET_MIPS64)
27136        case OPC_LDX:
27137#endif
27138        case OPC_LBUX:
27139        case OPC_LHX:
27140        case OPC_LWX:
27141            gen_mipsdsp_ld(ctx, op2, rd, rs, rt);
27142            break;
27143        default:            /* Invalid */
27144            MIPS_INVAL("MASK LX");
27145            generate_exception_end(ctx, EXCP_RI);
27146            break;
27147        }
27148        break;
27149    case OPC_ABSQ_S_PH_DSP:
27150        op2 = MASK_ABSQ_S_PH(ctx->opcode);
27151        switch (op2) {
27152        case OPC_ABSQ_S_QB:
27153        case OPC_ABSQ_S_PH:
27154        case OPC_ABSQ_S_W:
27155        case OPC_PRECEQ_W_PHL:
27156        case OPC_PRECEQ_W_PHR:
27157        case OPC_PRECEQU_PH_QBL:
27158        case OPC_PRECEQU_PH_QBR:
27159        case OPC_PRECEQU_PH_QBLA:
27160        case OPC_PRECEQU_PH_QBRA:
27161        case OPC_PRECEU_PH_QBL:
27162        case OPC_PRECEU_PH_QBR:
27163        case OPC_PRECEU_PH_QBLA:
27164        case OPC_PRECEU_PH_QBRA:
27165            gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
27166            break;
27167        case OPC_BITREV:
27168        case OPC_REPL_QB:
27169        case OPC_REPLV_QB:
27170        case OPC_REPL_PH:
27171        case OPC_REPLV_PH:
27172            gen_mipsdsp_bitinsn(ctx, op1, op2, rd, rt);
27173            break;
27174        default:
27175            MIPS_INVAL("MASK ABSQ_S.PH");
27176            generate_exception_end(ctx, EXCP_RI);
27177            break;
27178        }
27179        break;
27180    case OPC_ADDU_QB_DSP:
27181        op2 = MASK_ADDU_QB(ctx->opcode);
27182        switch (op2) {
27183        case OPC_ADDQ_PH:
27184        case OPC_ADDQ_S_PH:
27185        case OPC_ADDQ_S_W:
27186        case OPC_ADDU_QB:
27187        case OPC_ADDU_S_QB:
27188        case OPC_ADDU_PH:
27189        case OPC_ADDU_S_PH:
27190        case OPC_SUBQ_PH:
27191        case OPC_SUBQ_S_PH:
27192        case OPC_SUBQ_S_W:
27193        case OPC_SUBU_QB:
27194        case OPC_SUBU_S_QB:
27195        case OPC_SUBU_PH:
27196        case OPC_SUBU_S_PH:
27197        case OPC_ADDSC:
27198        case OPC_ADDWC:
27199        case OPC_MODSUB:
27200        case OPC_RADDU_W_QB:
27201            gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
27202            break;
27203        case OPC_MULEU_S_PH_QBL:
27204        case OPC_MULEU_S_PH_QBR:
27205        case OPC_MULQ_RS_PH:
27206        case OPC_MULEQ_S_W_PHL:
27207        case OPC_MULEQ_S_W_PHR:
27208        case OPC_MULQ_S_PH:
27209            gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 1);
27210            break;
27211        default:            /* Invalid */
27212            MIPS_INVAL("MASK ADDU.QB");
27213            generate_exception_end(ctx, EXCP_RI);
27214            break;
27215
27216        }
27217        break;
27218    case OPC_CMPU_EQ_QB_DSP:
27219        op2 = MASK_CMPU_EQ_QB(ctx->opcode);
27220        switch (op2) {
27221        case OPC_PRECR_SRA_PH_W:
27222        case OPC_PRECR_SRA_R_PH_W:
27223            gen_mipsdsp_arith(ctx, op1, op2, rt, rs, rd);
27224            break;
27225        case OPC_PRECR_QB_PH:
27226        case OPC_PRECRQ_QB_PH:
27227        case OPC_PRECRQ_PH_W:
27228        case OPC_PRECRQ_RS_PH_W:
27229        case OPC_PRECRQU_S_QB_PH:
27230            gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
27231            break;
27232        case OPC_CMPU_EQ_QB:
27233        case OPC_CMPU_LT_QB:
27234        case OPC_CMPU_LE_QB:
27235        case OPC_CMP_EQ_PH:
27236        case OPC_CMP_LT_PH:
27237        case OPC_CMP_LE_PH:
27238            gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 0);
27239            break;
27240        case OPC_CMPGU_EQ_QB:
27241        case OPC_CMPGU_LT_QB:
27242        case OPC_CMPGU_LE_QB:
27243        case OPC_CMPGDU_EQ_QB:
27244        case OPC_CMPGDU_LT_QB:
27245        case OPC_CMPGDU_LE_QB:
27246        case OPC_PICK_QB:
27247        case OPC_PICK_PH:
27248        case OPC_PACKRL_PH:
27249            gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 1);
27250            break;
27251        default:            /* Invalid */
27252            MIPS_INVAL("MASK CMPU.EQ.QB");
27253            generate_exception_end(ctx, EXCP_RI);
27254            break;
27255        }
27256        break;
27257    case OPC_SHLL_QB_DSP:
27258        gen_mipsdsp_shift(ctx, op1, rd, rs, rt);
27259        break;
27260    case OPC_DPA_W_PH_DSP:
27261        op2 = MASK_DPA_W_PH(ctx->opcode);
27262        switch (op2) {
27263        case OPC_DPAU_H_QBL:
27264        case OPC_DPAU_H_QBR:
27265        case OPC_DPSU_H_QBL:
27266        case OPC_DPSU_H_QBR:
27267        case OPC_DPA_W_PH:
27268        case OPC_DPAX_W_PH:
27269        case OPC_DPAQ_S_W_PH:
27270        case OPC_DPAQX_S_W_PH:
27271        case OPC_DPAQX_SA_W_PH:
27272        case OPC_DPS_W_PH:
27273        case OPC_DPSX_W_PH:
27274        case OPC_DPSQ_S_W_PH:
27275        case OPC_DPSQX_S_W_PH:
27276        case OPC_DPSQX_SA_W_PH:
27277        case OPC_MULSAQ_S_W_PH:
27278        case OPC_DPAQ_SA_L_W:
27279        case OPC_DPSQ_SA_L_W:
27280        case OPC_MAQ_S_W_PHL:
27281        case OPC_MAQ_S_W_PHR:
27282        case OPC_MAQ_SA_W_PHL:
27283        case OPC_MAQ_SA_W_PHR:
27284        case OPC_MULSA_W_PH:
27285            gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 0);
27286            break;
27287        default:            /* Invalid */
27288            MIPS_INVAL("MASK DPAW.PH");
27289            generate_exception_end(ctx, EXCP_RI);
27290            break;
27291        }
27292        break;
27293    case OPC_INSV_DSP:
27294        op2 = MASK_INSV(ctx->opcode);
27295        switch (op2) {
27296        case OPC_INSV:
27297            check_dsp(ctx);
27298            {
27299                TCGv t0, t1;
27300
27301                if (rt == 0) {
27302                    break;
27303                }
27304
27305                t0 = tcg_temp_new();
27306                t1 = tcg_temp_new();
27307
27308                gen_load_gpr(t0, rt);
27309                gen_load_gpr(t1, rs);
27310
27311                gen_helper_insv(cpu_gpr[rt], cpu_env, t1, t0);
27312
27313                tcg_temp_free(t0);
27314                tcg_temp_free(t1);
27315                break;
27316            }
27317        default:            /* Invalid */
27318            MIPS_INVAL("MASK INSV");
27319            generate_exception_end(ctx, EXCP_RI);
27320            break;
27321        }
27322        break;
27323    case OPC_APPEND_DSP:
27324        gen_mipsdsp_append(env, ctx, op1, rt, rs, rd);
27325        break;
27326    case OPC_EXTR_W_DSP:
27327        op2 = MASK_EXTR_W(ctx->opcode);
27328        switch (op2) {
27329        case OPC_EXTR_W:
27330        case OPC_EXTR_R_W:
27331        case OPC_EXTR_RS_W:
27332        case OPC_EXTR_S_H:
27333        case OPC_EXTRV_S_H:
27334        case OPC_EXTRV_W:
27335        case OPC_EXTRV_R_W:
27336        case OPC_EXTRV_RS_W:
27337        case OPC_EXTP:
27338        case OPC_EXTPV:
27339        case OPC_EXTPDP:
27340        case OPC_EXTPDPV:
27341            gen_mipsdsp_accinsn(ctx, op1, op2, rt, rs, rd, 1);
27342            break;
27343        case OPC_RDDSP:
27344            gen_mipsdsp_accinsn(ctx, op1, op2, rd, rs, rt, 1);
27345            break;
27346        case OPC_SHILO:
27347        case OPC_SHILOV:
27348        case OPC_MTHLIP:
27349        case OPC_WRDSP:
27350            gen_mipsdsp_accinsn(ctx, op1, op2, rd, rs, rt, 0);
27351            break;
27352        default:            /* Invalid */
27353            MIPS_INVAL("MASK EXTR.W");
27354            generate_exception_end(ctx, EXCP_RI);
27355            break;
27356        }
27357        break;
27358#if defined(TARGET_MIPS64)
27359    case OPC_DDIV_G_2E:
27360    case OPC_DDIVU_G_2E:
27361    case OPC_DMULT_G_2E:
27362    case OPC_DMULTU_G_2E:
27363    case OPC_DMOD_G_2E:
27364    case OPC_DMODU_G_2E:
27365        check_insn(ctx, INSN_LOONGSON2E);
27366        gen_loongson_integer(ctx, op1, rd, rs, rt);
27367        break;
27368    case OPC_ABSQ_S_QH_DSP:
27369        op2 = MASK_ABSQ_S_QH(ctx->opcode);
27370        switch (op2) {
27371        case OPC_PRECEQ_L_PWL:
27372        case OPC_PRECEQ_L_PWR:
27373        case OPC_PRECEQ_PW_QHL:
27374        case OPC_PRECEQ_PW_QHR:
27375        case OPC_PRECEQ_PW_QHLA:
27376        case OPC_PRECEQ_PW_QHRA:
27377        case OPC_PRECEQU_QH_OBL:
27378        case OPC_PRECEQU_QH_OBR:
27379        case OPC_PRECEQU_QH_OBLA:
27380        case OPC_PRECEQU_QH_OBRA:
27381        case OPC_PRECEU_QH_OBL:
27382        case OPC_PRECEU_QH_OBR:
27383        case OPC_PRECEU_QH_OBLA:
27384        case OPC_PRECEU_QH_OBRA:
27385        case OPC_ABSQ_S_OB:
27386        case OPC_ABSQ_S_PW:
27387        case OPC_ABSQ_S_QH:
27388            gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
27389            break;
27390        case OPC_REPL_OB:
27391        case OPC_REPL_PW:
27392        case OPC_REPL_QH:
27393        case OPC_REPLV_OB:
27394        case OPC_REPLV_PW:
27395        case OPC_REPLV_QH:
27396            gen_mipsdsp_bitinsn(ctx, op1, op2, rd, rt);
27397            break;
27398        default:            /* Invalid */
27399            MIPS_INVAL("MASK ABSQ_S.QH");
27400            generate_exception_end(ctx, EXCP_RI);
27401            break;
27402        }
27403        break;
27404    case OPC_ADDU_OB_DSP:
27405        op2 = MASK_ADDU_OB(ctx->opcode);
27406        switch (op2) {
27407        case OPC_RADDU_L_OB:
27408        case OPC_SUBQ_PW:
27409        case OPC_SUBQ_S_PW:
27410        case OPC_SUBQ_QH:
27411        case OPC_SUBQ_S_QH:
27412        case OPC_SUBU_OB:
27413        case OPC_SUBU_S_OB:
27414        case OPC_SUBU_QH:
27415        case OPC_SUBU_S_QH:
27416        case OPC_SUBUH_OB:
27417        case OPC_SUBUH_R_OB:
27418        case OPC_ADDQ_PW:
27419        case OPC_ADDQ_S_PW:
27420        case OPC_ADDQ_QH:
27421        case OPC_ADDQ_S_QH:
27422        case OPC_ADDU_OB:
27423        case OPC_ADDU_S_OB:
27424        case OPC_ADDU_QH:
27425        case OPC_ADDU_S_QH:
27426        case OPC_ADDUH_OB:
27427        case OPC_ADDUH_R_OB:
27428            gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
27429            break;
27430        case OPC_MULEQ_S_PW_QHL:
27431        case OPC_MULEQ_S_PW_QHR:
27432        case OPC_MULEU_S_QH_OBL:
27433        case OPC_MULEU_S_QH_OBR:
27434        case OPC_MULQ_RS_QH:
27435            gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 1);
27436            break;
27437        default:            /* Invalid */
27438            MIPS_INVAL("MASK ADDU.OB");
27439            generate_exception_end(ctx, EXCP_RI);
27440            break;
27441        }
27442        break;
27443    case OPC_CMPU_EQ_OB_DSP:
27444        op2 = MASK_CMPU_EQ_OB(ctx->opcode);
27445        switch (op2) {
27446        case OPC_PRECR_SRA_QH_PW:
27447        case OPC_PRECR_SRA_R_QH_PW:
27448            /* Return value is rt. */
27449            gen_mipsdsp_arith(ctx, op1, op2, rt, rs, rd);
27450            break;
27451        case OPC_PRECR_OB_QH:
27452        case OPC_PRECRQ_OB_QH:
27453        case OPC_PRECRQ_PW_L:
27454        case OPC_PRECRQ_QH_PW:
27455        case OPC_PRECRQ_RS_QH_PW:
27456        case OPC_PRECRQU_S_OB_QH:
27457            gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
27458            break;
27459        case OPC_CMPU_EQ_OB:
27460        case OPC_CMPU_LT_OB:
27461        case OPC_CMPU_LE_OB:
27462        case OPC_CMP_EQ_QH:
27463        case OPC_CMP_LT_QH:
27464        case OPC_CMP_LE_QH:
27465        case OPC_CMP_EQ_PW:
27466        case OPC_CMP_LT_PW:
27467        case OPC_CMP_LE_PW:
27468            gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 0);
27469            break;
27470        case OPC_CMPGDU_EQ_OB:
27471        case OPC_CMPGDU_LT_OB:
27472        case OPC_CMPGDU_LE_OB:
27473        case OPC_CMPGU_EQ_OB:
27474        case OPC_CMPGU_LT_OB:
27475        case OPC_CMPGU_LE_OB:
27476        case OPC_PACKRL_PW:
27477        case OPC_PICK_OB:
27478        case OPC_PICK_PW:
27479        case OPC_PICK_QH:
27480            gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 1);
27481            break;
27482        default:            /* Invalid */
27483            MIPS_INVAL("MASK CMPU_EQ.OB");
27484            generate_exception_end(ctx, EXCP_RI);
27485            break;
27486        }
27487        break;
27488    case OPC_DAPPEND_DSP:
27489        gen_mipsdsp_append(env, ctx, op1, rt, rs, rd);
27490        break;
27491    case OPC_DEXTR_W_DSP:
27492        op2 = MASK_DEXTR_W(ctx->opcode);
27493        switch (op2) {
27494        case OPC_DEXTP:
27495        case OPC_DEXTPDP:
27496        case OPC_DEXTPDPV:
27497        case OPC_DEXTPV:
27498        case OPC_DEXTR_L:
27499        case OPC_DEXTR_R_L:
27500        case OPC_DEXTR_RS_L:
27501        case OPC_DEXTR_W:
27502        case OPC_DEXTR_R_W:
27503        case OPC_DEXTR_RS_W:
27504        case OPC_DEXTR_S_H:
27505        case OPC_DEXTRV_L:
27506        case OPC_DEXTRV_R_L:
27507        case OPC_DEXTRV_RS_L:
27508        case OPC_DEXTRV_S_H:
27509        case OPC_DEXTRV_W:
27510        case OPC_DEXTRV_R_W:
27511        case OPC_DEXTRV_RS_W:
27512            gen_mipsdsp_accinsn(ctx, op1, op2, rt, rs, rd, 1);
27513            break;
27514        case OPC_DMTHLIP:
27515        case OPC_DSHILO:
27516        case OPC_DSHILOV:
27517            gen_mipsdsp_accinsn(ctx, op1, op2, rd, rs, rt, 0);
27518            break;
27519        default:            /* Invalid */
27520            MIPS_INVAL("MASK EXTR.W");
27521            generate_exception_end(ctx, EXCP_RI);
27522            break;
27523        }
27524        break;
27525    case OPC_DPAQ_W_QH_DSP:
27526        op2 = MASK_DPAQ_W_QH(ctx->opcode);
27527        switch (op2) {
27528        case OPC_DPAU_H_OBL:
27529        case OPC_DPAU_H_OBR:
27530        case OPC_DPSU_H_OBL:
27531        case OPC_DPSU_H_OBR:
27532        case OPC_DPA_W_QH:
27533        case OPC_DPAQ_S_W_QH:
27534        case OPC_DPS_W_QH:
27535        case OPC_DPSQ_S_W_QH:
27536        case OPC_MULSAQ_S_W_QH:
27537        case OPC_DPAQ_SA_L_PW:
27538        case OPC_DPSQ_SA_L_PW:
27539        case OPC_MULSAQ_S_L_PW:
27540            gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 0);
27541            break;
27542        case OPC_MAQ_S_W_QHLL:
27543        case OPC_MAQ_S_W_QHLR:
27544        case OPC_MAQ_S_W_QHRL:
27545        case OPC_MAQ_S_W_QHRR:
27546        case OPC_MAQ_SA_W_QHLL:
27547        case OPC_MAQ_SA_W_QHLR:
27548        case OPC_MAQ_SA_W_QHRL:
27549        case OPC_MAQ_SA_W_QHRR:
27550        case OPC_MAQ_S_L_PWL:
27551        case OPC_MAQ_S_L_PWR:
27552        case OPC_DMADD:
27553        case OPC_DMADDU:
27554        case OPC_DMSUB:
27555        case OPC_DMSUBU:
27556            gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 0);
27557            break;
27558        default:            /* Invalid */
27559            MIPS_INVAL("MASK DPAQ.W.QH");
27560            generate_exception_end(ctx, EXCP_RI);
27561            break;
27562        }
27563        break;
27564    case OPC_DINSV_DSP:
27565        op2 = MASK_INSV(ctx->opcode);
27566        switch (op2) {
27567        case OPC_DINSV:
27568        {
27569            TCGv t0, t1;
27570
27571            if (rt == 0) {
27572                break;
27573            }
27574            check_dsp(ctx);
27575
27576            t0 = tcg_temp_new();
27577            t1 = tcg_temp_new();
27578
27579            gen_load_gpr(t0, rt);
27580            gen_load_gpr(t1, rs);
27581
27582            gen_helper_dinsv(cpu_gpr[rt], cpu_env, t1, t0);
27583
27584            tcg_temp_free(t0);
27585            tcg_temp_free(t1);
27586            break;
27587        }
27588        default:            /* Invalid */
27589            MIPS_INVAL("MASK DINSV");
27590            generate_exception_end(ctx, EXCP_RI);
27591            break;
27592        }
27593        break;
27594    case OPC_SHLL_OB_DSP:
27595        gen_mipsdsp_shift(ctx, op1, rd, rs, rt);
27596        break;
27597#endif
27598    default:            /* Invalid */
27599        MIPS_INVAL("special3_legacy");
27600        generate_exception_end(ctx, EXCP_RI);
27601        break;
27602    }
27603}
27604
27605
27606#if defined(TARGET_MIPS64)
27607
27608static void decode_mmi0(CPUMIPSState *env, DisasContext *ctx)
27609{
27610    uint32_t opc = MASK_MMI0(ctx->opcode);
27611
27612    switch (opc) {
27613    case MMI_OPC_0_PADDW:     /* TODO: MMI_OPC_0_PADDW */
27614    case MMI_OPC_0_PSUBW:     /* TODO: MMI_OPC_0_PSUBW */
27615    case MMI_OPC_0_PCGTW:     /* TODO: MMI_OPC_0_PCGTW */
27616    case MMI_OPC_0_PMAXW:     /* TODO: MMI_OPC_0_PMAXW */
27617    case MMI_OPC_0_PADDH:     /* TODO: MMI_OPC_0_PADDH */
27618    case MMI_OPC_0_PSUBH:     /* TODO: MMI_OPC_0_PSUBH */
27619    case MMI_OPC_0_PCGTH:     /* TODO: MMI_OPC_0_PCGTH */
27620    case MMI_OPC_0_PMAXH:     /* TODO: MMI_OPC_0_PMAXH */
27621    case MMI_OPC_0_PADDB:     /* TODO: MMI_OPC_0_PADDB */
27622    case MMI_OPC_0_PSUBB:     /* TODO: MMI_OPC_0_PSUBB */
27623    case MMI_OPC_0_PCGTB:     /* TODO: MMI_OPC_0_PCGTB */
27624    case MMI_OPC_0_PADDSW:    /* TODO: MMI_OPC_0_PADDSW */
27625    case MMI_OPC_0_PSUBSW:    /* TODO: MMI_OPC_0_PSUBSW */
27626    case MMI_OPC_0_PEXTLW:    /* TODO: MMI_OPC_0_PEXTLW */
27627    case MMI_OPC_0_PPACW:     /* TODO: MMI_OPC_0_PPACW */
27628    case MMI_OPC_0_PADDSH:    /* TODO: MMI_OPC_0_PADDSH */
27629    case MMI_OPC_0_PSUBSH:    /* TODO: MMI_OPC_0_PSUBSH */
27630    case MMI_OPC_0_PEXTLH:    /* TODO: MMI_OPC_0_PEXTLH */
27631    case MMI_OPC_0_PPACH:     /* TODO: MMI_OPC_0_PPACH */
27632    case MMI_OPC_0_PADDSB:    /* TODO: MMI_OPC_0_PADDSB */
27633    case MMI_OPC_0_PSUBSB:    /* TODO: MMI_OPC_0_PSUBSB */
27634    case MMI_OPC_0_PEXTLB:    /* TODO: MMI_OPC_0_PEXTLB */
27635    case MMI_OPC_0_PPACB:     /* TODO: MMI_OPC_0_PPACB */
27636    case MMI_OPC_0_PEXT5:     /* TODO: MMI_OPC_0_PEXT5 */
27637    case MMI_OPC_0_PPAC5:     /* TODO: MMI_OPC_0_PPAC5 */
27638        generate_exception_end(ctx, EXCP_RI); /* TODO: MMI_OPC_CLASS_MMI0 */
27639        break;
27640    default:
27641        MIPS_INVAL("TX79 MMI class MMI0");
27642        generate_exception_end(ctx, EXCP_RI);
27643        break;
27644    }
27645}
27646
27647static void decode_mmi1(CPUMIPSState *env, DisasContext *ctx)
27648{
27649    uint32_t opc = MASK_MMI1(ctx->opcode);
27650
27651    switch (opc) {
27652    case MMI_OPC_1_PABSW:     /* TODO: MMI_OPC_1_PABSW */
27653    case MMI_OPC_1_PCEQW:     /* TODO: MMI_OPC_1_PCEQW */
27654    case MMI_OPC_1_PMINW:     /* TODO: MMI_OPC_1_PMINW */
27655    case MMI_OPC_1_PADSBH:    /* TODO: MMI_OPC_1_PADSBH */
27656    case MMI_OPC_1_PABSH:     /* TODO: MMI_OPC_1_PABSH */
27657    case MMI_OPC_1_PCEQH:     /* TODO: MMI_OPC_1_PCEQH */
27658    case MMI_OPC_1_PMINH:     /* TODO: MMI_OPC_1_PMINH */
27659    case MMI_OPC_1_PCEQB:     /* TODO: MMI_OPC_1_PCEQB */
27660    case MMI_OPC_1_PADDUW:    /* TODO: MMI_OPC_1_PADDUW */
27661    case MMI_OPC_1_PSUBUW:    /* TODO: MMI_OPC_1_PSUBUW */
27662    case MMI_OPC_1_PEXTUW:    /* TODO: MMI_OPC_1_PEXTUW */
27663    case MMI_OPC_1_PADDUH:    /* TODO: MMI_OPC_1_PADDUH */
27664    case MMI_OPC_1_PSUBUH:    /* TODO: MMI_OPC_1_PSUBUH */
27665    case MMI_OPC_1_PEXTUH:    /* TODO: MMI_OPC_1_PEXTUH */
27666    case MMI_OPC_1_PADDUB:    /* TODO: MMI_OPC_1_PADDUB */
27667    case MMI_OPC_1_PSUBUB:    /* TODO: MMI_OPC_1_PSUBUB */
27668    case MMI_OPC_1_PEXTUB:    /* TODO: MMI_OPC_1_PEXTUB */
27669    case MMI_OPC_1_QFSRV:     /* TODO: MMI_OPC_1_QFSRV */
27670        generate_exception_end(ctx, EXCP_RI); /* TODO: MMI_OPC_CLASS_MMI1 */
27671        break;
27672    default:
27673        MIPS_INVAL("TX79 MMI class MMI1");
27674        generate_exception_end(ctx, EXCP_RI);
27675        break;
27676    }
27677}
27678
27679static void decode_mmi2(CPUMIPSState *env, DisasContext *ctx)
27680{
27681    uint32_t opc = MASK_MMI2(ctx->opcode);
27682
27683    switch (opc) {
27684    case MMI_OPC_2_PMADDW:    /* TODO: MMI_OPC_2_PMADDW */
27685    case MMI_OPC_2_PSLLVW:    /* TODO: MMI_OPC_2_PSLLVW */
27686    case MMI_OPC_2_PSRLVW:    /* TODO: MMI_OPC_2_PSRLVW */
27687    case MMI_OPC_2_PMSUBW:    /* TODO: MMI_OPC_2_PMSUBW */
27688    case MMI_OPC_2_PMFHI:     /* TODO: MMI_OPC_2_PMFHI */
27689    case MMI_OPC_2_PMFLO:     /* TODO: MMI_OPC_2_PMFLO */
27690    case MMI_OPC_2_PINTH:     /* TODO: MMI_OPC_2_PINTH */
27691    case MMI_OPC_2_PMULTW:    /* TODO: MMI_OPC_2_PMULTW */
27692    case MMI_OPC_2_PDIVW:     /* TODO: MMI_OPC_2_PDIVW */
27693    case MMI_OPC_2_PMADDH:    /* TODO: MMI_OPC_2_PMADDH */
27694    case MMI_OPC_2_PHMADH:    /* TODO: MMI_OPC_2_PHMADH */
27695    case MMI_OPC_2_PAND:      /* TODO: MMI_OPC_2_PAND */
27696    case MMI_OPC_2_PXOR:      /* TODO: MMI_OPC_2_PXOR */
27697    case MMI_OPC_2_PMSUBH:    /* TODO: MMI_OPC_2_PMSUBH */
27698    case MMI_OPC_2_PHMSBH:    /* TODO: MMI_OPC_2_PHMSBH */
27699    case MMI_OPC_2_PEXEH:     /* TODO: MMI_OPC_2_PEXEH */
27700    case MMI_OPC_2_PREVH:     /* TODO: MMI_OPC_2_PREVH */
27701    case MMI_OPC_2_PMULTH:    /* TODO: MMI_OPC_2_PMULTH */
27702    case MMI_OPC_2_PDIVBW:    /* TODO: MMI_OPC_2_PDIVBW */
27703    case MMI_OPC_2_PEXEW:     /* TODO: MMI_OPC_2_PEXEW */
27704    case MMI_OPC_2_PROT3W:    /* TODO: MMI_OPC_2_PROT3W */
27705        generate_exception_end(ctx, EXCP_RI); /* TODO: MMI_OPC_CLASS_MMI2 */
27706        break;
27707    case MMI_OPC_2_PCPYLD:
27708        gen_mmi_pcpyld(ctx);
27709        break;
27710    default:
27711        MIPS_INVAL("TX79 MMI class MMI2");
27712        generate_exception_end(ctx, EXCP_RI);
27713        break;
27714    }
27715}
27716
27717static void decode_mmi3(CPUMIPSState *env, DisasContext *ctx)
27718{
27719    uint32_t opc = MASK_MMI3(ctx->opcode);
27720
27721    switch (opc) {
27722    case MMI_OPC_3_PMADDUW:    /* TODO: MMI_OPC_3_PMADDUW */
27723    case MMI_OPC_3_PSRAVW:     /* TODO: MMI_OPC_3_PSRAVW */
27724    case MMI_OPC_3_PMTHI:      /* TODO: MMI_OPC_3_PMTHI */
27725    case MMI_OPC_3_PMTLO:      /* TODO: MMI_OPC_3_PMTLO */
27726    case MMI_OPC_3_PINTEH:     /* TODO: MMI_OPC_3_PINTEH */
27727    case MMI_OPC_3_PMULTUW:    /* TODO: MMI_OPC_3_PMULTUW */
27728    case MMI_OPC_3_PDIVUW:     /* TODO: MMI_OPC_3_PDIVUW */
27729    case MMI_OPC_3_POR:        /* TODO: MMI_OPC_3_POR */
27730    case MMI_OPC_3_PNOR:       /* TODO: MMI_OPC_3_PNOR */
27731    case MMI_OPC_3_PEXCH:      /* TODO: MMI_OPC_3_PEXCH */
27732    case MMI_OPC_3_PEXCW:      /* TODO: MMI_OPC_3_PEXCW */
27733        generate_exception_end(ctx, EXCP_RI); /* TODO: MMI_OPC_CLASS_MMI3 */
27734        break;
27735    case MMI_OPC_3_PCPYH:
27736        gen_mmi_pcpyh(ctx);
27737        break;
27738    case MMI_OPC_3_PCPYUD:
27739        gen_mmi_pcpyud(ctx);
27740        break;
27741    default:
27742        MIPS_INVAL("TX79 MMI class MMI3");
27743        generate_exception_end(ctx, EXCP_RI);
27744        break;
27745    }
27746}
27747
27748static void decode_mmi(CPUMIPSState *env, DisasContext *ctx)
27749{
27750    uint32_t opc = MASK_MMI(ctx->opcode);
27751    int rs = extract32(ctx->opcode, 21, 5);
27752    int rt = extract32(ctx->opcode, 16, 5);
27753    int rd = extract32(ctx->opcode, 11, 5);
27754
27755    switch (opc) {
27756    case MMI_OPC_CLASS_MMI0:
27757        decode_mmi0(env, ctx);
27758        break;
27759    case MMI_OPC_CLASS_MMI1:
27760        decode_mmi1(env, ctx);
27761        break;
27762    case MMI_OPC_CLASS_MMI2:
27763        decode_mmi2(env, ctx);
27764        break;
27765    case MMI_OPC_CLASS_MMI3:
27766        decode_mmi3(env, ctx);
27767        break;
27768    case MMI_OPC_MULT1:
27769    case MMI_OPC_MULTU1:
27770    case MMI_OPC_MADD:
27771    case MMI_OPC_MADDU:
27772    case MMI_OPC_MADD1:
27773    case MMI_OPC_MADDU1:
27774        gen_mul_txx9(ctx, opc, rd, rs, rt);
27775        break;
27776    case MMI_OPC_DIV1:
27777    case MMI_OPC_DIVU1:
27778        gen_div1_tx79(ctx, opc, rs, rt);
27779        break;
27780    case MMI_OPC_MTLO1:
27781    case MMI_OPC_MTHI1:
27782        gen_HILO1_tx79(ctx, opc, rs);
27783        break;
27784    case MMI_OPC_MFLO1:
27785    case MMI_OPC_MFHI1:
27786        gen_HILO1_tx79(ctx, opc, rd);
27787        break;
27788    case MMI_OPC_PLZCW:         /* TODO: MMI_OPC_PLZCW */
27789    case MMI_OPC_PMFHL:         /* TODO: MMI_OPC_PMFHL */
27790    case MMI_OPC_PMTHL:         /* TODO: MMI_OPC_PMTHL */
27791    case MMI_OPC_PSLLH:         /* TODO: MMI_OPC_PSLLH */
27792    case MMI_OPC_PSRLH:         /* TODO: MMI_OPC_PSRLH */
27793    case MMI_OPC_PSRAH:         /* TODO: MMI_OPC_PSRAH */
27794    case MMI_OPC_PSLLW:         /* TODO: MMI_OPC_PSLLW */
27795    case MMI_OPC_PSRLW:         /* TODO: MMI_OPC_PSRLW */
27796    case MMI_OPC_PSRAW:         /* TODO: MMI_OPC_PSRAW */
27797        generate_exception_end(ctx, EXCP_RI);    /* TODO: MMI_OPC_CLASS_MMI */
27798        break;
27799    default:
27800        MIPS_INVAL("TX79 MMI class");
27801        generate_exception_end(ctx, EXCP_RI);
27802        break;
27803    }
27804}
27805
27806static void gen_mmi_lq(CPUMIPSState *env, DisasContext *ctx)
27807{
27808    generate_exception_end(ctx, EXCP_RI);    /* TODO: MMI_OPC_LQ */
27809}
27810
27811static void gen_mmi_sq(DisasContext *ctx, int base, int rt, int offset)
27812{
27813    generate_exception_end(ctx, EXCP_RI);    /* TODO: MMI_OPC_SQ */
27814}
27815
27816/*
27817 * The TX79-specific instruction Store Quadword
27818 *
27819 * +--------+-------+-------+------------------------+
27820 * | 011111 |  base |   rt  |           offset       | SQ
27821 * +--------+-------+-------+------------------------+
27822 *      6       5       5                 16
27823 *
27824 * has the same opcode as the Read Hardware Register instruction
27825 *
27826 * +--------+-------+-------+-------+-------+--------+
27827 * | 011111 | 00000 |   rt  |   rd  | 00000 | 111011 | RDHWR
27828 * +--------+-------+-------+-------+-------+--------+
27829 *      6       5       5       5       5        6
27830 *
27831 * that is required, trapped and emulated by the Linux kernel. However, all
27832 * RDHWR encodings yield address error exceptions on the TX79 since the SQ
27833 * offset is odd. Therefore all valid SQ instructions can execute normally.
27834 * In user mode, QEMU must verify the upper and lower 11 bits to distinguish
27835 * between SQ and RDHWR, as the Linux kernel does.
27836 */
27837static void decode_mmi_sq(CPUMIPSState *env, DisasContext *ctx)
27838{
27839    int base = extract32(ctx->opcode, 21, 5);
27840    int rt = extract32(ctx->opcode, 16, 5);
27841    int offset = extract32(ctx->opcode, 0, 16);
27842
27843#ifdef CONFIG_USER_ONLY
27844    uint32_t op1 = MASK_SPECIAL3(ctx->opcode);
27845    uint32_t op2 = extract32(ctx->opcode, 6, 5);
27846
27847    if (base == 0 && op2 == 0 && op1 == OPC_RDHWR) {
27848        int rd = extract32(ctx->opcode, 11, 5);
27849
27850        gen_rdhwr(ctx, rt, rd, 0);
27851        return;
27852    }
27853#endif
27854
27855    gen_mmi_sq(ctx, base, rt, offset);
27856}
27857
27858#endif
27859
27860static void decode_opc_special3(CPUMIPSState *env, DisasContext *ctx)
27861{
27862    int rs, rt, rd, sa;
27863    uint32_t op1, op2;
27864    int16_t imm;
27865
27866    rs = (ctx->opcode >> 21) & 0x1f;
27867    rt = (ctx->opcode >> 16) & 0x1f;
27868    rd = (ctx->opcode >> 11) & 0x1f;
27869    sa = (ctx->opcode >> 6) & 0x1f;
27870    imm = sextract32(ctx->opcode, 7, 9);
27871
27872    op1 = MASK_SPECIAL3(ctx->opcode);
27873
27874    /*
27875     * EVA loads and stores overlap Loongson 2E instructions decoded by
27876     * decode_opc_special3_legacy(), so be careful to allow their decoding when
27877     * EVA is absent.
27878     */
27879    if (ctx->eva) {
27880        switch (op1) {
27881        case OPC_LWLE:
27882        case OPC_LWRE:
27883            check_insn_opc_removed(ctx, ISA_MIPS32R6);
27884            /* fall through */
27885        case OPC_LBUE:
27886        case OPC_LHUE:
27887        case OPC_LBE:
27888        case OPC_LHE:
27889        case OPC_LLE:
27890        case OPC_LWE:
27891            check_cp0_enabled(ctx);
27892            gen_ld(ctx, op1, rt, rs, imm);
27893            return;
27894        case OPC_SWLE:
27895        case OPC_SWRE:
27896            check_insn_opc_removed(ctx, ISA_MIPS32R6);
27897            /* fall through */
27898        case OPC_SBE:
27899        case OPC_SHE:
27900        case OPC_SWE:
27901            check_cp0_enabled(ctx);
27902            gen_st(ctx, op1, rt, rs, imm);
27903            return;
27904        case OPC_SCE:
27905            check_cp0_enabled(ctx);
27906            gen_st_cond(ctx, rt, rs, imm, MO_TESL, true);
27907            return;
27908        case OPC_CACHEE:
27909            check_cp0_enabled(ctx);
27910            if (ctx->hflags & MIPS_HFLAG_ITC_CACHE) {
27911                gen_cache_operation(ctx, rt, rs, imm);
27912            }
27913            /* Treat as NOP. */
27914            return;
27915        case OPC_PREFE:
27916            check_cp0_enabled(ctx);
27917            /* Treat as NOP. */
27918            return;
27919        }
27920    }
27921
27922    switch (op1) {
27923    case OPC_EXT:
27924    case OPC_INS:
27925        check_insn(ctx, ISA_MIPS32R2);
27926        gen_bitops(ctx, op1, rt, rs, sa, rd);
27927        break;
27928    case OPC_BSHFL:
27929        op2 = MASK_BSHFL(ctx->opcode);
27930        switch (op2) {
27931        case OPC_ALIGN:
27932        case OPC_ALIGN_1:
27933        case OPC_ALIGN_2:
27934        case OPC_ALIGN_3:
27935        case OPC_BITSWAP:
27936            check_insn(ctx, ISA_MIPS32R6);
27937            decode_opc_special3_r6(env, ctx);
27938            break;
27939        default:
27940            check_insn(ctx, ISA_MIPS32R2);
27941            gen_bshfl(ctx, op2, rt, rd);
27942            break;
27943        }
27944        break;
27945#if defined(TARGET_MIPS64)
27946    case OPC_DEXTM:
27947    case OPC_DEXTU:
27948    case OPC_DEXT:
27949    case OPC_DINSM:
27950    case OPC_DINSU:
27951    case OPC_DINS:
27952        check_insn(ctx, ISA_MIPS64R2);
27953        check_mips_64(ctx);
27954        gen_bitops(ctx, op1, rt, rs, sa, rd);
27955        break;
27956    case OPC_DBSHFL:
27957        op2 = MASK_DBSHFL(ctx->opcode);
27958        switch (op2) {
27959        case OPC_DALIGN:
27960        case OPC_DALIGN_1:
27961        case OPC_DALIGN_2:
27962        case OPC_DALIGN_3:
27963        case OPC_DALIGN_4:
27964        case OPC_DALIGN_5:
27965        case OPC_DALIGN_6:
27966        case OPC_DALIGN_7:
27967        case OPC_DBITSWAP:
27968            check_insn(ctx, ISA_MIPS32R6);
27969            decode_opc_special3_r6(env, ctx);
27970            break;
27971        default:
27972            check_insn(ctx, ISA_MIPS64R2);
27973            check_mips_64(ctx);
27974            op2 = MASK_DBSHFL(ctx->opcode);
27975            gen_bshfl(ctx, op2, rt, rd);
27976            break;
27977        }
27978        break;
27979#endif
27980    case OPC_RDHWR:
27981        gen_rdhwr(ctx, rt, rd, extract32(ctx->opcode, 6, 3));
27982        break;
27983    case OPC_FORK:
27984        check_mt(ctx);
27985        {
27986            TCGv t0 = tcg_temp_new();
27987            TCGv t1 = tcg_temp_new();
27988
27989            gen_load_gpr(t0, rt);
27990            gen_load_gpr(t1, rs);
27991            gen_helper_fork(t0, t1);
27992            tcg_temp_free(t0);
27993            tcg_temp_free(t1);
27994        }
27995        break;
27996    case OPC_YIELD:
27997        check_mt(ctx);
27998        {
27999            TCGv t0 = tcg_temp_new();
28000
28001            gen_load_gpr(t0, rs);
28002            gen_helper_yield(t0, cpu_env, t0);
28003            gen_store_gpr(t0, rd);
28004            tcg_temp_free(t0);
28005        }
28006        break;
28007    default:
28008        if (ctx->insn_flags & ISA_MIPS32R6) {
28009            decode_opc_special3_r6(env, ctx);
28010        } else {
28011            decode_opc_special3_legacy(env, ctx);
28012        }
28013    }
28014}
28015
28016/* MIPS SIMD Architecture (MSA)  */
28017static inline int check_msa_access(DisasContext *ctx)
28018{
28019    if (unlikely((ctx->hflags & MIPS_HFLAG_FPU) &&
28020                 !(ctx->hflags & MIPS_HFLAG_F64))) {
28021        generate_exception_end(ctx, EXCP_RI);
28022        return 0;
28023    }
28024
28025    if (unlikely(!(ctx->hflags & MIPS_HFLAG_MSA))) {
28026        if (ctx->insn_flags & ASE_MSA) {
28027            generate_exception_end(ctx, EXCP_MSADIS);
28028            return 0;
28029        } else {
28030            generate_exception_end(ctx, EXCP_RI);
28031            return 0;
28032        }
28033    }
28034    return 1;
28035}
28036
28037static void gen_check_zero_element(TCGv tresult, uint8_t df, uint8_t wt)
28038{
28039    /* generates tcg ops to check if any element is 0 */
28040    /* Note this function only works with MSA_WRLEN = 128 */
28041    uint64_t eval_zero_or_big = 0;
28042    uint64_t eval_big = 0;
28043    TCGv_i64 t0 = tcg_temp_new_i64();
28044    TCGv_i64 t1 = tcg_temp_new_i64();
28045    switch (df) {
28046    case DF_BYTE:
28047        eval_zero_or_big = 0x0101010101010101ULL;
28048        eval_big = 0x8080808080808080ULL;
28049        break;
28050    case DF_HALF:
28051        eval_zero_or_big = 0x0001000100010001ULL;
28052        eval_big = 0x8000800080008000ULL;
28053        break;
28054    case DF_WORD:
28055        eval_zero_or_big = 0x0000000100000001ULL;
28056        eval_big = 0x8000000080000000ULL;
28057        break;
28058    case DF_DOUBLE:
28059        eval_zero_or_big = 0x0000000000000001ULL;
28060        eval_big = 0x8000000000000000ULL;
28061        break;
28062    }
28063    tcg_gen_subi_i64(t0, msa_wr_d[wt << 1], eval_zero_or_big);
28064    tcg_gen_andc_i64(t0, t0, msa_wr_d[wt << 1]);
28065    tcg_gen_andi_i64(t0, t0, eval_big);
28066    tcg_gen_subi_i64(t1, msa_wr_d[(wt << 1) + 1], eval_zero_or_big);
28067    tcg_gen_andc_i64(t1, t1, msa_wr_d[(wt << 1) + 1]);
28068    tcg_gen_andi_i64(t1, t1, eval_big);
28069    tcg_gen_or_i64(t0, t0, t1);
28070    /* if all bits are zero then all elements are not zero */
28071    /* if some bit is non-zero then some element is zero */
28072    tcg_gen_setcondi_i64(TCG_COND_NE, t0, t0, 0);
28073    tcg_gen_trunc_i64_tl(tresult, t0);
28074    tcg_temp_free_i64(t0);
28075    tcg_temp_free_i64(t1);
28076}
28077
28078static void gen_msa_branch(CPUMIPSState *env, DisasContext *ctx, uint32_t op1)
28079{
28080    uint8_t df = (ctx->opcode >> 21) & 0x3;
28081    uint8_t wt = (ctx->opcode >> 16) & 0x1f;
28082    int64_t s16 = (int16_t)ctx->opcode;
28083
28084    check_msa_access(ctx);
28085
28086    if (ctx->hflags & MIPS_HFLAG_BMASK) {
28087        generate_exception_end(ctx, EXCP_RI);
28088        return;
28089    }
28090    switch (op1) {
28091    case OPC_BZ_V:
28092    case OPC_BNZ_V:
28093        {
28094            TCGv_i64 t0 = tcg_temp_new_i64();
28095            tcg_gen_or_i64(t0, msa_wr_d[wt << 1], msa_wr_d[(wt << 1) + 1]);
28096            tcg_gen_setcondi_i64((op1 == OPC_BZ_V) ?
28097                    TCG_COND_EQ : TCG_COND_NE, t0, t0, 0);
28098            tcg_gen_trunc_i64_tl(bcond, t0);
28099            tcg_temp_free_i64(t0);
28100        }
28101        break;
28102    case OPC_BZ_B:
28103    case OPC_BZ_H:
28104    case OPC_BZ_W:
28105    case OPC_BZ_D:
28106        gen_check_zero_element(bcond, df, wt);
28107        break;
28108    case OPC_BNZ_B:
28109    case OPC_BNZ_H:
28110    case OPC_BNZ_W:
28111    case OPC_BNZ_D:
28112        gen_check_zero_element(bcond, df, wt);
28113        tcg_gen_setcondi_tl(TCG_COND_EQ, bcond, bcond, 0);
28114        break;
28115    }
28116
28117    ctx->btarget = ctx->base.pc_next + (s16 << 2) + 4;
28118
28119    ctx->hflags |= MIPS_HFLAG_BC;
28120    ctx->hflags |= MIPS_HFLAG_BDS32;
28121}
28122
28123static void gen_msa_i8(CPUMIPSState *env, DisasContext *ctx)
28124{
28125#define MASK_MSA_I8(op)    (MASK_MSA_MINOR(op) | (op & (0x03 << 24)))
28126    uint8_t i8 = (ctx->opcode >> 16) & 0xff;
28127    uint8_t ws = (ctx->opcode >> 11) & 0x1f;
28128    uint8_t wd = (ctx->opcode >> 6) & 0x1f;
28129
28130    TCGv_i32 twd = tcg_const_i32(wd);
28131    TCGv_i32 tws = tcg_const_i32(ws);
28132    TCGv_i32 ti8 = tcg_const_i32(i8);
28133
28134    switch (MASK_MSA_I8(ctx->opcode)) {
28135    case OPC_ANDI_B:
28136        gen_helper_msa_andi_b(cpu_env, twd, tws, ti8);
28137        break;
28138    case OPC_ORI_B:
28139        gen_helper_msa_ori_b(cpu_env, twd, tws, ti8);
28140        break;
28141    case OPC_NORI_B:
28142        gen_helper_msa_nori_b(cpu_env, twd, tws, ti8);
28143        break;
28144    case OPC_XORI_B:
28145        gen_helper_msa_xori_b(cpu_env, twd, tws, ti8);
28146        break;
28147    case OPC_BMNZI_B:
28148        gen_helper_msa_bmnzi_b(cpu_env, twd, tws, ti8);
28149        break;
28150    case OPC_BMZI_B:
28151        gen_helper_msa_bmzi_b(cpu_env, twd, tws, ti8);
28152        break;
28153    case OPC_BSELI_B:
28154        gen_helper_msa_bseli_b(cpu_env, twd, tws, ti8);
28155        break;
28156    case OPC_SHF_B:
28157    case OPC_SHF_H:
28158    case OPC_SHF_W:
28159        {
28160            uint8_t df = (ctx->opcode >> 24) & 0x3;
28161            if (df == DF_DOUBLE) {
28162                generate_exception_end(ctx, EXCP_RI);
28163            } else {
28164                TCGv_i32 tdf = tcg_const_i32(df);
28165                gen_helper_msa_shf_df(cpu_env, tdf, twd, tws, ti8);
28166                tcg_temp_free_i32(tdf);
28167            }
28168        }
28169        break;
28170    default:
28171        MIPS_INVAL("MSA instruction");
28172        generate_exception_end(ctx, EXCP_RI);
28173        break;
28174    }
28175
28176    tcg_temp_free_i32(twd);
28177    tcg_temp_free_i32(tws);
28178    tcg_temp_free_i32(ti8);
28179}
28180
28181static void gen_msa_i5(CPUMIPSState *env, DisasContext *ctx)
28182{
28183#define MASK_MSA_I5(op)    (MASK_MSA_MINOR(op) | (op & (0x7 << 23)))
28184    uint8_t df = (ctx->opcode >> 21) & 0x3;
28185    int8_t s5 = (int8_t) sextract32(ctx->opcode, 16, 5);
28186    uint8_t u5 = (ctx->opcode >> 16) & 0x1f;
28187    uint8_t ws = (ctx->opcode >> 11) & 0x1f;
28188    uint8_t wd = (ctx->opcode >> 6) & 0x1f;
28189
28190    TCGv_i32 tdf = tcg_const_i32(df);
28191    TCGv_i32 twd = tcg_const_i32(wd);
28192    TCGv_i32 tws = tcg_const_i32(ws);
28193    TCGv_i32 timm = tcg_temp_new_i32();
28194    tcg_gen_movi_i32(timm, u5);
28195
28196    switch (MASK_MSA_I5(ctx->opcode)) {
28197    case OPC_ADDVI_df:
28198        gen_helper_msa_addvi_df(cpu_env, tdf, twd, tws, timm);
28199        break;
28200    case OPC_SUBVI_df:
28201        gen_helper_msa_subvi_df(cpu_env, tdf, twd, tws, timm);
28202        break;
28203    case OPC_MAXI_S_df:
28204        tcg_gen_movi_i32(timm, s5);
28205        gen_helper_msa_maxi_s_df(cpu_env, tdf, twd, tws, timm);
28206        break;
28207    case OPC_MAXI_U_df:
28208        gen_helper_msa_maxi_u_df(cpu_env, tdf, twd, tws, timm);
28209        break;
28210    case OPC_MINI_S_df:
28211        tcg_gen_movi_i32(timm, s5);
28212        gen_helper_msa_mini_s_df(cpu_env, tdf, twd, tws, timm);
28213        break;
28214    case OPC_MINI_U_df:
28215        gen_helper_msa_mini_u_df(cpu_env, tdf, twd, tws, timm);
28216        break;
28217    case OPC_CEQI_df:
28218        tcg_gen_movi_i32(timm, s5);
28219        gen_helper_msa_ceqi_df(cpu_env, tdf, twd, tws, timm);
28220        break;
28221    case OPC_CLTI_S_df:
28222        tcg_gen_movi_i32(timm, s5);
28223        gen_helper_msa_clti_s_df(cpu_env, tdf, twd, tws, timm);
28224        break;
28225    case OPC_CLTI_U_df:
28226        gen_helper_msa_clti_u_df(cpu_env, tdf, twd, tws, timm);
28227        break;
28228    case OPC_CLEI_S_df:
28229        tcg_gen_movi_i32(timm, s5);
28230        gen_helper_msa_clei_s_df(cpu_env, tdf, twd, tws, timm);
28231        break;
28232    case OPC_CLEI_U_df:
28233        gen_helper_msa_clei_u_df(cpu_env, tdf, twd, tws, timm);
28234        break;
28235    case OPC_LDI_df:
28236        {
28237            int32_t s10 = sextract32(ctx->opcode, 11, 10);
28238            tcg_gen_movi_i32(timm, s10);
28239            gen_helper_msa_ldi_df(cpu_env, tdf, twd, timm);
28240        }
28241        break;
28242    default:
28243        MIPS_INVAL("MSA instruction");
28244        generate_exception_end(ctx, EXCP_RI);
28245        break;
28246    }
28247
28248    tcg_temp_free_i32(tdf);
28249    tcg_temp_free_i32(twd);
28250    tcg_temp_free_i32(tws);
28251    tcg_temp_free_i32(timm);
28252}
28253
28254static void gen_msa_bit(CPUMIPSState *env, DisasContext *ctx)
28255{
28256#define MASK_MSA_BIT(op)    (MASK_MSA_MINOR(op) | (op & (0x7 << 23)))
28257    uint8_t dfm = (ctx->opcode >> 16) & 0x7f;
28258    uint32_t df = 0, m = 0;
28259    uint8_t ws = (ctx->opcode >> 11) & 0x1f;
28260    uint8_t wd = (ctx->opcode >> 6) & 0x1f;
28261
28262    TCGv_i32 tdf;
28263    TCGv_i32 tm;
28264    TCGv_i32 twd;
28265    TCGv_i32 tws;
28266
28267    if ((dfm & 0x40) == 0x00) {
28268        m = dfm & 0x3f;
28269        df = DF_DOUBLE;
28270    } else if ((dfm & 0x60) == 0x40) {
28271        m = dfm & 0x1f;
28272        df = DF_WORD;
28273    } else if ((dfm & 0x70) == 0x60) {
28274        m = dfm & 0x0f;
28275        df = DF_HALF;
28276    } else if ((dfm & 0x78) == 0x70) {
28277        m = dfm & 0x7;
28278        df = DF_BYTE;
28279    } else {
28280        generate_exception_end(ctx, EXCP_RI);
28281        return;
28282    }
28283
28284    tdf = tcg_const_i32(df);
28285    tm  = tcg_const_i32(m);
28286    twd = tcg_const_i32(wd);
28287    tws = tcg_const_i32(ws);
28288
28289    switch (MASK_MSA_BIT(ctx->opcode)) {
28290    case OPC_SLLI_df:
28291        gen_helper_msa_slli_df(cpu_env, tdf, twd, tws, tm);
28292        break;
28293    case OPC_SRAI_df:
28294        gen_helper_msa_srai_df(cpu_env, tdf, twd, tws, tm);
28295        break;
28296    case OPC_SRLI_df:
28297        gen_helper_msa_srli_df(cpu_env, tdf, twd, tws, tm);
28298        break;
28299    case OPC_BCLRI_df:
28300        gen_helper_msa_bclri_df(cpu_env, tdf, twd, tws, tm);
28301        break;
28302    case OPC_BSETI_df:
28303        gen_helper_msa_bseti_df(cpu_env, tdf, twd, tws, tm);
28304        break;
28305    case OPC_BNEGI_df:
28306        gen_helper_msa_bnegi_df(cpu_env, tdf, twd, tws, tm);
28307        break;
28308    case OPC_BINSLI_df:
28309        gen_helper_msa_binsli_df(cpu_env, tdf, twd, tws, tm);
28310        break;
28311    case OPC_BINSRI_df:
28312        gen_helper_msa_binsri_df(cpu_env, tdf, twd, tws, tm);
28313        break;
28314    case OPC_SAT_S_df:
28315        gen_helper_msa_sat_s_df(cpu_env, tdf, twd, tws, tm);
28316        break;
28317    case OPC_SAT_U_df:
28318        gen_helper_msa_sat_u_df(cpu_env, tdf, twd, tws, tm);
28319        break;
28320    case OPC_SRARI_df:
28321        gen_helper_msa_srari_df(cpu_env, tdf, twd, tws, tm);
28322        break;
28323    case OPC_SRLRI_df:
28324        gen_helper_msa_srlri_df(cpu_env, tdf, twd, tws, tm);
28325        break;
28326    default:
28327        MIPS_INVAL("MSA instruction");
28328        generate_exception_end(ctx, EXCP_RI);
28329        break;
28330    }
28331
28332    tcg_temp_free_i32(tdf);
28333    tcg_temp_free_i32(tm);
28334    tcg_temp_free_i32(twd);
28335    tcg_temp_free_i32(tws);
28336}
28337
28338static void gen_msa_3r(CPUMIPSState *env, DisasContext *ctx)
28339{
28340#define MASK_MSA_3R(op)    (MASK_MSA_MINOR(op) | (op & (0x7 << 23)))
28341    uint8_t df = (ctx->opcode >> 21) & 0x3;
28342    uint8_t wt = (ctx->opcode >> 16) & 0x1f;
28343    uint8_t ws = (ctx->opcode >> 11) & 0x1f;
28344    uint8_t wd = (ctx->opcode >> 6) & 0x1f;
28345
28346    TCGv_i32 tdf = tcg_const_i32(df);
28347    TCGv_i32 twd = tcg_const_i32(wd);
28348    TCGv_i32 tws = tcg_const_i32(ws);
28349    TCGv_i32 twt = tcg_const_i32(wt);
28350
28351    switch (MASK_MSA_3R(ctx->opcode)) {
28352    case OPC_SLL_df:
28353        gen_helper_msa_sll_df(cpu_env, tdf, twd, tws, twt);
28354        break;
28355    case OPC_ADDV_df:
28356        gen_helper_msa_addv_df(cpu_env, tdf, twd, tws, twt);
28357        break;
28358    case OPC_CEQ_df:
28359        gen_helper_msa_ceq_df(cpu_env, tdf, twd, tws, twt);
28360        break;
28361    case OPC_ADD_A_df:
28362        gen_helper_msa_add_a_df(cpu_env, tdf, twd, tws, twt);
28363        break;
28364    case OPC_SUBS_S_df:
28365        gen_helper_msa_subs_s_df(cpu_env, tdf, twd, tws, twt);
28366        break;
28367    case OPC_MULV_df:
28368        gen_helper_msa_mulv_df(cpu_env, tdf, twd, tws, twt);
28369        break;
28370    case OPC_SLD_df:
28371        gen_helper_msa_sld_df(cpu_env, tdf, twd, tws, twt);
28372        break;
28373    case OPC_VSHF_df:
28374        gen_helper_msa_vshf_df(cpu_env, tdf, twd, tws, twt);
28375        break;
28376    case OPC_SRA_df:
28377        gen_helper_msa_sra_df(cpu_env, tdf, twd, tws, twt);
28378        break;
28379    case OPC_SUBV_df:
28380        gen_helper_msa_subv_df(cpu_env, tdf, twd, tws, twt);
28381        break;
28382    case OPC_ADDS_A_df:
28383        gen_helper_msa_adds_a_df(cpu_env, tdf, twd, tws, twt);
28384        break;
28385    case OPC_SUBS_U_df:
28386        gen_helper_msa_subs_u_df(cpu_env, tdf, twd, tws, twt);
28387        break;
28388    case OPC_MADDV_df:
28389        gen_helper_msa_maddv_df(cpu_env, tdf, twd, tws, twt);
28390        break;
28391    case OPC_SPLAT_df:
28392        gen_helper_msa_splat_df(cpu_env, tdf, twd, tws, twt);
28393        break;
28394    case OPC_SRAR_df:
28395        gen_helper_msa_srar_df(cpu_env, tdf, twd, tws, twt);
28396        break;
28397    case OPC_SRL_df:
28398        gen_helper_msa_srl_df(cpu_env, tdf, twd, tws, twt);
28399        break;
28400    case OPC_MAX_S_df:
28401        gen_helper_msa_max_s_df(cpu_env, tdf, twd, tws, twt);
28402        break;
28403    case OPC_CLT_S_df:
28404        gen_helper_msa_clt_s_df(cpu_env, tdf, twd, tws, twt);
28405        break;
28406    case OPC_ADDS_S_df:
28407        gen_helper_msa_adds_s_df(cpu_env, tdf, twd, tws, twt);
28408        break;
28409    case OPC_SUBSUS_U_df:
28410        gen_helper_msa_subsus_u_df(cpu_env, tdf, twd, tws, twt);
28411        break;
28412    case OPC_MSUBV_df:
28413        gen_helper_msa_msubv_df(cpu_env, tdf, twd, tws, twt);
28414        break;
28415    case OPC_PCKEV_df:
28416        gen_helper_msa_pckev_df(cpu_env, tdf, twd, tws, twt);
28417        break;
28418    case OPC_SRLR_df:
28419        gen_helper_msa_srlr_df(cpu_env, tdf, twd, tws, twt);
28420        break;
28421    case OPC_BCLR_df:
28422        gen_helper_msa_bclr_df(cpu_env, tdf, twd, tws, twt);
28423        break;
28424    case OPC_MAX_U_df:
28425        gen_helper_msa_max_u_df(cpu_env, tdf, twd, tws, twt);
28426        break;
28427    case OPC_CLT_U_df:
28428        gen_helper_msa_clt_u_df(cpu_env, tdf, twd, tws, twt);
28429        break;
28430    case OPC_ADDS_U_df:
28431        gen_helper_msa_adds_u_df(cpu_env, tdf, twd, tws, twt);
28432        break;
28433    case OPC_SUBSUU_S_df:
28434        gen_helper_msa_subsuu_s_df(cpu_env, tdf, twd, tws, twt);
28435        break;
28436    case OPC_PCKOD_df:
28437        gen_helper_msa_pckod_df(cpu_env, tdf, twd, tws, twt);
28438        break;
28439    case OPC_BSET_df:
28440        gen_helper_msa_bset_df(cpu_env, tdf, twd, tws, twt);
28441        break;
28442    case OPC_MIN_S_df:
28443        gen_helper_msa_min_s_df(cpu_env, tdf, twd, tws, twt);
28444        break;
28445    case OPC_CLE_S_df:
28446        gen_helper_msa_cle_s_df(cpu_env, tdf, twd, tws, twt);
28447        break;
28448    case OPC_AVE_S_df:
28449        gen_helper_msa_ave_s_df(cpu_env, tdf, twd, tws, twt);
28450        break;
28451    case OPC_ASUB_S_df:
28452        gen_helper_msa_asub_s_df(cpu_env, tdf, twd, tws, twt);
28453        break;
28454    case OPC_DIV_S_df:
28455        gen_helper_msa_div_s_df(cpu_env, tdf, twd, tws, twt);
28456        break;
28457    case OPC_ILVL_df:
28458        gen_helper_msa_ilvl_df(cpu_env, tdf, twd, tws, twt);
28459        break;
28460    case OPC_BNEG_df:
28461        gen_helper_msa_bneg_df(cpu_env, tdf, twd, tws, twt);
28462        break;
28463    case OPC_MIN_U_df:
28464        gen_helper_msa_min_u_df(cpu_env, tdf, twd, tws, twt);
28465        break;
28466    case OPC_CLE_U_df:
28467        gen_helper_msa_cle_u_df(cpu_env, tdf, twd, tws, twt);
28468        break;
28469    case OPC_AVE_U_df:
28470        gen_helper_msa_ave_u_df(cpu_env, tdf, twd, tws, twt);
28471        break;
28472    case OPC_ASUB_U_df:
28473        gen_helper_msa_asub_u_df(cpu_env, tdf, twd, tws, twt);
28474        break;
28475    case OPC_DIV_U_df:
28476        gen_helper_msa_div_u_df(cpu_env, tdf, twd, tws, twt);
28477        break;
28478    case OPC_ILVR_df:
28479        gen_helper_msa_ilvr_df(cpu_env, tdf, twd, tws, twt);
28480        break;
28481    case OPC_BINSL_df:
28482        gen_helper_msa_binsl_df(cpu_env, tdf, twd, tws, twt);
28483        break;
28484    case OPC_MAX_A_df:
28485        gen_helper_msa_max_a_df(cpu_env, tdf, twd, tws, twt);
28486        break;
28487    case OPC_AVER_S_df:
28488        gen_helper_msa_aver_s_df(cpu_env, tdf, twd, tws, twt);
28489        break;
28490    case OPC_MOD_S_df:
28491        gen_helper_msa_mod_s_df(cpu_env, tdf, twd, tws, twt);
28492        break;
28493    case OPC_ILVEV_df:
28494        gen_helper_msa_ilvev_df(cpu_env, tdf, twd, tws, twt);
28495        break;
28496    case OPC_BINSR_df:
28497        gen_helper_msa_binsr_df(cpu_env, tdf, twd, tws, twt);
28498        break;
28499    case OPC_MIN_A_df:
28500        gen_helper_msa_min_a_df(cpu_env, tdf, twd, tws, twt);
28501        break;
28502    case OPC_AVER_U_df:
28503        gen_helper_msa_aver_u_df(cpu_env, tdf, twd, tws, twt);
28504        break;
28505    case OPC_MOD_U_df:
28506        gen_helper_msa_mod_u_df(cpu_env, tdf, twd, tws, twt);
28507        break;
28508    case OPC_ILVOD_df:
28509        gen_helper_msa_ilvod_df(cpu_env, tdf, twd, tws, twt);
28510        break;
28511
28512    case OPC_DOTP_S_df:
28513    case OPC_DOTP_U_df:
28514    case OPC_DPADD_S_df:
28515    case OPC_DPADD_U_df:
28516    case OPC_DPSUB_S_df:
28517    case OPC_HADD_S_df:
28518    case OPC_DPSUB_U_df:
28519    case OPC_HADD_U_df:
28520    case OPC_HSUB_S_df:
28521    case OPC_HSUB_U_df:
28522        if (df == DF_BYTE) {
28523            generate_exception_end(ctx, EXCP_RI);
28524            break;
28525        }
28526        switch (MASK_MSA_3R(ctx->opcode)) {
28527        case OPC_DOTP_S_df:
28528            gen_helper_msa_dotp_s_df(cpu_env, tdf, twd, tws, twt);
28529            break;
28530        case OPC_DOTP_U_df:
28531            gen_helper_msa_dotp_u_df(cpu_env, tdf, twd, tws, twt);
28532            break;
28533        case OPC_DPADD_S_df:
28534            gen_helper_msa_dpadd_s_df(cpu_env, tdf, twd, tws, twt);
28535            break;
28536        case OPC_DPADD_U_df:
28537            gen_helper_msa_dpadd_u_df(cpu_env, tdf, twd, tws, twt);
28538            break;
28539        case OPC_DPSUB_S_df:
28540            gen_helper_msa_dpsub_s_df(cpu_env, tdf, twd, tws, twt);
28541            break;
28542        case OPC_HADD_S_df:
28543            gen_helper_msa_hadd_s_df(cpu_env, tdf, twd, tws, twt);
28544            break;
28545        case OPC_DPSUB_U_df:
28546            gen_helper_msa_dpsub_u_df(cpu_env, tdf, twd, tws, twt);
28547            break;
28548        case OPC_HADD_U_df:
28549            gen_helper_msa_hadd_u_df(cpu_env, tdf, twd, tws, twt);
28550            break;
28551        case OPC_HSUB_S_df:
28552            gen_helper_msa_hsub_s_df(cpu_env, tdf, twd, tws, twt);
28553            break;
28554        case OPC_HSUB_U_df:
28555            gen_helper_msa_hsub_u_df(cpu_env, tdf, twd, tws, twt);
28556            break;
28557        }
28558        break;
28559    default:
28560        MIPS_INVAL("MSA instruction");
28561        generate_exception_end(ctx, EXCP_RI);
28562        break;
28563    }
28564    tcg_temp_free_i32(twd);
28565    tcg_temp_free_i32(tws);
28566    tcg_temp_free_i32(twt);
28567    tcg_temp_free_i32(tdf);
28568}
28569
28570static void gen_msa_elm_3e(CPUMIPSState *env, DisasContext *ctx)
28571{
28572#define MASK_MSA_ELM_DF3E(op)   (MASK_MSA_MINOR(op) | (op & (0x3FF << 16)))
28573    uint8_t source = (ctx->opcode >> 11) & 0x1f;
28574    uint8_t dest = (ctx->opcode >> 6) & 0x1f;
28575    TCGv telm = tcg_temp_new();
28576    TCGv_i32 tsr = tcg_const_i32(source);
28577    TCGv_i32 tdt = tcg_const_i32(dest);
28578
28579    switch (MASK_MSA_ELM_DF3E(ctx->opcode)) {
28580    case OPC_CTCMSA:
28581        gen_load_gpr(telm, source);
28582        gen_helper_msa_ctcmsa(cpu_env, telm, tdt);
28583        break;
28584    case OPC_CFCMSA:
28585        gen_helper_msa_cfcmsa(telm, cpu_env, tsr);
28586        gen_store_gpr(telm, dest);
28587        break;
28588    case OPC_MOVE_V:
28589        gen_helper_msa_move_v(cpu_env, tdt, tsr);
28590        break;
28591    default:
28592        MIPS_INVAL("MSA instruction");
28593        generate_exception_end(ctx, EXCP_RI);
28594        break;
28595    }
28596
28597    tcg_temp_free(telm);
28598    tcg_temp_free_i32(tdt);
28599    tcg_temp_free_i32(tsr);
28600}
28601
28602static void gen_msa_elm_df(CPUMIPSState *env, DisasContext *ctx, uint32_t df,
28603        uint32_t n)
28604{
28605#define MASK_MSA_ELM(op)    (MASK_MSA_MINOR(op) | (op & (0xf << 22)))
28606    uint8_t ws = (ctx->opcode >> 11) & 0x1f;
28607    uint8_t wd = (ctx->opcode >> 6) & 0x1f;
28608
28609    TCGv_i32 tws = tcg_const_i32(ws);
28610    TCGv_i32 twd = tcg_const_i32(wd);
28611    TCGv_i32 tn  = tcg_const_i32(n);
28612    TCGv_i32 tdf = tcg_const_i32(df);
28613
28614    switch (MASK_MSA_ELM(ctx->opcode)) {
28615    case OPC_SLDI_df:
28616        gen_helper_msa_sldi_df(cpu_env, tdf, twd, tws, tn);
28617        break;
28618    case OPC_SPLATI_df:
28619        gen_helper_msa_splati_df(cpu_env, tdf, twd, tws, tn);
28620        break;
28621    case OPC_INSVE_df:
28622        gen_helper_msa_insve_df(cpu_env, tdf, twd, tws, tn);
28623        break;
28624    case OPC_COPY_S_df:
28625    case OPC_COPY_U_df:
28626    case OPC_INSERT_df:
28627#if !defined(TARGET_MIPS64)
28628        /* Double format valid only for MIPS64 */
28629        if (df == DF_DOUBLE) {
28630            generate_exception_end(ctx, EXCP_RI);
28631            break;
28632        }
28633        if ((MASK_MSA_ELM(ctx->opcode) == OPC_COPY_U_df) &&
28634              (df == DF_WORD)) {
28635            generate_exception_end(ctx, EXCP_RI);
28636            break;
28637        }
28638#endif
28639        switch (MASK_MSA_ELM(ctx->opcode)) {
28640        case OPC_COPY_S_df:
28641            if (likely(wd != 0)) {
28642                switch (df) {
28643                case DF_BYTE:
28644                    gen_helper_msa_copy_s_b(cpu_env, twd, tws, tn);
28645                    break;
28646                case DF_HALF:
28647                    gen_helper_msa_copy_s_h(cpu_env, twd, tws, tn);
28648                    break;
28649                case DF_WORD:
28650                    gen_helper_msa_copy_s_w(cpu_env, twd, tws, tn);
28651                    break;
28652#if defined(TARGET_MIPS64)
28653                case DF_DOUBLE:
28654                    gen_helper_msa_copy_s_d(cpu_env, twd, tws, tn);
28655                    break;
28656#endif
28657                default:
28658                    assert(0);
28659                }
28660            }
28661            break;
28662        case OPC_COPY_U_df:
28663            if (likely(wd != 0)) {
28664                switch (df) {
28665                case DF_BYTE:
28666                    gen_helper_msa_copy_u_b(cpu_env, twd, tws, tn);
28667                    break;
28668                case DF_HALF:
28669                    gen_helper_msa_copy_u_h(cpu_env, twd, tws, tn);
28670                    break;
28671#if defined(TARGET_MIPS64)
28672                case DF_WORD:
28673                    gen_helper_msa_copy_u_w(cpu_env, twd, tws, tn);
28674                    break;
28675#endif
28676                default:
28677                    assert(0);
28678                }
28679            }
28680            break;
28681        case OPC_INSERT_df:
28682            switch (df) {
28683            case DF_BYTE:
28684                gen_helper_msa_insert_b(cpu_env, twd, tws, tn);
28685                break;
28686            case DF_HALF:
28687                gen_helper_msa_insert_h(cpu_env, twd, tws, tn);
28688                break;
28689            case DF_WORD:
28690                gen_helper_msa_insert_w(cpu_env, twd, tws, tn);
28691                break;
28692#if defined(TARGET_MIPS64)
28693            case DF_DOUBLE:
28694                gen_helper_msa_insert_d(cpu_env, twd, tws, tn);
28695                break;
28696#endif
28697            default:
28698                assert(0);
28699            }
28700            break;
28701        }
28702        break;
28703    default:
28704        MIPS_INVAL("MSA instruction");
28705        generate_exception_end(ctx, EXCP_RI);
28706    }
28707    tcg_temp_free_i32(twd);
28708    tcg_temp_free_i32(tws);
28709    tcg_temp_free_i32(tn);
28710    tcg_temp_free_i32(tdf);
28711}
28712
28713static void gen_msa_elm(CPUMIPSState *env, DisasContext *ctx)
28714{
28715    uint8_t dfn = (ctx->opcode >> 16) & 0x3f;
28716    uint32_t df = 0, n = 0;
28717
28718    if ((dfn & 0x30) == 0x00) {
28719        n = dfn & 0x0f;
28720        df = DF_BYTE;
28721    } else if ((dfn & 0x38) == 0x20) {
28722        n = dfn & 0x07;
28723        df = DF_HALF;
28724    } else if ((dfn & 0x3c) == 0x30) {
28725        n = dfn & 0x03;
28726        df = DF_WORD;
28727    } else if ((dfn & 0x3e) == 0x38) {
28728        n = dfn & 0x01;
28729        df = DF_DOUBLE;
28730    } else if (dfn == 0x3E) {
28731        /* CTCMSA, CFCMSA, MOVE.V */
28732        gen_msa_elm_3e(env, ctx);
28733        return;
28734    } else {
28735        generate_exception_end(ctx, EXCP_RI);
28736        return;
28737    }
28738
28739    gen_msa_elm_df(env, ctx, df, n);
28740}
28741
28742static void gen_msa_3rf(CPUMIPSState *env, DisasContext *ctx)
28743{
28744#define MASK_MSA_3RF(op)    (MASK_MSA_MINOR(op) | (op & (0xf << 22)))
28745    uint8_t df = (ctx->opcode >> 21) & 0x1;
28746    uint8_t wt = (ctx->opcode >> 16) & 0x1f;
28747    uint8_t ws = (ctx->opcode >> 11) & 0x1f;
28748    uint8_t wd = (ctx->opcode >> 6) & 0x1f;
28749
28750    TCGv_i32 twd = tcg_const_i32(wd);
28751    TCGv_i32 tws = tcg_const_i32(ws);
28752    TCGv_i32 twt = tcg_const_i32(wt);
28753    TCGv_i32 tdf = tcg_temp_new_i32();
28754
28755    /* adjust df value for floating-point instruction */
28756    tcg_gen_movi_i32(tdf, df + 2);
28757
28758    switch (MASK_MSA_3RF(ctx->opcode)) {
28759    case OPC_FCAF_df:
28760        gen_helper_msa_fcaf_df(cpu_env, tdf, twd, tws, twt);
28761        break;
28762    case OPC_FADD_df:
28763        gen_helper_msa_fadd_df(cpu_env, tdf, twd, tws, twt);
28764        break;
28765    case OPC_FCUN_df:
28766        gen_helper_msa_fcun_df(cpu_env, tdf, twd, tws, twt);
28767        break;
28768    case OPC_FSUB_df:
28769        gen_helper_msa_fsub_df(cpu_env, tdf, twd, tws, twt);
28770        break;
28771    case OPC_FCOR_df:
28772        gen_helper_msa_fcor_df(cpu_env, tdf, twd, tws, twt);
28773        break;
28774    case OPC_FCEQ_df:
28775        gen_helper_msa_fceq_df(cpu_env, tdf, twd, tws, twt);
28776        break;
28777    case OPC_FMUL_df:
28778        gen_helper_msa_fmul_df(cpu_env, tdf, twd, tws, twt);
28779        break;
28780    case OPC_FCUNE_df:
28781        gen_helper_msa_fcune_df(cpu_env, tdf, twd, tws, twt);
28782        break;
28783    case OPC_FCUEQ_df:
28784        gen_helper_msa_fcueq_df(cpu_env, tdf, twd, tws, twt);
28785        break;
28786    case OPC_FDIV_df:
28787        gen_helper_msa_fdiv_df(cpu_env, tdf, twd, tws, twt);
28788        break;
28789    case OPC_FCNE_df:
28790        gen_helper_msa_fcne_df(cpu_env, tdf, twd, tws, twt);
28791        break;
28792    case OPC_FCLT_df:
28793        gen_helper_msa_fclt_df(cpu_env, tdf, twd, tws, twt);
28794        break;
28795    case OPC_FMADD_df:
28796        gen_helper_msa_fmadd_df(cpu_env, tdf, twd, tws, twt);
28797        break;
28798    case OPC_MUL_Q_df:
28799        tcg_gen_movi_i32(tdf, df + 1);
28800        gen_helper_msa_mul_q_df(cpu_env, tdf, twd, tws, twt);
28801        break;
28802    case OPC_FCULT_df:
28803        gen_helper_msa_fcult_df(cpu_env, tdf, twd, tws, twt);
28804        break;
28805    case OPC_FMSUB_df:
28806        gen_helper_msa_fmsub_df(cpu_env, tdf, twd, tws, twt);
28807        break;
28808    case OPC_MADD_Q_df:
28809        tcg_gen_movi_i32(tdf, df + 1);
28810        gen_helper_msa_madd_q_df(cpu_env, tdf, twd, tws, twt);
28811        break;
28812    case OPC_FCLE_df:
28813        gen_helper_msa_fcle_df(cpu_env, tdf, twd, tws, twt);
28814        break;
28815    case OPC_MSUB_Q_df:
28816        tcg_gen_movi_i32(tdf, df + 1);
28817        gen_helper_msa_msub_q_df(cpu_env, tdf, twd, tws, twt);
28818        break;
28819    case OPC_FCULE_df:
28820        gen_helper_msa_fcule_df(cpu_env, tdf, twd, tws, twt);
28821        break;
28822    case OPC_FEXP2_df:
28823        gen_helper_msa_fexp2_df(cpu_env, tdf, twd, tws, twt);
28824        break;
28825    case OPC_FSAF_df:
28826        gen_helper_msa_fsaf_df(cpu_env, tdf, twd, tws, twt);
28827        break;
28828    case OPC_FEXDO_df:
28829        gen_helper_msa_fexdo_df(cpu_env, tdf, twd, tws, twt);
28830        break;
28831    case OPC_FSUN_df:
28832        gen_helper_msa_fsun_df(cpu_env, tdf, twd, tws, twt);
28833        break;
28834    case OPC_FSOR_df:
28835        gen_helper_msa_fsor_df(cpu_env, tdf, twd, tws, twt);
28836        break;
28837    case OPC_FSEQ_df:
28838        gen_helper_msa_fseq_df(cpu_env, tdf, twd, tws, twt);
28839        break;
28840    case OPC_FTQ_df:
28841        gen_helper_msa_ftq_df(cpu_env, tdf, twd, tws, twt);
28842        break;
28843    case OPC_FSUNE_df:
28844        gen_helper_msa_fsune_df(cpu_env, tdf, twd, tws, twt);
28845        break;
28846    case OPC_FSUEQ_df:
28847        gen_helper_msa_fsueq_df(cpu_env, tdf, twd, tws, twt);
28848        break;
28849    case OPC_FSNE_df:
28850        gen_helper_msa_fsne_df(cpu_env, tdf, twd, tws, twt);
28851        break;
28852    case OPC_FSLT_df:
28853        gen_helper_msa_fslt_df(cpu_env, tdf, twd, tws, twt);
28854        break;
28855    case OPC_FMIN_df:
28856        gen_helper_msa_fmin_df(cpu_env, tdf, twd, tws, twt);
28857        break;
28858    case OPC_MULR_Q_df:
28859        tcg_gen_movi_i32(tdf, df + 1);
28860        gen_helper_msa_mulr_q_df(cpu_env, tdf, twd, tws, twt);
28861        break;
28862    case OPC_FSULT_df:
28863        gen_helper_msa_fsult_df(cpu_env, tdf, twd, tws, twt);
28864        break;
28865    case OPC_FMIN_A_df:
28866        gen_helper_msa_fmin_a_df(cpu_env, tdf, twd, tws, twt);
28867        break;
28868    case OPC_MADDR_Q_df:
28869        tcg_gen_movi_i32(tdf, df + 1);
28870        gen_helper_msa_maddr_q_df(cpu_env, tdf, twd, tws, twt);
28871        break;
28872    case OPC_FSLE_df:
28873        gen_helper_msa_fsle_df(cpu_env, tdf, twd, tws, twt);
28874        break;
28875    case OPC_FMAX_df:
28876        gen_helper_msa_fmax_df(cpu_env, tdf, twd, tws, twt);
28877        break;
28878    case OPC_MSUBR_Q_df:
28879        tcg_gen_movi_i32(tdf, df + 1);
28880        gen_helper_msa_msubr_q_df(cpu_env, tdf, twd, tws, twt);
28881        break;
28882    case OPC_FSULE_df:
28883        gen_helper_msa_fsule_df(cpu_env, tdf, twd, tws, twt);
28884        break;
28885    case OPC_FMAX_A_df:
28886        gen_helper_msa_fmax_a_df(cpu_env, tdf, twd, tws, twt);
28887        break;
28888    default:
28889        MIPS_INVAL("MSA instruction");
28890        generate_exception_end(ctx, EXCP_RI);
28891        break;
28892    }
28893
28894    tcg_temp_free_i32(twd);
28895    tcg_temp_free_i32(tws);
28896    tcg_temp_free_i32(twt);
28897    tcg_temp_free_i32(tdf);
28898}
28899
28900static void gen_msa_2r(CPUMIPSState *env, DisasContext *ctx)
28901{
28902#define MASK_MSA_2R(op)     (MASK_MSA_MINOR(op) | (op & (0x1f << 21)) | \
28903                            (op & (0x7 << 18)))
28904    uint8_t wt = (ctx->opcode >> 16) & 0x1f;
28905    uint8_t ws = (ctx->opcode >> 11) & 0x1f;
28906    uint8_t wd = (ctx->opcode >> 6) & 0x1f;
28907    uint8_t df = (ctx->opcode >> 16) & 0x3;
28908    TCGv_i32 twd = tcg_const_i32(wd);
28909    TCGv_i32 tws = tcg_const_i32(ws);
28910    TCGv_i32 twt = tcg_const_i32(wt);
28911    TCGv_i32 tdf = tcg_const_i32(df);
28912
28913    switch (MASK_MSA_2R(ctx->opcode)) {
28914    case OPC_FILL_df:
28915#if !defined(TARGET_MIPS64)
28916        /* Double format valid only for MIPS64 */
28917        if (df == DF_DOUBLE) {
28918            generate_exception_end(ctx, EXCP_RI);
28919            break;
28920        }
28921#endif
28922        gen_helper_msa_fill_df(cpu_env, tdf, twd, tws); /* trs */
28923        break;
28924    case OPC_PCNT_df:
28925        gen_helper_msa_pcnt_df(cpu_env, tdf, twd, tws);
28926        break;
28927    case OPC_NLOC_df:
28928        gen_helper_msa_nloc_df(cpu_env, tdf, twd, tws);
28929        break;
28930    case OPC_NLZC_df:
28931        gen_helper_msa_nlzc_df(cpu_env, tdf, twd, tws);
28932        break;
28933    default:
28934        MIPS_INVAL("MSA instruction");
28935        generate_exception_end(ctx, EXCP_RI);
28936        break;
28937    }
28938
28939    tcg_temp_free_i32(twd);
28940    tcg_temp_free_i32(tws);
28941    tcg_temp_free_i32(twt);
28942    tcg_temp_free_i32(tdf);
28943}
28944
28945static void gen_msa_2rf(CPUMIPSState *env, DisasContext *ctx)
28946{
28947#define MASK_MSA_2RF(op)    (MASK_MSA_MINOR(op) | (op & (0x1f << 21)) | \
28948                            (op & (0xf << 17)))
28949    uint8_t wt = (ctx->opcode >> 16) & 0x1f;
28950    uint8_t ws = (ctx->opcode >> 11) & 0x1f;
28951    uint8_t wd = (ctx->opcode >> 6) & 0x1f;
28952    uint8_t df = (ctx->opcode >> 16) & 0x1;
28953    TCGv_i32 twd = tcg_const_i32(wd);
28954    TCGv_i32 tws = tcg_const_i32(ws);
28955    TCGv_i32 twt = tcg_const_i32(wt);
28956    /* adjust df value for floating-point instruction */
28957    TCGv_i32 tdf = tcg_const_i32(df + 2);
28958
28959    switch (MASK_MSA_2RF(ctx->opcode)) {
28960    case OPC_FCLASS_df:
28961        gen_helper_msa_fclass_df(cpu_env, tdf, twd, tws);
28962        break;
28963    case OPC_FTRUNC_S_df:
28964        gen_helper_msa_ftrunc_s_df(cpu_env, tdf, twd, tws);
28965        break;
28966    case OPC_FTRUNC_U_df:
28967        gen_helper_msa_ftrunc_u_df(cpu_env, tdf, twd, tws);
28968        break;
28969    case OPC_FSQRT_df:
28970        gen_helper_msa_fsqrt_df(cpu_env, tdf, twd, tws);
28971        break;
28972    case OPC_FRSQRT_df:
28973        gen_helper_msa_frsqrt_df(cpu_env, tdf, twd, tws);
28974        break;
28975    case OPC_FRCP_df:
28976        gen_helper_msa_frcp_df(cpu_env, tdf, twd, tws);
28977        break;
28978    case OPC_FRINT_df:
28979        gen_helper_msa_frint_df(cpu_env, tdf, twd, tws);
28980        break;
28981    case OPC_FLOG2_df:
28982        gen_helper_msa_flog2_df(cpu_env, tdf, twd, tws);
28983        break;
28984    case OPC_FEXUPL_df:
28985        gen_helper_msa_fexupl_df(cpu_env, tdf, twd, tws);
28986        break;
28987    case OPC_FEXUPR_df:
28988        gen_helper_msa_fexupr_df(cpu_env, tdf, twd, tws);
28989        break;
28990    case OPC_FFQL_df:
28991        gen_helper_msa_ffql_df(cpu_env, tdf, twd, tws);
28992        break;
28993    case OPC_FFQR_df:
28994        gen_helper_msa_ffqr_df(cpu_env, tdf, twd, tws);
28995        break;
28996    case OPC_FTINT_S_df:
28997        gen_helper_msa_ftint_s_df(cpu_env, tdf, twd, tws);
28998        break;
28999    case OPC_FTINT_U_df:
29000        gen_helper_msa_ftint_u_df(cpu_env, tdf, twd, tws);
29001        break;
29002    case OPC_FFINT_S_df:
29003        gen_helper_msa_ffint_s_df(cpu_env, tdf, twd, tws);
29004        break;
29005    case OPC_FFINT_U_df:
29006        gen_helper_msa_ffint_u_df(cpu_env, tdf, twd, tws);
29007        break;
29008    }
29009
29010    tcg_temp_free_i32(twd);
29011    tcg_temp_free_i32(tws);
29012    tcg_temp_free_i32(twt);
29013    tcg_temp_free_i32(tdf);
29014}
29015
29016static void gen_msa_vec_v(CPUMIPSState *env, DisasContext *ctx)
29017{
29018#define MASK_MSA_VEC(op)    (MASK_MSA_MINOR(op) | (op & (0x1f << 21)))
29019    uint8_t wt = (ctx->opcode >> 16) & 0x1f;
29020    uint8_t ws = (ctx->opcode >> 11) & 0x1f;
29021    uint8_t wd = (ctx->opcode >> 6) & 0x1f;
29022    TCGv_i32 twd = tcg_const_i32(wd);
29023    TCGv_i32 tws = tcg_const_i32(ws);
29024    TCGv_i32 twt = tcg_const_i32(wt);
29025
29026    switch (MASK_MSA_VEC(ctx->opcode)) {
29027    case OPC_AND_V:
29028        gen_helper_msa_and_v(cpu_env, twd, tws, twt);
29029        break;
29030    case OPC_OR_V:
29031        gen_helper_msa_or_v(cpu_env, twd, tws, twt);
29032        break;
29033    case OPC_NOR_V:
29034        gen_helper_msa_nor_v(cpu_env, twd, tws, twt);
29035        break;
29036    case OPC_XOR_V:
29037        gen_helper_msa_xor_v(cpu_env, twd, tws, twt);
29038        break;
29039    case OPC_BMNZ_V:
29040        gen_helper_msa_bmnz_v(cpu_env, twd, tws, twt);
29041        break;
29042    case OPC_BMZ_V:
29043        gen_helper_msa_bmz_v(cpu_env, twd, tws, twt);
29044        break;
29045    case OPC_BSEL_V:
29046        gen_helper_msa_bsel_v(cpu_env, twd, tws, twt);
29047        break;
29048    default:
29049        MIPS_INVAL("MSA instruction");
29050        generate_exception_end(ctx, EXCP_RI);
29051        break;
29052    }
29053
29054    tcg_temp_free_i32(twd);
29055    tcg_temp_free_i32(tws);
29056    tcg_temp_free_i32(twt);
29057}
29058
29059static void gen_msa_vec(CPUMIPSState *env, DisasContext *ctx)
29060{
29061    switch (MASK_MSA_VEC(ctx->opcode)) {
29062    case OPC_AND_V:
29063    case OPC_OR_V:
29064    case OPC_NOR_V:
29065    case OPC_XOR_V:
29066    case OPC_BMNZ_V:
29067    case OPC_BMZ_V:
29068    case OPC_BSEL_V:
29069        gen_msa_vec_v(env, ctx);
29070        break;
29071    case OPC_MSA_2R:
29072        gen_msa_2r(env, ctx);
29073        break;
29074    case OPC_MSA_2RF:
29075        gen_msa_2rf(env, ctx);
29076        break;
29077    default:
29078        MIPS_INVAL("MSA instruction");
29079        generate_exception_end(ctx, EXCP_RI);
29080        break;
29081    }
29082}
29083
29084static void gen_msa(CPUMIPSState *env, DisasContext *ctx)
29085{
29086    uint32_t opcode = ctx->opcode;
29087    check_insn(ctx, ASE_MSA);
29088    check_msa_access(ctx);
29089
29090    switch (MASK_MSA_MINOR(opcode)) {
29091    case OPC_MSA_I8_00:
29092    case OPC_MSA_I8_01:
29093    case OPC_MSA_I8_02:
29094        gen_msa_i8(env, ctx);
29095        break;
29096    case OPC_MSA_I5_06:
29097    case OPC_MSA_I5_07:
29098        gen_msa_i5(env, ctx);
29099        break;
29100    case OPC_MSA_BIT_09:
29101    case OPC_MSA_BIT_0A:
29102        gen_msa_bit(env, ctx);
29103        break;
29104    case OPC_MSA_3R_0D:
29105    case OPC_MSA_3R_0E:
29106    case OPC_MSA_3R_0F:
29107    case OPC_MSA_3R_10:
29108    case OPC_MSA_3R_11:
29109    case OPC_MSA_3R_12:
29110    case OPC_MSA_3R_13:
29111    case OPC_MSA_3R_14:
29112    case OPC_MSA_3R_15:
29113        gen_msa_3r(env, ctx);
29114        break;
29115    case OPC_MSA_ELM:
29116        gen_msa_elm(env, ctx);
29117        break;
29118    case OPC_MSA_3RF_1A:
29119    case OPC_MSA_3RF_1B:
29120    case OPC_MSA_3RF_1C:
29121        gen_msa_3rf(env, ctx);
29122        break;
29123    case OPC_MSA_VEC:
29124        gen_msa_vec(env, ctx);
29125        break;
29126    case OPC_LD_B:
29127    case OPC_LD_H:
29128    case OPC_LD_W:
29129    case OPC_LD_D:
29130    case OPC_ST_B:
29131    case OPC_ST_H:
29132    case OPC_ST_W:
29133    case OPC_ST_D:
29134        {
29135            int32_t s10 = sextract32(ctx->opcode, 16, 10);
29136            uint8_t rs = (ctx->opcode >> 11) & 0x1f;
29137            uint8_t wd = (ctx->opcode >> 6) & 0x1f;
29138            uint8_t df = (ctx->opcode >> 0) & 0x3;
29139
29140            TCGv_i32 twd = tcg_const_i32(wd);
29141            TCGv taddr = tcg_temp_new();
29142            gen_base_offset_addr(ctx, taddr, rs, s10 << df);
29143
29144            switch (MASK_MSA_MINOR(opcode)) {
29145            case OPC_LD_B:
29146                gen_helper_msa_ld_b(cpu_env, twd, taddr);
29147                break;
29148            case OPC_LD_H:
29149                gen_helper_msa_ld_h(cpu_env, twd, taddr);
29150                break;
29151            case OPC_LD_W:
29152                gen_helper_msa_ld_w(cpu_env, twd, taddr);
29153                break;
29154            case OPC_LD_D:
29155                gen_helper_msa_ld_d(cpu_env, twd, taddr);
29156                break;
29157            case OPC_ST_B:
29158                gen_helper_msa_st_b(cpu_env, twd, taddr);
29159                break;
29160            case OPC_ST_H:
29161                gen_helper_msa_st_h(cpu_env, twd, taddr);
29162                break;
29163            case OPC_ST_W:
29164                gen_helper_msa_st_w(cpu_env, twd, taddr);
29165                break;
29166            case OPC_ST_D:
29167                gen_helper_msa_st_d(cpu_env, twd, taddr);
29168                break;
29169            }
29170
29171            tcg_temp_free_i32(twd);
29172            tcg_temp_free(taddr);
29173        }
29174        break;
29175    default:
29176        MIPS_INVAL("MSA instruction");
29177        generate_exception_end(ctx, EXCP_RI);
29178        break;
29179    }
29180
29181}
29182
29183static void decode_opc(CPUMIPSState *env, DisasContext *ctx)
29184{
29185    int32_t offset;
29186    int rs, rt, rd, sa;
29187    uint32_t op, op1;
29188    int16_t imm;
29189
29190    /* make sure instructions are on a word boundary */
29191    if (ctx->base.pc_next & 0x3) {
29192        env->CP0_BadVAddr = ctx->base.pc_next;
29193        generate_exception_err(ctx, EXCP_AdEL, EXCP_INST_NOTAVAIL);
29194        return;
29195    }
29196
29197    /* Handle blikely not taken case */
29198    if ((ctx->hflags & MIPS_HFLAG_BMASK_BASE) == MIPS_HFLAG_BL) {
29199        TCGLabel *l1 = gen_new_label();
29200
29201        tcg_gen_brcondi_tl(TCG_COND_NE, bcond, 0, l1);
29202        tcg_gen_movi_i32(hflags, ctx->hflags & ~MIPS_HFLAG_BMASK);
29203        gen_goto_tb(ctx, 1, ctx->base.pc_next + 4);
29204        gen_set_label(l1);
29205    }
29206
29207    op = MASK_OP_MAJOR(ctx->opcode);
29208    rs = (ctx->opcode >> 21) & 0x1f;
29209    rt = (ctx->opcode >> 16) & 0x1f;
29210    rd = (ctx->opcode >> 11) & 0x1f;
29211    sa = (ctx->opcode >> 6) & 0x1f;
29212    imm = (int16_t)ctx->opcode;
29213    switch (op) {
29214    case OPC_SPECIAL:
29215        decode_opc_special(env, ctx);
29216        break;
29217    case OPC_SPECIAL2:
29218#if defined(TARGET_MIPS64)
29219        if ((ctx->insn_flags & INSN_R5900) && (ctx->insn_flags & ASE_MMI)) {
29220            decode_mmi(env, ctx);
29221#else
29222        if (ctx->insn_flags & ASE_MXU) {
29223            decode_opc_mxu(env, ctx);
29224#endif
29225        } else {
29226            decode_opc_special2_legacy(env, ctx);
29227        }
29228        break;
29229    case OPC_SPECIAL3:
29230#if defined(TARGET_MIPS64)
29231        if (ctx->insn_flags & INSN_R5900) {
29232            decode_mmi_sq(env, ctx);    /* MMI_OPC_SQ */
29233        } else {
29234            decode_opc_special3(env, ctx);
29235        }
29236#else
29237        decode_opc_special3(env, ctx);
29238#endif
29239        break;
29240    case OPC_REGIMM:
29241        op1 = MASK_REGIMM(ctx->opcode);
29242        switch (op1) {
29243        case OPC_BLTZL: /* REGIMM branches */
29244        case OPC_BGEZL:
29245        case OPC_BLTZALL:
29246        case OPC_BGEZALL:
29247            check_insn(ctx, ISA_MIPS2);
29248            check_insn_opc_removed(ctx, ISA_MIPS32R6);
29249            /* Fallthrough */
29250        case OPC_BLTZ:
29251        case OPC_BGEZ:
29252            gen_compute_branch(ctx, op1, 4, rs, -1, imm << 2, 4);
29253            break;
29254        case OPC_BLTZAL:
29255        case OPC_BGEZAL:
29256            if (ctx->insn_flags & ISA_MIPS32R6) {
29257                if (rs == 0) {
29258                    /* OPC_NAL, OPC_BAL */
29259                    gen_compute_branch(ctx, op1, 4, 0, -1, imm << 2, 4);
29260                } else {
29261                    generate_exception_end(ctx, EXCP_RI);
29262                }
29263            } else {
29264                gen_compute_branch(ctx, op1, 4, rs, -1, imm << 2, 4);
29265            }
29266            break;
29267        case OPC_TGEI: /* REGIMM traps */
29268        case OPC_TGEIU:
29269        case OPC_TLTI:
29270        case OPC_TLTIU:
29271        case OPC_TEQI:
29272
29273        case OPC_TNEI:
29274            check_insn(ctx, ISA_MIPS2);
29275            check_insn_opc_removed(ctx, ISA_MIPS32R6);
29276            gen_trap(ctx, op1, rs, -1, imm);
29277            break;
29278        case OPC_SIGRIE:
29279            check_insn(ctx, ISA_MIPS32R6);
29280            generate_exception_end(ctx, EXCP_RI);
29281            break;
29282        case OPC_SYNCI:
29283            check_insn(ctx, ISA_MIPS32R2);
29284            /*
29285             * Break the TB to be able to sync copied instructions
29286             * immediately.
29287             */
29288            ctx->base.is_jmp = DISAS_STOP;
29289            break;
29290        case OPC_BPOSGE32:    /* MIPS DSP branch */
29291#if defined(TARGET_MIPS64)
29292        case OPC_BPOSGE64:
29293#endif
29294            check_dsp(ctx);
29295            gen_compute_branch(ctx, op1, 4, -1, -2, (int32_t)imm << 2, 4);
29296            break;
29297#if defined(TARGET_MIPS64)
29298        case OPC_DAHI:
29299            check_insn(ctx, ISA_MIPS32R6);
29300            check_mips_64(ctx);
29301            if (rs != 0) {
29302                tcg_gen_addi_tl(cpu_gpr[rs], cpu_gpr[rs], (int64_t)imm << 32);
29303            }
29304            break;
29305        case OPC_DATI:
29306            check_insn(ctx, ISA_MIPS32R6);
29307            check_mips_64(ctx);
29308            if (rs != 0) {
29309                tcg_gen_addi_tl(cpu_gpr[rs], cpu_gpr[rs], (int64_t)imm << 48);
29310            }
29311            break;
29312#endif
29313        default:            /* Invalid */
29314            MIPS_INVAL("regimm");
29315            generate_exception_end(ctx, EXCP_RI);
29316            break;
29317        }
29318        break;
29319    case OPC_CP0:
29320        check_cp0_enabled(ctx);
29321        op1 = MASK_CP0(ctx->opcode);
29322        switch (op1) {
29323        case OPC_MFC0:
29324        case OPC_MTC0:
29325        case OPC_MFTR:
29326        case OPC_MTTR:
29327        case OPC_MFHC0:
29328        case OPC_MTHC0:
29329#if defined(TARGET_MIPS64)
29330        case OPC_DMFC0:
29331        case OPC_DMTC0:
29332#endif
29333#ifndef CONFIG_USER_ONLY
29334            gen_cp0(env, ctx, op1, rt, rd);
29335#endif /* !CONFIG_USER_ONLY */
29336            break;
29337        case OPC_C0:
29338        case OPC_C0_1:
29339        case OPC_C0_2:
29340        case OPC_C0_3:
29341        case OPC_C0_4:
29342        case OPC_C0_5:
29343        case OPC_C0_6:
29344        case OPC_C0_7:
29345        case OPC_C0_8:
29346        case OPC_C0_9:
29347        case OPC_C0_A:
29348        case OPC_C0_B:
29349        case OPC_C0_C:
29350        case OPC_C0_D:
29351        case OPC_C0_E:
29352        case OPC_C0_F:
29353#ifndef CONFIG_USER_ONLY
29354            gen_cp0(env, ctx, MASK_C0(ctx->opcode), rt, rd);
29355#endif /* !CONFIG_USER_ONLY */
29356            break;
29357        case OPC_MFMC0:
29358#ifndef CONFIG_USER_ONLY
29359            {
29360                uint32_t op2;
29361                TCGv t0 = tcg_temp_new();
29362
29363                op2 = MASK_MFMC0(ctx->opcode);
29364                switch (op2) {
29365                case OPC_DMT:
29366                    check_cp0_mt(ctx);
29367                    gen_helper_dmt(t0);
29368                    gen_store_gpr(t0, rt);
29369                    break;
29370                case OPC_EMT:
29371                    check_cp0_mt(ctx);
29372                    gen_helper_emt(t0);
29373                    gen_store_gpr(t0, rt);
29374                    break;
29375                case OPC_DVPE:
29376                    check_cp0_mt(ctx);
29377                    gen_helper_dvpe(t0, cpu_env);
29378                    gen_store_gpr(t0, rt);
29379                    break;
29380                case OPC_EVPE:
29381                    check_cp0_mt(ctx);
29382                    gen_helper_evpe(t0, cpu_env);
29383                    gen_store_gpr(t0, rt);
29384                    break;
29385                case OPC_DVP:
29386                    check_insn(ctx, ISA_MIPS32R6);
29387                    if (ctx->vp) {
29388                        gen_helper_dvp(t0, cpu_env);
29389                        gen_store_gpr(t0, rt);
29390                    }
29391                    break;
29392                case OPC_EVP:
29393                    check_insn(ctx, ISA_MIPS32R6);
29394                    if (ctx->vp) {
29395                        gen_helper_evp(t0, cpu_env);
29396                        gen_store_gpr(t0, rt);
29397                    }
29398                    break;
29399                case OPC_DI:
29400                    check_insn(ctx, ISA_MIPS32R2);
29401                    save_cpu_state(ctx, 1);
29402                    gen_helper_di(t0, cpu_env);
29403                    gen_store_gpr(t0, rt);
29404                    /*
29405                     * Stop translation as we may have switched
29406                     * the execution mode.
29407                     */
29408                    ctx->base.is_jmp = DISAS_STOP;
29409                    break;
29410                case OPC_EI:
29411                    check_insn(ctx, ISA_MIPS32R2);
29412                    save_cpu_state(ctx, 1);
29413                    gen_helper_ei(t0, cpu_env);
29414                    gen_store_gpr(t0, rt);
29415                    /*
29416                     * DISAS_STOP isn't sufficient, we need to ensure we break
29417                     * out of translated code to check for pending interrupts.
29418                     */
29419                    gen_save_pc(ctx->base.pc_next + 4);
29420                    ctx->base.is_jmp = DISAS_EXIT;
29421                    break;
29422                default:            /* Invalid */
29423                    MIPS_INVAL("mfmc0");
29424                    generate_exception_end(ctx, EXCP_RI);
29425                    break;
29426                }
29427                tcg_temp_free(t0);
29428            }
29429#endif /* !CONFIG_USER_ONLY */
29430            break;
29431        case OPC_RDPGPR:
29432            check_insn(ctx, ISA_MIPS32R2);
29433            gen_load_srsgpr(rt, rd);
29434            break;
29435        case OPC_WRPGPR:
29436            check_insn(ctx, ISA_MIPS32R2);
29437            gen_store_srsgpr(rt, rd);
29438            break;
29439        default:
29440            MIPS_INVAL("cp0");
29441            generate_exception_end(ctx, EXCP_RI);
29442            break;
29443        }
29444        break;
29445    case OPC_BOVC: /* OPC_BEQZALC, OPC_BEQC, OPC_ADDI */
29446        if (ctx->insn_flags & ISA_MIPS32R6) {
29447            /* OPC_BOVC, OPC_BEQZALC, OPC_BEQC */
29448            gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
29449        } else {
29450            /* OPC_ADDI */
29451            /* Arithmetic with immediate opcode */
29452            gen_arith_imm(ctx, op, rt, rs, imm);
29453        }
29454        break;
29455    case OPC_ADDIU:
29456         gen_arith_imm(ctx, op, rt, rs, imm);
29457         break;
29458    case OPC_SLTI: /* Set on less than with immediate opcode */
29459    case OPC_SLTIU:
29460         gen_slt_imm(ctx, op, rt, rs, imm);
29461         break;
29462    case OPC_ANDI: /* Arithmetic with immediate opcode */
29463    case OPC_LUI: /* OPC_AUI */
29464    case OPC_ORI:
29465    case OPC_XORI:
29466         gen_logic_imm(ctx, op, rt, rs, imm);
29467         break;
29468    case OPC_J: /* Jump */
29469    case OPC_JAL:
29470         offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 2;
29471         gen_compute_branch(ctx, op, 4, rs, rt, offset, 4);
29472         break;
29473    /* Branch */
29474    case OPC_BLEZC: /* OPC_BGEZC, OPC_BGEC, OPC_BLEZL */
29475        if (ctx->insn_flags & ISA_MIPS32R6) {
29476            if (rt == 0) {
29477                generate_exception_end(ctx, EXCP_RI);
29478                break;
29479            }
29480            /* OPC_BLEZC, OPC_BGEZC, OPC_BGEC */
29481            gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
29482        } else {
29483            /* OPC_BLEZL */
29484            gen_compute_branch(ctx, op, 4, rs, rt, imm << 2, 4);
29485        }
29486        break;
29487    case OPC_BGTZC: /* OPC_BLTZC, OPC_BLTC, OPC_BGTZL */
29488        if (ctx->insn_flags & ISA_MIPS32R6) {
29489            if (rt == 0) {
29490                generate_exception_end(ctx, EXCP_RI);
29491                break;
29492            }
29493            /* OPC_BGTZC, OPC_BLTZC, OPC_BLTC */
29494            gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
29495        } else {
29496            /* OPC_BGTZL */
29497            gen_compute_branch(ctx, op, 4, rs, rt, imm << 2, 4);
29498        }
29499        break;
29500    case OPC_BLEZALC: /* OPC_BGEZALC, OPC_BGEUC, OPC_BLEZ */
29501        if (rt == 0) {
29502            /* OPC_BLEZ */
29503            gen_compute_branch(ctx, op, 4, rs, rt, imm << 2, 4);
29504        } else {
29505            check_insn(ctx, ISA_MIPS32R6);
29506            /* OPC_BLEZALC, OPC_BGEZALC, OPC_BGEUC */
29507            gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
29508        }
29509        break;
29510    case OPC_BGTZALC: /* OPC_BLTZALC, OPC_BLTUC, OPC_BGTZ */
29511        if (rt == 0) {
29512            /* OPC_BGTZ */
29513            gen_compute_branch(ctx, op, 4, rs, rt, imm << 2, 4);
29514        } else {
29515            check_insn(ctx, ISA_MIPS32R6);
29516            /* OPC_BGTZALC, OPC_BLTZALC, OPC_BLTUC */
29517            gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
29518        }
29519        break;
29520    case OPC_BEQL:
29521    case OPC_BNEL:
29522        check_insn(ctx, ISA_MIPS2);
29523         check_insn_opc_removed(ctx, ISA_MIPS32R6);
29524        /* Fallthrough */
29525    case OPC_BEQ:
29526    case OPC_BNE:
29527         gen_compute_branch(ctx, op, 4, rs, rt, imm << 2, 4);
29528         break;
29529    case OPC_LL: /* Load and stores */
29530        check_insn(ctx, ISA_MIPS2);
29531        if (ctx->insn_flags & INSN_R5900) {
29532            check_insn_opc_user_only(ctx, INSN_R5900);
29533        }
29534        /* Fallthrough */
29535    case OPC_LWL:
29536    case OPC_LWR:
29537        check_insn_opc_removed(ctx, ISA_MIPS32R6);
29538         /* Fallthrough */
29539    case OPC_LB:
29540    case OPC_LH:
29541    case OPC_LW:
29542    case OPC_LWPC:
29543    case OPC_LBU:
29544    case OPC_LHU:
29545         gen_ld(ctx, op, rt, rs, imm);
29546         break;
29547    case OPC_SWL:
29548    case OPC_SWR:
29549        check_insn_opc_removed(ctx, ISA_MIPS32R6);
29550        /* fall through */
29551    case OPC_SB:
29552    case OPC_SH:
29553    case OPC_SW:
29554         gen_st(ctx, op, rt, rs, imm);
29555         break;
29556    case OPC_SC:
29557        check_insn(ctx, ISA_MIPS2);
29558         check_insn_opc_removed(ctx, ISA_MIPS32R6);
29559        if (ctx->insn_flags & INSN_R5900) {
29560            check_insn_opc_user_only(ctx, INSN_R5900);
29561        }
29562        gen_st_cond(ctx, rt, rs, imm, MO_TESL, false);
29563        break;
29564    case OPC_CACHE:
29565        check_insn_opc_removed(ctx, ISA_MIPS32R6);
29566        check_cp0_enabled(ctx);
29567        check_insn(ctx, ISA_MIPS3 | ISA_MIPS32);
29568        if (ctx->hflags & MIPS_HFLAG_ITC_CACHE) {
29569            gen_cache_operation(ctx, rt, rs, imm);
29570        }
29571        /* Treat as NOP. */
29572        break;
29573    case OPC_PREF:
29574        check_insn_opc_removed(ctx, ISA_MIPS32R6);
29575        if (ctx->insn_flags & INSN_R5900) {
29576            /* Treat as NOP. */
29577        } else {
29578            check_insn(ctx, ISA_MIPS4 | ISA_MIPS32);
29579            /* Treat as NOP. */
29580        }
29581        break;
29582
29583    /* Floating point (COP1). */
29584    case OPC_LWC1:
29585    case OPC_LDC1:
29586    case OPC_SWC1:
29587    case OPC_SDC1:
29588        gen_cop1_ldst(ctx, op, rt, rs, imm);
29589        break;
29590
29591    case OPC_CP1:
29592        op1 = MASK_CP1(ctx->opcode);
29593
29594        switch (op1) {
29595        case OPC_MFHC1:
29596        case OPC_MTHC1:
29597            check_cp1_enabled(ctx);
29598            check_insn(ctx, ISA_MIPS32R2);
29599            /* fall through */
29600        case OPC_MFC1:
29601        case OPC_CFC1:
29602        case OPC_MTC1:
29603        case OPC_CTC1:
29604            check_cp1_enabled(ctx);
29605            gen_cp1(ctx, op1, rt, rd);
29606            break;
29607#if defined(TARGET_MIPS64)
29608        case OPC_DMFC1:
29609        case OPC_DMTC1:
29610            check_cp1_enabled(ctx);
29611            check_insn(ctx, ISA_MIPS3);
29612            check_mips_64(ctx);
29613            gen_cp1(ctx, op1, rt, rd);
29614            break;
29615#endif
29616        case OPC_BC1EQZ: /* OPC_BC1ANY2 */
29617            check_cp1_enabled(ctx);
29618            if (ctx->insn_flags & ISA_MIPS32R6) {
29619                /* OPC_BC1EQZ */
29620                gen_compute_branch1_r6(ctx, MASK_CP1(ctx->opcode),
29621                                       rt, imm << 2, 4);
29622            } else {
29623                /* OPC_BC1ANY2 */
29624                check_cop1x(ctx);
29625                check_insn(ctx, ASE_MIPS3D);
29626                gen_compute_branch1(ctx, MASK_BC1(ctx->opcode),
29627                                    (rt >> 2) & 0x7, imm << 2);
29628            }
29629            break;
29630        case OPC_BC1NEZ:
29631            check_cp1_enabled(ctx);
29632            check_insn(ctx, ISA_MIPS32R6);
29633            gen_compute_branch1_r6(ctx, MASK_CP1(ctx->opcode),
29634                                   rt, imm << 2, 4);
29635            break;
29636        case OPC_BC1ANY4:
29637            check_cp1_enabled(ctx);
29638            check_insn_opc_removed(ctx, ISA_MIPS32R6);
29639            check_cop1x(ctx);
29640            check_insn(ctx, ASE_MIPS3D);
29641            /* fall through */
29642        case OPC_BC1:
29643            check_cp1_enabled(ctx);
29644            check_insn_opc_removed(ctx, ISA_MIPS32R6);
29645            gen_compute_branch1(ctx, MASK_BC1(ctx->opcode),
29646                                (rt >> 2) & 0x7, imm << 2);
29647            break;
29648        case OPC_PS_FMT:
29649            check_ps(ctx);
29650            /* fall through */
29651        case OPC_S_FMT:
29652        case OPC_D_FMT:
29653            check_cp1_enabled(ctx);
29654            gen_farith(ctx, ctx->opcode & FOP(0x3f, 0x1f), rt, rd, sa,
29655                       (imm >> 8) & 0x7);
29656            break;
29657        case OPC_W_FMT:
29658        case OPC_L_FMT:
29659        {
29660            int r6_op = ctx->opcode & FOP(0x3f, 0x1f);
29661            check_cp1_enabled(ctx);
29662            if (ctx->insn_flags & ISA_MIPS32R6) {
29663                switch (r6_op) {
29664                case R6_OPC_CMP_AF_S:
29665                case R6_OPC_CMP_UN_S:
29666                case R6_OPC_CMP_EQ_S:
29667                case R6_OPC_CMP_UEQ_S:
29668                case R6_OPC_CMP_LT_S:
29669                case R6_OPC_CMP_ULT_S:
29670                case R6_OPC_CMP_LE_S:
29671                case R6_OPC_CMP_ULE_S:
29672                case R6_OPC_CMP_SAF_S:
29673                case R6_OPC_CMP_SUN_S:
29674                case R6_OPC_CMP_SEQ_S:
29675                case R6_OPC_CMP_SEUQ_S:
29676                case R6_OPC_CMP_SLT_S:
29677                case R6_OPC_CMP_SULT_S:
29678                case R6_OPC_CMP_SLE_S:
29679                case R6_OPC_CMP_SULE_S:
29680                case R6_OPC_CMP_OR_S:
29681                case R6_OPC_CMP_UNE_S:
29682                case R6_OPC_CMP_NE_S:
29683                case R6_OPC_CMP_SOR_S:
29684                case R6_OPC_CMP_SUNE_S:
29685                case R6_OPC_CMP_SNE_S:
29686                    gen_r6_cmp_s(ctx, ctx->opcode & 0x1f, rt, rd, sa);
29687                    break;
29688                case R6_OPC_CMP_AF_D:
29689                case R6_OPC_CMP_UN_D:
29690                case R6_OPC_CMP_EQ_D:
29691                case R6_OPC_CMP_UEQ_D:
29692                case R6_OPC_CMP_LT_D:
29693                case R6_OPC_CMP_ULT_D:
29694                case R6_OPC_CMP_LE_D:
29695                case R6_OPC_CMP_ULE_D:
29696                case R6_OPC_CMP_SAF_D:
29697                case R6_OPC_CMP_SUN_D:
29698                case R6_OPC_CMP_SEQ_D:
29699                case R6_OPC_CMP_SEUQ_D:
29700                case R6_OPC_CMP_SLT_D:
29701                case R6_OPC_CMP_SULT_D:
29702                case R6_OPC_CMP_SLE_D:
29703                case R6_OPC_CMP_SULE_D:
29704                case R6_OPC_CMP_OR_D:
29705                case R6_OPC_CMP_UNE_D:
29706                case R6_OPC_CMP_NE_D:
29707                case R6_OPC_CMP_SOR_D:
29708                case R6_OPC_CMP_SUNE_D:
29709                case R6_OPC_CMP_SNE_D:
29710                    gen_r6_cmp_d(ctx, ctx->opcode & 0x1f, rt, rd, sa);
29711                    break;
29712                default:
29713                    gen_farith(ctx, ctx->opcode & FOP(0x3f, 0x1f),
29714                               rt, rd, sa, (imm >> 8) & 0x7);
29715
29716                    break;
29717                }
29718            } else {
29719                gen_farith(ctx, ctx->opcode & FOP(0x3f, 0x1f), rt, rd, sa,
29720                           (imm >> 8) & 0x7);
29721            }
29722            break;
29723        }
29724        case OPC_BZ_V:
29725        case OPC_BNZ_V:
29726        case OPC_BZ_B:
29727        case OPC_BZ_H:
29728        case OPC_BZ_W:
29729        case OPC_BZ_D:
29730        case OPC_BNZ_B:
29731        case OPC_BNZ_H:
29732        case OPC_BNZ_W:
29733        case OPC_BNZ_D:
29734            check_insn(ctx, ASE_MSA);
29735            gen_msa_branch(env, ctx, op1);
29736            break;
29737        default:
29738            MIPS_INVAL("cp1");
29739            generate_exception_end(ctx, EXCP_RI);
29740            break;
29741        }
29742        break;
29743
29744    /* Compact branches [R6] and COP2 [non-R6] */
29745    case OPC_BC: /* OPC_LWC2 */
29746    case OPC_BALC: /* OPC_SWC2 */
29747        if (ctx->insn_flags & ISA_MIPS32R6) {
29748            /* OPC_BC, OPC_BALC */
29749            gen_compute_compact_branch(ctx, op, 0, 0,
29750                                       sextract32(ctx->opcode << 2, 0, 28));
29751        } else {
29752            /* OPC_LWC2, OPC_SWC2 */
29753            /* COP2: Not implemented. */
29754            generate_exception_err(ctx, EXCP_CpU, 2);
29755        }
29756        break;
29757    case OPC_BEQZC: /* OPC_JIC, OPC_LDC2 */
29758    case OPC_BNEZC: /* OPC_JIALC, OPC_SDC2 */
29759        if (ctx->insn_flags & ISA_MIPS32R6) {
29760            if (rs != 0) {
29761                /* OPC_BEQZC, OPC_BNEZC */
29762                gen_compute_compact_branch(ctx, op, rs, 0,
29763                                           sextract32(ctx->opcode << 2, 0, 23));
29764            } else {
29765                /* OPC_JIC, OPC_JIALC */
29766                gen_compute_compact_branch(ctx, op, 0, rt, imm);
29767            }
29768        } else {
29769            /* OPC_LWC2, OPC_SWC2 */
29770            /* COP2: Not implemented. */
29771            generate_exception_err(ctx, EXCP_CpU, 2);
29772        }
29773        break;
29774    case OPC_CP2:
29775        check_insn(ctx, INSN_LOONGSON2F);
29776        /* Note that these instructions use different fields.  */
29777        gen_loongson_multimedia(ctx, sa, rd, rt);
29778        break;
29779
29780    case OPC_CP3:
29781        check_insn_opc_removed(ctx, ISA_MIPS32R6);
29782        if (ctx->CP0_Config1 & (1 << CP0C1_FP)) {
29783            check_cp1_enabled(ctx);
29784            op1 = MASK_CP3(ctx->opcode);
29785            switch (op1) {
29786            case OPC_LUXC1:
29787            case OPC_SUXC1:
29788                check_insn(ctx, ISA_MIPS5 | ISA_MIPS32R2);
29789                /* Fallthrough */
29790            case OPC_LWXC1:
29791            case OPC_LDXC1:
29792            case OPC_SWXC1:
29793            case OPC_SDXC1:
29794                check_insn(ctx, ISA_MIPS4 | ISA_MIPS32R2);
29795                gen_flt3_ldst(ctx, op1, sa, rd, rs, rt);
29796                break;
29797            case OPC_PREFX:
29798                check_insn(ctx, ISA_MIPS4 | ISA_MIPS32R2);
29799                /* Treat as NOP. */
29800                break;
29801            case OPC_ALNV_PS:
29802                check_insn(ctx, ISA_MIPS5 | ISA_MIPS32R2);
29803                /* Fallthrough */
29804            case OPC_MADD_S:
29805            case OPC_MADD_D:
29806            case OPC_MADD_PS:
29807            case OPC_MSUB_S:
29808            case OPC_MSUB_D:
29809            case OPC_MSUB_PS:
29810            case OPC_NMADD_S:
29811            case OPC_NMADD_D:
29812            case OPC_NMADD_PS:
29813            case OPC_NMSUB_S:
29814            case OPC_NMSUB_D:
29815            case OPC_NMSUB_PS:
29816                check_insn(ctx, ISA_MIPS4 | ISA_MIPS32R2);
29817                gen_flt3_arith(ctx, op1, sa, rs, rd, rt);
29818                break;
29819            default:
29820                MIPS_INVAL("cp3");
29821                generate_exception_end(ctx, EXCP_RI);
29822                break;
29823            }
29824        } else {
29825            generate_exception_err(ctx, EXCP_CpU, 1);
29826        }
29827        break;
29828
29829#if defined(TARGET_MIPS64)
29830    /* MIPS64 opcodes */
29831    case OPC_LLD:
29832        if (ctx->insn_flags & INSN_R5900) {
29833            check_insn_opc_user_only(ctx, INSN_R5900);
29834        }
29835        /* fall through */
29836    case OPC_LDL:
29837    case OPC_LDR:
29838        check_insn_opc_removed(ctx, ISA_MIPS32R6);
29839        /* fall through */
29840    case OPC_LWU:
29841    case OPC_LD:
29842        check_insn(ctx, ISA_MIPS3);
29843        check_mips_64(ctx);
29844        gen_ld(ctx, op, rt, rs, imm);
29845        break;
29846    case OPC_SDL:
29847    case OPC_SDR:
29848        check_insn_opc_removed(ctx, ISA_MIPS32R6);
29849        /* fall through */
29850    case OPC_SD:
29851        check_insn(ctx, ISA_MIPS3);
29852        check_mips_64(ctx);
29853        gen_st(ctx, op, rt, rs, imm);
29854        break;
29855    case OPC_SCD:
29856        check_insn_opc_removed(ctx, ISA_MIPS32R6);
29857        check_insn(ctx, ISA_MIPS3);
29858        if (ctx->insn_flags & INSN_R5900) {
29859            check_insn_opc_user_only(ctx, INSN_R5900);
29860        }
29861        check_mips_64(ctx);
29862        gen_st_cond(ctx, rt, rs, imm, MO_TEQ, false);
29863        break;
29864    case OPC_BNVC: /* OPC_BNEZALC, OPC_BNEC, OPC_DADDI */
29865        if (ctx->insn_flags & ISA_MIPS32R6) {
29866            /* OPC_BNVC, OPC_BNEZALC, OPC_BNEC */
29867            gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
29868        } else {
29869            /* OPC_DADDI */
29870            check_insn(ctx, ISA_MIPS3);
29871            check_mips_64(ctx);
29872            gen_arith_imm(ctx, op, rt, rs, imm);
29873        }
29874        break;
29875    case OPC_DADDIU:
29876        check_insn(ctx, ISA_MIPS3);
29877        check_mips_64(ctx);
29878        gen_arith_imm(ctx, op, rt, rs, imm);
29879        break;
29880#else
29881    case OPC_BNVC: /* OPC_BNEZALC, OPC_BNEC */
29882        if (ctx->insn_flags & ISA_MIPS32R6) {
29883            gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
29884        } else {
29885            MIPS_INVAL("major opcode");
29886            generate_exception_end(ctx, EXCP_RI);
29887        }
29888        break;
29889#endif
29890    case OPC_DAUI: /* OPC_JALX */
29891        if (ctx->insn_flags & ISA_MIPS32R6) {
29892#if defined(TARGET_MIPS64)
29893            /* OPC_DAUI */
29894            check_mips_64(ctx);
29895            if (rs == 0) {
29896                generate_exception(ctx, EXCP_RI);
29897            } else if (rt != 0) {
29898                TCGv t0 = tcg_temp_new();
29899                gen_load_gpr(t0, rs);
29900                tcg_gen_addi_tl(cpu_gpr[rt], t0, imm << 16);
29901                tcg_temp_free(t0);
29902            }
29903#else
29904            generate_exception_end(ctx, EXCP_RI);
29905            MIPS_INVAL("major opcode");
29906#endif
29907        } else {
29908            /* OPC_JALX */
29909            check_insn(ctx, ASE_MIPS16 | ASE_MICROMIPS);
29910            offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 2;
29911            gen_compute_branch(ctx, op, 4, rs, rt, offset, 4);
29912        }
29913        break;
29914    case OPC_MSA: /* OPC_MDMX */
29915        if (ctx->insn_flags & INSN_R5900) {
29916#if defined(TARGET_MIPS64)
29917            gen_mmi_lq(env, ctx);    /* MMI_OPC_LQ */
29918#endif
29919        } else {
29920            /* MDMX: Not implemented. */
29921            gen_msa(env, ctx);
29922        }
29923        break;
29924    case OPC_PCREL:
29925        check_insn(ctx, ISA_MIPS32R6);
29926        gen_pcrel(ctx, ctx->opcode, ctx->base.pc_next, rs);
29927        break;
29928    default:            /* Invalid */
29929        MIPS_INVAL("major opcode");
29930        generate_exception_end(ctx, EXCP_RI);
29931        break;
29932    }
29933}
29934
29935static void mips_tr_init_disas_context(DisasContextBase *dcbase, CPUState *cs)
29936{
29937    DisasContext *ctx = container_of(dcbase, DisasContext, base);
29938    CPUMIPSState *env = cs->env_ptr;
29939
29940    ctx->page_start = ctx->base.pc_first & TARGET_PAGE_MASK;
29941    ctx->saved_pc = -1;
29942    ctx->insn_flags = env->insn_flags;
29943    ctx->CP0_Config1 = env->CP0_Config1;
29944    ctx->CP0_Config2 = env->CP0_Config2;
29945    ctx->CP0_Config3 = env->CP0_Config3;
29946    ctx->CP0_Config5 = env->CP0_Config5;
29947    ctx->btarget = 0;
29948    ctx->kscrexist = (env->CP0_Config4 >> CP0C4_KScrExist) & 0xff;
29949    ctx->rxi = (env->CP0_Config3 >> CP0C3_RXI) & 1;
29950    ctx->ie = (env->CP0_Config4 >> CP0C4_IE) & 3;
29951    ctx->bi = (env->CP0_Config3 >> CP0C3_BI) & 1;
29952    ctx->bp = (env->CP0_Config3 >> CP0C3_BP) & 1;
29953    ctx->PAMask = env->PAMask;
29954    ctx->mvh = (env->CP0_Config5 >> CP0C5_MVH) & 1;
29955    ctx->eva = (env->CP0_Config5 >> CP0C5_EVA) & 1;
29956    ctx->sc = (env->CP0_Config3 >> CP0C3_SC) & 1;
29957    ctx->CP0_LLAddr_shift = env->CP0_LLAddr_shift;
29958    ctx->cmgcr = (env->CP0_Config3 >> CP0C3_CMGCR) & 1;
29959    /* Restore delay slot state from the tb context.  */
29960    ctx->hflags = (uint32_t)ctx->base.tb->flags; /* FIXME: maybe use 64 bits? */
29961    ctx->ulri = (env->CP0_Config3 >> CP0C3_ULRI) & 1;
29962    ctx->ps = ((env->active_fpu.fcr0 >> FCR0_PS) & 1) ||
29963             (env->insn_flags & (INSN_LOONGSON2E | INSN_LOONGSON2F));
29964    ctx->vp = (env->CP0_Config5 >> CP0C5_VP) & 1;
29965    ctx->mrp = (env->CP0_Config5 >> CP0C5_MRP) & 1;
29966    ctx->nan2008 = (env->active_fpu.fcr31 >> FCR31_NAN2008) & 1;
29967    ctx->abs2008 = (env->active_fpu.fcr31 >> FCR31_ABS2008) & 1;
29968    restore_cpu_state(env, ctx);
29969#ifdef CONFIG_USER_ONLY
29970        ctx->mem_idx = MIPS_HFLAG_UM;
29971#else
29972        ctx->mem_idx = hflags_mmu_index(ctx->hflags);
29973#endif
29974    ctx->default_tcg_memop_mask = (ctx->insn_flags & ISA_MIPS32R6) ?
29975                                  MO_UNALN : MO_ALIGN;
29976
29977    LOG_DISAS("\ntb %p idx %d hflags %04x\n", ctx->base.tb, ctx->mem_idx,
29978              ctx->hflags);
29979}
29980
29981static void mips_tr_tb_start(DisasContextBase *dcbase, CPUState *cs)
29982{
29983}
29984
29985static void mips_tr_insn_start(DisasContextBase *dcbase, CPUState *cs)
29986{
29987    DisasContext *ctx = container_of(dcbase, DisasContext, base);
29988
29989    tcg_gen_insn_start(ctx->base.pc_next, ctx->hflags & MIPS_HFLAG_BMASK,
29990                       ctx->btarget);
29991}
29992
29993static bool mips_tr_breakpoint_check(DisasContextBase *dcbase, CPUState *cs,
29994                                     const CPUBreakpoint *bp)
29995{
29996    DisasContext *ctx = container_of(dcbase, DisasContext, base);
29997
29998    save_cpu_state(ctx, 1);
29999    ctx->base.is_jmp = DISAS_NORETURN;
30000    gen_helper_raise_exception_debug(cpu_env);
30001    /*
30002     * The address covered by the breakpoint must be included in
30003     * [tb->pc, tb->pc + tb->size) in order to for it to be
30004     * properly cleared -- thus we increment the PC here so that
30005     * the logic setting tb->size below does the right thing.
30006     */
30007    ctx->base.pc_next += 4;
30008    return true;
30009}
30010
30011static void mips_tr_translate_insn(DisasContextBase *dcbase, CPUState *cs)
30012{
30013    CPUMIPSState *env = cs->env_ptr;
30014    DisasContext *ctx = container_of(dcbase, DisasContext, base);
30015    int insn_bytes;
30016    int is_slot;
30017
30018    is_slot = ctx->hflags & MIPS_HFLAG_BMASK;
30019    if (ctx->insn_flags & ISA_NANOMIPS32) {
30020        ctx->opcode = cpu_lduw_code(env, ctx->base.pc_next);
30021        insn_bytes = decode_nanomips_opc(env, ctx);
30022    } else if (!(ctx->hflags & MIPS_HFLAG_M16)) {
30023        ctx->opcode = cpu_ldl_code(env, ctx->base.pc_next);
30024        insn_bytes = 4;
30025        decode_opc(env, ctx);
30026    } else if (ctx->insn_flags & ASE_MICROMIPS) {
30027        ctx->opcode = cpu_lduw_code(env, ctx->base.pc_next);
30028        insn_bytes = decode_micromips_opc(env, ctx);
30029    } else if (ctx->insn_flags & ASE_MIPS16) {
30030        ctx->opcode = cpu_lduw_code(env, ctx->base.pc_next);
30031        insn_bytes = decode_mips16_opc(env, ctx);
30032    } else {
30033        generate_exception_end(ctx, EXCP_RI);
30034        g_assert(ctx->base.is_jmp == DISAS_NORETURN);
30035        return;
30036    }
30037
30038    if (ctx->hflags & MIPS_HFLAG_BMASK) {
30039        if (!(ctx->hflags & (MIPS_HFLAG_BDS16 | MIPS_HFLAG_BDS32 |
30040                             MIPS_HFLAG_FBNSLOT))) {
30041            /*
30042             * Force to generate branch as there is neither delay nor
30043             * forbidden slot.
30044             */
30045            is_slot = 1;
30046        }
30047        if ((ctx->hflags & MIPS_HFLAG_M16) &&
30048            (ctx->hflags & MIPS_HFLAG_FBNSLOT)) {
30049            /*
30050             * Force to generate branch as microMIPS R6 doesn't restrict
30051             * branches in the forbidden slot.
30052             */
30053            is_slot = 1;
30054        }
30055    }
30056    if (is_slot) {
30057        gen_branch(ctx, insn_bytes);
30058    }
30059    ctx->base.pc_next += insn_bytes;
30060
30061    if (ctx->base.is_jmp != DISAS_NEXT) {
30062        return;
30063    }
30064    /*
30065     * Execute a branch and its delay slot as a single instruction.
30066     * This is what GDB expects and is consistent with what the
30067     * hardware does (e.g. if a delay slot instruction faults, the
30068     * reported PC is the PC of the branch).
30069     */
30070    if (ctx->base.singlestep_enabled &&
30071        (ctx->hflags & MIPS_HFLAG_BMASK) == 0) {
30072        ctx->base.is_jmp = DISAS_TOO_MANY;
30073    }
30074    if (ctx->base.pc_next - ctx->page_start >= TARGET_PAGE_SIZE) {
30075        ctx->base.is_jmp = DISAS_TOO_MANY;
30076    }
30077}
30078
30079static void mips_tr_tb_stop(DisasContextBase *dcbase, CPUState *cs)
30080{
30081    DisasContext *ctx = container_of(dcbase, DisasContext, base);
30082
30083    if (ctx->base.singlestep_enabled && ctx->base.is_jmp != DISAS_NORETURN) {
30084        save_cpu_state(ctx, ctx->base.is_jmp != DISAS_EXIT);
30085        gen_helper_raise_exception_debug(cpu_env);
30086    } else {
30087        switch (ctx->base.is_jmp) {
30088        case DISAS_STOP:
30089            gen_save_pc(ctx->base.pc_next);
30090            tcg_gen_lookup_and_goto_ptr();
30091            break;
30092        case DISAS_NEXT:
30093        case DISAS_TOO_MANY:
30094            save_cpu_state(ctx, 0);
30095            gen_goto_tb(ctx, 0, ctx->base.pc_next);
30096            break;
30097        case DISAS_EXIT:
30098            tcg_gen_exit_tb(NULL, 0);
30099            break;
30100        case DISAS_NORETURN:
30101            break;
30102        default:
30103            g_assert_not_reached();
30104        }
30105    }
30106}
30107
30108static void mips_tr_disas_log(const DisasContextBase *dcbase, CPUState *cs)
30109{
30110    qemu_log("IN: %s\n", lookup_symbol(dcbase->pc_first));
30111    log_target_disas(cs, dcbase->pc_first, dcbase->tb->size);
30112}
30113
30114static const TranslatorOps mips_tr_ops = {
30115    .init_disas_context = mips_tr_init_disas_context,
30116    .tb_start           = mips_tr_tb_start,
30117    .insn_start         = mips_tr_insn_start,
30118    .breakpoint_check   = mips_tr_breakpoint_check,
30119    .translate_insn     = mips_tr_translate_insn,
30120    .tb_stop            = mips_tr_tb_stop,
30121    .disas_log          = mips_tr_disas_log,
30122};
30123
30124void gen_intermediate_code(CPUState *cs, TranslationBlock *tb, int max_insns)
30125{
30126    DisasContext ctx;
30127
30128    translator_loop(&mips_tr_ops, &ctx.base, cs, tb, max_insns);
30129}
30130
30131static void fpu_dump_state(CPUMIPSState *env, FILE *f, int flags)
30132{
30133    int i;
30134    int is_fpu64 = !!(env->hflags & MIPS_HFLAG_F64);
30135
30136#define printfpr(fp)                                                    \
30137    do {                                                                \
30138        if (is_fpu64)                                                   \
30139            qemu_fprintf(f, "w:%08x d:%016" PRIx64                      \
30140                         " fd:%13g fs:%13g psu: %13g\n",                \
30141                         (fp)->w[FP_ENDIAN_IDX], (fp)->d,               \
30142                         (double)(fp)->fd,                              \
30143                         (double)(fp)->fs[FP_ENDIAN_IDX],               \
30144                         (double)(fp)->fs[!FP_ENDIAN_IDX]);             \
30145        else {                                                          \
30146            fpr_t tmp;                                                  \
30147            tmp.w[FP_ENDIAN_IDX] = (fp)->w[FP_ENDIAN_IDX];              \
30148            tmp.w[!FP_ENDIAN_IDX] = ((fp) + 1)->w[FP_ENDIAN_IDX];       \
30149            qemu_fprintf(f, "w:%08x d:%016" PRIx64                      \
30150                         " fd:%13g fs:%13g psu:%13g\n",                 \
30151                         tmp.w[FP_ENDIAN_IDX], tmp.d,                   \
30152                         (double)tmp.fd,                                \
30153                         (double)tmp.fs[FP_ENDIAN_IDX],                 \
30154                         (double)tmp.fs[!FP_ENDIAN_IDX]);               \
30155        }                                                               \
30156    } while(0)
30157
30158
30159    qemu_fprintf(f,
30160                 "CP1 FCR0 0x%08x  FCR31 0x%08x  SR.FR %d  fp_status 0x%02x\n",
30161                 env->active_fpu.fcr0, env->active_fpu.fcr31, is_fpu64,
30162                 get_float_exception_flags(&env->active_fpu.fp_status));
30163    for (i = 0; i < 32; (is_fpu64) ? i++ : (i += 2)) {
30164        qemu_fprintf(f, "%3s: ", fregnames[i]);
30165        printfpr(&env->active_fpu.fpr[i]);
30166    }
30167
30168#undef printfpr
30169}
30170
30171void mips_cpu_dump_state(CPUState *cs, FILE *f, int flags)
30172{
30173    MIPSCPU *cpu = MIPS_CPU(cs);
30174    CPUMIPSState *env = &cpu->env;
30175    int i;
30176
30177    qemu_fprintf(f, "pc=0x" TARGET_FMT_lx " HI=0x" TARGET_FMT_lx
30178                 " LO=0x" TARGET_FMT_lx " ds %04x "
30179                 TARGET_FMT_lx " " TARGET_FMT_ld "\n",
30180                 env->active_tc.PC, env->active_tc.HI[0], env->active_tc.LO[0],
30181                 env->hflags, env->btarget, env->bcond);
30182    for (i = 0; i < 32; i++) {
30183        if ((i & 3) == 0) {
30184            qemu_fprintf(f, "GPR%02d:", i);
30185        }
30186        qemu_fprintf(f, " %s " TARGET_FMT_lx,
30187                     regnames[i], env->active_tc.gpr[i]);
30188        if ((i & 3) == 3) {
30189            qemu_fprintf(f, "\n");
30190        }
30191    }
30192
30193    qemu_fprintf(f, "CP0 Status  0x%08x Cause   0x%08x EPC    0x" TARGET_FMT_lx "\n",
30194                 env->CP0_Status, env->CP0_Cause, env->CP0_EPC);
30195    qemu_fprintf(f, "    Config0 0x%08x Config1 0x%08x LLAddr 0x%016"
30196                 PRIx64 "\n",
30197                 env->CP0_Config0, env->CP0_Config1, env->CP0_LLAddr);
30198    qemu_fprintf(f, "    Config2 0x%08x Config3 0x%08x\n",
30199                 env->CP0_Config2, env->CP0_Config3);
30200    qemu_fprintf(f, "    Config4 0x%08x Config5 0x%08x\n",
30201                 env->CP0_Config4, env->CP0_Config5);
30202    if ((flags & CPU_DUMP_FPU) && (env->hflags & MIPS_HFLAG_FPU)) {
30203        fpu_dump_state(env, f, flags);
30204    }
30205}
30206
30207void mips_tcg_init(void)
30208{
30209    int i;
30210
30211    cpu_gpr[0] = NULL;
30212    for (i = 1; i < 32; i++)
30213        cpu_gpr[i] = tcg_global_mem_new(cpu_env,
30214                                        offsetof(CPUMIPSState, active_tc.gpr[i]),
30215                                        regnames[i]);
30216
30217    for (i = 0; i < 32; i++) {
30218        int off = offsetof(CPUMIPSState, active_fpu.fpr[i].wr.d[0]);
30219        msa_wr_d[i * 2] =
30220                tcg_global_mem_new_i64(cpu_env, off, msaregnames[i * 2]);
30221        /*
30222         * The scalar floating-point unit (FPU) registers are mapped on
30223         * the MSA vector registers.
30224         */
30225        fpu_f64[i] = msa_wr_d[i * 2];
30226        off = offsetof(CPUMIPSState, active_fpu.fpr[i].wr.d[1]);
30227        msa_wr_d[i * 2 + 1] =
30228                tcg_global_mem_new_i64(cpu_env, off, msaregnames[i * 2 + 1]);
30229    }
30230
30231    cpu_PC = tcg_global_mem_new(cpu_env,
30232                                offsetof(CPUMIPSState, active_tc.PC), "PC");
30233    for (i = 0; i < MIPS_DSP_ACC; i++) {
30234        cpu_HI[i] = tcg_global_mem_new(cpu_env,
30235                                       offsetof(CPUMIPSState, active_tc.HI[i]),
30236                                       regnames_HI[i]);
30237        cpu_LO[i] = tcg_global_mem_new(cpu_env,
30238                                       offsetof(CPUMIPSState, active_tc.LO[i]),
30239                                       regnames_LO[i]);
30240    }
30241    cpu_dspctrl = tcg_global_mem_new(cpu_env,
30242                                     offsetof(CPUMIPSState, active_tc.DSPControl),
30243                                     "DSPControl");
30244    bcond = tcg_global_mem_new(cpu_env,
30245                               offsetof(CPUMIPSState, bcond), "bcond");
30246    btarget = tcg_global_mem_new(cpu_env,
30247                                 offsetof(CPUMIPSState, btarget), "btarget");
30248    hflags = tcg_global_mem_new_i32(cpu_env,
30249                                    offsetof(CPUMIPSState, hflags), "hflags");
30250
30251    fpu_fcr0 = tcg_global_mem_new_i32(cpu_env,
30252                                      offsetof(CPUMIPSState, active_fpu.fcr0),
30253                                      "fcr0");
30254    fpu_fcr31 = tcg_global_mem_new_i32(cpu_env,
30255                                       offsetof(CPUMIPSState, active_fpu.fcr31),
30256                                       "fcr31");
30257    cpu_lladdr = tcg_global_mem_new(cpu_env, offsetof(CPUMIPSState, lladdr),
30258                                    "lladdr");
30259    cpu_llval = tcg_global_mem_new(cpu_env, offsetof(CPUMIPSState, llval),
30260                                   "llval");
30261
30262#if defined(TARGET_MIPS64)
30263    cpu_mmr[0] = NULL;
30264    for (i = 1; i < 32; i++) {
30265        cpu_mmr[i] = tcg_global_mem_new_i64(cpu_env,
30266                                            offsetof(CPUMIPSState,
30267                                                     active_tc.mmr[i]),
30268                                            regnames[i]);
30269    }
30270#endif
30271
30272#if !defined(TARGET_MIPS64)
30273    for (i = 0; i < NUMBER_OF_MXU_REGISTERS - 1; i++) {
30274        mxu_gpr[i] = tcg_global_mem_new(cpu_env,
30275                                        offsetof(CPUMIPSState,
30276                                                 active_tc.mxu_gpr[i]),
30277                                        mxuregnames[i]);
30278    }
30279
30280    mxu_CR = tcg_global_mem_new(cpu_env,
30281                                offsetof(CPUMIPSState, active_tc.mxu_cr),
30282                                mxuregnames[NUMBER_OF_MXU_REGISTERS - 1]);
30283#endif
30284}
30285
30286#include "translate_init.inc.c"
30287
30288void cpu_mips_realize_env(CPUMIPSState *env)
30289{
30290    env->exception_base = (int32_t)0xBFC00000;
30291
30292#ifndef CONFIG_USER_ONLY
30293    mmu_init(env, env->cpu_model);
30294#endif
30295    fpu_init(env, env->cpu_model);
30296    mvp_init(env, env->cpu_model);
30297}
30298
30299bool cpu_supports_cps_smp(const char *cpu_type)
30300{
30301    const MIPSCPUClass *mcc = MIPS_CPU_CLASS(object_class_by_name(cpu_type));
30302    return (mcc->cpu_def->CP0_Config3 & (1 << CP0C3_CMGCR)) != 0;
30303}
30304
30305bool cpu_supports_isa(const char *cpu_type, uint64_t isa)
30306{
30307    const MIPSCPUClass *mcc = MIPS_CPU_CLASS(object_class_by_name(cpu_type));
30308    return (mcc->cpu_def->insn_flags & isa) != 0;
30309}
30310
30311void cpu_set_exception_base(int vp_index, target_ulong address)
30312{
30313    MIPSCPU *vp = MIPS_CPU(qemu_get_cpu(vp_index));
30314    vp->env.exception_base = address;
30315}
30316
30317void cpu_state_reset(CPUMIPSState *env)
30318{
30319    CPUState *cs = env_cpu(env);
30320
30321    /* Reset registers to their default values */
30322    env->CP0_PRid = env->cpu_model->CP0_PRid;
30323    env->CP0_Config0 = env->cpu_model->CP0_Config0;
30324#ifdef TARGET_WORDS_BIGENDIAN
30325    env->CP0_Config0 |= (1 << CP0C0_BE);
30326#endif
30327    env->CP0_Config1 = env->cpu_model->CP0_Config1;
30328    env->CP0_Config2 = env->cpu_model->CP0_Config2;
30329    env->CP0_Config3 = env->cpu_model->CP0_Config3;
30330    env->CP0_Config4 = env->cpu_model->CP0_Config4;
30331    env->CP0_Config4_rw_bitmask = env->cpu_model->CP0_Config4_rw_bitmask;
30332    env->CP0_Config5 = env->cpu_model->CP0_Config5;
30333    env->CP0_Config5_rw_bitmask = env->cpu_model->CP0_Config5_rw_bitmask;
30334    env->CP0_Config6 = env->cpu_model->CP0_Config6;
30335    env->CP0_Config7 = env->cpu_model->CP0_Config7;
30336    env->CP0_LLAddr_rw_bitmask = env->cpu_model->CP0_LLAddr_rw_bitmask
30337                                 << env->cpu_model->CP0_LLAddr_shift;
30338    env->CP0_LLAddr_shift = env->cpu_model->CP0_LLAddr_shift;
30339    env->SYNCI_Step = env->cpu_model->SYNCI_Step;
30340    env->CCRes = env->cpu_model->CCRes;
30341    env->CP0_Status_rw_bitmask = env->cpu_model->CP0_Status_rw_bitmask;
30342    env->CP0_TCStatus_rw_bitmask = env->cpu_model->CP0_TCStatus_rw_bitmask;
30343    env->CP0_SRSCtl = env->cpu_model->CP0_SRSCtl;
30344    env->current_tc = 0;
30345    env->SEGBITS = env->cpu_model->SEGBITS;
30346    env->SEGMask = (target_ulong)((1ULL << env->cpu_model->SEGBITS) - 1);
30347#if defined(TARGET_MIPS64)
30348    if (env->cpu_model->insn_flags & ISA_MIPS3) {
30349        env->SEGMask |= 3ULL << 62;
30350    }
30351#endif
30352    env->PABITS = env->cpu_model->PABITS;
30353    env->CP0_SRSConf0_rw_bitmask = env->cpu_model->CP0_SRSConf0_rw_bitmask;
30354    env->CP0_SRSConf0 = env->cpu_model->CP0_SRSConf0;
30355    env->CP0_SRSConf1_rw_bitmask = env->cpu_model->CP0_SRSConf1_rw_bitmask;
30356    env->CP0_SRSConf1 = env->cpu_model->CP0_SRSConf1;
30357    env->CP0_SRSConf2_rw_bitmask = env->cpu_model->CP0_SRSConf2_rw_bitmask;
30358    env->CP0_SRSConf2 = env->cpu_model->CP0_SRSConf2;
30359    env->CP0_SRSConf3_rw_bitmask = env->cpu_model->CP0_SRSConf3_rw_bitmask;
30360    env->CP0_SRSConf3 = env->cpu_model->CP0_SRSConf3;
30361    env->CP0_SRSConf4_rw_bitmask = env->cpu_model->CP0_SRSConf4_rw_bitmask;
30362    env->CP0_SRSConf4 = env->cpu_model->CP0_SRSConf4;
30363    env->CP0_PageGrain_rw_bitmask = env->cpu_model->CP0_PageGrain_rw_bitmask;
30364    env->CP0_PageGrain = env->cpu_model->CP0_PageGrain;
30365    env->CP0_EBaseWG_rw_bitmask = env->cpu_model->CP0_EBaseWG_rw_bitmask;
30366    env->active_fpu.fcr0 = env->cpu_model->CP1_fcr0;
30367    env->active_fpu.fcr31_rw_bitmask = env->cpu_model->CP1_fcr31_rw_bitmask;
30368    env->active_fpu.fcr31 = env->cpu_model->CP1_fcr31;
30369    env->msair = env->cpu_model->MSAIR;
30370    env->insn_flags = env->cpu_model->insn_flags;
30371
30372#if defined(CONFIG_USER_ONLY)
30373    env->CP0_Status = (MIPS_HFLAG_UM << CP0St_KSU);
30374# ifdef TARGET_MIPS64
30375    /* Enable 64-bit register mode.  */
30376    env->CP0_Status |= (1 << CP0St_PX);
30377# endif
30378# ifdef TARGET_ABI_MIPSN64
30379    /* Enable 64-bit address mode.  */
30380    env->CP0_Status |= (1 << CP0St_UX);
30381# endif
30382    /*
30383     * Enable access to the CPUNum, SYNCI_Step, CC, and CCRes RDHWR
30384     * hardware registers.
30385     */
30386    env->CP0_HWREna |= 0x0000000F;
30387    if (env->CP0_Config1 & (1 << CP0C1_FP)) {
30388        env->CP0_Status |= (1 << CP0St_CU1);
30389    }
30390    if (env->CP0_Config3 & (1 << CP0C3_DSPP)) {
30391        env->CP0_Status |= (1 << CP0St_MX);
30392    }
30393# if defined(TARGET_MIPS64)
30394    /* For MIPS64, init FR bit to 1 if FPU unit is there and bit is writable. */
30395    if ((env->CP0_Config1 & (1 << CP0C1_FP)) &&
30396        (env->CP0_Status_rw_bitmask & (1 << CP0St_FR))) {
30397        env->CP0_Status |= (1 << CP0St_FR);
30398    }
30399# endif
30400#else
30401    if (env->hflags & MIPS_HFLAG_BMASK) {
30402        /*
30403         * If the exception was raised from a delay slot,
30404         * come back to the jump.
30405         */
30406        env->CP0_ErrorEPC = (env->active_tc.PC
30407                             - (env->hflags & MIPS_HFLAG_B16 ? 2 : 4));
30408    } else {
30409        env->CP0_ErrorEPC = env->active_tc.PC;
30410    }
30411    env->active_tc.PC = env->exception_base;
30412    env->CP0_Random = env->tlb->nb_tlb - 1;
30413    env->tlb->tlb_in_use = env->tlb->nb_tlb;
30414    env->CP0_Wired = 0;
30415    env->CP0_GlobalNumber = (cs->cpu_index & 0xFF) << CP0GN_VPId;
30416    env->CP0_EBase = (cs->cpu_index & 0x3FF);
30417    if (mips_um_ksegs_enabled()) {
30418        env->CP0_EBase |= 0x40000000;
30419    } else {
30420        env->CP0_EBase |= (int32_t)0x80000000;
30421    }
30422    if (env->CP0_Config3 & (1 << CP0C3_CMGCR)) {
30423        env->CP0_CMGCRBase = 0x1fbf8000 >> 4;
30424    }
30425    env->CP0_EntryHi_ASID_mask = (env->CP0_Config4 & (1 << CP0C4_AE)) ?
30426                                 0x3ff : 0xff;
30427    env->CP0_Status = (1 << CP0St_BEV) | (1 << CP0St_ERL);
30428    /*
30429     * Vectored interrupts not implemented, timer on int 7,
30430     * no performance counters.
30431     */
30432    env->CP0_IntCtl = 0xe0000000;
30433    {
30434        int i;
30435
30436        for (i = 0; i < 7; i++) {
30437            env->CP0_WatchLo[i] = 0;
30438            env->CP0_WatchHi[i] = 0x80000000;
30439        }
30440        env->CP0_WatchLo[7] = 0;
30441        env->CP0_WatchHi[7] = 0;
30442    }
30443    /* Count register increments in debug mode, EJTAG version 1 */
30444    env->CP0_Debug = (1 << CP0DB_CNT) | (0x1 << CP0DB_VER);
30445
30446    cpu_mips_store_count(env, 1);
30447
30448    if (env->CP0_Config3 & (1 << CP0C3_MT)) {
30449        int i;
30450
30451        /* Only TC0 on VPE 0 starts as active.  */
30452        for (i = 0; i < ARRAY_SIZE(env->tcs); i++) {
30453            env->tcs[i].CP0_TCBind = cs->cpu_index << CP0TCBd_CurVPE;
30454            env->tcs[i].CP0_TCHalt = 1;
30455        }
30456        env->active_tc.CP0_TCHalt = 1;
30457        cs->halted = 1;
30458
30459        if (cs->cpu_index == 0) {
30460            /* VPE0 starts up enabled.  */
30461            env->mvp->CP0_MVPControl |= (1 << CP0MVPCo_EVP);
30462            env->CP0_VPEConf0 |= (1 << CP0VPEC0_MVP) | (1 << CP0VPEC0_VPA);
30463
30464            /* TC0 starts up unhalted.  */
30465            cs->halted = 0;
30466            env->active_tc.CP0_TCHalt = 0;
30467            env->tcs[0].CP0_TCHalt = 0;
30468            /* With thread 0 active.  */
30469            env->active_tc.CP0_TCStatus = (1 << CP0TCSt_A);
30470            env->tcs[0].CP0_TCStatus = (1 << CP0TCSt_A);
30471        }
30472    }
30473
30474    /*
30475     * Configure default legacy segmentation control. We use this regardless of
30476     * whether segmentation control is presented to the guest.
30477     */
30478    /* KSeg3 (seg0 0xE0000000..0xFFFFFFFF) */
30479    env->CP0_SegCtl0 =   (CP0SC_AM_MK << CP0SC_AM);
30480    /* KSeg2 (seg1 0xC0000000..0xDFFFFFFF) */
30481    env->CP0_SegCtl0 |= ((CP0SC_AM_MSK << CP0SC_AM)) << 16;
30482    /* KSeg1 (seg2 0xA0000000..0x9FFFFFFF) */
30483    env->CP0_SegCtl1 =   (0 << CP0SC_PA) | (CP0SC_AM_UK << CP0SC_AM) |
30484                         (2 << CP0SC_C);
30485    /* KSeg0 (seg3 0x80000000..0x9FFFFFFF) */
30486    env->CP0_SegCtl1 |= ((0 << CP0SC_PA) | (CP0SC_AM_UK << CP0SC_AM) |
30487                         (3 << CP0SC_C)) << 16;
30488    /* USeg (seg4 0x40000000..0x7FFFFFFF) */
30489    env->CP0_SegCtl2 =   (2 << CP0SC_PA) | (CP0SC_AM_MUSK << CP0SC_AM) |
30490                         (1 << CP0SC_EU) | (2 << CP0SC_C);
30491    /* USeg (seg5 0x00000000..0x3FFFFFFF) */
30492    env->CP0_SegCtl2 |= ((0 << CP0SC_PA) | (CP0SC_AM_MUSK << CP0SC_AM) |
30493                         (1 << CP0SC_EU) | (2 << CP0SC_C)) << 16;
30494    /* XKPhys (note, SegCtl2.XR = 0, so XAM won't be used) */
30495    env->CP0_SegCtl1 |= (CP0SC_AM_UK << CP0SC1_XAM);
30496#endif
30497    if ((env->insn_flags & ISA_MIPS32R6) &&
30498        (env->active_fpu.fcr0 & (1 << FCR0_F64))) {
30499        /* Status.FR = 0 mode in 64-bit FPU not allowed in R6 */
30500        env->CP0_Status |= (1 << CP0St_FR);
30501    }
30502
30503    if (env->insn_flags & ISA_MIPS32R6) {
30504        /* PTW  =  1 */
30505        env->CP0_PWSize = 0x40;
30506        /* GDI  = 12 */
30507        /* UDI  = 12 */
30508        /* MDI  = 12 */
30509        /* PRI  = 12 */
30510        /* PTEI =  2 */
30511        env->CP0_PWField = 0x0C30C302;
30512    } else {
30513        /* GDI  =  0 */
30514        /* UDI  =  0 */
30515        /* MDI  =  0 */
30516        /* PRI  =  0 */
30517        /* PTEI =  2 */
30518        env->CP0_PWField = 0x02;
30519    }
30520
30521    if (env->CP0_Config3 & (1 << CP0C3_ISA) & (1 << (CP0C3_ISA + 1))) {
30522        /*  microMIPS on reset when Config3.ISA is 3 */
30523        env->hflags |= MIPS_HFLAG_M16;
30524    }
30525
30526    /* MSA */
30527    if (env->CP0_Config3 & (1 << CP0C3_MSAP)) {
30528        msa_reset(env);
30529    }
30530
30531    compute_hflags(env);
30532    restore_fp_status(env);
30533    restore_pamask(env);
30534    cs->exception_index = EXCP_NONE;
30535
30536    if (semihosting_get_argc()) {
30537        /* UHI interface can be used to obtain argc and argv */
30538        env->active_tc.gpr[4] = -1;
30539    }
30540}
30541
30542void restore_state_to_opc(CPUMIPSState *env, TranslationBlock *tb,
30543                          target_ulong *data)
30544{
30545    env->active_tc.PC = data[0];
30546    env->hflags &= ~MIPS_HFLAG_BMASK;
30547    env->hflags |= data[1];
30548    switch (env->hflags & MIPS_HFLAG_BMASK_BASE) {
30549    case MIPS_HFLAG_BR:
30550        break;
30551    case MIPS_HFLAG_BC:
30552    case MIPS_HFLAG_BL:
30553    case MIPS_HFLAG_B:
30554        env->btarget = data[2];
30555        break;
30556    }
30557}
30558