qemu/target-mips/translate.c
<<
>>
Prefs
   1/*
   2 *  MIPS32 emulation for qemu: main translation routines.
   3 *
   4 *  Copyright (c) 2004-2005 Jocelyn Mayer
   5 *  Copyright (c) 2006 Marius Groeger (FPU operations)
   6 *  Copyright (c) 2006 Thiemo Seufer (MIPS32R2 support)
   7 *  Copyright (c) 2009 CodeSourcery (MIPS16 and microMIPS support)
   8 *  Copyright (c) 2012 Jia Liu & Dongxue Zhang (MIPS ASE DSP support)
   9 *
  10 * This library is free software; you can redistribute it and/or
  11 * modify it under the terms of the GNU Lesser General Public
  12 * License as published by the Free Software Foundation; either
  13 * version 2 of the License, or (at your option) any later version.
  14 *
  15 * This library is distributed in the hope that it will be useful,
  16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
  17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  18 * Lesser General Public License for more details.
  19 *
  20 * You should have received a copy of the GNU Lesser General Public
  21 * License along with this library; if not, see <http://www.gnu.org/licenses/>.
  22 */
  23
  24#include "qemu/osdep.h"
  25#include "cpu.h"
  26#include "disas/disas.h"
  27#include "tcg-op.h"
  28#include "exec/cpu_ldst.h"
  29
  30#include "exec/helper-proto.h"
  31#include "exec/helper-gen.h"
  32#include "sysemu/kvm.h"
  33#include "exec/semihost.h"
  34
  35#include "trace-tcg.h"
  36#include "exec/log.h"
  37
  38#define MIPS_DEBUG_DISAS 0
  39
  40/* MIPS major opcodes */
  41#define MASK_OP_MAJOR(op)  (op & (0x3F << 26))
  42
  43enum {
  44    /* indirect opcode tables */
  45    OPC_SPECIAL  = (0x00 << 26),
  46    OPC_REGIMM   = (0x01 << 26),
  47    OPC_CP0      = (0x10 << 26),
  48    OPC_CP1      = (0x11 << 26),
  49    OPC_CP2      = (0x12 << 26),
  50    OPC_CP3      = (0x13 << 26),
  51    OPC_SPECIAL2 = (0x1C << 26),
  52    OPC_SPECIAL3 = (0x1F << 26),
  53    /* arithmetic with immediate */
  54    OPC_ADDI     = (0x08 << 26),
  55    OPC_ADDIU    = (0x09 << 26),
  56    OPC_SLTI     = (0x0A << 26),
  57    OPC_SLTIU    = (0x0B << 26),
  58    /* logic with immediate */
  59    OPC_ANDI     = (0x0C << 26),
  60    OPC_ORI      = (0x0D << 26),
  61    OPC_XORI     = (0x0E << 26),
  62    OPC_LUI      = (0x0F << 26),
  63    /* arithmetic with immediate */
  64    OPC_DADDI    = (0x18 << 26),
  65    OPC_DADDIU   = (0x19 << 26),
  66    /* Jump and branches */
  67    OPC_J        = (0x02 << 26),
  68    OPC_JAL      = (0x03 << 26),
  69    OPC_BEQ      = (0x04 << 26),  /* Unconditional if rs = rt = 0 (B) */
  70    OPC_BEQL     = (0x14 << 26),
  71    OPC_BNE      = (0x05 << 26),
  72    OPC_BNEL     = (0x15 << 26),
  73    OPC_BLEZ     = (0x06 << 26),
  74    OPC_BLEZL    = (0x16 << 26),
  75    OPC_BGTZ     = (0x07 << 26),
  76    OPC_BGTZL    = (0x17 << 26),
  77    OPC_JALX     = (0x1D << 26),
  78    OPC_DAUI     = (0x1D << 26),
  79    /* Load and stores */
  80    OPC_LDL      = (0x1A << 26),
  81    OPC_LDR      = (0x1B << 26),
  82    OPC_LB       = (0x20 << 26),
  83    OPC_LH       = (0x21 << 26),
  84    OPC_LWL      = (0x22 << 26),
  85    OPC_LW       = (0x23 << 26),
  86    OPC_LWPC     = OPC_LW | 0x5,
  87    OPC_LBU      = (0x24 << 26),
  88    OPC_LHU      = (0x25 << 26),
  89    OPC_LWR      = (0x26 << 26),
  90    OPC_LWU      = (0x27 << 26),
  91    OPC_SB       = (0x28 << 26),
  92    OPC_SH       = (0x29 << 26),
  93    OPC_SWL      = (0x2A << 26),
  94    OPC_SW       = (0x2B << 26),
  95    OPC_SDL      = (0x2C << 26),
  96    OPC_SDR      = (0x2D << 26),
  97    OPC_SWR      = (0x2E << 26),
  98    OPC_LL       = (0x30 << 26),
  99    OPC_LLD      = (0x34 << 26),
 100    OPC_LD       = (0x37 << 26),
 101    OPC_LDPC     = OPC_LD | 0x5,
 102    OPC_SC       = (0x38 << 26),
 103    OPC_SCD      = (0x3C << 26),
 104    OPC_SD       = (0x3F << 26),
 105    /* Floating point load/store */
 106    OPC_LWC1     = (0x31 << 26),
 107    OPC_LWC2     = (0x32 << 26),
 108    OPC_LDC1     = (0x35 << 26),
 109    OPC_LDC2     = (0x36 << 26),
 110    OPC_SWC1     = (0x39 << 26),
 111    OPC_SWC2     = (0x3A << 26),
 112    OPC_SDC1     = (0x3D << 26),
 113    OPC_SDC2     = (0x3E << 26),
 114    /* Compact Branches */
 115    OPC_BLEZALC  = (0x06 << 26),
 116    OPC_BGEZALC  = (0x06 << 26),
 117    OPC_BGEUC    = (0x06 << 26),
 118    OPC_BGTZALC  = (0x07 << 26),
 119    OPC_BLTZALC  = (0x07 << 26),
 120    OPC_BLTUC    = (0x07 << 26),
 121    OPC_BOVC     = (0x08 << 26),
 122    OPC_BEQZALC  = (0x08 << 26),
 123    OPC_BEQC     = (0x08 << 26),
 124    OPC_BLEZC    = (0x16 << 26),
 125    OPC_BGEZC    = (0x16 << 26),
 126    OPC_BGEC     = (0x16 << 26),
 127    OPC_BGTZC    = (0x17 << 26),
 128    OPC_BLTZC    = (0x17 << 26),
 129    OPC_BLTC     = (0x17 << 26),
 130    OPC_BNVC     = (0x18 << 26),
 131    OPC_BNEZALC  = (0x18 << 26),
 132    OPC_BNEC     = (0x18 << 26),
 133    OPC_BC       = (0x32 << 26),
 134    OPC_BEQZC    = (0x36 << 26),
 135    OPC_JIC      = (0x36 << 26),
 136    OPC_BALC     = (0x3A << 26),
 137    OPC_BNEZC    = (0x3E << 26),
 138    OPC_JIALC    = (0x3E << 26),
 139    /* MDMX ASE specific */
 140    OPC_MDMX     = (0x1E << 26),
 141    /* MSA ASE, same as MDMX */
 142    OPC_MSA      = OPC_MDMX,
 143    /* Cache and prefetch */
 144    OPC_CACHE    = (0x2F << 26),
 145    OPC_PREF     = (0x33 << 26),
 146    /* PC-relative address computation / loads */
 147    OPC_PCREL    = (0x3B << 26),
 148};
 149
 150/* PC-relative address computation / loads  */
 151#define MASK_OPC_PCREL_TOP2BITS(op)  (MASK_OP_MAJOR(op) | (op & (3 << 19)))
 152#define MASK_OPC_PCREL_TOP5BITS(op)  (MASK_OP_MAJOR(op) | (op & (0x1f << 16)))
 153enum {
 154    /* Instructions determined by bits 19 and 20 */
 155    OPC_ADDIUPC = OPC_PCREL | (0 << 19),
 156    R6_OPC_LWPC = OPC_PCREL | (1 << 19),
 157    OPC_LWUPC   = OPC_PCREL | (2 << 19),
 158
 159    /* Instructions determined by bits 16 ... 20 */
 160    OPC_AUIPC   = OPC_PCREL | (0x1e << 16),
 161    OPC_ALUIPC  = OPC_PCREL | (0x1f << 16),
 162
 163    /* Other */
 164    R6_OPC_LDPC = OPC_PCREL | (6 << 18),
 165};
 166
 167/* MIPS special opcodes */
 168#define MASK_SPECIAL(op)   MASK_OP_MAJOR(op) | (op & 0x3F)
 169
 170enum {
 171    /* Shifts */
 172    OPC_SLL      = 0x00 | OPC_SPECIAL,
 173    /* NOP is SLL r0, r0, 0   */
 174    /* SSNOP is SLL r0, r0, 1 */
 175    /* EHB is SLL r0, r0, 3 */
 176    OPC_SRL      = 0x02 | OPC_SPECIAL, /* also ROTR */
 177    OPC_ROTR     = OPC_SRL | (1 << 21),
 178    OPC_SRA      = 0x03 | OPC_SPECIAL,
 179    OPC_SLLV     = 0x04 | OPC_SPECIAL,
 180    OPC_SRLV     = 0x06 | OPC_SPECIAL, /* also ROTRV */
 181    OPC_ROTRV    = OPC_SRLV | (1 << 6),
 182    OPC_SRAV     = 0x07 | OPC_SPECIAL,
 183    OPC_DSLLV    = 0x14 | OPC_SPECIAL,
 184    OPC_DSRLV    = 0x16 | OPC_SPECIAL, /* also DROTRV */
 185    OPC_DROTRV   = OPC_DSRLV | (1 << 6),
 186    OPC_DSRAV    = 0x17 | OPC_SPECIAL,
 187    OPC_DSLL     = 0x38 | OPC_SPECIAL,
 188    OPC_DSRL     = 0x3A | OPC_SPECIAL, /* also DROTR */
 189    OPC_DROTR    = OPC_DSRL | (1 << 21),
 190    OPC_DSRA     = 0x3B | OPC_SPECIAL,
 191    OPC_DSLL32   = 0x3C | OPC_SPECIAL,
 192    OPC_DSRL32   = 0x3E | OPC_SPECIAL, /* also DROTR32 */
 193    OPC_DROTR32  = OPC_DSRL32 | (1 << 21),
 194    OPC_DSRA32   = 0x3F | OPC_SPECIAL,
 195    /* Multiplication / division */
 196    OPC_MULT     = 0x18 | OPC_SPECIAL,
 197    OPC_MULTU    = 0x19 | OPC_SPECIAL,
 198    OPC_DIV      = 0x1A | OPC_SPECIAL,
 199    OPC_DIVU     = 0x1B | OPC_SPECIAL,
 200    OPC_DMULT    = 0x1C | OPC_SPECIAL,
 201    OPC_DMULTU   = 0x1D | OPC_SPECIAL,
 202    OPC_DDIV     = 0x1E | OPC_SPECIAL,
 203    OPC_DDIVU    = 0x1F | OPC_SPECIAL,
 204
 205    /* 2 registers arithmetic / logic */
 206    OPC_ADD      = 0x20 | OPC_SPECIAL,
 207    OPC_ADDU     = 0x21 | OPC_SPECIAL,
 208    OPC_SUB      = 0x22 | OPC_SPECIAL,
 209    OPC_SUBU     = 0x23 | OPC_SPECIAL,
 210    OPC_AND      = 0x24 | OPC_SPECIAL,
 211    OPC_OR       = 0x25 | OPC_SPECIAL,
 212    OPC_XOR      = 0x26 | OPC_SPECIAL,
 213    OPC_NOR      = 0x27 | OPC_SPECIAL,
 214    OPC_SLT      = 0x2A | OPC_SPECIAL,
 215    OPC_SLTU     = 0x2B | OPC_SPECIAL,
 216    OPC_DADD     = 0x2C | OPC_SPECIAL,
 217    OPC_DADDU    = 0x2D | OPC_SPECIAL,
 218    OPC_DSUB     = 0x2E | OPC_SPECIAL,
 219    OPC_DSUBU    = 0x2F | OPC_SPECIAL,
 220    /* Jumps */
 221    OPC_JR       = 0x08 | OPC_SPECIAL, /* Also JR.HB */
 222    OPC_JALR     = 0x09 | OPC_SPECIAL, /* Also JALR.HB */
 223    /* Traps */
 224    OPC_TGE      = 0x30 | OPC_SPECIAL,
 225    OPC_TGEU     = 0x31 | OPC_SPECIAL,
 226    OPC_TLT      = 0x32 | OPC_SPECIAL,
 227    OPC_TLTU     = 0x33 | OPC_SPECIAL,
 228    OPC_TEQ      = 0x34 | OPC_SPECIAL,
 229    OPC_TNE      = 0x36 | OPC_SPECIAL,
 230    /* HI / LO registers load & stores */
 231    OPC_MFHI     = 0x10 | OPC_SPECIAL,
 232    OPC_MTHI     = 0x11 | OPC_SPECIAL,
 233    OPC_MFLO     = 0x12 | OPC_SPECIAL,
 234    OPC_MTLO     = 0x13 | OPC_SPECIAL,
 235    /* Conditional moves */
 236    OPC_MOVZ     = 0x0A | OPC_SPECIAL,
 237    OPC_MOVN     = 0x0B | OPC_SPECIAL,
 238
 239    OPC_SELEQZ   = 0x35 | OPC_SPECIAL,
 240    OPC_SELNEZ   = 0x37 | OPC_SPECIAL,
 241
 242    OPC_MOVCI    = 0x01 | OPC_SPECIAL,
 243
 244    /* Special */
 245    OPC_PMON     = 0x05 | OPC_SPECIAL, /* unofficial */
 246    OPC_SYSCALL  = 0x0C | OPC_SPECIAL,
 247    OPC_BREAK    = 0x0D | OPC_SPECIAL,
 248    OPC_SPIM     = 0x0E | OPC_SPECIAL, /* unofficial */
 249    OPC_SYNC     = 0x0F | OPC_SPECIAL,
 250
 251    OPC_SPECIAL28_RESERVED = 0x28 | OPC_SPECIAL,
 252    OPC_SPECIAL29_RESERVED = 0x29 | OPC_SPECIAL,
 253    OPC_SPECIAL39_RESERVED = 0x39 | OPC_SPECIAL,
 254    OPC_SPECIAL3D_RESERVED = 0x3D | OPC_SPECIAL,
 255};
 256
 257/* R6 Multiply and Divide instructions have the same Opcode
 258   and function field as legacy OPC_MULT[U]/OPC_DIV[U] */
 259#define MASK_R6_MULDIV(op)   (MASK_SPECIAL(op) | (op & (0x7ff)))
 260
 261enum {
 262    R6_OPC_MUL   = OPC_MULT  | (2 << 6),
 263    R6_OPC_MUH   = OPC_MULT  | (3 << 6),
 264    R6_OPC_MULU  = OPC_MULTU | (2 << 6),
 265    R6_OPC_MUHU  = OPC_MULTU | (3 << 6),
 266    R6_OPC_DIV   = OPC_DIV   | (2 << 6),
 267    R6_OPC_MOD   = OPC_DIV   | (3 << 6),
 268    R6_OPC_DIVU  = OPC_DIVU  | (2 << 6),
 269    R6_OPC_MODU  = OPC_DIVU  | (3 << 6),
 270
 271    R6_OPC_DMUL   = OPC_DMULT  | (2 << 6),
 272    R6_OPC_DMUH   = OPC_DMULT  | (3 << 6),
 273    R6_OPC_DMULU  = OPC_DMULTU | (2 << 6),
 274    R6_OPC_DMUHU  = OPC_DMULTU | (3 << 6),
 275    R6_OPC_DDIV   = OPC_DDIV   | (2 << 6),
 276    R6_OPC_DMOD   = OPC_DDIV   | (3 << 6),
 277    R6_OPC_DDIVU  = OPC_DDIVU  | (2 << 6),
 278    R6_OPC_DMODU  = OPC_DDIVU  | (3 << 6),
 279
 280    R6_OPC_CLZ      = 0x10 | OPC_SPECIAL,
 281    R6_OPC_CLO      = 0x11 | OPC_SPECIAL,
 282    R6_OPC_DCLZ     = 0x12 | OPC_SPECIAL,
 283    R6_OPC_DCLO     = 0x13 | OPC_SPECIAL,
 284    R6_OPC_SDBBP    = 0x0e | OPC_SPECIAL,
 285
 286    OPC_LSA  = 0x05 | OPC_SPECIAL,
 287    OPC_DLSA = 0x15 | OPC_SPECIAL,
 288};
 289
 290/* Multiplication variants of the vr54xx. */
 291#define MASK_MUL_VR54XX(op)   MASK_SPECIAL(op) | (op & (0x1F << 6))
 292
 293enum {
 294    OPC_VR54XX_MULS    = (0x03 << 6) | OPC_MULT,
 295    OPC_VR54XX_MULSU   = (0x03 << 6) | OPC_MULTU,
 296    OPC_VR54XX_MACC    = (0x05 << 6) | OPC_MULT,
 297    OPC_VR54XX_MACCU   = (0x05 << 6) | OPC_MULTU,
 298    OPC_VR54XX_MSAC    = (0x07 << 6) | OPC_MULT,
 299    OPC_VR54XX_MSACU   = (0x07 << 6) | OPC_MULTU,
 300    OPC_VR54XX_MULHI   = (0x09 << 6) | OPC_MULT,
 301    OPC_VR54XX_MULHIU  = (0x09 << 6) | OPC_MULTU,
 302    OPC_VR54XX_MULSHI  = (0x0B << 6) | OPC_MULT,
 303    OPC_VR54XX_MULSHIU = (0x0B << 6) | OPC_MULTU,
 304    OPC_VR54XX_MACCHI  = (0x0D << 6) | OPC_MULT,
 305    OPC_VR54XX_MACCHIU = (0x0D << 6) | OPC_MULTU,
 306    OPC_VR54XX_MSACHI  = (0x0F << 6) | OPC_MULT,
 307    OPC_VR54XX_MSACHIU = (0x0F << 6) | OPC_MULTU,
 308};
 309
 310/* REGIMM (rt field) opcodes */
 311#define MASK_REGIMM(op)    MASK_OP_MAJOR(op) | (op & (0x1F << 16))
 312
 313enum {
 314    OPC_BLTZ     = (0x00 << 16) | OPC_REGIMM,
 315    OPC_BLTZL    = (0x02 << 16) | OPC_REGIMM,
 316    OPC_BGEZ     = (0x01 << 16) | OPC_REGIMM,
 317    OPC_BGEZL    = (0x03 << 16) | OPC_REGIMM,
 318    OPC_BLTZAL   = (0x10 << 16) | OPC_REGIMM,
 319    OPC_BLTZALL  = (0x12 << 16) | OPC_REGIMM,
 320    OPC_BGEZAL   = (0x11 << 16) | OPC_REGIMM,
 321    OPC_BGEZALL  = (0x13 << 16) | OPC_REGIMM,
 322    OPC_TGEI     = (0x08 << 16) | OPC_REGIMM,
 323    OPC_TGEIU    = (0x09 << 16) | OPC_REGIMM,
 324    OPC_TLTI     = (0x0A << 16) | OPC_REGIMM,
 325    OPC_TLTIU    = (0x0B << 16) | OPC_REGIMM,
 326    OPC_TEQI     = (0x0C << 16) | OPC_REGIMM,
 327    OPC_TNEI     = (0x0E << 16) | OPC_REGIMM,
 328    OPC_SIGRIE   = (0x17 << 16) | OPC_REGIMM,
 329    OPC_SYNCI    = (0x1F << 16) | OPC_REGIMM,
 330
 331    OPC_DAHI     = (0x06 << 16) | OPC_REGIMM,
 332    OPC_DATI     = (0x1e << 16) | OPC_REGIMM,
 333};
 334
 335/* Special2 opcodes */
 336#define MASK_SPECIAL2(op)  MASK_OP_MAJOR(op) | (op & 0x3F)
 337
 338enum {
 339    /* Multiply & xxx operations */
 340    OPC_MADD     = 0x00 | OPC_SPECIAL2,
 341    OPC_MADDU    = 0x01 | OPC_SPECIAL2,
 342    OPC_MUL      = 0x02 | OPC_SPECIAL2,
 343    OPC_MSUB     = 0x04 | OPC_SPECIAL2,
 344    OPC_MSUBU    = 0x05 | OPC_SPECIAL2,
 345    /* Loongson 2F */
 346    OPC_MULT_G_2F   = 0x10 | OPC_SPECIAL2,
 347    OPC_DMULT_G_2F  = 0x11 | OPC_SPECIAL2,
 348    OPC_MULTU_G_2F  = 0x12 | OPC_SPECIAL2,
 349    OPC_DMULTU_G_2F = 0x13 | OPC_SPECIAL2,
 350    OPC_DIV_G_2F    = 0x14 | OPC_SPECIAL2,
 351    OPC_DDIV_G_2F   = 0x15 | OPC_SPECIAL2,
 352    OPC_DIVU_G_2F   = 0x16 | OPC_SPECIAL2,
 353    OPC_DDIVU_G_2F  = 0x17 | OPC_SPECIAL2,
 354    OPC_MOD_G_2F    = 0x1c | OPC_SPECIAL2,
 355    OPC_DMOD_G_2F   = 0x1d | OPC_SPECIAL2,
 356    OPC_MODU_G_2F   = 0x1e | OPC_SPECIAL2,
 357    OPC_DMODU_G_2F  = 0x1f | OPC_SPECIAL2,
 358    /* Misc */
 359    OPC_CLZ      = 0x20 | OPC_SPECIAL2,
 360    OPC_CLO      = 0x21 | OPC_SPECIAL2,
 361    OPC_DCLZ     = 0x24 | OPC_SPECIAL2,
 362    OPC_DCLO     = 0x25 | OPC_SPECIAL2,
 363    /* Special */
 364    OPC_SDBBP    = 0x3F | OPC_SPECIAL2,
 365};
 366
 367/* Special3 opcodes */
 368#define MASK_SPECIAL3(op)  MASK_OP_MAJOR(op) | (op & 0x3F)
 369
 370enum {
 371    OPC_EXT      = 0x00 | OPC_SPECIAL3,
 372    OPC_DEXTM    = 0x01 | OPC_SPECIAL3,
 373    OPC_DEXTU    = 0x02 | OPC_SPECIAL3,
 374    OPC_DEXT     = 0x03 | OPC_SPECIAL3,
 375    OPC_INS      = 0x04 | OPC_SPECIAL3,
 376    OPC_DINSM    = 0x05 | OPC_SPECIAL3,
 377    OPC_DINSU    = 0x06 | OPC_SPECIAL3,
 378    OPC_DINS     = 0x07 | OPC_SPECIAL3,
 379    OPC_FORK     = 0x08 | OPC_SPECIAL3,
 380    OPC_YIELD    = 0x09 | OPC_SPECIAL3,
 381    OPC_BSHFL    = 0x20 | OPC_SPECIAL3,
 382    OPC_DBSHFL   = 0x24 | OPC_SPECIAL3,
 383    OPC_RDHWR    = 0x3B | OPC_SPECIAL3,
 384
 385    /* Loongson 2E */
 386    OPC_MULT_G_2E   = 0x18 | OPC_SPECIAL3,
 387    OPC_MULTU_G_2E  = 0x19 | OPC_SPECIAL3,
 388    OPC_DIV_G_2E    = 0x1A | OPC_SPECIAL3,
 389    OPC_DIVU_G_2E   = 0x1B | OPC_SPECIAL3,
 390    OPC_DMULT_G_2E  = 0x1C | OPC_SPECIAL3,
 391    OPC_DMULTU_G_2E = 0x1D | OPC_SPECIAL3,
 392    OPC_DDIV_G_2E   = 0x1E | OPC_SPECIAL3,
 393    OPC_DDIVU_G_2E  = 0x1F | OPC_SPECIAL3,
 394    OPC_MOD_G_2E    = 0x22 | OPC_SPECIAL3,
 395    OPC_MODU_G_2E   = 0x23 | OPC_SPECIAL3,
 396    OPC_DMOD_G_2E   = 0x26 | OPC_SPECIAL3,
 397    OPC_DMODU_G_2E  = 0x27 | OPC_SPECIAL3,
 398
 399    /* MIPS DSP Load */
 400    OPC_LX_DSP         = 0x0A | OPC_SPECIAL3,
 401    /* MIPS DSP Arithmetic */
 402    OPC_ADDU_QB_DSP    = 0x10 | OPC_SPECIAL3,
 403    OPC_ADDU_OB_DSP    = 0x14 | OPC_SPECIAL3,
 404    OPC_ABSQ_S_PH_DSP  = 0x12 | OPC_SPECIAL3,
 405    OPC_ABSQ_S_QH_DSP  = 0x16 | OPC_SPECIAL3,
 406    /* OPC_ADDUH_QB_DSP is same as OPC_MULT_G_2E.  */
 407    /* OPC_ADDUH_QB_DSP   = 0x18 | OPC_SPECIAL3,  */
 408    OPC_CMPU_EQ_QB_DSP = 0x11 | OPC_SPECIAL3,
 409    OPC_CMPU_EQ_OB_DSP = 0x15 | OPC_SPECIAL3,
 410    /* MIPS DSP GPR-Based Shift Sub-class */
 411    OPC_SHLL_QB_DSP    = 0x13 | OPC_SPECIAL3,
 412    OPC_SHLL_OB_DSP    = 0x17 | OPC_SPECIAL3,
 413    /* MIPS DSP Multiply Sub-class insns */
 414    /* OPC_MUL_PH_DSP is same as OPC_ADDUH_QB_DSP.  */
 415    /* OPC_MUL_PH_DSP     = 0x18 | OPC_SPECIAL3,  */
 416    OPC_DPA_W_PH_DSP   = 0x30 | OPC_SPECIAL3,
 417    OPC_DPAQ_W_QH_DSP  = 0x34 | OPC_SPECIAL3,
 418    /* DSP Bit/Manipulation Sub-class */
 419    OPC_INSV_DSP       = 0x0C | OPC_SPECIAL3,
 420    OPC_DINSV_DSP      = 0x0D | OPC_SPECIAL3,
 421    /* MIPS DSP Append Sub-class */
 422    OPC_APPEND_DSP     = 0x31 | OPC_SPECIAL3,
 423    OPC_DAPPEND_DSP    = 0x35 | OPC_SPECIAL3,
 424    /* MIPS DSP Accumulator and DSPControl Access Sub-class */
 425    OPC_EXTR_W_DSP     = 0x38 | OPC_SPECIAL3,
 426    OPC_DEXTR_W_DSP    = 0x3C | OPC_SPECIAL3,
 427
 428    /* R6 */
 429    R6_OPC_PREF        = 0x35 | OPC_SPECIAL3,
 430    R6_OPC_CACHE       = 0x25 | OPC_SPECIAL3,
 431    R6_OPC_LL          = 0x36 | OPC_SPECIAL3,
 432    R6_OPC_SC          = 0x26 | OPC_SPECIAL3,
 433    R6_OPC_LLD         = 0x37 | OPC_SPECIAL3,
 434    R6_OPC_SCD         = 0x27 | OPC_SPECIAL3,
 435};
 436
 437/* BSHFL opcodes */
 438#define MASK_BSHFL(op)     MASK_SPECIAL3(op) | (op & (0x1F << 6))
 439
 440enum {
 441    OPC_WSBH      = (0x02 << 6) | OPC_BSHFL,
 442    OPC_SEB       = (0x10 << 6) | OPC_BSHFL,
 443    OPC_SEH       = (0x18 << 6) | OPC_BSHFL,
 444    OPC_ALIGN     = (0x08 << 6) | OPC_BSHFL, /* 010.bp */
 445    OPC_ALIGN_END = (0x0B << 6) | OPC_BSHFL, /* 010.00 to 010.11 */
 446    OPC_BITSWAP   = (0x00 << 6) | OPC_BSHFL  /* 00000 */
 447};
 448
 449/* DBSHFL opcodes */
 450#define MASK_DBSHFL(op)    MASK_SPECIAL3(op) | (op & (0x1F << 6))
 451
 452enum {
 453    OPC_DSBH       = (0x02 << 6) | OPC_DBSHFL,
 454    OPC_DSHD       = (0x05 << 6) | OPC_DBSHFL,
 455    OPC_DALIGN     = (0x08 << 6) | OPC_DBSHFL, /* 01.bp */
 456    OPC_DALIGN_END = (0x0F << 6) | OPC_DBSHFL, /* 01.000 to 01.111 */
 457    OPC_DBITSWAP   = (0x00 << 6) | OPC_DBSHFL, /* 00000 */
 458};
 459
 460/* MIPS DSP REGIMM opcodes */
 461enum {
 462    OPC_BPOSGE32 = (0x1C << 16) | OPC_REGIMM,
 463    OPC_BPOSGE64 = (0x1D << 16) | OPC_REGIMM,
 464};
 465
 466#define MASK_LX(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
 467/* MIPS DSP Load */
 468enum {
 469    OPC_LBUX = (0x06 << 6) | OPC_LX_DSP,
 470    OPC_LHX  = (0x04 << 6) | OPC_LX_DSP,
 471    OPC_LWX  = (0x00 << 6) | OPC_LX_DSP,
 472    OPC_LDX = (0x08 << 6) | OPC_LX_DSP,
 473};
 474
 475#define MASK_ADDU_QB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
 476enum {
 477    /* MIPS DSP Arithmetic Sub-class */
 478    OPC_ADDQ_PH        = (0x0A << 6) | OPC_ADDU_QB_DSP,
 479    OPC_ADDQ_S_PH      = (0x0E << 6) | OPC_ADDU_QB_DSP,
 480    OPC_ADDQ_S_W       = (0x16 << 6) | OPC_ADDU_QB_DSP,
 481    OPC_ADDU_QB        = (0x00 << 6) | OPC_ADDU_QB_DSP,
 482    OPC_ADDU_S_QB      = (0x04 << 6) | OPC_ADDU_QB_DSP,
 483    OPC_ADDU_PH        = (0x08 << 6) | OPC_ADDU_QB_DSP,
 484    OPC_ADDU_S_PH      = (0x0C << 6) | OPC_ADDU_QB_DSP,
 485    OPC_SUBQ_PH        = (0x0B << 6) | OPC_ADDU_QB_DSP,
 486    OPC_SUBQ_S_PH      = (0x0F << 6) | OPC_ADDU_QB_DSP,
 487    OPC_SUBQ_S_W       = (0x17 << 6) | OPC_ADDU_QB_DSP,
 488    OPC_SUBU_QB        = (0x01 << 6) | OPC_ADDU_QB_DSP,
 489    OPC_SUBU_S_QB      = (0x05 << 6) | OPC_ADDU_QB_DSP,
 490    OPC_SUBU_PH        = (0x09 << 6) | OPC_ADDU_QB_DSP,
 491    OPC_SUBU_S_PH      = (0x0D << 6) | OPC_ADDU_QB_DSP,
 492    OPC_ADDSC          = (0x10 << 6) | OPC_ADDU_QB_DSP,
 493    OPC_ADDWC          = (0x11 << 6) | OPC_ADDU_QB_DSP,
 494    OPC_MODSUB         = (0x12 << 6) | OPC_ADDU_QB_DSP,
 495    OPC_RADDU_W_QB     = (0x14 << 6) | OPC_ADDU_QB_DSP,
 496    /* MIPS DSP Multiply Sub-class insns */
 497    OPC_MULEU_S_PH_QBL = (0x06 << 6) | OPC_ADDU_QB_DSP,
 498    OPC_MULEU_S_PH_QBR = (0x07 << 6) | OPC_ADDU_QB_DSP,
 499    OPC_MULQ_RS_PH     = (0x1F << 6) | OPC_ADDU_QB_DSP,
 500    OPC_MULEQ_S_W_PHL  = (0x1C << 6) | OPC_ADDU_QB_DSP,
 501    OPC_MULEQ_S_W_PHR  = (0x1D << 6) | OPC_ADDU_QB_DSP,
 502    OPC_MULQ_S_PH      = (0x1E << 6) | OPC_ADDU_QB_DSP,
 503};
 504
 505#define OPC_ADDUH_QB_DSP OPC_MULT_G_2E
 506#define MASK_ADDUH_QB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
 507enum {
 508    /* MIPS DSP Arithmetic Sub-class */
 509    OPC_ADDUH_QB   = (0x00 << 6) | OPC_ADDUH_QB_DSP,
 510    OPC_ADDUH_R_QB = (0x02 << 6) | OPC_ADDUH_QB_DSP,
 511    OPC_ADDQH_PH   = (0x08 << 6) | OPC_ADDUH_QB_DSP,
 512    OPC_ADDQH_R_PH = (0x0A << 6) | OPC_ADDUH_QB_DSP,
 513    OPC_ADDQH_W    = (0x10 << 6) | OPC_ADDUH_QB_DSP,
 514    OPC_ADDQH_R_W  = (0x12 << 6) | OPC_ADDUH_QB_DSP,
 515    OPC_SUBUH_QB   = (0x01 << 6) | OPC_ADDUH_QB_DSP,
 516    OPC_SUBUH_R_QB = (0x03 << 6) | OPC_ADDUH_QB_DSP,
 517    OPC_SUBQH_PH   = (0x09 << 6) | OPC_ADDUH_QB_DSP,
 518    OPC_SUBQH_R_PH = (0x0B << 6) | OPC_ADDUH_QB_DSP,
 519    OPC_SUBQH_W    = (0x11 << 6) | OPC_ADDUH_QB_DSP,
 520    OPC_SUBQH_R_W  = (0x13 << 6) | OPC_ADDUH_QB_DSP,
 521    /* MIPS DSP Multiply Sub-class insns */
 522    OPC_MUL_PH     = (0x0C << 6) | OPC_ADDUH_QB_DSP,
 523    OPC_MUL_S_PH   = (0x0E << 6) | OPC_ADDUH_QB_DSP,
 524    OPC_MULQ_S_W   = (0x16 << 6) | OPC_ADDUH_QB_DSP,
 525    OPC_MULQ_RS_W  = (0x17 << 6) | OPC_ADDUH_QB_DSP,
 526};
 527
 528#define MASK_ABSQ_S_PH(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
 529enum {
 530    /* MIPS DSP Arithmetic Sub-class */
 531    OPC_ABSQ_S_QB       = (0x01 << 6) | OPC_ABSQ_S_PH_DSP,
 532    OPC_ABSQ_S_PH       = (0x09 << 6) | OPC_ABSQ_S_PH_DSP,
 533    OPC_ABSQ_S_W        = (0x11 << 6) | OPC_ABSQ_S_PH_DSP,
 534    OPC_PRECEQ_W_PHL    = (0x0C << 6) | OPC_ABSQ_S_PH_DSP,
 535    OPC_PRECEQ_W_PHR    = (0x0D << 6) | OPC_ABSQ_S_PH_DSP,
 536    OPC_PRECEQU_PH_QBL  = (0x04 << 6) | OPC_ABSQ_S_PH_DSP,
 537    OPC_PRECEQU_PH_QBR  = (0x05 << 6) | OPC_ABSQ_S_PH_DSP,
 538    OPC_PRECEQU_PH_QBLA = (0x06 << 6) | OPC_ABSQ_S_PH_DSP,
 539    OPC_PRECEQU_PH_QBRA = (0x07 << 6) | OPC_ABSQ_S_PH_DSP,
 540    OPC_PRECEU_PH_QBL   = (0x1C << 6) | OPC_ABSQ_S_PH_DSP,
 541    OPC_PRECEU_PH_QBR   = (0x1D << 6) | OPC_ABSQ_S_PH_DSP,
 542    OPC_PRECEU_PH_QBLA  = (0x1E << 6) | OPC_ABSQ_S_PH_DSP,
 543    OPC_PRECEU_PH_QBRA  = (0x1F << 6) | OPC_ABSQ_S_PH_DSP,
 544    /* DSP Bit/Manipulation Sub-class */
 545    OPC_BITREV          = (0x1B << 6) | OPC_ABSQ_S_PH_DSP,
 546    OPC_REPL_QB         = (0x02 << 6) | OPC_ABSQ_S_PH_DSP,
 547    OPC_REPLV_QB        = (0x03 << 6) | OPC_ABSQ_S_PH_DSP,
 548    OPC_REPL_PH         = (0x0A << 6) | OPC_ABSQ_S_PH_DSP,
 549    OPC_REPLV_PH        = (0x0B << 6) | OPC_ABSQ_S_PH_DSP,
 550};
 551
 552#define MASK_CMPU_EQ_QB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
 553enum {
 554    /* MIPS DSP Arithmetic Sub-class */
 555    OPC_PRECR_QB_PH      = (0x0D << 6) | OPC_CMPU_EQ_QB_DSP,
 556    OPC_PRECRQ_QB_PH     = (0x0C << 6) | OPC_CMPU_EQ_QB_DSP,
 557    OPC_PRECR_SRA_PH_W   = (0x1E << 6) | OPC_CMPU_EQ_QB_DSP,
 558    OPC_PRECR_SRA_R_PH_W = (0x1F << 6) | OPC_CMPU_EQ_QB_DSP,
 559    OPC_PRECRQ_PH_W      = (0x14 << 6) | OPC_CMPU_EQ_QB_DSP,
 560    OPC_PRECRQ_RS_PH_W   = (0x15 << 6) | OPC_CMPU_EQ_QB_DSP,
 561    OPC_PRECRQU_S_QB_PH  = (0x0F << 6) | OPC_CMPU_EQ_QB_DSP,
 562    /* DSP Compare-Pick Sub-class */
 563    OPC_CMPU_EQ_QB       = (0x00 << 6) | OPC_CMPU_EQ_QB_DSP,
 564    OPC_CMPU_LT_QB       = (0x01 << 6) | OPC_CMPU_EQ_QB_DSP,
 565    OPC_CMPU_LE_QB       = (0x02 << 6) | OPC_CMPU_EQ_QB_DSP,
 566    OPC_CMPGU_EQ_QB      = (0x04 << 6) | OPC_CMPU_EQ_QB_DSP,
 567    OPC_CMPGU_LT_QB      = (0x05 << 6) | OPC_CMPU_EQ_QB_DSP,
 568    OPC_CMPGU_LE_QB      = (0x06 << 6) | OPC_CMPU_EQ_QB_DSP,
 569    OPC_CMPGDU_EQ_QB     = (0x18 << 6) | OPC_CMPU_EQ_QB_DSP,
 570    OPC_CMPGDU_LT_QB     = (0x19 << 6) | OPC_CMPU_EQ_QB_DSP,
 571    OPC_CMPGDU_LE_QB     = (0x1A << 6) | OPC_CMPU_EQ_QB_DSP,
 572    OPC_CMP_EQ_PH        = (0x08 << 6) | OPC_CMPU_EQ_QB_DSP,
 573    OPC_CMP_LT_PH        = (0x09 << 6) | OPC_CMPU_EQ_QB_DSP,
 574    OPC_CMP_LE_PH        = (0x0A << 6) | OPC_CMPU_EQ_QB_DSP,
 575    OPC_PICK_QB          = (0x03 << 6) | OPC_CMPU_EQ_QB_DSP,
 576    OPC_PICK_PH          = (0x0B << 6) | OPC_CMPU_EQ_QB_DSP,
 577    OPC_PACKRL_PH        = (0x0E << 6) | OPC_CMPU_EQ_QB_DSP,
 578};
 579
 580#define MASK_SHLL_QB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
 581enum {
 582    /* MIPS DSP GPR-Based Shift Sub-class */
 583    OPC_SHLL_QB    = (0x00 << 6) | OPC_SHLL_QB_DSP,
 584    OPC_SHLLV_QB   = (0x02 << 6) | OPC_SHLL_QB_DSP,
 585    OPC_SHLL_PH    = (0x08 << 6) | OPC_SHLL_QB_DSP,
 586    OPC_SHLLV_PH   = (0x0A << 6) | OPC_SHLL_QB_DSP,
 587    OPC_SHLL_S_PH  = (0x0C << 6) | OPC_SHLL_QB_DSP,
 588    OPC_SHLLV_S_PH = (0x0E << 6) | OPC_SHLL_QB_DSP,
 589    OPC_SHLL_S_W   = (0x14 << 6) | OPC_SHLL_QB_DSP,
 590    OPC_SHLLV_S_W  = (0x16 << 6) | OPC_SHLL_QB_DSP,
 591    OPC_SHRL_QB    = (0x01 << 6) | OPC_SHLL_QB_DSP,
 592    OPC_SHRLV_QB   = (0x03 << 6) | OPC_SHLL_QB_DSP,
 593    OPC_SHRL_PH    = (0x19 << 6) | OPC_SHLL_QB_DSP,
 594    OPC_SHRLV_PH   = (0x1B << 6) | OPC_SHLL_QB_DSP,
 595    OPC_SHRA_QB    = (0x04 << 6) | OPC_SHLL_QB_DSP,
 596    OPC_SHRA_R_QB  = (0x05 << 6) | OPC_SHLL_QB_DSP,
 597    OPC_SHRAV_QB   = (0x06 << 6) | OPC_SHLL_QB_DSP,
 598    OPC_SHRAV_R_QB = (0x07 << 6) | OPC_SHLL_QB_DSP,
 599    OPC_SHRA_PH    = (0x09 << 6) | OPC_SHLL_QB_DSP,
 600    OPC_SHRAV_PH   = (0x0B << 6) | OPC_SHLL_QB_DSP,
 601    OPC_SHRA_R_PH  = (0x0D << 6) | OPC_SHLL_QB_DSP,
 602    OPC_SHRAV_R_PH = (0x0F << 6) | OPC_SHLL_QB_DSP,
 603    OPC_SHRA_R_W   = (0x15 << 6) | OPC_SHLL_QB_DSP,
 604    OPC_SHRAV_R_W  = (0x17 << 6) | OPC_SHLL_QB_DSP,
 605};
 606
 607#define MASK_DPA_W_PH(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
 608enum {
 609    /* MIPS DSP Multiply Sub-class insns */
 610    OPC_DPAU_H_QBL    = (0x03 << 6) | OPC_DPA_W_PH_DSP,
 611    OPC_DPAU_H_QBR    = (0x07 << 6) | OPC_DPA_W_PH_DSP,
 612    OPC_DPSU_H_QBL    = (0x0B << 6) | OPC_DPA_W_PH_DSP,
 613    OPC_DPSU_H_QBR    = (0x0F << 6) | OPC_DPA_W_PH_DSP,
 614    OPC_DPA_W_PH      = (0x00 << 6) | OPC_DPA_W_PH_DSP,
 615    OPC_DPAX_W_PH     = (0x08 << 6) | OPC_DPA_W_PH_DSP,
 616    OPC_DPAQ_S_W_PH   = (0x04 << 6) | OPC_DPA_W_PH_DSP,
 617    OPC_DPAQX_S_W_PH  = (0x18 << 6) | OPC_DPA_W_PH_DSP,
 618    OPC_DPAQX_SA_W_PH = (0x1A << 6) | OPC_DPA_W_PH_DSP,
 619    OPC_DPS_W_PH      = (0x01 << 6) | OPC_DPA_W_PH_DSP,
 620    OPC_DPSX_W_PH     = (0x09 << 6) | OPC_DPA_W_PH_DSP,
 621    OPC_DPSQ_S_W_PH   = (0x05 << 6) | OPC_DPA_W_PH_DSP,
 622    OPC_DPSQX_S_W_PH  = (0x19 << 6) | OPC_DPA_W_PH_DSP,
 623    OPC_DPSQX_SA_W_PH = (0x1B << 6) | OPC_DPA_W_PH_DSP,
 624    OPC_MULSAQ_S_W_PH = (0x06 << 6) | OPC_DPA_W_PH_DSP,
 625    OPC_DPAQ_SA_L_W   = (0x0C << 6) | OPC_DPA_W_PH_DSP,
 626    OPC_DPSQ_SA_L_W   = (0x0D << 6) | OPC_DPA_W_PH_DSP,
 627    OPC_MAQ_S_W_PHL   = (0x14 << 6) | OPC_DPA_W_PH_DSP,
 628    OPC_MAQ_S_W_PHR   = (0x16 << 6) | OPC_DPA_W_PH_DSP,
 629    OPC_MAQ_SA_W_PHL  = (0x10 << 6) | OPC_DPA_W_PH_DSP,
 630    OPC_MAQ_SA_W_PHR  = (0x12 << 6) | OPC_DPA_W_PH_DSP,
 631    OPC_MULSA_W_PH    = (0x02 << 6) | OPC_DPA_W_PH_DSP,
 632};
 633
 634#define MASK_INSV(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
 635enum {
 636    /* DSP Bit/Manipulation Sub-class */
 637    OPC_INSV = (0x00 << 6) | OPC_INSV_DSP,
 638};
 639
 640#define MASK_APPEND(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
 641enum {
 642    /* MIPS DSP Append Sub-class */
 643    OPC_APPEND  = (0x00 << 6) | OPC_APPEND_DSP,
 644    OPC_PREPEND = (0x01 << 6) | OPC_APPEND_DSP,
 645    OPC_BALIGN  = (0x10 << 6) | OPC_APPEND_DSP,
 646};
 647
 648#define MASK_EXTR_W(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
 649enum {
 650    /* MIPS DSP Accumulator and DSPControl Access Sub-class */
 651    OPC_EXTR_W     = (0x00 << 6) | OPC_EXTR_W_DSP,
 652    OPC_EXTR_R_W   = (0x04 << 6) | OPC_EXTR_W_DSP,
 653    OPC_EXTR_RS_W  = (0x06 << 6) | OPC_EXTR_W_DSP,
 654    OPC_EXTR_S_H   = (0x0E << 6) | OPC_EXTR_W_DSP,
 655    OPC_EXTRV_S_H  = (0x0F << 6) | OPC_EXTR_W_DSP,
 656    OPC_EXTRV_W    = (0x01 << 6) | OPC_EXTR_W_DSP,
 657    OPC_EXTRV_R_W  = (0x05 << 6) | OPC_EXTR_W_DSP,
 658    OPC_EXTRV_RS_W = (0x07 << 6) | OPC_EXTR_W_DSP,
 659    OPC_EXTP       = (0x02 << 6) | OPC_EXTR_W_DSP,
 660    OPC_EXTPV      = (0x03 << 6) | OPC_EXTR_W_DSP,
 661    OPC_EXTPDP     = (0x0A << 6) | OPC_EXTR_W_DSP,
 662    OPC_EXTPDPV    = (0x0B << 6) | OPC_EXTR_W_DSP,
 663    OPC_SHILO      = (0x1A << 6) | OPC_EXTR_W_DSP,
 664    OPC_SHILOV     = (0x1B << 6) | OPC_EXTR_W_DSP,
 665    OPC_MTHLIP     = (0x1F << 6) | OPC_EXTR_W_DSP,
 666    OPC_WRDSP      = (0x13 << 6) | OPC_EXTR_W_DSP,
 667    OPC_RDDSP      = (0x12 << 6) | OPC_EXTR_W_DSP,
 668};
 669
 670#define MASK_ABSQ_S_QH(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
 671enum {
 672    /* MIPS DSP Arithmetic Sub-class */
 673    OPC_PRECEQ_L_PWL    = (0x14 << 6) | OPC_ABSQ_S_QH_DSP,
 674    OPC_PRECEQ_L_PWR    = (0x15 << 6) | OPC_ABSQ_S_QH_DSP,
 675    OPC_PRECEQ_PW_QHL   = (0x0C << 6) | OPC_ABSQ_S_QH_DSP,
 676    OPC_PRECEQ_PW_QHR   = (0x0D << 6) | OPC_ABSQ_S_QH_DSP,
 677    OPC_PRECEQ_PW_QHLA  = (0x0E << 6) | OPC_ABSQ_S_QH_DSP,
 678    OPC_PRECEQ_PW_QHRA  = (0x0F << 6) | OPC_ABSQ_S_QH_DSP,
 679    OPC_PRECEQU_QH_OBL  = (0x04 << 6) | OPC_ABSQ_S_QH_DSP,
 680    OPC_PRECEQU_QH_OBR  = (0x05 << 6) | OPC_ABSQ_S_QH_DSP,
 681    OPC_PRECEQU_QH_OBLA = (0x06 << 6) | OPC_ABSQ_S_QH_DSP,
 682    OPC_PRECEQU_QH_OBRA = (0x07 << 6) | OPC_ABSQ_S_QH_DSP,
 683    OPC_PRECEU_QH_OBL   = (0x1C << 6) | OPC_ABSQ_S_QH_DSP,
 684    OPC_PRECEU_QH_OBR   = (0x1D << 6) | OPC_ABSQ_S_QH_DSP,
 685    OPC_PRECEU_QH_OBLA  = (0x1E << 6) | OPC_ABSQ_S_QH_DSP,
 686    OPC_PRECEU_QH_OBRA  = (0x1F << 6) | OPC_ABSQ_S_QH_DSP,
 687    OPC_ABSQ_S_OB       = (0x01 << 6) | OPC_ABSQ_S_QH_DSP,
 688    OPC_ABSQ_S_PW       = (0x11 << 6) | OPC_ABSQ_S_QH_DSP,
 689    OPC_ABSQ_S_QH       = (0x09 << 6) | OPC_ABSQ_S_QH_DSP,
 690    /* DSP Bit/Manipulation Sub-class */
 691    OPC_REPL_OB         = (0x02 << 6) | OPC_ABSQ_S_QH_DSP,
 692    OPC_REPL_PW         = (0x12 << 6) | OPC_ABSQ_S_QH_DSP,
 693    OPC_REPL_QH         = (0x0A << 6) | OPC_ABSQ_S_QH_DSP,
 694    OPC_REPLV_OB        = (0x03 << 6) | OPC_ABSQ_S_QH_DSP,
 695    OPC_REPLV_PW        = (0x13 << 6) | OPC_ABSQ_S_QH_DSP,
 696    OPC_REPLV_QH        = (0x0B << 6) | OPC_ABSQ_S_QH_DSP,
 697};
 698
 699#define MASK_ADDU_OB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
 700enum {
 701    /* MIPS DSP Multiply Sub-class insns */
 702    OPC_MULEQ_S_PW_QHL = (0x1C << 6) | OPC_ADDU_OB_DSP,
 703    OPC_MULEQ_S_PW_QHR = (0x1D << 6) | OPC_ADDU_OB_DSP,
 704    OPC_MULEU_S_QH_OBL = (0x06 << 6) | OPC_ADDU_OB_DSP,
 705    OPC_MULEU_S_QH_OBR = (0x07 << 6) | OPC_ADDU_OB_DSP,
 706    OPC_MULQ_RS_QH     = (0x1F << 6) | OPC_ADDU_OB_DSP,
 707    /* MIPS DSP Arithmetic Sub-class */
 708    OPC_RADDU_L_OB     = (0x14 << 6) | OPC_ADDU_OB_DSP,
 709    OPC_SUBQ_PW        = (0x13 << 6) | OPC_ADDU_OB_DSP,
 710    OPC_SUBQ_S_PW      = (0x17 << 6) | OPC_ADDU_OB_DSP,
 711    OPC_SUBQ_QH        = (0x0B << 6) | OPC_ADDU_OB_DSP,
 712    OPC_SUBQ_S_QH      = (0x0F << 6) | OPC_ADDU_OB_DSP,
 713    OPC_SUBU_OB        = (0x01 << 6) | OPC_ADDU_OB_DSP,
 714    OPC_SUBU_S_OB      = (0x05 << 6) | OPC_ADDU_OB_DSP,
 715    OPC_SUBU_QH        = (0x09 << 6) | OPC_ADDU_OB_DSP,
 716    OPC_SUBU_S_QH      = (0x0D << 6) | OPC_ADDU_OB_DSP,
 717    OPC_SUBUH_OB       = (0x19 << 6) | OPC_ADDU_OB_DSP,
 718    OPC_SUBUH_R_OB     = (0x1B << 6) | OPC_ADDU_OB_DSP,
 719    OPC_ADDQ_PW        = (0x12 << 6) | OPC_ADDU_OB_DSP,
 720    OPC_ADDQ_S_PW      = (0x16 << 6) | OPC_ADDU_OB_DSP,
 721    OPC_ADDQ_QH        = (0x0A << 6) | OPC_ADDU_OB_DSP,
 722    OPC_ADDQ_S_QH      = (0x0E << 6) | OPC_ADDU_OB_DSP,
 723    OPC_ADDU_OB        = (0x00 << 6) | OPC_ADDU_OB_DSP,
 724    OPC_ADDU_S_OB      = (0x04 << 6) | OPC_ADDU_OB_DSP,
 725    OPC_ADDU_QH        = (0x08 << 6) | OPC_ADDU_OB_DSP,
 726    OPC_ADDU_S_QH      = (0x0C << 6) | OPC_ADDU_OB_DSP,
 727    OPC_ADDUH_OB       = (0x18 << 6) | OPC_ADDU_OB_DSP,
 728    OPC_ADDUH_R_OB     = (0x1A << 6) | OPC_ADDU_OB_DSP,
 729};
 730
 731#define MASK_CMPU_EQ_OB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
 732enum {
 733    /* DSP Compare-Pick Sub-class */
 734    OPC_CMP_EQ_PW         = (0x10 << 6) | OPC_CMPU_EQ_OB_DSP,
 735    OPC_CMP_LT_PW         = (0x11 << 6) | OPC_CMPU_EQ_OB_DSP,
 736    OPC_CMP_LE_PW         = (0x12 << 6) | OPC_CMPU_EQ_OB_DSP,
 737    OPC_CMP_EQ_QH         = (0x08 << 6) | OPC_CMPU_EQ_OB_DSP,
 738    OPC_CMP_LT_QH         = (0x09 << 6) | OPC_CMPU_EQ_OB_DSP,
 739    OPC_CMP_LE_QH         = (0x0A << 6) | OPC_CMPU_EQ_OB_DSP,
 740    OPC_CMPGDU_EQ_OB      = (0x18 << 6) | OPC_CMPU_EQ_OB_DSP,
 741    OPC_CMPGDU_LT_OB      = (0x19 << 6) | OPC_CMPU_EQ_OB_DSP,
 742    OPC_CMPGDU_LE_OB      = (0x1A << 6) | OPC_CMPU_EQ_OB_DSP,
 743    OPC_CMPGU_EQ_OB       = (0x04 << 6) | OPC_CMPU_EQ_OB_DSP,
 744    OPC_CMPGU_LT_OB       = (0x05 << 6) | OPC_CMPU_EQ_OB_DSP,
 745    OPC_CMPGU_LE_OB       = (0x06 << 6) | OPC_CMPU_EQ_OB_DSP,
 746    OPC_CMPU_EQ_OB        = (0x00 << 6) | OPC_CMPU_EQ_OB_DSP,
 747    OPC_CMPU_LT_OB        = (0x01 << 6) | OPC_CMPU_EQ_OB_DSP,
 748    OPC_CMPU_LE_OB        = (0x02 << 6) | OPC_CMPU_EQ_OB_DSP,
 749    OPC_PACKRL_PW         = (0x0E << 6) | OPC_CMPU_EQ_OB_DSP,
 750    OPC_PICK_OB           = (0x03 << 6) | OPC_CMPU_EQ_OB_DSP,
 751    OPC_PICK_PW           = (0x13 << 6) | OPC_CMPU_EQ_OB_DSP,
 752    OPC_PICK_QH           = (0x0B << 6) | OPC_CMPU_EQ_OB_DSP,
 753    /* MIPS DSP Arithmetic Sub-class */
 754    OPC_PRECR_OB_QH       = (0x0D << 6) | OPC_CMPU_EQ_OB_DSP,
 755    OPC_PRECR_SRA_QH_PW   = (0x1E << 6) | OPC_CMPU_EQ_OB_DSP,
 756    OPC_PRECR_SRA_R_QH_PW = (0x1F << 6) | OPC_CMPU_EQ_OB_DSP,
 757    OPC_PRECRQ_OB_QH      = (0x0C << 6) | OPC_CMPU_EQ_OB_DSP,
 758    OPC_PRECRQ_PW_L       = (0x1C << 6) | OPC_CMPU_EQ_OB_DSP,
 759    OPC_PRECRQ_QH_PW      = (0x14 << 6) | OPC_CMPU_EQ_OB_DSP,
 760    OPC_PRECRQ_RS_QH_PW   = (0x15 << 6) | OPC_CMPU_EQ_OB_DSP,
 761    OPC_PRECRQU_S_OB_QH   = (0x0F << 6) | OPC_CMPU_EQ_OB_DSP,
 762};
 763
 764#define MASK_DAPPEND(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
 765enum {
 766    /* DSP Append Sub-class */
 767    OPC_DAPPEND  = (0x00 << 6) | OPC_DAPPEND_DSP,
 768    OPC_PREPENDD = (0x03 << 6) | OPC_DAPPEND_DSP,
 769    OPC_PREPENDW = (0x01 << 6) | OPC_DAPPEND_DSP,
 770    OPC_DBALIGN  = (0x10 << 6) | OPC_DAPPEND_DSP,
 771};
 772
 773#define MASK_DEXTR_W(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
 774enum {
 775    /* MIPS DSP Accumulator and DSPControl Access Sub-class */
 776    OPC_DMTHLIP     = (0x1F << 6) | OPC_DEXTR_W_DSP,
 777    OPC_DSHILO      = (0x1A << 6) | OPC_DEXTR_W_DSP,
 778    OPC_DEXTP       = (0x02 << 6) | OPC_DEXTR_W_DSP,
 779    OPC_DEXTPDP     = (0x0A << 6) | OPC_DEXTR_W_DSP,
 780    OPC_DEXTPDPV    = (0x0B << 6) | OPC_DEXTR_W_DSP,
 781    OPC_DEXTPV      = (0x03 << 6) | OPC_DEXTR_W_DSP,
 782    OPC_DEXTR_L     = (0x10 << 6) | OPC_DEXTR_W_DSP,
 783    OPC_DEXTR_R_L   = (0x14 << 6) | OPC_DEXTR_W_DSP,
 784    OPC_DEXTR_RS_L  = (0x16 << 6) | OPC_DEXTR_W_DSP,
 785    OPC_DEXTR_W     = (0x00 << 6) | OPC_DEXTR_W_DSP,
 786    OPC_DEXTR_R_W   = (0x04 << 6) | OPC_DEXTR_W_DSP,
 787    OPC_DEXTR_RS_W  = (0x06 << 6) | OPC_DEXTR_W_DSP,
 788    OPC_DEXTR_S_H   = (0x0E << 6) | OPC_DEXTR_W_DSP,
 789    OPC_DEXTRV_L    = (0x11 << 6) | OPC_DEXTR_W_DSP,
 790    OPC_DEXTRV_R_L  = (0x15 << 6) | OPC_DEXTR_W_DSP,
 791    OPC_DEXTRV_RS_L = (0x17 << 6) | OPC_DEXTR_W_DSP,
 792    OPC_DEXTRV_S_H  = (0x0F << 6) | OPC_DEXTR_W_DSP,
 793    OPC_DEXTRV_W    = (0x01 << 6) | OPC_DEXTR_W_DSP,
 794    OPC_DEXTRV_R_W  = (0x05 << 6) | OPC_DEXTR_W_DSP,
 795    OPC_DEXTRV_RS_W = (0x07 << 6) | OPC_DEXTR_W_DSP,
 796    OPC_DSHILOV     = (0x1B << 6) | OPC_DEXTR_W_DSP,
 797};
 798
 799#define MASK_DINSV(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
 800enum {
 801    /* DSP Bit/Manipulation Sub-class */
 802    OPC_DINSV = (0x00 << 6) | OPC_DINSV_DSP,
 803};
 804
 805#define MASK_DPAQ_W_QH(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
 806enum {
 807    /* MIPS DSP Multiply Sub-class insns */
 808    OPC_DMADD         = (0x19 << 6) | OPC_DPAQ_W_QH_DSP,
 809    OPC_DMADDU        = (0x1D << 6) | OPC_DPAQ_W_QH_DSP,
 810    OPC_DMSUB         = (0x1B << 6) | OPC_DPAQ_W_QH_DSP,
 811    OPC_DMSUBU        = (0x1F << 6) | OPC_DPAQ_W_QH_DSP,
 812    OPC_DPA_W_QH      = (0x00 << 6) | OPC_DPAQ_W_QH_DSP,
 813    OPC_DPAQ_S_W_QH   = (0x04 << 6) | OPC_DPAQ_W_QH_DSP,
 814    OPC_DPAQ_SA_L_PW  = (0x0C << 6) | OPC_DPAQ_W_QH_DSP,
 815    OPC_DPAU_H_OBL    = (0x03 << 6) | OPC_DPAQ_W_QH_DSP,
 816    OPC_DPAU_H_OBR    = (0x07 << 6) | OPC_DPAQ_W_QH_DSP,
 817    OPC_DPS_W_QH      = (0x01 << 6) | OPC_DPAQ_W_QH_DSP,
 818    OPC_DPSQ_S_W_QH   = (0x05 << 6) | OPC_DPAQ_W_QH_DSP,
 819    OPC_DPSQ_SA_L_PW  = (0x0D << 6) | OPC_DPAQ_W_QH_DSP,
 820    OPC_DPSU_H_OBL    = (0x0B << 6) | OPC_DPAQ_W_QH_DSP,
 821    OPC_DPSU_H_OBR    = (0x0F << 6) | OPC_DPAQ_W_QH_DSP,
 822    OPC_MAQ_S_L_PWL   = (0x1C << 6) | OPC_DPAQ_W_QH_DSP,
 823    OPC_MAQ_S_L_PWR   = (0x1E << 6) | OPC_DPAQ_W_QH_DSP,
 824    OPC_MAQ_S_W_QHLL  = (0x14 << 6) | OPC_DPAQ_W_QH_DSP,
 825    OPC_MAQ_SA_W_QHLL = (0x10 << 6) | OPC_DPAQ_W_QH_DSP,
 826    OPC_MAQ_S_W_QHLR  = (0x15 << 6) | OPC_DPAQ_W_QH_DSP,
 827    OPC_MAQ_SA_W_QHLR = (0x11 << 6) | OPC_DPAQ_W_QH_DSP,
 828    OPC_MAQ_S_W_QHRL  = (0x16 << 6) | OPC_DPAQ_W_QH_DSP,
 829    OPC_MAQ_SA_W_QHRL = (0x12 << 6) | OPC_DPAQ_W_QH_DSP,
 830    OPC_MAQ_S_W_QHRR  = (0x17 << 6) | OPC_DPAQ_W_QH_DSP,
 831    OPC_MAQ_SA_W_QHRR = (0x13 << 6) | OPC_DPAQ_W_QH_DSP,
 832    OPC_MULSAQ_S_L_PW = (0x0E << 6) | OPC_DPAQ_W_QH_DSP,
 833    OPC_MULSAQ_S_W_QH = (0x06 << 6) | OPC_DPAQ_W_QH_DSP,
 834};
 835
 836#define MASK_SHLL_OB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
 837enum {
 838    /* MIPS DSP GPR-Based Shift Sub-class */
 839    OPC_SHLL_PW    = (0x10 << 6) | OPC_SHLL_OB_DSP,
 840    OPC_SHLL_S_PW  = (0x14 << 6) | OPC_SHLL_OB_DSP,
 841    OPC_SHLLV_OB   = (0x02 << 6) | OPC_SHLL_OB_DSP,
 842    OPC_SHLLV_PW   = (0x12 << 6) | OPC_SHLL_OB_DSP,
 843    OPC_SHLLV_S_PW = (0x16 << 6) | OPC_SHLL_OB_DSP,
 844    OPC_SHLLV_QH   = (0x0A << 6) | OPC_SHLL_OB_DSP,
 845    OPC_SHLLV_S_QH = (0x0E << 6) | OPC_SHLL_OB_DSP,
 846    OPC_SHRA_PW    = (0x11 << 6) | OPC_SHLL_OB_DSP,
 847    OPC_SHRA_R_PW  = (0x15 << 6) | OPC_SHLL_OB_DSP,
 848    OPC_SHRAV_OB   = (0x06 << 6) | OPC_SHLL_OB_DSP,
 849    OPC_SHRAV_R_OB = (0x07 << 6) | OPC_SHLL_OB_DSP,
 850    OPC_SHRAV_PW   = (0x13 << 6) | OPC_SHLL_OB_DSP,
 851    OPC_SHRAV_R_PW = (0x17 << 6) | OPC_SHLL_OB_DSP,
 852    OPC_SHRAV_QH   = (0x0B << 6) | OPC_SHLL_OB_DSP,
 853    OPC_SHRAV_R_QH = (0x0F << 6) | OPC_SHLL_OB_DSP,
 854    OPC_SHRLV_OB   = (0x03 << 6) | OPC_SHLL_OB_DSP,
 855    OPC_SHRLV_QH   = (0x1B << 6) | OPC_SHLL_OB_DSP,
 856    OPC_SHLL_OB    = (0x00 << 6) | OPC_SHLL_OB_DSP,
 857    OPC_SHLL_QH    = (0x08 << 6) | OPC_SHLL_OB_DSP,
 858    OPC_SHLL_S_QH  = (0x0C << 6) | OPC_SHLL_OB_DSP,
 859    OPC_SHRA_OB    = (0x04 << 6) | OPC_SHLL_OB_DSP,
 860    OPC_SHRA_R_OB  = (0x05 << 6) | OPC_SHLL_OB_DSP,
 861    OPC_SHRA_QH    = (0x09 << 6) | OPC_SHLL_OB_DSP,
 862    OPC_SHRA_R_QH  = (0x0D << 6) | OPC_SHLL_OB_DSP,
 863    OPC_SHRL_OB    = (0x01 << 6) | OPC_SHLL_OB_DSP,
 864    OPC_SHRL_QH    = (0x19 << 6) | OPC_SHLL_OB_DSP,
 865};
 866
 867/* Coprocessor 0 (rs field) */
 868#define MASK_CP0(op)       MASK_OP_MAJOR(op) | (op & (0x1F << 21))
 869
 870enum {
 871    OPC_MFC0     = (0x00 << 21) | OPC_CP0,
 872    OPC_DMFC0    = (0x01 << 21) | OPC_CP0,
 873    OPC_MFHC0    = (0x02 << 21) | OPC_CP0,
 874    OPC_MTC0     = (0x04 << 21) | OPC_CP0,
 875    OPC_DMTC0    = (0x05 << 21) | OPC_CP0,
 876    OPC_MTHC0    = (0x06 << 21) | OPC_CP0,
 877    OPC_MFTR     = (0x08 << 21) | OPC_CP0,
 878    OPC_RDPGPR   = (0x0A << 21) | OPC_CP0,
 879    OPC_MFMC0    = (0x0B << 21) | OPC_CP0,
 880    OPC_MTTR     = (0x0C << 21) | OPC_CP0,
 881    OPC_WRPGPR   = (0x0E << 21) | OPC_CP0,
 882    OPC_C0       = (0x10 << 21) | OPC_CP0,
 883    OPC_C0_FIRST = (0x10 << 21) | OPC_CP0,
 884    OPC_C0_LAST  = (0x1F << 21) | OPC_CP0,
 885};
 886
 887/* MFMC0 opcodes */
 888#define MASK_MFMC0(op)     MASK_CP0(op) | (op & 0xFFFF)
 889
 890enum {
 891    OPC_DMT      = 0x01 | (0 << 5) | (0x0F << 6) | (0x01 << 11) | OPC_MFMC0,
 892    OPC_EMT      = 0x01 | (1 << 5) | (0x0F << 6) | (0x01 << 11) | OPC_MFMC0,
 893    OPC_DVPE     = 0x01 | (0 << 5) | OPC_MFMC0,
 894    OPC_EVPE     = 0x01 | (1 << 5) | OPC_MFMC0,
 895    OPC_DI       = (0 << 5) | (0x0C << 11) | OPC_MFMC0,
 896    OPC_EI       = (1 << 5) | (0x0C << 11) | OPC_MFMC0,
 897    OPC_DVP      = 0x04 | (0 << 3) | (1 << 5) | (0 << 11) | OPC_MFMC0,
 898    OPC_EVP      = 0x04 | (0 << 3) | (0 << 5) | (0 << 11) | OPC_MFMC0,
 899};
 900
 901/* Coprocessor 0 (with rs == C0) */
 902#define MASK_C0(op)        MASK_CP0(op) | (op & 0x3F)
 903
 904enum {
 905    OPC_TLBR     = 0x01 | OPC_C0,
 906    OPC_TLBWI    = 0x02 | OPC_C0,
 907    OPC_TLBINV   = 0x03 | OPC_C0,
 908    OPC_TLBINVF  = 0x04 | OPC_C0,
 909    OPC_TLBWR    = 0x06 | OPC_C0,
 910    OPC_TLBP     = 0x08 | OPC_C0,
 911    OPC_RFE      = 0x10 | OPC_C0,
 912    OPC_ERET     = 0x18 | OPC_C0,
 913    OPC_DERET    = 0x1F | OPC_C0,
 914    OPC_WAIT     = 0x20 | OPC_C0,
 915};
 916
 917/* Coprocessor 1 (rs field) */
 918#define MASK_CP1(op)       MASK_OP_MAJOR(op) | (op & (0x1F << 21))
 919
 920/* Values for the fmt field in FP instructions */
 921enum {
 922    /* 0 - 15 are reserved */
 923    FMT_S = 16,          /* single fp */
 924    FMT_D = 17,          /* double fp */
 925    FMT_E = 18,          /* extended fp */
 926    FMT_Q = 19,          /* quad fp */
 927    FMT_W = 20,          /* 32-bit fixed */
 928    FMT_L = 21,          /* 64-bit fixed */
 929    FMT_PS = 22,         /* paired single fp */
 930    /* 23 - 31 are reserved */
 931};
 932
 933enum {
 934    OPC_MFC1     = (0x00 << 21) | OPC_CP1,
 935    OPC_DMFC1    = (0x01 << 21) | OPC_CP1,
 936    OPC_CFC1     = (0x02 << 21) | OPC_CP1,
 937    OPC_MFHC1    = (0x03 << 21) | OPC_CP1,
 938    OPC_MTC1     = (0x04 << 21) | OPC_CP1,
 939    OPC_DMTC1    = (0x05 << 21) | OPC_CP1,
 940    OPC_CTC1     = (0x06 << 21) | OPC_CP1,
 941    OPC_MTHC1    = (0x07 << 21) | OPC_CP1,
 942    OPC_BC1      = (0x08 << 21) | OPC_CP1, /* bc */
 943    OPC_BC1ANY2  = (0x09 << 21) | OPC_CP1,
 944    OPC_BC1ANY4  = (0x0A << 21) | OPC_CP1,
 945    OPC_BZ_V     = (0x0B << 21) | OPC_CP1,
 946    OPC_BNZ_V    = (0x0F << 21) | OPC_CP1,
 947    OPC_S_FMT    = (FMT_S << 21) | OPC_CP1,
 948    OPC_D_FMT    = (FMT_D << 21) | OPC_CP1,
 949    OPC_E_FMT    = (FMT_E << 21) | OPC_CP1,
 950    OPC_Q_FMT    = (FMT_Q << 21) | OPC_CP1,
 951    OPC_W_FMT    = (FMT_W << 21) | OPC_CP1,
 952    OPC_L_FMT    = (FMT_L << 21) | OPC_CP1,
 953    OPC_PS_FMT   = (FMT_PS << 21) | OPC_CP1,
 954    OPC_BC1EQZ   = (0x09 << 21) | OPC_CP1,
 955    OPC_BC1NEZ   = (0x0D << 21) | OPC_CP1,
 956    OPC_BZ_B     = (0x18 << 21) | OPC_CP1,
 957    OPC_BZ_H     = (0x19 << 21) | OPC_CP1,
 958    OPC_BZ_W     = (0x1A << 21) | OPC_CP1,
 959    OPC_BZ_D     = (0x1B << 21) | OPC_CP1,
 960    OPC_BNZ_B    = (0x1C << 21) | OPC_CP1,
 961    OPC_BNZ_H    = (0x1D << 21) | OPC_CP1,
 962    OPC_BNZ_W    = (0x1E << 21) | OPC_CP1,
 963    OPC_BNZ_D    = (0x1F << 21) | OPC_CP1,
 964};
 965
 966#define MASK_CP1_FUNC(op)       MASK_CP1(op) | (op & 0x3F)
 967#define MASK_BC1(op)            MASK_CP1(op) | (op & (0x3 << 16))
 968
 969enum {
 970    OPC_BC1F     = (0x00 << 16) | OPC_BC1,
 971    OPC_BC1T     = (0x01 << 16) | OPC_BC1,
 972    OPC_BC1FL    = (0x02 << 16) | OPC_BC1,
 973    OPC_BC1TL    = (0x03 << 16) | OPC_BC1,
 974};
 975
 976enum {
 977    OPC_BC1FANY2     = (0x00 << 16) | OPC_BC1ANY2,
 978    OPC_BC1TANY2     = (0x01 << 16) | OPC_BC1ANY2,
 979};
 980
 981enum {
 982    OPC_BC1FANY4     = (0x00 << 16) | OPC_BC1ANY4,
 983    OPC_BC1TANY4     = (0x01 << 16) | OPC_BC1ANY4,
 984};
 985
 986#define MASK_CP2(op)       MASK_OP_MAJOR(op) | (op & (0x1F << 21))
 987
 988enum {
 989    OPC_MFC2    = (0x00 << 21) | OPC_CP2,
 990    OPC_DMFC2   = (0x01 << 21) | OPC_CP2,
 991    OPC_CFC2    = (0x02 << 21) | OPC_CP2,
 992    OPC_MFHC2   = (0x03 << 21) | OPC_CP2,
 993    OPC_MTC2    = (0x04 << 21) | OPC_CP2,
 994    OPC_DMTC2   = (0x05 << 21) | OPC_CP2,
 995    OPC_CTC2    = (0x06 << 21) | OPC_CP2,
 996    OPC_MTHC2   = (0x07 << 21) | OPC_CP2,
 997    OPC_BC2     = (0x08 << 21) | OPC_CP2,
 998    OPC_BC2EQZ  = (0x09 << 21) | OPC_CP2,
 999    OPC_BC2NEZ  = (0x0D << 21) | OPC_CP2,
1000};
1001
1002#define MASK_LMI(op)  (MASK_OP_MAJOR(op) | (op & (0x1F << 21)) | (op & 0x1F))
1003
1004enum {
1005    OPC_PADDSH  = (24 << 21) | (0x00) | OPC_CP2,
1006    OPC_PADDUSH = (25 << 21) | (0x00) | OPC_CP2,
1007    OPC_PADDH   = (26 << 21) | (0x00) | OPC_CP2,
1008    OPC_PADDW   = (27 << 21) | (0x00) | OPC_CP2,
1009    OPC_PADDSB  = (28 << 21) | (0x00) | OPC_CP2,
1010    OPC_PADDUSB = (29 << 21) | (0x00) | OPC_CP2,
1011    OPC_PADDB   = (30 << 21) | (0x00) | OPC_CP2,
1012    OPC_PADDD   = (31 << 21) | (0x00) | OPC_CP2,
1013
1014    OPC_PSUBSH  = (24 << 21) | (0x01) | OPC_CP2,
1015    OPC_PSUBUSH = (25 << 21) | (0x01) | OPC_CP2,
1016    OPC_PSUBH   = (26 << 21) | (0x01) | OPC_CP2,
1017    OPC_PSUBW   = (27 << 21) | (0x01) | OPC_CP2,
1018    OPC_PSUBSB  = (28 << 21) | (0x01) | OPC_CP2,
1019    OPC_PSUBUSB = (29 << 21) | (0x01) | OPC_CP2,
1020    OPC_PSUBB   = (30 << 21) | (0x01) | OPC_CP2,
1021    OPC_PSUBD   = (31 << 21) | (0x01) | OPC_CP2,
1022
1023    OPC_PSHUFH   = (24 << 21) | (0x02) | OPC_CP2,
1024    OPC_PACKSSWH = (25 << 21) | (0x02) | OPC_CP2,
1025    OPC_PACKSSHB = (26 << 21) | (0x02) | OPC_CP2,
1026    OPC_PACKUSHB = (27 << 21) | (0x02) | OPC_CP2,
1027    OPC_XOR_CP2  = (28 << 21) | (0x02) | OPC_CP2,
1028    OPC_NOR_CP2  = (29 << 21) | (0x02) | OPC_CP2,
1029    OPC_AND_CP2  = (30 << 21) | (0x02) | OPC_CP2,
1030    OPC_PANDN    = (31 << 21) | (0x02) | OPC_CP2,
1031
1032    OPC_PUNPCKLHW = (24 << 21) | (0x03) | OPC_CP2,
1033    OPC_PUNPCKHHW = (25 << 21) | (0x03) | OPC_CP2,
1034    OPC_PUNPCKLBH = (26 << 21) | (0x03) | OPC_CP2,
1035    OPC_PUNPCKHBH = (27 << 21) | (0x03) | OPC_CP2,
1036    OPC_PINSRH_0  = (28 << 21) | (0x03) | OPC_CP2,
1037    OPC_PINSRH_1  = (29 << 21) | (0x03) | OPC_CP2,
1038    OPC_PINSRH_2  = (30 << 21) | (0x03) | OPC_CP2,
1039    OPC_PINSRH_3  = (31 << 21) | (0x03) | OPC_CP2,
1040
1041    OPC_PAVGH   = (24 << 21) | (0x08) | OPC_CP2,
1042    OPC_PAVGB   = (25 << 21) | (0x08) | OPC_CP2,
1043    OPC_PMAXSH  = (26 << 21) | (0x08) | OPC_CP2,
1044    OPC_PMINSH  = (27 << 21) | (0x08) | OPC_CP2,
1045    OPC_PMAXUB  = (28 << 21) | (0x08) | OPC_CP2,
1046    OPC_PMINUB  = (29 << 21) | (0x08) | OPC_CP2,
1047
1048    OPC_PCMPEQW = (24 << 21) | (0x09) | OPC_CP2,
1049    OPC_PCMPGTW = (25 << 21) | (0x09) | OPC_CP2,
1050    OPC_PCMPEQH = (26 << 21) | (0x09) | OPC_CP2,
1051    OPC_PCMPGTH = (27 << 21) | (0x09) | OPC_CP2,
1052    OPC_PCMPEQB = (28 << 21) | (0x09) | OPC_CP2,
1053    OPC_PCMPGTB = (29 << 21) | (0x09) | OPC_CP2,
1054
1055    OPC_PSLLW   = (24 << 21) | (0x0A) | OPC_CP2,
1056    OPC_PSLLH   = (25 << 21) | (0x0A) | OPC_CP2,
1057    OPC_PMULLH  = (26 << 21) | (0x0A) | OPC_CP2,
1058    OPC_PMULHH  = (27 << 21) | (0x0A) | OPC_CP2,
1059    OPC_PMULUW  = (28 << 21) | (0x0A) | OPC_CP2,
1060    OPC_PMULHUH = (29 << 21) | (0x0A) | OPC_CP2,
1061
1062    OPC_PSRLW     = (24 << 21) | (0x0B) | OPC_CP2,
1063    OPC_PSRLH     = (25 << 21) | (0x0B) | OPC_CP2,
1064    OPC_PSRAW     = (26 << 21) | (0x0B) | OPC_CP2,
1065    OPC_PSRAH     = (27 << 21) | (0x0B) | OPC_CP2,
1066    OPC_PUNPCKLWD = (28 << 21) | (0x0B) | OPC_CP2,
1067    OPC_PUNPCKHWD = (29 << 21) | (0x0B) | OPC_CP2,
1068
1069    OPC_ADDU_CP2 = (24 << 21) | (0x0C) | OPC_CP2,
1070    OPC_OR_CP2   = (25 << 21) | (0x0C) | OPC_CP2,
1071    OPC_ADD_CP2  = (26 << 21) | (0x0C) | OPC_CP2,
1072    OPC_DADD_CP2 = (27 << 21) | (0x0C) | OPC_CP2,
1073    OPC_SEQU_CP2 = (28 << 21) | (0x0C) | OPC_CP2,
1074    OPC_SEQ_CP2  = (29 << 21) | (0x0C) | OPC_CP2,
1075
1076    OPC_SUBU_CP2 = (24 << 21) | (0x0D) | OPC_CP2,
1077    OPC_PASUBUB  = (25 << 21) | (0x0D) | OPC_CP2,
1078    OPC_SUB_CP2  = (26 << 21) | (0x0D) | OPC_CP2,
1079    OPC_DSUB_CP2 = (27 << 21) | (0x0D) | OPC_CP2,
1080    OPC_SLTU_CP2 = (28 << 21) | (0x0D) | OPC_CP2,
1081    OPC_SLT_CP2  = (29 << 21) | (0x0D) | OPC_CP2,
1082
1083    OPC_SLL_CP2  = (24 << 21) | (0x0E) | OPC_CP2,
1084    OPC_DSLL_CP2 = (25 << 21) | (0x0E) | OPC_CP2,
1085    OPC_PEXTRH   = (26 << 21) | (0x0E) | OPC_CP2,
1086    OPC_PMADDHW  = (27 << 21) | (0x0E) | OPC_CP2,
1087    OPC_SLEU_CP2 = (28 << 21) | (0x0E) | OPC_CP2,
1088    OPC_SLE_CP2  = (29 << 21) | (0x0E) | OPC_CP2,
1089
1090    OPC_SRL_CP2  = (24 << 21) | (0x0F) | OPC_CP2,
1091    OPC_DSRL_CP2 = (25 << 21) | (0x0F) | OPC_CP2,
1092    OPC_SRA_CP2  = (26 << 21) | (0x0F) | OPC_CP2,
1093    OPC_DSRA_CP2 = (27 << 21) | (0x0F) | OPC_CP2,
1094    OPC_BIADD    = (28 << 21) | (0x0F) | OPC_CP2,
1095    OPC_PMOVMSKB = (29 << 21) | (0x0F) | OPC_CP2,
1096};
1097
1098
1099#define MASK_CP3(op)       MASK_OP_MAJOR(op) | (op & 0x3F)
1100
1101enum {
1102    OPC_LWXC1   = 0x00 | OPC_CP3,
1103    OPC_LDXC1   = 0x01 | OPC_CP3,
1104    OPC_LUXC1   = 0x05 | OPC_CP3,
1105    OPC_SWXC1   = 0x08 | OPC_CP3,
1106    OPC_SDXC1   = 0x09 | OPC_CP3,
1107    OPC_SUXC1   = 0x0D | OPC_CP3,
1108    OPC_PREFX   = 0x0F | OPC_CP3,
1109    OPC_ALNV_PS = 0x1E | OPC_CP3,
1110    OPC_MADD_S  = 0x20 | OPC_CP3,
1111    OPC_MADD_D  = 0x21 | OPC_CP3,
1112    OPC_MADD_PS = 0x26 | OPC_CP3,
1113    OPC_MSUB_S  = 0x28 | OPC_CP3,
1114    OPC_MSUB_D  = 0x29 | OPC_CP3,
1115    OPC_MSUB_PS = 0x2E | OPC_CP3,
1116    OPC_NMADD_S = 0x30 | OPC_CP3,
1117    OPC_NMADD_D = 0x31 | OPC_CP3,
1118    OPC_NMADD_PS= 0x36 | OPC_CP3,
1119    OPC_NMSUB_S = 0x38 | OPC_CP3,
1120    OPC_NMSUB_D = 0x39 | OPC_CP3,
1121    OPC_NMSUB_PS= 0x3E | OPC_CP3,
1122};
1123
1124/* MSA Opcodes */
1125#define MASK_MSA_MINOR(op)    (MASK_OP_MAJOR(op) | (op & 0x3F))
1126enum {
1127    OPC_MSA_I8_00   = 0x00 | OPC_MSA,
1128    OPC_MSA_I8_01   = 0x01 | OPC_MSA,
1129    OPC_MSA_I8_02   = 0x02 | OPC_MSA,
1130    OPC_MSA_I5_06   = 0x06 | OPC_MSA,
1131    OPC_MSA_I5_07   = 0x07 | OPC_MSA,
1132    OPC_MSA_BIT_09  = 0x09 | OPC_MSA,
1133    OPC_MSA_BIT_0A  = 0x0A | OPC_MSA,
1134    OPC_MSA_3R_0D   = 0x0D | OPC_MSA,
1135    OPC_MSA_3R_0E   = 0x0E | OPC_MSA,
1136    OPC_MSA_3R_0F   = 0x0F | OPC_MSA,
1137    OPC_MSA_3R_10   = 0x10 | OPC_MSA,
1138    OPC_MSA_3R_11   = 0x11 | OPC_MSA,
1139    OPC_MSA_3R_12   = 0x12 | OPC_MSA,
1140    OPC_MSA_3R_13   = 0x13 | OPC_MSA,
1141    OPC_MSA_3R_14   = 0x14 | OPC_MSA,
1142    OPC_MSA_3R_15   = 0x15 | OPC_MSA,
1143    OPC_MSA_ELM     = 0x19 | OPC_MSA,
1144    OPC_MSA_3RF_1A  = 0x1A | OPC_MSA,
1145    OPC_MSA_3RF_1B  = 0x1B | OPC_MSA,
1146    OPC_MSA_3RF_1C  = 0x1C | OPC_MSA,
1147    OPC_MSA_VEC     = 0x1E | OPC_MSA,
1148
1149    /* MI10 instruction */
1150    OPC_LD_B    = (0x20) | OPC_MSA,
1151    OPC_LD_H    = (0x21) | OPC_MSA,
1152    OPC_LD_W    = (0x22) | OPC_MSA,
1153    OPC_LD_D    = (0x23) | OPC_MSA,
1154    OPC_ST_B    = (0x24) | OPC_MSA,
1155    OPC_ST_H    = (0x25) | OPC_MSA,
1156    OPC_ST_W    = (0x26) | OPC_MSA,
1157    OPC_ST_D    = (0x27) | OPC_MSA,
1158};
1159
1160enum {
1161    /* I5 instruction df(bits 22..21) = _b, _h, _w, _d */
1162    OPC_ADDVI_df    = (0x0 << 23) | OPC_MSA_I5_06,
1163    OPC_CEQI_df     = (0x0 << 23) | OPC_MSA_I5_07,
1164    OPC_SUBVI_df    = (0x1 << 23) | OPC_MSA_I5_06,
1165    OPC_MAXI_S_df   = (0x2 << 23) | OPC_MSA_I5_06,
1166    OPC_CLTI_S_df   = (0x2 << 23) | OPC_MSA_I5_07,
1167    OPC_MAXI_U_df   = (0x3 << 23) | OPC_MSA_I5_06,
1168    OPC_CLTI_U_df   = (0x3 << 23) | OPC_MSA_I5_07,
1169    OPC_MINI_S_df   = (0x4 << 23) | OPC_MSA_I5_06,
1170    OPC_CLEI_S_df   = (0x4 << 23) | OPC_MSA_I5_07,
1171    OPC_MINI_U_df   = (0x5 << 23) | OPC_MSA_I5_06,
1172    OPC_CLEI_U_df   = (0x5 << 23) | OPC_MSA_I5_07,
1173    OPC_LDI_df      = (0x6 << 23) | OPC_MSA_I5_07,
1174
1175    /* I8 instruction */
1176    OPC_ANDI_B  = (0x0 << 24) | OPC_MSA_I8_00,
1177    OPC_BMNZI_B = (0x0 << 24) | OPC_MSA_I8_01,
1178    OPC_SHF_B   = (0x0 << 24) | OPC_MSA_I8_02,
1179    OPC_ORI_B   = (0x1 << 24) | OPC_MSA_I8_00,
1180    OPC_BMZI_B  = (0x1 << 24) | OPC_MSA_I8_01,
1181    OPC_SHF_H   = (0x1 << 24) | OPC_MSA_I8_02,
1182    OPC_NORI_B  = (0x2 << 24) | OPC_MSA_I8_00,
1183    OPC_BSELI_B = (0x2 << 24) | OPC_MSA_I8_01,
1184    OPC_SHF_W   = (0x2 << 24) | OPC_MSA_I8_02,
1185    OPC_XORI_B  = (0x3 << 24) | OPC_MSA_I8_00,
1186
1187    /* VEC/2R/2RF instruction */
1188    OPC_AND_V   = (0x00 << 21) | OPC_MSA_VEC,
1189    OPC_OR_V    = (0x01 << 21) | OPC_MSA_VEC,
1190    OPC_NOR_V   = (0x02 << 21) | OPC_MSA_VEC,
1191    OPC_XOR_V   = (0x03 << 21) | OPC_MSA_VEC,
1192    OPC_BMNZ_V  = (0x04 << 21) | OPC_MSA_VEC,
1193    OPC_BMZ_V   = (0x05 << 21) | OPC_MSA_VEC,
1194    OPC_BSEL_V  = (0x06 << 21) | OPC_MSA_VEC,
1195
1196    OPC_MSA_2R      = (0x18 << 21) | OPC_MSA_VEC,
1197    OPC_MSA_2RF     = (0x19 << 21) | OPC_MSA_VEC,
1198
1199    /* 2R instruction df(bits 17..16) = _b, _h, _w, _d */
1200    OPC_FILL_df = (0x00 << 18) | OPC_MSA_2R,
1201    OPC_PCNT_df = (0x01 << 18) | OPC_MSA_2R,
1202    OPC_NLOC_df = (0x02 << 18) | OPC_MSA_2R,
1203    OPC_NLZC_df = (0x03 << 18) | OPC_MSA_2R,
1204
1205    /* 2RF instruction df(bit 16) = _w, _d */
1206    OPC_FCLASS_df   = (0x00 << 17) | OPC_MSA_2RF,
1207    OPC_FTRUNC_S_df = (0x01 << 17) | OPC_MSA_2RF,
1208    OPC_FTRUNC_U_df = (0x02 << 17) | OPC_MSA_2RF,
1209    OPC_FSQRT_df    = (0x03 << 17) | OPC_MSA_2RF,
1210    OPC_FRSQRT_df   = (0x04 << 17) | OPC_MSA_2RF,
1211    OPC_FRCP_df     = (0x05 << 17) | OPC_MSA_2RF,
1212    OPC_FRINT_df    = (0x06 << 17) | OPC_MSA_2RF,
1213    OPC_FLOG2_df    = (0x07 << 17) | OPC_MSA_2RF,
1214    OPC_FEXUPL_df   = (0x08 << 17) | OPC_MSA_2RF,
1215    OPC_FEXUPR_df   = (0x09 << 17) | OPC_MSA_2RF,
1216    OPC_FFQL_df     = (0x0A << 17) | OPC_MSA_2RF,
1217    OPC_FFQR_df     = (0x0B << 17) | OPC_MSA_2RF,
1218    OPC_FTINT_S_df  = (0x0C << 17) | OPC_MSA_2RF,
1219    OPC_FTINT_U_df  = (0x0D << 17) | OPC_MSA_2RF,
1220    OPC_FFINT_S_df  = (0x0E << 17) | OPC_MSA_2RF,
1221    OPC_FFINT_U_df  = (0x0F << 17) | OPC_MSA_2RF,
1222
1223    /* 3R instruction df(bits 22..21) = _b, _h, _w, d */
1224    OPC_SLL_df      = (0x0 << 23) | OPC_MSA_3R_0D,
1225    OPC_ADDV_df     = (0x0 << 23) | OPC_MSA_3R_0E,
1226    OPC_CEQ_df      = (0x0 << 23) | OPC_MSA_3R_0F,
1227    OPC_ADD_A_df    = (0x0 << 23) | OPC_MSA_3R_10,
1228    OPC_SUBS_S_df   = (0x0 << 23) | OPC_MSA_3R_11,
1229    OPC_MULV_df     = (0x0 << 23) | OPC_MSA_3R_12,
1230    OPC_DOTP_S_df   = (0x0 << 23) | OPC_MSA_3R_13,
1231    OPC_SLD_df      = (0x0 << 23) | OPC_MSA_3R_14,
1232    OPC_VSHF_df     = (0x0 << 23) | OPC_MSA_3R_15,
1233    OPC_SRA_df      = (0x1 << 23) | OPC_MSA_3R_0D,
1234    OPC_SUBV_df     = (0x1 << 23) | OPC_MSA_3R_0E,
1235    OPC_ADDS_A_df   = (0x1 << 23) | OPC_MSA_3R_10,
1236    OPC_SUBS_U_df   = (0x1 << 23) | OPC_MSA_3R_11,
1237    OPC_MADDV_df    = (0x1 << 23) | OPC_MSA_3R_12,
1238    OPC_DOTP_U_df   = (0x1 << 23) | OPC_MSA_3R_13,
1239    OPC_SPLAT_df    = (0x1 << 23) | OPC_MSA_3R_14,
1240    OPC_SRAR_df     = (0x1 << 23) | OPC_MSA_3R_15,
1241    OPC_SRL_df      = (0x2 << 23) | OPC_MSA_3R_0D,
1242    OPC_MAX_S_df    = (0x2 << 23) | OPC_MSA_3R_0E,
1243    OPC_CLT_S_df    = (0x2 << 23) | OPC_MSA_3R_0F,
1244    OPC_ADDS_S_df   = (0x2 << 23) | OPC_MSA_3R_10,
1245    OPC_SUBSUS_U_df = (0x2 << 23) | OPC_MSA_3R_11,
1246    OPC_MSUBV_df    = (0x2 << 23) | OPC_MSA_3R_12,
1247    OPC_DPADD_S_df  = (0x2 << 23) | OPC_MSA_3R_13,
1248    OPC_PCKEV_df    = (0x2 << 23) | OPC_MSA_3R_14,
1249    OPC_SRLR_df     = (0x2 << 23) | OPC_MSA_3R_15,
1250    OPC_BCLR_df     = (0x3 << 23) | OPC_MSA_3R_0D,
1251    OPC_MAX_U_df    = (0x3 << 23) | OPC_MSA_3R_0E,
1252    OPC_CLT_U_df    = (0x3 << 23) | OPC_MSA_3R_0F,
1253    OPC_ADDS_U_df   = (0x3 << 23) | OPC_MSA_3R_10,
1254    OPC_SUBSUU_S_df = (0x3 << 23) | OPC_MSA_3R_11,
1255    OPC_DPADD_U_df  = (0x3 << 23) | OPC_MSA_3R_13,
1256    OPC_PCKOD_df    = (0x3 << 23) | OPC_MSA_3R_14,
1257    OPC_BSET_df     = (0x4 << 23) | OPC_MSA_3R_0D,
1258    OPC_MIN_S_df    = (0x4 << 23) | OPC_MSA_3R_0E,
1259    OPC_CLE_S_df    = (0x4 << 23) | OPC_MSA_3R_0F,
1260    OPC_AVE_S_df    = (0x4 << 23) | OPC_MSA_3R_10,
1261    OPC_ASUB_S_df   = (0x4 << 23) | OPC_MSA_3R_11,
1262    OPC_DIV_S_df    = (0x4 << 23) | OPC_MSA_3R_12,
1263    OPC_DPSUB_S_df  = (0x4 << 23) | OPC_MSA_3R_13,
1264    OPC_ILVL_df     = (0x4 << 23) | OPC_MSA_3R_14,
1265    OPC_HADD_S_df   = (0x4 << 23) | OPC_MSA_3R_15,
1266    OPC_BNEG_df     = (0x5 << 23) | OPC_MSA_3R_0D,
1267    OPC_MIN_U_df    = (0x5 << 23) | OPC_MSA_3R_0E,
1268    OPC_CLE_U_df    = (0x5 << 23) | OPC_MSA_3R_0F,
1269    OPC_AVE_U_df    = (0x5 << 23) | OPC_MSA_3R_10,
1270    OPC_ASUB_U_df   = (0x5 << 23) | OPC_MSA_3R_11,
1271    OPC_DIV_U_df    = (0x5 << 23) | OPC_MSA_3R_12,
1272    OPC_DPSUB_U_df  = (0x5 << 23) | OPC_MSA_3R_13,
1273    OPC_ILVR_df     = (0x5 << 23) | OPC_MSA_3R_14,
1274    OPC_HADD_U_df   = (0x5 << 23) | OPC_MSA_3R_15,
1275    OPC_BINSL_df    = (0x6 << 23) | OPC_MSA_3R_0D,
1276    OPC_MAX_A_df    = (0x6 << 23) | OPC_MSA_3R_0E,
1277    OPC_AVER_S_df   = (0x6 << 23) | OPC_MSA_3R_10,
1278    OPC_MOD_S_df    = (0x6 << 23) | OPC_MSA_3R_12,
1279    OPC_ILVEV_df    = (0x6 << 23) | OPC_MSA_3R_14,
1280    OPC_HSUB_S_df   = (0x6 << 23) | OPC_MSA_3R_15,
1281    OPC_BINSR_df    = (0x7 << 23) | OPC_MSA_3R_0D,
1282    OPC_MIN_A_df    = (0x7 << 23) | OPC_MSA_3R_0E,
1283    OPC_AVER_U_df   = (0x7 << 23) | OPC_MSA_3R_10,
1284    OPC_MOD_U_df    = (0x7 << 23) | OPC_MSA_3R_12,
1285    OPC_ILVOD_df    = (0x7 << 23) | OPC_MSA_3R_14,
1286    OPC_HSUB_U_df   = (0x7 << 23) | OPC_MSA_3R_15,
1287
1288    /* ELM instructions df(bits 21..16) = _b, _h, _w, _d */
1289    OPC_SLDI_df     = (0x0 << 22) | (0x00 << 16) | OPC_MSA_ELM,
1290    OPC_CTCMSA      = (0x0 << 22) | (0x3E << 16) | OPC_MSA_ELM,
1291    OPC_SPLATI_df   = (0x1 << 22) | (0x00 << 16) | OPC_MSA_ELM,
1292    OPC_CFCMSA      = (0x1 << 22) | (0x3E << 16) | OPC_MSA_ELM,
1293    OPC_COPY_S_df   = (0x2 << 22) | (0x00 << 16) | OPC_MSA_ELM,
1294    OPC_MOVE_V      = (0x2 << 22) | (0x3E << 16) | OPC_MSA_ELM,
1295    OPC_COPY_U_df   = (0x3 << 22) | (0x00 << 16) | OPC_MSA_ELM,
1296    OPC_INSERT_df   = (0x4 << 22) | (0x00 << 16) | OPC_MSA_ELM,
1297    OPC_INSVE_df    = (0x5 << 22) | (0x00 << 16) | OPC_MSA_ELM,
1298
1299    /* 3RF instruction _df(bit 21) = _w, _d */
1300    OPC_FCAF_df     = (0x0 << 22) | OPC_MSA_3RF_1A,
1301    OPC_FADD_df     = (0x0 << 22) | OPC_MSA_3RF_1B,
1302    OPC_FCUN_df     = (0x1 << 22) | OPC_MSA_3RF_1A,
1303    OPC_FSUB_df     = (0x1 << 22) | OPC_MSA_3RF_1B,
1304    OPC_FCOR_df     = (0x1 << 22) | OPC_MSA_3RF_1C,
1305    OPC_FCEQ_df     = (0x2 << 22) | OPC_MSA_3RF_1A,
1306    OPC_FMUL_df     = (0x2 << 22) | OPC_MSA_3RF_1B,
1307    OPC_FCUNE_df    = (0x2 << 22) | OPC_MSA_3RF_1C,
1308    OPC_FCUEQ_df    = (0x3 << 22) | OPC_MSA_3RF_1A,
1309    OPC_FDIV_df     = (0x3 << 22) | OPC_MSA_3RF_1B,
1310    OPC_FCNE_df     = (0x3 << 22) | OPC_MSA_3RF_1C,
1311    OPC_FCLT_df     = (0x4 << 22) | OPC_MSA_3RF_1A,
1312    OPC_FMADD_df    = (0x4 << 22) | OPC_MSA_3RF_1B,
1313    OPC_MUL_Q_df    = (0x4 << 22) | OPC_MSA_3RF_1C,
1314    OPC_FCULT_df    = (0x5 << 22) | OPC_MSA_3RF_1A,
1315    OPC_FMSUB_df    = (0x5 << 22) | OPC_MSA_3RF_1B,
1316    OPC_MADD_Q_df   = (0x5 << 22) | OPC_MSA_3RF_1C,
1317    OPC_FCLE_df     = (0x6 << 22) | OPC_MSA_3RF_1A,
1318    OPC_MSUB_Q_df   = (0x6 << 22) | OPC_MSA_3RF_1C,
1319    OPC_FCULE_df    = (0x7 << 22) | OPC_MSA_3RF_1A,
1320    OPC_FEXP2_df    = (0x7 << 22) | OPC_MSA_3RF_1B,
1321    OPC_FSAF_df     = (0x8 << 22) | OPC_MSA_3RF_1A,
1322    OPC_FEXDO_df    = (0x8 << 22) | OPC_MSA_3RF_1B,
1323    OPC_FSUN_df     = (0x9 << 22) | OPC_MSA_3RF_1A,
1324    OPC_FSOR_df     = (0x9 << 22) | OPC_MSA_3RF_1C,
1325    OPC_FSEQ_df     = (0xA << 22) | OPC_MSA_3RF_1A,
1326    OPC_FTQ_df      = (0xA << 22) | OPC_MSA_3RF_1B,
1327    OPC_FSUNE_df    = (0xA << 22) | OPC_MSA_3RF_1C,
1328    OPC_FSUEQ_df    = (0xB << 22) | OPC_MSA_3RF_1A,
1329    OPC_FSNE_df     = (0xB << 22) | OPC_MSA_3RF_1C,
1330    OPC_FSLT_df     = (0xC << 22) | OPC_MSA_3RF_1A,
1331    OPC_FMIN_df     = (0xC << 22) | OPC_MSA_3RF_1B,
1332    OPC_MULR_Q_df   = (0xC << 22) | OPC_MSA_3RF_1C,
1333    OPC_FSULT_df    = (0xD << 22) | OPC_MSA_3RF_1A,
1334    OPC_FMIN_A_df   = (0xD << 22) | OPC_MSA_3RF_1B,
1335    OPC_MADDR_Q_df  = (0xD << 22) | OPC_MSA_3RF_1C,
1336    OPC_FSLE_df     = (0xE << 22) | OPC_MSA_3RF_1A,
1337    OPC_FMAX_df     = (0xE << 22) | OPC_MSA_3RF_1B,
1338    OPC_MSUBR_Q_df  = (0xE << 22) | OPC_MSA_3RF_1C,
1339    OPC_FSULE_df    = (0xF << 22) | OPC_MSA_3RF_1A,
1340    OPC_FMAX_A_df   = (0xF << 22) | OPC_MSA_3RF_1B,
1341
1342    /* BIT instruction df(bits 22..16) = _B _H _W _D */
1343    OPC_SLLI_df     = (0x0 << 23) | OPC_MSA_BIT_09,
1344    OPC_SAT_S_df    = (0x0 << 23) | OPC_MSA_BIT_0A,
1345    OPC_SRAI_df     = (0x1 << 23) | OPC_MSA_BIT_09,
1346    OPC_SAT_U_df    = (0x1 << 23) | OPC_MSA_BIT_0A,
1347    OPC_SRLI_df     = (0x2 << 23) | OPC_MSA_BIT_09,
1348    OPC_SRARI_df    = (0x2 << 23) | OPC_MSA_BIT_0A,
1349    OPC_BCLRI_df    = (0x3 << 23) | OPC_MSA_BIT_09,
1350    OPC_SRLRI_df    = (0x3 << 23) | OPC_MSA_BIT_0A,
1351    OPC_BSETI_df    = (0x4 << 23) | OPC_MSA_BIT_09,
1352    OPC_BNEGI_df    = (0x5 << 23) | OPC_MSA_BIT_09,
1353    OPC_BINSLI_df   = (0x6 << 23) | OPC_MSA_BIT_09,
1354    OPC_BINSRI_df   = (0x7 << 23) | OPC_MSA_BIT_09,
1355};
1356
1357/* global register indices */
1358static TCGv_env cpu_env;
1359static TCGv cpu_gpr[32], cpu_PC;
1360static TCGv cpu_HI[MIPS_DSP_ACC], cpu_LO[MIPS_DSP_ACC];
1361static TCGv cpu_dspctrl, btarget, bcond;
1362static TCGv_i32 hflags;
1363static TCGv_i32 fpu_fcr0, fpu_fcr31;
1364static TCGv_i64 fpu_f64[32];
1365static TCGv_i64 msa_wr_d[64];
1366
1367#include "exec/gen-icount.h"
1368
1369#define gen_helper_0e0i(name, arg) do {                           \
1370    TCGv_i32 helper_tmp = tcg_const_i32(arg);                     \
1371    gen_helper_##name(cpu_env, helper_tmp);                       \
1372    tcg_temp_free_i32(helper_tmp);                                \
1373    } while(0)
1374
1375#define gen_helper_0e1i(name, arg1, arg2) do {                    \
1376    TCGv_i32 helper_tmp = tcg_const_i32(arg2);                    \
1377    gen_helper_##name(cpu_env, arg1, helper_tmp);                 \
1378    tcg_temp_free_i32(helper_tmp);                                \
1379    } while(0)
1380
1381#define gen_helper_1e0i(name, ret, arg1) do {                     \
1382    TCGv_i32 helper_tmp = tcg_const_i32(arg1);                    \
1383    gen_helper_##name(ret, cpu_env, helper_tmp);                  \
1384    tcg_temp_free_i32(helper_tmp);                                \
1385    } while(0)
1386
1387#define gen_helper_1e1i(name, ret, arg1, arg2) do {               \
1388    TCGv_i32 helper_tmp = tcg_const_i32(arg2);                    \
1389    gen_helper_##name(ret, cpu_env, arg1, helper_tmp);            \
1390    tcg_temp_free_i32(helper_tmp);                                \
1391    } while(0)
1392
1393#define gen_helper_0e2i(name, arg1, arg2, arg3) do {              \
1394    TCGv_i32 helper_tmp = tcg_const_i32(arg3);                    \
1395    gen_helper_##name(cpu_env, arg1, arg2, helper_tmp);           \
1396    tcg_temp_free_i32(helper_tmp);                                \
1397    } while(0)
1398
1399#define gen_helper_1e2i(name, ret, arg1, arg2, arg3) do {         \
1400    TCGv_i32 helper_tmp = tcg_const_i32(arg3);                    \
1401    gen_helper_##name(ret, cpu_env, arg1, arg2, helper_tmp);      \
1402    tcg_temp_free_i32(helper_tmp);                                \
1403    } while(0)
1404
1405#define gen_helper_0e3i(name, arg1, arg2, arg3, arg4) do {        \
1406    TCGv_i32 helper_tmp = tcg_const_i32(arg4);                    \
1407    gen_helper_##name(cpu_env, arg1, arg2, arg3, helper_tmp);     \
1408    tcg_temp_free_i32(helper_tmp);                                \
1409    } while(0)
1410
1411typedef struct DisasContext {
1412    struct TranslationBlock *tb;
1413    target_ulong pc, saved_pc;
1414    uint32_t opcode;
1415    int singlestep_enabled;
1416    int insn_flags;
1417    int32_t CP0_Config1;
1418    /* Routine used to access memory */
1419    int mem_idx;
1420    TCGMemOp default_tcg_memop_mask;
1421    uint32_t hflags, saved_hflags;
1422    int bstate;
1423    target_ulong btarget;
1424    bool ulri;
1425    int kscrexist;
1426    bool rxi;
1427    int ie;
1428    bool bi;
1429    bool bp;
1430    uint64_t PAMask;
1431    bool mvh;
1432    int CP0_LLAddr_shift;
1433    bool ps;
1434    bool vp;
1435    bool cmgcr;
1436    bool mrp;
1437} DisasContext;
1438
1439enum {
1440    BS_NONE     = 0, /* We go out of the TB without reaching a branch or an
1441                      * exception condition */
1442    BS_STOP     = 1, /* We want to stop translation for any reason */
1443    BS_BRANCH   = 2, /* We reached a branch condition     */
1444    BS_EXCP     = 3, /* We reached an exception condition */
1445};
1446
1447static const char * const regnames[] = {
1448    "r0", "at", "v0", "v1", "a0", "a1", "a2", "a3",
1449    "t0", "t1", "t2", "t3", "t4", "t5", "t6", "t7",
1450    "s0", "s1", "s2", "s3", "s4", "s5", "s6", "s7",
1451    "t8", "t9", "k0", "k1", "gp", "sp", "s8", "ra",
1452};
1453
1454static const char * const regnames_HI[] = {
1455    "HI0", "HI1", "HI2", "HI3",
1456};
1457
1458static const char * const regnames_LO[] = {
1459    "LO0", "LO1", "LO2", "LO3",
1460};
1461
1462static const char * const fregnames[] = {
1463    "f0",  "f1",  "f2",  "f3",  "f4",  "f5",  "f6",  "f7",
1464    "f8",  "f9",  "f10", "f11", "f12", "f13", "f14", "f15",
1465    "f16", "f17", "f18", "f19", "f20", "f21", "f22", "f23",
1466    "f24", "f25", "f26", "f27", "f28", "f29", "f30", "f31",
1467};
1468
1469static const char * const msaregnames[] = {
1470    "w0.d0",  "w0.d1",  "w1.d0",  "w1.d1",
1471    "w2.d0",  "w2.d1",  "w3.d0",  "w3.d1",
1472    "w4.d0",  "w4.d1",  "w5.d0",  "w5.d1",
1473    "w6.d0",  "w6.d1",  "w7.d0",  "w7.d1",
1474    "w8.d0",  "w8.d1",  "w9.d0",  "w9.d1",
1475    "w10.d0", "w10.d1", "w11.d0", "w11.d1",
1476    "w12.d0", "w12.d1", "w13.d0", "w13.d1",
1477    "w14.d0", "w14.d1", "w15.d0", "w15.d1",
1478    "w16.d0", "w16.d1", "w17.d0", "w17.d1",
1479    "w18.d0", "w18.d1", "w19.d0", "w19.d1",
1480    "w20.d0", "w20.d1", "w21.d0", "w21.d1",
1481    "w22.d0", "w22.d1", "w23.d0", "w23.d1",
1482    "w24.d0", "w24.d1", "w25.d0", "w25.d1",
1483    "w26.d0", "w26.d1", "w27.d0", "w27.d1",
1484    "w28.d0", "w28.d1", "w29.d0", "w29.d1",
1485    "w30.d0", "w30.d1", "w31.d0", "w31.d1",
1486};
1487
1488#define LOG_DISAS(...)                                                        \
1489    do {                                                                      \
1490        if (MIPS_DEBUG_DISAS) {                                               \
1491            qemu_log_mask(CPU_LOG_TB_IN_ASM, ## __VA_ARGS__);                 \
1492        }                                                                     \
1493    } while (0)
1494
1495#define MIPS_INVAL(op)                                                        \
1496    do {                                                                      \
1497        if (MIPS_DEBUG_DISAS) {                                               \
1498            qemu_log_mask(CPU_LOG_TB_IN_ASM,                                  \
1499                          TARGET_FMT_lx ": %08x Invalid %s %03x %03x %03x\n", \
1500                          ctx->pc, ctx->opcode, op, ctx->opcode >> 26,        \
1501                          ctx->opcode & 0x3F, ((ctx->opcode >> 16) & 0x1F));  \
1502        }                                                                     \
1503    } while (0)
1504
1505/* General purpose registers moves. */
1506static inline void gen_load_gpr (TCGv t, int reg)
1507{
1508    if (reg == 0)
1509        tcg_gen_movi_tl(t, 0);
1510    else
1511        tcg_gen_mov_tl(t, cpu_gpr[reg]);
1512}
1513
1514static inline void gen_store_gpr (TCGv t, int reg)
1515{
1516    if (reg != 0)
1517        tcg_gen_mov_tl(cpu_gpr[reg], t);
1518}
1519
1520/* Moves to/from shadow registers. */
1521static inline void gen_load_srsgpr (int from, int to)
1522{
1523    TCGv t0 = tcg_temp_new();
1524
1525    if (from == 0)
1526        tcg_gen_movi_tl(t0, 0);
1527    else {
1528        TCGv_i32 t2 = tcg_temp_new_i32();
1529        TCGv_ptr addr = tcg_temp_new_ptr();
1530
1531        tcg_gen_ld_i32(t2, cpu_env, offsetof(CPUMIPSState, CP0_SRSCtl));
1532        tcg_gen_shri_i32(t2, t2, CP0SRSCtl_PSS);
1533        tcg_gen_andi_i32(t2, t2, 0xf);
1534        tcg_gen_muli_i32(t2, t2, sizeof(target_ulong) * 32);
1535        tcg_gen_ext_i32_ptr(addr, t2);
1536        tcg_gen_add_ptr(addr, cpu_env, addr);
1537
1538        tcg_gen_ld_tl(t0, addr, sizeof(target_ulong) * from);
1539        tcg_temp_free_ptr(addr);
1540        tcg_temp_free_i32(t2);
1541    }
1542    gen_store_gpr(t0, to);
1543    tcg_temp_free(t0);
1544}
1545
1546static inline void gen_store_srsgpr (int from, int to)
1547{
1548    if (to != 0) {
1549        TCGv t0 = tcg_temp_new();
1550        TCGv_i32 t2 = tcg_temp_new_i32();
1551        TCGv_ptr addr = tcg_temp_new_ptr();
1552
1553        gen_load_gpr(t0, from);
1554        tcg_gen_ld_i32(t2, cpu_env, offsetof(CPUMIPSState, CP0_SRSCtl));
1555        tcg_gen_shri_i32(t2, t2, CP0SRSCtl_PSS);
1556        tcg_gen_andi_i32(t2, t2, 0xf);
1557        tcg_gen_muli_i32(t2, t2, sizeof(target_ulong) * 32);
1558        tcg_gen_ext_i32_ptr(addr, t2);
1559        tcg_gen_add_ptr(addr, cpu_env, addr);
1560
1561        tcg_gen_st_tl(t0, addr, sizeof(target_ulong) * to);
1562        tcg_temp_free_ptr(addr);
1563        tcg_temp_free_i32(t2);
1564        tcg_temp_free(t0);
1565    }
1566}
1567
1568/* Tests */
1569static inline void gen_save_pc(target_ulong pc)
1570{
1571    tcg_gen_movi_tl(cpu_PC, pc);
1572}
1573
1574static inline void save_cpu_state(DisasContext *ctx, int do_save_pc)
1575{
1576    LOG_DISAS("hflags %08x saved %08x\n", ctx->hflags, ctx->saved_hflags);
1577    if (do_save_pc && ctx->pc != ctx->saved_pc) {
1578        gen_save_pc(ctx->pc);
1579        ctx->saved_pc = ctx->pc;
1580    }
1581    if (ctx->hflags != ctx->saved_hflags) {
1582        tcg_gen_movi_i32(hflags, ctx->hflags);
1583        ctx->saved_hflags = ctx->hflags;
1584        switch (ctx->hflags & MIPS_HFLAG_BMASK_BASE) {
1585        case MIPS_HFLAG_BR:
1586            break;
1587        case MIPS_HFLAG_BC:
1588        case MIPS_HFLAG_BL:
1589        case MIPS_HFLAG_B:
1590            tcg_gen_movi_tl(btarget, ctx->btarget);
1591            break;
1592        }
1593    }
1594}
1595
1596static inline void restore_cpu_state(CPUMIPSState *env, DisasContext *ctx)
1597{
1598    ctx->saved_hflags = ctx->hflags;
1599    switch (ctx->hflags & MIPS_HFLAG_BMASK_BASE) {
1600    case MIPS_HFLAG_BR:
1601        break;
1602    case MIPS_HFLAG_BC:
1603    case MIPS_HFLAG_BL:
1604    case MIPS_HFLAG_B:
1605        ctx->btarget = env->btarget;
1606        break;
1607    }
1608}
1609
1610static inline void generate_exception_err(DisasContext *ctx, int excp, int err)
1611{
1612    TCGv_i32 texcp = tcg_const_i32(excp);
1613    TCGv_i32 terr = tcg_const_i32(err);
1614    save_cpu_state(ctx, 1);
1615    gen_helper_raise_exception_err(cpu_env, texcp, terr);
1616    tcg_temp_free_i32(terr);
1617    tcg_temp_free_i32(texcp);
1618    ctx->bstate = BS_EXCP;
1619}
1620
1621static inline void generate_exception(DisasContext *ctx, int excp)
1622{
1623    gen_helper_0e0i(raise_exception, excp);
1624}
1625
1626static inline void generate_exception_end(DisasContext *ctx, int excp)
1627{
1628    generate_exception_err(ctx, excp, 0);
1629}
1630
1631/* Floating point register moves. */
1632static void gen_load_fpr32(DisasContext *ctx, TCGv_i32 t, int reg)
1633{
1634    if (ctx->hflags & MIPS_HFLAG_FRE) {
1635        generate_exception(ctx, EXCP_RI);
1636    }
1637    tcg_gen_extrl_i64_i32(t, fpu_f64[reg]);
1638}
1639
1640static void gen_store_fpr32(DisasContext *ctx, TCGv_i32 t, int reg)
1641{
1642    TCGv_i64 t64;
1643    if (ctx->hflags & MIPS_HFLAG_FRE) {
1644        generate_exception(ctx, EXCP_RI);
1645    }
1646    t64 = tcg_temp_new_i64();
1647    tcg_gen_extu_i32_i64(t64, t);
1648    tcg_gen_deposit_i64(fpu_f64[reg], fpu_f64[reg], t64, 0, 32);
1649    tcg_temp_free_i64(t64);
1650}
1651
1652static void gen_load_fpr32h(DisasContext *ctx, TCGv_i32 t, int reg)
1653{
1654    if (ctx->hflags & MIPS_HFLAG_F64) {
1655        tcg_gen_extrh_i64_i32(t, fpu_f64[reg]);
1656    } else {
1657        gen_load_fpr32(ctx, t, reg | 1);
1658    }
1659}
1660
1661static void gen_store_fpr32h(DisasContext *ctx, TCGv_i32 t, int reg)
1662{
1663    if (ctx->hflags & MIPS_HFLAG_F64) {
1664        TCGv_i64 t64 = tcg_temp_new_i64();
1665        tcg_gen_extu_i32_i64(t64, t);
1666        tcg_gen_deposit_i64(fpu_f64[reg], fpu_f64[reg], t64, 32, 32);
1667        tcg_temp_free_i64(t64);
1668    } else {
1669        gen_store_fpr32(ctx, t, reg | 1);
1670    }
1671}
1672
1673static void gen_load_fpr64(DisasContext *ctx, TCGv_i64 t, int reg)
1674{
1675    if (ctx->hflags & MIPS_HFLAG_F64) {
1676        tcg_gen_mov_i64(t, fpu_f64[reg]);
1677    } else {
1678        tcg_gen_concat32_i64(t, fpu_f64[reg & ~1], fpu_f64[reg | 1]);
1679    }
1680}
1681
1682static void gen_store_fpr64(DisasContext *ctx, TCGv_i64 t, int reg)
1683{
1684    if (ctx->hflags & MIPS_HFLAG_F64) {
1685        tcg_gen_mov_i64(fpu_f64[reg], t);
1686    } else {
1687        TCGv_i64 t0;
1688        tcg_gen_deposit_i64(fpu_f64[reg & ~1], fpu_f64[reg & ~1], t, 0, 32);
1689        t0 = tcg_temp_new_i64();
1690        tcg_gen_shri_i64(t0, t, 32);
1691        tcg_gen_deposit_i64(fpu_f64[reg | 1], fpu_f64[reg | 1], t0, 0, 32);
1692        tcg_temp_free_i64(t0);
1693    }
1694}
1695
1696static inline int get_fp_bit (int cc)
1697{
1698    if (cc)
1699        return 24 + cc;
1700    else
1701        return 23;
1702}
1703
1704/* Addresses computation */
1705static inline void gen_op_addr_add (DisasContext *ctx, TCGv ret, TCGv arg0, TCGv arg1)
1706{
1707    tcg_gen_add_tl(ret, arg0, arg1);
1708
1709#if defined(TARGET_MIPS64)
1710    if (ctx->hflags & MIPS_HFLAG_AWRAP) {
1711        tcg_gen_ext32s_i64(ret, ret);
1712    }
1713#endif
1714}
1715
1716/* Addresses computation (translation time) */
1717static target_long addr_add(DisasContext *ctx, target_long base,
1718                            target_long offset)
1719{
1720    target_long sum = base + offset;
1721
1722#if defined(TARGET_MIPS64)
1723    if (ctx->hflags & MIPS_HFLAG_AWRAP) {
1724        sum = (int32_t)sum;
1725    }
1726#endif
1727    return sum;
1728}
1729
1730/* Sign-extract the low 32-bits to a target_long.  */
1731static inline void gen_move_low32(TCGv ret, TCGv_i64 arg)
1732{
1733#if defined(TARGET_MIPS64)
1734    tcg_gen_ext32s_i64(ret, arg);
1735#else
1736    tcg_gen_extrl_i64_i32(ret, arg);
1737#endif
1738}
1739
1740/* Sign-extract the high 32-bits to a target_long.  */
1741static inline void gen_move_high32(TCGv ret, TCGv_i64 arg)
1742{
1743#if defined(TARGET_MIPS64)
1744    tcg_gen_sari_i64(ret, arg, 32);
1745#else
1746    tcg_gen_extrh_i64_i32(ret, arg);
1747#endif
1748}
1749
1750static inline void check_cp0_enabled(DisasContext *ctx)
1751{
1752    if (unlikely(!(ctx->hflags & MIPS_HFLAG_CP0)))
1753        generate_exception_err(ctx, EXCP_CpU, 0);
1754}
1755
1756static inline void check_cp1_enabled(DisasContext *ctx)
1757{
1758    if (unlikely(!(ctx->hflags & MIPS_HFLAG_FPU)))
1759        generate_exception_err(ctx, EXCP_CpU, 1);
1760}
1761
1762/* Verify that the processor is running with COP1X instructions enabled.
1763   This is associated with the nabla symbol in the MIPS32 and MIPS64
1764   opcode tables.  */
1765
1766static inline void check_cop1x(DisasContext *ctx)
1767{
1768    if (unlikely(!(ctx->hflags & MIPS_HFLAG_COP1X)))
1769        generate_exception_end(ctx, EXCP_RI);
1770}
1771
1772/* Verify that the processor is running with 64-bit floating-point
1773   operations enabled.  */
1774
1775static inline void check_cp1_64bitmode(DisasContext *ctx)
1776{
1777    if (unlikely(~ctx->hflags & (MIPS_HFLAG_F64 | MIPS_HFLAG_COP1X)))
1778        generate_exception_end(ctx, EXCP_RI);
1779}
1780
1781/*
1782 * Verify if floating point register is valid; an operation is not defined
1783 * if bit 0 of any register specification is set and the FR bit in the
1784 * Status register equals zero, since the register numbers specify an
1785 * even-odd pair of adjacent coprocessor general registers. When the FR bit
1786 * in the Status register equals one, both even and odd register numbers
1787 * are valid. This limitation exists only for 64 bit wide (d,l,ps) registers.
1788 *
1789 * Multiple 64 bit wide registers can be checked by calling
1790 * gen_op_cp1_registers(freg1 | freg2 | ... | fregN);
1791 */
1792static inline void check_cp1_registers(DisasContext *ctx, int regs)
1793{
1794    if (unlikely(!(ctx->hflags & MIPS_HFLAG_F64) && (regs & 1)))
1795        generate_exception_end(ctx, EXCP_RI);
1796}
1797
1798/* Verify that the processor is running with DSP instructions enabled.
1799   This is enabled by CP0 Status register MX(24) bit.
1800 */
1801
1802static inline void check_dsp(DisasContext *ctx)
1803{
1804    if (unlikely(!(ctx->hflags & MIPS_HFLAG_DSP))) {
1805        if (ctx->insn_flags & ASE_DSP) {
1806            generate_exception_end(ctx, EXCP_DSPDIS);
1807        } else {
1808            generate_exception_end(ctx, EXCP_RI);
1809        }
1810    }
1811}
1812
1813static inline void check_dspr2(DisasContext *ctx)
1814{
1815    if (unlikely(!(ctx->hflags & MIPS_HFLAG_DSPR2))) {
1816        if (ctx->insn_flags & ASE_DSP) {
1817            generate_exception_end(ctx, EXCP_DSPDIS);
1818        } else {
1819            generate_exception_end(ctx, EXCP_RI);
1820        }
1821    }
1822}
1823
1824/* This code generates a "reserved instruction" exception if the
1825   CPU does not support the instruction set corresponding to flags. */
1826static inline void check_insn(DisasContext *ctx, int flags)
1827{
1828    if (unlikely(!(ctx->insn_flags & flags))) {
1829        generate_exception_end(ctx, EXCP_RI);
1830    }
1831}
1832
1833/* This code generates a "reserved instruction" exception if the
1834   CPU has corresponding flag set which indicates that the instruction
1835   has been removed. */
1836static inline void check_insn_opc_removed(DisasContext *ctx, int flags)
1837{
1838    if (unlikely(ctx->insn_flags & flags)) {
1839        generate_exception_end(ctx, EXCP_RI);
1840    }
1841}
1842
1843/* This code generates a "reserved instruction" exception if the
1844   CPU does not support 64-bit paired-single (PS) floating point data type */
1845static inline void check_ps(DisasContext *ctx)
1846{
1847    if (unlikely(!ctx->ps)) {
1848        generate_exception(ctx, EXCP_RI);
1849    }
1850    check_cp1_64bitmode(ctx);
1851}
1852
1853#ifdef TARGET_MIPS64
1854/* This code generates a "reserved instruction" exception if 64-bit
1855   instructions are not enabled. */
1856static inline void check_mips_64(DisasContext *ctx)
1857{
1858    if (unlikely(!(ctx->hflags & MIPS_HFLAG_64)))
1859        generate_exception_end(ctx, EXCP_RI);
1860}
1861#endif
1862
1863#ifndef CONFIG_USER_ONLY
1864static inline void check_mvh(DisasContext *ctx)
1865{
1866    if (unlikely(!ctx->mvh)) {
1867        generate_exception(ctx, EXCP_RI);
1868    }
1869}
1870#endif
1871
1872/* Define small wrappers for gen_load_fpr* so that we have a uniform
1873   calling interface for 32 and 64-bit FPRs.  No sense in changing
1874   all callers for gen_load_fpr32 when we need the CTX parameter for
1875   this one use.  */
1876#define gen_ldcmp_fpr32(ctx, x, y) gen_load_fpr32(ctx, x, y)
1877#define gen_ldcmp_fpr64(ctx, x, y) gen_load_fpr64(ctx, x, y)
1878#define FOP_CONDS(type, abs, fmt, ifmt, bits)                                 \
1879static inline void gen_cmp ## type ## _ ## fmt(DisasContext *ctx, int n,      \
1880                                               int ft, int fs, int cc)        \
1881{                                                                             \
1882    TCGv_i##bits fp0 = tcg_temp_new_i##bits ();                               \
1883    TCGv_i##bits fp1 = tcg_temp_new_i##bits ();                               \
1884    switch (ifmt) {                                                           \
1885    case FMT_PS:                                                              \
1886        check_ps(ctx);                                                        \
1887        break;                                                                \
1888    case FMT_D:                                                               \
1889        if (abs) {                                                            \
1890            check_cop1x(ctx);                                                 \
1891        }                                                                     \
1892        check_cp1_registers(ctx, fs | ft);                                    \
1893        break;                                                                \
1894    case FMT_S:                                                               \
1895        if (abs) {                                                            \
1896            check_cop1x(ctx);                                                 \
1897        }                                                                     \
1898        break;                                                                \
1899    }                                                                         \
1900    gen_ldcmp_fpr##bits (ctx, fp0, fs);                                       \
1901    gen_ldcmp_fpr##bits (ctx, fp1, ft);                                       \
1902    switch (n) {                                                              \
1903    case  0: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _f, fp0, fp1, cc);    break;\
1904    case  1: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _un, fp0, fp1, cc);   break;\
1905    case  2: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _eq, fp0, fp1, cc);   break;\
1906    case  3: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ueq, fp0, fp1, cc);  break;\
1907    case  4: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _olt, fp0, fp1, cc);  break;\
1908    case  5: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ult, fp0, fp1, cc);  break;\
1909    case  6: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ole, fp0, fp1, cc);  break;\
1910    case  7: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ule, fp0, fp1, cc);  break;\
1911    case  8: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _sf, fp0, fp1, cc);   break;\
1912    case  9: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ngle, fp0, fp1, cc); break;\
1913    case 10: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _seq, fp0, fp1, cc);  break;\
1914    case 11: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ngl, fp0, fp1, cc);  break;\
1915    case 12: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _lt, fp0, fp1, cc);   break;\
1916    case 13: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _nge, fp0, fp1, cc);  break;\
1917    case 14: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _le, fp0, fp1, cc);   break;\
1918    case 15: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ngt, fp0, fp1, cc);  break;\
1919    default: abort();                                                         \
1920    }                                                                         \
1921    tcg_temp_free_i##bits (fp0);                                              \
1922    tcg_temp_free_i##bits (fp1);                                              \
1923}
1924
1925FOP_CONDS(, 0, d, FMT_D, 64)
1926FOP_CONDS(abs, 1, d, FMT_D, 64)
1927FOP_CONDS(, 0, s, FMT_S, 32)
1928FOP_CONDS(abs, 1, s, FMT_S, 32)
1929FOP_CONDS(, 0, ps, FMT_PS, 64)
1930FOP_CONDS(abs, 1, ps, FMT_PS, 64)
1931#undef FOP_CONDS
1932
1933#define FOP_CONDNS(fmt, ifmt, bits, STORE)                              \
1934static inline void gen_r6_cmp_ ## fmt(DisasContext * ctx, int n,        \
1935                                      int ft, int fs, int fd)           \
1936{                                                                       \
1937    TCGv_i ## bits fp0 = tcg_temp_new_i ## bits();                      \
1938    TCGv_i ## bits fp1 = tcg_temp_new_i ## bits();                      \
1939    if (ifmt == FMT_D) {                                                \
1940        check_cp1_registers(ctx, fs | ft | fd);                         \
1941    }                                                                   \
1942    gen_ldcmp_fpr ## bits(ctx, fp0, fs);                                \
1943    gen_ldcmp_fpr ## bits(ctx, fp1, ft);                                \
1944    switch (n) {                                                        \
1945    case  0:                                                            \
1946        gen_helper_r6_cmp_ ## fmt ## _af(fp0, cpu_env, fp0, fp1);       \
1947        break;                                                          \
1948    case  1:                                                            \
1949        gen_helper_r6_cmp_ ## fmt ## _un(fp0, cpu_env, fp0, fp1);       \
1950        break;                                                          \
1951    case  2:                                                            \
1952        gen_helper_r6_cmp_ ## fmt ## _eq(fp0, cpu_env, fp0, fp1);       \
1953        break;                                                          \
1954    case  3:                                                            \
1955        gen_helper_r6_cmp_ ## fmt ## _ueq(fp0, cpu_env, fp0, fp1);      \
1956        break;                                                          \
1957    case  4:                                                            \
1958        gen_helper_r6_cmp_ ## fmt ## _lt(fp0, cpu_env, fp0, fp1);       \
1959        break;                                                          \
1960    case  5:                                                            \
1961        gen_helper_r6_cmp_ ## fmt ## _ult(fp0, cpu_env, fp0, fp1);      \
1962        break;                                                          \
1963    case  6:                                                            \
1964        gen_helper_r6_cmp_ ## fmt ## _le(fp0, cpu_env, fp0, fp1);       \
1965        break;                                                          \
1966    case  7:                                                            \
1967        gen_helper_r6_cmp_ ## fmt ## _ule(fp0, cpu_env, fp0, fp1);      \
1968        break;                                                          \
1969    case  8:                                                            \
1970        gen_helper_r6_cmp_ ## fmt ## _saf(fp0, cpu_env, fp0, fp1);      \
1971        break;                                                          \
1972    case  9:                                                            \
1973        gen_helper_r6_cmp_ ## fmt ## _sun(fp0, cpu_env, fp0, fp1);      \
1974        break;                                                          \
1975    case 10:                                                            \
1976        gen_helper_r6_cmp_ ## fmt ## _seq(fp0, cpu_env, fp0, fp1);      \
1977        break;                                                          \
1978    case 11:                                                            \
1979        gen_helper_r6_cmp_ ## fmt ## _sueq(fp0, cpu_env, fp0, fp1);     \
1980        break;                                                          \
1981    case 12:                                                            \
1982        gen_helper_r6_cmp_ ## fmt ## _slt(fp0, cpu_env, fp0, fp1);      \
1983        break;                                                          \
1984    case 13:                                                            \
1985        gen_helper_r6_cmp_ ## fmt ## _sult(fp0, cpu_env, fp0, fp1);     \
1986        break;                                                          \
1987    case 14:                                                            \
1988        gen_helper_r6_cmp_ ## fmt ## _sle(fp0, cpu_env, fp0, fp1);      \
1989        break;                                                          \
1990    case 15:                                                            \
1991        gen_helper_r6_cmp_ ## fmt ## _sule(fp0, cpu_env, fp0, fp1);     \
1992        break;                                                          \
1993    case 17:                                                            \
1994        gen_helper_r6_cmp_ ## fmt ## _or(fp0, cpu_env, fp0, fp1);       \
1995        break;                                                          \
1996    case 18:                                                            \
1997        gen_helper_r6_cmp_ ## fmt ## _une(fp0, cpu_env, fp0, fp1);      \
1998        break;                                                          \
1999    case 19:                                                            \
2000        gen_helper_r6_cmp_ ## fmt ## _ne(fp0, cpu_env, fp0, fp1);       \
2001        break;                                                          \
2002    case 25:                                                            \
2003        gen_helper_r6_cmp_ ## fmt ## _sor(fp0, cpu_env, fp0, fp1);      \
2004        break;                                                          \
2005    case 26:                                                            \
2006        gen_helper_r6_cmp_ ## fmt ## _sune(fp0, cpu_env, fp0, fp1);     \
2007        break;                                                          \
2008    case 27:                                                            \
2009        gen_helper_r6_cmp_ ## fmt ## _sne(fp0, cpu_env, fp0, fp1);      \
2010        break;                                                          \
2011    default:                                                            \
2012        abort();                                                        \
2013    }                                                                   \
2014    STORE;                                                              \
2015    tcg_temp_free_i ## bits (fp0);                                      \
2016    tcg_temp_free_i ## bits (fp1);                                      \
2017}
2018
2019FOP_CONDNS(d, FMT_D, 64, gen_store_fpr64(ctx, fp0, fd))
2020FOP_CONDNS(s, FMT_S, 32, gen_store_fpr32(ctx, fp0, fd))
2021#undef FOP_CONDNS
2022#undef gen_ldcmp_fpr32
2023#undef gen_ldcmp_fpr64
2024
2025/* load/store instructions. */
2026#ifdef CONFIG_USER_ONLY
2027#define OP_LD_ATOMIC(insn,fname)                                           \
2028static inline void op_ld_##insn(TCGv ret, TCGv arg1, DisasContext *ctx)    \
2029{                                                                          \
2030    TCGv t0 = tcg_temp_new();                                              \
2031    tcg_gen_mov_tl(t0, arg1);                                              \
2032    tcg_gen_qemu_##fname(ret, arg1, ctx->mem_idx);                         \
2033    tcg_gen_st_tl(t0, cpu_env, offsetof(CPUMIPSState, lladdr));                \
2034    tcg_gen_st_tl(ret, cpu_env, offsetof(CPUMIPSState, llval));                \
2035    tcg_temp_free(t0);                                                     \
2036}
2037#else
2038#define OP_LD_ATOMIC(insn,fname)                                           \
2039static inline void op_ld_##insn(TCGv ret, TCGv arg1, DisasContext *ctx)    \
2040{                                                                          \
2041    gen_helper_1e1i(insn, ret, arg1, ctx->mem_idx);                        \
2042}
2043#endif
2044OP_LD_ATOMIC(ll,ld32s);
2045#if defined(TARGET_MIPS64)
2046OP_LD_ATOMIC(lld,ld64);
2047#endif
2048#undef OP_LD_ATOMIC
2049
2050#ifdef CONFIG_USER_ONLY
2051#define OP_ST_ATOMIC(insn,fname,ldname,almask)                               \
2052static inline void op_st_##insn(TCGv arg1, TCGv arg2, int rt, DisasContext *ctx) \
2053{                                                                            \
2054    TCGv t0 = tcg_temp_new();                                                \
2055    TCGLabel *l1 = gen_new_label();                                          \
2056    TCGLabel *l2 = gen_new_label();                                          \
2057                                                                             \
2058    tcg_gen_andi_tl(t0, arg2, almask);                                       \
2059    tcg_gen_brcondi_tl(TCG_COND_EQ, t0, 0, l1);                              \
2060    tcg_gen_st_tl(arg2, cpu_env, offsetof(CPUMIPSState, CP0_BadVAddr));          \
2061    generate_exception(ctx, EXCP_AdES);                                      \
2062    gen_set_label(l1);                                                       \
2063    tcg_gen_ld_tl(t0, cpu_env, offsetof(CPUMIPSState, lladdr));                  \
2064    tcg_gen_brcond_tl(TCG_COND_NE, arg2, t0, l2);                            \
2065    tcg_gen_movi_tl(t0, rt | ((almask << 3) & 0x20));                        \
2066    tcg_gen_st_tl(t0, cpu_env, offsetof(CPUMIPSState, llreg));                   \
2067    tcg_gen_st_tl(arg1, cpu_env, offsetof(CPUMIPSState, llnewval));              \
2068    generate_exception_end(ctx, EXCP_SC);                                    \
2069    gen_set_label(l2);                                                       \
2070    tcg_gen_movi_tl(t0, 0);                                                  \
2071    gen_store_gpr(t0, rt);                                                   \
2072    tcg_temp_free(t0);                                                       \
2073}
2074#else
2075#define OP_ST_ATOMIC(insn,fname,ldname,almask)                               \
2076static inline void op_st_##insn(TCGv arg1, TCGv arg2, int rt, DisasContext *ctx) \
2077{                                                                            \
2078    TCGv t0 = tcg_temp_new();                                                \
2079    gen_helper_1e2i(insn, t0, arg1, arg2, ctx->mem_idx);                     \
2080    gen_store_gpr(t0, rt);                                                   \
2081    tcg_temp_free(t0);                                                       \
2082}
2083#endif
2084OP_ST_ATOMIC(sc,st32,ld32s,0x3);
2085#if defined(TARGET_MIPS64)
2086OP_ST_ATOMIC(scd,st64,ld64,0x7);
2087#endif
2088#undef OP_ST_ATOMIC
2089
2090static void gen_base_offset_addr (DisasContext *ctx, TCGv addr,
2091                                  int base, int16_t offset)
2092{
2093    if (base == 0) {
2094        tcg_gen_movi_tl(addr, offset);
2095    } else if (offset == 0) {
2096        gen_load_gpr(addr, base);
2097    } else {
2098        tcg_gen_movi_tl(addr, offset);
2099        gen_op_addr_add(ctx, addr, cpu_gpr[base], addr);
2100    }
2101}
2102
2103static target_ulong pc_relative_pc (DisasContext *ctx)
2104{
2105    target_ulong pc = ctx->pc;
2106
2107    if (ctx->hflags & MIPS_HFLAG_BMASK) {
2108        int branch_bytes = ctx->hflags & MIPS_HFLAG_BDS16 ? 2 : 4;
2109
2110        pc -= branch_bytes;
2111    }
2112
2113    pc &= ~(target_ulong)3;
2114    return pc;
2115}
2116
2117/* Load */
2118static void gen_ld(DisasContext *ctx, uint32_t opc,
2119                   int rt, int base, int16_t offset)
2120{
2121    TCGv t0, t1, t2;
2122
2123    if (rt == 0 && ctx->insn_flags & (INSN_LOONGSON2E | INSN_LOONGSON2F)) {
2124        /* Loongson CPU uses a load to zero register for prefetch.
2125           We emulate it as a NOP. On other CPU we must perform the
2126           actual memory access. */
2127        return;
2128    }
2129
2130    t0 = tcg_temp_new();
2131    gen_base_offset_addr(ctx, t0, base, offset);
2132
2133    switch (opc) {
2134#if defined(TARGET_MIPS64)
2135    case OPC_LWU:
2136        tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEUL |
2137                           ctx->default_tcg_memop_mask);
2138        gen_store_gpr(t0, rt);
2139        break;
2140    case OPC_LD:
2141        tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEQ |
2142                           ctx->default_tcg_memop_mask);
2143        gen_store_gpr(t0, rt);
2144        break;
2145    case OPC_LLD:
2146    case R6_OPC_LLD:
2147        op_ld_lld(t0, t0, ctx);
2148        gen_store_gpr(t0, rt);
2149        break;
2150    case OPC_LDL:
2151        t1 = tcg_temp_new();
2152        /* Do a byte access to possibly trigger a page
2153           fault with the unaligned address.  */
2154        tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_UB);
2155        tcg_gen_andi_tl(t1, t0, 7);
2156#ifndef TARGET_WORDS_BIGENDIAN
2157        tcg_gen_xori_tl(t1, t1, 7);
2158#endif
2159        tcg_gen_shli_tl(t1, t1, 3);
2160        tcg_gen_andi_tl(t0, t0, ~7);
2161        tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEQ);
2162        tcg_gen_shl_tl(t0, t0, t1);
2163        t2 = tcg_const_tl(-1);
2164        tcg_gen_shl_tl(t2, t2, t1);
2165        gen_load_gpr(t1, rt);
2166        tcg_gen_andc_tl(t1, t1, t2);
2167        tcg_temp_free(t2);
2168        tcg_gen_or_tl(t0, t0, t1);
2169        tcg_temp_free(t1);
2170        gen_store_gpr(t0, rt);
2171        break;
2172    case OPC_LDR:
2173        t1 = tcg_temp_new();
2174        /* Do a byte access to possibly trigger a page
2175           fault with the unaligned address.  */
2176        tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_UB);
2177        tcg_gen_andi_tl(t1, t0, 7);
2178#ifdef TARGET_WORDS_BIGENDIAN
2179        tcg_gen_xori_tl(t1, t1, 7);
2180#endif
2181        tcg_gen_shli_tl(t1, t1, 3);
2182        tcg_gen_andi_tl(t0, t0, ~7);
2183        tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEQ);
2184        tcg_gen_shr_tl(t0, t0, t1);
2185        tcg_gen_xori_tl(t1, t1, 63);
2186        t2 = tcg_const_tl(0xfffffffffffffffeull);
2187        tcg_gen_shl_tl(t2, t2, t1);
2188        gen_load_gpr(t1, rt);
2189        tcg_gen_and_tl(t1, t1, t2);
2190        tcg_temp_free(t2);
2191        tcg_gen_or_tl(t0, t0, t1);
2192        tcg_temp_free(t1);
2193        gen_store_gpr(t0, rt);
2194        break;
2195    case OPC_LDPC:
2196        t1 = tcg_const_tl(pc_relative_pc(ctx));
2197        gen_op_addr_add(ctx, t0, t0, t1);
2198        tcg_temp_free(t1);
2199        tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEQ);
2200        gen_store_gpr(t0, rt);
2201        break;
2202#endif
2203    case OPC_LWPC:
2204        t1 = tcg_const_tl(pc_relative_pc(ctx));
2205        gen_op_addr_add(ctx, t0, t0, t1);
2206        tcg_temp_free(t1);
2207        tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TESL);
2208        gen_store_gpr(t0, rt);
2209        break;
2210    case OPC_LW:
2211        tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TESL |
2212                           ctx->default_tcg_memop_mask);
2213        gen_store_gpr(t0, rt);
2214        break;
2215    case OPC_LH:
2216        tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TESW |
2217                           ctx->default_tcg_memop_mask);
2218        gen_store_gpr(t0, rt);
2219        break;
2220    case OPC_LHU:
2221        tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEUW |
2222                           ctx->default_tcg_memop_mask);
2223        gen_store_gpr(t0, rt);
2224        break;
2225    case OPC_LB:
2226        tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_SB);
2227        gen_store_gpr(t0, rt);
2228        break;
2229    case OPC_LBU:
2230        tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_UB);
2231        gen_store_gpr(t0, rt);
2232        break;
2233    case OPC_LWL:
2234        t1 = tcg_temp_new();
2235        /* Do a byte access to possibly trigger a page
2236           fault with the unaligned address.  */
2237        tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_UB);
2238        tcg_gen_andi_tl(t1, t0, 3);
2239#ifndef TARGET_WORDS_BIGENDIAN
2240        tcg_gen_xori_tl(t1, t1, 3);
2241#endif
2242        tcg_gen_shli_tl(t1, t1, 3);
2243        tcg_gen_andi_tl(t0, t0, ~3);
2244        tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEUL);
2245        tcg_gen_shl_tl(t0, t0, t1);
2246        t2 = tcg_const_tl(-1);
2247        tcg_gen_shl_tl(t2, t2, t1);
2248        gen_load_gpr(t1, rt);
2249        tcg_gen_andc_tl(t1, t1, t2);
2250        tcg_temp_free(t2);
2251        tcg_gen_or_tl(t0, t0, t1);
2252        tcg_temp_free(t1);
2253        tcg_gen_ext32s_tl(t0, t0);
2254        gen_store_gpr(t0, rt);
2255        break;
2256    case OPC_LWR:
2257        t1 = tcg_temp_new();
2258        /* Do a byte access to possibly trigger a page
2259           fault with the unaligned address.  */
2260        tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_UB);
2261        tcg_gen_andi_tl(t1, t0, 3);
2262#ifdef TARGET_WORDS_BIGENDIAN
2263        tcg_gen_xori_tl(t1, t1, 3);
2264#endif
2265        tcg_gen_shli_tl(t1, t1, 3);
2266        tcg_gen_andi_tl(t0, t0, ~3);
2267        tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEUL);
2268        tcg_gen_shr_tl(t0, t0, t1);
2269        tcg_gen_xori_tl(t1, t1, 31);
2270        t2 = tcg_const_tl(0xfffffffeull);
2271        tcg_gen_shl_tl(t2, t2, t1);
2272        gen_load_gpr(t1, rt);
2273        tcg_gen_and_tl(t1, t1, t2);
2274        tcg_temp_free(t2);
2275        tcg_gen_or_tl(t0, t0, t1);
2276        tcg_temp_free(t1);
2277        tcg_gen_ext32s_tl(t0, t0);
2278        gen_store_gpr(t0, rt);
2279        break;
2280    case OPC_LL:
2281    case R6_OPC_LL:
2282        op_ld_ll(t0, t0, ctx);
2283        gen_store_gpr(t0, rt);
2284        break;
2285    }
2286    tcg_temp_free(t0);
2287}
2288
2289/* Store */
2290static void gen_st (DisasContext *ctx, uint32_t opc, int rt,
2291                    int base, int16_t offset)
2292{
2293    TCGv t0 = tcg_temp_new();
2294    TCGv t1 = tcg_temp_new();
2295
2296    gen_base_offset_addr(ctx, t0, base, offset);
2297    gen_load_gpr(t1, rt);
2298    switch (opc) {
2299#if defined(TARGET_MIPS64)
2300    case OPC_SD:
2301        tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEQ |
2302                           ctx->default_tcg_memop_mask);
2303        break;
2304    case OPC_SDL:
2305        gen_helper_0e2i(sdl, t1, t0, ctx->mem_idx);
2306        break;
2307    case OPC_SDR:
2308        gen_helper_0e2i(sdr, t1, t0, ctx->mem_idx);
2309        break;
2310#endif
2311    case OPC_SW:
2312        tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL |
2313                           ctx->default_tcg_memop_mask);
2314        break;
2315    case OPC_SH:
2316        tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUW |
2317                           ctx->default_tcg_memop_mask);
2318        break;
2319    case OPC_SB:
2320        tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_8);
2321        break;
2322    case OPC_SWL:
2323        gen_helper_0e2i(swl, t1, t0, ctx->mem_idx);
2324        break;
2325    case OPC_SWR:
2326        gen_helper_0e2i(swr, t1, t0, ctx->mem_idx);
2327        break;
2328    }
2329    tcg_temp_free(t0);
2330    tcg_temp_free(t1);
2331}
2332
2333
2334/* Store conditional */
2335static void gen_st_cond (DisasContext *ctx, uint32_t opc, int rt,
2336                         int base, int16_t offset)
2337{
2338    TCGv t0, t1;
2339
2340#ifdef CONFIG_USER_ONLY
2341    t0 = tcg_temp_local_new();
2342    t1 = tcg_temp_local_new();
2343#else
2344    t0 = tcg_temp_new();
2345    t1 = tcg_temp_new();
2346#endif
2347    gen_base_offset_addr(ctx, t0, base, offset);
2348    gen_load_gpr(t1, rt);
2349    switch (opc) {
2350#if defined(TARGET_MIPS64)
2351    case OPC_SCD:
2352    case R6_OPC_SCD:
2353        op_st_scd(t1, t0, rt, ctx);
2354        break;
2355#endif
2356    case OPC_SC:
2357    case R6_OPC_SC:
2358        op_st_sc(t1, t0, rt, ctx);
2359        break;
2360    }
2361    tcg_temp_free(t1);
2362    tcg_temp_free(t0);
2363}
2364
2365/* Load and store */
2366static void gen_flt_ldst (DisasContext *ctx, uint32_t opc, int ft,
2367                          int base, int16_t offset)
2368{
2369    TCGv t0 = tcg_temp_new();
2370
2371    gen_base_offset_addr(ctx, t0, base, offset);
2372    /* Don't do NOP if destination is zero: we must perform the actual
2373       memory access. */
2374    switch (opc) {
2375    case OPC_LWC1:
2376        {
2377            TCGv_i32 fp0 = tcg_temp_new_i32();
2378            tcg_gen_qemu_ld_i32(fp0, t0, ctx->mem_idx, MO_TESL |
2379                                ctx->default_tcg_memop_mask);
2380            gen_store_fpr32(ctx, fp0, ft);
2381            tcg_temp_free_i32(fp0);
2382        }
2383        break;
2384    case OPC_SWC1:
2385        {
2386            TCGv_i32 fp0 = tcg_temp_new_i32();
2387            gen_load_fpr32(ctx, fp0, ft);
2388            tcg_gen_qemu_st_i32(fp0, t0, ctx->mem_idx, MO_TEUL |
2389                                ctx->default_tcg_memop_mask);
2390            tcg_temp_free_i32(fp0);
2391        }
2392        break;
2393    case OPC_LDC1:
2394        {
2395            TCGv_i64 fp0 = tcg_temp_new_i64();
2396            tcg_gen_qemu_ld_i64(fp0, t0, ctx->mem_idx, MO_TEQ |
2397                                ctx->default_tcg_memop_mask);
2398            gen_store_fpr64(ctx, fp0, ft);
2399            tcg_temp_free_i64(fp0);
2400        }
2401        break;
2402    case OPC_SDC1:
2403        {
2404            TCGv_i64 fp0 = tcg_temp_new_i64();
2405            gen_load_fpr64(ctx, fp0, ft);
2406            tcg_gen_qemu_st_i64(fp0, t0, ctx->mem_idx, MO_TEQ |
2407                                ctx->default_tcg_memop_mask);
2408            tcg_temp_free_i64(fp0);
2409        }
2410        break;
2411    default:
2412        MIPS_INVAL("flt_ldst");
2413        generate_exception_end(ctx, EXCP_RI);
2414        goto out;
2415    }
2416 out:
2417    tcg_temp_free(t0);
2418}
2419
2420static void gen_cop1_ldst(DisasContext *ctx, uint32_t op, int rt,
2421                          int rs, int16_t imm)
2422{
2423    if (ctx->CP0_Config1 & (1 << CP0C1_FP)) {
2424        check_cp1_enabled(ctx);
2425        switch (op) {
2426        case OPC_LDC1:
2427        case OPC_SDC1:
2428            check_insn(ctx, ISA_MIPS2);
2429            /* Fallthrough */
2430        default:
2431            gen_flt_ldst(ctx, op, rt, rs, imm);
2432        }
2433    } else {
2434        generate_exception_err(ctx, EXCP_CpU, 1);
2435    }
2436}
2437
2438/* Arithmetic with immediate operand */
2439static void gen_arith_imm(DisasContext *ctx, uint32_t opc,
2440                          int rt, int rs, int16_t imm)
2441{
2442    target_ulong uimm = (target_long)imm; /* Sign extend to 32/64 bits */
2443
2444    if (rt == 0 && opc != OPC_ADDI && opc != OPC_DADDI) {
2445        /* If no destination, treat it as a NOP.
2446           For addi, we must generate the overflow exception when needed. */
2447        return;
2448    }
2449    switch (opc) {
2450    case OPC_ADDI:
2451        {
2452            TCGv t0 = tcg_temp_local_new();
2453            TCGv t1 = tcg_temp_new();
2454            TCGv t2 = tcg_temp_new();
2455            TCGLabel *l1 = gen_new_label();
2456
2457            gen_load_gpr(t1, rs);
2458            tcg_gen_addi_tl(t0, t1, uimm);
2459            tcg_gen_ext32s_tl(t0, t0);
2460
2461            tcg_gen_xori_tl(t1, t1, ~uimm);
2462            tcg_gen_xori_tl(t2, t0, uimm);
2463            tcg_gen_and_tl(t1, t1, t2);
2464            tcg_temp_free(t2);
2465            tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
2466            tcg_temp_free(t1);
2467            /* operands of same sign, result different sign */
2468            generate_exception(ctx, EXCP_OVERFLOW);
2469            gen_set_label(l1);
2470            tcg_gen_ext32s_tl(t0, t0);
2471            gen_store_gpr(t0, rt);
2472            tcg_temp_free(t0);
2473        }
2474        break;
2475    case OPC_ADDIU:
2476        if (rs != 0) {
2477            tcg_gen_addi_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
2478            tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
2479        } else {
2480            tcg_gen_movi_tl(cpu_gpr[rt], uimm);
2481        }
2482        break;
2483#if defined(TARGET_MIPS64)
2484    case OPC_DADDI:
2485        {
2486            TCGv t0 = tcg_temp_local_new();
2487            TCGv t1 = tcg_temp_new();
2488            TCGv t2 = tcg_temp_new();
2489            TCGLabel *l1 = gen_new_label();
2490
2491            gen_load_gpr(t1, rs);
2492            tcg_gen_addi_tl(t0, t1, uimm);
2493
2494            tcg_gen_xori_tl(t1, t1, ~uimm);
2495            tcg_gen_xori_tl(t2, t0, uimm);
2496            tcg_gen_and_tl(t1, t1, t2);
2497            tcg_temp_free(t2);
2498            tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
2499            tcg_temp_free(t1);
2500            /* operands of same sign, result different sign */
2501            generate_exception(ctx, EXCP_OVERFLOW);
2502            gen_set_label(l1);
2503            gen_store_gpr(t0, rt);
2504            tcg_temp_free(t0);
2505        }
2506        break;
2507    case OPC_DADDIU:
2508        if (rs != 0) {
2509            tcg_gen_addi_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
2510        } else {
2511            tcg_gen_movi_tl(cpu_gpr[rt], uimm);
2512        }
2513        break;
2514#endif
2515    }
2516}
2517
2518/* Logic with immediate operand */
2519static void gen_logic_imm(DisasContext *ctx, uint32_t opc,
2520                          int rt, int rs, int16_t imm)
2521{
2522    target_ulong uimm;
2523
2524    if (rt == 0) {
2525        /* If no destination, treat it as a NOP. */
2526        return;
2527    }
2528    uimm = (uint16_t)imm;
2529    switch (opc) {
2530    case OPC_ANDI:
2531        if (likely(rs != 0))
2532            tcg_gen_andi_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
2533        else
2534            tcg_gen_movi_tl(cpu_gpr[rt], 0);
2535        break;
2536    case OPC_ORI:
2537        if (rs != 0)
2538            tcg_gen_ori_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
2539        else
2540            tcg_gen_movi_tl(cpu_gpr[rt], uimm);
2541        break;
2542    case OPC_XORI:
2543        if (likely(rs != 0))
2544            tcg_gen_xori_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
2545        else
2546            tcg_gen_movi_tl(cpu_gpr[rt], uimm);
2547        break;
2548    case OPC_LUI:
2549        if (rs != 0 && (ctx->insn_flags & ISA_MIPS32R6)) {
2550            /* OPC_AUI */
2551            tcg_gen_addi_tl(cpu_gpr[rt], cpu_gpr[rs], imm << 16);
2552            tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
2553        } else {
2554            tcg_gen_movi_tl(cpu_gpr[rt], imm << 16);
2555        }
2556        break;
2557
2558    default:
2559        break;
2560    }
2561}
2562
2563/* Set on less than with immediate operand */
2564static void gen_slt_imm(DisasContext *ctx, uint32_t opc,
2565                        int rt, int rs, int16_t imm)
2566{
2567    target_ulong uimm = (target_long)imm; /* Sign extend to 32/64 bits */
2568    TCGv t0;
2569
2570    if (rt == 0) {
2571        /* If no destination, treat it as a NOP. */
2572        return;
2573    }
2574    t0 = tcg_temp_new();
2575    gen_load_gpr(t0, rs);
2576    switch (opc) {
2577    case OPC_SLTI:
2578        tcg_gen_setcondi_tl(TCG_COND_LT, cpu_gpr[rt], t0, uimm);
2579        break;
2580    case OPC_SLTIU:
2581        tcg_gen_setcondi_tl(TCG_COND_LTU, cpu_gpr[rt], t0, uimm);
2582        break;
2583    }
2584    tcg_temp_free(t0);
2585}
2586
2587/* Shifts with immediate operand */
2588static void gen_shift_imm(DisasContext *ctx, uint32_t opc,
2589                          int rt, int rs, int16_t imm)
2590{
2591    target_ulong uimm = ((uint16_t)imm) & 0x1f;
2592    TCGv t0;
2593
2594    if (rt == 0) {
2595        /* If no destination, treat it as a NOP. */
2596        return;
2597    }
2598
2599    t0 = tcg_temp_new();
2600    gen_load_gpr(t0, rs);
2601    switch (opc) {
2602    case OPC_SLL:
2603        tcg_gen_shli_tl(t0, t0, uimm);
2604        tcg_gen_ext32s_tl(cpu_gpr[rt], t0);
2605        break;
2606    case OPC_SRA:
2607        tcg_gen_sari_tl(cpu_gpr[rt], t0, uimm);
2608        break;
2609    case OPC_SRL:
2610        if (uimm != 0) {
2611            tcg_gen_ext32u_tl(t0, t0);
2612            tcg_gen_shri_tl(cpu_gpr[rt], t0, uimm);
2613        } else {
2614            tcg_gen_ext32s_tl(cpu_gpr[rt], t0);
2615        }
2616        break;
2617    case OPC_ROTR:
2618        if (uimm != 0) {
2619            TCGv_i32 t1 = tcg_temp_new_i32();
2620
2621            tcg_gen_trunc_tl_i32(t1, t0);
2622            tcg_gen_rotri_i32(t1, t1, uimm);
2623            tcg_gen_ext_i32_tl(cpu_gpr[rt], t1);
2624            tcg_temp_free_i32(t1);
2625        } else {
2626            tcg_gen_ext32s_tl(cpu_gpr[rt], t0);
2627        }
2628        break;
2629#if defined(TARGET_MIPS64)
2630    case OPC_DSLL:
2631        tcg_gen_shli_tl(cpu_gpr[rt], t0, uimm);
2632        break;
2633    case OPC_DSRA:
2634        tcg_gen_sari_tl(cpu_gpr[rt], t0, uimm);
2635        break;
2636    case OPC_DSRL:
2637        tcg_gen_shri_tl(cpu_gpr[rt], t0, uimm);
2638        break;
2639    case OPC_DROTR:
2640        if (uimm != 0) {
2641            tcg_gen_rotri_tl(cpu_gpr[rt], t0, uimm);
2642        } else {
2643            tcg_gen_mov_tl(cpu_gpr[rt], t0);
2644        }
2645        break;
2646    case OPC_DSLL32:
2647        tcg_gen_shli_tl(cpu_gpr[rt], t0, uimm + 32);
2648        break;
2649    case OPC_DSRA32:
2650        tcg_gen_sari_tl(cpu_gpr[rt], t0, uimm + 32);
2651        break;
2652    case OPC_DSRL32:
2653        tcg_gen_shri_tl(cpu_gpr[rt], t0, uimm + 32);
2654        break;
2655    case OPC_DROTR32:
2656        tcg_gen_rotri_tl(cpu_gpr[rt], t0, uimm + 32);
2657        break;
2658#endif
2659    }
2660    tcg_temp_free(t0);
2661}
2662
2663/* Arithmetic */
2664static void gen_arith(DisasContext *ctx, uint32_t opc,
2665                      int rd, int rs, int rt)
2666{
2667    if (rd == 0 && opc != OPC_ADD && opc != OPC_SUB
2668       && opc != OPC_DADD && opc != OPC_DSUB) {
2669        /* If no destination, treat it as a NOP.
2670           For add & sub, we must generate the overflow exception when needed. */
2671        return;
2672    }
2673
2674    switch (opc) {
2675    case OPC_ADD:
2676        {
2677            TCGv t0 = tcg_temp_local_new();
2678            TCGv t1 = tcg_temp_new();
2679            TCGv t2 = tcg_temp_new();
2680            TCGLabel *l1 = gen_new_label();
2681
2682            gen_load_gpr(t1, rs);
2683            gen_load_gpr(t2, rt);
2684            tcg_gen_add_tl(t0, t1, t2);
2685            tcg_gen_ext32s_tl(t0, t0);
2686            tcg_gen_xor_tl(t1, t1, t2);
2687            tcg_gen_xor_tl(t2, t0, t2);
2688            tcg_gen_andc_tl(t1, t2, t1);
2689            tcg_temp_free(t2);
2690            tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
2691            tcg_temp_free(t1);
2692            /* operands of same sign, result different sign */
2693            generate_exception(ctx, EXCP_OVERFLOW);
2694            gen_set_label(l1);
2695            gen_store_gpr(t0, rd);
2696            tcg_temp_free(t0);
2697        }
2698        break;
2699    case OPC_ADDU:
2700        if (rs != 0 && rt != 0) {
2701            tcg_gen_add_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2702            tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
2703        } else if (rs == 0 && rt != 0) {
2704            tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
2705        } else if (rs != 0 && rt == 0) {
2706            tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
2707        } else {
2708            tcg_gen_movi_tl(cpu_gpr[rd], 0);
2709        }
2710        break;
2711    case OPC_SUB:
2712        {
2713            TCGv t0 = tcg_temp_local_new();
2714            TCGv t1 = tcg_temp_new();
2715            TCGv t2 = tcg_temp_new();
2716            TCGLabel *l1 = gen_new_label();
2717
2718            gen_load_gpr(t1, rs);
2719            gen_load_gpr(t2, rt);
2720            tcg_gen_sub_tl(t0, t1, t2);
2721            tcg_gen_ext32s_tl(t0, t0);
2722            tcg_gen_xor_tl(t2, t1, t2);
2723            tcg_gen_xor_tl(t1, t0, t1);
2724            tcg_gen_and_tl(t1, t1, t2);
2725            tcg_temp_free(t2);
2726            tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
2727            tcg_temp_free(t1);
2728            /* operands of different sign, first operand and result different sign */
2729            generate_exception(ctx, EXCP_OVERFLOW);
2730            gen_set_label(l1);
2731            gen_store_gpr(t0, rd);
2732            tcg_temp_free(t0);
2733        }
2734        break;
2735    case OPC_SUBU:
2736        if (rs != 0 && rt != 0) {
2737            tcg_gen_sub_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2738            tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
2739        } else if (rs == 0 && rt != 0) {
2740            tcg_gen_neg_tl(cpu_gpr[rd], cpu_gpr[rt]);
2741            tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
2742        } else if (rs != 0 && rt == 0) {
2743            tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
2744        } else {
2745            tcg_gen_movi_tl(cpu_gpr[rd], 0);
2746        }
2747        break;
2748#if defined(TARGET_MIPS64)
2749    case OPC_DADD:
2750        {
2751            TCGv t0 = tcg_temp_local_new();
2752            TCGv t1 = tcg_temp_new();
2753            TCGv t2 = tcg_temp_new();
2754            TCGLabel *l1 = gen_new_label();
2755
2756            gen_load_gpr(t1, rs);
2757            gen_load_gpr(t2, rt);
2758            tcg_gen_add_tl(t0, t1, t2);
2759            tcg_gen_xor_tl(t1, t1, t2);
2760            tcg_gen_xor_tl(t2, t0, t2);
2761            tcg_gen_andc_tl(t1, t2, t1);
2762            tcg_temp_free(t2);
2763            tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
2764            tcg_temp_free(t1);
2765            /* operands of same sign, result different sign */
2766            generate_exception(ctx, EXCP_OVERFLOW);
2767            gen_set_label(l1);
2768            gen_store_gpr(t0, rd);
2769            tcg_temp_free(t0);
2770        }
2771        break;
2772    case OPC_DADDU:
2773        if (rs != 0 && rt != 0) {
2774            tcg_gen_add_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2775        } else if (rs == 0 && rt != 0) {
2776            tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
2777        } else if (rs != 0 && rt == 0) {
2778            tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
2779        } else {
2780            tcg_gen_movi_tl(cpu_gpr[rd], 0);
2781        }
2782        break;
2783    case OPC_DSUB:
2784        {
2785            TCGv t0 = tcg_temp_local_new();
2786            TCGv t1 = tcg_temp_new();
2787            TCGv t2 = tcg_temp_new();
2788            TCGLabel *l1 = gen_new_label();
2789
2790            gen_load_gpr(t1, rs);
2791            gen_load_gpr(t2, rt);
2792            tcg_gen_sub_tl(t0, t1, t2);
2793            tcg_gen_xor_tl(t2, t1, t2);
2794            tcg_gen_xor_tl(t1, t0, t1);
2795            tcg_gen_and_tl(t1, t1, t2);
2796            tcg_temp_free(t2);
2797            tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
2798            tcg_temp_free(t1);
2799            /* operands of different sign, first operand and result different sign */
2800            generate_exception(ctx, EXCP_OVERFLOW);
2801            gen_set_label(l1);
2802            gen_store_gpr(t0, rd);
2803            tcg_temp_free(t0);
2804        }
2805        break;
2806    case OPC_DSUBU:
2807        if (rs != 0 && rt != 0) {
2808            tcg_gen_sub_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2809        } else if (rs == 0 && rt != 0) {
2810            tcg_gen_neg_tl(cpu_gpr[rd], cpu_gpr[rt]);
2811        } else if (rs != 0 && rt == 0) {
2812            tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
2813        } else {
2814            tcg_gen_movi_tl(cpu_gpr[rd], 0);
2815        }
2816        break;
2817#endif
2818    case OPC_MUL:
2819        if (likely(rs != 0 && rt != 0)) {
2820            tcg_gen_mul_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2821            tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
2822        } else {
2823            tcg_gen_movi_tl(cpu_gpr[rd], 0);
2824        }
2825        break;
2826    }
2827}
2828
2829/* Conditional move */
2830static void gen_cond_move(DisasContext *ctx, uint32_t opc,
2831                          int rd, int rs, int rt)
2832{
2833    TCGv t0, t1, t2;
2834
2835    if (rd == 0) {
2836        /* If no destination, treat it as a NOP. */
2837        return;
2838    }
2839
2840    t0 = tcg_temp_new();
2841    gen_load_gpr(t0, rt);
2842    t1 = tcg_const_tl(0);
2843    t2 = tcg_temp_new();
2844    gen_load_gpr(t2, rs);
2845    switch (opc) {
2846    case OPC_MOVN:
2847        tcg_gen_movcond_tl(TCG_COND_NE, cpu_gpr[rd], t0, t1, t2, cpu_gpr[rd]);
2848        break;
2849    case OPC_MOVZ:
2850        tcg_gen_movcond_tl(TCG_COND_EQ, cpu_gpr[rd], t0, t1, t2, cpu_gpr[rd]);
2851        break;
2852    case OPC_SELNEZ:
2853        tcg_gen_movcond_tl(TCG_COND_NE, cpu_gpr[rd], t0, t1, t2, t1);
2854        break;
2855    case OPC_SELEQZ:
2856        tcg_gen_movcond_tl(TCG_COND_EQ, cpu_gpr[rd], t0, t1, t2, t1);
2857        break;
2858    }
2859    tcg_temp_free(t2);
2860    tcg_temp_free(t1);
2861    tcg_temp_free(t0);
2862}
2863
2864/* Logic */
2865static void gen_logic(DisasContext *ctx, uint32_t opc,
2866                      int rd, int rs, int rt)
2867{
2868    if (rd == 0) {
2869        /* If no destination, treat it as a NOP. */
2870        return;
2871    }
2872
2873    switch (opc) {
2874    case OPC_AND:
2875        if (likely(rs != 0 && rt != 0)) {
2876            tcg_gen_and_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2877        } else {
2878            tcg_gen_movi_tl(cpu_gpr[rd], 0);
2879        }
2880        break;
2881    case OPC_NOR:
2882        if (rs != 0 && rt != 0) {
2883            tcg_gen_nor_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2884        } else if (rs == 0 && rt != 0) {
2885            tcg_gen_not_tl(cpu_gpr[rd], cpu_gpr[rt]);
2886        } else if (rs != 0 && rt == 0) {
2887            tcg_gen_not_tl(cpu_gpr[rd], cpu_gpr[rs]);
2888        } else {
2889            tcg_gen_movi_tl(cpu_gpr[rd], ~((target_ulong)0));
2890        }
2891        break;
2892    case OPC_OR:
2893        if (likely(rs != 0 && rt != 0)) {
2894            tcg_gen_or_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2895        } else if (rs == 0 && rt != 0) {
2896            tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
2897        } else if (rs != 0 && rt == 0) {
2898            tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
2899        } else {
2900            tcg_gen_movi_tl(cpu_gpr[rd], 0);
2901        }
2902        break;
2903    case OPC_XOR:
2904        if (likely(rs != 0 && rt != 0)) {
2905            tcg_gen_xor_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2906        } else if (rs == 0 && rt != 0) {
2907            tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
2908        } else if (rs != 0 && rt == 0) {
2909            tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
2910        } else {
2911            tcg_gen_movi_tl(cpu_gpr[rd], 0);
2912        }
2913        break;
2914    }
2915}
2916
2917/* Set on lower than */
2918static void gen_slt(DisasContext *ctx, uint32_t opc,
2919                    int rd, int rs, int rt)
2920{
2921    TCGv t0, t1;
2922
2923    if (rd == 0) {
2924        /* If no destination, treat it as a NOP. */
2925        return;
2926    }
2927
2928    t0 = tcg_temp_new();
2929    t1 = tcg_temp_new();
2930    gen_load_gpr(t0, rs);
2931    gen_load_gpr(t1, rt);
2932    switch (opc) {
2933    case OPC_SLT:
2934        tcg_gen_setcond_tl(TCG_COND_LT, cpu_gpr[rd], t0, t1);
2935        break;
2936    case OPC_SLTU:
2937        tcg_gen_setcond_tl(TCG_COND_LTU, cpu_gpr[rd], t0, t1);
2938        break;
2939    }
2940    tcg_temp_free(t0);
2941    tcg_temp_free(t1);
2942}
2943
2944/* Shifts */
2945static void gen_shift(DisasContext *ctx, uint32_t opc,
2946                      int rd, int rs, int rt)
2947{
2948    TCGv t0, t1;
2949
2950    if (rd == 0) {
2951        /* If no destination, treat it as a NOP.
2952           For add & sub, we must generate the overflow exception when needed. */
2953        return;
2954    }
2955
2956    t0 = tcg_temp_new();
2957    t1 = tcg_temp_new();
2958    gen_load_gpr(t0, rs);
2959    gen_load_gpr(t1, rt);
2960    switch (opc) {
2961    case OPC_SLLV:
2962        tcg_gen_andi_tl(t0, t0, 0x1f);
2963        tcg_gen_shl_tl(t0, t1, t0);
2964        tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
2965        break;
2966    case OPC_SRAV:
2967        tcg_gen_andi_tl(t0, t0, 0x1f);
2968        tcg_gen_sar_tl(cpu_gpr[rd], t1, t0);
2969        break;
2970    case OPC_SRLV:
2971        tcg_gen_ext32u_tl(t1, t1);
2972        tcg_gen_andi_tl(t0, t0, 0x1f);
2973        tcg_gen_shr_tl(t0, t1, t0);
2974        tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
2975        break;
2976    case OPC_ROTRV:
2977        {
2978            TCGv_i32 t2 = tcg_temp_new_i32();
2979            TCGv_i32 t3 = tcg_temp_new_i32();
2980
2981            tcg_gen_trunc_tl_i32(t2, t0);
2982            tcg_gen_trunc_tl_i32(t3, t1);
2983            tcg_gen_andi_i32(t2, t2, 0x1f);
2984            tcg_gen_rotr_i32(t2, t3, t2);
2985            tcg_gen_ext_i32_tl(cpu_gpr[rd], t2);
2986            tcg_temp_free_i32(t2);
2987            tcg_temp_free_i32(t3);
2988        }
2989        break;
2990#if defined(TARGET_MIPS64)
2991    case OPC_DSLLV:
2992        tcg_gen_andi_tl(t0, t0, 0x3f);
2993        tcg_gen_shl_tl(cpu_gpr[rd], t1, t0);
2994        break;
2995    case OPC_DSRAV:
2996        tcg_gen_andi_tl(t0, t0, 0x3f);
2997        tcg_gen_sar_tl(cpu_gpr[rd], t1, t0);
2998        break;
2999    case OPC_DSRLV:
3000        tcg_gen_andi_tl(t0, t0, 0x3f);
3001        tcg_gen_shr_tl(cpu_gpr[rd], t1, t0);
3002        break;
3003    case OPC_DROTRV:
3004        tcg_gen_andi_tl(t0, t0, 0x3f);
3005        tcg_gen_rotr_tl(cpu_gpr[rd], t1, t0);
3006        break;
3007#endif
3008    }
3009    tcg_temp_free(t0);
3010    tcg_temp_free(t1);
3011}
3012
3013/* Arithmetic on HI/LO registers */
3014static void gen_HILO(DisasContext *ctx, uint32_t opc, int acc, int reg)
3015{
3016    if (reg == 0 && (opc == OPC_MFHI || opc == OPC_MFLO)) {
3017        /* Treat as NOP. */
3018        return;
3019    }
3020
3021    if (acc != 0) {
3022        check_dsp(ctx);
3023    }
3024
3025    switch (opc) {
3026    case OPC_MFHI:
3027#if defined(TARGET_MIPS64)
3028        if (acc != 0) {
3029            tcg_gen_ext32s_tl(cpu_gpr[reg], cpu_HI[acc]);
3030        } else
3031#endif
3032        {
3033            tcg_gen_mov_tl(cpu_gpr[reg], cpu_HI[acc]);
3034        }
3035        break;
3036    case OPC_MFLO:
3037#if defined(TARGET_MIPS64)
3038        if (acc != 0) {
3039            tcg_gen_ext32s_tl(cpu_gpr[reg], cpu_LO[acc]);
3040        } else
3041#endif
3042        {
3043            tcg_gen_mov_tl(cpu_gpr[reg], cpu_LO[acc]);
3044        }
3045        break;
3046    case OPC_MTHI:
3047        if (reg != 0) {
3048#if defined(TARGET_MIPS64)
3049            if (acc != 0) {
3050                tcg_gen_ext32s_tl(cpu_HI[acc], cpu_gpr[reg]);
3051            } else
3052#endif
3053            {
3054                tcg_gen_mov_tl(cpu_HI[acc], cpu_gpr[reg]);
3055            }
3056        } else {
3057            tcg_gen_movi_tl(cpu_HI[acc], 0);
3058        }
3059        break;
3060    case OPC_MTLO:
3061        if (reg != 0) {
3062#if defined(TARGET_MIPS64)
3063            if (acc != 0) {
3064                tcg_gen_ext32s_tl(cpu_LO[acc], cpu_gpr[reg]);
3065            } else
3066#endif
3067            {
3068                tcg_gen_mov_tl(cpu_LO[acc], cpu_gpr[reg]);
3069            }
3070        } else {
3071            tcg_gen_movi_tl(cpu_LO[acc], 0);
3072        }
3073        break;
3074    }
3075}
3076
3077static inline void gen_r6_ld(target_long addr, int reg, int memidx,
3078                             TCGMemOp memop)
3079{
3080    TCGv t0 = tcg_const_tl(addr);
3081    tcg_gen_qemu_ld_tl(t0, t0, memidx, memop);
3082    gen_store_gpr(t0, reg);
3083    tcg_temp_free(t0);
3084}
3085
3086static inline void gen_pcrel(DisasContext *ctx, int opc, target_ulong pc,
3087                             int rs)
3088{
3089    target_long offset;
3090    target_long addr;
3091
3092    switch (MASK_OPC_PCREL_TOP2BITS(opc)) {
3093    case OPC_ADDIUPC:
3094        if (rs != 0) {
3095            offset = sextract32(ctx->opcode << 2, 0, 21);
3096            addr = addr_add(ctx, pc, offset);
3097            tcg_gen_movi_tl(cpu_gpr[rs], addr);
3098        }
3099        break;
3100    case R6_OPC_LWPC:
3101        offset = sextract32(ctx->opcode << 2, 0, 21);
3102        addr = addr_add(ctx, pc, offset);
3103        gen_r6_ld(addr, rs, ctx->mem_idx, MO_TESL);
3104        break;
3105#if defined(TARGET_MIPS64)
3106    case OPC_LWUPC:
3107        check_mips_64(ctx);
3108        offset = sextract32(ctx->opcode << 2, 0, 21);
3109        addr = addr_add(ctx, pc, offset);
3110        gen_r6_ld(addr, rs, ctx->mem_idx, MO_TEUL);
3111        break;
3112#endif
3113    default:
3114        switch (MASK_OPC_PCREL_TOP5BITS(opc)) {
3115        case OPC_AUIPC:
3116            if (rs != 0) {
3117                offset = sextract32(ctx->opcode, 0, 16) << 16;
3118                addr = addr_add(ctx, pc, offset);
3119                tcg_gen_movi_tl(cpu_gpr[rs], addr);
3120            }
3121            break;
3122        case OPC_ALUIPC:
3123            if (rs != 0) {
3124                offset = sextract32(ctx->opcode, 0, 16) << 16;
3125                addr = ~0xFFFF & addr_add(ctx, pc, offset);
3126                tcg_gen_movi_tl(cpu_gpr[rs], addr);
3127            }
3128            break;
3129#if defined(TARGET_MIPS64)
3130        case R6_OPC_LDPC: /* bits 16 and 17 are part of immediate */
3131        case R6_OPC_LDPC + (1 << 16):
3132        case R6_OPC_LDPC + (2 << 16):
3133        case R6_OPC_LDPC + (3 << 16):
3134            check_mips_64(ctx);
3135            offset = sextract32(ctx->opcode << 3, 0, 21);
3136            addr = addr_add(ctx, (pc & ~0x7), offset);
3137            gen_r6_ld(addr, rs, ctx->mem_idx, MO_TEQ);
3138            break;
3139#endif
3140        default:
3141            MIPS_INVAL("OPC_PCREL");
3142            generate_exception_end(ctx, EXCP_RI);
3143            break;
3144        }
3145        break;
3146    }
3147}
3148
3149static void gen_r6_muldiv(DisasContext *ctx, int opc, int rd, int rs, int rt)
3150{
3151    TCGv t0, t1;
3152
3153    if (rd == 0) {
3154        /* Treat as NOP. */
3155        return;
3156    }
3157
3158    t0 = tcg_temp_new();
3159    t1 = tcg_temp_new();
3160
3161    gen_load_gpr(t0, rs);
3162    gen_load_gpr(t1, rt);
3163
3164    switch (opc) {
3165    case R6_OPC_DIV:
3166        {
3167            TCGv t2 = tcg_temp_new();
3168            TCGv t3 = tcg_temp_new();
3169            tcg_gen_ext32s_tl(t0, t0);
3170            tcg_gen_ext32s_tl(t1, t1);
3171            tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, INT_MIN);
3172            tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1);
3173            tcg_gen_and_tl(t2, t2, t3);
3174            tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
3175            tcg_gen_or_tl(t2, t2, t3);
3176            tcg_gen_movi_tl(t3, 0);
3177            tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
3178            tcg_gen_div_tl(cpu_gpr[rd], t0, t1);
3179            tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3180            tcg_temp_free(t3);
3181            tcg_temp_free(t2);
3182        }
3183        break;
3184    case R6_OPC_MOD:
3185        {
3186            TCGv t2 = tcg_temp_new();
3187            TCGv t3 = tcg_temp_new();
3188            tcg_gen_ext32s_tl(t0, t0);
3189            tcg_gen_ext32s_tl(t1, t1);
3190            tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, INT_MIN);
3191            tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1);
3192            tcg_gen_and_tl(t2, t2, t3);
3193            tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
3194            tcg_gen_or_tl(t2, t2, t3);
3195            tcg_gen_movi_tl(t3, 0);
3196            tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
3197            tcg_gen_rem_tl(cpu_gpr[rd], t0, t1);
3198            tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3199            tcg_temp_free(t3);
3200            tcg_temp_free(t2);
3201        }
3202        break;
3203    case R6_OPC_DIVU:
3204        {
3205            TCGv t2 = tcg_const_tl(0);
3206            TCGv t3 = tcg_const_tl(1);
3207            tcg_gen_ext32u_tl(t0, t0);
3208            tcg_gen_ext32u_tl(t1, t1);
3209            tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
3210            tcg_gen_divu_tl(cpu_gpr[rd], t0, t1);
3211            tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3212            tcg_temp_free(t3);
3213            tcg_temp_free(t2);
3214        }
3215        break;
3216    case R6_OPC_MODU:
3217        {
3218            TCGv t2 = tcg_const_tl(0);
3219            TCGv t3 = tcg_const_tl(1);
3220            tcg_gen_ext32u_tl(t0, t0);
3221            tcg_gen_ext32u_tl(t1, t1);
3222            tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
3223            tcg_gen_remu_tl(cpu_gpr[rd], t0, t1);
3224            tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3225            tcg_temp_free(t3);
3226            tcg_temp_free(t2);
3227        }
3228        break;
3229    case R6_OPC_MUL:
3230        {
3231            TCGv_i32 t2 = tcg_temp_new_i32();
3232            TCGv_i32 t3 = tcg_temp_new_i32();
3233            tcg_gen_trunc_tl_i32(t2, t0);
3234            tcg_gen_trunc_tl_i32(t3, t1);
3235            tcg_gen_mul_i32(t2, t2, t3);
3236            tcg_gen_ext_i32_tl(cpu_gpr[rd], t2);
3237            tcg_temp_free_i32(t2);
3238            tcg_temp_free_i32(t3);
3239        }
3240        break;
3241    case R6_OPC_MUH:
3242        {
3243            TCGv_i32 t2 = tcg_temp_new_i32();
3244            TCGv_i32 t3 = tcg_temp_new_i32();
3245            tcg_gen_trunc_tl_i32(t2, t0);
3246            tcg_gen_trunc_tl_i32(t3, t1);
3247            tcg_gen_muls2_i32(t2, t3, t2, t3);
3248            tcg_gen_ext_i32_tl(cpu_gpr[rd], t3);
3249            tcg_temp_free_i32(t2);
3250            tcg_temp_free_i32(t3);
3251        }
3252        break;
3253    case R6_OPC_MULU:
3254        {
3255            TCGv_i32 t2 = tcg_temp_new_i32();
3256            TCGv_i32 t3 = tcg_temp_new_i32();
3257            tcg_gen_trunc_tl_i32(t2, t0);
3258            tcg_gen_trunc_tl_i32(t3, t1);
3259            tcg_gen_mul_i32(t2, t2, t3);
3260            tcg_gen_ext_i32_tl(cpu_gpr[rd], t2);
3261            tcg_temp_free_i32(t2);
3262            tcg_temp_free_i32(t3);
3263        }
3264        break;
3265    case R6_OPC_MUHU:
3266        {
3267            TCGv_i32 t2 = tcg_temp_new_i32();
3268            TCGv_i32 t3 = tcg_temp_new_i32();
3269            tcg_gen_trunc_tl_i32(t2, t0);
3270            tcg_gen_trunc_tl_i32(t3, t1);
3271            tcg_gen_mulu2_i32(t2, t3, t2, t3);
3272            tcg_gen_ext_i32_tl(cpu_gpr[rd], t3);
3273            tcg_temp_free_i32(t2);
3274            tcg_temp_free_i32(t3);
3275        }
3276        break;
3277#if defined(TARGET_MIPS64)
3278    case R6_OPC_DDIV:
3279        {
3280            TCGv t2 = tcg_temp_new();
3281            TCGv t3 = tcg_temp_new();
3282            tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, -1LL << 63);
3283            tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1LL);
3284            tcg_gen_and_tl(t2, t2, t3);
3285            tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
3286            tcg_gen_or_tl(t2, t2, t3);
3287            tcg_gen_movi_tl(t3, 0);
3288            tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
3289            tcg_gen_div_tl(cpu_gpr[rd], t0, t1);
3290            tcg_temp_free(t3);
3291            tcg_temp_free(t2);
3292        }
3293        break;
3294    case R6_OPC_DMOD:
3295        {
3296            TCGv t2 = tcg_temp_new();
3297            TCGv t3 = tcg_temp_new();
3298            tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, -1LL << 63);
3299            tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1LL);
3300            tcg_gen_and_tl(t2, t2, t3);
3301            tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
3302            tcg_gen_or_tl(t2, t2, t3);
3303            tcg_gen_movi_tl(t3, 0);
3304            tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
3305            tcg_gen_rem_tl(cpu_gpr[rd], t0, t1);
3306            tcg_temp_free(t3);
3307            tcg_temp_free(t2);
3308        }
3309        break;
3310    case R6_OPC_DDIVU:
3311        {
3312            TCGv t2 = tcg_const_tl(0);
3313            TCGv t3 = tcg_const_tl(1);
3314            tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
3315            tcg_gen_divu_i64(cpu_gpr[rd], t0, t1);
3316            tcg_temp_free(t3);
3317            tcg_temp_free(t2);
3318        }
3319        break;
3320    case R6_OPC_DMODU:
3321        {
3322            TCGv t2 = tcg_const_tl(0);
3323            TCGv t3 = tcg_const_tl(1);
3324            tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
3325            tcg_gen_remu_i64(cpu_gpr[rd], t0, t1);
3326            tcg_temp_free(t3);
3327            tcg_temp_free(t2);
3328        }
3329        break;
3330    case R6_OPC_DMUL:
3331        tcg_gen_mul_i64(cpu_gpr[rd], t0, t1);
3332        break;
3333    case R6_OPC_DMUH:
3334        {
3335            TCGv t2 = tcg_temp_new();
3336            tcg_gen_muls2_i64(t2, cpu_gpr[rd], t0, t1);
3337            tcg_temp_free(t2);
3338        }
3339        break;
3340    case R6_OPC_DMULU:
3341        tcg_gen_mul_i64(cpu_gpr[rd], t0, t1);
3342        break;
3343    case R6_OPC_DMUHU:
3344        {
3345            TCGv t2 = tcg_temp_new();
3346            tcg_gen_mulu2_i64(t2, cpu_gpr[rd], t0, t1);
3347            tcg_temp_free(t2);
3348        }
3349        break;
3350#endif
3351    default:
3352        MIPS_INVAL("r6 mul/div");
3353        generate_exception_end(ctx, EXCP_RI);
3354        goto out;
3355    }
3356 out:
3357    tcg_temp_free(t0);
3358    tcg_temp_free(t1);
3359}
3360
3361static void gen_muldiv(DisasContext *ctx, uint32_t opc,
3362                       int acc, int rs, int rt)
3363{
3364    TCGv t0, t1;
3365
3366    t0 = tcg_temp_new();
3367    t1 = tcg_temp_new();
3368
3369    gen_load_gpr(t0, rs);
3370    gen_load_gpr(t1, rt);
3371
3372    if (acc != 0) {
3373        check_dsp(ctx);
3374    }
3375
3376    switch (opc) {
3377    case OPC_DIV:
3378        {
3379            TCGv t2 = tcg_temp_new();
3380            TCGv t3 = tcg_temp_new();
3381            tcg_gen_ext32s_tl(t0, t0);
3382            tcg_gen_ext32s_tl(t1, t1);
3383            tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, INT_MIN);
3384            tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1);
3385            tcg_gen_and_tl(t2, t2, t3);
3386            tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
3387            tcg_gen_or_tl(t2, t2, t3);
3388            tcg_gen_movi_tl(t3, 0);
3389            tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
3390            tcg_gen_div_tl(cpu_LO[acc], t0, t1);
3391            tcg_gen_rem_tl(cpu_HI[acc], t0, t1);
3392            tcg_gen_ext32s_tl(cpu_LO[acc], cpu_LO[acc]);
3393            tcg_gen_ext32s_tl(cpu_HI[acc], cpu_HI[acc]);
3394            tcg_temp_free(t3);
3395            tcg_temp_free(t2);
3396        }
3397        break;
3398    case OPC_DIVU:
3399        {
3400            TCGv t2 = tcg_const_tl(0);
3401            TCGv t3 = tcg_const_tl(1);
3402            tcg_gen_ext32u_tl(t0, t0);
3403            tcg_gen_ext32u_tl(t1, t1);
3404            tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
3405            tcg_gen_divu_tl(cpu_LO[acc], t0, t1);
3406            tcg_gen_remu_tl(cpu_HI[acc], t0, t1);
3407            tcg_gen_ext32s_tl(cpu_LO[acc], cpu_LO[acc]);
3408            tcg_gen_ext32s_tl(cpu_HI[acc], cpu_HI[acc]);
3409            tcg_temp_free(t3);
3410            tcg_temp_free(t2);
3411        }
3412        break;
3413    case OPC_MULT:
3414        {
3415            TCGv_i32 t2 = tcg_temp_new_i32();
3416            TCGv_i32 t3 = tcg_temp_new_i32();
3417            tcg_gen_trunc_tl_i32(t2, t0);
3418            tcg_gen_trunc_tl_i32(t3, t1);
3419            tcg_gen_muls2_i32(t2, t3, t2, t3);
3420            tcg_gen_ext_i32_tl(cpu_LO[acc], t2);
3421            tcg_gen_ext_i32_tl(cpu_HI[acc], t3);
3422            tcg_temp_free_i32(t2);
3423            tcg_temp_free_i32(t3);
3424        }
3425        break;
3426    case OPC_MULTU:
3427        {
3428            TCGv_i32 t2 = tcg_temp_new_i32();
3429            TCGv_i32 t3 = tcg_temp_new_i32();
3430            tcg_gen_trunc_tl_i32(t2, t0);
3431            tcg_gen_trunc_tl_i32(t3, t1);
3432            tcg_gen_mulu2_i32(t2, t3, t2, t3);
3433            tcg_gen_ext_i32_tl(cpu_LO[acc], t2);
3434            tcg_gen_ext_i32_tl(cpu_HI[acc], t3);
3435            tcg_temp_free_i32(t2);
3436            tcg_temp_free_i32(t3);
3437        }
3438        break;
3439#if defined(TARGET_MIPS64)
3440    case OPC_DDIV:
3441        {
3442            TCGv t2 = tcg_temp_new();
3443            TCGv t3 = tcg_temp_new();
3444            tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, -1LL << 63);
3445            tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1LL);
3446            tcg_gen_and_tl(t2, t2, t3);
3447            tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
3448            tcg_gen_or_tl(t2, t2, t3);
3449            tcg_gen_movi_tl(t3, 0);
3450            tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
3451            tcg_gen_div_tl(cpu_LO[acc], t0, t1);
3452            tcg_gen_rem_tl(cpu_HI[acc], t0, t1);
3453            tcg_temp_free(t3);
3454            tcg_temp_free(t2);
3455        }
3456        break;
3457    case OPC_DDIVU:
3458        {
3459            TCGv t2 = tcg_const_tl(0);
3460            TCGv t3 = tcg_const_tl(1);
3461            tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
3462            tcg_gen_divu_i64(cpu_LO[acc], t0, t1);
3463            tcg_gen_remu_i64(cpu_HI[acc], t0, t1);
3464            tcg_temp_free(t3);
3465            tcg_temp_free(t2);
3466        }
3467        break;
3468    case OPC_DMULT:
3469        tcg_gen_muls2_i64(cpu_LO[acc], cpu_HI[acc], t0, t1);
3470        break;
3471    case OPC_DMULTU:
3472        tcg_gen_mulu2_i64(cpu_LO[acc], cpu_HI[acc], t0, t1);
3473        break;
3474#endif
3475    case OPC_MADD:
3476        {
3477            TCGv_i64 t2 = tcg_temp_new_i64();
3478            TCGv_i64 t3 = tcg_temp_new_i64();
3479
3480            tcg_gen_ext_tl_i64(t2, t0);
3481            tcg_gen_ext_tl_i64(t3, t1);
3482            tcg_gen_mul_i64(t2, t2, t3);
3483            tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
3484            tcg_gen_add_i64(t2, t2, t3);
3485            tcg_temp_free_i64(t3);
3486            gen_move_low32(cpu_LO[acc], t2);
3487            gen_move_high32(cpu_HI[acc], t2);
3488            tcg_temp_free_i64(t2);
3489        }
3490        break;
3491    case OPC_MADDU:
3492        {
3493            TCGv_i64 t2 = tcg_temp_new_i64();
3494            TCGv_i64 t3 = tcg_temp_new_i64();
3495
3496            tcg_gen_ext32u_tl(t0, t0);
3497            tcg_gen_ext32u_tl(t1, t1);
3498            tcg_gen_extu_tl_i64(t2, t0);
3499            tcg_gen_extu_tl_i64(t3, t1);
3500            tcg_gen_mul_i64(t2, t2, t3);
3501            tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
3502            tcg_gen_add_i64(t2, t2, t3);
3503            tcg_temp_free_i64(t3);
3504            gen_move_low32(cpu_LO[acc], t2);
3505            gen_move_high32(cpu_HI[acc], t2);
3506            tcg_temp_free_i64(t2);
3507        }
3508        break;
3509    case OPC_MSUB:
3510        {
3511            TCGv_i64 t2 = tcg_temp_new_i64();
3512            TCGv_i64 t3 = tcg_temp_new_i64();
3513
3514            tcg_gen_ext_tl_i64(t2, t0);
3515            tcg_gen_ext_tl_i64(t3, t1);
3516            tcg_gen_mul_i64(t2, t2, t3);
3517            tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
3518            tcg_gen_sub_i64(t2, t3, t2);
3519            tcg_temp_free_i64(t3);
3520            gen_move_low32(cpu_LO[acc], t2);
3521            gen_move_high32(cpu_HI[acc], t2);
3522            tcg_temp_free_i64(t2);
3523        }
3524        break;
3525    case OPC_MSUBU:
3526        {
3527            TCGv_i64 t2 = tcg_temp_new_i64();
3528            TCGv_i64 t3 = tcg_temp_new_i64();
3529
3530            tcg_gen_ext32u_tl(t0, t0);
3531            tcg_gen_ext32u_tl(t1, t1);
3532            tcg_gen_extu_tl_i64(t2, t0);
3533            tcg_gen_extu_tl_i64(t3, t1);
3534            tcg_gen_mul_i64(t2, t2, t3);
3535            tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
3536            tcg_gen_sub_i64(t2, t3, t2);
3537            tcg_temp_free_i64(t3);
3538            gen_move_low32(cpu_LO[acc], t2);
3539            gen_move_high32(cpu_HI[acc], t2);
3540            tcg_temp_free_i64(t2);
3541        }
3542        break;
3543    default:
3544        MIPS_INVAL("mul/div");
3545        generate_exception_end(ctx, EXCP_RI);
3546        goto out;
3547    }
3548 out:
3549    tcg_temp_free(t0);
3550    tcg_temp_free(t1);
3551}
3552
3553static void gen_mul_vr54xx (DisasContext *ctx, uint32_t opc,
3554                            int rd, int rs, int rt)
3555{
3556    TCGv t0 = tcg_temp_new();
3557    TCGv t1 = tcg_temp_new();
3558
3559    gen_load_gpr(t0, rs);
3560    gen_load_gpr(t1, rt);
3561
3562    switch (opc) {
3563    case OPC_VR54XX_MULS:
3564        gen_helper_muls(t0, cpu_env, t0, t1);
3565        break;
3566    case OPC_VR54XX_MULSU:
3567        gen_helper_mulsu(t0, cpu_env, t0, t1);
3568        break;
3569    case OPC_VR54XX_MACC:
3570        gen_helper_macc(t0, cpu_env, t0, t1);
3571        break;
3572    case OPC_VR54XX_MACCU:
3573        gen_helper_maccu(t0, cpu_env, t0, t1);
3574        break;
3575    case OPC_VR54XX_MSAC:
3576        gen_helper_msac(t0, cpu_env, t0, t1);
3577        break;
3578    case OPC_VR54XX_MSACU:
3579        gen_helper_msacu(t0, cpu_env, t0, t1);
3580        break;
3581    case OPC_VR54XX_MULHI:
3582        gen_helper_mulhi(t0, cpu_env, t0, t1);
3583        break;
3584    case OPC_VR54XX_MULHIU:
3585        gen_helper_mulhiu(t0, cpu_env, t0, t1);
3586        break;
3587    case OPC_VR54XX_MULSHI:
3588        gen_helper_mulshi(t0, cpu_env, t0, t1);
3589        break;
3590    case OPC_VR54XX_MULSHIU:
3591        gen_helper_mulshiu(t0, cpu_env, t0, t1);
3592        break;
3593    case OPC_VR54XX_MACCHI:
3594        gen_helper_macchi(t0, cpu_env, t0, t1);
3595        break;
3596    case OPC_VR54XX_MACCHIU:
3597        gen_helper_macchiu(t0, cpu_env, t0, t1);
3598        break;
3599    case OPC_VR54XX_MSACHI:
3600        gen_helper_msachi(t0, cpu_env, t0, t1);
3601        break;
3602    case OPC_VR54XX_MSACHIU:
3603        gen_helper_msachiu(t0, cpu_env, t0, t1);
3604        break;
3605    default:
3606        MIPS_INVAL("mul vr54xx");
3607        generate_exception_end(ctx, EXCP_RI);
3608        goto out;
3609    }
3610    gen_store_gpr(t0, rd);
3611
3612 out:
3613    tcg_temp_free(t0);
3614    tcg_temp_free(t1);
3615}
3616
3617static void gen_cl (DisasContext *ctx, uint32_t opc,
3618                    int rd, int rs)
3619{
3620    TCGv t0;
3621
3622    if (rd == 0) {
3623        /* Treat as NOP. */
3624        return;
3625    }
3626    t0 = tcg_temp_new();
3627    gen_load_gpr(t0, rs);
3628    switch (opc) {
3629    case OPC_CLO:
3630    case R6_OPC_CLO:
3631        gen_helper_clo(cpu_gpr[rd], t0);
3632        break;
3633    case OPC_CLZ:
3634    case R6_OPC_CLZ:
3635        gen_helper_clz(cpu_gpr[rd], t0);
3636        break;
3637#if defined(TARGET_MIPS64)
3638    case OPC_DCLO:
3639    case R6_OPC_DCLO:
3640        gen_helper_dclo(cpu_gpr[rd], t0);
3641        break;
3642    case OPC_DCLZ:
3643    case R6_OPC_DCLZ:
3644        gen_helper_dclz(cpu_gpr[rd], t0);
3645        break;
3646#endif
3647    }
3648    tcg_temp_free(t0);
3649}
3650
3651/* Godson integer instructions */
3652static void gen_loongson_integer(DisasContext *ctx, uint32_t opc,
3653                                 int rd, int rs, int rt)
3654{
3655    TCGv t0, t1;
3656
3657    if (rd == 0) {
3658        /* Treat as NOP. */
3659        return;
3660    }
3661
3662    switch (opc) {
3663    case OPC_MULT_G_2E:
3664    case OPC_MULT_G_2F:
3665    case OPC_MULTU_G_2E:
3666    case OPC_MULTU_G_2F:
3667#if defined(TARGET_MIPS64)
3668    case OPC_DMULT_G_2E:
3669    case OPC_DMULT_G_2F:
3670    case OPC_DMULTU_G_2E:
3671    case OPC_DMULTU_G_2F:
3672#endif
3673        t0 = tcg_temp_new();
3674        t1 = tcg_temp_new();
3675        break;
3676    default:
3677        t0 = tcg_temp_local_new();
3678        t1 = tcg_temp_local_new();
3679        break;
3680    }
3681
3682    gen_load_gpr(t0, rs);
3683    gen_load_gpr(t1, rt);
3684
3685    switch (opc) {
3686    case OPC_MULT_G_2E:
3687    case OPC_MULT_G_2F:
3688        tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
3689        tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3690        break;
3691    case OPC_MULTU_G_2E:
3692    case OPC_MULTU_G_2F:
3693        tcg_gen_ext32u_tl(t0, t0);
3694        tcg_gen_ext32u_tl(t1, t1);
3695        tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
3696        tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3697        break;
3698    case OPC_DIV_G_2E:
3699    case OPC_DIV_G_2F:
3700        {
3701            TCGLabel *l1 = gen_new_label();
3702            TCGLabel *l2 = gen_new_label();
3703            TCGLabel *l3 = gen_new_label();
3704            tcg_gen_ext32s_tl(t0, t0);
3705            tcg_gen_ext32s_tl(t1, t1);
3706            tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
3707            tcg_gen_movi_tl(cpu_gpr[rd], 0);
3708            tcg_gen_br(l3);
3709            gen_set_label(l1);
3710            tcg_gen_brcondi_tl(TCG_COND_NE, t0, INT_MIN, l2);
3711            tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1, l2);
3712            tcg_gen_mov_tl(cpu_gpr[rd], t0);
3713            tcg_gen_br(l3);
3714            gen_set_label(l2);
3715            tcg_gen_div_tl(cpu_gpr[rd], t0, t1);
3716            tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3717            gen_set_label(l3);
3718        }
3719        break;
3720    case OPC_DIVU_G_2E:
3721    case OPC_DIVU_G_2F:
3722        {
3723            TCGLabel *l1 = gen_new_label();
3724            TCGLabel *l2 = gen_new_label();
3725            tcg_gen_ext32u_tl(t0, t0);
3726            tcg_gen_ext32u_tl(t1, t1);
3727            tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
3728            tcg_gen_movi_tl(cpu_gpr[rd], 0);
3729            tcg_gen_br(l2);
3730            gen_set_label(l1);
3731            tcg_gen_divu_tl(cpu_gpr[rd], t0, t1);
3732            tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3733            gen_set_label(l2);
3734        }
3735        break;
3736    case OPC_MOD_G_2E:
3737    case OPC_MOD_G_2F:
3738        {
3739            TCGLabel *l1 = gen_new_label();
3740            TCGLabel *l2 = gen_new_label();
3741            TCGLabel *l3 = gen_new_label();
3742            tcg_gen_ext32u_tl(t0, t0);
3743            tcg_gen_ext32u_tl(t1, t1);
3744            tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
3745            tcg_gen_brcondi_tl(TCG_COND_NE, t0, INT_MIN, l2);
3746            tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1, l2);
3747            gen_set_label(l1);
3748            tcg_gen_movi_tl(cpu_gpr[rd], 0);
3749            tcg_gen_br(l3);
3750            gen_set_label(l2);
3751            tcg_gen_rem_tl(cpu_gpr[rd], t0, t1);
3752            tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3753            gen_set_label(l3);
3754        }
3755        break;
3756    case OPC_MODU_G_2E:
3757    case OPC_MODU_G_2F:
3758        {
3759            TCGLabel *l1 = gen_new_label();
3760            TCGLabel *l2 = gen_new_label();
3761            tcg_gen_ext32u_tl(t0, t0);
3762            tcg_gen_ext32u_tl(t1, t1);
3763            tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
3764            tcg_gen_movi_tl(cpu_gpr[rd], 0);
3765            tcg_gen_br(l2);
3766            gen_set_label(l1);
3767            tcg_gen_remu_tl(cpu_gpr[rd], t0, t1);
3768            tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3769            gen_set_label(l2);
3770        }
3771        break;
3772#if defined(TARGET_MIPS64)
3773    case OPC_DMULT_G_2E:
3774    case OPC_DMULT_G_2F:
3775        tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
3776        break;
3777    case OPC_DMULTU_G_2E:
3778    case OPC_DMULTU_G_2F:
3779        tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
3780        break;
3781    case OPC_DDIV_G_2E:
3782    case OPC_DDIV_G_2F:
3783        {
3784            TCGLabel *l1 = gen_new_label();
3785            TCGLabel *l2 = gen_new_label();
3786            TCGLabel *l3 = gen_new_label();
3787            tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
3788            tcg_gen_movi_tl(cpu_gpr[rd], 0);
3789            tcg_gen_br(l3);
3790            gen_set_label(l1);
3791            tcg_gen_brcondi_tl(TCG_COND_NE, t0, -1LL << 63, l2);
3792            tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1LL, l2);
3793            tcg_gen_mov_tl(cpu_gpr[rd], t0);
3794            tcg_gen_br(l3);
3795            gen_set_label(l2);
3796            tcg_gen_div_tl(cpu_gpr[rd], t0, t1);
3797            gen_set_label(l3);
3798        }
3799        break;
3800    case OPC_DDIVU_G_2E:
3801    case OPC_DDIVU_G_2F:
3802        {
3803            TCGLabel *l1 = gen_new_label();
3804            TCGLabel *l2 = gen_new_label();
3805            tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
3806            tcg_gen_movi_tl(cpu_gpr[rd], 0);
3807            tcg_gen_br(l2);
3808            gen_set_label(l1);
3809            tcg_gen_divu_tl(cpu_gpr[rd], t0, t1);
3810            gen_set_label(l2);
3811        }
3812        break;
3813    case OPC_DMOD_G_2E:
3814    case OPC_DMOD_G_2F:
3815        {
3816            TCGLabel *l1 = gen_new_label();
3817            TCGLabel *l2 = gen_new_label();
3818            TCGLabel *l3 = gen_new_label();
3819            tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
3820            tcg_gen_brcondi_tl(TCG_COND_NE, t0, -1LL << 63, l2);
3821            tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1LL, l2);
3822            gen_set_label(l1);
3823            tcg_gen_movi_tl(cpu_gpr[rd], 0);
3824            tcg_gen_br(l3);
3825            gen_set_label(l2);
3826            tcg_gen_rem_tl(cpu_gpr[rd], t0, t1);
3827            gen_set_label(l3);
3828        }
3829        break;
3830    case OPC_DMODU_G_2E:
3831    case OPC_DMODU_G_2F:
3832        {
3833            TCGLabel *l1 = gen_new_label();
3834            TCGLabel *l2 = gen_new_label();
3835            tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
3836            tcg_gen_movi_tl(cpu_gpr[rd], 0);
3837            tcg_gen_br(l2);
3838            gen_set_label(l1);
3839            tcg_gen_remu_tl(cpu_gpr[rd], t0, t1);
3840            gen_set_label(l2);
3841        }
3842        break;
3843#endif
3844    }
3845
3846    tcg_temp_free(t0);
3847    tcg_temp_free(t1);
3848}
3849
3850/* Loongson multimedia instructions */
3851static void gen_loongson_multimedia(DisasContext *ctx, int rd, int rs, int rt)
3852{
3853    uint32_t opc, shift_max;
3854    TCGv_i64 t0, t1;
3855
3856    opc = MASK_LMI(ctx->opcode);
3857    switch (opc) {
3858    case OPC_ADD_CP2:
3859    case OPC_SUB_CP2:
3860    case OPC_DADD_CP2:
3861    case OPC_DSUB_CP2:
3862        t0 = tcg_temp_local_new_i64();
3863        t1 = tcg_temp_local_new_i64();
3864        break;
3865    default:
3866        t0 = tcg_temp_new_i64();
3867        t1 = tcg_temp_new_i64();
3868        break;
3869    }
3870
3871    gen_load_fpr64(ctx, t0, rs);
3872    gen_load_fpr64(ctx, t1, rt);
3873
3874#define LMI_HELPER(UP, LO) \
3875    case OPC_##UP: gen_helper_##LO(t0, t0, t1); break
3876#define LMI_HELPER_1(UP, LO) \
3877    case OPC_##UP: gen_helper_##LO(t0, t0); break
3878#define LMI_DIRECT(UP, LO, OP) \
3879    case OPC_##UP: tcg_gen_##OP##_i64(t0, t0, t1); break
3880
3881    switch (opc) {
3882    LMI_HELPER(PADDSH, paddsh);
3883    LMI_HELPER(PADDUSH, paddush);
3884    LMI_HELPER(PADDH, paddh);
3885    LMI_HELPER(PADDW, paddw);
3886    LMI_HELPER(PADDSB, paddsb);
3887    LMI_HELPER(PADDUSB, paddusb);
3888    LMI_HELPER(PADDB, paddb);
3889
3890    LMI_HELPER(PSUBSH, psubsh);
3891    LMI_HELPER(PSUBUSH, psubush);
3892    LMI_HELPER(PSUBH, psubh);
3893    LMI_HELPER(PSUBW, psubw);
3894    LMI_HELPER(PSUBSB, psubsb);
3895    LMI_HELPER(PSUBUSB, psubusb);
3896    LMI_HELPER(PSUBB, psubb);
3897
3898    LMI_HELPER(PSHUFH, pshufh);
3899    LMI_HELPER(PACKSSWH, packsswh);
3900    LMI_HELPER(PACKSSHB, packsshb);
3901    LMI_HELPER(PACKUSHB, packushb);
3902
3903    LMI_HELPER(PUNPCKLHW, punpcklhw);
3904    LMI_HELPER(PUNPCKHHW, punpckhhw);
3905    LMI_HELPER(PUNPCKLBH, punpcklbh);
3906    LMI_HELPER(PUNPCKHBH, punpckhbh);
3907    LMI_HELPER(PUNPCKLWD, punpcklwd);
3908    LMI_HELPER(PUNPCKHWD, punpckhwd);
3909
3910    LMI_HELPER(PAVGH, pavgh);
3911    LMI_HELPER(PAVGB, pavgb);
3912    LMI_HELPER(PMAXSH, pmaxsh);
3913    LMI_HELPER(PMINSH, pminsh);
3914    LMI_HELPER(PMAXUB, pmaxub);
3915    LMI_HELPER(PMINUB, pminub);
3916
3917    LMI_HELPER(PCMPEQW, pcmpeqw);
3918    LMI_HELPER(PCMPGTW, pcmpgtw);
3919    LMI_HELPER(PCMPEQH, pcmpeqh);
3920    LMI_HELPER(PCMPGTH, pcmpgth);
3921    LMI_HELPER(PCMPEQB, pcmpeqb);
3922    LMI_HELPER(PCMPGTB, pcmpgtb);
3923
3924    LMI_HELPER(PSLLW, psllw);
3925    LMI_HELPER(PSLLH, psllh);
3926    LMI_HELPER(PSRLW, psrlw);
3927    LMI_HELPER(PSRLH, psrlh);
3928    LMI_HELPER(PSRAW, psraw);
3929    LMI_HELPER(PSRAH, psrah);
3930
3931    LMI_HELPER(PMULLH, pmullh);
3932    LMI_HELPER(PMULHH, pmulhh);
3933    LMI_HELPER(PMULHUH, pmulhuh);
3934    LMI_HELPER(PMADDHW, pmaddhw);
3935
3936    LMI_HELPER(PASUBUB, pasubub);
3937    LMI_HELPER_1(BIADD, biadd);
3938    LMI_HELPER_1(PMOVMSKB, pmovmskb);
3939
3940    LMI_DIRECT(PADDD, paddd, add);
3941    LMI_DIRECT(PSUBD, psubd, sub);
3942    LMI_DIRECT(XOR_CP2, xor, xor);
3943    LMI_DIRECT(NOR_CP2, nor, nor);
3944    LMI_DIRECT(AND_CP2, and, and);
3945    LMI_DIRECT(PANDN, pandn, andc);
3946    LMI_DIRECT(OR, or, or);
3947
3948    case OPC_PINSRH_0:
3949        tcg_gen_deposit_i64(t0, t0, t1, 0, 16);
3950        break;
3951    case OPC_PINSRH_1:
3952        tcg_gen_deposit_i64(t0, t0, t1, 16, 16);
3953        break;
3954    case OPC_PINSRH_2:
3955        tcg_gen_deposit_i64(t0, t0, t1, 32, 16);
3956        break;
3957    case OPC_PINSRH_3:
3958        tcg_gen_deposit_i64(t0, t0, t1, 48, 16);
3959        break;
3960
3961    case OPC_PEXTRH:
3962        tcg_gen_andi_i64(t1, t1, 3);
3963        tcg_gen_shli_i64(t1, t1, 4);
3964        tcg_gen_shr_i64(t0, t0, t1);
3965        tcg_gen_ext16u_i64(t0, t0);
3966        break;
3967
3968    case OPC_ADDU_CP2:
3969        tcg_gen_add_i64(t0, t0, t1);
3970        tcg_gen_ext32s_i64(t0, t0);
3971        break;
3972    case OPC_SUBU_CP2:
3973        tcg_gen_sub_i64(t0, t0, t1);
3974        tcg_gen_ext32s_i64(t0, t0);
3975        break;
3976
3977    case OPC_SLL_CP2:
3978        shift_max = 32;
3979        goto do_shift;
3980    case OPC_SRL_CP2:
3981        shift_max = 32;
3982        goto do_shift;
3983    case OPC_SRA_CP2:
3984        shift_max = 32;
3985        goto do_shift;
3986    case OPC_DSLL_CP2:
3987        shift_max = 64;
3988        goto do_shift;
3989    case OPC_DSRL_CP2:
3990        shift_max = 64;
3991        goto do_shift;
3992    case OPC_DSRA_CP2:
3993        shift_max = 64;
3994        goto do_shift;
3995    do_shift:
3996        /* Make sure shift count isn't TCG undefined behaviour.  */
3997        tcg_gen_andi_i64(t1, t1, shift_max - 1);
3998
3999        switch (opc) {
4000        case OPC_SLL_CP2:
4001        case OPC_DSLL_CP2:
4002            tcg_gen_shl_i64(t0, t0, t1);
4003            break;
4004        case OPC_SRA_CP2:
4005        case OPC_DSRA_CP2:
4006            /* Since SRA is UndefinedResult without sign-extended inputs,
4007               we can treat SRA and DSRA the same.  */
4008            tcg_gen_sar_i64(t0, t0, t1);
4009            break;
4010        case OPC_SRL_CP2:
4011            /* We want to shift in zeros for SRL; zero-extend first.  */
4012            tcg_gen_ext32u_i64(t0, t0);
4013            /* FALLTHRU */
4014        case OPC_DSRL_CP2:
4015            tcg_gen_shr_i64(t0, t0, t1);
4016            break;
4017        }
4018
4019        if (shift_max == 32) {
4020            tcg_gen_ext32s_i64(t0, t0);
4021        }
4022
4023        /* Shifts larger than MAX produce zero.  */
4024        tcg_gen_setcondi_i64(TCG_COND_LTU, t1, t1, shift_max);
4025        tcg_gen_neg_i64(t1, t1);
4026        tcg_gen_and_i64(t0, t0, t1);
4027        break;
4028
4029    case OPC_ADD_CP2:
4030    case OPC_DADD_CP2:
4031        {
4032            TCGv_i64 t2 = tcg_temp_new_i64();
4033            TCGLabel *lab = gen_new_label();
4034
4035            tcg_gen_mov_i64(t2, t0);
4036            tcg_gen_add_i64(t0, t1, t2);
4037            if (opc == OPC_ADD_CP2) {
4038                tcg_gen_ext32s_i64(t0, t0);
4039            }
4040            tcg_gen_xor_i64(t1, t1, t2);
4041            tcg_gen_xor_i64(t2, t2, t0);
4042            tcg_gen_andc_i64(t1, t2, t1);
4043            tcg_temp_free_i64(t2);
4044            tcg_gen_brcondi_i64(TCG_COND_GE, t1, 0, lab);
4045            generate_exception(ctx, EXCP_OVERFLOW);
4046            gen_set_label(lab);
4047            break;
4048        }
4049
4050    case OPC_SUB_CP2:
4051    case OPC_DSUB_CP2:
4052        {
4053            TCGv_i64 t2 = tcg_temp_new_i64();
4054            TCGLabel *lab = gen_new_label();
4055
4056            tcg_gen_mov_i64(t2, t0);
4057            tcg_gen_sub_i64(t0, t1, t2);
4058            if (opc == OPC_SUB_CP2) {
4059                tcg_gen_ext32s_i64(t0, t0);
4060            }
4061            tcg_gen_xor_i64(t1, t1, t2);
4062            tcg_gen_xor_i64(t2, t2, t0);
4063            tcg_gen_and_i64(t1, t1, t2);
4064            tcg_temp_free_i64(t2);
4065            tcg_gen_brcondi_i64(TCG_COND_GE, t1, 0, lab);
4066            generate_exception(ctx, EXCP_OVERFLOW);
4067            gen_set_label(lab);
4068            break;
4069        }
4070
4071    case OPC_PMULUW:
4072        tcg_gen_ext32u_i64(t0, t0);
4073        tcg_gen_ext32u_i64(t1, t1);
4074        tcg_gen_mul_i64(t0, t0, t1);
4075        break;
4076
4077    case OPC_SEQU_CP2:
4078    case OPC_SEQ_CP2:
4079    case OPC_SLTU_CP2:
4080    case OPC_SLT_CP2:
4081    case OPC_SLEU_CP2:
4082    case OPC_SLE_CP2:
4083        /* ??? Document is unclear: Set FCC[CC].  Does that mean the
4084           FD field is the CC field?  */
4085    default:
4086        MIPS_INVAL("loongson_cp2");
4087        generate_exception_end(ctx, EXCP_RI);
4088        return;
4089    }
4090
4091#undef LMI_HELPER
4092#undef LMI_DIRECT
4093
4094    gen_store_fpr64(ctx, t0, rd);
4095
4096    tcg_temp_free_i64(t0);
4097    tcg_temp_free_i64(t1);
4098}
4099
4100/* Traps */
4101static void gen_trap (DisasContext *ctx, uint32_t opc,
4102                      int rs, int rt, int16_t imm)
4103{
4104    int cond;
4105    TCGv t0 = tcg_temp_new();
4106    TCGv t1 = tcg_temp_new();
4107
4108    cond = 0;
4109    /* Load needed operands */
4110    switch (opc) {
4111    case OPC_TEQ:
4112    case OPC_TGE:
4113    case OPC_TGEU:
4114    case OPC_TLT:
4115    case OPC_TLTU:
4116    case OPC_TNE:
4117        /* Compare two registers */
4118        if (rs != rt) {
4119            gen_load_gpr(t0, rs);
4120            gen_load_gpr(t1, rt);
4121            cond = 1;
4122        }
4123        break;
4124    case OPC_TEQI:
4125    case OPC_TGEI:
4126    case OPC_TGEIU:
4127    case OPC_TLTI:
4128    case OPC_TLTIU:
4129    case OPC_TNEI:
4130        /* Compare register to immediate */
4131        if (rs != 0 || imm != 0) {
4132            gen_load_gpr(t0, rs);
4133            tcg_gen_movi_tl(t1, (int32_t)imm);
4134            cond = 1;
4135        }
4136        break;
4137    }
4138    if (cond == 0) {
4139        switch (opc) {
4140        case OPC_TEQ:   /* rs == rs */
4141        case OPC_TEQI:  /* r0 == 0  */
4142        case OPC_TGE:   /* rs >= rs */
4143        case OPC_TGEI:  /* r0 >= 0  */
4144        case OPC_TGEU:  /* rs >= rs unsigned */
4145        case OPC_TGEIU: /* r0 >= 0  unsigned */
4146            /* Always trap */
4147            generate_exception_end(ctx, EXCP_TRAP);
4148            break;
4149        case OPC_TLT:   /* rs < rs           */
4150        case OPC_TLTI:  /* r0 < 0            */
4151        case OPC_TLTU:  /* rs < rs unsigned  */
4152        case OPC_TLTIU: /* r0 < 0  unsigned  */
4153        case OPC_TNE:   /* rs != rs          */
4154        case OPC_TNEI:  /* r0 != 0           */
4155            /* Never trap: treat as NOP. */
4156            break;
4157        }
4158    } else {
4159        TCGLabel *l1 = gen_new_label();
4160
4161        switch (opc) {
4162        case OPC_TEQ:
4163        case OPC_TEQI:
4164            tcg_gen_brcond_tl(TCG_COND_NE, t0, t1, l1);
4165            break;
4166        case OPC_TGE:
4167        case OPC_TGEI:
4168            tcg_gen_brcond_tl(TCG_COND_LT, t0, t1, l1);
4169            break;
4170        case OPC_TGEU:
4171        case OPC_TGEIU:
4172            tcg_gen_brcond_tl(TCG_COND_LTU, t0, t1, l1);
4173            break;
4174        case OPC_TLT:
4175        case OPC_TLTI:
4176            tcg_gen_brcond_tl(TCG_COND_GE, t0, t1, l1);
4177            break;
4178        case OPC_TLTU:
4179        case OPC_TLTIU:
4180            tcg_gen_brcond_tl(TCG_COND_GEU, t0, t1, l1);
4181            break;
4182        case OPC_TNE:
4183        case OPC_TNEI:
4184            tcg_gen_brcond_tl(TCG_COND_EQ, t0, t1, l1);
4185            break;
4186        }
4187        generate_exception(ctx, EXCP_TRAP);
4188        gen_set_label(l1);
4189    }
4190    tcg_temp_free(t0);
4191    tcg_temp_free(t1);
4192}
4193
4194static inline void gen_goto_tb(DisasContext *ctx, int n, target_ulong dest)
4195{
4196    TranslationBlock *tb;
4197    tb = ctx->tb;
4198    if ((tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK) &&
4199        likely(!ctx->singlestep_enabled)) {
4200        tcg_gen_goto_tb(n);
4201        gen_save_pc(dest);
4202        tcg_gen_exit_tb((uintptr_t)tb + n);
4203    } else {
4204        gen_save_pc(dest);
4205        if (ctx->singlestep_enabled) {
4206            save_cpu_state(ctx, 0);
4207            gen_helper_raise_exception_debug(cpu_env);
4208        }
4209        tcg_gen_exit_tb(0);
4210    }
4211}
4212
4213/* Branches (before delay slot) */
4214static void gen_compute_branch (DisasContext *ctx, uint32_t opc,
4215                                int insn_bytes,
4216                                int rs, int rt, int32_t offset,
4217                                int delayslot_size)
4218{
4219    target_ulong btgt = -1;
4220    int blink = 0;
4221    int bcond_compute = 0;
4222    TCGv t0 = tcg_temp_new();
4223    TCGv t1 = tcg_temp_new();
4224
4225    if (ctx->hflags & MIPS_HFLAG_BMASK) {
4226#ifdef MIPS_DEBUG_DISAS
4227        LOG_DISAS("Branch in delay / forbidden slot at PC 0x"
4228                  TARGET_FMT_lx "\n", ctx->pc);
4229#endif
4230        generate_exception_end(ctx, EXCP_RI);
4231        goto out;
4232    }
4233
4234    /* Load needed operands */
4235    switch (opc) {
4236    case OPC_BEQ:
4237    case OPC_BEQL:
4238    case OPC_BNE:
4239    case OPC_BNEL:
4240        /* Compare two registers */
4241        if (rs != rt) {
4242            gen_load_gpr(t0, rs);
4243            gen_load_gpr(t1, rt);
4244            bcond_compute = 1;
4245        }
4246        btgt = ctx->pc + insn_bytes + offset;
4247        break;
4248    case OPC_BGEZ:
4249    case OPC_BGEZAL:
4250    case OPC_BGEZALL:
4251    case OPC_BGEZL:
4252    case OPC_BGTZ:
4253    case OPC_BGTZL:
4254    case OPC_BLEZ:
4255    case OPC_BLEZL:
4256    case OPC_BLTZ:
4257    case OPC_BLTZAL:
4258    case OPC_BLTZALL:
4259    case OPC_BLTZL:
4260        /* Compare to zero */
4261        if (rs != 0) {
4262            gen_load_gpr(t0, rs);
4263            bcond_compute = 1;
4264        }
4265        btgt = ctx->pc + insn_bytes + offset;
4266        break;
4267    case OPC_BPOSGE32:
4268#if defined(TARGET_MIPS64)
4269    case OPC_BPOSGE64:
4270        tcg_gen_andi_tl(t0, cpu_dspctrl, 0x7F);
4271#else
4272        tcg_gen_andi_tl(t0, cpu_dspctrl, 0x3F);
4273#endif
4274        bcond_compute = 1;
4275        btgt = ctx->pc + insn_bytes + offset;
4276        break;
4277    case OPC_J:
4278    case OPC_JAL:
4279    case OPC_JALX:
4280        /* Jump to immediate */
4281        btgt = ((ctx->pc + insn_bytes) & (int32_t)0xF0000000) | (uint32_t)offset;
4282        break;
4283    case OPC_JR:
4284    case OPC_JALR:
4285        /* Jump to register */
4286        if (offset != 0 && offset != 16) {
4287            /* Hint = 0 is JR/JALR, hint 16 is JR.HB/JALR.HB, the
4288               others are reserved. */
4289            MIPS_INVAL("jump hint");
4290            generate_exception_end(ctx, EXCP_RI);
4291            goto out;
4292        }
4293        gen_load_gpr(btarget, rs);
4294        break;
4295    default:
4296        MIPS_INVAL("branch/jump");
4297        generate_exception_end(ctx, EXCP_RI);
4298        goto out;
4299    }
4300    if (bcond_compute == 0) {
4301        /* No condition to be computed */
4302        switch (opc) {
4303        case OPC_BEQ:     /* rx == rx        */
4304        case OPC_BEQL:    /* rx == rx likely */
4305        case OPC_BGEZ:    /* 0 >= 0          */
4306        case OPC_BGEZL:   /* 0 >= 0 likely   */
4307        case OPC_BLEZ:    /* 0 <= 0          */
4308        case OPC_BLEZL:   /* 0 <= 0 likely   */
4309            /* Always take */
4310            ctx->hflags |= MIPS_HFLAG_B;
4311            break;
4312        case OPC_BGEZAL:  /* 0 >= 0          */
4313        case OPC_BGEZALL: /* 0 >= 0 likely   */
4314            /* Always take and link */
4315            blink = 31;
4316            ctx->hflags |= MIPS_HFLAG_B;
4317            break;
4318        case OPC_BNE:     /* rx != rx        */
4319        case OPC_BGTZ:    /* 0 > 0           */
4320        case OPC_BLTZ:    /* 0 < 0           */
4321            /* Treat as NOP. */
4322            goto out;
4323        case OPC_BLTZAL:  /* 0 < 0           */
4324            /* Handle as an unconditional branch to get correct delay
4325               slot checking.  */
4326            blink = 31;
4327            btgt = ctx->pc + insn_bytes + delayslot_size;
4328            ctx->hflags |= MIPS_HFLAG_B;
4329            break;
4330        case OPC_BLTZALL: /* 0 < 0 likely */
4331            tcg_gen_movi_tl(cpu_gpr[31], ctx->pc + 8);
4332            /* Skip the instruction in the delay slot */
4333            ctx->pc += 4;
4334            goto out;
4335        case OPC_BNEL:    /* rx != rx likely */
4336        case OPC_BGTZL:   /* 0 > 0 likely */
4337        case OPC_BLTZL:   /* 0 < 0 likely */
4338            /* Skip the instruction in the delay slot */
4339            ctx->pc += 4;
4340            goto out;
4341        case OPC_J:
4342            ctx->hflags |= MIPS_HFLAG_B;
4343            break;
4344        case OPC_JALX:
4345            ctx->hflags |= MIPS_HFLAG_BX;
4346            /* Fallthrough */
4347        case OPC_JAL:
4348            blink = 31;
4349            ctx->hflags |= MIPS_HFLAG_B;
4350            break;
4351        case OPC_JR:
4352            ctx->hflags |= MIPS_HFLAG_BR;
4353            break;
4354        case OPC_JALR:
4355            blink = rt;
4356            ctx->hflags |= MIPS_HFLAG_BR;
4357            break;
4358        default:
4359            MIPS_INVAL("branch/jump");
4360            generate_exception_end(ctx, EXCP_RI);
4361            goto out;
4362        }
4363    } else {
4364        switch (opc) {
4365        case OPC_BEQ:
4366            tcg_gen_setcond_tl(TCG_COND_EQ, bcond, t0, t1);
4367            goto not_likely;
4368        case OPC_BEQL:
4369            tcg_gen_setcond_tl(TCG_COND_EQ, bcond, t0, t1);
4370            goto likely;
4371        case OPC_BNE:
4372            tcg_gen_setcond_tl(TCG_COND_NE, bcond, t0, t1);
4373            goto not_likely;
4374        case OPC_BNEL:
4375            tcg_gen_setcond_tl(TCG_COND_NE, bcond, t0, t1);
4376            goto likely;
4377        case OPC_BGEZ:
4378            tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
4379            goto not_likely;
4380        case OPC_BGEZL:
4381            tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
4382            goto likely;
4383        case OPC_BGEZAL:
4384            tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
4385            blink = 31;
4386            goto not_likely;
4387        case OPC_BGEZALL:
4388            tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
4389            blink = 31;
4390            goto likely;
4391        case OPC_BGTZ:
4392            tcg_gen_setcondi_tl(TCG_COND_GT, bcond, t0, 0);
4393            goto not_likely;
4394        case OPC_BGTZL:
4395            tcg_gen_setcondi_tl(TCG_COND_GT, bcond, t0, 0);
4396            goto likely;
4397        case OPC_BLEZ:
4398            tcg_gen_setcondi_tl(TCG_COND_LE, bcond, t0, 0);
4399            goto not_likely;
4400        case OPC_BLEZL:
4401            tcg_gen_setcondi_tl(TCG_COND_LE, bcond, t0, 0);
4402            goto likely;
4403        case OPC_BLTZ:
4404            tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
4405            goto not_likely;
4406        case OPC_BLTZL:
4407            tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
4408            goto likely;
4409        case OPC_BPOSGE32:
4410            tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 32);
4411            goto not_likely;
4412#if defined(TARGET_MIPS64)
4413        case OPC_BPOSGE64:
4414            tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 64);
4415            goto not_likely;
4416#endif
4417        case OPC_BLTZAL:
4418            tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
4419            blink = 31;
4420        not_likely:
4421            ctx->hflags |= MIPS_HFLAG_BC;
4422            break;
4423        case OPC_BLTZALL:
4424            tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
4425            blink = 31;
4426        likely:
4427            ctx->hflags |= MIPS_HFLAG_BL;
4428            break;
4429        default:
4430            MIPS_INVAL("conditional branch/jump");
4431            generate_exception_end(ctx, EXCP_RI);
4432            goto out;
4433        }
4434    }
4435
4436    ctx->btarget = btgt;
4437
4438    switch (delayslot_size) {
4439    case 2:
4440        ctx->hflags |= MIPS_HFLAG_BDS16;
4441        break;
4442    case 4:
4443        ctx->hflags |= MIPS_HFLAG_BDS32;
4444        break;
4445    }
4446
4447    if (blink > 0) {
4448        int post_delay = insn_bytes + delayslot_size;
4449        int lowbit = !!(ctx->hflags & MIPS_HFLAG_M16);
4450
4451        tcg_gen_movi_tl(cpu_gpr[blink], ctx->pc + post_delay + lowbit);
4452    }
4453
4454 out:
4455    if (insn_bytes == 2)
4456        ctx->hflags |= MIPS_HFLAG_B16;
4457    tcg_temp_free(t0);
4458    tcg_temp_free(t1);
4459}
4460
4461/* special3 bitfield operations */
4462static void gen_bitops (DisasContext *ctx, uint32_t opc, int rt,
4463                        int rs, int lsb, int msb)
4464{
4465    TCGv t0 = tcg_temp_new();
4466    TCGv t1 = tcg_temp_new();
4467
4468    gen_load_gpr(t1, rs);
4469    switch (opc) {
4470    case OPC_EXT:
4471        if (lsb + msb > 31) {
4472            goto fail;
4473        }
4474        tcg_gen_shri_tl(t0, t1, lsb);
4475        if (msb != 31) {
4476            tcg_gen_andi_tl(t0, t0, (1U << (msb + 1)) - 1);
4477        } else {
4478            tcg_gen_ext32s_tl(t0, t0);
4479        }
4480        break;
4481#if defined(TARGET_MIPS64)
4482    case OPC_DEXTU:
4483        lsb += 32;
4484        goto do_dext;
4485    case OPC_DEXTM:
4486        msb += 32;
4487        goto do_dext;
4488    case OPC_DEXT:
4489    do_dext:
4490        if (lsb + msb > 63) {
4491            goto fail;
4492        }
4493        tcg_gen_shri_tl(t0, t1, lsb);
4494        if (msb != 63) {
4495            tcg_gen_andi_tl(t0, t0, (1ULL << (msb + 1)) - 1);
4496        }
4497        break;
4498#endif
4499    case OPC_INS:
4500        if (lsb > msb) {
4501            goto fail;
4502        }
4503        gen_load_gpr(t0, rt);
4504        tcg_gen_deposit_tl(t0, t0, t1, lsb, msb - lsb + 1);
4505        tcg_gen_ext32s_tl(t0, t0);
4506        break;
4507#if defined(TARGET_MIPS64)
4508    case OPC_DINSU:
4509        lsb += 32;
4510        /* FALLTHRU */
4511    case OPC_DINSM:
4512        msb += 32;
4513        /* FALLTHRU */
4514    case OPC_DINS:
4515        if (lsb > msb) {
4516            goto fail;
4517        }
4518        gen_load_gpr(t0, rt);
4519        tcg_gen_deposit_tl(t0, t0, t1, lsb, msb - lsb + 1);
4520        break;
4521#endif
4522    default:
4523fail:
4524        MIPS_INVAL("bitops");
4525        generate_exception_end(ctx, EXCP_RI);
4526        tcg_temp_free(t0);
4527        tcg_temp_free(t1);
4528        return;
4529    }
4530    gen_store_gpr(t0, rt);
4531    tcg_temp_free(t0);
4532    tcg_temp_free(t1);
4533}
4534
4535static void gen_bshfl (DisasContext *ctx, uint32_t op2, int rt, int rd)
4536{
4537    TCGv t0;
4538
4539    if (rd == 0) {
4540        /* If no destination, treat it as a NOP. */
4541        return;
4542    }
4543
4544    t0 = tcg_temp_new();
4545    gen_load_gpr(t0, rt);
4546    switch (op2) {
4547    case OPC_WSBH:
4548        {
4549            TCGv t1 = tcg_temp_new();
4550
4551            tcg_gen_shri_tl(t1, t0, 8);
4552            tcg_gen_andi_tl(t1, t1, 0x00FF00FF);
4553            tcg_gen_shli_tl(t0, t0, 8);
4554            tcg_gen_andi_tl(t0, t0, ~0x00FF00FF);
4555            tcg_gen_or_tl(t0, t0, t1);
4556            tcg_temp_free(t1);
4557            tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
4558        }
4559        break;
4560    case OPC_SEB:
4561        tcg_gen_ext8s_tl(cpu_gpr[rd], t0);
4562        break;
4563    case OPC_SEH:
4564        tcg_gen_ext16s_tl(cpu_gpr[rd], t0);
4565        break;
4566#if defined(TARGET_MIPS64)
4567    case OPC_DSBH:
4568        {
4569            TCGv t1 = tcg_temp_new();
4570
4571            tcg_gen_shri_tl(t1, t0, 8);
4572            tcg_gen_andi_tl(t1, t1, 0x00FF00FF00FF00FFULL);
4573            tcg_gen_shli_tl(t0, t0, 8);
4574            tcg_gen_andi_tl(t0, t0, ~0x00FF00FF00FF00FFULL);
4575            tcg_gen_or_tl(cpu_gpr[rd], t0, t1);
4576            tcg_temp_free(t1);
4577        }
4578        break;
4579    case OPC_DSHD:
4580        {
4581            TCGv t1 = tcg_temp_new();
4582
4583            tcg_gen_shri_tl(t1, t0, 16);
4584            tcg_gen_andi_tl(t1, t1, 0x0000FFFF0000FFFFULL);
4585            tcg_gen_shli_tl(t0, t0, 16);
4586            tcg_gen_andi_tl(t0, t0, ~0x0000FFFF0000FFFFULL);
4587            tcg_gen_or_tl(t0, t0, t1);
4588            tcg_gen_shri_tl(t1, t0, 32);
4589            tcg_gen_shli_tl(t0, t0, 32);
4590            tcg_gen_or_tl(cpu_gpr[rd], t0, t1);
4591            tcg_temp_free(t1);
4592        }
4593        break;
4594#endif
4595    default:
4596        MIPS_INVAL("bsfhl");
4597        generate_exception_end(ctx, EXCP_RI);
4598        tcg_temp_free(t0);
4599        return;
4600    }
4601    tcg_temp_free(t0);
4602}
4603
4604static void gen_lsa(DisasContext *ctx, int opc, int rd, int rs, int rt,
4605                    int imm2)
4606{
4607    TCGv t0;
4608    TCGv t1;
4609    if (rd == 0) {
4610        /* Treat as NOP. */
4611        return;
4612    }
4613    t0 = tcg_temp_new();
4614    t1 = tcg_temp_new();
4615    gen_load_gpr(t0, rs);
4616    gen_load_gpr(t1, rt);
4617    tcg_gen_shli_tl(t0, t0, imm2 + 1);
4618    tcg_gen_add_tl(cpu_gpr[rd], t0, t1);
4619    if (opc == OPC_LSA) {
4620        tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
4621    }
4622
4623    tcg_temp_free(t1);
4624    tcg_temp_free(t0);
4625
4626    return;
4627}
4628
4629static void gen_align(DisasContext *ctx, int opc, int rd, int rs, int rt,
4630                      int bp)
4631{
4632    TCGv t0;
4633    if (rd == 0) {
4634        /* Treat as NOP. */
4635        return;
4636    }
4637    t0 = tcg_temp_new();
4638    gen_load_gpr(t0, rt);
4639    if (bp == 0) {
4640        switch (opc) {
4641        case OPC_ALIGN:
4642            tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
4643            break;
4644#if defined(TARGET_MIPS64)
4645        case OPC_DALIGN:
4646            tcg_gen_mov_tl(cpu_gpr[rd], t0);
4647            break;
4648#endif
4649        }
4650    } else {
4651        TCGv t1 = tcg_temp_new();
4652        gen_load_gpr(t1, rs);
4653        switch (opc) {
4654        case OPC_ALIGN:
4655            {
4656                TCGv_i64 t2 = tcg_temp_new_i64();
4657                tcg_gen_concat_tl_i64(t2, t1, t0);
4658                tcg_gen_shri_i64(t2, t2, 8 * (4 - bp));
4659                gen_move_low32(cpu_gpr[rd], t2);
4660                tcg_temp_free_i64(t2);
4661            }
4662            break;
4663#if defined(TARGET_MIPS64)
4664        case OPC_DALIGN:
4665            tcg_gen_shli_tl(t0, t0, 8 * bp);
4666            tcg_gen_shri_tl(t1, t1, 8 * (8 - bp));
4667            tcg_gen_or_tl(cpu_gpr[rd], t1, t0);
4668            break;
4669#endif
4670        }
4671        tcg_temp_free(t1);
4672    }
4673
4674    tcg_temp_free(t0);
4675}
4676
4677static void gen_bitswap(DisasContext *ctx, int opc, int rd, int rt)
4678{
4679    TCGv t0;
4680    if (rd == 0) {
4681        /* Treat as NOP. */
4682        return;
4683    }
4684    t0 = tcg_temp_new();
4685    gen_load_gpr(t0, rt);
4686    switch (opc) {
4687    case OPC_BITSWAP:
4688        gen_helper_bitswap(cpu_gpr[rd], t0);
4689        break;
4690#if defined(TARGET_MIPS64)
4691    case OPC_DBITSWAP:
4692        gen_helper_dbitswap(cpu_gpr[rd], t0);
4693        break;
4694#endif
4695    }
4696    tcg_temp_free(t0);
4697}
4698
4699#ifndef CONFIG_USER_ONLY
4700/* CP0 (MMU and control) */
4701static inline void gen_mthc0_entrylo(TCGv arg, target_ulong off)
4702{
4703    TCGv_i64 t0 = tcg_temp_new_i64();
4704    TCGv_i64 t1 = tcg_temp_new_i64();
4705
4706    tcg_gen_ext_tl_i64(t0, arg);
4707    tcg_gen_ld_i64(t1, cpu_env, off);
4708#if defined(TARGET_MIPS64)
4709    tcg_gen_deposit_i64(t1, t1, t0, 30, 32);
4710#else
4711    tcg_gen_concat32_i64(t1, t1, t0);
4712#endif
4713    tcg_gen_st_i64(t1, cpu_env, off);
4714    tcg_temp_free_i64(t1);
4715    tcg_temp_free_i64(t0);
4716}
4717
4718static inline void gen_mthc0_store64(TCGv arg, target_ulong off)
4719{
4720    TCGv_i64 t0 = tcg_temp_new_i64();
4721    TCGv_i64 t1 = tcg_temp_new_i64();
4722
4723    tcg_gen_ext_tl_i64(t0, arg);
4724    tcg_gen_ld_i64(t1, cpu_env, off);
4725    tcg_gen_concat32_i64(t1, t1, t0);
4726    tcg_gen_st_i64(t1, cpu_env, off);
4727    tcg_temp_free_i64(t1);
4728    tcg_temp_free_i64(t0);
4729}
4730
4731static inline void gen_mfhc0_entrylo(TCGv arg, target_ulong off)
4732{
4733    TCGv_i64 t0 = tcg_temp_new_i64();
4734
4735    tcg_gen_ld_i64(t0, cpu_env, off);
4736#if defined(TARGET_MIPS64)
4737    tcg_gen_shri_i64(t0, t0, 30);
4738#else
4739    tcg_gen_shri_i64(t0, t0, 32);
4740#endif
4741    gen_move_low32(arg, t0);
4742    tcg_temp_free_i64(t0);
4743}
4744
4745static inline void gen_mfhc0_load64(TCGv arg, target_ulong off, int shift)
4746{
4747    TCGv_i64 t0 = tcg_temp_new_i64();
4748
4749    tcg_gen_ld_i64(t0, cpu_env, off);
4750    tcg_gen_shri_i64(t0, t0, 32 + shift);
4751    gen_move_low32(arg, t0);
4752    tcg_temp_free_i64(t0);
4753}
4754
4755static inline void gen_mfc0_load32 (TCGv arg, target_ulong off)
4756{
4757    TCGv_i32 t0 = tcg_temp_new_i32();
4758
4759    tcg_gen_ld_i32(t0, cpu_env, off);
4760    tcg_gen_ext_i32_tl(arg, t0);
4761    tcg_temp_free_i32(t0);
4762}
4763
4764static inline void gen_mfc0_load64 (TCGv arg, target_ulong off)
4765{
4766    tcg_gen_ld_tl(arg, cpu_env, off);
4767    tcg_gen_ext32s_tl(arg, arg);
4768}
4769
4770static inline void gen_mtc0_store32 (TCGv arg, target_ulong off)
4771{
4772    TCGv_i32 t0 = tcg_temp_new_i32();
4773
4774    tcg_gen_trunc_tl_i32(t0, arg);
4775    tcg_gen_st_i32(t0, cpu_env, off);
4776    tcg_temp_free_i32(t0);
4777}
4778
4779#define CP0_CHECK(c)                            \
4780    do {                                        \
4781        if (!(c)) {                             \
4782            goto cp0_unimplemented;             \
4783        }                                       \
4784    } while (0)
4785
4786static void gen_mfhc0(DisasContext *ctx, TCGv arg, int reg, int sel)
4787{
4788    const char *rn = "invalid";
4789
4790    CP0_CHECK(ctx->hflags & MIPS_HFLAG_ELPA);
4791
4792    switch (reg) {
4793    case 2:
4794        switch (sel) {
4795        case 0:
4796            gen_mfhc0_entrylo(arg, offsetof(CPUMIPSState, CP0_EntryLo0));
4797            rn = "EntryLo0";
4798            break;
4799        default:
4800            goto cp0_unimplemented;
4801        }
4802        break;
4803    case 3:
4804        switch (sel) {
4805        case 0:
4806            gen_mfhc0_entrylo(arg, offsetof(CPUMIPSState, CP0_EntryLo1));
4807            rn = "EntryLo1";
4808            break;
4809        default:
4810            goto cp0_unimplemented;
4811        }
4812        break;
4813    case 17:
4814        switch (sel) {
4815        case 0:
4816            gen_mfhc0_load64(arg, offsetof(CPUMIPSState, lladdr),
4817                             ctx->CP0_LLAddr_shift);
4818            rn = "LLAddr";
4819            break;
4820        case 1:
4821            CP0_CHECK(ctx->mrp);
4822            gen_helper_mfhc0_maar(arg, cpu_env);
4823            rn = "MAAR";
4824            break;
4825        default:
4826            goto cp0_unimplemented;
4827        }
4828        break;
4829    case 28:
4830        switch (sel) {
4831        case 0:
4832        case 2:
4833        case 4:
4834        case 6:
4835            gen_mfhc0_load64(arg, offsetof(CPUMIPSState, CP0_TagLo), 0);
4836            rn = "TagLo";
4837            break;
4838        default:
4839            goto cp0_unimplemented;
4840        }
4841        break;
4842    default:
4843        goto cp0_unimplemented;
4844    }
4845
4846    (void)rn; /* avoid a compiler warning */
4847    LOG_DISAS("mfhc0 %s (reg %d sel %d)\n", rn, reg, sel);
4848    return;
4849
4850cp0_unimplemented:
4851    LOG_DISAS("mfhc0 %s (reg %d sel %d)\n", rn, reg, sel);
4852    tcg_gen_movi_tl(arg, 0);
4853}
4854
4855static void gen_mthc0(DisasContext *ctx, TCGv arg, int reg, int sel)
4856{
4857    const char *rn = "invalid";
4858    uint64_t mask = ctx->PAMask >> 36;
4859
4860    CP0_CHECK(ctx->hflags & MIPS_HFLAG_ELPA);
4861
4862    switch (reg) {
4863    case 2:
4864        switch (sel) {
4865        case 0:
4866            tcg_gen_andi_tl(arg, arg, mask);
4867            gen_mthc0_entrylo(arg, offsetof(CPUMIPSState, CP0_EntryLo0));
4868            rn = "EntryLo0";
4869            break;
4870        default:
4871            goto cp0_unimplemented;
4872        }
4873        break;
4874    case 3:
4875        switch (sel) {
4876        case 0:
4877            tcg_gen_andi_tl(arg, arg, mask);
4878            gen_mthc0_entrylo(arg, offsetof(CPUMIPSState, CP0_EntryLo1));
4879            rn = "EntryLo1";
4880            break;
4881        default:
4882            goto cp0_unimplemented;
4883        }
4884        break;
4885    case 17:
4886        switch (sel) {
4887        case 0:
4888            /* LLAddr is read-only (the only exception is bit 0 if LLB is
4889               supported); the CP0_LLAddr_rw_bitmask does not seem to be
4890               relevant for modern MIPS cores supporting MTHC0, therefore
4891               treating MTHC0 to LLAddr as NOP. */
4892            rn = "LLAddr";
4893            break;
4894        case 1:
4895            CP0_CHECK(ctx->mrp);
4896            gen_helper_mthc0_maar(cpu_env, arg);
4897            rn = "MAAR";
4898            break;
4899        default:
4900            goto cp0_unimplemented;
4901        }
4902        break;
4903    case 28:
4904        switch (sel) {
4905        case 0:
4906        case 2:
4907        case 4:
4908        case 6:
4909            tcg_gen_andi_tl(arg, arg, mask);
4910            gen_mthc0_store64(arg, offsetof(CPUMIPSState, CP0_TagLo));
4911            rn = "TagLo";
4912            break;
4913        default:
4914            goto cp0_unimplemented;
4915        }
4916        break;
4917    default:
4918        goto cp0_unimplemented;
4919    }
4920
4921    (void)rn; /* avoid a compiler warning */
4922cp0_unimplemented:
4923    LOG_DISAS("mthc0 %s (reg %d sel %d)\n", rn, reg, sel);
4924}
4925
4926static inline void gen_mfc0_unimplemented(DisasContext *ctx, TCGv arg)
4927{
4928    if (ctx->insn_flags & ISA_MIPS32R6) {
4929        tcg_gen_movi_tl(arg, 0);
4930    } else {
4931        tcg_gen_movi_tl(arg, ~0);
4932    }
4933}
4934
4935static void gen_mfc0(DisasContext *ctx, TCGv arg, int reg, int sel)
4936{
4937    const char *rn = "invalid";
4938
4939    if (sel != 0)
4940        check_insn(ctx, ISA_MIPS32);
4941
4942    switch (reg) {
4943    case 0:
4944        switch (sel) {
4945        case 0:
4946            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Index));
4947            rn = "Index";
4948            break;
4949        case 1:
4950            CP0_CHECK(ctx->insn_flags & ASE_MT);
4951            gen_helper_mfc0_mvpcontrol(arg, cpu_env);
4952            rn = "MVPControl";
4953            break;
4954        case 2:
4955            CP0_CHECK(ctx->insn_flags & ASE_MT);
4956            gen_helper_mfc0_mvpconf0(arg, cpu_env);
4957            rn = "MVPConf0";
4958            break;
4959        case 3:
4960            CP0_CHECK(ctx->insn_flags & ASE_MT);
4961            gen_helper_mfc0_mvpconf1(arg, cpu_env);
4962            rn = "MVPConf1";
4963            break;
4964        case 4:
4965            CP0_CHECK(ctx->vp);
4966            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPControl));
4967            rn = "VPControl";
4968            break;
4969        default:
4970            goto cp0_unimplemented;
4971        }
4972        break;
4973    case 1:
4974        switch (sel) {
4975        case 0:
4976            CP0_CHECK(!(ctx->insn_flags & ISA_MIPS32R6));
4977            gen_helper_mfc0_random(arg, cpu_env);
4978            rn = "Random";
4979            break;
4980        case 1:
4981            CP0_CHECK(ctx->insn_flags & ASE_MT);
4982            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEControl));
4983            rn = "VPEControl";
4984            break;
4985        case 2:
4986            CP0_CHECK(ctx->insn_flags & ASE_MT);
4987            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf0));
4988            rn = "VPEConf0";
4989            break;
4990        case 3:
4991            CP0_CHECK(ctx->insn_flags & ASE_MT);
4992            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf1));
4993            rn = "VPEConf1";
4994            break;
4995        case 4:
4996            CP0_CHECK(ctx->insn_flags & ASE_MT);
4997            gen_mfc0_load64(arg, offsetof(CPUMIPSState, CP0_YQMask));
4998            rn = "YQMask";
4999            break;
5000        case 5:
5001            CP0_CHECK(ctx->insn_flags & ASE_MT);
5002            gen_mfc0_load64(arg, offsetof(CPUMIPSState, CP0_VPESchedule));
5003            rn = "VPESchedule";
5004            break;
5005        case 6:
5006            CP0_CHECK(ctx->insn_flags & ASE_MT);
5007            gen_mfc0_load64(arg, offsetof(CPUMIPSState, CP0_VPEScheFBack));
5008            rn = "VPEScheFBack";
5009            break;
5010        case 7:
5011            CP0_CHECK(ctx->insn_flags & ASE_MT);
5012            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEOpt));
5013            rn = "VPEOpt";
5014            break;
5015        default:
5016            goto cp0_unimplemented;
5017        }
5018        break;
5019    case 2:
5020        switch (sel) {
5021        case 0:
5022            {
5023                TCGv_i64 tmp = tcg_temp_new_i64();
5024                tcg_gen_ld_i64(tmp, cpu_env,
5025                               offsetof(CPUMIPSState, CP0_EntryLo0));
5026#if defined(TARGET_MIPS64)
5027                if (ctx->rxi) {
5028                    /* Move RI/XI fields to bits 31:30 */
5029                    tcg_gen_shri_tl(arg, tmp, CP0EnLo_XI);
5030                    tcg_gen_deposit_tl(tmp, tmp, arg, 30, 2);
5031                }
5032#endif
5033                gen_move_low32(arg, tmp);
5034                tcg_temp_free_i64(tmp);
5035            }
5036            rn = "EntryLo0";
5037            break;
5038        case 1:
5039            CP0_CHECK(ctx->insn_flags & ASE_MT);
5040            gen_helper_mfc0_tcstatus(arg, cpu_env);
5041            rn = "TCStatus";
5042            break;
5043        case 2:
5044            CP0_CHECK(ctx->insn_flags & ASE_MT);
5045            gen_helper_mfc0_tcbind(arg, cpu_env);
5046            rn = "TCBind";
5047            break;
5048        case 3:
5049            CP0_CHECK(ctx->insn_flags & ASE_MT);
5050            gen_helper_mfc0_tcrestart(arg, cpu_env);
5051            rn = "TCRestart";
5052            break;
5053        case 4:
5054            CP0_CHECK(ctx->insn_flags & ASE_MT);
5055            gen_helper_mfc0_tchalt(arg, cpu_env);
5056            rn = "TCHalt";
5057            break;
5058        case 5:
5059            CP0_CHECK(ctx->insn_flags & ASE_MT);
5060            gen_helper_mfc0_tccontext(arg, cpu_env);
5061            rn = "TCContext";
5062            break;
5063        case 6:
5064            CP0_CHECK(ctx->insn_flags & ASE_MT);
5065            gen_helper_mfc0_tcschedule(arg, cpu_env);
5066            rn = "TCSchedule";
5067            break;
5068        case 7:
5069            CP0_CHECK(ctx->insn_flags & ASE_MT);
5070            gen_helper_mfc0_tcschefback(arg, cpu_env);
5071            rn = "TCScheFBack";
5072            break;
5073        default:
5074            goto cp0_unimplemented;
5075        }
5076        break;
5077    case 3:
5078        switch (sel) {
5079        case 0:
5080            {
5081                TCGv_i64 tmp = tcg_temp_new_i64();
5082                tcg_gen_ld_i64(tmp, cpu_env,
5083                               offsetof(CPUMIPSState, CP0_EntryLo1));
5084#if defined(TARGET_MIPS64)
5085                if (ctx->rxi) {
5086                    /* Move RI/XI fields to bits 31:30 */
5087                    tcg_gen_shri_tl(arg, tmp, CP0EnLo_XI);
5088                    tcg_gen_deposit_tl(tmp, tmp, arg, 30, 2);
5089                }
5090#endif
5091                gen_move_low32(arg, tmp);
5092                tcg_temp_free_i64(tmp);
5093            }
5094            rn = "EntryLo1";
5095            break;
5096        case 1:
5097            CP0_CHECK(ctx->vp);
5098            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_GlobalNumber));
5099            rn = "GlobalNumber";
5100            break;
5101        default:
5102            goto cp0_unimplemented;
5103        }
5104        break;
5105    case 4:
5106        switch (sel) {
5107        case 0:
5108            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_Context));
5109            tcg_gen_ext32s_tl(arg, arg);
5110            rn = "Context";
5111            break;
5112        case 1:
5113//            gen_helper_mfc0_contextconfig(arg); /* SmartMIPS ASE */
5114            rn = "ContextConfig";
5115            goto cp0_unimplemented;
5116//            break;
5117        case 2:
5118            CP0_CHECK(ctx->ulri);
5119            tcg_gen_ld32s_tl(arg, cpu_env,
5120                             offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
5121            rn = "UserLocal";
5122            break;
5123        default:
5124            goto cp0_unimplemented;
5125        }
5126        break;
5127    case 5:
5128        switch (sel) {
5129        case 0:
5130            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageMask));
5131            rn = "PageMask";
5132            break;
5133        case 1:
5134            check_insn(ctx, ISA_MIPS32R2);
5135            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageGrain));
5136            rn = "PageGrain";
5137            break;
5138        default:
5139            goto cp0_unimplemented;
5140        }
5141        break;
5142    case 6:
5143        switch (sel) {
5144        case 0:
5145            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Wired));
5146            rn = "Wired";
5147            break;
5148        case 1:
5149            check_insn(ctx, ISA_MIPS32R2);
5150            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf0));
5151            rn = "SRSConf0";
5152            break;
5153        case 2:
5154            check_insn(ctx, ISA_MIPS32R2);
5155            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf1));
5156            rn = "SRSConf1";
5157            break;
5158        case 3:
5159            check_insn(ctx, ISA_MIPS32R2);
5160            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf2));
5161            rn = "SRSConf2";
5162            break;
5163        case 4:
5164            check_insn(ctx, ISA_MIPS32R2);
5165            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf3));
5166            rn = "SRSConf3";
5167            break;
5168        case 5:
5169            check_insn(ctx, ISA_MIPS32R2);
5170            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf4));
5171            rn = "SRSConf4";
5172            break;
5173        default:
5174            goto cp0_unimplemented;
5175        }
5176        break;
5177    case 7:
5178        switch (sel) {
5179        case 0:
5180            check_insn(ctx, ISA_MIPS32R2);
5181            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_HWREna));
5182            rn = "HWREna";
5183            break;
5184        default:
5185            goto cp0_unimplemented;
5186        }
5187        break;
5188    case 8:
5189        switch (sel) {
5190        case 0:
5191            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_BadVAddr));
5192            tcg_gen_ext32s_tl(arg, arg);
5193            rn = "BadVAddr";
5194            break;
5195        case 1:
5196            CP0_CHECK(ctx->bi);
5197            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_BadInstr));
5198            rn = "BadInstr";
5199            break;
5200        case 2:
5201            CP0_CHECK(ctx->bp);
5202            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_BadInstrP));
5203            rn = "BadInstrP";
5204            break;
5205        default:
5206            goto cp0_unimplemented;
5207        }
5208        break;
5209    case 9:
5210        switch (sel) {
5211        case 0:
5212            /* Mark as an IO operation because we read the time.  */
5213            if (ctx->tb->cflags & CF_USE_ICOUNT) {
5214                gen_io_start();
5215            }
5216            gen_helper_mfc0_count(arg, cpu_env);
5217            if (ctx->tb->cflags & CF_USE_ICOUNT) {
5218                gen_io_end();
5219            }
5220            /* Break the TB to be able to take timer interrupts immediately
5221               after reading count.  */
5222            ctx->bstate = BS_STOP;
5223            rn = "Count";
5224            break;
5225        /* 6,7 are implementation dependent */
5226        default:
5227            goto cp0_unimplemented;
5228        }
5229        break;
5230    case 10:
5231        switch (sel) {
5232        case 0:
5233            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryHi));
5234            tcg_gen_ext32s_tl(arg, arg);
5235            rn = "EntryHi";
5236            break;
5237        default:
5238            goto cp0_unimplemented;
5239        }
5240        break;
5241    case 11:
5242        switch (sel) {
5243        case 0:
5244            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Compare));
5245            rn = "Compare";
5246            break;
5247        /* 6,7 are implementation dependent */
5248        default:
5249            goto cp0_unimplemented;