qemu/target/mips/tcg/translate.c
<<
>>
Prefs
   1/*
   2 *  MIPS emulation for QEMU - main translation routines
   3 *
   4 *  Copyright (c) 2004-2005 Jocelyn Mayer
   5 *  Copyright (c) 2006 Marius Groeger (FPU operations)
   6 *  Copyright (c) 2006 Thiemo Seufer (MIPS32R2 support)
   7 *  Copyright (c) 2009 CodeSourcery (MIPS16 and microMIPS support)
   8 *  Copyright (c) 2012 Jia Liu & Dongxue Zhang (MIPS ASE DSP support)
   9 *  Copyright (c) 2020 Philippe Mathieu-Daudé
  10 *
  11 * This library is free software; you can redistribute it and/or
  12 * modify it under the terms of the GNU Lesser General Public
  13 * License as published by the Free Software Foundation; either
  14 * version 2.1 of the License, or (at your option) any later version.
  15 *
  16 * This library is distributed in the hope that it will be useful,
  17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
  18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  19 * Lesser General Public License for more details.
  20 *
  21 * You should have received a copy of the GNU Lesser General Public
  22 * License along with this library; if not, see <http://www.gnu.org/licenses/>.
  23 */
  24
  25#include "qemu/osdep.h"
  26#include "translate.h"
  27#include "internal.h"
  28#include "exec/helper-proto.h"
  29#include "exec/translation-block.h"
  30#include "semihosting/semihost.h"
  31#include "trace.h"
  32#include "disas/disas.h"
  33#include "fpu_helper.h"
  34
  35#define HELPER_H "helper.h"
  36#include "exec/helper-info.c.inc"
  37#undef  HELPER_H
  38
  39
  40/*
  41 * Many sysemu-only helpers are not reachable for user-only.
  42 * Define stub generators here, so that we need not either sprinkle
  43 * ifdefs through the translator, nor provide the helper function.
  44 */
  45#define STUB_HELPER(NAME, ...) \
  46    static inline void gen_helper_##NAME(__VA_ARGS__) \
  47    { g_assert_not_reached(); }
  48
  49#ifdef CONFIG_USER_ONLY
  50STUB_HELPER(cache, TCGv_env env, TCGv val, TCGv_i32 reg)
  51#endif
  52
  53enum {
  54    /* indirect opcode tables */
  55    OPC_SPECIAL  = (0x00 << 26),
  56    OPC_REGIMM   = (0x01 << 26),
  57    OPC_CP0      = (0x10 << 26),
  58    OPC_CP2      = (0x12 << 26),
  59    OPC_CP3      = (0x13 << 26),
  60    OPC_SPECIAL2 = (0x1C << 26),
  61    OPC_SPECIAL3 = (0x1F << 26),
  62    /* arithmetic with immediate */
  63    OPC_ADDI     = (0x08 << 26),
  64    OPC_ADDIU    = (0x09 << 26),
  65    OPC_SLTI     = (0x0A << 26),
  66    OPC_SLTIU    = (0x0B << 26),
  67    /* logic with immediate */
  68    OPC_ANDI     = (0x0C << 26),
  69    OPC_ORI      = (0x0D << 26),
  70    OPC_XORI     = (0x0E << 26),
  71    OPC_LUI      = (0x0F << 26),
  72    /* arithmetic with immediate */
  73    OPC_DADDI    = (0x18 << 26),
  74    OPC_DADDIU   = (0x19 << 26),
  75    /* Jump and branches */
  76    OPC_J        = (0x02 << 26),
  77    OPC_JAL      = (0x03 << 26),
  78    OPC_BEQ      = (0x04 << 26),  /* Unconditional if rs = rt = 0 (B) */
  79    OPC_BEQL     = (0x14 << 26),
  80    OPC_BNE      = (0x05 << 26),
  81    OPC_BNEL     = (0x15 << 26),
  82    OPC_BLEZ     = (0x06 << 26),
  83    OPC_BLEZL    = (0x16 << 26),
  84    OPC_BGTZ     = (0x07 << 26),
  85    OPC_BGTZL    = (0x17 << 26),
  86    OPC_JALX     = (0x1D << 26),
  87    OPC_DAUI     = (0x1D << 26),
  88    /* Load and stores */
  89    OPC_LDL      = (0x1A << 26),
  90    OPC_LDR      = (0x1B << 26),
  91    OPC_LB       = (0x20 << 26),
  92    OPC_LH       = (0x21 << 26),
  93    OPC_LWL      = (0x22 << 26),
  94    OPC_LW       = (0x23 << 26),
  95    OPC_LWPC     = OPC_LW | 0x5,
  96    OPC_LBU      = (0x24 << 26),
  97    OPC_LHU      = (0x25 << 26),
  98    OPC_LWR      = (0x26 << 26),
  99    OPC_LWU      = (0x27 << 26),
 100    OPC_SB       = (0x28 << 26),
 101    OPC_SH       = (0x29 << 26),
 102    OPC_SWL      = (0x2A << 26),
 103    OPC_SW       = (0x2B << 26),
 104    OPC_SDL      = (0x2C << 26),
 105    OPC_SDR      = (0x2D << 26),
 106    OPC_SWR      = (0x2E << 26),
 107    OPC_LL       = (0x30 << 26),
 108    OPC_LLD      = (0x34 << 26),
 109    OPC_LD       = (0x37 << 26),
 110    OPC_LDPC     = OPC_LD | 0x5,
 111    OPC_SC       = (0x38 << 26),
 112    OPC_SCD      = (0x3C << 26),
 113    OPC_SD       = (0x3F << 26),
 114    /* Floating point load/store */
 115    OPC_LWC1     = (0x31 << 26),
 116    OPC_LWC2     = (0x32 << 26),
 117    OPC_LDC1     = (0x35 << 26),
 118    OPC_LDC2     = (0x36 << 26),
 119    OPC_SWC1     = (0x39 << 26),
 120    OPC_SWC2     = (0x3A << 26),
 121    OPC_SDC1     = (0x3D << 26),
 122    OPC_SDC2     = (0x3E << 26),
 123    /* Compact Branches */
 124    OPC_BLEZALC  = (0x06 << 26),
 125    OPC_BGEZALC  = (0x06 << 26),
 126    OPC_BGEUC    = (0x06 << 26),
 127    OPC_BGTZALC  = (0x07 << 26),
 128    OPC_BLTZALC  = (0x07 << 26),
 129    OPC_BLTUC    = (0x07 << 26),
 130    OPC_BOVC     = (0x08 << 26),
 131    OPC_BEQZALC  = (0x08 << 26),
 132    OPC_BEQC     = (0x08 << 26),
 133    OPC_BLEZC    = (0x16 << 26),
 134    OPC_BGEZC    = (0x16 << 26),
 135    OPC_BGEC     = (0x16 << 26),
 136    OPC_BGTZC    = (0x17 << 26),
 137    OPC_BLTZC    = (0x17 << 26),
 138    OPC_BLTC     = (0x17 << 26),
 139    OPC_BNVC     = (0x18 << 26),
 140    OPC_BNEZALC  = (0x18 << 26),
 141    OPC_BNEC     = (0x18 << 26),
 142    OPC_BC       = (0x32 << 26),
 143    OPC_BEQZC    = (0x36 << 26),
 144    OPC_JIC      = (0x36 << 26),
 145    OPC_BALC     = (0x3A << 26),
 146    OPC_BNEZC    = (0x3E << 26),
 147    OPC_JIALC    = (0x3E << 26),
 148    /* MDMX ASE specific */
 149    OPC_MDMX     = (0x1E << 26),
 150    /* Cache and prefetch */
 151    OPC_CACHE    = (0x2F << 26),
 152    OPC_PREF     = (0x33 << 26),
 153    /* PC-relative address computation / loads */
 154    OPC_PCREL    = (0x3B << 26),
 155};
 156
 157/* PC-relative address computation / loads  */
 158#define MASK_OPC_PCREL_TOP2BITS(op) (MASK_OP_MAJOR(op) | (op & (3 << 19)))
 159#define MASK_OPC_PCREL_TOP5BITS(op) (MASK_OP_MAJOR(op) | (op & (0x1f << 16)))
 160enum {
 161    /* Instructions determined by bits 19 and 20 */
 162    OPC_ADDIUPC = OPC_PCREL | (0 << 19),
 163    R6_OPC_LWPC = OPC_PCREL | (1 << 19),
 164    OPC_LWUPC   = OPC_PCREL | (2 << 19),
 165
 166    /* Instructions determined by bits 16 ... 20 */
 167    OPC_AUIPC   = OPC_PCREL | (0x1e << 16),
 168    OPC_ALUIPC  = OPC_PCREL | (0x1f << 16),
 169
 170    /* Other */
 171    R6_OPC_LDPC = OPC_PCREL | (6 << 18),
 172};
 173
 174/* MIPS special opcodes */
 175#define MASK_SPECIAL(op)            (MASK_OP_MAJOR(op) | (op & 0x3F))
 176
 177enum {
 178    /* Shifts */
 179    OPC_SLL      = 0x00 | OPC_SPECIAL,
 180    /* NOP is SLL r0, r0, 0   */
 181    /* SSNOP is SLL r0, r0, 1 */
 182    /* EHB is SLL r0, r0, 3 */
 183    OPC_SRL      = 0x02 | OPC_SPECIAL, /* also ROTR */
 184    OPC_ROTR     = OPC_SRL | (1 << 21),
 185    OPC_SRA      = 0x03 | OPC_SPECIAL,
 186    OPC_SLLV     = 0x04 | OPC_SPECIAL,
 187    OPC_SRLV     = 0x06 | OPC_SPECIAL, /* also ROTRV */
 188    OPC_ROTRV    = OPC_SRLV | (1 << 6),
 189    OPC_SRAV     = 0x07 | OPC_SPECIAL,
 190    OPC_DSLLV    = 0x14 | OPC_SPECIAL,
 191    OPC_DSRLV    = 0x16 | OPC_SPECIAL, /* also DROTRV */
 192    OPC_DROTRV   = OPC_DSRLV | (1 << 6),
 193    OPC_DSRAV    = 0x17 | OPC_SPECIAL,
 194    OPC_DSLL     = 0x38 | OPC_SPECIAL,
 195    OPC_DSRL     = 0x3A | OPC_SPECIAL, /* also DROTR */
 196    OPC_DROTR    = OPC_DSRL | (1 << 21),
 197    OPC_DSRA     = 0x3B | OPC_SPECIAL,
 198    OPC_DSLL32   = 0x3C | OPC_SPECIAL,
 199    OPC_DSRL32   = 0x3E | OPC_SPECIAL, /* also DROTR32 */
 200    OPC_DROTR32  = OPC_DSRL32 | (1 << 21),
 201    OPC_DSRA32   = 0x3F | OPC_SPECIAL,
 202    /* Multiplication / division */
 203    OPC_MULT     = 0x18 | OPC_SPECIAL,
 204    OPC_MULTU    = 0x19 | OPC_SPECIAL,
 205    OPC_DIV      = 0x1A | OPC_SPECIAL,
 206    OPC_DIVU     = 0x1B | OPC_SPECIAL,
 207    OPC_DMULT    = 0x1C | OPC_SPECIAL,
 208    OPC_DMULTU   = 0x1D | OPC_SPECIAL,
 209    OPC_DDIV     = 0x1E | OPC_SPECIAL,
 210    OPC_DDIVU    = 0x1F | OPC_SPECIAL,
 211
 212    /* 2 registers arithmetic / logic */
 213    OPC_ADD      = 0x20 | OPC_SPECIAL,
 214    OPC_ADDU     = 0x21 | OPC_SPECIAL,
 215    OPC_SUB      = 0x22 | OPC_SPECIAL,
 216    OPC_SUBU     = 0x23 | OPC_SPECIAL,
 217    OPC_AND      = 0x24 | OPC_SPECIAL,
 218    OPC_OR       = 0x25 | OPC_SPECIAL,
 219    OPC_XOR      = 0x26 | OPC_SPECIAL,
 220    OPC_NOR      = 0x27 | OPC_SPECIAL,
 221    OPC_SLT      = 0x2A | OPC_SPECIAL,
 222    OPC_SLTU     = 0x2B | OPC_SPECIAL,
 223    OPC_DADD     = 0x2C | OPC_SPECIAL,
 224    OPC_DADDU    = 0x2D | OPC_SPECIAL,
 225    OPC_DSUB     = 0x2E | OPC_SPECIAL,
 226    OPC_DSUBU    = 0x2F | OPC_SPECIAL,
 227    /* Jumps */
 228    OPC_JR       = 0x08 | OPC_SPECIAL, /* Also JR.HB */
 229    OPC_JALR     = 0x09 | OPC_SPECIAL, /* Also JALR.HB */
 230    /* Traps */
 231    OPC_TGE      = 0x30 | OPC_SPECIAL,
 232    OPC_TGEU     = 0x31 | OPC_SPECIAL,
 233    OPC_TLT      = 0x32 | OPC_SPECIAL,
 234    OPC_TLTU     = 0x33 | OPC_SPECIAL,
 235    OPC_TEQ      = 0x34 | OPC_SPECIAL,
 236    OPC_TNE      = 0x36 | OPC_SPECIAL,
 237    /* HI / LO registers load & stores */
 238    OPC_MFHI     = 0x10 | OPC_SPECIAL,
 239    OPC_MTHI     = 0x11 | OPC_SPECIAL,
 240    OPC_MFLO     = 0x12 | OPC_SPECIAL,
 241    OPC_MTLO     = 0x13 | OPC_SPECIAL,
 242    /* Conditional moves */
 243    OPC_MOVZ     = 0x0A | OPC_SPECIAL,
 244    OPC_MOVN     = 0x0B | OPC_SPECIAL,
 245
 246    OPC_SELEQZ   = 0x35 | OPC_SPECIAL,
 247    OPC_SELNEZ   = 0x37 | OPC_SPECIAL,
 248
 249    OPC_MOVCI    = 0x01 | OPC_SPECIAL,
 250
 251    /* Special */
 252    OPC_PMON     = 0x05 | OPC_SPECIAL, /* unofficial */
 253    OPC_SYSCALL  = 0x0C | OPC_SPECIAL,
 254    OPC_BREAK    = 0x0D | OPC_SPECIAL,
 255    OPC_SPIM     = 0x0E | OPC_SPECIAL, /* unofficial */
 256    OPC_SYNC     = 0x0F | OPC_SPECIAL,
 257
 258    OPC_SPECIAL28_RESERVED = 0x28 | OPC_SPECIAL,
 259    OPC_SPECIAL29_RESERVED = 0x29 | OPC_SPECIAL,
 260    OPC_SPECIAL39_RESERVED = 0x39 | OPC_SPECIAL,
 261    OPC_SPECIAL3D_RESERVED = 0x3D | OPC_SPECIAL,
 262};
 263
 264/*
 265 * R6 Multiply and Divide instructions have the same opcode
 266 * and function field as legacy OPC_MULT[U]/OPC_DIV[U]
 267 */
 268#define MASK_R6_MULDIV(op)          (MASK_SPECIAL(op) | (op & (0x7ff)))
 269
 270enum {
 271    R6_OPC_MUL   = OPC_MULT  | (2 << 6),
 272    R6_OPC_MUH   = OPC_MULT  | (3 << 6),
 273    R6_OPC_MULU  = OPC_MULTU | (2 << 6),
 274    R6_OPC_MUHU  = OPC_MULTU | (3 << 6),
 275    R6_OPC_DIV   = OPC_DIV   | (2 << 6),
 276    R6_OPC_MOD   = OPC_DIV   | (3 << 6),
 277    R6_OPC_DIVU  = OPC_DIVU  | (2 << 6),
 278    R6_OPC_MODU  = OPC_DIVU  | (3 << 6),
 279
 280    R6_OPC_DMUL   = OPC_DMULT  | (2 << 6),
 281    R6_OPC_DMUH   = OPC_DMULT  | (3 << 6),
 282    R6_OPC_DMULU  = OPC_DMULTU | (2 << 6),
 283    R6_OPC_DMUHU  = OPC_DMULTU | (3 << 6),
 284    R6_OPC_DDIV   = OPC_DDIV   | (2 << 6),
 285    R6_OPC_DMOD   = OPC_DDIV   | (3 << 6),
 286    R6_OPC_DDIVU  = OPC_DDIVU  | (2 << 6),
 287    R6_OPC_DMODU  = OPC_DDIVU  | (3 << 6),
 288
 289    R6_OPC_CLZ      = 0x10 | OPC_SPECIAL,
 290    R6_OPC_CLO      = 0x11 | OPC_SPECIAL,
 291    R6_OPC_DCLZ     = 0x12 | OPC_SPECIAL,
 292    R6_OPC_DCLO     = 0x13 | OPC_SPECIAL,
 293    R6_OPC_SDBBP    = 0x0e | OPC_SPECIAL,
 294};
 295
 296/* REGIMM (rt field) opcodes */
 297#define MASK_REGIMM(op)             (MASK_OP_MAJOR(op) | (op & (0x1F << 16)))
 298
 299enum {
 300    OPC_BLTZ     = (0x00 << 16) | OPC_REGIMM,
 301    OPC_BLTZL    = (0x02 << 16) | OPC_REGIMM,
 302    OPC_BGEZ     = (0x01 << 16) | OPC_REGIMM,
 303    OPC_BGEZL    = (0x03 << 16) | OPC_REGIMM,
 304    OPC_BLTZAL   = (0x10 << 16) | OPC_REGIMM,
 305    OPC_BLTZALL  = (0x12 << 16) | OPC_REGIMM,
 306    OPC_BGEZAL   = (0x11 << 16) | OPC_REGIMM,
 307    OPC_BGEZALL  = (0x13 << 16) | OPC_REGIMM,
 308    OPC_TGEI     = (0x08 << 16) | OPC_REGIMM,
 309    OPC_TGEIU    = (0x09 << 16) | OPC_REGIMM,
 310    OPC_TLTI     = (0x0A << 16) | OPC_REGIMM,
 311    OPC_TLTIU    = (0x0B << 16) | OPC_REGIMM,
 312    OPC_TEQI     = (0x0C << 16) | OPC_REGIMM,
 313    OPC_TNEI     = (0x0E << 16) | OPC_REGIMM,
 314    OPC_SIGRIE   = (0x17 << 16) | OPC_REGIMM,
 315    OPC_SYNCI    = (0x1F << 16) | OPC_REGIMM,
 316
 317    OPC_DAHI     = (0x06 << 16) | OPC_REGIMM,
 318    OPC_DATI     = (0x1e << 16) | OPC_REGIMM,
 319};
 320
 321/* Special2 opcodes */
 322#define MASK_SPECIAL2(op)           (MASK_OP_MAJOR(op) | (op & 0x3F))
 323
 324enum {
 325    /* Multiply & xxx operations */
 326    OPC_MADD     = 0x00 | OPC_SPECIAL2,
 327    OPC_MADDU    = 0x01 | OPC_SPECIAL2,
 328    OPC_MUL      = 0x02 | OPC_SPECIAL2,
 329    OPC_MSUB     = 0x04 | OPC_SPECIAL2,
 330    OPC_MSUBU    = 0x05 | OPC_SPECIAL2,
 331    /* Loongson 2F */
 332    OPC_MULT_G_2F   = 0x10 | OPC_SPECIAL2,
 333    OPC_DMULT_G_2F  = 0x11 | OPC_SPECIAL2,
 334    OPC_MULTU_G_2F  = 0x12 | OPC_SPECIAL2,
 335    OPC_DMULTU_G_2F = 0x13 | OPC_SPECIAL2,
 336    OPC_DIV_G_2F    = 0x14 | OPC_SPECIAL2,
 337    OPC_DDIV_G_2F   = 0x15 | OPC_SPECIAL2,
 338    OPC_DIVU_G_2F   = 0x16 | OPC_SPECIAL2,
 339    OPC_DDIVU_G_2F  = 0x17 | OPC_SPECIAL2,
 340    OPC_MOD_G_2F    = 0x1c | OPC_SPECIAL2,
 341    OPC_DMOD_G_2F   = 0x1d | OPC_SPECIAL2,
 342    OPC_MODU_G_2F   = 0x1e | OPC_SPECIAL2,
 343    OPC_DMODU_G_2F  = 0x1f | OPC_SPECIAL2,
 344    /* Misc */
 345    OPC_CLZ      = 0x20 | OPC_SPECIAL2,
 346    OPC_CLO      = 0x21 | OPC_SPECIAL2,
 347    OPC_DCLZ     = 0x24 | OPC_SPECIAL2,
 348    OPC_DCLO     = 0x25 | OPC_SPECIAL2,
 349    /* Special */
 350    OPC_SDBBP    = 0x3F | OPC_SPECIAL2,
 351};
 352
 353/* Special3 opcodes */
 354#define MASK_SPECIAL3(op)           (MASK_OP_MAJOR(op) | (op & 0x3F))
 355
 356enum {
 357    OPC_EXT      = 0x00 | OPC_SPECIAL3,
 358    OPC_DEXTM    = 0x01 | OPC_SPECIAL3,
 359    OPC_DEXTU    = 0x02 | OPC_SPECIAL3,
 360    OPC_DEXT     = 0x03 | OPC_SPECIAL3,
 361    OPC_INS      = 0x04 | OPC_SPECIAL3,
 362    OPC_DINSM    = 0x05 | OPC_SPECIAL3,
 363    OPC_DINSU    = 0x06 | OPC_SPECIAL3,
 364    OPC_DINS     = 0x07 | OPC_SPECIAL3,
 365    OPC_FORK     = 0x08 | OPC_SPECIAL3,
 366    OPC_YIELD    = 0x09 | OPC_SPECIAL3,
 367    OPC_BSHFL    = 0x20 | OPC_SPECIAL3,
 368    OPC_DBSHFL   = 0x24 | OPC_SPECIAL3,
 369    OPC_RDHWR    = 0x3B | OPC_SPECIAL3,
 370    OPC_GINV     = 0x3D | OPC_SPECIAL3,
 371
 372    /* Loongson 2E */
 373    OPC_MULT_G_2E   = 0x18 | OPC_SPECIAL3,
 374    OPC_MULTU_G_2E  = 0x19 | OPC_SPECIAL3,
 375    OPC_DIV_G_2E    = 0x1A | OPC_SPECIAL3,
 376    OPC_DIVU_G_2E   = 0x1B | OPC_SPECIAL3,
 377    OPC_DMULT_G_2E  = 0x1C | OPC_SPECIAL3,
 378    OPC_DMULTU_G_2E = 0x1D | OPC_SPECIAL3,
 379    OPC_DDIV_G_2E   = 0x1E | OPC_SPECIAL3,
 380    OPC_DDIVU_G_2E  = 0x1F | OPC_SPECIAL3,
 381    OPC_MOD_G_2E    = 0x22 | OPC_SPECIAL3,
 382    OPC_MODU_G_2E   = 0x23 | OPC_SPECIAL3,
 383    OPC_DMOD_G_2E   = 0x26 | OPC_SPECIAL3,
 384    OPC_DMODU_G_2E  = 0x27 | OPC_SPECIAL3,
 385
 386    /* MIPS DSP Load */
 387    OPC_LX_DSP         = 0x0A | OPC_SPECIAL3,
 388    /* MIPS DSP Arithmetic */
 389    OPC_ADDU_QB_DSP    = 0x10 | OPC_SPECIAL3,
 390    OPC_ADDU_OB_DSP    = 0x14 | OPC_SPECIAL3,
 391    OPC_ABSQ_S_PH_DSP  = 0x12 | OPC_SPECIAL3,
 392    OPC_ABSQ_S_QH_DSP  = 0x16 | OPC_SPECIAL3,
 393    /* OPC_ADDUH_QB_DSP is same as OPC_MULT_G_2E.  */
 394    /* OPC_ADDUH_QB_DSP   = 0x18 | OPC_SPECIAL3,  */
 395    OPC_CMPU_EQ_QB_DSP = 0x11 | OPC_SPECIAL3,
 396    OPC_CMPU_EQ_OB_DSP = 0x15 | OPC_SPECIAL3,
 397    /* MIPS DSP GPR-Based Shift Sub-class */
 398    OPC_SHLL_QB_DSP    = 0x13 | OPC_SPECIAL3,
 399    OPC_SHLL_OB_DSP    = 0x17 | OPC_SPECIAL3,
 400    /* MIPS DSP Multiply Sub-class insns */
 401    /* OPC_MUL_PH_DSP is same as OPC_ADDUH_QB_DSP.  */
 402    /* OPC_MUL_PH_DSP     = 0x18 | OPC_SPECIAL3,  */
 403    OPC_DPA_W_PH_DSP   = 0x30 | OPC_SPECIAL3,
 404    OPC_DPAQ_W_QH_DSP  = 0x34 | OPC_SPECIAL3,
 405    /* DSP Bit/Manipulation Sub-class */
 406    OPC_INSV_DSP       = 0x0C | OPC_SPECIAL3,
 407    OPC_DINSV_DSP      = 0x0D | OPC_SPECIAL3,
 408    /* MIPS DSP Append Sub-class */
 409    OPC_APPEND_DSP     = 0x31 | OPC_SPECIAL3,
 410    OPC_DAPPEND_DSP    = 0x35 | OPC_SPECIAL3,
 411    /* MIPS DSP Accumulator and DSPControl Access Sub-class */
 412    OPC_EXTR_W_DSP     = 0x38 | OPC_SPECIAL3,
 413    OPC_DEXTR_W_DSP    = 0x3C | OPC_SPECIAL3,
 414
 415    /* EVA */
 416    OPC_LWLE           = 0x19 | OPC_SPECIAL3,
 417    OPC_LWRE           = 0x1A | OPC_SPECIAL3,
 418    OPC_CACHEE         = 0x1B | OPC_SPECIAL3,
 419    OPC_SBE            = 0x1C | OPC_SPECIAL3,
 420    OPC_SHE            = 0x1D | OPC_SPECIAL3,
 421    OPC_SCE            = 0x1E | OPC_SPECIAL3,
 422    OPC_SWE            = 0x1F | OPC_SPECIAL3,
 423    OPC_SWLE           = 0x21 | OPC_SPECIAL3,
 424    OPC_SWRE           = 0x22 | OPC_SPECIAL3,
 425    OPC_PREFE          = 0x23 | OPC_SPECIAL3,
 426    OPC_LBUE           = 0x28 | OPC_SPECIAL3,
 427    OPC_LHUE           = 0x29 | OPC_SPECIAL3,
 428    OPC_LBE            = 0x2C | OPC_SPECIAL3,
 429    OPC_LHE            = 0x2D | OPC_SPECIAL3,
 430    OPC_LLE            = 0x2E | OPC_SPECIAL3,
 431    OPC_LWE            = 0x2F | OPC_SPECIAL3,
 432
 433    /* R6 */
 434    R6_OPC_PREF        = 0x35 | OPC_SPECIAL3,
 435    R6_OPC_CACHE       = 0x25 | OPC_SPECIAL3,
 436    R6_OPC_LL          = 0x36 | OPC_SPECIAL3,
 437    R6_OPC_SC          = 0x26 | OPC_SPECIAL3,
 438    R6_OPC_LLD         = 0x37 | OPC_SPECIAL3,
 439    R6_OPC_SCD         = 0x27 | OPC_SPECIAL3,
 440};
 441
 442/* Loongson EXT load/store quad word opcodes */
 443#define MASK_LOONGSON_GSLSQ(op)           (MASK_OP_MAJOR(op) | (op & 0x8020))
 444enum {
 445    OPC_GSLQ        = 0x0020 | OPC_LWC2,
 446    OPC_GSLQC1      = 0x8020 | OPC_LWC2,
 447    OPC_GSSHFL      = OPC_LWC2,
 448    OPC_GSSQ        = 0x0020 | OPC_SWC2,
 449    OPC_GSSQC1      = 0x8020 | OPC_SWC2,
 450    OPC_GSSHFS      = OPC_SWC2,
 451};
 452
 453/* Loongson EXT shifted load/store opcodes */
 454#define MASK_LOONGSON_GSSHFLS(op)         (MASK_OP_MAJOR(op) | (op & 0xc03f))
 455enum {
 456    OPC_GSLWLC1     = 0x4 | OPC_GSSHFL,
 457    OPC_GSLWRC1     = 0x5 | OPC_GSSHFL,
 458    OPC_GSLDLC1     = 0x6 | OPC_GSSHFL,
 459    OPC_GSLDRC1     = 0x7 | OPC_GSSHFL,
 460    OPC_GSSWLC1     = 0x4 | OPC_GSSHFS,
 461    OPC_GSSWRC1     = 0x5 | OPC_GSSHFS,
 462    OPC_GSSDLC1     = 0x6 | OPC_GSSHFS,
 463    OPC_GSSDRC1     = 0x7 | OPC_GSSHFS,
 464};
 465
 466/* Loongson EXT LDC2/SDC2 opcodes */
 467#define MASK_LOONGSON_LSDC2(op)           (MASK_OP_MAJOR(op) | (op & 0x7))
 468
 469enum {
 470    OPC_GSLBX      = 0x0 | OPC_LDC2,
 471    OPC_GSLHX      = 0x1 | OPC_LDC2,
 472    OPC_GSLWX      = 0x2 | OPC_LDC2,
 473    OPC_GSLDX      = 0x3 | OPC_LDC2,
 474    OPC_GSLWXC1    = 0x6 | OPC_LDC2,
 475    OPC_GSLDXC1    = 0x7 | OPC_LDC2,
 476    OPC_GSSBX      = 0x0 | OPC_SDC2,
 477    OPC_GSSHX      = 0x1 | OPC_SDC2,
 478    OPC_GSSWX      = 0x2 | OPC_SDC2,
 479    OPC_GSSDX      = 0x3 | OPC_SDC2,
 480    OPC_GSSWXC1    = 0x6 | OPC_SDC2,
 481    OPC_GSSDXC1    = 0x7 | OPC_SDC2,
 482};
 483
 484/* BSHFL opcodes */
 485#define MASK_BSHFL(op)              (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
 486
 487enum {
 488    OPC_WSBH      = (0x02 << 6) | OPC_BSHFL,
 489    OPC_SEB       = (0x10 << 6) | OPC_BSHFL,
 490    OPC_SEH       = (0x18 << 6) | OPC_BSHFL,
 491    OPC_ALIGN     = (0x08 << 6) | OPC_BSHFL, /* 010.bp (010.00 to 010.11) */
 492    OPC_ALIGN_1   = (0x09 << 6) | OPC_BSHFL,
 493    OPC_ALIGN_2   = (0x0A << 6) | OPC_BSHFL,
 494    OPC_ALIGN_3   = (0x0B << 6) | OPC_BSHFL,
 495    OPC_BITSWAP   = (0x00 << 6) | OPC_BSHFL  /* 00000 */
 496};
 497
 498/* DBSHFL opcodes */
 499#define MASK_DBSHFL(op)             (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
 500
 501enum {
 502    OPC_DSBH       = (0x02 << 6) | OPC_DBSHFL,
 503    OPC_DSHD       = (0x05 << 6) | OPC_DBSHFL,
 504    OPC_DALIGN     = (0x08 << 6) | OPC_DBSHFL, /* 01.bp (01.000 to 01.111) */
 505    OPC_DALIGN_1   = (0x09 << 6) | OPC_DBSHFL,
 506    OPC_DALIGN_2   = (0x0A << 6) | OPC_DBSHFL,
 507    OPC_DALIGN_3   = (0x0B << 6) | OPC_DBSHFL,
 508    OPC_DALIGN_4   = (0x0C << 6) | OPC_DBSHFL,
 509    OPC_DALIGN_5   = (0x0D << 6) | OPC_DBSHFL,
 510    OPC_DALIGN_6   = (0x0E << 6) | OPC_DBSHFL,
 511    OPC_DALIGN_7   = (0x0F << 6) | OPC_DBSHFL,
 512    OPC_DBITSWAP   = (0x00 << 6) | OPC_DBSHFL, /* 00000 */
 513};
 514
 515/* MIPS DSP REGIMM opcodes */
 516enum {
 517    OPC_BPOSGE32 = (0x1C << 16) | OPC_REGIMM,
 518    OPC_BPOSGE64 = (0x1D << 16) | OPC_REGIMM,
 519};
 520
 521#define MASK_LX(op)                 (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
 522/* MIPS DSP Load */
 523enum {
 524    OPC_LBUX = (0x06 << 6) | OPC_LX_DSP,
 525    OPC_LHX  = (0x04 << 6) | OPC_LX_DSP,
 526    OPC_LWX  = (0x00 << 6) | OPC_LX_DSP,
 527    OPC_LDX = (0x08 << 6) | OPC_LX_DSP,
 528};
 529
 530#define MASK_ADDU_QB(op)            (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
 531enum {
 532    /* MIPS DSP Arithmetic Sub-class */
 533    OPC_ADDQ_PH        = (0x0A << 6) | OPC_ADDU_QB_DSP,
 534    OPC_ADDQ_S_PH      = (0x0E << 6) | OPC_ADDU_QB_DSP,
 535    OPC_ADDQ_S_W       = (0x16 << 6) | OPC_ADDU_QB_DSP,
 536    OPC_ADDU_QB        = (0x00 << 6) | OPC_ADDU_QB_DSP,
 537    OPC_ADDU_S_QB      = (0x04 << 6) | OPC_ADDU_QB_DSP,
 538    OPC_ADDU_PH        = (0x08 << 6) | OPC_ADDU_QB_DSP,
 539    OPC_ADDU_S_PH      = (0x0C << 6) | OPC_ADDU_QB_DSP,
 540    OPC_SUBQ_PH        = (0x0B << 6) | OPC_ADDU_QB_DSP,
 541    OPC_SUBQ_S_PH      = (0x0F << 6) | OPC_ADDU_QB_DSP,
 542    OPC_SUBQ_S_W       = (0x17 << 6) | OPC_ADDU_QB_DSP,
 543    OPC_SUBU_QB        = (0x01 << 6) | OPC_ADDU_QB_DSP,
 544    OPC_SUBU_S_QB      = (0x05 << 6) | OPC_ADDU_QB_DSP,
 545    OPC_SUBU_PH        = (0x09 << 6) | OPC_ADDU_QB_DSP,
 546    OPC_SUBU_S_PH      = (0x0D << 6) | OPC_ADDU_QB_DSP,
 547    OPC_ADDSC          = (0x10 << 6) | OPC_ADDU_QB_DSP,
 548    OPC_ADDWC          = (0x11 << 6) | OPC_ADDU_QB_DSP,
 549    OPC_MODSUB         = (0x12 << 6) | OPC_ADDU_QB_DSP,
 550    OPC_RADDU_W_QB     = (0x14 << 6) | OPC_ADDU_QB_DSP,
 551    /* MIPS DSP Multiply Sub-class insns */
 552    OPC_MULEU_S_PH_QBL = (0x06 << 6) | OPC_ADDU_QB_DSP,
 553    OPC_MULEU_S_PH_QBR = (0x07 << 6) | OPC_ADDU_QB_DSP,
 554    OPC_MULQ_RS_PH     = (0x1F << 6) | OPC_ADDU_QB_DSP,
 555    OPC_MULEQ_S_W_PHL  = (0x1C << 6) | OPC_ADDU_QB_DSP,
 556    OPC_MULEQ_S_W_PHR  = (0x1D << 6) | OPC_ADDU_QB_DSP,
 557    OPC_MULQ_S_PH      = (0x1E << 6) | OPC_ADDU_QB_DSP,
 558};
 559
 560#define OPC_ADDUH_QB_DSP OPC_MULT_G_2E
 561#define MASK_ADDUH_QB(op)           (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
 562enum {
 563    /* MIPS DSP Arithmetic Sub-class */
 564    OPC_ADDUH_QB   = (0x00 << 6) | OPC_ADDUH_QB_DSP,
 565    OPC_ADDUH_R_QB = (0x02 << 6) | OPC_ADDUH_QB_DSP,
 566    OPC_ADDQH_PH   = (0x08 << 6) | OPC_ADDUH_QB_DSP,
 567    OPC_ADDQH_R_PH = (0x0A << 6) | OPC_ADDUH_QB_DSP,
 568    OPC_ADDQH_W    = (0x10 << 6) | OPC_ADDUH_QB_DSP,
 569    OPC_ADDQH_R_W  = (0x12 << 6) | OPC_ADDUH_QB_DSP,
 570    OPC_SUBUH_QB   = (0x01 << 6) | OPC_ADDUH_QB_DSP,
 571    OPC_SUBUH_R_QB = (0x03 << 6) | OPC_ADDUH_QB_DSP,
 572    OPC_SUBQH_PH   = (0x09 << 6) | OPC_ADDUH_QB_DSP,
 573    OPC_SUBQH_R_PH = (0x0B << 6) | OPC_ADDUH_QB_DSP,
 574    OPC_SUBQH_W    = (0x11 << 6) | OPC_ADDUH_QB_DSP,
 575    OPC_SUBQH_R_W  = (0x13 << 6) | OPC_ADDUH_QB_DSP,
 576    /* MIPS DSP Multiply Sub-class insns */
 577    OPC_MUL_PH     = (0x0C << 6) | OPC_ADDUH_QB_DSP,
 578    OPC_MUL_S_PH   = (0x0E << 6) | OPC_ADDUH_QB_DSP,
 579    OPC_MULQ_S_W   = (0x16 << 6) | OPC_ADDUH_QB_DSP,
 580    OPC_MULQ_RS_W  = (0x17 << 6) | OPC_ADDUH_QB_DSP,
 581};
 582
 583#define MASK_ABSQ_S_PH(op)          (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
 584enum {
 585    /* MIPS DSP Arithmetic Sub-class */
 586    OPC_ABSQ_S_QB       = (0x01 << 6) | OPC_ABSQ_S_PH_DSP,
 587    OPC_ABSQ_S_PH       = (0x09 << 6) | OPC_ABSQ_S_PH_DSP,
 588    OPC_ABSQ_S_W        = (0x11 << 6) | OPC_ABSQ_S_PH_DSP,
 589    OPC_PRECEQ_W_PHL    = (0x0C << 6) | OPC_ABSQ_S_PH_DSP,
 590    OPC_PRECEQ_W_PHR    = (0x0D << 6) | OPC_ABSQ_S_PH_DSP,
 591    OPC_PRECEQU_PH_QBL  = (0x04 << 6) | OPC_ABSQ_S_PH_DSP,
 592    OPC_PRECEQU_PH_QBR  = (0x05 << 6) | OPC_ABSQ_S_PH_DSP,
 593    OPC_PRECEQU_PH_QBLA = (0x06 << 6) | OPC_ABSQ_S_PH_DSP,
 594    OPC_PRECEQU_PH_QBRA = (0x07 << 6) | OPC_ABSQ_S_PH_DSP,
 595    OPC_PRECEU_PH_QBL   = (0x1C << 6) | OPC_ABSQ_S_PH_DSP,
 596    OPC_PRECEU_PH_QBR   = (0x1D << 6) | OPC_ABSQ_S_PH_DSP,
 597    OPC_PRECEU_PH_QBLA  = (0x1E << 6) | OPC_ABSQ_S_PH_DSP,
 598    OPC_PRECEU_PH_QBRA  = (0x1F << 6) | OPC_ABSQ_S_PH_DSP,
 599    /* DSP Bit/Manipulation Sub-class */
 600    OPC_BITREV          = (0x1B << 6) | OPC_ABSQ_S_PH_DSP,
 601    OPC_REPL_QB         = (0x02 << 6) | OPC_ABSQ_S_PH_DSP,
 602    OPC_REPLV_QB        = (0x03 << 6) | OPC_ABSQ_S_PH_DSP,
 603    OPC_REPL_PH         = (0x0A << 6) | OPC_ABSQ_S_PH_DSP,
 604    OPC_REPLV_PH        = (0x0B << 6) | OPC_ABSQ_S_PH_DSP,
 605};
 606
 607#define MASK_CMPU_EQ_QB(op)         (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
 608enum {
 609    /* MIPS DSP Arithmetic Sub-class */
 610    OPC_PRECR_QB_PH      = (0x0D << 6) | OPC_CMPU_EQ_QB_DSP,
 611    OPC_PRECRQ_QB_PH     = (0x0C << 6) | OPC_CMPU_EQ_QB_DSP,
 612    OPC_PRECR_SRA_PH_W   = (0x1E << 6) | OPC_CMPU_EQ_QB_DSP,
 613    OPC_PRECR_SRA_R_PH_W = (0x1F << 6) | OPC_CMPU_EQ_QB_DSP,
 614    OPC_PRECRQ_PH_W      = (0x14 << 6) | OPC_CMPU_EQ_QB_DSP,
 615    OPC_PRECRQ_RS_PH_W   = (0x15 << 6) | OPC_CMPU_EQ_QB_DSP,
 616    OPC_PRECRQU_S_QB_PH  = (0x0F << 6) | OPC_CMPU_EQ_QB_DSP,
 617    /* DSP Compare-Pick Sub-class */
 618    OPC_CMPU_EQ_QB       = (0x00 << 6) | OPC_CMPU_EQ_QB_DSP,
 619    OPC_CMPU_LT_QB       = (0x01 << 6) | OPC_CMPU_EQ_QB_DSP,
 620    OPC_CMPU_LE_QB       = (0x02 << 6) | OPC_CMPU_EQ_QB_DSP,
 621    OPC_CMPGU_EQ_QB      = (0x04 << 6) | OPC_CMPU_EQ_QB_DSP,
 622    OPC_CMPGU_LT_QB      = (0x05 << 6) | OPC_CMPU_EQ_QB_DSP,
 623    OPC_CMPGU_LE_QB      = (0x06 << 6) | OPC_CMPU_EQ_QB_DSP,
 624    OPC_CMPGDU_EQ_QB     = (0x18 << 6) | OPC_CMPU_EQ_QB_DSP,
 625    OPC_CMPGDU_LT_QB     = (0x19 << 6) | OPC_CMPU_EQ_QB_DSP,
 626    OPC_CMPGDU_LE_QB     = (0x1A << 6) | OPC_CMPU_EQ_QB_DSP,
 627    OPC_CMP_EQ_PH        = (0x08 << 6) | OPC_CMPU_EQ_QB_DSP,
 628    OPC_CMP_LT_PH        = (0x09 << 6) | OPC_CMPU_EQ_QB_DSP,
 629    OPC_CMP_LE_PH        = (0x0A << 6) | OPC_CMPU_EQ_QB_DSP,
 630    OPC_PICK_QB          = (0x03 << 6) | OPC_CMPU_EQ_QB_DSP,
 631    OPC_PICK_PH          = (0x0B << 6) | OPC_CMPU_EQ_QB_DSP,
 632    OPC_PACKRL_PH        = (0x0E << 6) | OPC_CMPU_EQ_QB_DSP,
 633};
 634
 635#define MASK_SHLL_QB(op)            (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
 636enum {
 637    /* MIPS DSP GPR-Based Shift Sub-class */
 638    OPC_SHLL_QB    = (0x00 << 6) | OPC_SHLL_QB_DSP,
 639    OPC_SHLLV_QB   = (0x02 << 6) | OPC_SHLL_QB_DSP,
 640    OPC_SHLL_PH    = (0x08 << 6) | OPC_SHLL_QB_DSP,
 641    OPC_SHLLV_PH   = (0x0A << 6) | OPC_SHLL_QB_DSP,
 642    OPC_SHLL_S_PH  = (0x0C << 6) | OPC_SHLL_QB_DSP,
 643    OPC_SHLLV_S_PH = (0x0E << 6) | OPC_SHLL_QB_DSP,
 644    OPC_SHLL_S_W   = (0x14 << 6) | OPC_SHLL_QB_DSP,
 645    OPC_SHLLV_S_W  = (0x16 << 6) | OPC_SHLL_QB_DSP,
 646    OPC_SHRL_QB    = (0x01 << 6) | OPC_SHLL_QB_DSP,
 647    OPC_SHRLV_QB   = (0x03 << 6) | OPC_SHLL_QB_DSP,
 648    OPC_SHRL_PH    = (0x19 << 6) | OPC_SHLL_QB_DSP,
 649    OPC_SHRLV_PH   = (0x1B << 6) | OPC_SHLL_QB_DSP,
 650    OPC_SHRA_QB    = (0x04 << 6) | OPC_SHLL_QB_DSP,
 651    OPC_SHRA_R_QB  = (0x05 << 6) | OPC_SHLL_QB_DSP,
 652    OPC_SHRAV_QB   = (0x06 << 6) | OPC_SHLL_QB_DSP,
 653    OPC_SHRAV_R_QB = (0x07 << 6) | OPC_SHLL_QB_DSP,
 654    OPC_SHRA_PH    = (0x09 << 6) | OPC_SHLL_QB_DSP,
 655    OPC_SHRAV_PH   = (0x0B << 6) | OPC_SHLL_QB_DSP,
 656    OPC_SHRA_R_PH  = (0x0D << 6) | OPC_SHLL_QB_DSP,
 657    OPC_SHRAV_R_PH = (0x0F << 6) | OPC_SHLL_QB_DSP,
 658    OPC_SHRA_R_W   = (0x15 << 6) | OPC_SHLL_QB_DSP,
 659    OPC_SHRAV_R_W  = (0x17 << 6) | OPC_SHLL_QB_DSP,
 660};
 661
 662#define MASK_DPA_W_PH(op)           (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
 663enum {
 664    /* MIPS DSP Multiply Sub-class insns */
 665    OPC_DPAU_H_QBL    = (0x03 << 6) | OPC_DPA_W_PH_DSP,
 666    OPC_DPAU_H_QBR    = (0x07 << 6) | OPC_DPA_W_PH_DSP,
 667    OPC_DPSU_H_QBL    = (0x0B << 6) | OPC_DPA_W_PH_DSP,
 668    OPC_DPSU_H_QBR    = (0x0F << 6) | OPC_DPA_W_PH_DSP,
 669    OPC_DPA_W_PH      = (0x00 << 6) | OPC_DPA_W_PH_DSP,
 670    OPC_DPAX_W_PH     = (0x08 << 6) | OPC_DPA_W_PH_DSP,
 671    OPC_DPAQ_S_W_PH   = (0x04 << 6) | OPC_DPA_W_PH_DSP,
 672    OPC_DPAQX_S_W_PH  = (0x18 << 6) | OPC_DPA_W_PH_DSP,
 673    OPC_DPAQX_SA_W_PH = (0x1A << 6) | OPC_DPA_W_PH_DSP,
 674    OPC_DPS_W_PH      = (0x01 << 6) | OPC_DPA_W_PH_DSP,
 675    OPC_DPSX_W_PH     = (0x09 << 6) | OPC_DPA_W_PH_DSP,
 676    OPC_DPSQ_S_W_PH   = (0x05 << 6) | OPC_DPA_W_PH_DSP,
 677    OPC_DPSQX_S_W_PH  = (0x19 << 6) | OPC_DPA_W_PH_DSP,
 678    OPC_DPSQX_SA_W_PH = (0x1B << 6) | OPC_DPA_W_PH_DSP,
 679    OPC_MULSAQ_S_W_PH = (0x06 << 6) | OPC_DPA_W_PH_DSP,
 680    OPC_DPAQ_SA_L_W   = (0x0C << 6) | OPC_DPA_W_PH_DSP,
 681    OPC_DPSQ_SA_L_W   = (0x0D << 6) | OPC_DPA_W_PH_DSP,
 682    OPC_MAQ_S_W_PHL   = (0x14 << 6) | OPC_DPA_W_PH_DSP,
 683    OPC_MAQ_S_W_PHR   = (0x16 << 6) | OPC_DPA_W_PH_DSP,
 684    OPC_MAQ_SA_W_PHL  = (0x10 << 6) | OPC_DPA_W_PH_DSP,
 685    OPC_MAQ_SA_W_PHR  = (0x12 << 6) | OPC_DPA_W_PH_DSP,
 686    OPC_MULSA_W_PH    = (0x02 << 6) | OPC_DPA_W_PH_DSP,
 687};
 688
 689#define MASK_INSV(op)               (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
 690enum {
 691    /* DSP Bit/Manipulation Sub-class */
 692    OPC_INSV = (0x00 << 6) | OPC_INSV_DSP,
 693};
 694
 695#define MASK_APPEND(op)             (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
 696enum {
 697    /* MIPS DSP Append Sub-class */
 698    OPC_APPEND  = (0x00 << 6) | OPC_APPEND_DSP,
 699    OPC_PREPEND = (0x01 << 6) | OPC_APPEND_DSP,
 700    OPC_BALIGN  = (0x10 << 6) | OPC_APPEND_DSP,
 701};
 702
 703#define MASK_EXTR_W(op)             (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
 704enum {
 705    /* MIPS DSP Accumulator and DSPControl Access Sub-class */
 706    OPC_EXTR_W     = (0x00 << 6) | OPC_EXTR_W_DSP,
 707    OPC_EXTR_R_W   = (0x04 << 6) | OPC_EXTR_W_DSP,
 708    OPC_EXTR_RS_W  = (0x06 << 6) | OPC_EXTR_W_DSP,
 709    OPC_EXTR_S_H   = (0x0E << 6) | OPC_EXTR_W_DSP,
 710    OPC_EXTRV_S_H  = (0x0F << 6) | OPC_EXTR_W_DSP,
 711    OPC_EXTRV_W    = (0x01 << 6) | OPC_EXTR_W_DSP,
 712    OPC_EXTRV_R_W  = (0x05 << 6) | OPC_EXTR_W_DSP,
 713    OPC_EXTRV_RS_W = (0x07 << 6) | OPC_EXTR_W_DSP,
 714    OPC_EXTP       = (0x02 << 6) | OPC_EXTR_W_DSP,
 715    OPC_EXTPV      = (0x03 << 6) | OPC_EXTR_W_DSP,
 716    OPC_EXTPDP     = (0x0A << 6) | OPC_EXTR_W_DSP,
 717    OPC_EXTPDPV    = (0x0B << 6) | OPC_EXTR_W_DSP,
 718    OPC_SHILO      = (0x1A << 6) | OPC_EXTR_W_DSP,
 719    OPC_SHILOV     = (0x1B << 6) | OPC_EXTR_W_DSP,
 720    OPC_MTHLIP     = (0x1F << 6) | OPC_EXTR_W_DSP,
 721    OPC_WRDSP      = (0x13 << 6) | OPC_EXTR_W_DSP,
 722    OPC_RDDSP      = (0x12 << 6) | OPC_EXTR_W_DSP,
 723};
 724
 725#define MASK_ABSQ_S_QH(op)          (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
 726enum {
 727    /* MIPS DSP Arithmetic Sub-class */
 728    OPC_PRECEQ_L_PWL    = (0x14 << 6) | OPC_ABSQ_S_QH_DSP,
 729    OPC_PRECEQ_L_PWR    = (0x15 << 6) | OPC_ABSQ_S_QH_DSP,
 730    OPC_PRECEQ_PW_QHL   = (0x0C << 6) | OPC_ABSQ_S_QH_DSP,
 731    OPC_PRECEQ_PW_QHR   = (0x0D << 6) | OPC_ABSQ_S_QH_DSP,
 732    OPC_PRECEQ_PW_QHLA  = (0x0E << 6) | OPC_ABSQ_S_QH_DSP,
 733    OPC_PRECEQ_PW_QHRA  = (0x0F << 6) | OPC_ABSQ_S_QH_DSP,
 734    OPC_PRECEQU_QH_OBL  = (0x04 << 6) | OPC_ABSQ_S_QH_DSP,
 735    OPC_PRECEQU_QH_OBR  = (0x05 << 6) | OPC_ABSQ_S_QH_DSP,
 736    OPC_PRECEQU_QH_OBLA = (0x06 << 6) | OPC_ABSQ_S_QH_DSP,
 737    OPC_PRECEQU_QH_OBRA = (0x07 << 6) | OPC_ABSQ_S_QH_DSP,
 738    OPC_PRECEU_QH_OBL   = (0x1C << 6) | OPC_ABSQ_S_QH_DSP,
 739    OPC_PRECEU_QH_OBR   = (0x1D << 6) | OPC_ABSQ_S_QH_DSP,
 740    OPC_PRECEU_QH_OBLA  = (0x1E << 6) | OPC_ABSQ_S_QH_DSP,
 741    OPC_PRECEU_QH_OBRA  = (0x1F << 6) | OPC_ABSQ_S_QH_DSP,
 742    OPC_ABSQ_S_OB       = (0x01 << 6) | OPC_ABSQ_S_QH_DSP,
 743    OPC_ABSQ_S_PW       = (0x11 << 6) | OPC_ABSQ_S_QH_DSP,
 744    OPC_ABSQ_S_QH       = (0x09 << 6) | OPC_ABSQ_S_QH_DSP,
 745    /* DSP Bit/Manipulation Sub-class */
 746    OPC_REPL_OB         = (0x02 << 6) | OPC_ABSQ_S_QH_DSP,
 747    OPC_REPL_PW         = (0x12 << 6) | OPC_ABSQ_S_QH_DSP,
 748    OPC_REPL_QH         = (0x0A << 6) | OPC_ABSQ_S_QH_DSP,
 749    OPC_REPLV_OB        = (0x03 << 6) | OPC_ABSQ_S_QH_DSP,
 750    OPC_REPLV_PW        = (0x13 << 6) | OPC_ABSQ_S_QH_DSP,
 751    OPC_REPLV_QH        = (0x0B << 6) | OPC_ABSQ_S_QH_DSP,
 752};
 753
 754#define MASK_ADDU_OB(op)            (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
 755enum {
 756    /* MIPS DSP Multiply Sub-class insns */
 757    OPC_MULEQ_S_PW_QHL = (0x1C << 6) | OPC_ADDU_OB_DSP,
 758    OPC_MULEQ_S_PW_QHR = (0x1D << 6) | OPC_ADDU_OB_DSP,
 759    OPC_MULEU_S_QH_OBL = (0x06 << 6) | OPC_ADDU_OB_DSP,
 760    OPC_MULEU_S_QH_OBR = (0x07 << 6) | OPC_ADDU_OB_DSP,
 761    OPC_MULQ_RS_QH     = (0x1F << 6) | OPC_ADDU_OB_DSP,
 762    /* MIPS DSP Arithmetic Sub-class */
 763    OPC_RADDU_L_OB     = (0x14 << 6) | OPC_ADDU_OB_DSP,
 764    OPC_SUBQ_PW        = (0x13 << 6) | OPC_ADDU_OB_DSP,
 765    OPC_SUBQ_S_PW      = (0x17 << 6) | OPC_ADDU_OB_DSP,
 766    OPC_SUBQ_QH        = (0x0B << 6) | OPC_ADDU_OB_DSP,
 767    OPC_SUBQ_S_QH      = (0x0F << 6) | OPC_ADDU_OB_DSP,
 768    OPC_SUBU_OB        = (0x01 << 6) | OPC_ADDU_OB_DSP,
 769    OPC_SUBU_S_OB      = (0x05 << 6) | OPC_ADDU_OB_DSP,
 770    OPC_SUBU_QH        = (0x09 << 6) | OPC_ADDU_OB_DSP,
 771    OPC_SUBU_S_QH      = (0x0D << 6) | OPC_ADDU_OB_DSP,
 772    OPC_SUBUH_OB       = (0x19 << 6) | OPC_ADDU_OB_DSP,
 773    OPC_SUBUH_R_OB     = (0x1B << 6) | OPC_ADDU_OB_DSP,
 774    OPC_ADDQ_PW        = (0x12 << 6) | OPC_ADDU_OB_DSP,
 775    OPC_ADDQ_S_PW      = (0x16 << 6) | OPC_ADDU_OB_DSP,
 776    OPC_ADDQ_QH        = (0x0A << 6) | OPC_ADDU_OB_DSP,
 777    OPC_ADDQ_S_QH      = (0x0E << 6) | OPC_ADDU_OB_DSP,
 778    OPC_ADDU_OB        = (0x00 << 6) | OPC_ADDU_OB_DSP,
 779    OPC_ADDU_S_OB      = (0x04 << 6) | OPC_ADDU_OB_DSP,
 780    OPC_ADDU_QH        = (0x08 << 6) | OPC_ADDU_OB_DSP,
 781    OPC_ADDU_S_QH      = (0x0C << 6) | OPC_ADDU_OB_DSP,
 782    OPC_ADDUH_OB       = (0x18 << 6) | OPC_ADDU_OB_DSP,
 783    OPC_ADDUH_R_OB     = (0x1A << 6) | OPC_ADDU_OB_DSP,
 784};
 785
 786#define MASK_CMPU_EQ_OB(op)         (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
 787enum {
 788    /* DSP Compare-Pick Sub-class */
 789    OPC_CMP_EQ_PW         = (0x10 << 6) | OPC_CMPU_EQ_OB_DSP,
 790    OPC_CMP_LT_PW         = (0x11 << 6) | OPC_CMPU_EQ_OB_DSP,
 791    OPC_CMP_LE_PW         = (0x12 << 6) | OPC_CMPU_EQ_OB_DSP,
 792    OPC_CMP_EQ_QH         = (0x08 << 6) | OPC_CMPU_EQ_OB_DSP,
 793    OPC_CMP_LT_QH         = (0x09 << 6) | OPC_CMPU_EQ_OB_DSP,
 794    OPC_CMP_LE_QH         = (0x0A << 6) | OPC_CMPU_EQ_OB_DSP,
 795    OPC_CMPGDU_EQ_OB      = (0x18 << 6) | OPC_CMPU_EQ_OB_DSP,
 796    OPC_CMPGDU_LT_OB      = (0x19 << 6) | OPC_CMPU_EQ_OB_DSP,
 797    OPC_CMPGDU_LE_OB      = (0x1A << 6) | OPC_CMPU_EQ_OB_DSP,
 798    OPC_CMPGU_EQ_OB       = (0x04 << 6) | OPC_CMPU_EQ_OB_DSP,
 799    OPC_CMPGU_LT_OB       = (0x05 << 6) | OPC_CMPU_EQ_OB_DSP,
 800    OPC_CMPGU_LE_OB       = (0x06 << 6) | OPC_CMPU_EQ_OB_DSP,
 801    OPC_CMPU_EQ_OB        = (0x00 << 6) | OPC_CMPU_EQ_OB_DSP,
 802    OPC_CMPU_LT_OB        = (0x01 << 6) | OPC_CMPU_EQ_OB_DSP,
 803    OPC_CMPU_LE_OB        = (0x02 << 6) | OPC_CMPU_EQ_OB_DSP,
 804    OPC_PACKRL_PW         = (0x0E << 6) | OPC_CMPU_EQ_OB_DSP,
 805    OPC_PICK_OB           = (0x03 << 6) | OPC_CMPU_EQ_OB_DSP,
 806    OPC_PICK_PW           = (0x13 << 6) | OPC_CMPU_EQ_OB_DSP,
 807    OPC_PICK_QH           = (0x0B << 6) | OPC_CMPU_EQ_OB_DSP,
 808    /* MIPS DSP Arithmetic Sub-class */
 809    OPC_PRECR_OB_QH       = (0x0D << 6) | OPC_CMPU_EQ_OB_DSP,
 810    OPC_PRECR_SRA_QH_PW   = (0x1E << 6) | OPC_CMPU_EQ_OB_DSP,
 811    OPC_PRECR_SRA_R_QH_PW = (0x1F << 6) | OPC_CMPU_EQ_OB_DSP,
 812    OPC_PRECRQ_OB_QH      = (0x0C << 6) | OPC_CMPU_EQ_OB_DSP,
 813    OPC_PRECRQ_PW_L       = (0x1C << 6) | OPC_CMPU_EQ_OB_DSP,
 814    OPC_PRECRQ_QH_PW      = (0x14 << 6) | OPC_CMPU_EQ_OB_DSP,
 815    OPC_PRECRQ_RS_QH_PW   = (0x15 << 6) | OPC_CMPU_EQ_OB_DSP,
 816    OPC_PRECRQU_S_OB_QH   = (0x0F << 6) | OPC_CMPU_EQ_OB_DSP,
 817};
 818
 819#define MASK_DAPPEND(op)            (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
 820enum {
 821    /* DSP Append Sub-class */
 822    OPC_DAPPEND  = (0x00 << 6) | OPC_DAPPEND_DSP,
 823    OPC_PREPENDD = (0x03 << 6) | OPC_DAPPEND_DSP,
 824    OPC_PREPENDW = (0x01 << 6) | OPC_DAPPEND_DSP,
 825    OPC_DBALIGN  = (0x10 << 6) | OPC_DAPPEND_DSP,
 826};
 827
 828#define MASK_DEXTR_W(op)            (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
 829enum {
 830    /* MIPS DSP Accumulator and DSPControl Access Sub-class */
 831    OPC_DMTHLIP     = (0x1F << 6) | OPC_DEXTR_W_DSP,
 832    OPC_DSHILO      = (0x1A << 6) | OPC_DEXTR_W_DSP,
 833    OPC_DEXTP       = (0x02 << 6) | OPC_DEXTR_W_DSP,
 834    OPC_DEXTPDP     = (0x0A << 6) | OPC_DEXTR_W_DSP,
 835    OPC_DEXTPDPV    = (0x0B << 6) | OPC_DEXTR_W_DSP,
 836    OPC_DEXTPV      = (0x03 << 6) | OPC_DEXTR_W_DSP,
 837    OPC_DEXTR_L     = (0x10 << 6) | OPC_DEXTR_W_DSP,
 838    OPC_DEXTR_R_L   = (0x14 << 6) | OPC_DEXTR_W_DSP,
 839    OPC_DEXTR_RS_L  = (0x16 << 6) | OPC_DEXTR_W_DSP,
 840    OPC_DEXTR_W     = (0x00 << 6) | OPC_DEXTR_W_DSP,
 841    OPC_DEXTR_R_W   = (0x04 << 6) | OPC_DEXTR_W_DSP,
 842    OPC_DEXTR_RS_W  = (0x06 << 6) | OPC_DEXTR_W_DSP,
 843    OPC_DEXTR_S_H   = (0x0E << 6) | OPC_DEXTR_W_DSP,
 844    OPC_DEXTRV_L    = (0x11 << 6) | OPC_DEXTR_W_DSP,
 845    OPC_DEXTRV_R_L  = (0x15 << 6) | OPC_DEXTR_W_DSP,
 846    OPC_DEXTRV_RS_L = (0x17 << 6) | OPC_DEXTR_W_DSP,
 847    OPC_DEXTRV_S_H  = (0x0F << 6) | OPC_DEXTR_W_DSP,
 848    OPC_DEXTRV_W    = (0x01 << 6) | OPC_DEXTR_W_DSP,
 849    OPC_DEXTRV_R_W  = (0x05 << 6) | OPC_DEXTR_W_DSP,
 850    OPC_DEXTRV_RS_W = (0x07 << 6) | OPC_DEXTR_W_DSP,
 851    OPC_DSHILOV     = (0x1B << 6) | OPC_DEXTR_W_DSP,
 852};
 853
 854#define MASK_DINSV(op)              (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
 855enum {
 856    /* DSP Bit/Manipulation Sub-class */
 857    OPC_DINSV = (0x00 << 6) | OPC_DINSV_DSP,
 858};
 859
 860#define MASK_DPAQ_W_QH(op)          (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
 861enum {
 862    /* MIPS DSP Multiply Sub-class insns */
 863    OPC_DMADD         = (0x19 << 6) | OPC_DPAQ_W_QH_DSP,
 864    OPC_DMADDU        = (0x1D << 6) | OPC_DPAQ_W_QH_DSP,
 865    OPC_DMSUB         = (0x1B << 6) | OPC_DPAQ_W_QH_DSP,
 866    OPC_DMSUBU        = (0x1F << 6) | OPC_DPAQ_W_QH_DSP,
 867    OPC_DPA_W_QH      = (0x00 << 6) | OPC_DPAQ_W_QH_DSP,
 868    OPC_DPAQ_S_W_QH   = (0x04 << 6) | OPC_DPAQ_W_QH_DSP,
 869    OPC_DPAQ_SA_L_PW  = (0x0C << 6) | OPC_DPAQ_W_QH_DSP,
 870    OPC_DPAU_H_OBL    = (0x03 << 6) | OPC_DPAQ_W_QH_DSP,
 871    OPC_DPAU_H_OBR    = (0x07 << 6) | OPC_DPAQ_W_QH_DSP,
 872    OPC_DPS_W_QH      = (0x01 << 6) | OPC_DPAQ_W_QH_DSP,
 873    OPC_DPSQ_S_W_QH   = (0x05 << 6) | OPC_DPAQ_W_QH_DSP,
 874    OPC_DPSQ_SA_L_PW  = (0x0D << 6) | OPC_DPAQ_W_QH_DSP,
 875    OPC_DPSU_H_OBL    = (0x0B << 6) | OPC_DPAQ_W_QH_DSP,
 876    OPC_DPSU_H_OBR    = (0x0F << 6) | OPC_DPAQ_W_QH_DSP,
 877    OPC_MAQ_S_L_PWL   = (0x1C << 6) | OPC_DPAQ_W_QH_DSP,
 878    OPC_MAQ_S_L_PWR   = (0x1E << 6) | OPC_DPAQ_W_QH_DSP,
 879    OPC_MAQ_S_W_QHLL  = (0x14 << 6) | OPC_DPAQ_W_QH_DSP,
 880    OPC_MAQ_SA_W_QHLL = (0x10 << 6) | OPC_DPAQ_W_QH_DSP,
 881    OPC_MAQ_S_W_QHLR  = (0x15 << 6) | OPC_DPAQ_W_QH_DSP,
 882    OPC_MAQ_SA_W_QHLR = (0x11 << 6) | OPC_DPAQ_W_QH_DSP,
 883    OPC_MAQ_S_W_QHRL  = (0x16 << 6) | OPC_DPAQ_W_QH_DSP,
 884    OPC_MAQ_SA_W_QHRL = (0x12 << 6) | OPC_DPAQ_W_QH_DSP,
 885    OPC_MAQ_S_W_QHRR  = (0x17 << 6) | OPC_DPAQ_W_QH_DSP,
 886    OPC_MAQ_SA_W_QHRR = (0x13 << 6) | OPC_DPAQ_W_QH_DSP,
 887    OPC_MULSAQ_S_L_PW = (0x0E << 6) | OPC_DPAQ_W_QH_DSP,
 888    OPC_MULSAQ_S_W_QH = (0x06 << 6) | OPC_DPAQ_W_QH_DSP,
 889};
 890
 891#define MASK_SHLL_OB(op)            (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
 892enum {
 893    /* MIPS DSP GPR-Based Shift Sub-class */
 894    OPC_SHLL_PW    = (0x10 << 6) | OPC_SHLL_OB_DSP,
 895    OPC_SHLL_S_PW  = (0x14 << 6) | OPC_SHLL_OB_DSP,
 896    OPC_SHLLV_OB   = (0x02 << 6) | OPC_SHLL_OB_DSP,
 897    OPC_SHLLV_PW   = (0x12 << 6) | OPC_SHLL_OB_DSP,
 898    OPC_SHLLV_S_PW = (0x16 << 6) | OPC_SHLL_OB_DSP,
 899    OPC_SHLLV_QH   = (0x0A << 6) | OPC_SHLL_OB_DSP,
 900    OPC_SHLLV_S_QH = (0x0E << 6) | OPC_SHLL_OB_DSP,
 901    OPC_SHRA_PW    = (0x11 << 6) | OPC_SHLL_OB_DSP,
 902    OPC_SHRA_R_PW  = (0x15 << 6) | OPC_SHLL_OB_DSP,
 903    OPC_SHRAV_OB   = (0x06 << 6) | OPC_SHLL_OB_DSP,
 904    OPC_SHRAV_R_OB = (0x07 << 6) | OPC_SHLL_OB_DSP,
 905    OPC_SHRAV_PW   = (0x13 << 6) | OPC_SHLL_OB_DSP,
 906    OPC_SHRAV_R_PW = (0x17 << 6) | OPC_SHLL_OB_DSP,
 907    OPC_SHRAV_QH   = (0x0B << 6) | OPC_SHLL_OB_DSP,
 908    OPC_SHRAV_R_QH = (0x0F << 6) | OPC_SHLL_OB_DSP,
 909    OPC_SHRLV_OB   = (0x03 << 6) | OPC_SHLL_OB_DSP,
 910    OPC_SHRLV_QH   = (0x1B << 6) | OPC_SHLL_OB_DSP,
 911    OPC_SHLL_OB    = (0x00 << 6) | OPC_SHLL_OB_DSP,
 912    OPC_SHLL_QH    = (0x08 << 6) | OPC_SHLL_OB_DSP,
 913    OPC_SHLL_S_QH  = (0x0C << 6) | OPC_SHLL_OB_DSP,
 914    OPC_SHRA_OB    = (0x04 << 6) | OPC_SHLL_OB_DSP,
 915    OPC_SHRA_R_OB  = (0x05 << 6) | OPC_SHLL_OB_DSP,
 916    OPC_SHRA_QH    = (0x09 << 6) | OPC_SHLL_OB_DSP,
 917    OPC_SHRA_R_QH  = (0x0D << 6) | OPC_SHLL_OB_DSP,
 918    OPC_SHRL_OB    = (0x01 << 6) | OPC_SHLL_OB_DSP,
 919    OPC_SHRL_QH    = (0x19 << 6) | OPC_SHLL_OB_DSP,
 920};
 921
 922/* Coprocessor 0 (rs field) */
 923#define MASK_CP0(op)                (MASK_OP_MAJOR(op) | (op & (0x1F << 21)))
 924
 925enum {
 926    OPC_MFC0     = (0x00 << 21) | OPC_CP0,
 927    OPC_DMFC0    = (0x01 << 21) | OPC_CP0,
 928    OPC_MFHC0    = (0x02 << 21) | OPC_CP0,
 929    OPC_MTC0     = (0x04 << 21) | OPC_CP0,
 930    OPC_DMTC0    = (0x05 << 21) | OPC_CP0,
 931    OPC_MTHC0    = (0x06 << 21) | OPC_CP0,
 932    OPC_MFTR     = (0x08 << 21) | OPC_CP0,
 933    OPC_RDPGPR   = (0x0A << 21) | OPC_CP0,
 934    OPC_MFMC0    = (0x0B << 21) | OPC_CP0,
 935    OPC_MTTR     = (0x0C << 21) | OPC_CP0,
 936    OPC_WRPGPR   = (0x0E << 21) | OPC_CP0,
 937    OPC_C0       = (0x10 << 21) | OPC_CP0,
 938    OPC_C0_1     = (0x11 << 21) | OPC_CP0,
 939    OPC_C0_2     = (0x12 << 21) | OPC_CP0,
 940    OPC_C0_3     = (0x13 << 21) | OPC_CP0,
 941    OPC_C0_4     = (0x14 << 21) | OPC_CP0,
 942    OPC_C0_5     = (0x15 << 21) | OPC_CP0,
 943    OPC_C0_6     = (0x16 << 21) | OPC_CP0,
 944    OPC_C0_7     = (0x17 << 21) | OPC_CP0,
 945    OPC_C0_8     = (0x18 << 21) | OPC_CP0,
 946    OPC_C0_9     = (0x19 << 21) | OPC_CP0,
 947    OPC_C0_A     = (0x1A << 21) | OPC_CP0,
 948    OPC_C0_B     = (0x1B << 21) | OPC_CP0,
 949    OPC_C0_C     = (0x1C << 21) | OPC_CP0,
 950    OPC_C0_D     = (0x1D << 21) | OPC_CP0,
 951    OPC_C0_E     = (0x1E << 21) | OPC_CP0,
 952    OPC_C0_F     = (0x1F << 21) | OPC_CP0,
 953};
 954
 955/* MFMC0 opcodes */
 956#define MASK_MFMC0(op)              (MASK_CP0(op) | (op & 0xFFFF))
 957
 958enum {
 959    OPC_DMT      = 0x01 | (0 << 5) | (0x0F << 6) | (0x01 << 11) | OPC_MFMC0,
 960    OPC_EMT      = 0x01 | (1 << 5) | (0x0F << 6) | (0x01 << 11) | OPC_MFMC0,
 961    OPC_DVPE     = 0x01 | (0 << 5) | OPC_MFMC0,
 962    OPC_EVPE     = 0x01 | (1 << 5) | OPC_MFMC0,
 963    OPC_DI       = (0 << 5) | (0x0C << 11) | OPC_MFMC0,
 964    OPC_EI       = (1 << 5) | (0x0C << 11) | OPC_MFMC0,
 965    OPC_DVP      = 0x04 | (0 << 3) | (1 << 5) | (0 << 11) | OPC_MFMC0,
 966    OPC_EVP      = 0x04 | (0 << 3) | (0 << 5) | (0 << 11) | OPC_MFMC0,
 967};
 968
 969/* Coprocessor 0 (with rs == C0) */
 970#define MASK_C0(op)                 (MASK_CP0(op) | (op & 0x3F))
 971
 972enum {
 973    OPC_TLBR     = 0x01 | OPC_C0,
 974    OPC_TLBWI    = 0x02 | OPC_C0,
 975    OPC_TLBINV   = 0x03 | OPC_C0,
 976    OPC_TLBINVF  = 0x04 | OPC_C0,
 977    OPC_TLBWR    = 0x06 | OPC_C0,
 978    OPC_TLBP     = 0x08 | OPC_C0,
 979    OPC_RFE      = 0x10 | OPC_C0,
 980    OPC_ERET     = 0x18 | OPC_C0,
 981    OPC_DERET    = 0x1F | OPC_C0,
 982    OPC_WAIT     = 0x20 | OPC_C0,
 983};
 984
 985#define MASK_CP2(op)                (MASK_OP_MAJOR(op) | (op & (0x1F << 21)))
 986
 987enum {
 988    OPC_MFC2    = (0x00 << 21) | OPC_CP2,
 989    OPC_DMFC2   = (0x01 << 21) | OPC_CP2,
 990    OPC_CFC2    = (0x02 << 21) | OPC_CP2,
 991    OPC_MFHC2   = (0x03 << 21) | OPC_CP2,
 992    OPC_MTC2    = (0x04 << 21) | OPC_CP2,
 993    OPC_DMTC2   = (0x05 << 21) | OPC_CP2,
 994    OPC_CTC2    = (0x06 << 21) | OPC_CP2,
 995    OPC_MTHC2   = (0x07 << 21) | OPC_CP2,
 996    OPC_BC2     = (0x08 << 21) | OPC_CP2,
 997    OPC_BC2EQZ  = (0x09 << 21) | OPC_CP2,
 998    OPC_BC2NEZ  = (0x0D << 21) | OPC_CP2,
 999};
1000
1001#define MASK_LMMI(op)    (MASK_OP_MAJOR(op) | (op & (0x1F << 21)) | (op & 0x1F))
1002
1003enum {
1004    OPC_PADDSH      = (24 << 21) | (0x00) | OPC_CP2,
1005    OPC_PADDUSH     = (25 << 21) | (0x00) | OPC_CP2,
1006    OPC_PADDH       = (26 << 21) | (0x00) | OPC_CP2,
1007    OPC_PADDW       = (27 << 21) | (0x00) | OPC_CP2,
1008    OPC_PADDSB      = (28 << 21) | (0x00) | OPC_CP2,
1009    OPC_PADDUSB     = (29 << 21) | (0x00) | OPC_CP2,
1010    OPC_PADDB       = (30 << 21) | (0x00) | OPC_CP2,
1011    OPC_PADDD       = (31 << 21) | (0x00) | OPC_CP2,
1012
1013    OPC_PSUBSH      = (24 << 21) | (0x01) | OPC_CP2,
1014    OPC_PSUBUSH     = (25 << 21) | (0x01) | OPC_CP2,
1015    OPC_PSUBH       = (26 << 21) | (0x01) | OPC_CP2,
1016    OPC_PSUBW       = (27 << 21) | (0x01) | OPC_CP2,
1017    OPC_PSUBSB      = (28 << 21) | (0x01) | OPC_CP2,
1018    OPC_PSUBUSB     = (29 << 21) | (0x01) | OPC_CP2,
1019    OPC_PSUBB       = (30 << 21) | (0x01) | OPC_CP2,
1020    OPC_PSUBD       = (31 << 21) | (0x01) | OPC_CP2,
1021
1022    OPC_PSHUFH      = (24 << 21) | (0x02) | OPC_CP2,
1023    OPC_PACKSSWH    = (25 << 21) | (0x02) | OPC_CP2,
1024    OPC_PACKSSHB    = (26 << 21) | (0x02) | OPC_CP2,
1025    OPC_PACKUSHB    = (27 << 21) | (0x02) | OPC_CP2,
1026    OPC_XOR_CP2     = (28 << 21) | (0x02) | OPC_CP2,
1027    OPC_NOR_CP2     = (29 << 21) | (0x02) | OPC_CP2,
1028    OPC_AND_CP2     = (30 << 21) | (0x02) | OPC_CP2,
1029    OPC_PANDN       = (31 << 21) | (0x02) | OPC_CP2,
1030
1031    OPC_PUNPCKLHW   = (24 << 21) | (0x03) | OPC_CP2,
1032    OPC_PUNPCKHHW   = (25 << 21) | (0x03) | OPC_CP2,
1033    OPC_PUNPCKLBH   = (26 << 21) | (0x03) | OPC_CP2,
1034    OPC_PUNPCKHBH   = (27 << 21) | (0x03) | OPC_CP2,
1035    OPC_PINSRH_0    = (28 << 21) | (0x03) | OPC_CP2,
1036    OPC_PINSRH_1    = (29 << 21) | (0x03) | OPC_CP2,
1037    OPC_PINSRH_2    = (30 << 21) | (0x03) | OPC_CP2,
1038    OPC_PINSRH_3    = (31 << 21) | (0x03) | OPC_CP2,
1039
1040    OPC_PAVGH       = (24 << 21) | (0x08) | OPC_CP2,
1041    OPC_PAVGB       = (25 << 21) | (0x08) | OPC_CP2,
1042    OPC_PMAXSH      = (26 << 21) | (0x08) | OPC_CP2,
1043    OPC_PMINSH      = (27 << 21) | (0x08) | OPC_CP2,
1044    OPC_PMAXUB      = (28 << 21) | (0x08) | OPC_CP2,
1045    OPC_PMINUB      = (29 << 21) | (0x08) | OPC_CP2,
1046
1047    OPC_PCMPEQW     = (24 << 21) | (0x09) | OPC_CP2,
1048    OPC_PCMPGTW     = (25 << 21) | (0x09) | OPC_CP2,
1049    OPC_PCMPEQH     = (26 << 21) | (0x09) | OPC_CP2,
1050    OPC_PCMPGTH     = (27 << 21) | (0x09) | OPC_CP2,
1051    OPC_PCMPEQB     = (28 << 21) | (0x09) | OPC_CP2,
1052    OPC_PCMPGTB     = (29 << 21) | (0x09) | OPC_CP2,
1053
1054    OPC_PSLLW       = (24 << 21) | (0x0A) | OPC_CP2,
1055    OPC_PSLLH       = (25 << 21) | (0x0A) | OPC_CP2,
1056    OPC_PMULLH      = (26 << 21) | (0x0A) | OPC_CP2,
1057    OPC_PMULHH      = (27 << 21) | (0x0A) | OPC_CP2,
1058    OPC_PMULUW      = (28 << 21) | (0x0A) | OPC_CP2,
1059    OPC_PMULHUH     = (29 << 21) | (0x0A) | OPC_CP2,
1060
1061    OPC_PSRLW       = (24 << 21) | (0x0B) | OPC_CP2,
1062    OPC_PSRLH       = (25 << 21) | (0x0B) | OPC_CP2,
1063    OPC_PSRAW       = (26 << 21) | (0x0B) | OPC_CP2,
1064    OPC_PSRAH       = (27 << 21) | (0x0B) | OPC_CP2,
1065    OPC_PUNPCKLWD   = (28 << 21) | (0x0B) | OPC_CP2,
1066    OPC_PUNPCKHWD   = (29 << 21) | (0x0B) | OPC_CP2,
1067
1068    OPC_ADDU_CP2    = (24 << 21) | (0x0C) | OPC_CP2,
1069    OPC_OR_CP2      = (25 << 21) | (0x0C) | OPC_CP2,
1070    OPC_ADD_CP2     = (26 << 21) | (0x0C) | OPC_CP2,
1071    OPC_DADD_CP2    = (27 << 21) | (0x0C) | OPC_CP2,
1072    OPC_SEQU_CP2    = (28 << 21) | (0x0C) | OPC_CP2,
1073    OPC_SEQ_CP2     = (29 << 21) | (0x0C) | OPC_CP2,
1074
1075    OPC_SUBU_CP2    = (24 << 21) | (0x0D) | OPC_CP2,
1076    OPC_PASUBUB     = (25 << 21) | (0x0D) | OPC_CP2,
1077    OPC_SUB_CP2     = (26 << 21) | (0x0D) | OPC_CP2,
1078    OPC_DSUB_CP2    = (27 << 21) | (0x0D) | OPC_CP2,
1079    OPC_SLTU_CP2    = (28 << 21) | (0x0D) | OPC_CP2,
1080    OPC_SLT_CP2     = (29 << 21) | (0x0D) | OPC_CP2,
1081
1082    OPC_SLL_CP2     = (24 << 21) | (0x0E) | OPC_CP2,
1083    OPC_DSLL_CP2    = (25 << 21) | (0x0E) | OPC_CP2,
1084    OPC_PEXTRH      = (26 << 21) | (0x0E) | OPC_CP2,
1085    OPC_PMADDHW     = (27 << 21) | (0x0E) | OPC_CP2,
1086    OPC_SLEU_CP2    = (28 << 21) | (0x0E) | OPC_CP2,
1087    OPC_SLE_CP2     = (29 << 21) | (0x0E) | OPC_CP2,
1088
1089    OPC_SRL_CP2     = (24 << 21) | (0x0F) | OPC_CP2,
1090    OPC_DSRL_CP2    = (25 << 21) | (0x0F) | OPC_CP2,
1091    OPC_SRA_CP2     = (26 << 21) | (0x0F) | OPC_CP2,
1092    OPC_DSRA_CP2    = (27 << 21) | (0x0F) | OPC_CP2,
1093    OPC_BIADD       = (28 << 21) | (0x0F) | OPC_CP2,
1094    OPC_PMOVMSKB    = (29 << 21) | (0x0F) | OPC_CP2,
1095};
1096
1097
1098#define MASK_CP3(op)                (MASK_OP_MAJOR(op) | (op & 0x3F))
1099
1100enum {
1101    OPC_LWXC1       = 0x00 | OPC_CP3,
1102    OPC_LDXC1       = 0x01 | OPC_CP3,
1103    OPC_LUXC1       = 0x05 | OPC_CP3,
1104    OPC_SWXC1       = 0x08 | OPC_CP3,
1105    OPC_SDXC1       = 0x09 | OPC_CP3,
1106    OPC_SUXC1       = 0x0D | OPC_CP3,
1107    OPC_PREFX       = 0x0F | OPC_CP3,
1108    OPC_ALNV_PS     = 0x1E | OPC_CP3,
1109    OPC_MADD_S      = 0x20 | OPC_CP3,
1110    OPC_MADD_D      = 0x21 | OPC_CP3,
1111    OPC_MADD_PS     = 0x26 | OPC_CP3,
1112    OPC_MSUB_S      = 0x28 | OPC_CP3,
1113    OPC_MSUB_D      = 0x29 | OPC_CP3,
1114    OPC_MSUB_PS     = 0x2E | OPC_CP3,
1115    OPC_NMADD_S     = 0x30 | OPC_CP3,
1116    OPC_NMADD_D     = 0x31 | OPC_CP3,
1117    OPC_NMADD_PS    = 0x36 | OPC_CP3,
1118    OPC_NMSUB_S     = 0x38 | OPC_CP3,
1119    OPC_NMSUB_D     = 0x39 | OPC_CP3,
1120    OPC_NMSUB_PS    = 0x3E | OPC_CP3,
1121};
1122
1123/*
1124 *     MMI (MultiMedia Instruction) encodings
1125 *     ======================================
1126 *
1127 * MMI instructions encoding table keys:
1128 *
1129 *     *   This code is reserved for future use. An attempt to execute it
1130 *         causes a Reserved Instruction exception.
1131 *     %   This code indicates an instruction class. The instruction word
1132 *         must be further decoded by examining additional tables that show
1133 *         the values for other instruction fields.
1134 *     #   This code is reserved for the unsupported instructions DMULT,
1135 *         DMULTU, DDIV, DDIVU, LL, LLD, SC, SCD, LWC2 and SWC2. An attempt
1136 *         to execute it causes a Reserved Instruction exception.
1137 *
1138 * MMI instructions encoded by opcode field (MMI, LQ, SQ):
1139 *
1140 *  31    26                                        0
1141 * +--------+----------------------------------------+
1142 * | opcode |                                        |
1143 * +--------+----------------------------------------+
1144 *
1145 *   opcode  bits 28..26
1146 *     bits |   0   |   1   |   2   |   3   |   4   |   5   |   6   |   7
1147 *   31..29 |  000  |  001  |  010  |  011  |  100  |  101  |  110  |  111
1148 *   -------+-------+-------+-------+-------+-------+-------+-------+-------
1149 *    0 000 |SPECIAL| REGIMM|   J   |  JAL  |  BEQ  |  BNE  |  BLEZ |  BGTZ
1150 *    1 001 |  ADDI | ADDIU |  SLTI | SLTIU |  ANDI |  ORI  |  XORI |  LUI
1151 *    2 010 |  COP0 |  COP1 |   *   |   *   |  BEQL |  BNEL | BLEZL | BGTZL
1152 *    3 011 | DADDI | DADDIU|  LDL  |  LDR  |  MMI% |   *   |   LQ  |   SQ
1153 *    4 100 |   LB  |   LH  |  LWL  |   LW  |  LBU  |  LHU  |  LWR  |  LWU
1154 *    5 101 |   SB  |   SH  |  SWL  |   SW  |  SDL  |  SDR  |  SWR  | CACHE
1155 *    6 110 |   #   |  LWC1 |   #   |  PREF |   #   |  LDC1 |   #   |   LD
1156 *    7 111 |   #   |  SWC1 |   #   |   *   |   #   |  SDC1 |   #   |   SD
1157 */
1158
1159enum {
1160    MMI_OPC_CLASS_MMI = 0x1C << 26,    /* Same as OPC_SPECIAL2 */
1161    MMI_OPC_SQ        = 0x1F << 26,    /* Same as OPC_SPECIAL3 */
1162};
1163
1164/*
1165 * MMI instructions with opcode field = MMI:
1166 *
1167 *  31    26                                 5      0
1168 * +--------+-------------------------------+--------+
1169 * |   MMI  |                               |function|
1170 * +--------+-------------------------------+--------+
1171 *
1172 * function  bits 2..0
1173 *     bits |   0   |   1   |   2   |   3   |   4   |   5   |   6   |   7
1174 *     5..3 |  000  |  001  |  010  |  011  |  100  |  101  |  110  |  111
1175 *   -------+-------+-------+-------+-------+-------+-------+-------+-------
1176 *    0 000 |  MADD | MADDU |   *   |   *   | PLZCW |   *   |   *   |   *
1177 *    1 001 | MMI0% | MMI2% |   *   |   *   |   *   |   *   |   *   |   *
1178 *    2 010 | MFHI1 | MTHI1 | MFLO1 | MTLO1 |   *   |   *   |   *   |   *
1179 *    3 011 | MULT1 | MULTU1|  DIV1 | DIVU1 |   *   |   *   |   *   |   *
1180 *    4 100 | MADD1 | MADDU1|   *   |   *   |   *   |   *   |   *   |   *
1181 *    5 101 | MMI1% | MMI3% |   *   |   *   |   *   |   *   |   *   |   *
1182 *    6 110 | PMFHL | PMTHL |   *   |   *   | PSLLH |   *   | PSRLH | PSRAH
1183 *    7 111 |   *   |   *   |   *   |   *   | PSLLW |   *   | PSRLW | PSRAW
1184 */
1185
1186#define MASK_MMI(op) (MASK_OP_MAJOR(op) | ((op) & 0x3F))
1187enum {
1188    MMI_OPC_MADD       = 0x00 | MMI_OPC_CLASS_MMI, /* Same as OPC_MADD */
1189    MMI_OPC_MADDU      = 0x01 | MMI_OPC_CLASS_MMI, /* Same as OPC_MADDU */
1190    MMI_OPC_MULT1      = 0x18 | MMI_OPC_CLASS_MMI, /* Same minor as OPC_MULT */
1191    MMI_OPC_MULTU1     = 0x19 | MMI_OPC_CLASS_MMI, /* Same min. as OPC_MULTU */
1192    MMI_OPC_DIV1       = 0x1A | MMI_OPC_CLASS_MMI, /* Same minor as OPC_DIV  */
1193    MMI_OPC_DIVU1      = 0x1B | MMI_OPC_CLASS_MMI, /* Same minor as OPC_DIVU */
1194    MMI_OPC_MADD1      = 0x20 | MMI_OPC_CLASS_MMI,
1195    MMI_OPC_MADDU1     = 0x21 | MMI_OPC_CLASS_MMI,
1196};
1197
1198/* global register indices */
1199TCGv cpu_gpr[32], cpu_PC;
1200/*
1201 * For CPUs using 128-bit GPR registers, we put the lower halves in cpu_gpr[])
1202 * and the upper halves in cpu_gpr_hi[].
1203 */
1204TCGv_i64 cpu_gpr_hi[32];
1205TCGv cpu_HI[MIPS_DSP_ACC], cpu_LO[MIPS_DSP_ACC];
1206static TCGv cpu_dspctrl, btarget;
1207TCGv bcond;
1208static TCGv cpu_lladdr, cpu_llval;
1209static TCGv_i32 hflags;
1210TCGv_i32 fpu_fcr0, fpu_fcr31;
1211TCGv_i64 fpu_f64[32];
1212
1213static const char regnames_HI[][4] = {
1214    "HI0", "HI1", "HI2", "HI3",
1215};
1216
1217static const char regnames_LO[][4] = {
1218    "LO0", "LO1", "LO2", "LO3",
1219};
1220
1221/* General purpose registers moves. */
1222void gen_load_gpr(TCGv t, int reg)
1223{
1224    assert(reg >= 0 && reg <= ARRAY_SIZE(cpu_gpr));
1225    if (reg == 0) {
1226        tcg_gen_movi_tl(t, 0);
1227    } else {
1228        tcg_gen_mov_tl(t, cpu_gpr[reg]);
1229    }
1230}
1231
1232void gen_store_gpr(TCGv t, int reg)
1233{
1234    assert(reg >= 0 && reg <= ARRAY_SIZE(cpu_gpr));
1235    if (reg != 0) {
1236        tcg_gen_mov_tl(cpu_gpr[reg], t);
1237    }
1238}
1239
1240#if defined(TARGET_MIPS64)
1241void gen_load_gpr_hi(TCGv_i64 t, int reg)
1242{
1243    assert(reg >= 0 && reg <= ARRAY_SIZE(cpu_gpr_hi));
1244    if (reg == 0) {
1245        tcg_gen_movi_i64(t, 0);
1246    } else {
1247        tcg_gen_mov_i64(t, cpu_gpr_hi[reg]);
1248    }
1249}
1250
1251void gen_store_gpr_hi(TCGv_i64 t, int reg)
1252{
1253    assert(reg >= 0 && reg <= ARRAY_SIZE(cpu_gpr_hi));
1254    if (reg != 0) {
1255        tcg_gen_mov_i64(cpu_gpr_hi[reg], t);
1256    }
1257}
1258#endif /* TARGET_MIPS64 */
1259
1260/* Moves to/from shadow registers. */
1261static inline void gen_load_srsgpr(int from, int to)
1262{
1263    TCGv t0 = tcg_temp_new();
1264
1265    if (from == 0) {
1266        tcg_gen_movi_tl(t0, 0);
1267    } else {
1268        TCGv_i32 t2 = tcg_temp_new_i32();
1269        TCGv_ptr addr = tcg_temp_new_ptr();
1270
1271        tcg_gen_ld_i32(t2, cpu_env, offsetof(CPUMIPSState, CP0_SRSCtl));
1272        tcg_gen_shri_i32(t2, t2, CP0SRSCtl_PSS);
1273        tcg_gen_andi_i32(t2, t2, 0xf);
1274        tcg_gen_muli_i32(t2, t2, sizeof(target_ulong) * 32);
1275        tcg_gen_ext_i32_ptr(addr, t2);
1276        tcg_gen_add_ptr(addr, cpu_env, addr);
1277
1278        tcg_gen_ld_tl(t0, addr, sizeof(target_ulong) * from);
1279    }
1280    gen_store_gpr(t0, to);
1281}
1282
1283static inline void gen_store_srsgpr(int from, int to)
1284{
1285    if (to != 0) {
1286        TCGv t0 = tcg_temp_new();
1287        TCGv_i32 t2 = tcg_temp_new_i32();
1288        TCGv_ptr addr = tcg_temp_new_ptr();
1289
1290        gen_load_gpr(t0, from);
1291        tcg_gen_ld_i32(t2, cpu_env, offsetof(CPUMIPSState, CP0_SRSCtl));
1292        tcg_gen_shri_i32(t2, t2, CP0SRSCtl_PSS);
1293        tcg_gen_andi_i32(t2, t2, 0xf);
1294        tcg_gen_muli_i32(t2, t2, sizeof(target_ulong) * 32);
1295        tcg_gen_ext_i32_ptr(addr, t2);
1296        tcg_gen_add_ptr(addr, cpu_env, addr);
1297
1298        tcg_gen_st_tl(t0, addr, sizeof(target_ulong) * to);
1299    }
1300}
1301
1302/* Tests */
1303static inline void gen_save_pc(target_ulong pc)
1304{
1305    tcg_gen_movi_tl(cpu_PC, pc);
1306}
1307
1308static inline void save_cpu_state(DisasContext *ctx, int do_save_pc)
1309{
1310    LOG_DISAS("hflags %08x saved %08x\n", ctx->hflags, ctx->saved_hflags);
1311    if (do_save_pc && ctx->base.pc_next != ctx->saved_pc) {
1312        gen_save_pc(ctx->base.pc_next);
1313        ctx->saved_pc = ctx->base.pc_next;
1314    }
1315    if (ctx->hflags != ctx->saved_hflags) {
1316        tcg_gen_movi_i32(hflags, ctx->hflags);
1317        ctx->saved_hflags = ctx->hflags;
1318        switch (ctx->hflags & MIPS_HFLAG_BMASK_BASE) {
1319        case MIPS_HFLAG_BR:
1320            break;
1321        case MIPS_HFLAG_BC:
1322        case MIPS_HFLAG_BL:
1323        case MIPS_HFLAG_B:
1324            tcg_gen_movi_tl(btarget, ctx->btarget);
1325            break;
1326        }
1327    }
1328}
1329
1330static inline void restore_cpu_state(CPUMIPSState *env, DisasContext *ctx)
1331{
1332    ctx->saved_hflags = ctx->hflags;
1333    switch (ctx->hflags & MIPS_HFLAG_BMASK_BASE) {
1334    case MIPS_HFLAG_BR:
1335        break;
1336    case MIPS_HFLAG_BC:
1337    case MIPS_HFLAG_BL:
1338    case MIPS_HFLAG_B:
1339        ctx->btarget = env->btarget;
1340        break;
1341    }
1342}
1343
1344void generate_exception_err(DisasContext *ctx, int excp, int err)
1345{
1346    save_cpu_state(ctx, 1);
1347    gen_helper_raise_exception_err(cpu_env, tcg_constant_i32(excp),
1348                                   tcg_constant_i32(err));
1349    ctx->base.is_jmp = DISAS_NORETURN;
1350}
1351
1352void generate_exception(DisasContext *ctx, int excp)
1353{
1354    gen_helper_raise_exception(cpu_env, tcg_constant_i32(excp));
1355}
1356
1357void generate_exception_end(DisasContext *ctx, int excp)
1358{
1359    generate_exception_err(ctx, excp, 0);
1360}
1361
1362void generate_exception_break(DisasContext *ctx, int code)
1363{
1364#ifdef CONFIG_USER_ONLY
1365    /* Pass the break code along to cpu_loop. */
1366    tcg_gen_st_i32(tcg_constant_i32(code), cpu_env,
1367                   offsetof(CPUMIPSState, error_code));
1368#endif
1369    generate_exception_end(ctx, EXCP_BREAK);
1370}
1371
1372void gen_reserved_instruction(DisasContext *ctx)
1373{
1374    generate_exception_end(ctx, EXCP_RI);
1375}
1376
1377/* Floating point register moves. */
1378void gen_load_fpr32(DisasContext *ctx, TCGv_i32 t, int reg)
1379{
1380    if (ctx->hflags & MIPS_HFLAG_FRE) {
1381        generate_exception(ctx, EXCP_RI);
1382    }
1383    tcg_gen_extrl_i64_i32(t, fpu_f64[reg]);
1384}
1385
1386void gen_store_fpr32(DisasContext *ctx, TCGv_i32 t, int reg)
1387{
1388    TCGv_i64 t64;
1389    if (ctx->hflags & MIPS_HFLAG_FRE) {
1390        generate_exception(ctx, EXCP_RI);
1391    }
1392    t64 = tcg_temp_new_i64();
1393    tcg_gen_extu_i32_i64(t64, t);
1394    tcg_gen_deposit_i64(fpu_f64[reg], fpu_f64[reg], t64, 0, 32);
1395}
1396
1397static void gen_load_fpr32h(DisasContext *ctx, TCGv_i32 t, int reg)
1398{
1399    if (ctx->hflags & MIPS_HFLAG_F64) {
1400        tcg_gen_extrh_i64_i32(t, fpu_f64[reg]);
1401    } else {
1402        gen_load_fpr32(ctx, t, reg | 1);
1403    }
1404}
1405
1406static void gen_store_fpr32h(DisasContext *ctx, TCGv_i32 t, int reg)
1407{
1408    if (ctx->hflags & MIPS_HFLAG_F64) {
1409        TCGv_i64 t64 = tcg_temp_new_i64();
1410        tcg_gen_extu_i32_i64(t64, t);
1411        tcg_gen_deposit_i64(fpu_f64[reg], fpu_f64[reg], t64, 32, 32);
1412    } else {
1413        gen_store_fpr32(ctx, t, reg | 1);
1414    }
1415}
1416
1417void gen_load_fpr64(DisasContext *ctx, TCGv_i64 t, int reg)
1418{
1419    if (ctx->hflags & MIPS_HFLAG_F64) {
1420        tcg_gen_mov_i64(t, fpu_f64[reg]);
1421    } else {
1422        tcg_gen_concat32_i64(t, fpu_f64[reg & ~1], fpu_f64[reg | 1]);
1423    }
1424}
1425
1426void gen_store_fpr64(DisasContext *ctx, TCGv_i64 t, int reg)
1427{
1428    if (ctx->hflags & MIPS_HFLAG_F64) {
1429        tcg_gen_mov_i64(fpu_f64[reg], t);
1430    } else {
1431        TCGv_i64 t0;
1432        tcg_gen_deposit_i64(fpu_f64[reg & ~1], fpu_f64[reg & ~1], t, 0, 32);
1433        t0 = tcg_temp_new_i64();
1434        tcg_gen_shri_i64(t0, t, 32);
1435        tcg_gen_deposit_i64(fpu_f64[reg | 1], fpu_f64[reg | 1], t0, 0, 32);
1436    }
1437}
1438
1439int get_fp_bit(int cc)
1440{
1441    if (cc) {
1442        return 24 + cc;
1443    } else {
1444        return 23;
1445    }
1446}
1447
1448/* Addresses computation */
1449void gen_op_addr_add(DisasContext *ctx, TCGv ret, TCGv arg0, TCGv arg1)
1450{
1451    tcg_gen_add_tl(ret, arg0, arg1);
1452
1453#if defined(TARGET_MIPS64)
1454    if (ctx->hflags & MIPS_HFLAG_AWRAP) {
1455        tcg_gen_ext32s_i64(ret, ret);
1456    }
1457#endif
1458}
1459
1460static inline void gen_op_addr_addi(DisasContext *ctx, TCGv ret, TCGv base,
1461                                    target_long ofs)
1462{
1463    tcg_gen_addi_tl(ret, base, ofs);
1464
1465#if defined(TARGET_MIPS64)
1466    if (ctx->hflags & MIPS_HFLAG_AWRAP) {
1467        tcg_gen_ext32s_i64(ret, ret);
1468    }
1469#endif
1470}
1471
1472/* Addresses computation (translation time) */
1473static target_long addr_add(DisasContext *ctx, target_long base,
1474                            target_long offset)
1475{
1476    target_long sum = base + offset;
1477
1478#if defined(TARGET_MIPS64)
1479    if (ctx->hflags & MIPS_HFLAG_AWRAP) {
1480        sum = (int32_t)sum;
1481    }
1482#endif
1483    return sum;
1484}
1485
1486/* Sign-extract the low 32-bits to a target_long.  */
1487void gen_move_low32(TCGv ret, TCGv_i64 arg)
1488{
1489#if defined(TARGET_MIPS64)
1490    tcg_gen_ext32s_i64(ret, arg);
1491#else
1492    tcg_gen_extrl_i64_i32(ret, arg);
1493#endif
1494}
1495
1496/* Sign-extract the high 32-bits to a target_long.  */
1497void gen_move_high32(TCGv ret, TCGv_i64 arg)
1498{
1499#if defined(TARGET_MIPS64)
1500    tcg_gen_sari_i64(ret, arg, 32);
1501#else
1502    tcg_gen_extrh_i64_i32(ret, arg);
1503#endif
1504}
1505
1506bool check_cp0_enabled(DisasContext *ctx)
1507{
1508    if (unlikely(!(ctx->hflags & MIPS_HFLAG_CP0))) {
1509        generate_exception_end(ctx, EXCP_CpU);
1510        return false;
1511    }
1512    return true;
1513}
1514
1515void check_cp1_enabled(DisasContext *ctx)
1516{
1517    if (unlikely(!(ctx->hflags & MIPS_HFLAG_FPU))) {
1518        generate_exception_err(ctx, EXCP_CpU, 1);
1519    }
1520}
1521
1522/*
1523 * Verify that the processor is running with COP1X instructions enabled.
1524 * This is associated with the nabla symbol in the MIPS32 and MIPS64
1525 * opcode tables.
1526 */
1527void check_cop1x(DisasContext *ctx)
1528{
1529    if (unlikely(!(ctx->hflags & MIPS_HFLAG_COP1X))) {
1530        gen_reserved_instruction(ctx);
1531    }
1532}
1533
1534/*
1535 * Verify that the processor is running with 64-bit floating-point
1536 * operations enabled.
1537 */
1538void check_cp1_64bitmode(DisasContext *ctx)
1539{
1540    if (unlikely(~ctx->hflags & MIPS_HFLAG_F64)) {
1541        gen_reserved_instruction(ctx);
1542    }
1543}
1544
1545/*
1546 * Verify if floating point register is valid; an operation is not defined
1547 * if bit 0 of any register specification is set and the FR bit in the
1548 * Status register equals zero, since the register numbers specify an
1549 * even-odd pair of adjacent coprocessor general registers. When the FR bit
1550 * in the Status register equals one, both even and odd register numbers
1551 * are valid. This limitation exists only for 64 bit wide (d,l,ps) registers.
1552 *
1553 * Multiple 64 bit wide registers can be checked by calling
1554 * gen_op_cp1_registers(freg1 | freg2 | ... | fregN);
1555 */
1556void check_cp1_registers(DisasContext *ctx, int regs)
1557{
1558    if (unlikely(!(ctx->hflags & MIPS_HFLAG_F64) && (regs & 1))) {
1559        gen_reserved_instruction(ctx);
1560    }
1561}
1562
1563/*
1564 * Verify that the processor is running with DSP instructions enabled.
1565 * This is enabled by CP0 Status register MX(24) bit.
1566 */
1567static inline void check_dsp(DisasContext *ctx)
1568{
1569    if (unlikely(!(ctx->hflags & MIPS_HFLAG_DSP))) {
1570        if (ctx->insn_flags & ASE_DSP) {
1571            generate_exception_end(ctx, EXCP_DSPDIS);
1572        } else {
1573            gen_reserved_instruction(ctx);
1574        }
1575    }
1576}
1577
1578static inline void check_dsp_r2(DisasContext *ctx)
1579{
1580    if (unlikely(!(ctx->hflags & MIPS_HFLAG_DSP_R2))) {
1581        if (ctx->insn_flags & ASE_DSP) {
1582            generate_exception_end(ctx, EXCP_DSPDIS);
1583        } else {
1584            gen_reserved_instruction(ctx);
1585        }
1586    }
1587}
1588
1589static inline void check_dsp_r3(DisasContext *ctx)
1590{
1591    if (unlikely(!(ctx->hflags & MIPS_HFLAG_DSP_R3))) {
1592        if (ctx->insn_flags & ASE_DSP) {
1593            generate_exception_end(ctx, EXCP_DSPDIS);
1594        } else {
1595            gen_reserved_instruction(ctx);
1596        }
1597    }
1598}
1599
1600/*
1601 * This code generates a "reserved instruction" exception if the
1602 * CPU does not support the instruction set corresponding to flags.
1603 */
1604void check_insn(DisasContext *ctx, uint64_t flags)
1605{
1606    if (unlikely(!(ctx->insn_flags & flags))) {
1607        gen_reserved_instruction(ctx);
1608    }
1609}
1610
1611/*
1612 * This code generates a "reserved instruction" exception if the
1613 * CPU has corresponding flag set which indicates that the instruction
1614 * has been removed.
1615 */
1616static inline void check_insn_opc_removed(DisasContext *ctx, uint64_t flags)
1617{
1618    if (unlikely(ctx->insn_flags & flags)) {
1619        gen_reserved_instruction(ctx);
1620    }
1621}
1622
1623/*
1624 * The Linux kernel traps certain reserved instruction exceptions to
1625 * emulate the corresponding instructions. QEMU is the kernel in user
1626 * mode, so those traps are emulated by accepting the instructions.
1627 *
1628 * A reserved instruction exception is generated for flagged CPUs if
1629 * QEMU runs in system mode.
1630 */
1631static inline void check_insn_opc_user_only(DisasContext *ctx, uint64_t flags)
1632{
1633#ifndef CONFIG_USER_ONLY
1634    check_insn_opc_removed(ctx, flags);
1635#endif
1636}
1637
1638/*
1639 * This code generates a "reserved instruction" exception if the
1640 * CPU does not support 64-bit paired-single (PS) floating point data type.
1641 */
1642static inline void check_ps(DisasContext *ctx)
1643{
1644    if (unlikely(!ctx->ps)) {
1645        generate_exception(ctx, EXCP_RI);
1646    }
1647    check_cp1_64bitmode(ctx);
1648}
1649
1650/*
1651 * This code generates a "reserved instruction" exception if cpu is not
1652 * 64-bit or 64-bit instructions are not enabled.
1653 */
1654void check_mips_64(DisasContext *ctx)
1655{
1656    if (unlikely((TARGET_LONG_BITS != 64) || !(ctx->hflags & MIPS_HFLAG_64))) {
1657        gen_reserved_instruction(ctx);
1658    }
1659}
1660
1661#ifndef CONFIG_USER_ONLY
1662static inline void check_mvh(DisasContext *ctx)
1663{
1664    if (unlikely(!ctx->mvh)) {
1665        generate_exception(ctx, EXCP_RI);
1666    }
1667}
1668#endif
1669
1670/*
1671 * This code generates a "reserved instruction" exception if the
1672 * Config5 XNP bit is set.
1673 */
1674static inline void check_xnp(DisasContext *ctx)
1675{
1676    if (unlikely(ctx->CP0_Config5 & (1 << CP0C5_XNP))) {
1677        gen_reserved_instruction(ctx);
1678    }
1679}
1680
1681#ifndef CONFIG_USER_ONLY
1682/*
1683 * This code generates a "reserved instruction" exception if the
1684 * Config3 PW bit is NOT set.
1685 */
1686static inline void check_pw(DisasContext *ctx)
1687{
1688    if (unlikely(!(ctx->CP0_Config3 & (1 << CP0C3_PW)))) {
1689        gen_reserved_instruction(ctx);
1690    }
1691}
1692#endif
1693
1694/*
1695 * This code generates a "reserved instruction" exception if the
1696 * Config3 MT bit is NOT set.
1697 */
1698static inline void check_mt(DisasContext *ctx)
1699{
1700    if (unlikely(!(ctx->CP0_Config3 & (1 << CP0C3_MT)))) {
1701        gen_reserved_instruction(ctx);
1702    }
1703}
1704
1705#ifndef CONFIG_USER_ONLY
1706/*
1707 * This code generates a "coprocessor unusable" exception if CP0 is not
1708 * available, and, if that is not the case, generates a "reserved instruction"
1709 * exception if the Config5 MT bit is NOT set. This is needed for availability
1710 * control of some of MT ASE instructions.
1711 */
1712static inline void check_cp0_mt(DisasContext *ctx)
1713{
1714    if (unlikely(!(ctx->hflags & MIPS_HFLAG_CP0))) {
1715        generate_exception_end(ctx, EXCP_CpU);
1716    } else {
1717        if (unlikely(!(ctx->CP0_Config3 & (1 << CP0C3_MT)))) {
1718            gen_reserved_instruction(ctx);
1719        }
1720    }
1721}
1722#endif
1723
1724/*
1725 * This code generates a "reserved instruction" exception if the
1726 * Config5 NMS bit is set.
1727 */
1728static inline void check_nms(DisasContext *ctx)
1729{
1730    if (unlikely(ctx->CP0_Config5 & (1 << CP0C5_NMS))) {
1731        gen_reserved_instruction(ctx);
1732    }
1733}
1734
1735/*
1736 * This code generates a "reserved instruction" exception if the
1737 * Config5 NMS bit is set, and Config1 DL, Config1 IL, Config2 SL,
1738 * Config2 TL, and Config5 L2C are unset.
1739 */
1740static inline void check_nms_dl_il_sl_tl_l2c(DisasContext *ctx)
1741{
1742    if (unlikely((ctx->CP0_Config5 & (1 << CP0C5_NMS)) &&
1743                 !(ctx->CP0_Config1 & (1 << CP0C1_DL)) &&
1744                 !(ctx->CP0_Config1 & (1 << CP0C1_IL)) &&
1745                 !(ctx->CP0_Config2 & (1 << CP0C2_SL)) &&
1746                 !(ctx->CP0_Config2 & (1 << CP0C2_TL)) &&
1747                 !(ctx->CP0_Config5 & (1 << CP0C5_L2C)))) {
1748        gen_reserved_instruction(ctx);
1749    }
1750}
1751
1752/*
1753 * This code generates a "reserved instruction" exception if the
1754 * Config5 EVA bit is NOT set.
1755 */
1756static inline void check_eva(DisasContext *ctx)
1757{
1758    if (unlikely(!(ctx->CP0_Config5 & (1 << CP0C5_EVA)))) {
1759        gen_reserved_instruction(ctx);
1760    }
1761}
1762
1763
1764/*
1765 * Define small wrappers for gen_load_fpr* so that we have a uniform
1766 * calling interface for 32 and 64-bit FPRs.  No sense in changing
1767 * all callers for gen_load_fpr32 when we need the CTX parameter for
1768 * this one use.
1769 */
1770#define gen_ldcmp_fpr32(ctx, x, y) gen_load_fpr32(ctx, x, y)
1771#define gen_ldcmp_fpr64(ctx, x, y) gen_load_fpr64(ctx, x, y)
1772#define FOP_CONDS(type, abs, fmt, ifmt, bits)                                 \
1773static inline void gen_cmp ## type ## _ ## fmt(DisasContext *ctx, int n,      \
1774                                               int ft, int fs, int cc)        \
1775{                                                                             \
1776    TCGv_i##bits fp0 = tcg_temp_new_i##bits();                                \
1777    TCGv_i##bits fp1 = tcg_temp_new_i##bits();                                \
1778    switch (ifmt) {                                                           \
1779    case FMT_PS:                                                              \
1780        check_ps(ctx);                                                        \
1781        break;                                                                \
1782    case FMT_D:                                                               \
1783        if (abs) {                                                            \
1784            check_cop1x(ctx);                                                 \
1785        }                                                                     \
1786        check_cp1_registers(ctx, fs | ft);                                    \
1787        break;                                                                \
1788    case FMT_S:                                                               \
1789        if (abs) {                                                            \
1790            check_cop1x(ctx);                                                 \
1791        }                                                                     \
1792        break;                                                                \
1793    }                                                                         \
1794    gen_ldcmp_fpr##bits(ctx, fp0, fs);                                        \
1795    gen_ldcmp_fpr##bits(ctx, fp1, ft);                                        \
1796    switch (n) {                                                              \
1797    case  0:                                                                  \
1798        gen_helper_0e2i(cmp ## type ## _ ## fmt ## _f, fp0, fp1, cc);         \
1799    break;                                                                    \
1800    case  1:                                                                  \
1801        gen_helper_0e2i(cmp ## type ## _ ## fmt ## _un, fp0, fp1, cc);        \
1802    break;                                                                    \
1803    case  2:                                                                  \
1804        gen_helper_0e2i(cmp ## type ## _ ## fmt ## _eq, fp0, fp1, cc);        \
1805    break;                                                                    \
1806    case  3:                                                                  \
1807        gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ueq, fp0, fp1, cc);       \
1808    break;                                                                    \
1809    case  4:                                                                  \
1810        gen_helper_0e2i(cmp ## type ## _ ## fmt ## _olt, fp0, fp1, cc);       \
1811    break;                                                                    \
1812    case  5:                                                                  \
1813        gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ult, fp0, fp1, cc);       \
1814    break;                                                                    \
1815    case  6:                                                                  \
1816        gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ole, fp0, fp1, cc);       \
1817    break;                                                                    \
1818    case  7:                                                                  \
1819        gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ule, fp0, fp1, cc);       \
1820    break;                                                                    \
1821    case  8:                                                                  \
1822        gen_helper_0e2i(cmp ## type ## _ ## fmt ## _sf, fp0, fp1, cc);        \
1823    break;                                                                    \
1824    case  9:                                                                  \
1825        gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ngle, fp0, fp1, cc);      \
1826    break;                                                                    \
1827    case 10:                                                                  \
1828        gen_helper_0e2i(cmp ## type ## _ ## fmt ## _seq, fp0, fp1, cc);       \
1829    break;                                                                    \
1830    case 11:                                                                  \
1831        gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ngl, fp0, fp1, cc);       \
1832    break;                                                                    \
1833    case 12:                                                                  \
1834        gen_helper_0e2i(cmp ## type ## _ ## fmt ## _lt, fp0, fp1, cc);        \
1835    break;                                                                    \
1836    case 13:                                                                  \
1837        gen_helper_0e2i(cmp ## type ## _ ## fmt ## _nge, fp0, fp1, cc);       \
1838    break;                                                                    \
1839    case 14:                                                                  \
1840        gen_helper_0e2i(cmp ## type ## _ ## fmt ## _le, fp0, fp1, cc);        \
1841    break;                                                                    \
1842    case 15:                                                                  \
1843        gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ngt, fp0, fp1, cc);       \
1844    break;                                                                    \
1845    default:                                                                  \
1846        abort();                                                              \
1847    }                                                                         \
1848}
1849
1850FOP_CONDS(, 0, d, FMT_D, 64)
1851FOP_CONDS(abs, 1, d, FMT_D, 64)
1852FOP_CONDS(, 0, s, FMT_S, 32)
1853FOP_CONDS(abs, 1, s, FMT_S, 32)
1854FOP_CONDS(, 0, ps, FMT_PS, 64)
1855FOP_CONDS(abs, 1, ps, FMT_PS, 64)
1856#undef FOP_CONDS
1857
1858#define FOP_CONDNS(fmt, ifmt, bits, STORE)                              \
1859static inline void gen_r6_cmp_ ## fmt(DisasContext *ctx, int n,         \
1860                                      int ft, int fs, int fd)           \
1861{                                                                       \
1862    TCGv_i ## bits fp0 = tcg_temp_new_i ## bits();                      \
1863    TCGv_i ## bits fp1 = tcg_temp_new_i ## bits();                      \
1864    if (ifmt == FMT_D) {                                                \
1865        check_cp1_registers(ctx, fs | ft | fd);                         \
1866    }                                                                   \
1867    gen_ldcmp_fpr ## bits(ctx, fp0, fs);                                \
1868    gen_ldcmp_fpr ## bits(ctx, fp1, ft);                                \
1869    switch (n) {                                                        \
1870    case  0:                                                            \
1871        gen_helper_r6_cmp_ ## fmt ## _af(fp0, cpu_env, fp0, fp1);       \
1872        break;                                                          \
1873    case  1:                                                            \
1874        gen_helper_r6_cmp_ ## fmt ## _un(fp0, cpu_env, fp0, fp1);       \
1875        break;                                                          \
1876    case  2:                                                            \
1877        gen_helper_r6_cmp_ ## fmt ## _eq(fp0, cpu_env, fp0, fp1);       \
1878        break;                                                          \
1879    case  3:                                                            \
1880        gen_helper_r6_cmp_ ## fmt ## _ueq(fp0, cpu_env, fp0, fp1);      \
1881        break;                                                          \
1882    case  4:                                                            \
1883        gen_helper_r6_cmp_ ## fmt ## _lt(fp0, cpu_env, fp0, fp1);       \
1884        break;                                                          \
1885    case  5:                                                            \
1886        gen_helper_r6_cmp_ ## fmt ## _ult(fp0, cpu_env, fp0, fp1);      \
1887        break;                                                          \
1888    case  6:                                                            \
1889        gen_helper_r6_cmp_ ## fmt ## _le(fp0, cpu_env, fp0, fp1);       \
1890        break;                                                          \
1891    case  7:                                                            \
1892        gen_helper_r6_cmp_ ## fmt ## _ule(fp0, cpu_env, fp0, fp1);      \
1893        break;                                                          \
1894    case  8:                                                            \
1895        gen_helper_r6_cmp_ ## fmt ## _saf(fp0, cpu_env, fp0, fp1);      \
1896        break;                                                          \
1897    case  9:                                                            \
1898        gen_helper_r6_cmp_ ## fmt ## _sun(fp0, cpu_env, fp0, fp1);      \
1899        break;                                                          \
1900    case 10:                                                            \
1901        gen_helper_r6_cmp_ ## fmt ## _seq(fp0, cpu_env, fp0, fp1);      \
1902        break;                                                          \
1903    case 11:                                                            \
1904        gen_helper_r6_cmp_ ## fmt ## _sueq(fp0, cpu_env, fp0, fp1);     \
1905        break;                                                          \
1906    case 12:                                                            \
1907        gen_helper_r6_cmp_ ## fmt ## _slt(fp0, cpu_env, fp0, fp1);      \
1908        break;                                                          \
1909    case 13:                                                            \
1910        gen_helper_r6_cmp_ ## fmt ## _sult(fp0, cpu_env, fp0, fp1);     \
1911        break;                                                          \
1912    case 14:                                                            \
1913        gen_helper_r6_cmp_ ## fmt ## _sle(fp0, cpu_env, fp0, fp1);      \
1914        break;                                                          \
1915    case 15:                                                            \
1916        gen_helper_r6_cmp_ ## fmt ## _sule(fp0, cpu_env, fp0, fp1);     \
1917        break;                                                          \
1918    case 17:                                                            \
1919        gen_helper_r6_cmp_ ## fmt ## _or(fp0, cpu_env, fp0, fp1);       \
1920        break;                                                          \
1921    case 18:                                                            \
1922        gen_helper_r6_cmp_ ## fmt ## _une(fp0, cpu_env, fp0, fp1);      \
1923        break;                                                          \
1924    case 19:                                                            \
1925        gen_helper_r6_cmp_ ## fmt ## _ne(fp0, cpu_env, fp0, fp1);       \
1926        break;                                                          \
1927    case 25:                                                            \
1928        gen_helper_r6_cmp_ ## fmt ## _sor(fp0, cpu_env, fp0, fp1);      \
1929        break;                                                          \
1930    case 26:                                                            \
1931        gen_helper_r6_cmp_ ## fmt ## _sune(fp0, cpu_env, fp0, fp1);     \
1932        break;                                                          \
1933    case 27:                                                            \
1934        gen_helper_r6_cmp_ ## fmt ## _sne(fp0, cpu_env, fp0, fp1);      \
1935        break;                                                          \
1936    default:                                                            \
1937        abort();                                                        \
1938    }                                                                   \
1939    STORE;                                                              \
1940}
1941
1942FOP_CONDNS(d, FMT_D, 64, gen_store_fpr64(ctx, fp0, fd))
1943FOP_CONDNS(s, FMT_S, 32, gen_store_fpr32(ctx, fp0, fd))
1944#undef FOP_CONDNS
1945#undef gen_ldcmp_fpr32
1946#undef gen_ldcmp_fpr64
1947
1948/* load/store instructions. */
1949#ifdef CONFIG_USER_ONLY
1950#define OP_LD_ATOMIC(insn, memop)                                          \
1951static inline void op_ld_##insn(TCGv ret, TCGv arg1, int mem_idx,          \
1952                                DisasContext *ctx)                         \
1953{                                                                          \
1954    TCGv t0 = tcg_temp_new();                                              \
1955    tcg_gen_mov_tl(t0, arg1);                                              \
1956    tcg_gen_qemu_ld_tl(ret, arg1, ctx->mem_idx, memop);                    \
1957    tcg_gen_st_tl(t0, cpu_env, offsetof(CPUMIPSState, lladdr));            \
1958    tcg_gen_st_tl(ret, cpu_env, offsetof(CPUMIPSState, llval));            \
1959}
1960#else
1961#define OP_LD_ATOMIC(insn, fname)                                          \
1962static inline void op_ld_##insn(TCGv ret, TCGv arg1, int mem_idx,          \
1963                                DisasContext *ctx)                         \
1964{                                                                          \
1965    gen_helper_##insn(ret, cpu_env, arg1, tcg_constant_i32(mem_idx));      \
1966}
1967#endif
1968OP_LD_ATOMIC(ll, MO_TESL);
1969#if defined(TARGET_MIPS64)
1970OP_LD_ATOMIC(lld, MO_TEUQ);
1971#endif
1972#undef OP_LD_ATOMIC
1973
1974void gen_base_offset_addr(DisasContext *ctx, TCGv addr, int base, int offset)
1975{
1976    if (base == 0) {
1977        tcg_gen_movi_tl(addr, offset);
1978    } else if (offset == 0) {
1979        gen_load_gpr(addr, base);
1980    } else {
1981        tcg_gen_movi_tl(addr, offset);
1982        gen_op_addr_add(ctx, addr, cpu_gpr[base], addr);
1983    }
1984}
1985
1986static target_ulong pc_relative_pc(DisasContext *ctx)
1987{
1988    target_ulong pc = ctx->base.pc_next;
1989
1990    if (ctx->hflags & MIPS_HFLAG_BMASK) {
1991        int branch_bytes = ctx->hflags & MIPS_HFLAG_BDS16 ? 2 : 4;
1992
1993        pc -= branch_bytes;
1994    }
1995
1996    pc &= ~(target_ulong)3;
1997    return pc;
1998}
1999
2000/* LWL or LDL, depending on MemOp. */
2001static void gen_lxl(DisasContext *ctx, TCGv reg, TCGv addr,
2002                     int mem_idx, MemOp mop)
2003{
2004    int sizem1 = memop_size(mop) - 1;
2005    TCGv t0 = tcg_temp_new();
2006    TCGv t1 = tcg_temp_new();
2007
2008    /*
2009     * Do a byte access to possibly trigger a page
2010     * fault with the unaligned address.
2011     */
2012    tcg_gen_qemu_ld_tl(t1, addr, mem_idx, MO_UB);
2013    tcg_gen_andi_tl(t1, addr, sizem1);
2014    if (!cpu_is_bigendian(ctx)) {
2015        tcg_gen_xori_tl(t1, t1, sizem1);
2016    }
2017    tcg_gen_shli_tl(t1, t1, 3);
2018    tcg_gen_andi_tl(t0, addr, ~sizem1);
2019    tcg_gen_qemu_ld_tl(t0, t0, mem_idx, mop);
2020    tcg_gen_shl_tl(t0, t0, t1);
2021    tcg_gen_shl_tl(t1, tcg_constant_tl(-1), t1);
2022    tcg_gen_andc_tl(t1, reg, t1);
2023    tcg_gen_or_tl(reg, t0, t1);
2024}
2025
2026/* LWR or LDR, depending on MemOp. */
2027static void gen_lxr(DisasContext *ctx, TCGv reg, TCGv addr,
2028                     int mem_idx, MemOp mop)
2029{
2030    int size = memop_size(mop);
2031    int sizem1 = size - 1;
2032    TCGv t0 = tcg_temp_new();
2033    TCGv t1 = tcg_temp_new();
2034
2035    /*
2036     * Do a byte access to possibly trigger a page
2037     * fault with the unaligned address.
2038     */
2039    tcg_gen_qemu_ld_tl(t1, addr, mem_idx, MO_UB);
2040    tcg_gen_andi_tl(t1, addr, sizem1);
2041    if (cpu_is_bigendian(ctx)) {
2042        tcg_gen_xori_tl(t1, t1, sizem1);
2043    }
2044    tcg_gen_shli_tl(t1, t1, 3);
2045    tcg_gen_andi_tl(t0, addr, ~sizem1);
2046    tcg_gen_qemu_ld_tl(t0, t0, mem_idx, mop);
2047    tcg_gen_shr_tl(t0, t0, t1);
2048    tcg_gen_xori_tl(t1, t1, size * 8 - 1);
2049    tcg_gen_shl_tl(t1, tcg_constant_tl(~1), t1);
2050    tcg_gen_and_tl(t1, reg, t1);
2051    tcg_gen_or_tl(reg, t0, t1);
2052}
2053
2054/* Load */
2055static void gen_ld(DisasContext *ctx, uint32_t opc,
2056                   int rt, int base, int offset)
2057{
2058    TCGv t0, t1;
2059    int mem_idx = ctx->mem_idx;
2060
2061    if (rt == 0 && ctx->insn_flags & (INSN_LOONGSON2E | INSN_LOONGSON2F |
2062                                      INSN_LOONGSON3A)) {
2063        /*
2064         * Loongson CPU uses a load to zero register for prefetch.
2065         * We emulate it as a NOP. On other CPU we must perform the
2066         * actual memory access.
2067         */
2068        return;
2069    }
2070
2071    t0 = tcg_temp_new();
2072    gen_base_offset_addr(ctx, t0, base, offset);
2073
2074    switch (opc) {
2075#if defined(TARGET_MIPS64)
2076    case OPC_LWU:
2077        tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TEUL |
2078                           ctx->default_tcg_memop_mask);
2079        gen_store_gpr(t0, rt);
2080        break;
2081    case OPC_LD:
2082        tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TEUQ |
2083                           ctx->default_tcg_memop_mask);
2084        gen_store_gpr(t0, rt);
2085        break;
2086    case OPC_LLD:
2087    case R6_OPC_LLD:
2088        op_ld_lld(t0, t0, mem_idx, ctx);
2089        gen_store_gpr(t0, rt);
2090        break;
2091    case OPC_LDL:
2092        t1 = tcg_temp_new();
2093        gen_load_gpr(t1, rt);
2094        gen_lxl(ctx, t1, t0, mem_idx, MO_TEUQ);
2095        gen_store_gpr(t1, rt);
2096        break;
2097    case OPC_LDR:
2098        t1 = tcg_temp_new();
2099        gen_load_gpr(t1, rt);
2100        gen_lxr(ctx, t1, t0, mem_idx, MO_TEUQ);
2101        gen_store_gpr(t1, rt);
2102        break;
2103    case OPC_LDPC:
2104        t1 = tcg_constant_tl(pc_relative_pc(ctx));
2105        gen_op_addr_add(ctx, t0, t0, t1);
2106        tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TEUQ);
2107        gen_store_gpr(t0, rt);
2108        break;
2109#endif
2110    case OPC_LWPC:
2111        t1 = tcg_constant_tl(pc_relative_pc(ctx));
2112        gen_op_addr_add(ctx, t0, t0, t1);
2113        tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TESL);
2114        gen_store_gpr(t0, rt);
2115        break;
2116    case OPC_LWE:
2117        mem_idx = MIPS_HFLAG_UM;
2118        /* fall through */
2119    case OPC_LW:
2120        tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TESL |
2121                           ctx->default_tcg_memop_mask);
2122        gen_store_gpr(t0, rt);
2123        break;
2124    case OPC_LHE:
2125        mem_idx = MIPS_HFLAG_UM;
2126        /* fall through */
2127    case OPC_LH:
2128        tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TESW |
2129                           ctx->default_tcg_memop_mask);
2130        gen_store_gpr(t0, rt);
2131        break;
2132    case OPC_LHUE:
2133        mem_idx = MIPS_HFLAG_UM;
2134        /* fall through */
2135    case OPC_LHU:
2136        tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TEUW |
2137                           ctx->default_tcg_memop_mask);
2138        gen_store_gpr(t0, rt);
2139        break;
2140    case OPC_LBE:
2141        mem_idx = MIPS_HFLAG_UM;
2142        /* fall through */
2143    case OPC_LB:
2144        tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_SB);
2145        gen_store_gpr(t0, rt);
2146        break;
2147    case OPC_LBUE:
2148        mem_idx = MIPS_HFLAG_UM;
2149        /* fall through */
2150    case OPC_LBU:
2151        tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_UB);
2152        gen_store_gpr(t0, rt);
2153        break;
2154    case OPC_LWLE:
2155        mem_idx = MIPS_HFLAG_UM;
2156        /* fall through */
2157    case OPC_LWL:
2158        t1 = tcg_temp_new();
2159        gen_load_gpr(t1, rt);
2160        gen_lxl(ctx, t1, t0, mem_idx, MO_TEUL);
2161        tcg_gen_ext32s_tl(t1, t1);
2162        gen_store_gpr(t1, rt);
2163        break;
2164    case OPC_LWRE:
2165        mem_idx = MIPS_HFLAG_UM;
2166        /* fall through */
2167    case OPC_LWR:
2168        t1 = tcg_temp_new();
2169        gen_load_gpr(t1, rt);
2170        gen_lxr(ctx, t1, t0, mem_idx, MO_TEUL);
2171        tcg_gen_ext32s_tl(t1, t1);
2172        gen_store_gpr(t1, rt);
2173        break;
2174    case OPC_LLE:
2175        mem_idx = MIPS_HFLAG_UM;
2176        /* fall through */
2177    case OPC_LL:
2178    case R6_OPC_LL:
2179        op_ld_ll(t0, t0, mem_idx, ctx);
2180        gen_store_gpr(t0, rt);
2181        break;
2182    }
2183}
2184
2185/* Store */
2186static void gen_st(DisasContext *ctx, uint32_t opc, int rt,
2187                   int base, int offset)
2188{
2189    TCGv t0 = tcg_temp_new();
2190    TCGv t1 = tcg_temp_new();
2191    int mem_idx = ctx->mem_idx;
2192
2193    gen_base_offset_addr(ctx, t0, base, offset);
2194    gen_load_gpr(t1, rt);
2195    switch (opc) {
2196#if defined(TARGET_MIPS64)
2197    case OPC_SD:
2198        tcg_gen_qemu_st_tl(t1, t0, mem_idx, MO_TEUQ |
2199                           ctx->default_tcg_memop_mask);
2200        break;
2201    case OPC_SDL:
2202        gen_helper_0e2i(sdl, t1, t0, mem_idx);
2203        break;
2204    case OPC_SDR:
2205        gen_helper_0e2i(sdr, t1, t0, mem_idx);
2206        break;
2207#endif
2208    case OPC_SWE:
2209        mem_idx = MIPS_HFLAG_UM;
2210        /* fall through */
2211    case OPC_SW:
2212        tcg_gen_qemu_st_tl(t1, t0, mem_idx, MO_TEUL |
2213                           ctx->default_tcg_memop_mask);
2214        break;
2215    case OPC_SHE:
2216        mem_idx = MIPS_HFLAG_UM;
2217        /* fall through */
2218    case OPC_SH:
2219        tcg_gen_qemu_st_tl(t1, t0, mem_idx, MO_TEUW |
2220                           ctx->default_tcg_memop_mask);
2221        break;
2222    case OPC_SBE:
2223        mem_idx = MIPS_HFLAG_UM;
2224        /* fall through */
2225    case OPC_SB:
2226        tcg_gen_qemu_st_tl(t1, t0, mem_idx, MO_8);
2227        break;
2228    case OPC_SWLE:
2229        mem_idx = MIPS_HFLAG_UM;
2230        /* fall through */
2231    case OPC_SWL:
2232        gen_helper_0e2i(swl, t1, t0, mem_idx);
2233        break;
2234    case OPC_SWRE:
2235        mem_idx = MIPS_HFLAG_UM;
2236        /* fall through */
2237    case OPC_SWR:
2238        gen_helper_0e2i(swr, t1, t0, mem_idx);
2239        break;
2240    }
2241}
2242
2243
2244/* Store conditional */
2245static void gen_st_cond(DisasContext *ctx, int rt, int base, int offset,
2246                        MemOp tcg_mo, bool eva)
2247{
2248    TCGv addr, t0, val;
2249    TCGLabel *l1 = gen_new_label();
2250    TCGLabel *done = gen_new_label();
2251
2252    t0 = tcg_temp_new();
2253    addr = tcg_temp_new();
2254    /* compare the address against that of the preceding LL */
2255    gen_base_offset_addr(ctx, addr, base, offset);
2256    tcg_gen_brcond_tl(TCG_COND_EQ, addr, cpu_lladdr, l1);
2257    tcg_gen_movi_tl(t0, 0);
2258    gen_store_gpr(t0, rt);
2259    tcg_gen_br(done);
2260
2261    gen_set_label(l1);
2262    /* generate cmpxchg */
2263    val = tcg_temp_new();
2264    gen_load_gpr(val, rt);
2265    tcg_gen_atomic_cmpxchg_tl(t0, cpu_lladdr, cpu_llval, val,
2266                              eva ? MIPS_HFLAG_UM : ctx->mem_idx, tcg_mo);
2267    tcg_gen_setcond_tl(TCG_COND_EQ, t0, t0, cpu_llval);
2268    gen_store_gpr(t0, rt);
2269
2270    gen_set_label(done);
2271}
2272
2273/* Load and store */
2274static void gen_flt_ldst(DisasContext *ctx, uint32_t opc, int ft,
2275                         TCGv t0)
2276{
2277    /*
2278     * Don't do NOP if destination is zero: we must perform the actual
2279     * memory access.
2280     */
2281    switch (opc) {
2282    case OPC_LWC1:
2283        {
2284            TCGv_i32 fp0 = tcg_temp_new_i32();
2285            tcg_gen_qemu_ld_i32(fp0, t0, ctx->mem_idx, MO_TESL |
2286                                ctx->default_tcg_memop_mask);
2287            gen_store_fpr32(ctx, fp0, ft);
2288        }
2289        break;
2290    case OPC_SWC1:
2291        {
2292            TCGv_i32 fp0 = tcg_temp_new_i32();
2293            gen_load_fpr32(ctx, fp0, ft);
2294            tcg_gen_qemu_st_i32(fp0, t0, ctx->mem_idx, MO_TEUL |
2295                                ctx->default_tcg_memop_mask);
2296        }
2297        break;
2298    case OPC_LDC1:
2299        {
2300            TCGv_i64 fp0 = tcg_temp_new_i64();
2301            tcg_gen_qemu_ld_i64(fp0, t0, ctx->mem_idx, MO_TEUQ |
2302                                ctx->default_tcg_memop_mask);
2303            gen_store_fpr64(ctx, fp0, ft);
2304        }
2305        break;
2306    case OPC_SDC1:
2307        {
2308            TCGv_i64 fp0 = tcg_temp_new_i64();
2309            gen_load_fpr64(ctx, fp0, ft);
2310            tcg_gen_qemu_st_i64(fp0, t0, ctx->mem_idx, MO_TEUQ |
2311                                ctx->default_tcg_memop_mask);
2312        }
2313        break;
2314    default:
2315        MIPS_INVAL("flt_ldst");
2316        gen_reserved_instruction(ctx);
2317        break;
2318    }
2319}
2320
2321static void gen_cop1_ldst(DisasContext *ctx, uint32_t op, int rt,
2322                          int rs, int16_t imm)
2323{
2324    TCGv t0 = tcg_temp_new();
2325
2326    if (ctx->CP0_Config1 & (1 << CP0C1_FP)) {
2327        check_cp1_enabled(ctx);
2328        switch (op) {
2329        case OPC_LDC1:
2330        case OPC_SDC1:
2331            check_insn(ctx, ISA_MIPS2);
2332            /* Fallthrough */
2333        default:
2334            gen_base_offset_addr(ctx, t0, rs, imm);
2335            gen_flt_ldst(ctx, op, rt, t0);
2336        }
2337    } else {
2338        generate_exception_err(ctx, EXCP_CpU, 1);
2339    }
2340}
2341
2342/* Arithmetic with immediate operand */
2343static void gen_arith_imm(DisasContext *ctx, uint32_t opc,
2344                          int rt, int rs, int imm)
2345{
2346    target_ulong uimm = (target_long)imm; /* Sign extend to 32/64 bits */
2347
2348    if (rt == 0 && opc != OPC_ADDI && opc != OPC_DADDI) {
2349        /*
2350         * If no destination, treat it as a NOP.
2351         * For addi, we must generate the overflow exception when needed.
2352         */
2353        return;
2354    }
2355    switch (opc) {
2356    case OPC_ADDI:
2357        {
2358            TCGv t0 = tcg_temp_new();
2359            TCGv t1 = tcg_temp_new();
2360            TCGv t2 = tcg_temp_new();
2361            TCGLabel *l1 = gen_new_label();
2362
2363            gen_load_gpr(t1, rs);
2364            tcg_gen_addi_tl(t0, t1, uimm);
2365            tcg_gen_ext32s_tl(t0, t0);
2366
2367            tcg_gen_xori_tl(t1, t1, ~uimm);
2368            tcg_gen_xori_tl(t2, t0, uimm);
2369            tcg_gen_and_tl(t1, t1, t2);
2370            tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
2371            /* operands of same sign, result different sign */
2372            generate_exception(ctx, EXCP_OVERFLOW);
2373            gen_set_label(l1);
2374            tcg_gen_ext32s_tl(t0, t0);
2375            gen_store_gpr(t0, rt);
2376        }
2377        break;
2378    case OPC_ADDIU:
2379        if (rs != 0) {
2380            tcg_gen_addi_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
2381            tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
2382        } else {
2383            tcg_gen_movi_tl(cpu_gpr[rt], uimm);
2384        }
2385        break;
2386#if defined(TARGET_MIPS64)
2387    case OPC_DADDI:
2388        {
2389            TCGv t0 = tcg_temp_new();
2390            TCGv t1 = tcg_temp_new();
2391            TCGv t2 = tcg_temp_new();
2392            TCGLabel *l1 = gen_new_label();
2393
2394            gen_load_gpr(t1, rs);
2395            tcg_gen_addi_tl(t0, t1, uimm);
2396
2397            tcg_gen_xori_tl(t1, t1, ~uimm);
2398            tcg_gen_xori_tl(t2, t0, uimm);
2399            tcg_gen_and_tl(t1, t1, t2);
2400            tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
2401            /* operands of same sign, result different sign */
2402            generate_exception(ctx, EXCP_OVERFLOW);
2403            gen_set_label(l1);
2404            gen_store_gpr(t0, rt);
2405        }
2406        break;
2407    case OPC_DADDIU:
2408        if (rs != 0) {
2409            tcg_gen_addi_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
2410        } else {
2411            tcg_gen_movi_tl(cpu_gpr[rt], uimm);
2412        }
2413        break;
2414#endif
2415    }
2416}
2417
2418/* Logic with immediate operand */
2419static void gen_logic_imm(DisasContext *ctx, uint32_t opc,
2420                          int rt, int rs, int16_t imm)
2421{
2422    target_ulong uimm;
2423
2424    if (rt == 0) {
2425        /* If no destination, treat it as a NOP. */
2426        return;
2427    }
2428    uimm = (uint16_t)imm;
2429    switch (opc) {
2430    case OPC_ANDI:
2431        if (likely(rs != 0)) {
2432            tcg_gen_andi_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
2433        } else {
2434            tcg_gen_movi_tl(cpu_gpr[rt], 0);
2435        }
2436        break;
2437    case OPC_ORI:
2438        if (rs != 0) {
2439            tcg_gen_ori_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
2440        } else {
2441            tcg_gen_movi_tl(cpu_gpr[rt], uimm);
2442        }
2443        break;
2444    case OPC_XORI:
2445        if (likely(rs != 0)) {
2446            tcg_gen_xori_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
2447        } else {
2448            tcg_gen_movi_tl(cpu_gpr[rt], uimm);
2449        }
2450        break;
2451    case OPC_LUI:
2452        if (rs != 0 && (ctx->insn_flags & ISA_MIPS_R6)) {
2453            /* OPC_AUI */
2454            tcg_gen_addi_tl(cpu_gpr[rt], cpu_gpr[rs], imm << 16);
2455            tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
2456        } else {
2457            tcg_gen_movi_tl(cpu_gpr[rt], imm << 16);
2458        }
2459        break;
2460
2461    default:
2462        break;
2463    }
2464}
2465
2466/* Set on less than with immediate operand */
2467static void gen_slt_imm(DisasContext *ctx, uint32_t opc,
2468                        int rt, int rs, int16_t imm)
2469{
2470    target_ulong uimm = (target_long)imm; /* Sign extend to 32/64 bits */
2471    TCGv t0;
2472
2473    if (rt == 0) {
2474        /* If no destination, treat it as a NOP. */
2475        return;
2476    }
2477    t0 = tcg_temp_new();
2478    gen_load_gpr(t0, rs);
2479    switch (opc) {
2480    case OPC_SLTI:
2481        tcg_gen_setcondi_tl(TCG_COND_LT, cpu_gpr[rt], t0, uimm);
2482        break;
2483    case OPC_SLTIU:
2484        tcg_gen_setcondi_tl(TCG_COND_LTU, cpu_gpr[rt], t0, uimm);
2485        break;
2486    }
2487}
2488
2489/* Shifts with immediate operand */
2490static void gen_shift_imm(DisasContext *ctx, uint32_t opc,
2491                          int rt, int rs, int16_t imm)
2492{
2493    target_ulong uimm = ((uint16_t)imm) & 0x1f;
2494    TCGv t0;
2495
2496    if (rt == 0) {
2497        /* If no destination, treat it as a NOP. */
2498        return;
2499    }
2500
2501    t0 = tcg_temp_new();
2502    gen_load_gpr(t0, rs);
2503    switch (opc) {
2504    case OPC_SLL:
2505        tcg_gen_shli_tl(t0, t0, uimm);
2506        tcg_gen_ext32s_tl(cpu_gpr[rt], t0);
2507        break;
2508    case OPC_SRA:
2509        tcg_gen_sari_tl(cpu_gpr[rt], t0, uimm);
2510        break;
2511    case OPC_SRL:
2512        if (uimm != 0) {
2513            tcg_gen_ext32u_tl(t0, t0);
2514            tcg_gen_shri_tl(cpu_gpr[rt], t0, uimm);
2515        } else {
2516            tcg_gen_ext32s_tl(cpu_gpr[rt], t0);
2517        }
2518        break;
2519    case OPC_ROTR:
2520        if (uimm != 0) {
2521            TCGv_i32 t1 = tcg_temp_new_i32();
2522
2523            tcg_gen_trunc_tl_i32(t1, t0);
2524            tcg_gen_rotri_i32(t1, t1, uimm);
2525            tcg_gen_ext_i32_tl(cpu_gpr[rt], t1);
2526        } else {
2527            tcg_gen_ext32s_tl(cpu_gpr[rt], t0);
2528        }
2529        break;
2530#if defined(TARGET_MIPS64)
2531    case OPC_DSLL:
2532        tcg_gen_shli_tl(cpu_gpr[rt], t0, uimm);
2533        break;
2534    case OPC_DSRA:
2535        tcg_gen_sari_tl(cpu_gpr[rt], t0, uimm);
2536        break;
2537    case OPC_DSRL:
2538        tcg_gen_shri_tl(cpu_gpr[rt], t0, uimm);
2539        break;
2540    case OPC_DROTR:
2541        if (uimm != 0) {
2542            tcg_gen_rotri_tl(cpu_gpr[rt], t0, uimm);
2543        } else {
2544            tcg_gen_mov_tl(cpu_gpr[rt], t0);
2545        }
2546        break;
2547    case OPC_DSLL32:
2548        tcg_gen_shli_tl(cpu_gpr[rt], t0, uimm + 32);
2549        break;
2550    case OPC_DSRA32:
2551        tcg_gen_sari_tl(cpu_gpr[rt], t0, uimm + 32);
2552        break;
2553    case OPC_DSRL32:
2554        tcg_gen_shri_tl(cpu_gpr[rt], t0, uimm + 32);
2555        break;
2556    case OPC_DROTR32:
2557        tcg_gen_rotri_tl(cpu_gpr[rt], t0, uimm + 32);
2558        break;
2559#endif
2560    }
2561}
2562
2563/* Arithmetic */
2564static void gen_arith(DisasContext *ctx, uint32_t opc,
2565                      int rd, int rs, int rt)
2566{
2567    if (rd == 0 && opc != OPC_ADD && opc != OPC_SUB
2568       && opc != OPC_DADD && opc != OPC_DSUB) {
2569        /*
2570         * If no destination, treat it as a NOP.
2571         * For add & sub, we must generate the overflow exception when needed.
2572         */
2573        return;
2574    }
2575
2576    switch (opc) {
2577    case OPC_ADD:
2578        {
2579            TCGv t0 = tcg_temp_new();
2580            TCGv t1 = tcg_temp_new();
2581            TCGv t2 = tcg_temp_new();
2582            TCGLabel *l1 = gen_new_label();
2583
2584            gen_load_gpr(t1, rs);
2585            gen_load_gpr(t2, rt);
2586            tcg_gen_add_tl(t0, t1, t2);
2587            tcg_gen_ext32s_tl(t0, t0);
2588            tcg_gen_xor_tl(t1, t1, t2);
2589            tcg_gen_xor_tl(t2, t0, t2);
2590            tcg_gen_andc_tl(t1, t2, t1);
2591            tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
2592            /* operands of same sign, result different sign */
2593            generate_exception(ctx, EXCP_OVERFLOW);
2594            gen_set_label(l1);
2595            gen_store_gpr(t0, rd);
2596        }
2597        break;
2598    case OPC_ADDU:
2599        if (rs != 0 && rt != 0) {
2600            tcg_gen_add_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2601            tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
2602        } else if (rs == 0 && rt != 0) {
2603            tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
2604        } else if (rs != 0 && rt == 0) {
2605            tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
2606        } else {
2607            tcg_gen_movi_tl(cpu_gpr[rd], 0);
2608        }
2609        break;
2610    case OPC_SUB:
2611        {
2612            TCGv t0 = tcg_temp_new();
2613            TCGv t1 = tcg_temp_new();
2614            TCGv t2 = tcg_temp_new();
2615            TCGLabel *l1 = gen_new_label();
2616
2617            gen_load_gpr(t1, rs);
2618            gen_load_gpr(t2, rt);
2619            tcg_gen_sub_tl(t0, t1, t2);
2620            tcg_gen_ext32s_tl(t0, t0);
2621            tcg_gen_xor_tl(t2, t1, t2);
2622            tcg_gen_xor_tl(t1, t0, t1);
2623            tcg_gen_and_tl(t1, t1, t2);
2624            tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
2625            /*
2626             * operands of different sign, first operand and the result
2627             * of different sign
2628             */
2629            generate_exception(ctx, EXCP_OVERFLOW);
2630            gen_set_label(l1);
2631            gen_store_gpr(t0, rd);
2632        }
2633        break;
2634    case OPC_SUBU:
2635        if (rs != 0 && rt != 0) {
2636            tcg_gen_sub_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2637            tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
2638        } else if (rs == 0 && rt != 0) {
2639            tcg_gen_neg_tl(cpu_gpr[rd], cpu_gpr[rt]);
2640            tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
2641        } else if (rs != 0 && rt == 0) {
2642            tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
2643        } else {
2644            tcg_gen_movi_tl(cpu_gpr[rd], 0);
2645        }
2646        break;
2647#if defined(TARGET_MIPS64)
2648    case OPC_DADD:
2649        {
2650            TCGv t0 = tcg_temp_new();
2651            TCGv t1 = tcg_temp_new();
2652            TCGv t2 = tcg_temp_new();
2653            TCGLabel *l1 = gen_new_label();
2654
2655            gen_load_gpr(t1, rs);
2656            gen_load_gpr(t2, rt);
2657            tcg_gen_add_tl(t0, t1, t2);
2658            tcg_gen_xor_tl(t1, t1, t2);
2659            tcg_gen_xor_tl(t2, t0, t2);
2660            tcg_gen_andc_tl(t1, t2, t1);
2661            tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
2662            /* operands of same sign, result different sign */
2663            generate_exception(ctx, EXCP_OVERFLOW);
2664            gen_set_label(l1);
2665            gen_store_gpr(t0, rd);
2666        }
2667        break;
2668    case OPC_DADDU:
2669        if (rs != 0 && rt != 0) {
2670            tcg_gen_add_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2671        } else if (rs == 0 && rt != 0) {
2672            tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
2673        } else if (rs != 0 && rt == 0) {
2674            tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
2675        } else {
2676            tcg_gen_movi_tl(cpu_gpr[rd], 0);
2677        }
2678        break;
2679    case OPC_DSUB:
2680        {
2681            TCGv t0 = tcg_temp_new();
2682            TCGv t1 = tcg_temp_new();
2683            TCGv t2 = tcg_temp_new();
2684            TCGLabel *l1 = gen_new_label();
2685
2686            gen_load_gpr(t1, rs);
2687            gen_load_gpr(t2, rt);
2688            tcg_gen_sub_tl(t0, t1, t2);
2689            tcg_gen_xor_tl(t2, t1, t2);
2690            tcg_gen_xor_tl(t1, t0, t1);
2691            tcg_gen_and_tl(t1, t1, t2);
2692            tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
2693            /*
2694             * Operands of different sign, first operand and result different
2695             * sign.
2696             */
2697            generate_exception(ctx, EXCP_OVERFLOW);
2698            gen_set_label(l1);
2699            gen_store_gpr(t0, rd);
2700        }
2701        break;
2702    case OPC_DSUBU:
2703        if (rs != 0 && rt != 0) {
2704            tcg_gen_sub_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2705        } else if (rs == 0 && rt != 0) {
2706            tcg_gen_neg_tl(cpu_gpr[rd], cpu_gpr[rt]);
2707        } else if (rs != 0 && rt == 0) {
2708            tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
2709        } else {
2710            tcg_gen_movi_tl(cpu_gpr[rd], 0);
2711        }
2712        break;
2713#endif
2714    case OPC_MUL:
2715        if (likely(rs != 0 && rt != 0)) {
2716            tcg_gen_mul_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2717            tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
2718        } else {
2719            tcg_gen_movi_tl(cpu_gpr[rd], 0);
2720        }
2721        break;
2722    }
2723}
2724
2725/* Conditional move */
2726static void gen_cond_move(DisasContext *ctx, uint32_t opc,
2727                          int rd, int rs, int rt)
2728{
2729    TCGv t0, t1, t2;
2730
2731    if (rd == 0) {
2732        /* If no destination, treat it as a NOP. */
2733        return;
2734    }
2735
2736    t0 = tcg_temp_new();
2737    gen_load_gpr(t0, rt);
2738    t1 = tcg_constant_tl(0);
2739    t2 = tcg_temp_new();
2740    gen_load_gpr(t2, rs);
2741    switch (opc) {
2742    case OPC_MOVN:
2743        tcg_gen_movcond_tl(TCG_COND_NE, cpu_gpr[rd], t0, t1, t2, cpu_gpr[rd]);
2744        break;
2745    case OPC_MOVZ:
2746        tcg_gen_movcond_tl(TCG_COND_EQ, cpu_gpr[rd], t0, t1, t2, cpu_gpr[rd]);
2747        break;
2748    case OPC_SELNEZ:
2749        tcg_gen_movcond_tl(TCG_COND_NE, cpu_gpr[rd], t0, t1, t2, t1);
2750        break;
2751    case OPC_SELEQZ:
2752        tcg_gen_movcond_tl(TCG_COND_EQ, cpu_gpr[rd], t0, t1, t2, t1);
2753        break;
2754    }
2755}
2756
2757/* Logic */
2758static void gen_logic(DisasContext *ctx, uint32_t opc,
2759                      int rd, int rs, int rt)
2760{
2761    if (rd == 0) {
2762        /* If no destination, treat it as a NOP. */
2763        return;
2764    }
2765
2766    switch (opc) {
2767    case OPC_AND:
2768        if (likely(rs != 0 && rt != 0)) {
2769            tcg_gen_and_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2770        } else {
2771            tcg_gen_movi_tl(cpu_gpr[rd], 0);
2772        }
2773        break;
2774    case OPC_NOR:
2775        if (rs != 0 && rt != 0) {
2776            tcg_gen_nor_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2777        } else if (rs == 0 && rt != 0) {
2778            tcg_gen_not_tl(cpu_gpr[rd], cpu_gpr[rt]);
2779        } else if (rs != 0 && rt == 0) {
2780            tcg_gen_not_tl(cpu_gpr[rd], cpu_gpr[rs]);
2781        } else {
2782            tcg_gen_movi_tl(cpu_gpr[rd], ~((target_ulong)0));
2783        }
2784        break;
2785    case OPC_OR:
2786        if (likely(rs != 0 && rt != 0)) {
2787            tcg_gen_or_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2788        } else if (rs == 0 && rt != 0) {
2789            tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
2790        } else if (rs != 0 && rt == 0) {
2791            tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
2792        } else {
2793            tcg_gen_movi_tl(cpu_gpr[rd], 0);
2794        }
2795        break;
2796    case OPC_XOR:
2797        if (likely(rs != 0 && rt != 0)) {
2798            tcg_gen_xor_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2799        } else if (rs == 0 && rt != 0) {
2800            tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
2801        } else if (rs != 0 && rt == 0) {
2802            tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
2803        } else {
2804            tcg_gen_movi_tl(cpu_gpr[rd], 0);
2805        }
2806        break;
2807    }
2808}
2809
2810/* Set on lower than */
2811static void gen_slt(DisasContext *ctx, uint32_t opc,
2812                    int rd, int rs, int rt)
2813{
2814    TCGv t0, t1;
2815
2816    if (rd == 0) {
2817        /* If no destination, treat it as a NOP. */
2818        return;
2819    }
2820
2821    t0 = tcg_temp_new();
2822    t1 = tcg_temp_new();
2823    gen_load_gpr(t0, rs);
2824    gen_load_gpr(t1, rt);
2825    switch (opc) {
2826    case OPC_SLT:
2827        tcg_gen_setcond_tl(TCG_COND_LT, cpu_gpr[rd], t0, t1);
2828        break;
2829    case OPC_SLTU:
2830        tcg_gen_setcond_tl(TCG_COND_LTU, cpu_gpr[rd], t0, t1);
2831        break;
2832    }
2833}
2834
2835/* Shifts */
2836static void gen_shift(DisasContext *ctx, uint32_t opc,
2837                      int rd, int rs, int rt)
2838{
2839    TCGv t0, t1;
2840
2841    if (rd == 0) {
2842        /*
2843         * If no destination, treat it as a NOP.
2844         * For add & sub, we must generate the overflow exception when needed.
2845         */
2846        return;
2847    }
2848
2849    t0 = tcg_temp_new();
2850    t1 = tcg_temp_new();
2851    gen_load_gpr(t0, rs);
2852    gen_load_gpr(t1, rt);
2853    switch (opc) {
2854    case OPC_SLLV:
2855        tcg_gen_andi_tl(t0, t0, 0x1f);
2856        tcg_gen_shl_tl(t0, t1, t0);
2857        tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
2858        break;
2859    case OPC_SRAV:
2860        tcg_gen_andi_tl(t0, t0, 0x1f);
2861        tcg_gen_sar_tl(cpu_gpr[rd], t1, t0);
2862        break;
2863    case OPC_SRLV:
2864        tcg_gen_ext32u_tl(t1, t1);
2865        tcg_gen_andi_tl(t0, t0, 0x1f);
2866        tcg_gen_shr_tl(t0, t1, t0);
2867        tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
2868        break;
2869    case OPC_ROTRV:
2870        {
2871            TCGv_i32 t2 = tcg_temp_new_i32();
2872            TCGv_i32 t3 = tcg_temp_new_i32();
2873
2874            tcg_gen_trunc_tl_i32(t2, t0);
2875            tcg_gen_trunc_tl_i32(t3, t1);
2876            tcg_gen_andi_i32(t2, t2, 0x1f);
2877            tcg_gen_rotr_i32(t2, t3, t2);
2878            tcg_gen_ext_i32_tl(cpu_gpr[rd], t2);
2879        }
2880        break;
2881#if defined(TARGET_MIPS64)
2882    case OPC_DSLLV:
2883        tcg_gen_andi_tl(t0, t0, 0x3f);
2884        tcg_gen_shl_tl(cpu_gpr[rd], t1, t0);
2885        break;
2886    case OPC_DSRAV:
2887        tcg_gen_andi_tl(t0, t0, 0x3f);
2888        tcg_gen_sar_tl(cpu_gpr[rd], t1, t0);
2889        break;
2890    case OPC_DSRLV:
2891        tcg_gen_andi_tl(t0, t0, 0x3f);
2892        tcg_gen_shr_tl(cpu_gpr[rd], t1, t0);
2893        break;
2894    case OPC_DROTRV:
2895        tcg_gen_andi_tl(t0, t0, 0x3f);
2896        tcg_gen_rotr_tl(cpu_gpr[rd], t1, t0);
2897        break;
2898#endif
2899    }
2900}
2901
2902/* Arithmetic on HI/LO registers */
2903static void gen_HILO(DisasContext *ctx, uint32_t opc, int acc, int reg)
2904{
2905    if (reg == 0 && (opc == OPC_MFHI || opc == OPC_MFLO)) {
2906        /* Treat as NOP. */
2907        return;
2908    }
2909
2910    if (acc != 0) {
2911        check_dsp(ctx);
2912    }
2913
2914    switch (opc) {
2915    case OPC_MFHI:
2916#if defined(TARGET_MIPS64)
2917        if (acc != 0) {
2918            tcg_gen_ext32s_tl(cpu_gpr[reg], cpu_HI[acc]);
2919        } else
2920#endif
2921        {
2922            tcg_gen_mov_tl(cpu_gpr[reg], cpu_HI[acc]);
2923        }
2924        break;
2925    case OPC_MFLO:
2926#if defined(TARGET_MIPS64)
2927        if (acc != 0) {
2928            tcg_gen_ext32s_tl(cpu_gpr[reg], cpu_LO[acc]);
2929        } else
2930#endif
2931        {
2932            tcg_gen_mov_tl(cpu_gpr[reg], cpu_LO[acc]);
2933        }
2934        break;
2935    case OPC_MTHI:
2936        if (reg != 0) {
2937#if defined(TARGET_MIPS64)
2938            if (acc != 0) {
2939                tcg_gen_ext32s_tl(cpu_HI[acc], cpu_gpr[reg]);
2940            } else
2941#endif
2942            {
2943                tcg_gen_mov_tl(cpu_HI[acc], cpu_gpr[reg]);
2944            }
2945        } else {
2946            tcg_gen_movi_tl(cpu_HI[acc], 0);
2947        }
2948        break;
2949    case OPC_MTLO:
2950        if (reg != 0) {
2951#if defined(TARGET_MIPS64)
2952            if (acc != 0) {
2953                tcg_gen_ext32s_tl(cpu_LO[acc], cpu_gpr[reg]);
2954            } else
2955#endif
2956            {
2957                tcg_gen_mov_tl(cpu_LO[acc], cpu_gpr[reg]);
2958            }
2959        } else {
2960            tcg_gen_movi_tl(cpu_LO[acc], 0);
2961        }
2962        break;
2963    }
2964}
2965
2966static inline void gen_r6_ld(target_long addr, int reg, int memidx,
2967                             MemOp memop)
2968{
2969    TCGv t0 = tcg_temp_new();
2970    tcg_gen_qemu_ld_tl(t0, tcg_constant_tl(addr), memidx, memop);
2971    gen_store_gpr(t0, reg);
2972}
2973
2974static inline void gen_pcrel(DisasContext *ctx, int opc, target_ulong pc,
2975                             int rs)
2976{
2977    target_long offset;
2978    target_long addr;
2979
2980    switch (MASK_OPC_PCREL_TOP2BITS(opc)) {
2981    case OPC_ADDIUPC:
2982        if (rs != 0) {
2983            offset = sextract32(ctx->opcode << 2, 0, 21);
2984            addr = addr_add(ctx, pc, offset);
2985            tcg_gen_movi_tl(cpu_gpr[rs], addr);
2986        }
2987        break;
2988    case R6_OPC_LWPC:
2989        offset = sextract32(ctx->opcode << 2, 0, 21);
2990        addr = addr_add(ctx, pc, offset);
2991        gen_r6_ld(addr, rs, ctx->mem_idx, MO_TESL);
2992        break;
2993#if defined(TARGET_MIPS64)
2994    case OPC_LWUPC:
2995        check_mips_64(ctx);
2996        offset = sextract32(ctx->opcode << 2, 0, 21);
2997        addr = addr_add(ctx, pc, offset);
2998        gen_r6_ld(addr, rs, ctx->mem_idx, MO_TEUL);
2999        break;
3000#endif
3001    default:
3002        switch (MASK_OPC_PCREL_TOP5BITS(opc)) {
3003        case OPC_AUIPC:
3004            if (rs != 0) {
3005                offset = sextract32(ctx->opcode, 0, 16) << 16;
3006                addr = addr_add(ctx, pc, offset);
3007                tcg_gen_movi_tl(cpu_gpr[rs], addr);
3008            }
3009            break;
3010        case OPC_ALUIPC:
3011            if (rs != 0) {
3012                offset = sextract32(ctx->opcode, 0, 16) << 16;
3013                addr = ~0xFFFF & addr_add(ctx, pc, offset);
3014                tcg_gen_movi_tl(cpu_gpr[rs], addr);
3015            }
3016            break;
3017#if defined(TARGET_MIPS64)
3018        case R6_OPC_LDPC: /* bits 16 and 17 are part of immediate */
3019        case R6_OPC_LDPC + (1 << 16):
3020        case R6_OPC_LDPC + (2 << 16):
3021        case R6_OPC_LDPC + (3 << 16):
3022            check_mips_64(ctx);
3023            offset = sextract32(ctx->opcode << 3, 0, 21);
3024            addr = addr_add(ctx, (pc & ~0x7), offset);
3025            gen_r6_ld(addr, rs, ctx->mem_idx, MO_TEUQ);
3026            break;
3027#endif
3028        default:
3029            MIPS_INVAL("OPC_PCREL");
3030            gen_reserved_instruction(ctx);
3031            break;
3032        }
3033        break;
3034    }
3035}
3036
3037static void gen_r6_muldiv(DisasContext *ctx, int opc, int rd, int rs, int rt)
3038{
3039    TCGv t0, t1;
3040
3041    if (rd == 0) {
3042        /* Treat as NOP. */
3043        return;
3044    }
3045
3046    t0 = tcg_temp_new();
3047    t1 = tcg_temp_new();
3048
3049    gen_load_gpr(t0, rs);
3050    gen_load_gpr(t1, rt);
3051
3052    switch (opc) {
3053    case R6_OPC_DIV:
3054        {
3055            TCGv t2 = tcg_temp_new();
3056            TCGv t3 = tcg_temp_new();
3057            tcg_gen_ext32s_tl(t0, t0);
3058            tcg_gen_ext32s_tl(t1, t1);
3059            tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, INT_MIN);
3060            tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1);
3061            tcg_gen_and_tl(t2, t2, t3);
3062            tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
3063            tcg_gen_or_tl(t2, t2, t3);
3064            tcg_gen_movi_tl(t3, 0);
3065            tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
3066            tcg_gen_div_tl(cpu_gpr[rd], t0, t1);
3067            tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3068        }
3069        break;
3070    case R6_OPC_MOD:
3071        {
3072            TCGv t2 = tcg_temp_new();
3073            TCGv t3 = tcg_temp_new();
3074            tcg_gen_ext32s_tl(t0, t0);
3075            tcg_gen_ext32s_tl(t1, t1);
3076            tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, INT_MIN);
3077            tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1);
3078            tcg_gen_and_tl(t2, t2, t3);
3079            tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
3080            tcg_gen_or_tl(t2, t2, t3);
3081            tcg_gen_movi_tl(t3, 0);
3082            tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
3083            tcg_gen_rem_tl(cpu_gpr[rd], t0, t1);
3084            tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3085        }
3086        break;
3087    case R6_OPC_DIVU:
3088        {
3089            TCGv t2 = tcg_constant_tl(0);
3090            TCGv t3 = tcg_constant_tl(1);
3091            tcg_gen_ext32u_tl(t0, t0);
3092            tcg_gen_ext32u_tl(t1, t1);
3093            tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
3094            tcg_gen_divu_tl(cpu_gpr[rd], t0, t1);
3095            tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3096        }
3097        break;
3098    case R6_OPC_MODU:
3099        {
3100            TCGv t2 = tcg_constant_tl(0);
3101            TCGv t3 = tcg_constant_tl(1);
3102            tcg_gen_ext32u_tl(t0, t0);
3103            tcg_gen_ext32u_tl(t1, t1);
3104            tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
3105            tcg_gen_remu_tl(cpu_gpr[rd], t0, t1);
3106            tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3107        }
3108        break;
3109    case R6_OPC_MUL:
3110        {
3111            TCGv_i32 t2 = tcg_temp_new_i32();
3112            TCGv_i32 t3 = tcg_temp_new_i32();
3113            tcg_gen_trunc_tl_i32(t2, t0);
3114            tcg_gen_trunc_tl_i32(t3, t1);
3115            tcg_gen_mul_i32(t2, t2, t3);
3116            tcg_gen_ext_i32_tl(cpu_gpr[rd], t2);
3117        }
3118        break;
3119    case R6_OPC_MUH:
3120        {
3121            TCGv_i32 t2 = tcg_temp_new_i32();
3122            TCGv_i32 t3 = tcg_temp_new_i32();
3123            tcg_gen_trunc_tl_i32(t2, t0);
3124            tcg_gen_trunc_tl_i32(t3, t1);
3125            tcg_gen_muls2_i32(t2, t3, t2, t3);
3126            tcg_gen_ext_i32_tl(cpu_gpr[rd], t3);
3127        }
3128        break;
3129    case R6_OPC_MULU:
3130        {
3131            TCGv_i32 t2 = tcg_temp_new_i32();
3132            TCGv_i32 t3 = tcg_temp_new_i32();
3133            tcg_gen_trunc_tl_i32(t2, t0);
3134            tcg_gen_trunc_tl_i32(t3, t1);
3135            tcg_gen_mul_i32(t2, t2, t3);
3136            tcg_gen_ext_i32_tl(cpu_gpr[rd], t2);
3137        }
3138        break;
3139    case R6_OPC_MUHU:
3140        {
3141            TCGv_i32 t2 = tcg_temp_new_i32();
3142            TCGv_i32 t3 = tcg_temp_new_i32();
3143            tcg_gen_trunc_tl_i32(t2, t0);
3144            tcg_gen_trunc_tl_i32(t3, t1);
3145            tcg_gen_mulu2_i32(t2, t3, t2, t3);
3146            tcg_gen_ext_i32_tl(cpu_gpr[rd], t3);
3147        }
3148        break;
3149#if defined(TARGET_MIPS64)
3150    case R6_OPC_DDIV:
3151        {
3152            TCGv t2 = tcg_temp_new();
3153            TCGv t3 = tcg_temp_new();
3154            tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, -1LL << 63);
3155            tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1LL);
3156            tcg_gen_and_tl(t2, t2, t3);
3157            tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
3158            tcg_gen_or_tl(t2, t2, t3);
3159            tcg_gen_movi_tl(t3, 0);
3160            tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
3161            tcg_gen_div_tl(cpu_gpr[rd], t0, t1);
3162        }
3163        break;
3164    case R6_OPC_DMOD:
3165        {
3166            TCGv t2 = tcg_temp_new();
3167            TCGv t3 = tcg_temp_new();
3168            tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, -1LL << 63);
3169            tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1LL);
3170            tcg_gen_and_tl(t2, t2, t3);
3171            tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
3172            tcg_gen_or_tl(t2, t2, t3);
3173            tcg_gen_movi_tl(t3, 0);
3174            tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
3175            tcg_gen_rem_tl(cpu_gpr[rd], t0, t1);
3176        }
3177        break;
3178    case R6_OPC_DDIVU:
3179        {
3180            TCGv t2 = tcg_constant_tl(0);
3181            TCGv t3 = tcg_constant_tl(1);
3182            tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
3183            tcg_gen_divu_i64(cpu_gpr[rd], t0, t1);
3184        }
3185        break;
3186    case R6_OPC_DMODU:
3187        {
3188            TCGv t2 = tcg_constant_tl(0);
3189            TCGv t3 = tcg_constant_tl(1);
3190            tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
3191            tcg_gen_remu_i64(cpu_gpr[rd], t0, t1);
3192        }
3193        break;
3194    case R6_OPC_DMUL:
3195        tcg_gen_mul_i64(cpu_gpr[rd], t0, t1);
3196        break;
3197    case R6_OPC_DMUH:
3198        {
3199            TCGv t2 = tcg_temp_new();
3200            tcg_gen_muls2_i64(t2, cpu_gpr[rd], t0, t1);
3201        }
3202        break;
3203    case R6_OPC_DMULU:
3204        tcg_gen_mul_i64(cpu_gpr[rd], t0, t1);
3205        break;
3206    case R6_OPC_DMUHU:
3207        {
3208            TCGv t2 = tcg_temp_new();
3209            tcg_gen_mulu2_i64(t2, cpu_gpr[rd], t0, t1);
3210        }
3211        break;
3212#endif
3213    default:
3214        MIPS_INVAL("r6 mul/div");
3215        gen_reserved_instruction(ctx);
3216        break;
3217    }
3218}
3219
3220#if defined(TARGET_MIPS64)
3221static void gen_div1_tx79(DisasContext *ctx, uint32_t opc, int rs, int rt)
3222{
3223    TCGv t0, t1;
3224
3225    t0 = tcg_temp_new();
3226    t1 = tcg_temp_new();
3227
3228    gen_load_gpr(t0, rs);
3229    gen_load_gpr(t1, rt);
3230
3231    switch (opc) {
3232    case MMI_OPC_DIV1:
3233        {
3234            TCGv t2 = tcg_temp_new();
3235            TCGv t3 = tcg_temp_new();
3236            tcg_gen_ext32s_tl(t0, t0);
3237            tcg_gen_ext32s_tl(t1, t1);
3238            tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, INT_MIN);
3239            tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1);
3240            tcg_gen_and_tl(t2, t2, t3);
3241            tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
3242            tcg_gen_or_tl(t2, t2, t3);
3243            tcg_gen_movi_tl(t3, 0);
3244            tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
3245            tcg_gen_div_tl(cpu_LO[1], t0, t1);
3246            tcg_gen_rem_tl(cpu_HI[1], t0, t1);
3247            tcg_gen_ext32s_tl(cpu_LO[1], cpu_LO[1]);
3248            tcg_gen_ext32s_tl(cpu_HI[1], cpu_HI[1]);
3249        }
3250        break;
3251    case MMI_OPC_DIVU1:
3252        {
3253            TCGv t2 = tcg_constant_tl(0);
3254            TCGv t3 = tcg_constant_tl(1);
3255            tcg_gen_ext32u_tl(t0, t0);
3256            tcg_gen_ext32u_tl(t1, t1);
3257            tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
3258            tcg_gen_divu_tl(cpu_LO[1], t0, t1);
3259            tcg_gen_remu_tl(cpu_HI[1], t0, t1);
3260            tcg_gen_ext32s_tl(cpu_LO[1], cpu_LO[1]);
3261            tcg_gen_ext32s_tl(cpu_HI[1], cpu_HI[1]);
3262        }
3263        break;
3264    default:
3265        MIPS_INVAL("div1 TX79");
3266        gen_reserved_instruction(ctx);
3267        break;
3268    }
3269}
3270#endif
3271
3272static void gen_muldiv(DisasContext *ctx, uint32_t opc,
3273                       int acc, int rs, int rt)
3274{
3275    TCGv t0, t1;
3276
3277    t0 = tcg_temp_new();
3278    t1 = tcg_temp_new();
3279
3280    gen_load_gpr(t0, rs);
3281    gen_load_gpr(t1, rt);
3282
3283    if (acc != 0) {
3284        check_dsp(ctx);
3285    }
3286
3287    switch (opc) {
3288    case OPC_DIV:
3289        {
3290            TCGv t2 = tcg_temp_new();
3291            TCGv t3 = tcg_temp_new();
3292            tcg_gen_ext32s_tl(t0, t0);
3293            tcg_gen_ext32s_tl(t1, t1);
3294            tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, INT_MIN);
3295            tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1);
3296            tcg_gen_and_tl(t2, t2, t3);
3297            tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
3298            tcg_gen_or_tl(t2, t2, t3);
3299            tcg_gen_movi_tl(t3, 0);
3300            tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
3301            tcg_gen_div_tl(cpu_LO[acc], t0, t1);
3302            tcg_gen_rem_tl(cpu_HI[acc], t0, t1);
3303            tcg_gen_ext32s_tl(cpu_LO[acc], cpu_LO[acc]);
3304            tcg_gen_ext32s_tl(cpu_HI[acc], cpu_HI[acc]);
3305        }
3306        break;
3307    case OPC_DIVU:
3308        {
3309            TCGv t2 = tcg_constant_tl(0);
3310            TCGv t3 = tcg_constant_tl(1);
3311            tcg_gen_ext32u_tl(t0, t0);
3312            tcg_gen_ext32u_tl(t1, t1);
3313            tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
3314            tcg_gen_divu_tl(cpu_LO[acc], t0, t1);
3315            tcg_gen_remu_tl(cpu_HI[acc], t0, t1);
3316            tcg_gen_ext32s_tl(cpu_LO[acc], cpu_LO[acc]);
3317            tcg_gen_ext32s_tl(cpu_HI[acc], cpu_HI[acc]);
3318        }
3319        break;
3320    case OPC_MULT:
3321        {
3322            TCGv_i32 t2 = tcg_temp_new_i32();
3323            TCGv_i32 t3 = tcg_temp_new_i32();
3324            tcg_gen_trunc_tl_i32(t2, t0);
3325            tcg_gen_trunc_tl_i32(t3, t1);
3326            tcg_gen_muls2_i32(t2, t3, t2, t3);
3327            tcg_gen_ext_i32_tl(cpu_LO[acc], t2);
3328            tcg_gen_ext_i32_tl(cpu_HI[acc], t3);
3329        }
3330        break;
3331    case OPC_MULTU:
3332        {
3333            TCGv_i32 t2 = tcg_temp_new_i32();
3334            TCGv_i32 t3 = tcg_temp_new_i32();
3335            tcg_gen_trunc_tl_i32(t2, t0);
3336            tcg_gen_trunc_tl_i32(t3, t1);
3337            tcg_gen_mulu2_i32(t2, t3, t2, t3);
3338            tcg_gen_ext_i32_tl(cpu_LO[acc], t2);
3339            tcg_gen_ext_i32_tl(cpu_HI[acc], t3);
3340        }
3341        break;
3342#if defined(TARGET_MIPS64)
3343    case OPC_DDIV:
3344        {
3345            TCGv t2 = tcg_temp_new();
3346            TCGv t3 = tcg_temp_new();
3347            tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, -1LL << 63);
3348            tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1LL);
3349            tcg_gen_and_tl(t2, t2, t3);
3350            tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
3351            tcg_gen_or_tl(t2, t2, t3);
3352            tcg_gen_movi_tl(t3, 0);
3353            tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
3354            tcg_gen_div_tl(cpu_LO[acc], t0, t1);
3355            tcg_gen_rem_tl(cpu_HI[acc], t0, t1);
3356        }
3357        break;
3358    case OPC_DDIVU:
3359        {
3360            TCGv t2 = tcg_constant_tl(0);
3361            TCGv t3 = tcg_constant_tl(1);
3362            tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
3363            tcg_gen_divu_i64(cpu_LO[acc], t0, t1);
3364            tcg_gen_remu_i64(cpu_HI[acc], t0, t1);
3365        }
3366        break;
3367    case OPC_DMULT:
3368        tcg_gen_muls2_i64(cpu_LO[acc], cpu_HI[acc], t0, t1);
3369        break;
3370    case OPC_DMULTU:
3371        tcg_gen_mulu2_i64(cpu_LO[acc], cpu_HI[acc], t0, t1);
3372        break;
3373#endif
3374    case OPC_MADD:
3375        {
3376            TCGv_i64 t2 = tcg_temp_new_i64();
3377            TCGv_i64 t3 = tcg_temp_new_i64();
3378
3379            tcg_gen_ext_tl_i64(t2, t0);
3380            tcg_gen_ext_tl_i64(t3, t1);
3381            tcg_gen_mul_i64(t2, t2, t3);
3382            tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
3383            tcg_gen_add_i64(t2, t2, t3);
3384            gen_move_low32(cpu_LO[acc], t2);
3385            gen_move_high32(cpu_HI[acc], t2);
3386        }
3387        break;
3388    case OPC_MADDU:
3389        {
3390            TCGv_i64 t2 = tcg_temp_new_i64();
3391            TCGv_i64 t3 = tcg_temp_new_i64();
3392
3393            tcg_gen_ext32u_tl(t0, t0);
3394            tcg_gen_ext32u_tl(t1, t1);
3395            tcg_gen_extu_tl_i64(t2, t0);
3396            tcg_gen_extu_tl_i64(t3, t1);
3397            tcg_gen_mul_i64(t2, t2, t3);
3398            tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
3399            tcg_gen_add_i64(t2, t2, t3);
3400            gen_move_low32(cpu_LO[acc], t2);
3401            gen_move_high32(cpu_HI[acc], t2);
3402        }
3403        break;
3404    case OPC_MSUB:
3405        {
3406            TCGv_i64 t2 = tcg_temp_new_i64();
3407            TCGv_i64 t3 = tcg_temp_new_i64();
3408
3409            tcg_gen_ext_tl_i64(t2, t0);
3410            tcg_gen_ext_tl_i64(t3, t1);
3411            tcg_gen_mul_i64(t2, t2, t3);
3412            tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
3413            tcg_gen_sub_i64(t2, t3, t2);
3414            gen_move_low32(cpu_LO[acc], t2);
3415            gen_move_high32(cpu_HI[acc], t2);
3416        }
3417        break;
3418    case OPC_MSUBU:
3419        {
3420            TCGv_i64 t2 = tcg_temp_new_i64();
3421            TCGv_i64 t3 = tcg_temp_new_i64();
3422
3423            tcg_gen_ext32u_tl(t0, t0);
3424            tcg_gen_ext32u_tl(t1, t1);
3425            tcg_gen_extu_tl_i64(t2, t0);
3426            tcg_gen_extu_tl_i64(t3, t1);
3427            tcg_gen_mul_i64(t2, t2, t3);
3428            tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
3429            tcg_gen_sub_i64(t2, t3, t2);
3430            gen_move_low32(cpu_LO[acc], t2);
3431            gen_move_high32(cpu_HI[acc], t2);
3432        }
3433        break;
3434    default:
3435        MIPS_INVAL("mul/div");
3436        gen_reserved_instruction(ctx);
3437        break;
3438    }
3439}
3440
3441/*
3442 * These MULT[U] and MADD[U] instructions implemented in for example
3443 * the Toshiba/Sony R5900 and the Toshiba TX19, TX39 and TX79 core
3444 * architectures are special three-operand variants with the syntax
3445 *
3446 *     MULT[U][1] rd, rs, rt
3447 *
3448 * such that
3449 *
3450 *     (rd, LO, HI) <- rs * rt
3451 *
3452 * and
3453 *
3454 *     MADD[U][1] rd, rs, rt
3455 *
3456 * such that
3457 *
3458 *     (rd, LO, HI) <- (LO, HI) + rs * rt
3459 *
3460 * where the low-order 32-bits of the result is placed into both the
3461 * GPR rd and the special register LO. The high-order 32-bits of the
3462 * result is placed into the special register HI.
3463 *
3464 * If the GPR rd is omitted in assembly language, it is taken to be 0,
3465 * which is the zero register that always reads as 0.
3466 */
3467static void gen_mul_txx9(DisasContext *ctx, uint32_t opc,
3468                         int rd, int rs, int rt)
3469{
3470    TCGv t0 = tcg_temp_new();
3471    TCGv t1 = tcg_temp_new();
3472    int acc = 0;
3473
3474    gen_load_gpr(t0, rs);
3475    gen_load_gpr(t1, rt);
3476
3477    switch (opc) {
3478    case MMI_OPC_MULT1:
3479        acc = 1;
3480        /* Fall through */
3481    case OPC_MULT:
3482        {
3483            TCGv_i32 t2 = tcg_temp_new_i32();
3484            TCGv_i32 t3 = tcg_temp_new_i32();
3485            tcg_gen_trunc_tl_i32(t2, t0);
3486            tcg_gen_trunc_tl_i32(t3, t1);
3487            tcg_gen_muls2_i32(t2, t3, t2, t3);
3488            if (rd) {
3489                tcg_gen_ext_i32_tl(cpu_gpr[rd], t2);
3490            }
3491            tcg_gen_ext_i32_tl(cpu_LO[acc], t2);
3492            tcg_gen_ext_i32_tl(cpu_HI[acc], t3);
3493        }
3494        break;
3495    case MMI_OPC_MULTU1:
3496        acc = 1;
3497        /* Fall through */
3498    case OPC_MULTU:
3499        {
3500            TCGv_i32 t2 = tcg_temp_new_i32();
3501            TCGv_i32 t3 = tcg_temp_new_i32();
3502            tcg_gen_trunc_tl_i32(t2, t0);
3503            tcg_gen_trunc_tl_i32(t3, t1);
3504            tcg_gen_mulu2_i32(t2, t3, t2, t3);
3505            if (rd) {
3506                tcg_gen_ext_i32_tl(cpu_gpr[rd], t2);
3507            }
3508            tcg_gen_ext_i32_tl(cpu_LO[acc], t2);
3509            tcg_gen_ext_i32_tl(cpu_HI[acc], t3);
3510        }
3511        break;
3512    case MMI_OPC_MADD1:
3513        acc = 1;
3514        /* Fall through */
3515    case MMI_OPC_MADD:
3516        {
3517            TCGv_i64 t2 = tcg_temp_new_i64();
3518            TCGv_i64 t3 = tcg_temp_new_i64();
3519
3520            tcg_gen_ext_tl_i64(t2, t0);
3521            tcg_gen_ext_tl_i64(t3, t1);
3522            tcg_gen_mul_i64(t2, t2, t3);
3523            tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
3524            tcg_gen_add_i64(t2, t2, t3);
3525            gen_move_low32(cpu_LO[acc], t2);
3526            gen_move_high32(cpu_HI[acc], t2);
3527            if (rd) {
3528                gen_move_low32(cpu_gpr[rd], t2);
3529            }
3530        }
3531        break;
3532    case MMI_OPC_MADDU1:
3533        acc = 1;
3534        /* Fall through */
3535    case MMI_OPC_MADDU:
3536        {
3537            TCGv_i64 t2 = tcg_temp_new_i64();
3538            TCGv_i64 t3 = tcg_temp_new_i64();
3539
3540            tcg_gen_ext32u_tl(t0, t0);
3541            tcg_gen_ext32u_tl(t1, t1);
3542            tcg_gen_extu_tl_i64(t2, t0);
3543            tcg_gen_extu_tl_i64(t3, t1);
3544            tcg_gen_mul_i64(t2, t2, t3);
3545            tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
3546            tcg_gen_add_i64(t2, t2, t3);
3547            gen_move_low32(cpu_LO[acc], t2);
3548            gen_move_high32(cpu_HI[acc], t2);
3549            if (rd) {
3550                gen_move_low32(cpu_gpr[rd], t2);
3551            }
3552        }
3553        break;
3554    default:
3555        MIPS_INVAL("mul/madd TXx9");
3556        gen_reserved_instruction(ctx);
3557        break;
3558    }
3559}
3560
3561static void gen_cl(DisasContext *ctx, uint32_t opc,
3562                   int rd, int rs)
3563{
3564    TCGv t0;
3565
3566    if (rd == 0) {
3567        /* Treat as NOP. */
3568        return;
3569    }
3570    t0 = cpu_gpr[rd];
3571    gen_load_gpr(t0, rs);
3572
3573    switch (opc) {
3574    case OPC_CLO:
3575    case R6_OPC_CLO:
3576#if defined(TARGET_MIPS64)
3577    case OPC_DCLO:
3578    case R6_OPC_DCLO:
3579#endif
3580        tcg_gen_not_tl(t0, t0);
3581        break;
3582    }
3583
3584    switch (opc) {
3585    case OPC_CLO:
3586    case R6_OPC_CLO:
3587    case OPC_CLZ:
3588    case R6_OPC_CLZ:
3589        tcg_gen_ext32u_tl(t0, t0);
3590        tcg_gen_clzi_tl(t0, t0, TARGET_LONG_BITS);
3591        tcg_gen_subi_tl(t0, t0, TARGET_LONG_BITS - 32);
3592        break;
3593#if defined(TARGET_MIPS64)
3594    case OPC_DCLO:
3595    case R6_OPC_DCLO:
3596    case OPC_DCLZ:
3597    case R6_OPC_DCLZ:
3598        tcg_gen_clzi_i64(t0, t0, 64);
3599        break;
3600#endif
3601    }
3602}
3603
3604/* Godson integer instructions */
3605static void gen_loongson_integer(DisasContext *ctx, uint32_t opc,
3606                                 int rd, int rs, int rt)
3607{
3608    TCGv t0, t1;
3609
3610    if (rd == 0) {
3611        /* Treat as NOP. */
3612        return;
3613    }
3614
3615    t0 = tcg_temp_new();
3616    t1 = tcg_temp_new();
3617    gen_load_gpr(t0, rs);
3618    gen_load_gpr(t1, rt);
3619
3620    switch (opc) {
3621    case OPC_MULT_G_2E:
3622    case OPC_MULT_G_2F:
3623        tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
3624        tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3625        break;
3626    case OPC_MULTU_G_2E:
3627    case OPC_MULTU_G_2F:
3628        tcg_gen_ext32u_tl(t0, t0);
3629        tcg_gen_ext32u_tl(t1, t1);
3630        tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
3631        tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3632        break;
3633    case OPC_DIV_G_2E:
3634    case OPC_DIV_G_2F:
3635        {
3636            TCGLabel *l1 = gen_new_label();
3637            TCGLabel *l2 = gen_new_label();
3638            TCGLabel *l3 = gen_new_label();
3639            tcg_gen_ext32s_tl(t0, t0);
3640            tcg_gen_ext32s_tl(t1, t1);
3641            tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
3642            tcg_gen_movi_tl(cpu_gpr[rd], 0);
3643            tcg_gen_br(l3);
3644            gen_set_label(l1);
3645            tcg_gen_brcondi_tl(TCG_COND_NE, t0, INT_MIN, l2);
3646            tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1, l2);
3647            tcg_gen_mov_tl(cpu_gpr[rd], t0);
3648            tcg_gen_br(l3);
3649            gen_set_label(l2);
3650            tcg_gen_div_tl(cpu_gpr[rd], t0, t1);
3651            tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3652            gen_set_label(l3);
3653        }
3654        break;
3655    case OPC_DIVU_G_2E:
3656    case OPC_DIVU_G_2F:
3657        {
3658            TCGLabel *l1 = gen_new_label();
3659            TCGLabel *l2 = gen_new_label();
3660            tcg_gen_ext32u_tl(t0, t0);
3661            tcg_gen_ext32u_tl(t1, t1);
3662            tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
3663            tcg_gen_movi_tl(cpu_gpr[rd], 0);
3664            tcg_gen_br(l2);
3665            gen_set_label(l1);
3666            tcg_gen_divu_tl(cpu_gpr[rd], t0, t1);
3667            tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3668            gen_set_label(l2);
3669        }
3670        break;
3671    case OPC_MOD_G_2E:
3672    case OPC_MOD_G_2F:
3673        {
3674            TCGLabel *l1 = gen_new_label();
3675            TCGLabel *l2 = gen_new_label();
3676            TCGLabel *l3 = gen_new_label();
3677            tcg_gen_ext32u_tl(t0, t0);
3678            tcg_gen_ext32u_tl(t1, t1);
3679            tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
3680            tcg_gen_brcondi_tl(TCG_COND_NE, t0, INT_MIN, l2);
3681            tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1, l2);
3682            gen_set_label(l1);
3683            tcg_gen_movi_tl(cpu_gpr[rd], 0);
3684            tcg_gen_br(l3);
3685            gen_set_label(l2);
3686            tcg_gen_rem_tl(cpu_gpr[rd], t0, t1);
3687            tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3688            gen_set_label(l3);
3689        }
3690        break;
3691    case OPC_MODU_G_2E:
3692    case OPC_MODU_G_2F:
3693        {
3694            TCGLabel *l1 = gen_new_label();
3695            TCGLabel *l2 = gen_new_label();
3696            tcg_gen_ext32u_tl(t0, t0);
3697            tcg_gen_ext32u_tl(t1, t1);
3698            tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
3699            tcg_gen_movi_tl(cpu_gpr[rd], 0);
3700            tcg_gen_br(l2);
3701            gen_set_label(l1);
3702            tcg_gen_remu_tl(cpu_gpr[rd], t0, t1);
3703            tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3704            gen_set_label(l2);
3705        }
3706        break;
3707#if defined(TARGET_MIPS64)
3708    case OPC_DMULT_G_2E:
3709    case OPC_DMULT_G_2F:
3710        tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
3711        break;
3712    case OPC_DMULTU_G_2E:
3713    case OPC_DMULTU_G_2F:
3714        tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
3715        break;
3716    case OPC_DDIV_G_2E:
3717    case OPC_DDIV_G_2F:
3718        {
3719            TCGLabel *l1 = gen_new_label();
3720            TCGLabel *l2 = gen_new_label();
3721            TCGLabel *l3 = gen_new_label();
3722            tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
3723            tcg_gen_movi_tl(cpu_gpr[rd], 0);
3724            tcg_gen_br(l3);
3725            gen_set_label(l1);
3726            tcg_gen_brcondi_tl(TCG_COND_NE, t0, -1LL << 63, l2);
3727            tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1LL, l2);
3728            tcg_gen_mov_tl(cpu_gpr[rd], t0);
3729            tcg_gen_br(l3);
3730            gen_set_label(l2);
3731            tcg_gen_div_tl(cpu_gpr[rd], t0, t1);
3732            gen_set_label(l3);
3733        }
3734        break;
3735    case OPC_DDIVU_G_2E:
3736    case OPC_DDIVU_G_2F:
3737        {
3738            TCGLabel *l1 = gen_new_label();
3739            TCGLabel *l2 = gen_new_label();
3740            tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
3741            tcg_gen_movi_tl(cpu_gpr[rd], 0);
3742            tcg_gen_br(l2);
3743            gen_set_label(l1);
3744            tcg_gen_divu_tl(cpu_gpr[rd], t0, t1);
3745            gen_set_label(l2);
3746        }
3747        break;
3748    case OPC_DMOD_G_2E:
3749    case OPC_DMOD_G_2F:
3750        {
3751            TCGLabel *l1 = gen_new_label();
3752            TCGLabel *l2 = gen_new_label();
3753            TCGLabel *l3 = gen_new_label();
3754            tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
3755            tcg_gen_brcondi_tl(TCG_COND_NE, t0, -1LL << 63, l2);
3756            tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1LL, l2);
3757            gen_set_label(l1);
3758            tcg_gen_movi_tl(cpu_gpr[rd], 0);
3759            tcg_gen_br(l3);
3760            gen_set_label(l2);
3761            tcg_gen_rem_tl(cpu_gpr[rd], t0, t1);
3762            gen_set_label(l3);
3763        }
3764        break;
3765    case OPC_DMODU_G_2E:
3766    case OPC_DMODU_G_2F:
3767        {
3768            TCGLabel *l1 = gen_new_label();
3769            TCGLabel *l2 = gen_new_label();
3770            tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
3771            tcg_gen_movi_tl(cpu_gpr[rd], 0);
3772            tcg_gen_br(l2);
3773            gen_set_label(l1);
3774            tcg_gen_remu_tl(cpu_gpr[rd], t0, t1);
3775            gen_set_label(l2);
3776        }
3777        break;
3778#endif
3779    }
3780}
3781
3782/* Loongson multimedia instructions */
3783static void gen_loongson_multimedia(DisasContext *ctx, int rd, int rs, int rt)
3784{
3785    uint32_t opc, shift_max;
3786    TCGv_i64 t0, t1;
3787    TCGCond cond;
3788
3789    opc = MASK_LMMI(ctx->opcode);
3790    check_cp1_enabled(ctx);
3791
3792    t0 = tcg_temp_new_i64();
3793    t1 = tcg_temp_new_i64();
3794    gen_load_fpr64(ctx, t0, rs);
3795    gen_load_fpr64(ctx, t1, rt);
3796
3797    switch (opc) {
3798    case OPC_PADDSH:
3799        gen_helper_paddsh(t0, t0, t1);
3800        break;
3801    case OPC_PADDUSH:
3802        gen_helper_paddush(t0, t0, t1);
3803        break;
3804    case OPC_PADDH:
3805        gen_helper_paddh(t0, t0, t1);
3806        break;
3807    case OPC_PADDW:
3808        gen_helper_paddw(t0, t0, t1);
3809        break;
3810    case OPC_PADDSB:
3811        gen_helper_paddsb(t0, t0, t1);
3812        break;
3813    case OPC_PADDUSB:
3814        gen_helper_paddusb(t0, t0, t1);
3815        break;
3816    case OPC_PADDB:
3817        gen_helper_paddb(t0, t0, t1);
3818        break;
3819
3820    case OPC_PSUBSH:
3821        gen_helper_psubsh(t0, t0, t1);
3822        break;
3823    case OPC_PSUBUSH:
3824        gen_helper_psubush(t0, t0, t1);
3825        break;
3826    case OPC_PSUBH:
3827        gen_helper_psubh(t0, t0, t1);
3828        break;
3829    case OPC_PSUBW:
3830        gen_helper_psubw(t0, t0, t1);
3831        break;
3832    case OPC_PSUBSB:
3833        gen_helper_psubsb(t0, t0, t1);
3834        break;
3835    case OPC_PSUBUSB:
3836        gen_helper_psubusb(t0, t0, t1);
3837        break;
3838    case OPC_PSUBB:
3839        gen_helper_psubb(t0, t0, t1);
3840        break;
3841
3842    case OPC_PSHUFH:
3843        gen_helper_pshufh(t0, t0, t1);
3844        break;
3845    case OPC_PACKSSWH:
3846        gen_helper_packsswh(t0, t0, t1);
3847        break;
3848    case OPC_PACKSSHB:
3849        gen_helper_packsshb(t0, t0, t1);
3850        break;
3851    case OPC_PACKUSHB:
3852        gen_helper_packushb(t0, t0, t1);
3853        break;
3854
3855    case OPC_PUNPCKLHW:
3856        gen_helper_punpcklhw(t0, t0, t1);
3857        break;
3858    case OPC_PUNPCKHHW:
3859        gen_helper_punpckhhw(t0, t0, t1);
3860        break;
3861    case OPC_PUNPCKLBH:
3862        gen_helper_punpcklbh(t0, t0, t1);
3863        break;
3864    case OPC_PUNPCKHBH:
3865        gen_helper_punpckhbh(t0, t0, t1);
3866        break;
3867    case OPC_PUNPCKLWD:
3868        gen_helper_punpcklwd(t0, t0, t1);
3869        break;
3870    case OPC_PUNPCKHWD:
3871        gen_helper_punpckhwd(t0, t0, t1);
3872        break;
3873
3874    case OPC_PAVGH:
3875        gen_helper_pavgh(t0, t0, t1);
3876        break;
3877    case OPC_PAVGB:
3878        gen_helper_pavgb(t0, t0, t1);
3879        break;
3880    case OPC_PMAXSH:
3881        gen_helper_pmaxsh(t0, t0, t1);
3882        break;
3883    case OPC_PMINSH:
3884        gen_helper_pminsh(t0, t0, t1);
3885        break;
3886    case OPC_PMAXUB:
3887        gen_helper_pmaxub(t0, t0, t1);
3888        break;
3889    case OPC_PMINUB:
3890        gen_helper_pminub(t0, t0, t1);
3891        break;
3892
3893    case OPC_PCMPEQW:
3894        gen_helper_pcmpeqw(t0, t0, t1);
3895        break;
3896    case OPC_PCMPGTW:
3897        gen_helper_pcmpgtw(t0, t0, t1);
3898        break;
3899    case OPC_PCMPEQH:
3900        gen_helper_pcmpeqh(t0, t0, t1);
3901        break;
3902    case OPC_PCMPGTH:
3903        gen_helper_pcmpgth(t0, t0, t1);
3904        break;
3905    case OPC_PCMPEQB:
3906        gen_helper_pcmpeqb(t0, t0, t1);
3907        break;
3908    case OPC_PCMPGTB:
3909        gen_helper_pcmpgtb(t0, t0, t1);
3910        break;
3911
3912    case OPC_PSLLW:
3913        gen_helper_psllw(t0, t0, t1);
3914        break;
3915    case OPC_PSLLH:
3916        gen_helper_psllh(t0, t0, t1);
3917        break;
3918    case OPC_PSRLW:
3919        gen_helper_psrlw(t0, t0, t1);
3920        break;
3921    case OPC_PSRLH:
3922        gen_helper_psrlh(t0, t0, t1);
3923        break;
3924    case OPC_PSRAW:
3925        gen_helper_psraw(t0, t0, t1);
3926        break;
3927    case OPC_PSRAH:
3928        gen_helper_psrah(t0, t0, t1);
3929        break;
3930
3931    case OPC_PMULLH:
3932        gen_helper_pmullh(t0, t0, t1);
3933        break;
3934    case OPC_PMULHH:
3935        gen_helper_pmulhh(t0, t0, t1);
3936        break;
3937    case OPC_PMULHUH:
3938        gen_helper_pmulhuh(t0, t0, t1);
3939        break;
3940    case OPC_PMADDHW:
3941        gen_helper_pmaddhw(t0, t0, t1);
3942        break;
3943
3944    case OPC_PASUBUB:
3945        gen_helper_pasubub(t0, t0, t1);
3946        break;
3947    case OPC_BIADD:
3948        gen_helper_biadd(t0, t0);
3949        break;
3950    case OPC_PMOVMSKB:
3951        gen_helper_pmovmskb(t0, t0);
3952        break;
3953
3954    case OPC_PADDD:
3955        tcg_gen_add_i64(t0, t0, t1);
3956        break;
3957    case OPC_PSUBD:
3958        tcg_gen_sub_i64(t0, t0, t1);
3959        break;
3960    case OPC_XOR_CP2:
3961        tcg_gen_xor_i64(t0, t0, t1);
3962        break;
3963    case OPC_NOR_CP2:
3964        tcg_gen_nor_i64(t0, t0, t1);
3965        break;
3966    case OPC_AND_CP2:
3967        tcg_gen_and_i64(t0, t0, t1);
3968        break;
3969    case OPC_OR_CP2:
3970        tcg_gen_or_i64(t0, t0, t1);
3971        break;
3972
3973    case OPC_PANDN:
3974        tcg_gen_andc_i64(t0, t1, t0);
3975        break;
3976
3977    case OPC_PINSRH_0:
3978        tcg_gen_deposit_i64(t0, t0, t1, 0, 16);
3979        break;
3980    case OPC_PINSRH_1:
3981        tcg_gen_deposit_i64(t0, t0, t1, 16, 16);
3982        break;
3983    case OPC_PINSRH_2:
3984        tcg_gen_deposit_i64(t0, t0, t1, 32, 16);
3985        break;
3986    case OPC_PINSRH_3:
3987        tcg_gen_deposit_i64(t0, t0, t1, 48, 16);
3988        break;
3989
3990    case OPC_PEXTRH:
3991        tcg_gen_andi_i64(t1, t1, 3);
3992        tcg_gen_shli_i64(t1, t1, 4);
3993        tcg_gen_shr_i64(t0, t0, t1);
3994        tcg_gen_ext16u_i64(t0, t0);
3995        break;
3996
3997    case OPC_ADDU_CP2:
3998        tcg_gen_add_i64(t0, t0, t1);
3999        tcg_gen_ext32s_i64(t0, t0);
4000        break;
4001    case OPC_SUBU_CP2:
4002        tcg_gen_sub_i64(t0, t0, t1);
4003        tcg_gen_ext32s_i64(t0, t0);
4004        break;
4005
4006    case OPC_SLL_CP2:
4007        shift_max = 32;
4008        goto do_shift;
4009    case OPC_SRL_CP2:
4010        shift_max = 32;
4011        goto do_shift;
4012    case OPC_SRA_CP2:
4013        shift_max = 32;
4014        goto do_shift;
4015    case OPC_DSLL_CP2:
4016        shift_max = 64;
4017        goto do_shift;
4018    case OPC_DSRL_CP2:
4019        shift_max = 64;
4020        goto do_shift;
4021    case OPC_DSRA_CP2:
4022        shift_max = 64;
4023        goto do_shift;
4024    do_shift:
4025        /* Make sure shift count isn't TCG undefined behaviour.  */
4026        tcg_gen_andi_i64(t1, t1, shift_max - 1);
4027
4028        switch (opc) {
4029        case OPC_SLL_CP2:
4030        case OPC_DSLL_CP2:
4031            tcg_gen_shl_i64(t0, t0, t1);
4032            break;
4033        case OPC_SRA_CP2:
4034        case OPC_DSRA_CP2:
4035            /*
4036             * Since SRA is UndefinedResult without sign-extended inputs,
4037             * we can treat SRA and DSRA the same.
4038             */
4039            tcg_gen_sar_i64(t0, t0, t1);
4040            break;
4041        case OPC_SRL_CP2:
4042            /* We want to shift in zeros for SRL; zero-extend first.  */
4043            tcg_gen_ext32u_i64(t0, t0);
4044            /* FALLTHRU */
4045        case OPC_DSRL_CP2:
4046            tcg_gen_shr_i64(t0, t0, t1);
4047            break;
4048        }
4049
4050        if (shift_max == 32) {
4051            tcg_gen_ext32s_i64(t0, t0);
4052        }
4053
4054        /* Shifts larger than MAX produce zero.  */
4055        tcg_gen_setcondi_i64(TCG_COND_LTU, t1, t1, shift_max);
4056        tcg_gen_neg_i64(t1, t1);
4057        tcg_gen_and_i64(t0, t0, t1);
4058        break;
4059
4060    case OPC_ADD_CP2:
4061    case OPC_DADD_CP2:
4062        {
4063            TCGv_i64 t2 = tcg_temp_new_i64();
4064            TCGLabel *lab = gen_new_label();
4065
4066            tcg_gen_mov_i64(t2, t0);
4067            tcg_gen_add_i64(t0, t1, t2);
4068            if (opc == OPC_ADD_CP2) {
4069                tcg_gen_ext32s_i64(t0, t0);
4070            }
4071            tcg_gen_xor_i64(t1, t1, t2);
4072            tcg_gen_xor_i64(t2, t2, t0);
4073            tcg_gen_andc_i64(t1, t2, t1);
4074            tcg_gen_brcondi_i64(TCG_COND_GE, t1, 0, lab);
4075            generate_exception(ctx, EXCP_OVERFLOW);
4076            gen_set_label(lab);
4077            break;
4078        }
4079
4080    case OPC_SUB_CP2:
4081    case OPC_DSUB_CP2:
4082        {
4083            TCGv_i64 t2 = tcg_temp_new_i64();
4084            TCGLabel *lab = gen_new_label();
4085
4086            tcg_gen_mov_i64(t2, t0);
4087            tcg_gen_sub_i64(t0, t1, t2);
4088            if (opc == OPC_SUB_CP2) {
4089                tcg_gen_ext32s_i64(t0, t0);
4090            }
4091            tcg_gen_xor_i64(t1, t1, t2);
4092            tcg_gen_xor_i64(t2, t2, t0);
4093            tcg_gen_and_i64(t1, t1, t2);
4094            tcg_gen_brcondi_i64(TCG_COND_GE, t1, 0, lab);
4095            generate_exception(ctx, EXCP_OVERFLOW);
4096            gen_set_label(lab);
4097            break;
4098        }
4099
4100    case OPC_PMULUW:
4101        tcg_gen_ext32u_i64(t0, t0);
4102        tcg_gen_ext32u_i64(t1, t1);
4103        tcg_gen_mul_i64(t0, t0, t1);
4104        break;
4105
4106    case OPC_SEQU_CP2:
4107    case OPC_SEQ_CP2:
4108        cond = TCG_COND_EQ;
4109        goto do_cc_cond;
4110        break;
4111    case OPC_SLTU_CP2:
4112        cond = TCG_COND_LTU;
4113        goto do_cc_cond;
4114        break;
4115    case OPC_SLT_CP2:
4116        cond = TCG_COND_LT;
4117        goto do_cc_cond;
4118        break;
4119    case OPC_SLEU_CP2:
4120        cond = TCG_COND_LEU;
4121        goto do_cc_cond;
4122        break;
4123    case OPC_SLE_CP2:
4124        cond = TCG_COND_LE;
4125    do_cc_cond:
4126        {
4127            int cc = (ctx->opcode >> 8) & 0x7;
4128            TCGv_i64 t64 = tcg_temp_new_i64();
4129            TCGv_i32 t32 = tcg_temp_new_i32();
4130
4131            tcg_gen_setcond_i64(cond, t64, t0, t1);
4132            tcg_gen_extrl_i64_i32(t32, t64);
4133            tcg_gen_deposit_i32(fpu_fcr31, fpu_fcr31, t32,
4134                                get_fp_bit(cc), 1);
4135        }
4136        return;
4137    default:
4138        MIPS_INVAL("loongson_cp2");
4139        gen_reserved_instruction(ctx);
4140        return;
4141    }
4142
4143    gen_store_fpr64(ctx, t0, rd);
4144}
4145
4146static void gen_loongson_lswc2(DisasContext *ctx, int rt,
4147                               int rs, int rd)
4148{
4149    TCGv t0, t1;
4150    TCGv_i32 fp0;
4151#if defined(TARGET_MIPS64)
4152    int lsq_rt1 = ctx->opcode & 0x1f;
4153    int lsq_offset = sextract32(ctx->opcode, 6, 9) << 4;
4154#endif
4155    int shf_offset = sextract32(ctx->opcode, 6, 8);
4156
4157    t0 = tcg_temp_new();
4158
4159    switch (MASK_LOONGSON_GSLSQ(ctx->opcode)) {
4160#if defined(TARGET_MIPS64)
4161    case OPC_GSLQ:
4162        t1 = tcg_temp_new();
4163        gen_base_offset_addr(ctx, t0, rs, lsq_offset);
4164        tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TEUQ |
4165                           ctx->default_tcg_memop_mask);
4166        gen_base_offset_addr(ctx, t0, rs, lsq_offset + 8);
4167        tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEUQ |
4168                           ctx->default_tcg_memop_mask);
4169        gen_store_gpr(t1, rt);
4170        gen_store_gpr(t0, lsq_rt1);
4171        break;
4172    case OPC_GSLQC1:
4173        check_cp1_enabled(ctx);
4174        t1 = tcg_temp_new();
4175        gen_base_offset_addr(ctx, t0, rs, lsq_offset);
4176        tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TEUQ |
4177                           ctx->default_tcg_memop_mask);
4178        gen_base_offset_addr(ctx, t0, rs, lsq_offset + 8);
4179        tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEUQ |
4180                           ctx->default_tcg_memop_mask);
4181        gen_store_fpr64(ctx, t1, rt);
4182        gen_store_fpr64(ctx, t0, lsq_rt1);
4183        break;
4184    case OPC_GSSQ:
4185        t1 = tcg_temp_new();
4186        gen_base_offset_addr(ctx, t0, rs, lsq_offset);
4187        gen_load_gpr(t1, rt);
4188        tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUQ |
4189                           ctx->default_tcg_memop_mask);
4190        gen_base_offset_addr(ctx, t0, rs, lsq_offset + 8);
4191        gen_load_gpr(t1, lsq_rt1);
4192        tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUQ |
4193                           ctx->default_tcg_memop_mask);
4194        break;
4195    case OPC_GSSQC1:
4196        check_cp1_enabled(ctx);
4197        t1 = tcg_temp_new();
4198        gen_base_offset_addr(ctx, t0, rs, lsq_offset);
4199        gen_load_fpr64(ctx, t1, rt);
4200        tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUQ |
4201                           ctx->default_tcg_memop_mask);
4202        gen_base_offset_addr(ctx, t0, rs, lsq_offset + 8);
4203        gen_load_fpr64(ctx, t1, lsq_rt1);
4204        tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUQ |
4205                           ctx->default_tcg_memop_mask);
4206        break;
4207#endif
4208    case OPC_GSSHFL:
4209        switch (MASK_LOONGSON_GSSHFLS(ctx->opcode)) {
4210        case OPC_GSLWLC1:
4211            check_cp1_enabled(ctx);
4212            gen_base_offset_addr(ctx, t0, rs, shf_offset);
4213            fp0 = tcg_temp_new_i32();
4214            gen_load_fpr32(ctx, fp0, rt);
4215            t1 = tcg_temp_new();
4216            tcg_gen_ext_i32_tl(t1, fp0);
4217            gen_lxl(ctx, t1, t0, ctx->mem_idx, MO_TEUL);
4218            tcg_gen_trunc_tl_i32(fp0, t1);
4219            gen_store_fpr32(ctx, fp0, rt);
4220            break;
4221        case OPC_GSLWRC1:
4222            check_cp1_enabled(ctx);
4223            gen_base_offset_addr(ctx, t0, rs, shf_offset);
4224            fp0 = tcg_temp_new_i32();
4225            gen_load_fpr32(ctx, fp0, rt);
4226            t1 = tcg_temp_new();
4227            tcg_gen_ext_i32_tl(t1, fp0);
4228            gen_lxr(ctx, t1, t0, ctx->mem_idx, MO_TEUL);
4229            tcg_gen_trunc_tl_i32(fp0, t1);
4230            gen_store_fpr32(ctx, fp0, rt);
4231            break;
4232#if defined(TARGET_MIPS64)
4233        case OPC_GSLDLC1:
4234            check_cp1_enabled(ctx);
4235            gen_base_offset_addr(ctx, t0, rs, shf_offset);
4236            t1 = tcg_temp_new();
4237            gen_load_fpr64(ctx, t1, rt);
4238            gen_lxl(ctx, t1, t0, ctx->mem_idx, MO_TEUQ);
4239            gen_store_fpr64(ctx, t1, rt);
4240            break;
4241        case OPC_GSLDRC1:
4242            check_cp1_enabled(ctx);
4243            gen_base_offset_addr(ctx, t0, rs, shf_offset);
4244            t1 = tcg_temp_new();
4245            gen_load_fpr64(ctx, t1, rt);
4246            gen_lxr(ctx, t1, t0, ctx->mem_idx, MO_TEUQ);
4247            gen_store_fpr64(ctx, t1, rt);
4248            break;
4249#endif
4250        default:
4251            MIPS_INVAL("loongson_gsshfl");
4252            gen_reserved_instruction(ctx);
4253            break;
4254        }
4255        break;
4256    case OPC_GSSHFS:
4257        switch (MASK_LOONGSON_GSSHFLS(ctx->opcode)) {
4258        case OPC_GSSWLC1:
4259            check_cp1_enabled(ctx);
4260            t1 = tcg_temp_new();
4261            gen_base_offset_addr(ctx, t0, rs, shf_offset);
4262            fp0 = tcg_temp_new_i32();
4263            gen_load_fpr32(ctx, fp0, rt);
4264            tcg_gen_ext_i32_tl(t1, fp0);
4265            gen_helper_0e2i(swl, t1, t0, ctx->mem_idx);
4266            break;
4267        case OPC_GSSWRC1:
4268            check_cp1_enabled(ctx);
4269            t1 = tcg_temp_new();
4270            gen_base_offset_addr(ctx, t0, rs, shf_offset);
4271            fp0 = tcg_temp_new_i32();
4272            gen_load_fpr32(ctx, fp0, rt);
4273            tcg_gen_ext_i32_tl(t1, fp0);
4274            gen_helper_0e2i(swr, t1, t0, ctx->mem_idx);
4275            break;
4276#if defined(TARGET_MIPS64)
4277        case OPC_GSSDLC1:
4278            check_cp1_enabled(ctx);
4279            t1 = tcg_temp_new();
4280            gen_base_offset_addr(ctx, t0, rs, shf_offset);
4281            gen_load_fpr64(ctx, t1, rt);
4282            gen_helper_0e2i(sdl, t1, t0, ctx->mem_idx);
4283            break;
4284        case OPC_GSSDRC1:
4285            check_cp1_enabled(ctx);
4286            t1 = tcg_temp_new();
4287            gen_base_offset_addr(ctx, t0, rs, shf_offset);
4288            gen_load_fpr64(ctx, t1, rt);
4289            gen_helper_0e2i(sdr, t1, t0, ctx->mem_idx);
4290            break;
4291#endif
4292        default:
4293            MIPS_INVAL("loongson_gsshfs");
4294            gen_reserved_instruction(ctx);
4295            break;
4296        }
4297        break;
4298    default:
4299        MIPS_INVAL("loongson_gslsq");
4300        gen_reserved_instruction(ctx);
4301        break;
4302    }
4303}
4304
4305/* Loongson EXT LDC2/SDC2 */
4306static void gen_loongson_lsdc2(DisasContext *ctx, int rt,
4307                               int rs, int rd)
4308{
4309    int offset = sextract32(ctx->opcode, 3, 8);
4310    uint32_t opc = MASK_LOONGSON_LSDC2(ctx->opcode);
4311    TCGv t0, t1;
4312    TCGv_i32 fp0;
4313
4314    /* Pre-conditions */
4315    switch (opc) {
4316    case OPC_GSLBX:
4317    case OPC_GSLHX:
4318    case OPC_GSLWX:
4319    case OPC_GSLDX:
4320        /* prefetch, implement as NOP */
4321        if (rt == 0) {
4322            return;
4323        }
4324        break;
4325    case OPC_GSSBX:
4326    case OPC_GSSHX:
4327    case OPC_GSSWX:
4328    case OPC_GSSDX:
4329        break;
4330    case OPC_GSLWXC1:
4331#if defined(TARGET_MIPS64)
4332    case OPC_GSLDXC1:
4333#endif
4334        check_cp1_enabled(ctx);
4335        /* prefetch, implement as NOP */
4336        if (rt == 0) {
4337            return;
4338        }
4339        break;
4340    case OPC_GSSWXC1:
4341#if defined(TARGET_MIPS64)
4342    case OPC_GSSDXC1:
4343#endif
4344        check_cp1_enabled(ctx);
4345        break;
4346    default:
4347        MIPS_INVAL("loongson_lsdc2");
4348        gen_reserved_instruction(ctx);
4349        return;
4350        break;
4351    }
4352
4353    t0 = tcg_temp_new();
4354
4355    gen_base_offset_addr(ctx, t0, rs, offset);
4356    gen_op_addr_add(ctx, t0, cpu_gpr[rd], t0);
4357
4358    switch (opc) {
4359    case OPC_GSLBX:
4360        tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_SB);
4361        gen_store_gpr(t0, rt);
4362        break;
4363    case OPC_GSLHX:
4364        tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TESW |
4365                           ctx->default_tcg_memop_mask);
4366        gen_store_gpr(t0, rt);
4367        break;
4368    case OPC_GSLWX:
4369        gen_base_offset_addr(ctx, t0, rs, offset);
4370        if (rd) {
4371            gen_op_addr_add(ctx, t0, cpu_gpr[rd], t0);
4372        }
4373        tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TESL |
4374                           ctx->default_tcg_memop_mask);
4375        gen_store_gpr(t0, rt);
4376        break;
4377#if defined(TARGET_MIPS64)
4378    case OPC_GSLDX:
4379        gen_base_offset_addr(ctx, t0, rs, offset);
4380        if (rd) {
4381            gen_op_addr_add(ctx, t0, cpu_gpr[rd], t0);
4382        }
4383        tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEUQ |
4384                           ctx->default_tcg_memop_mask);
4385        gen_store_gpr(t0, rt);
4386        break;
4387#endif
4388    case OPC_GSLWXC1:
4389        gen_base_offset_addr(ctx, t0, rs, offset);
4390        if (rd) {
4391            gen_op_addr_add(ctx, t0, cpu_gpr[rd], t0);
4392        }
4393        fp0 = tcg_temp_new_i32();
4394        tcg_gen_qemu_ld_i32(fp0, t0, ctx->mem_idx, MO_TESL |
4395                            ctx->default_tcg_memop_mask);
4396        gen_store_fpr32(ctx, fp0, rt);
4397        break;
4398#if defined(TARGET_MIPS64)
4399    case OPC_GSLDXC1:
4400        gen_base_offset_addr(ctx, t0, rs, offset);
4401        if (rd) {
4402            gen_op_addr_add(ctx, t0, cpu_gpr[rd], t0);
4403        }
4404        tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEUQ |
4405                           ctx->default_tcg_memop_mask);
4406        gen_store_fpr64(ctx, t0, rt);
4407        break;
4408#endif
4409    case OPC_GSSBX:
4410        t1 = tcg_temp_new();
4411        gen_load_gpr(t1, rt);
4412        tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_SB);
4413        break;
4414    case OPC_GSSHX:
4415        t1 = tcg_temp_new();
4416        gen_load_gpr(t1, rt);
4417        tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUW |
4418                           ctx->default_tcg_memop_mask);
4419        break;
4420    case OPC_GSSWX:
4421        t1 = tcg_temp_new();
4422        gen_load_gpr(t1, rt);
4423        tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL |
4424                           ctx->default_tcg_memop_mask);
4425        break;
4426#if defined(TARGET_MIPS64)
4427    case OPC_GSSDX:
4428        t1 = tcg_temp_new();
4429        gen_load_gpr(t1, rt);
4430        tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUQ |
4431                           ctx->default_tcg_memop_mask);
4432        break;
4433#endif
4434    case OPC_GSSWXC1:
4435        fp0 = tcg_temp_new_i32();
4436        gen_load_fpr32(ctx, fp0, rt);
4437        tcg_gen_qemu_st_i32(fp0, t0, ctx->mem_idx, MO_TEUL |
4438                            ctx->default_tcg_memop_mask);
4439        break;
4440#if defined(TARGET_MIPS64)
4441    case OPC_GSSDXC1:
4442        t1 = tcg_temp_new();
4443        gen_load_fpr64(ctx, t1, rt);
4444        tcg_gen_qemu_st_i64(t1, t0, ctx->mem_idx, MO_TEUQ |
4445                            ctx->default_tcg_memop_mask);
4446        break;
4447#endif
4448    default:
4449        break;
4450    }
4451}
4452
4453/* Traps */
4454static void gen_trap(DisasContext *ctx, uint32_t opc,
4455                     int rs, int rt, int16_t imm, int code)
4456{
4457    int cond;
4458    TCGv t0 = tcg_temp_new();
4459    TCGv t1 = tcg_temp_new();
4460
4461    cond = 0;
4462    /* Load needed operands */
4463    switch (opc) {
4464    case OPC_TEQ:
4465    case OPC_TGE:
4466    case OPC_TGEU:
4467    case OPC_TLT:
4468    case OPC_TLTU:
4469    case OPC_TNE:
4470        /* Compare two registers */
4471        if (rs != rt) {
4472            gen_load_gpr(t0, rs);
4473            gen_load_gpr(t1, rt);
4474            cond = 1;
4475        }
4476        break;
4477    case OPC_TEQI:
4478    case OPC_TGEI:
4479    case OPC_TGEIU:
4480    case OPC_TLTI:
4481    case OPC_TLTIU:
4482    case OPC_TNEI:
4483        /* Compare register to immediate */
4484        if (rs != 0 || imm != 0) {
4485            gen_load_gpr(t0, rs);
4486            tcg_gen_movi_tl(t1, (int32_t)imm);
4487            cond = 1;
4488        }
4489        break;
4490    }
4491    if (cond == 0) {
4492        switch (opc) {
4493        case OPC_TEQ:   /* rs == rs */
4494        case OPC_TEQI:  /* r0 == 0  */
4495        case OPC_TGE:   /* rs >= rs */
4496        case OPC_TGEI:  /* r0 >= 0  */
4497        case OPC_TGEU:  /* rs >= rs unsigned */
4498        case OPC_TGEIU: /* r0 >= 0  unsigned */
4499            /* Always trap */
4500#ifdef CONFIG_USER_ONLY
4501            /* Pass the break code along to cpu_loop. */
4502            tcg_gen_st_i32(tcg_constant_i32(code), cpu_env,
4503                           offsetof(CPUMIPSState, error_code));
4504#endif
4505            generate_exception_end(ctx, EXCP_TRAP);
4506            break;
4507        case OPC_TLT:   /* rs < rs           */
4508        case OPC_TLTI:  /* r0 < 0            */
4509        case OPC_TLTU:  /* rs < rs unsigned  */
4510        case OPC_TLTIU: /* r0 < 0  unsigned  */
4511        case OPC_TNE:   /* rs != rs          */
4512        case OPC_TNEI:  /* r0 != 0           */
4513            /* Never trap: treat as NOP. */
4514            break;
4515        }
4516    } else {
4517        TCGLabel *l1 = gen_new_label();
4518
4519        switch (opc) {
4520        case OPC_TEQ:
4521        case OPC_TEQI:
4522            tcg_gen_brcond_tl(TCG_COND_NE, t0, t1, l1);
4523            break;
4524        case OPC_TGE:
4525        case OPC_TGEI:
4526            tcg_gen_brcond_tl(TCG_COND_LT, t0, t1, l1);
4527            break;
4528        case OPC_TGEU:
4529        case OPC_TGEIU:
4530            tcg_gen_brcond_tl(TCG_COND_LTU, t0, t1, l1);
4531            break;
4532        case OPC_TLT:
4533        case OPC_TLTI:
4534            tcg_gen_brcond_tl(TCG_COND_GE, t0, t1, l1);
4535            break;
4536        case OPC_TLTU:
4537        case OPC_TLTIU:
4538            tcg_gen_brcond_tl(TCG_COND_GEU, t0, t1, l1);
4539            break;
4540        case OPC_TNE:
4541        case OPC_TNEI:
4542            tcg_gen_brcond_tl(TCG_COND_EQ, t0, t1, l1);
4543            break;
4544        }
4545#ifdef CONFIG_USER_ONLY
4546        /* Pass the break code along to cpu_loop. */
4547        tcg_gen_st_i32(tcg_constant_i32(code), cpu_env,
4548                       offsetof(CPUMIPSState, error_code));
4549#endif
4550        /* Like save_cpu_state, only don't update saved values. */
4551        if (ctx->base.pc_next != ctx->saved_pc) {
4552            gen_save_pc(ctx->base.pc_next);
4553        }
4554        if (ctx->hflags != ctx->saved_hflags) {
4555            tcg_gen_movi_i32(hflags, ctx->hflags);
4556        }
4557        generate_exception(ctx, EXCP_TRAP);
4558        gen_set_label(l1);
4559    }
4560}
4561
4562static void gen_goto_tb(DisasContext *ctx, int n, target_ulong dest)
4563{
4564    if (translator_use_goto_tb(&ctx->base, dest)) {
4565        tcg_gen_goto_tb(n);
4566        gen_save_pc(dest);
4567        tcg_gen_exit_tb(ctx->base.tb, n);
4568    } else {
4569        gen_save_pc(dest);
4570        tcg_gen_lookup_and_goto_ptr();
4571    }
4572}
4573
4574/* Branches (before delay slot) */
4575static void gen_compute_branch(DisasContext *ctx, uint32_t opc,
4576                               int insn_bytes,
4577                               int rs, int rt, int32_t offset,
4578                               int delayslot_size)
4579{
4580    target_ulong btgt = -1;
4581    int blink = 0;
4582    int bcond_compute = 0;
4583    TCGv t0 = tcg_temp_new();
4584    TCGv t1 = tcg_temp_new();
4585
4586    if (ctx->hflags & MIPS_HFLAG_BMASK) {
4587#ifdef MIPS_DEBUG_DISAS
4588        LOG_DISAS("Branch in delay / forbidden slot at PC 0x"
4589                  TARGET_FMT_lx "\n", ctx->base.pc_next);
4590#endif
4591        gen_reserved_instruction(ctx);
4592        goto out;
4593    }
4594
4595    /* Load needed operands */
4596    switch (opc) {
4597    case OPC_BEQ:
4598    case OPC_BEQL:
4599    case OPC_BNE:
4600    case OPC_BNEL:
4601        /* Compare two registers */
4602        if (rs != rt) {
4603            gen_load_gpr(t0, rs);
4604            gen_load_gpr(t1, rt);
4605            bcond_compute = 1;
4606        }
4607        btgt = ctx->base.pc_next + insn_bytes + offset;
4608        break;
4609    case OPC_BGEZ:
4610    case OPC_BGEZAL:
4611    case OPC_BGEZALL:
4612    case OPC_BGEZL:
4613    case OPC_BGTZ:
4614    case OPC_BGTZL:
4615    case OPC_BLEZ:
4616    case OPC_BLEZL:
4617    case OPC_BLTZ:
4618    case OPC_BLTZAL:
4619    case OPC_BLTZALL:
4620    case OPC_BLTZL:
4621        /* Compare to zero */
4622        if (rs != 0) {
4623            gen_load_gpr(t0, rs);
4624            bcond_compute = 1;
4625        }
4626        btgt = ctx->base.pc_next + insn_bytes + offset;
4627        break;
4628    case OPC_BPOSGE32:
4629#if defined(TARGET_MIPS64)
4630    case OPC_BPOSGE64:
4631        tcg_gen_andi_tl(t0, cpu_dspctrl, 0x7F);
4632#else
4633        tcg_gen_andi_tl(t0, cpu_dspctrl, 0x3F);
4634#endif
4635        bcond_compute = 1;
4636        btgt = ctx->base.pc_next + insn_bytes + offset;
4637        break;
4638    case OPC_J:
4639    case OPC_JAL:
4640        {
4641            /* Jump to immediate */
4642            int jal_mask = ctx->hflags & MIPS_HFLAG_M16 ? 0xF8000000
4643                                                        : 0xF0000000;
4644            btgt = ((ctx->base.pc_next + insn_bytes) & jal_mask)
4645                   | (uint32_t)offset;
4646            break;
4647        }
4648    case OPC_JALX:
4649        /* Jump to immediate */
4650        btgt = ((ctx->base.pc_next + insn_bytes) & (int32_t)0xF0000000) |
4651            (uint32_t)offset;
4652        break;
4653    case OPC_JR:
4654    case OPC_JALR:
4655        /* Jump to register */
4656        if (offset != 0 && offset != 16) {
4657            /*
4658             * Hint = 0 is JR/JALR, hint 16 is JR.HB/JALR.HB, the
4659             * others are reserved.
4660             */
4661            MIPS_INVAL("jump hint");
4662            gen_reserved_instruction(ctx);
4663            goto out;
4664        }
4665        gen_load_gpr(btarget, rs);
4666        break;
4667    default:
4668        MIPS_INVAL("branch/jump");
4669        gen_reserved_instruction(ctx);
4670        goto out;
4671    }
4672    if (bcond_compute == 0) {
4673        /* No condition to be computed */
4674        switch (opc) {
4675        case OPC_BEQ:     /* rx == rx        */
4676        case OPC_BEQL:    /* rx == rx likely */
4677        case OPC_BGEZ:    /* 0 >= 0          */
4678        case OPC_BGEZL:   /* 0 >= 0 likely   */
4679        case OPC_BLEZ:    /* 0 <= 0          */
4680        case OPC_BLEZL:   /* 0 <= 0 likely   */
4681            /* Always take */
4682            ctx->hflags |= MIPS_HFLAG_B;
4683            break;
4684        case OPC_BGEZAL:  /* 0 >= 0          */
4685        case OPC_BGEZALL: /* 0 >= 0 likely   */
4686            /* Always take and link */
4687            blink = 31;
4688            ctx->hflags |= MIPS_HFLAG_B;
4689            break;
4690        case OPC_BNE:     /* rx != rx        */
4691        case OPC_BGTZ:    /* 0 > 0           */
4692        case OPC_BLTZ:    /* 0 < 0           */
4693            /* Treat as NOP. */
4694            goto out;
4695        case OPC_BLTZAL:  /* 0 < 0           */
4696            /*
4697             * Handle as an unconditional branch to get correct delay
4698             * slot checking.
4699             */
4700            blink = 31;
4701            btgt = ctx->base.pc_next + insn_bytes + delayslot_size;
4702            ctx->hflags |= MIPS_HFLAG_B;
4703            break;
4704        case OPC_BLTZALL: /* 0 < 0 likely */
4705            tcg_gen_movi_tl(cpu_gpr[31], ctx->base.pc_next + 8);
4706            /* Skip the instruction in the delay slot */
4707            ctx->base.pc_next += 4;
4708            goto out;
4709        case OPC_BNEL:    /* rx != rx likely */
4710        case OPC_BGTZL:   /* 0 > 0 likely */
4711        case OPC_BLTZL:   /* 0 < 0 likely */
4712            /* Skip the instruction in the delay slot */
4713            ctx->base.pc_next += 4;
4714            goto out;
4715        case OPC_J:
4716            ctx->hflags |= MIPS_HFLAG_B;
4717            break;
4718        case OPC_JALX:
4719            ctx->hflags |= MIPS_HFLAG_BX;
4720            /* Fallthrough */
4721        case OPC_JAL:
4722            blink = 31;
4723            ctx->hflags |= MIPS_HFLAG_B;
4724            break;
4725        case OPC_JR:
4726            ctx->hflags |= MIPS_HFLAG_BR;
4727            break;
4728        case OPC_JALR:
4729            blink = rt;
4730            ctx->hflags |= MIPS_HFLAG_BR;
4731            break;
4732        default:
4733            MIPS_INVAL("branch/jump");
4734            gen_reserved_instruction(ctx);
4735            goto out;
4736        }
4737    } else {
4738        switch (opc) {
4739        case OPC_BEQ:
4740            tcg_gen_setcond_tl(TCG_COND_EQ, bcond, t0, t1);
4741            goto not_likely;
4742        case OPC_BEQL:
4743            tcg_gen_setcond_tl(TCG_COND_EQ, bcond, t0, t1);
4744            goto likely;
4745        case OPC_BNE:
4746            tcg_gen_setcond_tl(TCG_COND_NE, bcond, t0, t1);
4747            goto not_likely;
4748        case OPC_BNEL:
4749            tcg_gen_setcond_tl(TCG_COND_NE, bcond, t0, t1);
4750            goto likely;
4751        case OPC_BGEZ:
4752            tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
4753            goto not_likely;
4754        case OPC_BGEZL:
4755            tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
4756            goto likely;
4757        case OPC_BGEZAL:
4758            tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
4759            blink = 31;
4760            goto not_likely;
4761        case OPC_BGEZALL:
4762            tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
4763            blink = 31;
4764            goto likely;
4765        case OPC_BGTZ:
4766            tcg_gen_setcondi_tl(TCG_COND_GT, bcond, t0, 0);
4767            goto not_likely;
4768        case OPC_BGTZL:
4769            tcg_gen_setcondi_tl(TCG_COND_GT, bcond, t0, 0);
4770            goto likely;
4771        case OPC_BLEZ:
4772            tcg_gen_setcondi_tl(TCG_COND_LE, bcond, t0, 0);
4773            goto not_likely;
4774        case OPC_BLEZL:
4775            tcg_gen_setcondi_tl(TCG_COND_LE, bcond, t0, 0);
4776            goto likely;
4777        case OPC_BLTZ:
4778            tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
4779            goto not_likely;
4780        case OPC_BLTZL:
4781            tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
4782            goto likely;
4783        case OPC_BPOSGE32:
4784            tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 32);
4785            goto not_likely;
4786#if defined(TARGET_MIPS64)
4787        case OPC_BPOSGE64:
4788            tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 64);
4789            goto not_likely;
4790#endif
4791        case OPC_BLTZAL:
4792            tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
4793            blink = 31;
4794        not_likely:
4795            ctx->hflags |= MIPS_HFLAG_BC;
4796            break;
4797        case OPC_BLTZALL:
4798            tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
4799            blink = 31;
4800        likely:
4801            ctx->hflags |= MIPS_HFLAG_BL;
4802            break;
4803        default:
4804            MIPS_INVAL("conditional branch/jump");
4805            gen_reserved_instruction(ctx);
4806            goto out;
4807        }
4808    }
4809
4810    ctx->btarget = btgt;
4811
4812    switch (delayslot_size) {
4813    case 2:
4814        ctx->hflags |= MIPS_HFLAG_BDS16;
4815        break;
4816    case 4:
4817        ctx->hflags |= MIPS_HFLAG_BDS32;
4818        break;
4819    }
4820
4821    if (blink > 0) {
4822        int post_delay = insn_bytes + delayslot_size;
4823        int lowbit = !!(ctx->hflags & MIPS_HFLAG_M16);
4824
4825        tcg_gen_movi_tl(cpu_gpr[blink],
4826                        ctx->base.pc_next + post_delay + lowbit);
4827    }
4828
4829 out:
4830    if (insn_bytes == 2) {
4831        ctx->hflags |= MIPS_HFLAG_B16;
4832    }
4833}
4834
4835
4836/* special3 bitfield operations */
4837static void gen_bitops(DisasContext *ctx, uint32_t opc, int rt,
4838                       int rs, int lsb, int msb)
4839{
4840    TCGv t0 = tcg_temp_new();
4841    TCGv t1 = tcg_temp_new();
4842
4843    gen_load_gpr(t1, rs);
4844    switch (opc) {
4845    case OPC_EXT:
4846        if (lsb + msb > 31) {
4847            goto fail;
4848        }
4849        if (msb != 31) {
4850            tcg_gen_extract_tl(t0, t1, lsb, msb + 1);
4851        } else {
4852            /*
4853             * The two checks together imply that lsb == 0,
4854             * so this is a simple sign-extension.
4855             */
4856            tcg_gen_ext32s_tl(t0, t1);
4857        }
4858        break;
4859#if defined(TARGET_MIPS64)
4860    case OPC_DEXTU:
4861        lsb += 32;
4862        goto do_dext;
4863    case OPC_DEXTM:
4864        msb += 32;
4865        goto do_dext;
4866    case OPC_DEXT:
4867    do_dext:
4868        if (lsb + msb > 63) {
4869            goto fail;
4870        }
4871        tcg_gen_extract_tl(t0, t1, lsb, msb + 1);
4872        break;
4873#endif
4874    case OPC_INS:
4875        if (lsb > msb) {
4876            goto fail;
4877        }
4878        gen_load_gpr(t0, rt);
4879        tcg_gen_deposit_tl(t0, t0, t1, lsb, msb - lsb + 1);
4880        tcg_gen_ext32s_tl(t0, t0);
4881        break;
4882#if defined(TARGET_MIPS64)
4883    case OPC_DINSU:
4884        lsb += 32;
4885        /* FALLTHRU */
4886    case OPC_DINSM:
4887        msb += 32;
4888        /* FALLTHRU */
4889    case OPC_DINS:
4890        if (lsb > msb) {
4891            goto fail;
4892        }
4893        gen_load_gpr(t0, rt);
4894        tcg_gen_deposit_tl(t0, t0, t1, lsb, msb - lsb + 1);
4895        break;
4896#endif
4897    default:
4898fail:
4899        MIPS_INVAL("bitops");
4900        gen_reserved_instruction(ctx);
4901        return;
4902    }
4903    gen_store_gpr(t0, rt);
4904}
4905
4906static void gen_bshfl(DisasContext *ctx, uint32_t op2, int rt, int rd)
4907{
4908    TCGv t0;
4909
4910    if (rd == 0) {
4911        /* If no destination, treat it as a NOP. */
4912        return;
4913    }
4914
4915    t0 = tcg_temp_new();
4916    gen_load_gpr(t0, rt);
4917    switch (op2) {
4918    case OPC_WSBH:
4919        {
4920            TCGv t1 = tcg_temp_new();
4921            TCGv t2 = tcg_constant_tl(0x00FF00FF);
4922
4923            tcg_gen_shri_tl(t1, t0, 8);
4924            tcg_gen_and_tl(t1, t1, t2);
4925            tcg_gen_and_tl(t0, t0, t2);
4926            tcg_gen_shli_tl(t0, t0, 8);
4927            tcg_gen_or_tl(t0, t0, t1);
4928            tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
4929        }
4930        break;
4931    case OPC_SEB:
4932        tcg_gen_ext8s_tl(cpu_gpr[rd], t0);
4933        break;
4934    case OPC_SEH:
4935        tcg_gen_ext16s_tl(cpu_gpr[rd], t0);
4936        break;
4937#if defined(TARGET_MIPS64)
4938    case OPC_DSBH:
4939        {
4940            TCGv t1 = tcg_temp_new();
4941            TCGv t2 = tcg_constant_tl(0x00FF00FF00FF00FFULL);
4942
4943            tcg_gen_shri_tl(t1, t0, 8);
4944            tcg_gen_and_tl(t1, t1, t2);
4945            tcg_gen_and_tl(t0, t0, t2);
4946            tcg_gen_shli_tl(t0, t0, 8);
4947            tcg_gen_or_tl(cpu_gpr[rd], t0, t1);
4948        }
4949        break;
4950    case OPC_DSHD:
4951        {
4952            TCGv t1 = tcg_temp_new();
4953            TCGv t2 = tcg_constant_tl(0x0000FFFF0000FFFFULL);
4954
4955            tcg_gen_shri_tl(t1, t0, 16);
4956            tcg_gen_and_tl(t1, t1, t2);
4957            tcg_gen_and_tl(t0, t0, t2);
4958            tcg_gen_shli_tl(t0, t0, 16);
4959            tcg_gen_or_tl(t0, t0, t1);
4960            tcg_gen_shri_tl(t1, t0, 32);
4961            tcg_gen_shli_tl(t0, t0, 32);
4962            tcg_gen_or_tl(cpu_gpr[rd], t0, t1);
4963        }
4964        break;
4965#endif
4966    default:
4967        MIPS_INVAL("bsfhl");
4968        gen_reserved_instruction(ctx);
4969        return;
4970    }
4971}
4972
4973static void gen_align_bits(DisasContext *ctx, int wordsz, int rd, int rs,
4974                           int rt, int bits)
4975{
4976    TCGv t0;
4977    if (rd == 0) {
4978        /* Treat as NOP. */
4979        return;
4980    }
4981    t0 = tcg_temp_new();
4982    if (bits == 0 || bits == wordsz) {
4983        if (bits == 0) {
4984            gen_load_gpr(t0, rt);
4985        } else {
4986            gen_load_gpr(t0, rs);
4987        }
4988        switch (wordsz) {
4989        case 32:
4990            tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
4991            break;
4992#if defined(TARGET_MIPS64)
4993        case 64:
4994            tcg_gen_mov_tl(cpu_gpr[rd], t0);
4995            break;
4996#endif
4997        }
4998    } else {
4999        TCGv t1 = tcg_temp_new();
5000        gen_load_gpr(t0, rt);
5001        gen_load_gpr(t1, rs);
5002        switch (wordsz) {
5003        case 32:
5004            {
5005                TCGv_i64 t2 = tcg_temp_new_i64();
5006                tcg_gen_concat_tl_i64(t2, t1, t0);
5007                tcg_gen_shri_i64(t2, t2, 32 - bits);
5008                gen_move_low32(cpu_gpr[rd], t2);
5009            }
5010            break;
5011#if defined(TARGET_MIPS64)
5012        case 64:
5013            tcg_gen_shli_tl(t0, t0, bits);
5014            tcg_gen_shri_tl(t1, t1, 64 - bits);
5015            tcg_gen_or_tl(cpu_gpr[rd], t1, t0);
5016            break;
5017#endif
5018        }
5019    }
5020}
5021
5022void gen_align(DisasContext *ctx, int wordsz, int rd, int rs, int rt, int bp)
5023{
5024    gen_align_bits(ctx, wordsz, rd, rs, rt, bp * 8);
5025}
5026
5027static void gen_bitswap(DisasContext *ctx, int opc, int rd, int rt)
5028{
5029    TCGv t0;
5030    if (rd == 0) {
5031        /* Treat as NOP. */
5032        return;
5033    }
5034    t0 = tcg_temp_new();
5035    gen_load_gpr(t0, rt);
5036    switch (opc) {
5037    case OPC_BITSWAP:
5038        gen_helper_bitswap(cpu_gpr[rd], t0);
5039        break;
5040#if defined(TARGET_MIPS64)
5041    case OPC_DBITSWAP:
5042        gen_helper_dbitswap(cpu_gpr[rd], t0);
5043        break;
5044#endif
5045    }
5046}
5047
5048#ifndef CONFIG_USER_ONLY
5049/* CP0 (MMU and control) */
5050static inline void gen_mthc0_entrylo(TCGv arg, target_ulong off)
5051{
5052    TCGv_i64 t0 = tcg_temp_new_i64();
5053    TCGv_i64 t1 = tcg_temp_new_i64();
5054
5055    tcg_gen_ext_tl_i64(t0, arg);
5056    tcg_gen_ld_i64(t1, cpu_env, off);
5057#if defined(TARGET_MIPS64)
5058    tcg_gen_deposit_i64(t1, t1, t0, 30, 32);
5059#else
5060    tcg_gen_concat32_i64(t1, t1, t0);
5061#endif
5062    tcg_gen_st_i64(t1, cpu_env, off);
5063}
5064
5065static inline void gen_mthc0_store64(TCGv arg, target_ulong off)
5066{
5067    TCGv_i64 t0 = tcg_temp_new_i64();
5068    TCGv_i64 t1 = tcg_temp_new_i64();
5069
5070    tcg_gen_ext_tl_i64(t0, arg);
5071    tcg_gen_ld_i64(t1, cpu_env, off);
5072    tcg_gen_concat32_i64(t1, t1, t0);
5073    tcg_gen_st_i64(t1, cpu_env, off);
5074}
5075
5076static inline void gen_mfhc0_entrylo(TCGv arg, target_ulong off)
5077{
5078    TCGv_i64 t0 = tcg_temp_new_i64();
5079
5080    tcg_gen_ld_i64(t0, cpu_env, off);
5081#if defined(TARGET_MIPS64)
5082    tcg_gen_shri_i64(t0, t0, 30);
5083#else
5084    tcg_gen_shri_i64(t0, t0, 32);
5085#endif
5086    gen_move_low32(arg, t0);
5087}
5088
5089static inline void gen_mfhc0_load64(TCGv arg, target_ulong off, int shift)
5090{
5091    TCGv_i64 t0 = tcg_temp_new_i64();
5092
5093    tcg_gen_ld_i64(t0, cpu_env, off);
5094    tcg_gen_shri_i64(t0, t0, 32 + shift);
5095    gen_move_low32(arg, t0);
5096}
5097
5098static inline void gen_mfc0_load32(TCGv arg, target_ulong off)
5099{
5100    TCGv_i32 t0 = tcg_temp_new_i32();
5101
5102    tcg_gen_ld_i32(t0, cpu_env, off);
5103    tcg_gen_ext_i32_tl(arg, t0);
5104}
5105
5106static inline void gen_mfc0_load64(TCGv arg, target_ulong off)
5107{
5108    tcg_gen_ld_tl(arg, cpu_env, off);
5109    tcg_gen_ext32s_tl(arg, arg);
5110}
5111
5112static inline void gen_mtc0_store32(TCGv arg, target_ulong off)
5113{
5114    TCGv_i32 t0 = tcg_temp_new_i32();
5115
5116    tcg_gen_trunc_tl_i32(t0, arg);
5117    tcg_gen_st_i32(t0, cpu_env, off);
5118}
5119
5120#define CP0_CHECK(c)                            \
5121    do {                                        \
5122        if (!(c)) {                             \
5123            goto cp0_unimplemented;             \
5124        }                                       \
5125    } while (0)
5126
5127static void gen_mfhc0(DisasContext *ctx, TCGv arg, int reg, int sel)
5128{
5129    const char *register_name = "invalid";
5130
5131    switch (reg) {
5132    case CP0_REGISTER_02:
5133        switch (sel) {
5134        case 0:
5135            CP0_CHECK(ctx->hflags & MIPS_HFLAG_ELPA);
5136            gen_mfhc0_entrylo(arg, offsetof(CPUMIPSState, CP0_EntryLo0));
5137            register_name = "EntryLo0";
5138            break;
5139        default:
5140            goto cp0_unimplemented;
5141        }
5142        break;
5143    case CP0_REGISTER_03:
5144        switch (sel) {
5145        case CP0_REG03__ENTRYLO1:
5146            CP0_CHECK(ctx->hflags & MIPS_HFLAG_ELPA);
5147            gen_mfhc0_entrylo(arg, offsetof(CPUMIPSState, CP0_EntryLo1));
5148            register_name = "EntryLo1";
5149            break;
5150        default:
5151            goto cp0_unimplemented;
5152        }
5153        break;
5154    case CP0_REGISTER_09:
5155        switch (sel) {
5156        case CP0_REG09__SAAR:
5157            CP0_CHECK(ctx->saar);
5158            gen_helper_mfhc0_saar(arg, cpu_env);
5159            register_name = "SAAR";
5160            break;
5161        default:
5162            goto cp0_unimplemented;
5163        }
5164        break;
5165    case CP0_REGISTER_17:
5166        switch (sel) {
5167        case CP0_REG17__LLADDR:
5168            gen_mfhc0_load64(arg, offsetof(CPUMIPSState, CP0_LLAddr),
5169                             ctx->CP0_LLAddr_shift);
5170            register_name = "LLAddr";
5171            break;
5172        case CP0_REG17__MAAR:
5173            CP0_CHECK(ctx->mrp);
5174            gen_helper_mfhc0_maar(arg, cpu_env);
5175            register_name = "MAAR";
5176            break;
5177        default:
5178            goto cp0_unimplemented;
5179        }
5180        break;
5181    case CP0_REGISTER_19:
5182        switch (sel) {
5183        case CP0_REG19__WATCHHI0:
5184        case CP0_REG19__WATCHHI1:
5185        case CP0_REG19__WATCHHI2:
5186        case CP0_REG19__WATCHHI3:
5187        case CP0_REG19__WATCHHI4:
5188        case CP0_REG19__WATCHHI5:
5189        case CP0_REG19__WATCHHI6:
5190        case CP0_REG19__WATCHHI7:
5191            /* upper 32 bits are only available when Config5MI != 0 */
5192            CP0_CHECK(ctx->mi);
5193            gen_mfhc0_load64(arg, offsetof(CPUMIPSState, CP0_WatchHi[sel]), 0);
5194            register_name = "WatchHi";
5195            break;
5196        default:
5197            goto cp0_unimplemented;
5198        }
5199        break;
5200    case CP0_REGISTER_28:
5201        switch (sel) {
5202        case 0:
5203        case 2:
5204        case 4:
5205        case 6:
5206            gen_mfhc0_load64(arg, offsetof(CPUMIPSState, CP0_TagLo), 0);
5207            register_name = "TagLo";
5208            break;
5209        default:
5210            goto cp0_unimplemented;
5211        }
5212        break;
5213    default:
5214        goto cp0_unimplemented;
5215    }
5216    trace_mips_translate_c0("mfhc0", register_name, reg, sel);
5217    return;
5218
5219cp0_unimplemented:
5220    qemu_log_mask(LOG_UNIMP, "mfhc0 %s (reg %d sel %d)\n",
5221                  register_name, reg, sel);
5222    tcg_gen_movi_tl(arg, 0);
5223}
5224
5225static void gen_mthc0(DisasContext *ctx, TCGv arg, int reg, int sel)
5226{
5227    const char *register_name = "invalid";
5228    uint64_t mask = ctx->PAMask >> 36;
5229
5230    switch (reg) {
5231    case CP0_REGISTER_02:
5232        switch (sel) {
5233        case 0:
5234            CP0_CHECK(ctx->hflags & MIPS_HFLAG_ELPA);
5235            tcg_gen_andi_tl(arg, arg, mask);
5236            gen_mthc0_entrylo(arg, offsetof(CPUMIPSState, CP0_EntryLo0));
5237            register_name = "EntryLo0";
5238            break;
5239        default:
5240            goto cp0_unimplemented;
5241        }
5242        break;
5243    case CP0_REGISTER_03:
5244        switch (sel) {
5245        case CP0_REG03__ENTRYLO1:
5246            CP0_CHECK(ctx->hflags & MIPS_HFLAG_ELPA);
5247            tcg_gen_andi_tl(arg, arg, mask);
5248            gen_mthc0_entrylo(arg, offsetof(CPUMIPSState, CP0_EntryLo1));
5249            register_name = "EntryLo1";
5250            break;
5251        default:
5252            goto cp0_unimplemented;
5253        }
5254        break;
5255    case CP0_REGISTER_09:
5256        switch (sel) {
5257        case CP0_REG09__SAAR:
5258            CP0_CHECK(ctx->saar);
5259            gen_helper_mthc0_saar(cpu_env, arg);
5260            register_name = "SAAR";
5261            break;
5262        default:
5263            goto cp0_unimplemented;
5264        }
5265        break;
5266    case CP0_REGISTER_17:
5267        switch (sel) {
5268        case CP0_REG17__LLADDR:
5269            /*
5270             * LLAddr is read-only (the only exception is bit 0 if LLB is
5271             * supported); the CP0_LLAddr_rw_bitmask does not seem to be
5272             * relevant for modern MIPS cores supporting MTHC0, therefore
5273             * treating MTHC0 to LLAddr as NOP.
5274             */
5275            register_name = "LLAddr";
5276            break;
5277        case CP0_REG17__MAAR:
5278            CP0_CHECK(ctx->mrp);
5279            gen_helper_mthc0_maar(cpu_env, arg);
5280            register_name = "MAAR";
5281            break;
5282        default:
5283            goto cp0_unimplemented;
5284        }
5285        break;
5286    case CP0_REGISTER_19:
5287        switch (sel) {
5288        case CP0_REG19__WATCHHI0:
5289        case CP0_REG19__WATCHHI1:
5290        case CP0_REG19__WATCHHI2:
5291        case CP0_REG19__WATCHHI3:
5292        case CP0_REG19__WATCHHI4:
5293        case CP0_REG19__WATCHHI5:
5294        case CP0_REG19__WATCHHI6:
5295        case CP0_REG19__WATCHHI7:
5296            /* upper 32 bits are only available when Config5MI != 0 */
5297            CP0_CHECK(ctx->mi);
5298            gen_helper_0e1i(mthc0_watchhi, arg, sel);
5299            register_name = "WatchHi";
5300            break;
5301        default:
5302            goto cp0_unimplemented;
5303        }
5304        break;
5305    case CP0_REGISTER_28:
5306        switch (sel) {
5307        case 0:
5308        case 2:
5309        case 4:
5310        case 6:
5311            tcg_gen_andi_tl(arg, arg, mask);
5312            gen_mthc0_store64(arg, offsetof(CPUMIPSState, CP0_TagLo));
5313            register_name = "TagLo";
5314            break;
5315        default:
5316            goto cp0_unimplemented;
5317        }
5318        break;
5319    default:
5320        goto cp0_unimplemented;
5321    }
5322    trace_mips_translate_c0("mthc0", register_name, reg, sel);
5323    return;
5324
5325cp0_unimplemented:
5326    qemu_log_mask(LOG_UNIMP, "mthc0 %s (reg %d sel %d)\n",
5327                  register_name, reg, sel);
5328}
5329
5330static inline void gen_mfc0_unimplemented(DisasContext *ctx, TCGv arg)
5331{
5332    if (ctx->insn_flags & ISA_MIPS_R6) {
5333        tcg_gen_movi_tl(arg, 0);
5334    } else {
5335        tcg_gen_movi_tl(arg, ~0);
5336    }
5337}
5338
5339static void gen_mfc0(DisasContext *ctx, TCGv arg, int reg, int sel)
5340{
5341    const char *register_name = "invalid";
5342
5343    if (sel != 0) {
5344        check_insn(ctx, ISA_MIPS_R1);
5345    }
5346
5347    switch (reg) {
5348    case CP0_REGISTER_00:
5349        switch (sel) {
5350        case CP0_REG00__INDEX:
5351            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Index));
5352            register_name = "Index";
5353            break;
5354        case CP0_REG00__MVPCONTROL:
5355            CP0_CHECK(ctx->insn_flags & ASE_MT);
5356            gen_helper_mfc0_mvpcontrol(arg, cpu_env);
5357            register_name = "MVPControl";
5358            break;
5359        case CP0_REG00__MVPCONF0:
5360            CP0_CHECK(ctx->insn_flags & ASE_MT);
5361            gen_helper_mfc0_mvpconf0(arg, cpu_env);
5362            register_name = "MVPConf0";
5363            break;
5364        case CP0_REG00__MVPCONF1:
5365            CP0_CHECK(ctx->insn_flags & ASE_MT);
5366            gen_helper_mfc0_mvpconf1(arg, cpu_env);
5367            register_name = "MVPConf1";
5368            break;
5369        case CP0_REG00__VPCONTROL:
5370            CP0_CHECK(ctx->vp);
5371            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPControl));
5372            register_name = "VPControl";
5373            break;
5374        default:
5375            goto cp0_unimplemented;
5376        }
5377        break;
5378    case CP0_REGISTER_01:
5379        switch (sel) {
5380        case CP0_REG01__RANDOM:
5381            CP0_CHECK(!(ctx->insn_flags & ISA_MIPS_R6));
5382            gen_helper_mfc0_random(arg, cpu_env);
5383            register_name = "Random";
5384            break;
5385        case CP0_REG01__VPECONTROL:
5386            CP0_CHECK(ctx->insn_flags & ASE_MT);
5387            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEControl));
5388            register_name = "VPEControl";
5389            break;
5390        case CP0_REG01__VPECONF0:
5391            CP0_CHECK(ctx->insn_flags & ASE_MT);
5392            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf0));
5393            register_name = "VPEConf0";
5394            break;
5395        case CP0_REG01__VPECONF1:
5396            CP0_CHECK(ctx->insn_flags & ASE_MT);
5397            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf1));
5398            register_name = "VPEConf1";
5399            break;
5400        case CP0_REG01__YQMASK:
5401            CP0_CHECK(ctx->insn_flags & ASE_MT);
5402            gen_mfc0_load64(arg, offsetof(CPUMIPSState, CP0_YQMask));
5403            register_name = "YQMask";
5404            break;
5405        case CP0_REG01__VPESCHEDULE:
5406            CP0_CHECK(ctx->insn_flags & ASE_MT);
5407            gen_mfc0_load64(arg, offsetof(CPUMIPSState, CP0_VPESchedule));
5408            register_name = "VPESchedule";
5409            break;
5410        case CP0_REG01__VPESCHEFBACK:
5411            CP0_CHECK(ctx->insn_flags & ASE_MT);
5412            gen_mfc0_load64(arg, offsetof(CPUMIPSState, CP0_VPEScheFBack));
5413            register_name = "VPEScheFBack";
5414            break;
5415        case CP0_REG01__VPEOPT:
5416            CP0_CHECK(ctx->insn_flags & ASE_MT);
5417            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEOpt));
5418            register_name = "VPEOpt";
5419            break;
5420        default:
5421            goto cp0_unimplemented;
5422        }
5423        break;
5424    case CP0_REGISTER_02:
5425        switch (sel) {
5426        case CP0_REG02__ENTRYLO0:
5427            {
5428                TCGv_i64 tmp = tcg_temp_new_i64();
5429                tcg_gen_ld_i64(tmp, cpu_env,
5430                               offsetof(CPUMIPSState, CP0_EntryLo0));
5431#if defined(TARGET_MIPS64)
5432                if (ctx->rxi) {
5433                    /* Move RI/XI fields to bits 31:30 */
5434                    tcg_gen_shri_tl(arg, tmp, CP0EnLo_XI);
5435                    tcg_gen_deposit_tl(tmp, tmp, arg, 30, 2);
5436                }
5437#endif
5438                gen_move_low32(arg, tmp);
5439            }
5440            register_name = "EntryLo0";
5441            break;
5442        case CP0_REG02__TCSTATUS:
5443            CP0_CHECK(ctx->insn_flags & ASE_MT);
5444            gen_helper_mfc0_tcstatus(arg, cpu_env);
5445            register_name = "TCStatus";
5446            break;
5447        case CP0_REG02__TCBIND:
5448            CP0_CHECK(ctx->insn_flags & ASE_MT);
5449            gen_helper_mfc0_tcbind(arg, cpu_env);
5450            register_name = "TCBind";
5451            break;
5452        case CP0_REG02__TCRESTART:
5453            CP0_CHECK(ctx->insn_flags & ASE_MT);
5454            gen_helper_mfc0_tcrestart(arg, cpu_env);
5455            register_name = "TCRestart";
5456            break;
5457        case CP0_REG02__TCHALT:
5458            CP0_CHECK(ctx->insn_flags & ASE_MT);
5459            gen_helper_mfc0_tchalt(arg, cpu_env);
5460            register_name = "TCHalt";
5461            break;
5462        case CP0_REG02__TCCONTEXT:
5463            CP0_CHECK(ctx->insn_flags & ASE_MT);
5464            gen_helper_mfc0_tccontext(arg, cpu_env);
5465            register_name = "TCContext";
5466            break;
5467        case CP0_REG02__TCSCHEDULE:
5468            CP0_CHECK(ctx->insn_flags & ASE_MT);
5469            gen_helper_mfc0_tcschedule(arg, cpu_env);
5470            register_name = "TCSchedule";
5471            break;
5472        case CP0_REG02__TCSCHEFBACK:
5473            CP0_CHECK(ctx->insn_flags & ASE_MT);
5474            gen_helper_mfc0_tcschefback(arg, cpu_env);
5475            register_name = "TCScheFBack";
5476            break;
5477        default:
5478            goto cp0_unimplemented;
5479        }
5480        break;
5481    case CP0_REGISTER_03:
5482        switch (sel) {
5483        case CP0_REG03__ENTRYLO1:
5484            {
5485                TCGv_i64 tmp = tcg_temp_new_i64();
5486                tcg_gen_ld_i64(tmp, cpu_env,
5487                               offsetof(CPUMIPSState, CP0_EntryLo1));
5488#if defined(TARGET_MIPS64)
5489                if (ctx->rxi) {
5490                    /* Move RI/XI fields to bits 31:30 */
5491                    tcg_gen_shri_tl(arg, tmp, CP0EnLo_XI);
5492                    tcg_gen_deposit_tl(tmp, tmp, arg, 30, 2);
5493                }
5494#endif
5495                gen_move_low32(arg, tmp);
5496            }
5497            register_name = "EntryLo1";
5498            break;
5499        case CP0_REG03__GLOBALNUM:
5500            CP0_CHECK(ctx->vp);
5501            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_GlobalNumber));
5502            register_name = "GlobalNumber";
5503            break;
5504        default:
5505            goto cp0_unimplemented;
5506        }
5507        break;
5508    case CP0_REGISTER_04:
5509        switch (sel) {
5510        case CP0_REG04__CONTEXT:
5511            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_Context));
5512            tcg_gen_ext32s_tl(arg, arg);
5513            register_name = "Context";
5514            break;
5515        case CP0_REG04__CONTEXTCONFIG:
5516            /* SmartMIPS ASE */
5517            /* gen_helper_mfc0_contextconfig(arg); */
5518            register_name = "ContextConfig";
5519            goto cp0_unimplemented;
5520        case CP0_REG04__USERLOCAL:
5521            CP0_CHECK(ctx->ulri);
5522            tcg_gen_ld_tl(arg, cpu_env,
5523                          offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
5524            tcg_gen_ext32s_tl(arg, arg);
5525            register_name = "UserLocal";
5526            break;
5527        case CP0_REG04__MMID:
5528            CP0_CHECK(ctx->mi);
5529            gen_helper_mtc0_memorymapid(cpu_env, arg);
5530            register_name = "MMID";
5531            break;
5532        default:
5533            goto cp0_unimplemented;
5534        }
5535        break;
5536    case CP0_REGISTER_05:
5537        switch (sel) {
5538        case CP0_REG05__PAGEMASK:
5539            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageMask));
5540            register_name = "PageMask";
5541            break;
5542        case CP0_REG05__PAGEGRAIN:
5543            check_insn(ctx, ISA_MIPS_R2);
5544            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageGrain));
5545            register_name = "PageGrain";
5546            break;
5547        case CP0_REG05__SEGCTL0:
5548            CP0_CHECK(ctx->sc);
5549            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_SegCtl0));
5550            tcg_gen_ext32s_tl(arg, arg);
5551            register_name = "SegCtl0";
5552            break;
5553        case CP0_REG05__SEGCTL1:
5554            CP0_CHECK(ctx->sc);
5555            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_SegCtl1));
5556            tcg_gen_ext32s_tl(arg, arg);
5557            register_name = "SegCtl1";
5558            break;
5559        case CP0_REG05__SEGCTL2:
5560            CP0_CHECK(ctx->sc);
5561            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_SegCtl2));
5562            tcg_gen_ext32s_tl(arg, arg);
5563            register_name = "SegCtl2";
5564            break;
5565        case CP0_REG05__PWBASE:
5566            check_pw(ctx);
5567            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PWBase));
5568            register_name = "PWBase";
5569            break;
5570        case CP0_REG05__PWFIELD:
5571            check_pw(ctx);
5572            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PWField));
5573            register_name = "PWField";
5574            break;
5575        case CP0_REG05__PWSIZE:
5576            check_pw(ctx);
5577            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PWSize));
5578            register_name = "PWSize";
5579            break;
5580        default:
5581            goto cp0_unimplemented;
5582        }
5583        break;
5584    case CP0_REGISTER_06:
5585        switch (sel) {
5586        case CP0_REG06__WIRED:
5587            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Wired));
5588            register_name = "Wired";
5589            break;
5590        case CP0_REG06__SRSCONF0:
5591            check_insn(ctx, ISA_MIPS_R2);
5592            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf0));
5593            register_name = "SRSConf0";
5594            break;
5595        case CP0_REG06__SRSCONF1:
5596            check_insn(ctx, ISA_MIPS_R2);
5597            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf1));
5598            register_name = "SRSConf1";
5599            break;
5600        case CP0_REG06__SRSCONF2:
5601            check_insn(ctx, ISA_MIPS_R2);
5602            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf2));
5603            register_name = "SRSConf2";
5604            break;
5605        case CP0_REG06__SRSCONF3:
5606            check_insn(ctx, ISA_MIPS_R2);
5607            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf3));
5608            register_name = "SRSConf3";
5609            break;
5610        case CP0_REG06__SRSCONF4:
5611            check_insn(ctx, ISA_MIPS_R2);
5612            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf4));
5613            register_name = "SRSConf4";
5614            break;
5615        case CP0_REG06__PWCTL:
5616            check_pw(ctx);
5617            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PWCtl));
5618            register_name = "PWCtl";
5619            break;
5620        default:
5621            goto cp0_unimplemented;
5622        }
5623        break;
5624    case CP0_REGISTER_07:
5625        switch (sel) {
5626        case CP0_REG07__HWRENA:
5627            check_insn(ctx, ISA_MIPS_R2);
5628            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_HWREna));
5629            register_name = "HWREna";
5630            break;
5631        default:
5632            goto cp0_unimplemented;
5633        }
5634        break;
5635    case CP0_REGISTER_08:
5636        switch (sel) {
5637        case CP0_REG08__BADVADDR:
5638            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_BadVAddr));
5639            tcg_gen_ext32s_tl(arg, arg);
5640            register_name = "BadVAddr";
5641            break;
5642        case CP0_REG08__BADINSTR:
5643            CP0_CHECK(ctx->bi);
5644            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_BadInstr));
5645            register_name = "BadInstr";
5646            break;
5647        case CP0_REG08__BADINSTRP:
5648            CP0_CHECK(ctx->bp);
5649            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_BadInstrP));
5650            register_name = "BadInstrP";
5651            break;
5652        case CP0_REG08__BADINSTRX:
5653            CP0_CHECK(ctx->bi);
5654            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_BadInstrX));
5655            tcg_gen_andi_tl(arg, arg, ~0xffff);
5656            register_name = "BadInstrX";
5657            break;
5658        default:
5659            goto cp0_unimplemented;
5660        }
5661        break;
5662    case CP0_REGISTER_09:
5663        switch (sel) {
5664        case CP0_REG09__COUNT:
5665            /* Mark as an IO operation because we read the time.  */
5666            translator_io_start(&ctx->base);
5667
5668            gen_helper_mfc0_count(arg, cpu_env);
5669            /*
5670             * Break the TB to be able to take timer interrupts immediately
5671             * after reading count. DISAS_STOP isn't sufficient, we need to
5672             * ensure we break completely out of translated code.
5673             */
5674            gen_save_pc(ctx->base.pc_next + 4);
5675            ctx->base.is_jmp = DISAS_EXIT;
5676            register_name = "Count";
5677            break;
5678        case CP0_REG09__SAARI:
5679            CP0_CHECK(ctx->saar);
5680            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SAARI));
5681            register_name = "SAARI";
5682            break;
5683        case CP0_REG09__SAAR:
5684            CP0_CHECK(ctx->saar);
5685            gen_helper_mfc0_saar(arg, cpu_env);
5686            register_name = "SAAR";
5687            break;
5688        default:
5689            goto cp0_unimplemented;
5690        }
5691        break;
5692    case CP0_REGISTER_10:
5693        switch (sel) {
5694        case CP0_REG10__ENTRYHI:
5695            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryHi));
5696            tcg_gen_ext32s_tl(arg, arg);
5697            register_name = "EntryHi";
5698            break;
5699        default:
5700            goto cp0_unimplemented;
5701        }
5702        break;
5703    case CP0_REGISTER_11:
5704        switch (sel) {
5705        case CP0_REG11__COMPARE:
5706            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Compare));
5707            register_name = "Compare";
5708            break;
5709        /* 6,7 are implementation dependent */
5710        default:
5711            goto cp0_unimplemented;
5712        }
5713        break;
5714    case CP0_REGISTER_12:
5715        switch (sel) {
5716        case CP0_REG12__STATUS:
5717            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Status));
5718            register_name = "Status";
5719            break;
5720        case CP0_REG12__INTCTL:
5721            check_insn(ctx, ISA_MIPS_R2);
5722            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_IntCtl));
5723            register_name = "IntCtl";
5724            break;
5725        case CP0_REG12__SRSCTL:
5726            check_insn(ctx, ISA_MIPS_R2);
5727            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSCtl));
5728            register_name = "SRSCtl";
5729            break;
5730        case CP0_REG12__SRSMAP:
5731            check_insn(ctx, ISA_MIPS_R2);
5732            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSMap));
5733            register_name = "SRSMap";
5734            break;
5735        default:
5736            goto cp0_unimplemented;
5737       }
5738        break;
5739    case CP0_REGISTER_13:
5740        switch (sel) {
5741        case CP0_REG13__CAUSE:
5742            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Cause));
5743            register_name = "Cause";
5744            break;
5745        default:
5746            goto cp0_unimplemented;
5747       }
5748        break;
5749    case CP0_REGISTER_14:
5750        switch (sel) {
5751        case CP0_REG14__EPC:
5752            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EPC));
5753            tcg_gen_ext32s_tl(arg, arg);
5754            register_name = "EPC";
5755            break;
5756        default:
5757            goto cp0_unimplemented;
5758        }
5759        break;
5760    case CP0_REGISTER_15:
5761        switch (sel) {
5762        case CP0_REG15__PRID:
5763            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PRid));
5764            register_name = "PRid";
5765            break;
5766        case CP0_REG15__EBASE:
5767            check_insn(ctx, ISA_MIPS_R2);
5768            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EBase));
5769            tcg_gen_ext32s_tl(arg, arg);
5770            register_name = "EBase";
5771            break;
5772        case CP0_REG15__CMGCRBASE:
5773            check_insn(ctx, ISA_MIPS_R2);
5774            CP0_CHECK(ctx->cmgcr);
5775            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_CMGCRBase));
5776            tcg_gen_ext32s_tl(arg, arg);
5777            register_name = "CMGCRBase";
5778            break;
5779        default:
5780            goto cp0_unimplemented;
5781       }
5782        break;
5783    case CP0_REGISTER_16:
5784        switch (sel) {
5785        case CP0_REG16__CONFIG:
5786            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config0));
5787            register_name = "Config";
5788            break;
5789        case CP0_REG16__CONFIG1:
5790            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config1));
5791            register_name = "Config1";
5792            break;
5793        case CP0_REG16__CONFIG2:
5794            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config2));
5795            register_name = "Config2";
5796            break;
5797        case CP0_REG16__CONFIG3:
5798            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config3));
5799            register_name = "Config3";
5800            break;
5801        case CP0_REG16__CONFIG4:
5802            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config4));
5803            register_name = "Config4";
5804            break;
5805        case CP0_REG16__CONFIG5:
5806            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config5));
5807            register_name = "Config5";
5808            break;
5809        /* 6,7 are implementation dependent */
5810        case CP0_REG16__CONFIG6:
5811            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config6));
5812            register_name = "Config6";
5813            break;
5814        case CP0_REG16__CONFIG7:
5815            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config7));
5816            register_name = "Config7";
5817            break;
5818        default:
5819            goto cp0_unimplemented;
5820        }
5821        break;
5822    case CP0_REGISTER_17:
5823        switch (sel) {
5824        case CP0_REG17__LLADDR:
5825            gen_helper_mfc0_lladdr(arg, cpu_env);
5826            register_name = "LLAddr";
5827            break;
5828        case CP0_REG17__MAAR:
5829            CP0_CHECK(ctx->mrp);
5830            gen_helper_mfc0_maar(arg, cpu_env);
5831            register_name = "MAAR";
5832            break;
5833        case CP0_REG17__MAARI:
5834            CP0_CHECK(ctx->mrp);
5835            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_MAARI));
5836            register_name = "MAARI";
5837            break;
5838        default:
5839            goto cp0_unimplemented;
5840        }
5841        break;
5842    case CP0_REGISTER_18:
5843        switch (sel) {
5844        case CP0_REG18__WATCHLO0:
5845        case CP0_REG18__WATCHLO1:
5846        case CP0_REG18__WATCHLO2:
5847        case CP0_REG18__WATCHLO3:
5848        case CP0_REG18__WATCHLO4:
5849        case CP0_REG18__WATCHLO5:
5850        case CP0_REG18__WATCHLO6:
5851        case CP0_REG18__WATCHLO7:
5852            CP0_CHECK(ctx->CP0_Config1 & (1 << CP0C1_WR));
5853            gen_helper_1e0i(mfc0_watchlo, arg, sel);
5854            register_name = "WatchLo";
5855            break;
5856        default:
5857            goto cp0_unimplemented;
5858        }
5859        break;
5860    case CP0_REGISTER_19:
5861        switch (sel) {
5862        case CP0_REG19__WATCHHI0:
5863        case CP0_REG19__WATCHHI1:
5864        case CP0_REG19__WATCHHI2:
5865        case CP0_REG19__WATCHHI3:
5866        case CP0_REG19__WATCHHI4:
5867        case CP0_REG19__WATCHHI5:
5868        case CP0_REG19__WATCHHI6:
5869        case CP0_REG19__WATCHHI7:
5870            CP0_CHECK(ctx->CP0_Config1 & (1 << CP0C1_WR));
5871            gen_helper_1e0i(mfc0_watchhi, arg, sel);
5872            register_name = "WatchHi";
5873            break;
5874        default:
5875            goto cp0_unimplemented;
5876        }
5877        break;
5878    case CP0_REGISTER_20:
5879        switch (sel) {
5880        case CP0_REG20__XCONTEXT:
5881#if defined(TARGET_MIPS64)
5882            check_insn(ctx, ISA_MIPS3);
5883            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_XContext));
5884            tcg_gen_ext32s_tl(arg, arg);
5885            register_name = "XContext";
5886            break;
5887#endif
5888        default:
5889            goto cp0_unimplemented;
5890        }
5891        break;
5892    case CP0_REGISTER_21:
5893       /* Officially reserved, but sel 0 is used for R1x000 framemask */
5894        CP0_CHECK(!(ctx->insn_flags & ISA_MIPS_R6));
5895        switch (sel) {
5896        case 0:
5897            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Framemask));
5898            register_name = "Framemask";
5899            break;
5900        default:
5901            goto cp0_unimplemented;
5902        }
5903        break;
5904    case CP0_REGISTER_22:
5905        tcg_gen_movi_tl(arg, 0); /* unimplemented */
5906        register_name = "'Diagnostic"; /* implementation dependent */
5907        break;
5908    case CP0_REGISTER_23:
5909        switch (sel) {
5910        case CP0_REG23__DEBUG:
5911            gen_helper_mfc0_debug(arg, cpu_env); /* EJTAG support */
5912            register_name = "Debug";
5913            break;
5914        case CP0_REG23__TRACECONTROL:
5915            /* PDtrace support */
5916            /* gen_helper_mfc0_tracecontrol(arg);  */
5917            register_name = "TraceControl";
5918            goto cp0_unimplemented;
5919        case CP0_REG23__TRACECONTROL2:
5920            /* PDtrace support */
5921            /* gen_helper_mfc0_tracecontrol2(arg); */
5922            register_name = "TraceControl2";
5923            goto cp0_unimplemented;
5924        case CP0_REG23__USERTRACEDATA1:
5925            /* PDtrace support */
5926            /* gen_helper_mfc0_usertracedata1(arg);*/
5927            register_name = "UserTraceData1";
5928            goto cp0_unimplemented;
5929        case CP0_REG23__TRACEIBPC:
5930            /* PDtrace support */
5931            /* gen_helper_mfc0_traceibpc(arg);     */
5932            register_name = "TraceIBPC";
5933            goto cp0_unimplemented;
5934        case CP0_REG23__TRACEDBPC:
5935            /* PDtrace support */
5936            /* gen_helper_mfc0_tracedbpc(arg);     */
5937            register_name = "TraceDBPC";
5938            goto cp0_unimplemented;
5939        default:
5940            goto cp0_unimplemented;
5941        }
5942        break;
5943    case CP0_REGISTER_24:
5944        switch (sel) {
5945        case CP0_REG24__DEPC:
5946            /* EJTAG support */
5947            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_DEPC));
5948            tcg_gen_ext32s_tl(arg, arg);
5949            register_name = "DEPC";
5950            break;
5951        default:
5952            goto cp0_unimplemented;
5953        }
5954        break;
5955    case CP0_REGISTER_25:
5956        switch (sel) {
5957        case CP0_REG25__PERFCTL0:
5958            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Performance0));
5959            register_name = "Performance0";
5960            break;
5961        case CP0_REG25__PERFCNT0:
5962            /* gen_helper_mfc0_performance1(arg); */
5963            register_name = "Performance1";
5964            goto cp0_unimplemented;
5965        case CP0_REG25__PERFCTL1:
5966            /* gen_helper_mfc0_performance2(arg); */
5967            register_name = "Performance2";
5968            goto cp0_unimplemented;
5969        case CP0_REG25__PERFCNT1:
5970            /* gen_helper_mfc0_performance3(arg); */
5971            register_name = "Performance3";
5972            goto cp0_unimplemented;
5973        case CP0_REG25__PERFCTL2:
5974            /* gen_helper_mfc0_performance4(arg); */
5975            register_name = "Performance4";
5976            goto cp0_unimplemented;
5977        case CP0_REG25__PERFCNT2:
5978            /* gen_helper_mfc0_performance5(arg); */
5979            register_name = "Performance5";
5980            goto cp0_unimplemented;
5981        case CP0_REG25__PERFCTL3:
5982            /* gen_helper_mfc0_performance6(arg); */
5983            register_name = "Performance6";
5984            goto cp0_unimplemented;
5985        case CP0_REG25__PERFCNT3:
5986            /* gen_helper_mfc0_performance7(arg); */
5987            register_name = "Performance7";
5988            goto cp0_unimplemented;
5989        default:
5990            goto cp0_unimplemented;
5991        }
5992        break;
5993    case CP0_REGISTER_26:
5994        switch (sel) {
5995        case CP0_REG26__ERRCTL:
5996            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_ErrCtl));
5997            register_name = "ErrCtl";
5998            break;
5999        default:
6000            goto cp0_unimplemented;
6001        }
6002        break;
6003    case CP0_REGISTER_27:
6004        switch (sel) {
6005        case CP0_REG27__CACHERR:
6006            tcg_gen_movi_tl(arg, 0); /* unimplemented */
6007            register_name = "CacheErr";
6008            break;
6009        default:
6010            goto cp0_unimplemented;
6011        }
6012        break;
6013    case CP0_REGISTER_28:
6014        switch (sel) {
6015        case CP0_REG28__TAGLO:
6016        case CP0_REG28__TAGLO1:
6017        case CP0_REG28__TAGLO2:
6018        case CP0_REG28__TAGLO3:
6019            {
6020                TCGv_i64 tmp = tcg_temp_new_i64();
6021                tcg_gen_ld_i64(tmp, cpu_env, offsetof(CPUMIPSState, CP0_TagLo));
6022                gen_move_low32(arg, tmp);
6023            }
6024            register_name = "TagLo";
6025            break;
6026        case CP0_REG28__DATALO:
6027        case CP0_REG28__DATALO1:
6028        case CP0_REG28__DATALO2:
6029        case CP0_REG28__DATALO3:
6030            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataLo));
6031            register_name = "DataLo";
6032            break;
6033        default:
6034            goto cp0_unimplemented;
6035        }
6036        break;
6037    case CP0_REGISTER_29:
6038        switch (sel) {
6039        case CP0_REG29__TAGHI:
6040        case CP0_REG29__TAGHI1:
6041        case CP0_REG29__TAGHI2:
6042        case CP0_REG29__TAGHI3:
6043            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_TagHi));
6044            register_name = "TagHi";
6045            break;
6046        case CP0_REG29__DATAHI:
6047        case CP0_REG29__DATAHI1:
6048        case CP0_REG29__DATAHI2:
6049        case CP0_REG29__DATAHI3:
6050            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataHi));
6051            register_name = "DataHi";
6052            break;
6053        default:
6054            goto cp0_unimplemented;
6055        }
6056        break;
6057    case CP0_REGISTER_30:
6058        switch (sel) {
6059        case CP0_REG30__ERROREPC:
6060            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_ErrorEPC));
6061            tcg_gen_ext32s_tl(arg, arg);
6062            register_name = "ErrorEPC";
6063            break;
6064        default:
6065            goto cp0_unimplemented;
6066        }
6067        break;
6068    case CP0_REGISTER_31:
6069        switch (sel) {
6070        case CP0_REG31__DESAVE:
6071            /* EJTAG support */
6072            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DESAVE));
6073            register_name = "DESAVE";
6074            break;
6075        case CP0_REG31__KSCRATCH1:
6076        case CP0_REG31__KSCRATCH2:
6077        case CP0_REG31__KSCRATCH3:
6078        case CP0_REG31__KSCRATCH4:
6079        case CP0_REG31__KSCRATCH5:
6080        case CP0_REG31__KSCRATCH6:
6081            CP0_CHECK(ctx->kscrexist & (1 << sel));
6082            tcg_gen_ld_tl(arg, cpu_env,
6083                          offsetof(CPUMIPSState, CP0_KScratch[sel - 2]));
6084            tcg_gen_ext32s_tl(arg, arg);
6085            register_name = "KScratch";
6086            break;
6087        default:
6088            goto cp0_unimplemented;
6089        }
6090        break;
6091    default:
6092       goto cp0_unimplemented;
6093    }
6094    trace_mips_translate_c0("mfc0", register_name, reg, sel);
6095    return;
6096
6097cp0_unimplemented:
6098    qemu_log_mask(LOG_UNIMP, "mfc0 %s (reg %d sel %d)\n",
6099                  register_name, reg, sel);
6100    gen_mfc0_unimplemented(ctx, arg);
6101}
6102
6103static void gen_mtc0(DisasContext *ctx, TCGv arg, int reg, int sel)
6104{
6105    const char *register_name = "invalid";
6106    bool icount;
6107
6108    if (sel != 0) {
6109        check_insn(ctx, ISA_MIPS_R1);
6110    }
6111
6112    icount = translator_io_start(&ctx->base);
6113
6114    switch (reg) {
6115    case CP0_REGISTER_00:
6116        switch (sel) {
6117        case CP0_REG00__INDEX:
6118            gen_helper_mtc0_index(cpu_env, arg);
6119            register_name = "Index";
6120            break;
6121        case CP0_REG00__MVPCONTROL:
6122            CP0_CHECK(ctx->insn_flags & ASE_MT);
6123            gen_helper_mtc0_mvpcontrol(cpu_env, arg);
6124            register_name = "MVPControl";
6125            break;
6126        case CP0_REG00__MVPCONF0:
6127            CP0_CHECK(ctx->insn_flags & ASE_MT);
6128            /* ignored */
6129            register_name = "MVPConf0";
6130            break;
6131        case CP0_REG00__MVPCONF1:
6132            CP0_CHECK(ctx->insn_flags & ASE_MT);
6133            /* ignored */
6134            register_name = "MVPConf1";
6135            break;
6136        case CP0_REG00__VPCONTROL:
6137            CP0_CHECK(ctx->vp);
6138            /* ignored */
6139            register_name = "VPControl";
6140            break;
6141        default:
6142            goto cp0_unimplemented;
6143        }
6144        break;
6145    case CP0_REGISTER_01:
6146        switch (sel) {
6147        case CP0_REG01__RANDOM:
6148            /* ignored */
6149            register_name = "Random";
6150            break;
6151        case CP0_REG01__VPECONTROL:
6152            CP0_CHECK(ctx->insn_flags & ASE_MT);
6153            gen_helper_mtc0_vpecontrol(cpu_env, arg);
6154            register_name = "VPEControl";
6155            break;
6156        case CP0_REG01__VPECONF0:
6157            CP0_CHECK(ctx->insn_flags & ASE_MT);
6158            gen_helper_mtc0_vpeconf0(cpu_env, arg);
6159            register_name = "VPEConf0";
6160            break;
6161        case CP0_REG01__VPECONF1:
6162            CP0_CHECK(ctx->insn_flags & ASE_MT);
6163            gen_helper_mtc0_vpeconf1(cpu_env, arg);
6164            register_name = "VPEConf1";
6165            break;
6166        case CP0_REG01__YQMASK:
6167            CP0_CHECK(ctx->insn_flags & ASE_MT);
6168            gen_helper_mtc0_yqmask(cpu_env, arg);
6169            register_name = "YQMask";
6170            break;
6171        case CP0_REG01__VPESCHEDULE:
6172            CP0_CHECK(ctx->insn_flags & ASE_MT);
6173            tcg_gen_st_tl(arg, cpu_env,
6174                          offsetof(CPUMIPSState, CP0_VPESchedule));
6175            register_name = "VPESchedule";
6176            break;
6177        case CP0_REG01__VPESCHEFBACK:
6178            CP0_CHECK(ctx->insn_flags & ASE_MT);
6179            tcg_gen_st_tl(arg, cpu_env,
6180                          offsetof(CPUMIPSState, CP0_VPEScheFBack));
6181            register_name = "VPEScheFBack";
6182            break;
6183        case CP0_REG01__VPEOPT:
6184            CP0_CHECK(ctx->insn_flags & ASE_MT);
6185            gen_helper_mtc0_vpeopt(cpu_env, arg);
6186            register_name = "VPEOpt";
6187            break;
6188        default:
6189            goto cp0_unimplemented;
6190        }
6191        break;
6192    case CP0_REGISTER_02:
6193        switch (sel) {
6194        case CP0_REG02__ENTRYLO0:
6195            gen_helper_mtc0_entrylo0(cpu_env, arg);
6196            register_name = "EntryLo0";
6197            break;
6198        case CP0_REG02__TCSTATUS:
6199            CP0_CHECK(ctx->insn_flags & ASE_MT);
6200            gen_helper_mtc0_tcstatus(cpu_env, arg);
6201            register_name = "TCStatus";
6202            break;
6203        case CP0_REG02__TCBIND:
6204            CP0_CHECK(ctx->insn_flags & ASE_MT);
6205            gen_helper_mtc0_tcbind(cpu_env, arg);
6206            register_name = "TCBind";
6207            break;
6208        case CP0_REG02__TCRESTART:
6209            CP0_CHECK(ctx->insn_flags & ASE_MT);
6210            gen_helper_mtc0_tcrestart(cpu_env, arg);
6211            register_name = "TCRestart";
6212            break;
6213        case CP0_REG02__TCHALT:
6214            CP0_CHECK(ctx->insn_flags & ASE_MT);
6215            gen_helper_mtc0_tchalt(cpu_env, arg);
6216            register_name = "TCHalt";
6217            break;
6218        case CP0_REG02__TCCONTEXT:
6219            CP0_CHECK(ctx->insn_flags & ASE_MT);
6220            gen_helper_mtc0_tccontext(cpu_env, arg);
6221            register_name = "TCContext";
6222            break;
6223        case CP0_REG02__TCSCHEDULE:
6224            CP0_CHECK(ctx->insn_flags & ASE_MT);
6225            gen_helper_mtc0_tcschedule(cpu_env, arg);
6226            register_name = "TCSchedule";
6227            break;
6228        case CP0_REG02__TCSCHEFBACK:
6229            CP0_CHECK(ctx->insn_flags & ASE_MT);
6230            gen_helper_mtc0_tcschefback(cpu_env, arg);
6231            register_name = "TCScheFBack";
6232            break;
6233        default:
6234            goto cp0_unimplemented;
6235        }
6236        break;
6237    case CP0_REGISTER_03:
6238        switch (sel) {
6239        case CP0_REG03__ENTRYLO1:
6240            gen_helper_mtc0_entrylo1(cpu_env, arg);
6241            register_name = "EntryLo1";
6242            break;
6243        case CP0_REG03__GLOBALNUM:
6244            CP0_CHECK(ctx->vp);
6245            /* ignored */
6246            register_name = "GlobalNumber";
6247            break;
6248        default:
6249            goto cp0_unimplemented;
6250        }
6251        break;
6252    case CP0_REGISTER_04:
6253        switch (sel) {
6254        case CP0_REG04__CONTEXT:
6255            gen_helper_mtc0_context(cpu_env, arg);
6256            register_name = "Context";
6257            break;
6258        case CP0_REG04__CONTEXTCONFIG:
6259            /* SmartMIPS ASE */
6260            /* gen_helper_mtc0_contextconfig(arg); */
6261            register_name = "ContextConfig";
6262            goto cp0_unimplemented;
6263        case CP0_REG04__USERLOCAL:
6264            CP0_CHECK(ctx->ulri);
6265            tcg_gen_st_tl(arg, cpu_env,
6266                          offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
6267            register_name = "UserLocal";
6268            break;
6269        case CP0_REG04__MMID:
6270            CP0_CHECK(ctx->mi);
6271            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_MemoryMapID));
6272            register_name = "MMID";
6273            break;
6274        default:
6275            goto cp0_unimplemented;
6276        }
6277        break;
6278    case CP0_REGISTER_05:
6279        switch (sel) {
6280        case CP0_REG05__PAGEMASK:
6281            gen_helper_mtc0_pagemask(cpu_env, arg);
6282            register_name = "PageMask";
6283            break;
6284        case CP0_REG05__PAGEGRAIN:
6285            check_insn(ctx, ISA_MIPS_R2);
6286            gen_helper_mtc0_pagegrain(cpu_env, arg);
6287            register_name = "PageGrain";
6288            ctx->base.is_jmp = DISAS_STOP;
6289            break;
6290        case CP0_REG05__SEGCTL0:
6291            CP0_CHECK(ctx->sc);
6292            gen_helper_mtc0_segctl0(cpu_env, arg);
6293            register_name = "SegCtl0";
6294            break;
6295        case CP0_REG05__SEGCTL1:
6296            CP0_CHECK(ctx->sc);
6297            gen_helper_mtc0_segctl1(cpu_env, arg);
6298            register_name = "SegCtl1";
6299            break;
6300        case CP0_REG05__SEGCTL2:
6301            CP0_CHECK(ctx->sc);
6302            gen_helper_mtc0_segctl2(cpu_env, arg);
6303            register_name = "SegCtl2";
6304            break;
6305        case CP0_REG05__PWBASE:
6306            check_pw(ctx);
6307            gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_PWBase));
6308            register_name = "PWBase";
6309            break;
6310        case CP0_REG05__PWFIELD:
6311            check_pw(ctx);
6312            gen_helper_mtc0_pwfield(cpu_env, arg);
6313            register_name = "PWField";
6314            break;
6315        case CP0_REG05__PWSIZE:
6316            check_pw(ctx);
6317            gen_helper_mtc0_pwsize(cpu_env, arg);
6318            register_name = "PWSize";
6319            break;
6320        default:
6321            goto cp0_unimplemented;
6322        }
6323        break;
6324    case CP0_REGISTER_06:
6325        switch (sel) {
6326        case CP0_REG06__WIRED:
6327            gen_helper_mtc0_wired(cpu_env, arg);
6328            register_name = "Wired";
6329            break;
6330        case CP0_REG06__SRSCONF0:
6331            check_insn(ctx, ISA_MIPS_R2);
6332            gen_helper_mtc0_srsconf0(cpu_env, arg);
6333            register_name = "SRSConf0";
6334            break;
6335        case CP0_REG06__SRSCONF1:
6336            check_insn(ctx, ISA_MIPS_R2);
6337            gen_helper_mtc0_srsconf1(cpu_env, arg);
6338            register_name = "SRSConf1";
6339            break;
6340        case CP0_REG06__SRSCONF2:
6341            check_insn(ctx, ISA_MIPS_R2);
6342            gen_helper_mtc0_srsconf2(cpu_env, arg);
6343            register_name = "SRSConf2";
6344            break;
6345        case CP0_REG06__SRSCONF3:
6346            check_insn(ctx, ISA_MIPS_R2);
6347            gen_helper_mtc0_srsconf3(cpu_env, arg);
6348            register_name = "SRSConf3";
6349            break;
6350        case CP0_REG06__SRSCONF4:
6351            check_insn(ctx, ISA_MIPS_R2);
6352            gen_helper_mtc0_srsconf4(cpu_env, arg);
6353            register_name = "SRSConf4";
6354            break;
6355        case CP0_REG06__PWCTL:
6356            check_pw(ctx);
6357            gen_helper_mtc0_pwctl(cpu_env, arg);
6358            register_name = "PWCtl";
6359            break;
6360        default:
6361            goto cp0_unimplemented;
6362        }
6363        break;
6364    case CP0_REGISTER_07:
6365        switch (sel) {
6366        case CP0_REG07__HWRENA:
6367            check_insn(ctx, ISA_MIPS_R2);
6368            gen_helper_mtc0_hwrena(cpu_env, arg);
6369            ctx->base.is_jmp = DISAS_STOP;
6370            register_name = "HWREna";
6371            break;
6372        default:
6373            goto cp0_unimplemented;
6374        }
6375        break;
6376    case CP0_REGISTER_08:
6377        switch (sel) {
6378        case CP0_REG08__BADVADDR:
6379            /* ignored */
6380            register_name = "BadVAddr";
6381            break;
6382        case CP0_REG08__BADINSTR:
6383            /* ignored */
6384            register_name = "BadInstr";
6385            break;
6386        case CP0_REG08__BADINSTRP:
6387            /* ignored */
6388            register_name = "BadInstrP";
6389            break;
6390        case CP0_REG08__BADINSTRX:
6391            /* ignored */
6392            register_name = "BadInstrX";
6393            break;
6394        default:
6395            goto cp0_unimplemented;
6396        }
6397        break;
6398    case CP0_REGISTER_09:
6399        switch (sel) {
6400        case CP0_REG09__COUNT:
6401            gen_helper_mtc0_count(cpu_env, arg);
6402            register_name = "Count";
6403            break;
6404        case CP0_REG09__SAARI:
6405            CP0_CHECK(ctx->saar);
6406            gen_helper_mtc0_saari(cpu_env, arg);
6407            register_name = "SAARI";
6408            break;
6409        case CP0_REG09__SAAR:
6410            CP0_CHECK(ctx->saar);
6411            gen_helper_mtc0_saar(cpu_env, arg);
6412            register_name = "SAAR";
6413            break;
6414        default:
6415            goto cp0_unimplemented;
6416        }
6417        break;
6418    case CP0_REGISTER_10:
6419        switch (sel) {
6420        case CP0_REG10__ENTRYHI:
6421            gen_helper_mtc0_entryhi(cpu_env, arg);
6422            register_name = "EntryHi";
6423            break;
6424        default:
6425            goto cp0_unimplemented;
6426        }
6427        break;
6428    case CP0_REGISTER_11:
6429        switch (sel) {
6430        case CP0_REG11__COMPARE:
6431            gen_helper_mtc0_compare(cpu_env, arg);
6432            register_name = "Compare";
6433            break;
6434        /* 6,7 are implementation dependent */
6435        default:
6436            goto cp0_unimplemented;
6437        }
6438        break;
6439    case CP0_REGISTER_12:
6440        switch (sel) {
6441        case CP0_REG12__STATUS:
6442            save_cpu_state(ctx, 1);
6443            gen_helper_mtc0_status(cpu_env, arg);
6444            /* DISAS_STOP isn't good enough here, hflags may have changed. */
6445            gen_save_pc(ctx->base.pc_next + 4);
6446            ctx->base.is_jmp = DISAS_EXIT;
6447            register_name = "Status";
6448            break;
6449        case CP0_REG12__INTCTL:
6450            check_insn(ctx, ISA_MIPS_R2);
6451            gen_helper_mtc0_intctl(cpu_env, arg);
6452            /* Stop translation as we may have switched the execution mode */
6453            ctx->base.is_jmp = DISAS_STOP;
6454            register_name = "IntCtl";
6455            break;
6456        case CP0_REG12__SRSCTL:
6457            check_insn(ctx, ISA_MIPS_R2);
6458            gen_helper_mtc0_srsctl(cpu_env, arg);
6459            /* Stop translation as we may have switched the execution mode */
6460            ctx->base.is_jmp = DISAS_STOP;
6461            register_name = "SRSCtl";
6462            break;
6463        case CP0_REG12__SRSMAP:
6464            check_insn(ctx, ISA_MIPS_R2);
6465            gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_SRSMap));
6466            /* Stop translation as we may have switched the execution mode */
6467            ctx->base.is_jmp = DISAS_STOP;
6468            register_name = "SRSMap";
6469            break;
6470        default:
6471            goto cp0_unimplemented;
6472        }
6473        break;
6474    case CP0_REGISTER_13:
6475        switch (sel) {
6476        case CP0_REG13__CAUSE:
6477            save_cpu_state(ctx, 1);
6478            gen_helper_mtc0_cause(cpu_env, arg);
6479            /*
6480             * Stop translation as we may have triggered an interrupt.
6481             * DISAS_STOP isn't sufficient, we need to ensure we break out of
6482             * translated code to check for pending interrupts.
6483             */
6484            gen_save_pc(ctx->base.pc_next + 4);
6485            ctx->base.is_jmp = DISAS_EXIT;
6486            register_name = "Cause";
6487            break;
6488        default:
6489            goto cp0_unimplemented;
6490        }
6491        break;
6492    case CP0_REGISTER_14:
6493        switch (sel) {
6494        case CP0_REG14__EPC:
6495            tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EPC));
6496            register_name = "EPC";
6497            break;
6498        default:
6499            goto cp0_unimplemented;
6500        }
6501        break;
6502    case CP0_REGISTER_15:
6503        switch (sel) {
6504        case CP0_REG15__PRID:
6505            /* ignored */
6506            register_name = "PRid";
6507            break;
6508        case CP0_REG15__EBASE:
6509            check_insn(ctx, ISA_MIPS_R2);
6510            gen_helper_mtc0_ebase(cpu_env, arg);
6511            register_name = "EBase";
6512            break;
6513        default:
6514            goto cp0_unimplemented;
6515        }
6516        break;
6517    case CP0_REGISTER_16:
6518        switch (sel) {
6519        case CP0_REG16__CONFIG:
6520            gen_helper_mtc0_config0(cpu_env, arg);
6521            register_name = "Config";
6522            /* Stop translation as we may have switched the execution mode */
6523            ctx->base.is_jmp = DISAS_STOP;
6524            break;
6525        case CP0_REG16__CONFIG1:
6526            /* ignored, read only */
6527            register_name = "Config1";
6528            break;
6529        case CP0_REG16__CONFIG2:
6530            gen_helper_mtc0_config2(cpu_env, arg);
6531            register_name = "Config2";
6532            /* Stop translation as we may have switched the execution mode */
6533            ctx->base.is_jmp = DISAS_STOP;
6534            break;
6535        case CP0_REG16__CONFIG3:
6536            gen_helper_mtc0_config3(cpu_env, arg);
6537            register_name = "Config3";
6538            /* Stop translation as we may have switched the execution mode */
6539            ctx->base.is_jmp = DISAS_STOP;
6540            break;
6541        case CP0_REG16__CONFIG4:
6542            gen_helper_mtc0_config4(cpu_env, arg);
6543            register_name = "Config4";
6544            ctx->base.is_jmp = DISAS_STOP;
6545            break;
6546        case CP0_REG16__CONFIG5:
6547            gen_helper_mtc0_config5(cpu_env, arg);
6548            register_name = "Config5";
6549            /* Stop translation as we may have switched the execution mode */
6550            ctx->base.is_jmp = DISAS_STOP;
6551            break;
6552        /* 6,7 are implementation dependent */
6553        case CP0_REG16__CONFIG6:
6554            /* ignored */
6555            register_name = "Config6";
6556            break;
6557        case CP0_REG16__CONFIG7:
6558            /* ignored */
6559            register_name = "Config7";
6560            break;
6561        default:
6562            register_name = "Invalid config selector";
6563            goto cp0_unimplemented;
6564        }
6565        break;
6566    case CP0_REGISTER_17:
6567        switch (sel) {
6568        case CP0_REG17__LLADDR:
6569            gen_helper_mtc0_lladdr(cpu_env, arg);
6570            register_name = "LLAddr";
6571            break;
6572        case CP0_REG17__MAAR:
6573            CP0_CHECK(ctx->mrp);
6574            gen_helper_mtc0_maar(cpu_env, arg);
6575            register_name = "MAAR";
6576            break;
6577        case CP0_REG17__MAARI:
6578            CP0_CHECK(ctx->mrp);
6579            gen_helper_mtc0_maari(cpu_env, arg);
6580            register_name = "MAARI";
6581            break;
6582        default:
6583            goto cp0_unimplemented;
6584        }
6585        break;
6586    case CP0_REGISTER_18:
6587        switch (sel) {
6588        case CP0_REG18__WATCHLO0:
6589        case CP0_REG18__WATCHLO1:
6590        case CP0_REG18__WATCHLO2:
6591        case CP0_REG18__WATCHLO3:
6592        case CP0_REG18__WATCHLO4:
6593        case CP0_REG18__WATCHLO5:
6594        case CP0_REG18__WATCHLO6:
6595        case CP0_REG18__WATCHLO7:
6596            CP0_CHECK(ctx->CP0_Config1 & (1 << CP0C1_WR));
6597            gen_helper_0e1i(mtc0_watchlo, arg, sel);
6598            register_name = "WatchLo";
6599            break;
6600        default:
6601            goto cp0_unimplemented;
6602        }
6603        break;
6604    case CP0_REGISTER_19:
6605        switch (sel) {
6606        case CP0_REG19__WATCHHI0:
6607        case CP0_REG19__WATCHHI1:
6608        case CP0_REG19__WATCHHI2:
6609        case CP0_REG19__WATCHHI3:
6610        case CP0_REG19__WATCHHI4:
6611        case CP0_REG19__WATCHHI5:
6612        case CP0_REG19__WATCHHI6:
6613        case CP0_REG19__WATCHHI7:
6614            CP0_CHECK(ctx->CP0_Config1 & (1 << CP0C1_WR));
6615            gen_helper_0e1i(mtc0_watchhi, arg, sel);
6616            register_name = "WatchHi";
6617            break;
6618        default:
6619            goto cp0_unimplemented;
6620        }
6621        break;
6622    case CP0_REGISTER_20:
6623        switch (sel) {
6624        case CP0_REG20__XCONTEXT:
6625#if defined(TARGET_MIPS64)
6626            check_insn(ctx, ISA_MIPS3);
6627            gen_helper_mtc0_xcontext(cpu_env, arg);
6628            register_name = "XContext";
6629            break;
6630#endif
6631        default:
6632            goto cp0_unimplemented;
6633        }
6634        break;
6635    case CP0_REGISTER_21:
6636       /* Officially reserved, but sel 0 is used for R1x000 framemask */
6637        CP0_CHECK(!(ctx->insn_flags & ISA_MIPS_R6));
6638        switch (sel) {
6639        case 0:
6640            gen_helper_mtc0_framemask(cpu_env, arg);
6641            register_name = "Framemask";
6642            break;
6643        default:
6644            goto cp0_unimplemented;
6645        }
6646        break;
6647    case CP0_REGISTER_22:
6648        /* ignored */
6649        register_name = "Diagnostic"; /* implementation dependent */
6650        break;
6651    case CP0_REGISTER_23:
6652        switch (sel) {
6653        case CP0_REG23__DEBUG:
6654            gen_helper_mtc0_debug(cpu_env, arg); /* EJTAG support */
6655            /* DISAS_STOP isn't good enough here, hflags may have changed. */
6656            gen_save_pc(ctx->base.pc_next + 4);
6657            ctx->base.is_jmp = DISAS_EXIT;
6658            register_name = "Debug";
6659            break;
6660        case CP0_REG23__TRACECONTROL:
6661            /* PDtrace support */
6662            /* gen_helper_mtc0_tracecontrol(cpu_env, arg);  */
6663            register_name = "TraceControl";
6664            /* Stop translation as we may have switched the execution mode */
6665            ctx->base.is_jmp = DISAS_STOP;
6666            goto cp0_unimplemented;
6667        case CP0_REG23__TRACECONTROL2:
6668            /* PDtrace support */
6669            /* gen_helper_mtc0_tracecontrol2(cpu_env, arg); */
6670            register_name = "TraceControl2";
6671            /* Stop translation as we may have switched the execution mode */
6672            ctx->base.is_jmp = DISAS_STOP;
6673            goto cp0_unimplemented;
6674        case CP0_REG23__USERTRACEDATA1:
6675            /* Stop translation as we may have switched the execution mode */
6676            ctx->base.is_jmp = DISAS_STOP;
6677            /* PDtrace support */
6678            /* gen_helper_mtc0_usertracedata1(cpu_env, arg);*/
6679            register_name = "UserTraceData";
6680            /* Stop translation as we may have switched the execution mode */
6681            ctx->base.is_jmp = DISAS_STOP;
6682            goto cp0_unimplemented;
6683        case CP0_REG23__TRACEIBPC:
6684            /* PDtrace support */
6685            /* gen_helper_mtc0_traceibpc(cpu_env, arg);     */
6686            /* Stop translation as we may have switched the execution mode */
6687            ctx->base.is_jmp = DISAS_STOP;
6688            register_name = "TraceIBPC";
6689            goto cp0_unimplemented;
6690        case CP0_REG23__TRACEDBPC:
6691            /* PDtrace support */
6692            /* gen_helper_mtc0_tracedbpc(cpu_env, arg);     */
6693            /* Stop translation as we may have switched the execution mode */
6694            ctx->base.is_jmp = DISAS_STOP;
6695            register_name = "TraceDBPC";
6696            goto cp0_unimplemented;
6697        default:
6698            goto cp0_unimplemented;
6699        }
6700        break;
6701    case CP0_REGISTER_24:
6702        switch (sel) {
6703        case CP0_REG24__DEPC:
6704            /* EJTAG support */
6705            tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_DEPC));
6706            register_name = "DEPC";
6707            break;
6708        default:
6709            goto cp0_unimplemented;
6710        }
6711        break;
6712    case CP0_REGISTER_25:
6713        switch (sel) {
6714        case CP0_REG25__PERFCTL0:
6715            gen_helper_mtc0_performance0(cpu_env, arg);
6716            register_name = "Performance0";
6717            break;
6718        case CP0_REG25__PERFCNT0:
6719            /* gen_helper_mtc0_performance1(arg); */
6720            register_name = "Performance1";
6721            goto cp0_unimplemented;
6722        case CP0_REG25__PERFCTL1:
6723            /* gen_helper_mtc0_performance2(arg); */
6724            register_name = "Performance2";
6725            goto cp0_unimplemented;
6726        case CP0_REG25__PERFCNT1:
6727            /* gen_helper_mtc0_performance3(arg); */
6728            register_name = "Performance3";
6729            goto cp0_unimplemented;
6730        case CP0_REG25__PERFCTL2:
6731            /* gen_helper_mtc0_performance4(arg); */
6732            register_name = "Performance4";
6733            goto cp0_unimplemented;
6734        case CP0_REG25__PERFCNT2:
6735            /* gen_helper_mtc0_performance5(arg); */
6736            register_name = "Performance5";
6737            goto cp0_unimplemented;
6738        case CP0_REG25__PERFCTL3:
6739            /* gen_helper_mtc0_performance6(arg); */
6740            register_name = "Performance6";
6741            goto cp0_unimplemented;
6742        case CP0_REG25__PERFCNT3:
6743            /* gen_helper_mtc0_performance7(arg); */
6744            register_name = "Performance7";
6745            goto cp0_unimplemented;
6746        default:
6747            goto cp0_unimplemented;
6748        }
6749       break;
6750    case CP0_REGISTER_26:
6751        switch (sel) {
6752        case CP0_REG26__ERRCTL:
6753            gen_helper_mtc0_errctl(cpu_env, arg);
6754            ctx->base.is_jmp = DISAS_STOP;
6755            register_name = "ErrCtl";
6756            break;
6757        default:
6758            goto cp0_unimplemented;
6759        }
6760        break;
6761    case CP0_REGISTER_27:
6762        switch (sel) {
6763        case CP0_REG27__CACHERR:
6764            /* ignored */
6765            register_name = "CacheErr";
6766            break;
6767        default:
6768            goto cp0_unimplemented;
6769        }
6770       break;
6771    case CP0_REGISTER_28:
6772        switch (sel) {
6773        case CP0_REG28__TAGLO:
6774        case CP0_REG28__TAGLO1:
6775        case CP0_REG28__TAGLO2:
6776        case CP0_REG28__TAGLO3:
6777            gen_helper_mtc0_taglo(cpu_env, arg);
6778            register_name = "TagLo";
6779            break;
6780        case CP0_REG28__DATALO:
6781        case CP0_REG28__DATALO1:
6782        case CP0_REG28__DATALO2:
6783        case CP0_REG28__DATALO3:
6784            gen_helper_mtc0_datalo(cpu_env, arg);
6785            register_name = "DataLo";
6786            break;
6787        default:
6788            goto cp0_unimplemented;
6789        }
6790        break;
6791    case CP0_REGISTER_29:
6792        switch (sel) {
6793        case CP0_REG29__TAGHI:
6794        case CP0_REG29__TAGHI1:
6795        case CP0_REG29__TAGHI2:
6796        case CP0_REG29__TAGHI3:
6797            gen_helper_mtc0_taghi(cpu_env, arg);
6798            register_name = "TagHi";
6799            break;
6800        case CP0_REG29__DATAHI:
6801        case CP0_REG29__DATAHI1:
6802        case CP0_REG29__DATAHI2:
6803        case CP0_REG29__DATAHI3:
6804            gen_helper_mtc0_datahi(cpu_env, arg);
6805            register_name = "DataHi";
6806            break;
6807        default:
6808            register_name = "invalid sel";
6809            goto cp0_unimplemented;
6810        }
6811       break;
6812    case CP0_REGISTER_30:
6813        switch (sel) {
6814        case CP0_REG30__ERROREPC:
6815            tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_ErrorEPC));
6816            register_name = "ErrorEPC";
6817            break;
6818        default:
6819            goto cp0_unimplemented;
6820        }
6821        break;
6822    case CP0_REGISTER_31:
6823        switch (sel) {
6824        case CP0_REG31__DESAVE:
6825            /* EJTAG support */
6826            gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_DESAVE));
6827            register_name = "DESAVE";
6828            break;
6829        case CP0_REG31__KSCRATCH1:
6830        case CP0_REG31__KSCRATCH2:
6831        case CP0_REG31__KSCRATCH3:
6832        case CP0_REG31__KSCRATCH4:
6833        case CP0_REG31__KSCRATCH5:
6834        case CP0_REG31__KSCRATCH6:
6835            CP0_CHECK(ctx->kscrexist & (1 << sel));
6836            tcg_gen_st_tl(arg, cpu_env,
6837                          offsetof(CPUMIPSState, CP0_KScratch[sel - 2]));
6838            register_name = "KScratch";
6839            break;
6840        default:
6841            goto cp0_unimplemented;
6842        }
6843        break;
6844    default:
6845       goto cp0_unimplemented;
6846    }
6847    trace_mips_translate_c0("mtc0", register_name, reg, sel);
6848
6849    /* For simplicity assume that all writes can cause interrupts.  */
6850    if (icount) {
6851        /*
6852         * DISAS_STOP isn't sufficient, we need to ensure we break out of
6853         * translated code to check for pending interrupts.
6854         */
6855        gen_save_pc(ctx->base.pc_next + 4);
6856        ctx->base.is_jmp = DISAS_EXIT;
6857    }
6858    return;
6859
6860cp0_unimplemented:
6861    qemu_log_mask(LOG_UNIMP, "mtc0 %s (reg %d sel %d)\n",
6862                  register_name, reg, sel);
6863}
6864
6865#if defined(TARGET_MIPS64)
6866static void gen_dmfc0(DisasContext *ctx, TCGv arg, int reg, int sel)
6867{
6868    const char *register_name = "invalid";
6869
6870    if (sel != 0) {
6871        check_insn(ctx, ISA_MIPS_R1);
6872    }
6873
6874    switch (reg) {
6875    case CP0_REGISTER_00:
6876        switch (sel) {
6877        case CP0_REG00__INDEX:
6878            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Index));
6879            register_name = "Index";
6880            break;
6881        case CP0_REG00__MVPCONTROL:
6882            CP0_CHECK(ctx->insn_flags & ASE_MT);
6883            gen_helper_mfc0_mvpcontrol(arg, cpu_env);
6884            register_name = "MVPControl";
6885            break;
6886        case CP0_REG00__MVPCONF0:
6887            CP0_CHECK(ctx->insn_flags & ASE_MT);
6888            gen_helper_mfc0_mvpconf0(arg, cpu_env);
6889            register_name = "MVPConf0";
6890            break;
6891        case CP0_REG00__MVPCONF1:
6892            CP0_CHECK(ctx->insn_flags & ASE_MT);
6893            gen_helper_mfc0_mvpconf1(arg, cpu_env);
6894            register_name = "MVPConf1";
6895            break;
6896        case CP0_REG00__VPCONTROL:
6897            CP0_CHECK(ctx->vp);
6898            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPControl));
6899            register_name = "VPControl";
6900            break;
6901        default:
6902            goto cp0_unimplemented;
6903        }
6904        break;
6905    case CP0_REGISTER_01:
6906        switch (sel) {
6907        case CP0_REG01__RANDOM:
6908            CP0_CHECK(!(ctx->insn_flags & ISA_MIPS_R6));
6909            gen_helper_mfc0_random(arg, cpu_env);
6910            register_name = "Random";
6911            break;
6912        case CP0_REG01__VPECONTROL:
6913            CP0_CHECK(ctx->insn_flags & ASE_MT);
6914            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEControl));
6915            register_name = "VPEControl";
6916            break;
6917        case CP0_REG01__VPECONF0:
6918            CP0_CHECK(ctx->insn_flags & ASE_MT);
6919            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf0));
6920            register_name = "VPEConf0";
6921            break;
6922        case CP0_REG01__VPECONF1:
6923            CP0_CHECK(ctx->insn_flags & ASE_MT);
6924            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf1));
6925            register_name = "VPEConf1";
6926            break;
6927        case CP0_REG01__YQMASK:
6928            CP0_CHECK(ctx->insn_flags & ASE_MT);
6929            tcg_gen_ld_tl(arg, cpu_env,
6930                          offsetof(CPUMIPSState, CP0_YQMask));
6931            register_name = "YQMask";
6932            break;
6933        case CP0_REG01__VPESCHEDULE:
6934            CP0_CHECK(ctx->insn_flags & ASE_MT);
6935            tcg_gen_ld_tl(arg, cpu_env,
6936                          offsetof(CPUMIPSState, CP0_VPESchedule));
6937            register_name = "VPESchedule";
6938            break;
6939        case CP0_REG01__VPESCHEFBACK:
6940            CP0_CHECK(ctx->insn_flags & ASE_MT);
6941            tcg_gen_ld_tl(arg, cpu_env,
6942                          offsetof(CPUMIPSState, CP0_VPEScheFBack));
6943            register_name = "VPEScheFBack";
6944            break;
6945        case CP0_REG01__VPEOPT:
6946            CP0_CHECK(ctx->insn_flags & ASE_MT);
6947            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEOpt));
6948            register_name = "VPEOpt";
6949            break;
6950        default:
6951            goto cp0_unimplemented;
6952        }
6953        break;
6954    case CP0_REGISTER_02:
6955        switch (sel) {
6956        case CP0_REG02__ENTRYLO0:
6957            tcg_gen_ld_tl(arg, cpu_env,
6958                          offsetof(CPUMIPSState, CP0_EntryLo0));
6959            register_name = "EntryLo0";
6960            break;
6961        case CP0_REG02__TCSTATUS:
6962            CP0_CHECK(ctx->insn_flags & ASE_MT);
6963            gen_helper_mfc0_tcstatus(arg, cpu_env);
6964            register_name = "TCStatus";
6965            break;
6966        case CP0_REG02__TCBIND:
6967            CP0_CHECK(ctx->insn_flags & ASE_MT);
6968            gen_helper_mfc0_tcbind(arg, cpu_env);
6969            register_name = "TCBind";
6970            break;
6971        case CP0_REG02__TCRESTART:
6972            CP0_CHECK(ctx->insn_flags & ASE_MT);
6973            gen_helper_dmfc0_tcrestart(arg, cpu_env);
6974            register_name = "TCRestart";
6975            break;
6976        case CP0_REG02__TCHALT:
6977            CP0_CHECK(ctx->insn_flags & ASE_MT);
6978            gen_helper_dmfc0_tchalt(arg, cpu_env);
6979            register_name = "TCHalt";
6980            break;
6981        case CP0_REG02__TCCONTEXT:
6982            CP0_CHECK(ctx->insn_flags & ASE_MT);
6983            gen_helper_dmfc0_tccontext(arg, cpu_env);
6984            register_name = "TCContext";
6985            break;
6986        case CP0_REG02__TCSCHEDULE:
6987            CP0_CHECK(ctx->insn_flags & ASE_MT);
6988            gen_helper_dmfc0_tcschedule(arg, cpu_env);
6989            register_name = "TCSchedule";
6990            break;
6991        case CP0_REG02__TCSCHEFBACK:
6992            CP0_CHECK(ctx->insn_flags & ASE_MT);
6993            gen_helper_dmfc0_tcschefback(arg, cpu_env);
6994            register_name = "TCScheFBack";
6995            break;
6996        default:
6997            goto cp0_unimplemented;
6998        }
6999        break;
7000    case CP0_REGISTER_03:
7001        switch (sel) {
7002        case CP0_REG03__ENTRYLO1:
7003            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryLo1));
7004            register_name = "EntryLo1";
7005            break;
7006        case CP0_REG03__GLOBALNUM:
7007            CP0_CHECK(ctx->vp);
7008            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_GlobalNumber));
7009            register_name = "GlobalNumber";
7010            break;
7011        default:
7012            goto cp0_unimplemented;
7013        }
7014        break;
7015    case CP0_REGISTER_04:
7016        switch (sel) {
7017        case CP0_REG04__CONTEXT:
7018            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_Context));
7019            register_name = "Context";
7020            break;
7021        case CP0_REG04__CONTEXTCONFIG:
7022            /* SmartMIPS ASE */
7023            /* gen_helper_dmfc0_contextconfig(arg); */
7024            register_name = "ContextConfig";
7025            goto cp0_unimplemented;
7026        case CP0_REG04__USERLOCAL:
7027            CP0_CHECK(ctx->ulri);
7028            tcg_gen_ld_tl(arg, cpu_env,
7029                          offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
7030            register_name = "UserLocal";
7031            break;
7032        case CP0_REG04__MMID:
7033            CP0_CHECK(ctx->mi);
7034            gen_helper_mtc0_memorymapid(cpu_env, arg);
7035            register_name = "MMID";
7036            break;
7037        default:
7038            goto cp0_unimplemented;
7039        }
7040        break;
7041    case CP0_REGISTER_05:
7042        switch (sel) {
7043        case CP0_REG05__PAGEMASK:
7044            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageMask));
7045            register_name = "PageMask";
7046            break;
7047        case CP0_REG05__PAGEGRAIN:
7048            check_insn(ctx, ISA_MIPS_R2);
7049            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageGrain));
7050            register_name = "PageGrain";
7051            break;
7052        case CP0_REG05__SEGCTL0:
7053            CP0_CHECK(ctx->sc);
7054            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_SegCtl0));
7055            register_name = "SegCtl0";
7056            break;
7057        case CP0_REG05__SEGCTL1:
7058            CP0_CHECK(ctx->sc);
7059            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_SegCtl1));
7060            register_name = "SegCtl1";
7061            break;
7062        case CP0_REG05__SEGCTL2:
7063            CP0_CHECK(ctx->sc);
7064            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_SegCtl2));
7065            register_name = "SegCtl2";
7066            break;
7067        case CP0_REG05__PWBASE:
7068            check_pw(ctx);
7069            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_PWBase));
7070            register_name = "PWBase";
7071            break;
7072        case CP0_REG05__PWFIELD:
7073            check_pw(ctx);
7074            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_PWField));
7075            register_name = "PWField";
7076            break;
7077        case CP0_REG05__PWSIZE:
7078            check_pw(ctx);
7079            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_PWSize));
7080            register_name = "PWSize";
7081            break;
7082        default:
7083            goto cp0_unimplemented;
7084        }
7085        break;
7086    case CP0_REGISTER_06:
7087        switch (sel) {
7088        case CP0_REG06__WIRED:
7089            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Wired));
7090            register_name = "Wired";
7091            break;
7092        case CP0_REG06__SRSCONF0:
7093            check_insn(ctx, ISA_MIPS_R2);
7094            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf0));
7095            register_name = "SRSConf0";
7096            break;
7097        case CP0_REG06__SRSCONF1:
7098            check_insn(ctx, ISA_MIPS_R2);
7099            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf1));
7100            register_name = "SRSConf1";
7101            break;
7102        case CP0_REG06__SRSCONF2:
7103            check_insn(ctx, ISA_MIPS_R2);
7104            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf2));
7105            register_name = "SRSConf2";
7106            break;
7107        case CP0_REG06__SRSCONF3:
7108            check_insn(ctx, ISA_MIPS_R2);
7109            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf3));
7110            register_name = "SRSConf3";
7111            break;
7112        case CP0_REG06__SRSCONF4:
7113            check_insn(ctx, ISA_MIPS_R2);
7114            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf4));
7115            register_name = "SRSConf4";
7116            break;
7117        case CP0_REG06__PWCTL:
7118            check_pw(ctx);
7119            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PWCtl));
7120            register_name = "PWCtl";
7121            break;
7122        default:
7123            goto cp0_unimplemented;
7124        }
7125        break;
7126    case CP0_REGISTER_07:
7127        switch (sel) {
7128        case CP0_REG07__HWRENA:
7129            check_insn(ctx, ISA_MIPS_R2);
7130            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_HWREna));
7131            register_name = "HWREna";
7132            break;
7133        default:
7134            goto cp0_unimplemented;
7135        }
7136        break;
7137    case CP0_REGISTER_08:
7138        switch (sel) {
7139        case CP0_REG08__BADVADDR:
7140            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_BadVAddr));
7141            register_name = "BadVAddr";
7142            break;
7143        case CP0_REG08__BADINSTR:
7144            CP0_CHECK(ctx->bi);
7145            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_BadInstr));
7146            register_name = "BadInstr";
7147            break;
7148        case CP0_REG08__BADINSTRP:
7149            CP0_CHECK(ctx->bp);
7150            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_BadInstrP));
7151            register_name = "BadInstrP";
7152            break;
7153        case CP0_REG08__BADINSTRX:
7154            CP0_CHECK(ctx->bi);
7155            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_BadInstrX));
7156            tcg_gen_andi_tl(arg, arg, ~0xffff);
7157            register_name = "BadInstrX";
7158            break;
7159        default:
7160            goto cp0_unimplemented;
7161        }
7162        break;
7163    case CP0_REGISTER_09:
7164        switch (sel) {
7165        case CP0_REG09__COUNT:
7166            /* Mark as an IO operation because we read the time.  */
7167            translator_io_start(&ctx->base);
7168            gen_helper_mfc0_count(arg, cpu_env);
7169            /*
7170             * Break the TB to be able to take timer interrupts immediately
7171             * after reading count. DISAS_STOP isn't sufficient, we need to
7172             * ensure we break completely out of translated code.
7173             */
7174            gen_save_pc(ctx->base.pc_next + 4);
7175            ctx->base.is_jmp = DISAS_EXIT;
7176            register_name = "Count";
7177            break;
7178        case CP0_REG09__SAARI:
7179            CP0_CHECK(ctx->saar);
7180            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SAARI));
7181            register_name = "SAARI";
7182            break;
7183        case CP0_REG09__SAAR:
7184            CP0_CHECK(ctx->saar);
7185            gen_helper_dmfc0_saar(arg, cpu_env);
7186            register_name = "SAAR";
7187            break;
7188        default:
7189            goto cp0_unimplemented;
7190        }
7191        break;
7192    case CP0_REGISTER_10:
7193        switch (sel) {
7194        case CP0_REG10__ENTRYHI:
7195            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryHi));
7196            register_name = "EntryHi";
7197            break;
7198        default:
7199            goto cp0_unimplemented;
7200        }
7201        break;
7202    case CP0_REGISTER_11:
7203        switch (sel) {
7204        case CP0_REG11__COMPARE:
7205            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Compare));
7206            register_name = "Compare";
7207            break;
7208        /* 6,7 are implementation dependent */
7209        default:
7210            goto cp0_unimplemented;
7211        }
7212        break;
7213    case CP0_REGISTER_12:
7214        switch (sel) {
7215        case CP0_REG12__STATUS:
7216            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Status));
7217            register_name = "Status";
7218            break;
7219        case CP0_REG12__INTCTL:
7220            check_insn(ctx, ISA_MIPS_R2);
7221            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_IntCtl));
7222            register_name = "IntCtl";
7223            break;
7224        case CP0_REG12__SRSCTL:
7225            check_insn(ctx, ISA_MIPS_R2);
7226            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSCtl));
7227            register_name = "SRSCtl";
7228            break;
7229        case CP0_REG12__SRSMAP:
7230            check_insn(ctx, ISA_MIPS_R2);
7231            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSMap));
7232            register_name = "SRSMap";
7233            break;
7234        default:
7235            goto cp0_unimplemented;
7236        }
7237        break;
7238    case CP0_REGISTER_13:
7239        switch (sel) {
7240        case CP0_REG13__CAUSE:
7241            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Cause));
7242            register_name = "Cause";
7243            break;
7244        default:
7245            goto cp0_unimplemented;
7246        }
7247        break;
7248    case CP0_REGISTER_14:
7249        switch (sel) {
7250        case CP0_REG14__EPC:
7251            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EPC));
7252            register_name = "EPC";
7253            break;
7254        default:
7255            goto cp0_unimplemented;
7256        }
7257        break;
7258    case CP0_REGISTER_15:
7259        switch (sel) {
7260        case CP0_REG15__PRID:
7261            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PRid));
7262            register_name = "PRid";
7263            break;
7264        case CP0_REG15__EBASE:
7265            check_insn(ctx, ISA_MIPS_R2);
7266            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EBase));
7267            register_name = "EBase";
7268            break;
7269        case CP0_REG15__CMGCRBASE:
7270            check_insn(ctx, ISA_MIPS_R2);
7271            CP0_CHECK(ctx->cmgcr);
7272            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_CMGCRBase));
7273            register_name = "CMGCRBase";
7274            break;
7275        default:
7276            goto cp0_unimplemented;
7277        }
7278        break;
7279    case CP0_REGISTER_16:
7280        switch (sel) {
7281        case CP0_REG16__CONFIG:
7282            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config0));
7283            register_name = "Config";
7284            break;
7285        case CP0_REG16__CONFIG1:
7286            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config1));
7287            register_name = "Config1";
7288            break;
7289        case CP0_REG16__CONFIG2:
7290            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config2));
7291            register_name = "Config2";
7292            break;
7293        case CP0_REG16__CONFIG3:
7294            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config3));
7295            register_name = "Config3";
7296            break;
7297        case CP0_REG16__CONFIG4:
7298            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config4));
7299            register_name = "Config4";
7300            break;
7301        case CP0_REG16__CONFIG5:
7302            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config5));
7303            register_name = "Config5";
7304            break;
7305        /* 6,7 are implementation dependent */
7306        case CP0_REG16__CONFIG6:
7307            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config6));
7308            register_name = "Config6";
7309            break;
7310        case CP0_REG16__CONFIG7:
7311            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config7));
7312            register_name = "Config7";
7313            break;
7314        default:
7315            goto cp0_unimplemented;
7316        }
7317        break;
7318    case CP0_REGISTER_17:
7319        switch (sel) {
7320        case CP0_REG17__LLADDR:
7321            gen_helper_dmfc0_lladdr(arg, cpu_env);
7322            register_name = "LLAddr";
7323            break;
7324        case CP0_REG17__MAAR:
7325            CP0_CHECK(ctx->mrp);
7326            gen_helper_dmfc0_maar(arg, cpu_env);
7327            register_name = "MAAR";
7328            break;
7329        case CP0_REG17__MAARI:
7330            CP0_CHECK(ctx->mrp);
7331            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_MAARI));
7332            register_name = "MAARI";
7333            break;
7334        default:
7335            goto cp0_unimplemented;
7336        }
7337        break;
7338    case CP0_REGISTER_18:
7339        switch (sel) {
7340        case CP0_REG18__WATCHLO0:
7341        case CP0_REG18__WATCHLO1:
7342        case CP0_REG18__WATCHLO2:
7343        case CP0_REG18__WATCHLO3:
7344        case CP0_REG18__WATCHLO4:
7345        case CP0_REG18__WATCHLO5:
7346        case CP0_REG18__WATCHLO6:
7347        case CP0_REG18__WATCHLO7:
7348            CP0_CHECK(ctx->CP0_Config1 & (1 << CP0C1_WR));
7349            gen_helper_1e0i(dmfc0_watchlo, arg, sel);
7350            register_name = "WatchLo";
7351            break;
7352        default:
7353            goto cp0_unimplemented;
7354        }
7355        break;
7356    case CP0_REGISTER_19:
7357        switch (sel) {
7358        case CP0_REG19__WATCHHI0:
7359        case CP0_REG19__WATCHHI1:
7360        case CP0_REG19__WATCHHI2:
7361        case CP0_REG19__WATCHHI3:
7362        case CP0_REG19__WATCHHI4:
7363        case CP0_REG19__WATCHHI5:
7364        case CP0_REG19__WATCHHI6:
7365        case CP0_REG19__WATCHHI7:
7366            CP0_CHECK(ctx->CP0_Config1 & (1 << CP0C1_WR));
7367            gen_helper_1e0i(dmfc0_watchhi, arg, sel);
7368            register_name = "WatchHi";
7369            break;
7370        default:
7371            goto cp0_unimplemented;
7372        }
7373        break;
7374    case CP0_REGISTER_20:
7375        switch (sel) {
7376        case CP0_REG20__XCONTEXT:
7377            check_insn(ctx, ISA_MIPS3);
7378            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_XContext));
7379            register_name = "XContext";
7380            break;
7381        default:
7382            goto cp0_unimplemented;
7383        }
7384        break;
7385    case CP0_REGISTER_21:
7386        /* Officially reserved, but sel 0 is used for R1x000 framemask */
7387        CP0_CHECK(!(ctx->insn_flags & ISA_MIPS_R6));
7388        switch (sel) {
7389        case 0:
7390            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Framemask));
7391            register_name = "Framemask";
7392            break;
7393        default:
7394            goto cp0_unimplemented;
7395        }
7396        break;
7397    case CP0_REGISTER_22:
7398        tcg_gen_movi_tl(arg, 0); /* unimplemented */
7399        register_name = "'Diagnostic"; /* implementation dependent */
7400        break;
7401    case CP0_REGISTER_23:
7402        switch (sel) {
7403        case CP0_REG23__DEBUG:
7404            gen_helper_mfc0_debug(arg, cpu_env); /* EJTAG support */
7405            register_name = "Debug";
7406            break;
7407        case CP0_REG23__TRACECONTROL:
7408            /* PDtrace support */
7409            /* gen_helper_dmfc0_tracecontrol(arg, cpu_env);  */
7410            register_name = "TraceControl";
7411            goto cp0_unimplemented;
7412        case CP0_REG23__TRACECONTROL2:
7413            /* PDtrace support */
7414            /* gen_helper_dmfc0_tracecontrol2(arg, cpu_env); */
7415            register_name = "TraceControl2";
7416            goto cp0_unimplemented;
7417        case CP0_REG23__USERTRACEDATA1:
7418            /* PDtrace support */
7419            /* gen_helper_dmfc0_usertracedata1(arg, cpu_env);*/
7420            register_name = "UserTraceData1";
7421            goto cp0_unimplemented;
7422        case CP0_REG23__TRACEIBPC:
7423            /* PDtrace support */
7424            /* gen_helper_dmfc0_traceibpc(arg, cpu_env);     */
7425            register_name = "TraceIBPC";
7426            goto cp0_unimplemented;
7427        case CP0_REG23__TRACEDBPC:
7428            /* PDtrace support */
7429            /* gen_helper_dmfc0_tracedbpc(arg, cpu_env);     */
7430            register_name = "TraceDBPC";
7431            goto cp0_unimplemented;
7432        default:
7433            goto cp0_unimplemented;
7434        }
7435        break;
7436    case CP0_REGISTER_24:
7437        switch (sel) {
7438        case CP0_REG24__DEPC:
7439            /* EJTAG support */
7440            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_DEPC));
7441            register_name = "DEPC";
7442            break;
7443        default:
7444            goto cp0_unimplemented;
7445        }
7446        break;
7447    case CP0_REGISTER_25:
7448        switch (sel) {
7449        case CP0_REG25__PERFCTL0:
7450            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Performance0));
7451            register_name = "Performance0";
7452            break;
7453        case CP0_REG25__PERFCNT0:
7454            /* gen_helper_dmfc0_performance1(arg); */
7455            register_name = "Performance1";
7456            goto cp0_unimplemented;
7457        case CP0_REG25__PERFCTL1:
7458            /* gen_helper_dmfc0_performance2(arg); */
7459            register_name = "Performance2";
7460            goto cp0_unimplemented;
7461        case CP0_REG25__PERFCNT1:
7462            /* gen_helper_dmfc0_performance3(arg); */
7463            register_name = "Performance3";
7464            goto cp0_unimplemented;
7465        case CP0_REG25__PERFCTL2:
7466            /* gen_helper_dmfc0_performance4(arg); */
7467            register_name = "Performance4";
7468            goto cp0_unimplemented;
7469        case CP0_REG25__PERFCNT2:
7470            /* gen_helper_dmfc0_performance5(arg); */
7471            register_name = "Performance5";
7472            goto cp0_unimplemented;
7473        case CP0_REG25__PERFCTL3:
7474            /* gen_helper_dmfc0_performance6(arg); */
7475            register_name = "Performance6";
7476            goto cp0_unimplemented;
7477        case CP0_REG25__PERFCNT3:
7478            /* gen_helper_dmfc0_performance7(arg); */
7479            register_name = "Performance7";
7480            goto cp0_unimplemented;
7481        default:
7482            goto cp0_unimplemented;
7483        }
7484        break;
7485    case CP0_REGISTER_26:
7486        switch (sel) {
7487        case CP0_REG26__ERRCTL:
7488            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_ErrCtl));
7489            register_name = "ErrCtl";
7490            break;
7491        default:
7492            goto cp0_unimplemented;
7493        }
7494        break;
7495    case CP0_REGISTER_27:
7496        switch (sel) {
7497        /* ignored */
7498        case CP0_REG27__CACHERR:
7499            tcg_gen_movi_tl(arg, 0); /* unimplemented */
7500            register_name = "CacheErr";
7501            break;
7502        default:
7503            goto cp0_unimplemented;
7504        }
7505        break;
7506    case CP0_REGISTER_28:
7507        switch (sel) {
7508        case CP0_REG28__TAGLO:
7509        case CP0_REG28__TAGLO1:
7510        case CP0_REG28__TAGLO2:
7511        case CP0_REG28__TAGLO3:
7512            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_TagLo));
7513            register_name = "TagLo";
7514            break;
7515        case CP0_REG28__DATALO:
7516        case CP0_REG28__DATALO1:
7517        case CP0_REG28__DATALO2:
7518        case CP0_REG28__DATALO3:
7519            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataLo));
7520            register_name = "DataLo";
7521            break;
7522        default:
7523            goto cp0_unimplemented;
7524        }
7525        break;
7526    case CP0_REGISTER_29:
7527        switch (sel) {
7528        case CP0_REG29__TAGHI:
7529        case CP0_REG29__TAGHI1:
7530        case CP0_REG29__TAGHI2:
7531        case CP0_REG29__TAGHI3:
7532            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_TagHi));
7533            register_name = "TagHi";
7534            break;
7535        case CP0_REG29__DATAHI:
7536        case CP0_REG29__DATAHI1:
7537        case CP0_REG29__DATAHI2:
7538        case CP0_REG29__DATAHI3:
7539            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataHi));
7540            register_name = "DataHi";
7541            break;
7542        default:
7543            goto cp0_unimplemented;
7544        }
7545        break;
7546    case CP0_REGISTER_30:
7547        switch (sel) {
7548        case CP0_REG30__ERROREPC:
7549            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_ErrorEPC));
7550            register_name = "ErrorEPC";
7551            break;
7552        default:
7553            goto cp0_unimplemented;
7554        }
7555        break;
7556    case CP0_REGISTER_31:
7557        switch (sel) {
7558        case CP0_REG31__DESAVE:
7559            /* EJTAG support */
7560            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DESAVE));
7561            register_name = "DESAVE";
7562            break;
7563        case CP0_REG31__KSCRATCH1:
7564        case CP0_REG31__KSCRATCH2:
7565        case CP0_REG31__KSCRATCH3:
7566        case CP0_REG31__KSCRATCH4:
7567        case CP0_REG31__KSCRATCH5:
7568        case CP0_REG31__KSCRATCH6:
7569            CP0_CHECK(ctx->kscrexist & (1 << sel));
7570            tcg_gen_ld_tl(arg, cpu_env,
7571                          offsetof(CPUMIPSState, CP0_KScratch[sel - 2]));
7572            register_name = "KScratch";
7573            break;
7574        default:
7575            goto cp0_unimplemented;
7576        }
7577        break;
7578    default:
7579        goto cp0_unimplemented;
7580    }
7581    trace_mips_translate_c0("dmfc0", register_name, reg, sel);
7582    return;
7583
7584cp0_unimplemented:
7585    qemu_log_mask(LOG_UNIMP, "dmfc0 %s (reg %d sel %d)\n",
7586                  register_name, reg, sel);
7587    gen_mfc0_unimplemented(ctx, arg);
7588}
7589
7590static void gen_dmtc0(DisasContext *ctx, TCGv arg, int reg, int sel)
7591{
7592    const char *register_name = "invalid";
7593    bool icount;
7594
7595    if (sel != 0) {
7596        check_insn(ctx, ISA_MIPS_R1);
7597    }
7598
7599    icount = translator_io_start(&ctx->base);
7600
7601    switch (reg) {
7602    case CP0_REGISTER_00:
7603        switch (sel) {
7604        case CP0_REG00__INDEX:
7605            gen_helper_mtc0_index(cpu_env, arg);
7606            register_name = "Index";
7607            break;
7608        case CP0_REG00__MVPCONTROL:
7609            CP0_CHECK(ctx->insn_flags & ASE_MT);
7610            gen_helper_mtc0_mvpcontrol(cpu_env, arg);
7611            register_name = "MVPControl";
7612            break;
7613        case CP0_REG00__MVPCONF0:
7614            CP0_CHECK(ctx->insn_flags & ASE_MT);
7615            /* ignored */
7616            register_name = "MVPConf0";
7617            break;
7618        case CP0_REG00__MVPCONF1:
7619            CP0_CHECK(ctx->insn_flags & ASE_MT);
7620            /* ignored */
7621            register_name = "MVPConf1";
7622            break;
7623        case CP0_REG00__VPCONTROL:
7624            CP0_CHECK(ctx->vp);
7625            /* ignored */
7626            register_name = "VPControl";
7627            break;
7628        default:
7629            goto cp0_unimplemented;
7630        }
7631        break;
7632    case CP0_REGISTER_01:
7633        switch (sel) {
7634        case CP0_REG01__RANDOM:
7635            /* ignored */
7636            register_name = "Random";
7637            break;
7638        case CP0_REG01__VPECONTROL:
7639            CP0_CHECK(ctx->insn_flags & ASE_MT);
7640            gen_helper_mtc0_vpecontrol(cpu_env, arg);
7641            register_name = "VPEControl";
7642            break;
7643        case CP0_REG01__VPECONF0:
7644            CP0_CHECK(ctx->insn_flags & ASE_MT);
7645            gen_helper_mtc0_vpeconf0(cpu_env, arg);
7646            register_name = "VPEConf0";
7647            break;
7648        case CP0_REG01__VPECONF1:
7649            CP0_CHECK(ctx->insn_flags & ASE_MT);
7650            gen_helper_mtc0_vpeconf1(cpu_env, arg);
7651            register_name = "VPEConf1";
7652            break;
7653        case CP0_REG01__YQMASK:
7654            CP0_CHECK(ctx->insn_flags & ASE_MT);
7655            gen_helper_mtc0_yqmask(cpu_env, arg);
7656            register_name = "YQMask";
7657            break;
7658        case CP0_REG01__VPESCHEDULE:
7659            CP0_CHECK(ctx->insn_flags & ASE_MT);
7660            tcg_gen_st_tl(arg, cpu_env,
7661                          offsetof(CPUMIPSState, CP0_VPESchedule));
7662            register_name = "VPESchedule";
7663            break;
7664        case CP0_REG01__VPESCHEFBACK:
7665            CP0_CHECK(ctx->insn_flags & ASE_MT);
7666            tcg_gen_st_tl(arg, cpu_env,
7667                          offsetof(CPUMIPSState, CP0_VPEScheFBack));
7668            register_name = "VPEScheFBack";
7669            break;
7670        case CP0_REG01__VPEOPT:
7671            CP0_CHECK(ctx->insn_flags & ASE_MT);
7672            gen_helper_mtc0_vpeopt(cpu_env, arg);
7673            register_name = "VPEOpt";
7674            break;
7675        default:
7676            goto cp0_unimplemented;
7677        }
7678        break;
7679    case CP0_REGISTER_02:
7680        switch (sel) {
7681        case CP0_REG02__ENTRYLO0:
7682            gen_helper_dmtc0_entrylo0(cpu_env, arg);
7683            register_name = "EntryLo0";
7684            break;
7685        case CP0_REG02__TCSTATUS:
7686            CP0_CHECK(ctx->insn_flags & ASE_MT);
7687            gen_helper_mtc0_tcstatus(cpu_env, arg);
7688            register_name = "TCStatus";
7689            break;
7690        case CP0_REG02__TCBIND:
7691            CP0_CHECK(ctx->insn_flags & ASE_MT);
7692            gen_helper_mtc0_tcbind(cpu_env, arg);
7693            register_name = "TCBind";
7694            break;
7695        case CP0_REG02__TCRESTART:
7696            CP0_CHECK(ctx->insn_flags & ASE_MT);
7697            gen_helper_mtc0_tcrestart(cpu_env, arg);
7698            register_name = "TCRestart";
7699            break;
7700        case CP0_REG02__TCHALT:
7701            CP0_CHECK(ctx->insn_flags & ASE_MT);
7702            gen_helper_mtc0_tchalt(cpu_env, arg);
7703            register_name = "TCHalt";
7704            break;
7705        case CP0_REG02__TCCONTEXT:
7706            CP0_CHECK(ctx->insn_flags & ASE_MT);
7707            gen_helper_mtc0_tccontext(cpu_env, arg);
7708            register_name = "TCContext";
7709            break;
7710        case CP0_REG02__TCSCHEDULE:
7711            CP0_CHECK(ctx->insn_flags & ASE_MT);
7712            gen_helper_mtc0_tcschedule(cpu_env, arg);
7713            register_name = "TCSchedule";
7714            break;
7715        case CP0_REG02__TCSCHEFBACK:
7716            CP0_CHECK(ctx->insn_flags & ASE_MT);
7717            gen_helper_mtc0_tcschefback(cpu_env, arg);
7718            register_name = "TCScheFBack";
7719            break;
7720        default:
7721            goto cp0_unimplemented;
7722        }
7723        break;
7724    case CP0_REGISTER_03:
7725        switch (sel) {
7726        case CP0_REG03__ENTRYLO1:
7727            gen_helper_dmtc0_entrylo1(cpu_env, arg);
7728            register_name = "EntryLo1";
7729            break;
7730        case CP0_REG03__GLOBALNUM:
7731            CP0_CHECK(ctx->vp);
7732            /* ignored */
7733            register_name = "GlobalNumber";
7734            break;
7735        default:
7736            goto cp0_unimplemented;
7737        }
7738        break;
7739    case CP0_REGISTER_04:
7740        switch (sel) {
7741        case CP0_REG04__CONTEXT:
7742            gen_helper_mtc0_context(cpu_env, arg);
7743            register_name = "Context";
7744            break;
7745        case CP0_REG04__CONTEXTCONFIG:
7746            /* SmartMIPS ASE */
7747            /* gen_helper_dmtc0_contextconfig(arg); */
7748            register_name = "ContextConfig";
7749            goto cp0_unimplemented;
7750        case CP0_REG04__USERLOCAL:
7751            CP0_CHECK(ctx->ulri);
7752            tcg_gen_st_tl(arg, cpu_env,
7753                          offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
7754            register_name = "UserLocal";
7755            break;
7756        case CP0_REG04__MMID:
7757            CP0_CHECK(ctx->mi);
7758            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_MemoryMapID));
7759            register_name = "MMID";
7760            break;
7761        default:
7762            goto cp0_unimplemented;
7763        }
7764        break;
7765    case CP0_REGISTER_05:
7766        switch (sel) {
7767        case CP0_REG05__PAGEMASK:
7768            gen_helper_mtc0_pagemask(cpu_env, arg);
7769            register_name = "PageMask";
7770            break;
7771        case CP0_REG05__PAGEGRAIN:
7772            check_insn(ctx, ISA_MIPS_R2);
7773            gen_helper_mtc0_pagegrain(cpu_env, arg);
7774            register_name = "PageGrain";
7775            break;
7776        case CP0_REG05__SEGCTL0:
7777            CP0_CHECK(ctx->sc);
7778            gen_helper_mtc0_segctl0(cpu_env, arg);
7779            register_name = "SegCtl0";
7780            break;
7781        case CP0_REG05__SEGCTL1:
7782            CP0_CHECK(ctx->sc);
7783            gen_helper_mtc0_segctl1(cpu_env, arg);
7784            register_name = "SegCtl1";
7785            break;
7786        case CP0_REG05__SEGCTL2:
7787            CP0_CHECK(ctx->sc);
7788            gen_helper_mtc0_segctl2(cpu_env, arg);
7789            register_name = "SegCtl2";
7790            break;
7791        case CP0_REG05__PWBASE:
7792            check_pw(ctx);
7793            tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_PWBase));
7794            register_name = "PWBase";
7795            break;
7796        case CP0_REG05__PWFIELD:
7797            check_pw(ctx);
7798            gen_helper_mtc0_pwfield(cpu_env, arg);
7799            register_name = "PWField";
7800            break;
7801        case CP0_REG05__PWSIZE:
7802            check_pw(ctx);
7803            gen_helper_mtc0_pwsize(cpu_env, arg);
7804            register_name = "PWSize";
7805            break;
7806        default:
7807            goto cp0_unimplemented;
7808        }
7809        break;
7810    case CP0_REGISTER_06:
7811        switch (sel) {
7812        case CP0_REG06__WIRED:
7813            gen_helper_mtc0_wired(cpu_env, arg);
7814            register_name = "Wired";
7815            break;
7816        case CP0_REG06__SRSCONF0:
7817            check_insn(ctx, ISA_MIPS_R2);
7818            gen_helper_mtc0_srsconf0(cpu_env, arg);
7819            register_name = "SRSConf0";
7820            break;
7821        case CP0_REG06__SRSCONF1:
7822            check_insn(ctx, ISA_MIPS_R2);
7823            gen_helper_mtc0_srsconf1(cpu_env, arg);
7824            register_name = "SRSConf1";
7825            break;
7826        case CP0_REG06__SRSCONF2:
7827            check_insn(ctx, ISA_MIPS_R2);
7828            gen_helper_mtc0_srsconf2(cpu_env, arg);
7829            register_name = "SRSConf2";
7830            break;
7831        case CP0_REG06__SRSCONF3:
7832            check_insn(ctx, ISA_MIPS_R2);
7833            gen_helper_mtc0_srsconf3(cpu_env, arg);
7834            register_name = "SRSConf3";
7835            break;
7836        case CP0_REG06__SRSCONF4:
7837            check_insn(ctx, ISA_MIPS_R2);
7838            gen_helper_mtc0_srsconf4(cpu_env, arg);
7839            register_name = "SRSConf4";
7840            break;
7841        case CP0_REG06__PWCTL:
7842            check_pw(ctx);
7843            gen_helper_mtc0_pwctl(cpu_env, arg);
7844            register_name = "PWCtl";
7845            break;
7846        default:
7847            goto cp0_unimplemented;
7848        }
7849        break;
7850    case CP0_REGISTER_07:
7851        switch (sel) {
7852        case CP0_REG07__HWRENA:
7853            check_insn(ctx, ISA_MIPS_R2);
7854            gen_helper_mtc0_hwrena(cpu_env, arg);
7855            ctx->base.is_jmp = DISAS_STOP;
7856            register_name = "HWREna";
7857            break;
7858        default:
7859            goto cp0_unimplemented;
7860        }
7861        break;
7862    case CP0_REGISTER_08:
7863        switch (sel) {
7864        case CP0_REG08__BADVADDR:
7865            /* ignored */
7866            register_name = "BadVAddr";
7867            break;
7868        case CP0_REG08__BADINSTR:
7869            /* ignored */
7870            register_name = "BadInstr";
7871            break;
7872        case CP0_REG08__BADINSTRP:
7873            /* ignored */
7874            register_name = "BadInstrP";
7875            break;
7876        case CP0_REG08__BADINSTRX:
7877            /* ignored */
7878            register_name = "BadInstrX";
7879            break;
7880        default:
7881            goto cp0_unimplemented;
7882        }
7883        break;
7884    case CP0_REGISTER_09:
7885        switch (sel) {
7886        case CP0_REG09__COUNT:
7887            gen_helper_mtc0_count(cpu_env, arg);
7888            register_name = "Count";
7889            break;
7890        case CP0_REG09__SAARI:
7891            CP0_CHECK(ctx->saar);
7892            gen_helper_mtc0_saari(cpu_env, arg);
7893            register_name = "SAARI";
7894            break;
7895        case CP0_REG09__SAAR:
7896            CP0_CHECK(ctx->saar);
7897            gen_helper_mtc0_saar(cpu_env, arg);
7898            register_name = "SAAR";
7899            break;
7900        default:
7901            goto cp0_unimplemented;
7902        }
7903        /* Stop translation as we may have switched the execution mode */
7904        ctx->base.is_jmp = DISAS_STOP;
7905        break;
7906    case CP0_REGISTER_10:
7907        switch (sel) {
7908        case CP0_REG10__ENTRYHI:
7909            gen_helper_mtc0_entryhi(cpu_env, arg);
7910            register_name = "EntryHi";
7911            break;
7912        default:
7913            goto cp0_unimplemented;
7914        }
7915        break;
7916    case CP0_REGISTER_11:
7917        switch (sel) {
7918        case CP0_REG11__COMPARE:
7919            gen_helper_mtc0_compare(cpu_env, arg);
7920            register_name = "Compare";
7921            break;
7922        /* 6,7 are implementation dependent */
7923        default:
7924            goto cp0_unimplemented;
7925        }
7926        /* Stop translation as we may have switched the execution mode */
7927        ctx->base.is_jmp = DISAS_STOP;
7928        break;
7929    case CP0_REGISTER_12:
7930        switch (sel) {
7931        case CP0_REG12__STATUS:
7932            save_cpu_state(ctx, 1);
7933            gen_helper_mtc0_status(cpu_env, arg);
7934            /* DISAS_STOP isn't good enough here, hflags may have changed. */
7935            gen_save_pc(ctx->base.pc_next + 4);
7936            ctx->base.is_jmp = DISAS_EXIT;
7937            register_name = "Status";
7938            break;
7939        case CP0_REG12__INTCTL:
7940            check_insn(ctx, ISA_MIPS_R2);
7941            gen_helper_mtc0_intctl(cpu_env, arg);
7942            /* Stop translation as we may have switched the execution mode */
7943            ctx->base.is_jmp = DISAS_STOP;
7944            register_name = "IntCtl";
7945            break;
7946        case CP0_REG12__SRSCTL:
7947            check_insn(ctx, ISA_MIPS_R2);
7948            gen_helper_mtc0_srsctl(cpu_env, arg);
7949            /* Stop translation as we may have switched the execution mode */
7950            ctx->base.is_jmp = DISAS_STOP;
7951            register_name = "SRSCtl";
7952            break;
7953        case CP0_REG12__SRSMAP:
7954            check_insn(ctx, ISA_MIPS_R2);
7955            gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_SRSMap));
7956            /* Stop translation as we may have switched the execution mode */
7957            ctx->base.is_jmp = DISAS_STOP;
7958            register_name = "SRSMap";
7959            break;
7960        default:
7961            goto cp0_unimplemented;
7962        }
7963        break;
7964    case CP0_REGISTER_13:
7965        switch (sel) {
7966        case CP0_REG13__CAUSE:
7967            save_cpu_state(ctx, 1);
7968            gen_helper_mtc0_cause(cpu_env, arg);
7969            /*
7970             * Stop translation as we may have triggered an interrupt.
7971             * DISAS_STOP isn't sufficient, we need to ensure we break out of
7972             * translated code to check for pending interrupts.
7973             */
7974            gen_save_pc(ctx->base.pc_next + 4);
7975            ctx->base.is_jmp = DISAS_EXIT;
7976            register_name = "Cause";
7977            break;
7978        default:
7979            goto cp0_unimplemented;
7980        }
7981        break;
7982    case CP0_REGISTER_14:
7983        switch (sel) {
7984        case CP0_REG14__EPC:
7985            tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EPC));
7986            register_name = "EPC";
7987            break;
7988        default:
7989            goto cp0_unimplemented;
7990        }
7991        break;
7992    case CP0_REGISTER_15:
7993        switch (sel) {
7994        case CP0_REG15__PRID:
7995            /* ignored */
7996            register_name = "PRid";
7997            break;
7998        case CP0_REG15__EBASE:
7999            check_insn(ctx, ISA_MIPS_R2);
8000            gen_helper_mtc0_ebase(cpu_env, arg);
8001            register_name = "EBase";
8002            break;
8003        default:
8004            goto cp0_unimplemented;
8005        }
8006        break;
8007    case CP0_REGISTER_16:
8008        switch (sel) {
8009        case CP0_REG16__CONFIG:
8010            gen_helper_mtc0_config0(cpu_env, arg);
8011            register_name = "Config";
8012            /* Stop translation as we may have switched the execution mode */
8013            ctx->base.is_jmp = DISAS_STOP;
8014            break;
8015        case CP0_REG16__CONFIG1:
8016            /* ignored, read only */
8017            register_name = "Config1";
8018            break;
8019        case CP0_REG16__CONFIG2:
8020            gen_helper_mtc0_config2(cpu_env, arg);
8021            register_name = "Config2";
8022            /* Stop translation as we may have switched the execution mode */
8023            ctx->base.is_jmp = DISAS_STOP;
8024            break;
8025        case CP0_REG16__CONFIG3:
8026            gen_helper_mtc0_config3(cpu_env, arg);
8027            register_name = "Config3";
8028            /* Stop translation as we may have switched the execution mode */
8029            ctx->base.is_jmp = DISAS_STOP;
8030            break;
8031        case CP0_REG16__CONFIG4:
8032            /* currently ignored */
8033            register_name = "Config4";
8034            break;
8035        case CP0_REG16__CONFIG5:
8036            gen_helper_mtc0_config5(cpu_env, arg);
8037            register_name = "Config5";
8038            /* Stop translation as we may have switched the execution mode */
8039            ctx->base.is_jmp = DISAS_STOP;
8040            break;
8041        /* 6,7 are implementation dependent */
8042        default:
8043            register_name = "Invalid config selector";
8044            goto cp0_unimplemented;
8045        }
8046        break;
8047    case CP0_REGISTER_17:
8048        switch (sel) {
8049        case CP0_REG17__LLADDR:
8050            gen_helper_mtc0_lladdr(cpu_env, arg);
8051            register_name = "LLAddr";
8052            break;
8053        case CP0_REG17__MAAR:
8054            CP0_CHECK(ctx->mrp);
8055            gen_helper_mtc0_maar(cpu_env, arg);
8056            register_name = "MAAR";
8057            break;
8058        case CP0_REG17__MAARI:
8059            CP0_CHECK(ctx->mrp);
8060            gen_helper_mtc0_maari(cpu_env, arg);
8061            register_name = "MAARI";
8062            break;
8063        default:
8064            goto cp0_unimplemented;
8065        }
8066        break;
8067    case CP0_REGISTER_18:
8068        switch (sel) {
8069        case CP0_REG18__WATCHLO0:
8070        case CP0_REG18__WATCHLO1:
8071        case CP0_REG18__WATCHLO2:
8072        case CP0_REG18__WATCHLO3:
8073        case CP0_REG18__WATCHLO4:
8074        case CP0_REG18__WATCHLO5:
8075        case CP0_REG18__WATCHLO6:
8076        case CP0_REG18__WATCHLO7:
8077            CP0_CHECK(ctx->CP0_Config1 & (1 << CP0C1_WR));
8078            gen_helper_0e1i(mtc0_watchlo, arg, sel);
8079            register_name = "WatchLo";
8080            break;
8081        default:
8082            goto cp0_unimplemented;
8083        }
8084        break;
8085    case CP0_REGISTER_19:
8086        switch (sel) {
8087        case CP0_REG19__WATCHHI0:
8088        case CP0_REG19__WATCHHI1:
8089        case CP0_REG19__WATCHHI2:
8090        case CP0_REG19__WATCHHI3:
8091        case CP0_REG19__WATCHHI4:
8092        case CP0_REG19__WATCHHI5:
8093        case CP0_REG19__WATCHHI6:
8094        case CP0_REG19__WATCHHI7:
8095            CP0_CHECK(ctx->CP0_Config1 & (1 << CP0C1_WR));
8096            gen_helper_0e1i(mtc0_watchhi, arg, sel);
8097            register_name = "WatchHi";
8098            break;
8099        default:
8100            goto cp0_unimplemented;
8101        }
8102        break;
8103    case CP0_REGISTER_20:
8104        switch (sel) {
8105        case CP0_REG20__XCONTEXT:
8106            check_insn(ctx, ISA_MIPS3);
8107            gen_helper_mtc0_xcontext(cpu_env, arg);
8108            register_name = "XContext";
8109            break;
8110        default:
8111            goto cp0_unimplemented;
8112        }
8113        break;
8114    case CP0_REGISTER_21:
8115       /* Officially reserved, but sel 0 is used for R1x000 framemask */
8116        CP0_CHECK(!(ctx->insn_flags & ISA_MIPS_R6));
8117        switch (sel) {
8118        case 0:
8119            gen_helper_mtc0_framemask(cpu_env, arg);
8120            register_name = "Framemask";
8121            break;
8122        default:
8123            goto cp0_unimplemented;
8124        }
8125        break;
8126    case CP0_REGISTER_22:
8127        /* ignored */
8128        register_name = "Diagnostic"; /* implementation dependent */
8129        break;
8130    case CP0_REGISTER_23:
8131        switch (sel) {
8132        case CP0_REG23__DEBUG:
8133            gen_helper_mtc0_debug(cpu_env, arg); /* EJTAG support */
8134            /* DISAS_STOP isn't good enough here, hflags may have changed. */
8135            gen_save_pc(ctx->base.pc_next + 4);
8136            ctx->base.is_jmp = DISAS_EXIT;
8137            register_name = "Debug";
8138            break;
8139        case CP0_REG23__TRACECONTROL:
8140            /* PDtrace support */
8141            /* gen_helper_mtc0_tracecontrol(cpu_env, arg);  */
8142            /* Stop translation as we may have switched the execution mode */
8143            ctx->base.is_jmp = DISAS_STOP;
8144            register_name = "TraceControl";
8145            goto cp0_unimplemented;
8146        case CP0_REG23__TRACECONTROL2:
8147            /* PDtrace support */
8148            /* gen_helper_mtc0_tracecontrol2(cpu_env, arg); */
8149            /* Stop translation as we may have switched the execution mode */
8150            ctx->base.is_jmp = DISAS_STOP;
8151            register_name = "TraceControl2";
8152            goto cp0_unimplemented;
8153        case CP0_REG23__USERTRACEDATA1:
8154            /* PDtrace support */
8155            /* gen_helper_mtc0_usertracedata1(cpu_env, arg);*/
8156            /* Stop translation as we may have switched the execution mode */
8157            ctx->base.is_jmp = DISAS_STOP;
8158            register_name = "UserTraceData1";
8159            goto cp0_unimplemented;
8160        case CP0_REG23__TRACEIBPC:
8161            /* PDtrace support */
8162            /* gen_helper_mtc0_traceibpc(cpu_env, arg);     */
8163            /* Stop translation as we may have switched the execution mode */
8164            ctx->base.is_jmp = DISAS_STOP;
8165            register_name = "TraceIBPC";
8166            goto cp0_unimplemented;
8167        case CP0_REG23__TRACEDBPC:
8168            /* PDtrace support */
8169            /* gen_helper_mtc0_tracedbpc(cpu_env, arg);     */
8170            /* Stop translation as we may have switched the execution mode */
8171            ctx->base.is_jmp = DISAS_STOP;
8172            register_name = "TraceDBPC";
8173            goto cp0_unimplemented;
8174        default:
8175            goto cp0_unimplemented;
8176        }
8177        break;
8178    case CP0_REGISTER_24:
8179        switch (sel) {
8180        case CP0_REG24__DEPC:
8181            /* EJTAG support */
8182            tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_DEPC));
8183            register_name = "DEPC";
8184            break;
8185        default:
8186            goto cp0_unimplemented;
8187        }
8188        break;
8189    case CP0_REGISTER_25:
8190        switch (sel) {
8191        case CP0_REG25__PERFCTL0:
8192            gen_helper_mtc0_performance0(cpu_env, arg);
8193            register_name = "Performance0";
8194            break;
8195        case CP0_REG25__PERFCNT0:
8196            /* gen_helper_mtc0_performance1(cpu_env, arg); */
8197            register_name = "Performance1";
8198            goto cp0_unimplemented;
8199        case CP0_REG25__PERFCTL1:
8200            /* gen_helper_mtc0_performance2(cpu_env, arg); */
8201            register_name = "Performance2";
8202            goto cp0_unimplemented;
8203        case CP0_REG25__PERFCNT1:
8204            /* gen_helper_mtc0_performance3(cpu_env, arg); */
8205            register_name = "Performance3";
8206            goto cp0_unimplemented;
8207        case CP0_REG25__PERFCTL2:
8208            /* gen_helper_mtc0_performance4(cpu_env, arg); */
8209            register_name = "Performance4";
8210            goto cp0_unimplemented;
8211        case CP0_REG25__PERFCNT2:
8212            /* gen_helper_mtc0_performance5(cpu_env, arg); */
8213            register_name = "Performance5";
8214            goto cp0_unimplemented;
8215        case CP0_REG25__PERFCTL3:
8216            /* gen_helper_mtc0_performance6(cpu_env, arg); */
8217            register_name = "Performance6";
8218            goto cp0_unimplemented;
8219        case CP0_REG25__PERFCNT3:
8220            /* gen_helper_mtc0_performance7(cpu_env, arg); */
8221            register_name = "Performance7";
8222            goto cp0_unimplemented;
8223        default:
8224            goto cp0_unimplemented;
8225        }
8226        break;
8227    case CP0_REGISTER_26:
8228        switch (sel) {
8229        case CP0_REG26__ERRCTL:
8230            gen_helper_mtc0_errctl(cpu_env, arg);
8231            ctx->base.is_jmp = DISAS_STOP;
8232            register_name = "ErrCtl";
8233            break;
8234        default:
8235            goto cp0_unimplemented;
8236        }
8237        break;
8238    case CP0_REGISTER_27:
8239        switch (sel) {
8240        case CP0_REG27__CACHERR:
8241            /* ignored */
8242            register_name = "CacheErr";
8243            break;
8244        default:
8245            goto cp0_unimplemented;
8246        }
8247        break;
8248    case CP0_REGISTER_28:
8249        switch (sel) {
8250        case CP0_REG28__TAGLO:
8251        case CP0_REG28__TAGLO1:
8252        case CP0_REG28__TAGLO2:
8253        case CP0_REG28__TAGLO3:
8254            gen_helper_mtc0_taglo(cpu_env, arg);
8255            register_name = "TagLo";
8256            break;
8257        case CP0_REG28__DATALO:
8258        case CP0_REG28__DATALO1:
8259        case CP0_REG28__DATALO2:
8260        case CP0_REG28__DATALO3:
8261            gen_helper_mtc0_datalo(cpu_env, arg);
8262            register_name = "DataLo";
8263            break;
8264        default:
8265            goto cp0_unimplemented;
8266        }
8267        break;
8268    case CP0_REGISTER_29:
8269        switch (sel) {
8270        case CP0_REG29__TAGHI:
8271        case CP0_REG29__TAGHI1:
8272        case CP0_REG29__TAGHI2:
8273        case CP0_REG29__TAGHI3:
8274            gen_helper_mtc0_taghi(cpu_env, arg);
8275            register_name = "TagHi";
8276            break;
8277        case CP0_REG29__DATAHI:
8278        case CP0_REG29__DATAHI1:
8279        case CP0_REG29__DATAHI2:
8280        case CP0_REG29__DATAHI3:
8281            gen_helper_mtc0_datahi(cpu_env, arg);
8282            register_name = "DataHi";
8283            break;
8284        default:
8285            register_name = "invalid sel";
8286            goto cp0_unimplemented;
8287        }
8288        break;
8289    case CP0_REGISTER_30:
8290        switch (sel) {
8291        case CP0_REG30__ERROREPC:
8292            tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_ErrorEPC));
8293            register_name = "ErrorEPC";
8294            break;
8295        default:
8296            goto cp0_unimplemented;
8297        }
8298        break;
8299    case CP0_REGISTER_31:
8300        switch (sel) {
8301        case CP0_REG31__DESAVE:
8302            /* EJTAG support */
8303            gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_DESAVE));
8304            register_name = "DESAVE";
8305            break;
8306        case CP0_REG31__KSCRATCH1:
8307        case CP0_REG31__KSCRATCH2:
8308        case CP0_REG31__KSCRATCH3:
8309        case CP0_REG31__KSCRATCH4:
8310        case CP0_REG31__KSCRATCH5:
8311        case CP0_REG31__KSCRATCH6:
8312            CP0_CHECK(ctx->kscrexist & (1 << sel));
8313            tcg_gen_st_tl(arg, cpu_env,
8314                          offsetof(CPUMIPSState, CP0_KScratch[sel - 2]));
8315            register_name = "KScratch";
8316            break;
8317        default:
8318            goto cp0_unimplemented;
8319        }
8320        break;
8321    default:
8322        goto cp0_unimplemented;
8323    }
8324    trace_mips_translate_c0("dmtc0", register_name, reg, sel);
8325
8326    /* For simplicity assume that all writes can cause interrupts.  */
8327    if (icount) {
8328        /*
8329         * DISAS_STOP isn't sufficient, we need to ensure we break out of
8330         * translated code to check for pending interrupts.
8331         */
8332        gen_save_pc(ctx->base.pc_next + 4);
8333        ctx->base.is_jmp = DISAS_EXIT;
8334    }
8335    return;
8336
8337cp0_unimplemented:
8338    qemu_log_mask(LOG_UNIMP, "dmtc0 %s (reg %d sel %d)\n",
8339                  register_name, reg, sel);
8340}
8341#endif /* TARGET_MIPS64 */
8342
8343static void gen_mftr(CPUMIPSState *env, DisasContext *ctx, int rt, int rd,
8344                     int u, int sel, int h)
8345{
8346    int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
8347    TCGv t0 = tcg_temp_new();
8348
8349    if ((env->CP0_VPEConf0 & (1 << CP0VPEC0_MVP)) == 0 &&
8350        ((env->tcs[other_tc].CP0_TCBind & (0xf << CP0TCBd_CurVPE)) !=
8351         (env->active_tc.CP0_TCBind & (0xf << CP0TCBd_CurVPE)))) {
8352        tcg_gen_movi_tl(t0, -1);
8353    } else if ((env->CP0_VPEControl & (0xff << CP0VPECo_TargTC)) >
8354               (env->mvp->CP0_MVPConf0 & (0xff << CP0MVPC0_PTC))) {
8355        tcg_gen_movi_tl(t0, -1);
8356    } else if (u == 0) {
8357        switch (rt) {
8358        case 1:
8359            switch (sel) {
8360            case 1:
8361                gen_helper_mftc0_vpecontrol(t0, cpu_env);
8362                break;
8363            case 2:
8364                gen_helper_mftc0_vpeconf0(t0, cpu_env);
8365                break;
8366            default:
8367                goto die;
8368                break;
8369            }
8370            break;
8371        case 2:
8372            switch (sel) {
8373            case 1:
8374                gen_helper_mftc0_tcstatus(t0, cpu_env);
8375                break;
8376            case 2:
8377                gen_helper_mftc0_tcbind(t0, cpu_env);
8378                break;
8379            case 3:
8380                gen_helper_mftc0_tcrestart(t0, cpu_env);
8381                break;
8382            case 4:
8383                gen_helper_mftc0_tchalt(t0, cpu_env);
8384                break;
8385            case 5:
8386                gen_helper_mftc0_tccontext(t0, cpu_env);
8387                break;
8388            case 6:
8389                gen_helper_mftc0_tcschedule(t0, cpu_env);
8390                break;
8391            case 7:
8392                gen_helper_mftc0_tcschefback(t0, cpu_env);
8393                break;
8394            default:
8395                gen_mfc0(ctx, t0, rt, sel);
8396                break;
8397            }
8398            break;
8399        case 10:
8400            switch (sel) {
8401            case 0:
8402                gen_helper_mftc0_entryhi(t0, cpu_env);
8403                break;
8404            default:
8405                gen_mfc0(ctx, t0, rt, sel);
8406                break;
8407            }
8408            break;
8409        case 12:
8410            switch (sel) {
8411            case 0:
8412                gen_helper_mftc0_status(t0, cpu_env);
8413                break;
8414            default:
8415                gen_mfc0(ctx, t0, rt, sel);
8416                break;
8417            }
8418            break;
8419        case 13:
8420            switch (sel) {
8421            case 0:
8422                gen_helper_mftc0_cause(t0, cpu_env);
8423                break;
8424            default:
8425                goto die;
8426                break;
8427            }
8428            break;
8429        case 14:
8430            switch (sel) {
8431            case 0:
8432                gen_helper_mftc0_epc(t0, cpu_env);
8433                break;
8434            default:
8435                goto die;
8436                break;
8437            }
8438            break;
8439        case 15:
8440            switch (sel) {
8441            case 1:
8442                gen_helper_mftc0_ebase(t0, cpu_env);
8443                break;
8444            default:
8445                goto die;
8446                break;
8447            }
8448            break;
8449        case 16:
8450            switch (sel) {
8451            case 0:
8452            case 1:
8453            case 2:
8454            case 3:
8455            case 4:
8456            case 5:
8457            case 6:
8458            case 7:
8459                gen_helper_mftc0_configx(t0, cpu_env, tcg_constant_tl(sel));
8460                break;
8461            default:
8462                goto die;
8463                break;
8464            }
8465            break;
8466        case 23:
8467            switch (sel) {
8468            case 0:
8469                gen_helper_mftc0_debug(t0, cpu_env);
8470                break;
8471            default:
8472                gen_mfc0(ctx, t0, rt, sel);
8473                break;
8474            }
8475            break;
8476        default:
8477            gen_mfc0(ctx, t0, rt, sel);
8478        }
8479    } else {
8480        switch (sel) {
8481        /* GPR registers. */
8482        case 0:
8483            gen_helper_1e0i(mftgpr, t0, rt);
8484            break;
8485        /* Auxiliary CPU registers */
8486        case 1:
8487            switch (rt) {
8488            case 0:
8489                gen_helper_1e0i(mftlo, t0, 0);
8490                break;
8491            case 1:
8492                gen_helper_1e0i(mfthi, t0, 0);
8493                break;
8494            case 2:
8495                gen_helper_1e0i(mftacx, t0, 0);
8496                break;
8497            case 4:
8498                gen_helper_1e0i(mftlo, t0, 1);
8499                break;
8500            case 5:
8501                gen_helper_1e0i(mfthi, t0, 1);
8502                break;
8503            case 6:
8504                gen_helper_1e0i(mftacx, t0, 1);
8505                break;
8506            case 8:
8507                gen_helper_1e0i(mftlo, t0, 2);
8508                break;
8509            case 9:
8510                gen_helper_1e0i(mfthi, t0, 2);
8511                break;
8512            case 10:
8513                gen_helper_1e0i(mftacx, t0, 2);
8514                break;
8515            case 12:
8516                gen_helper_1e0i(mftlo, t0, 3);
8517                break;
8518            case 13:
8519                gen_helper_1e0i(mfthi, t0, 3);
8520                break;
8521            case 14:
8522                gen_helper_1e0i(mftacx, t0, 3);
8523                break;
8524            case 16:
8525                gen_helper_mftdsp(t0, cpu_env);
8526                break;
8527            default:
8528                goto die;
8529            }
8530            break;
8531        /* Floating point (COP1). */
8532        case 2:
8533            /* XXX: For now we support only a single FPU context. */
8534            if (h == 0) {
8535                TCGv_i32 fp0 = tcg_temp_new_i32();
8536
8537                gen_load_fpr32(ctx, fp0, rt);
8538                tcg_gen_ext_i32_tl(t0, fp0);
8539            } else {
8540                TCGv_i32 fp0 = tcg_temp_new_i32();
8541
8542                gen_load_fpr32h(ctx, fp0, rt);
8543                tcg_gen_ext_i32_tl(t0, fp0);
8544            }
8545            break;
8546        case 3:
8547            /* XXX: For now we support only a single FPU context. */
8548            gen_helper_1e0i(cfc1, t0, rt);
8549            break;
8550        /* COP2: Not implemented. */
8551        case 4:
8552        case 5:
8553            /* fall through */
8554        default:
8555            goto die;
8556        }
8557    }
8558    trace_mips_translate_tr("mftr", rt, u, sel, h);
8559    gen_store_gpr(t0, rd);
8560    return;
8561
8562die:
8563    LOG_DISAS("mftr (reg %d u %d sel %d h %d)\n", rt, u, sel, h);
8564    gen_reserved_instruction(ctx);
8565}
8566
8567static void gen_mttr(CPUMIPSState *env, DisasContext *ctx, int rd, int rt,
8568                     int u, int sel, int h)
8569{
8570    int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
8571    TCGv t0 = tcg_temp_new();
8572
8573    gen_load_gpr(t0, rt);
8574    if ((env->CP0_VPEConf0 & (1 << CP0VPEC0_MVP)) == 0 &&
8575        ((env->tcs[other_tc].CP0_TCBind & (0xf << CP0TCBd_CurVPE)) !=
8576         (env->active_tc.CP0_TCBind & (0xf << CP0TCBd_CurVPE)))) {
8577        /* NOP */
8578        ;
8579    } else if ((env->CP0_VPEControl & (0xff << CP0VPECo_TargTC)) >
8580             (env->mvp->CP0_MVPConf0 & (0xff << CP0MVPC0_PTC))) {
8581        /* NOP */
8582        ;
8583    } else if (u == 0) {
8584        switch (rd) {
8585        case 1:
8586            switch (sel) {
8587            case 1:
8588                gen_helper_mttc0_vpecontrol(cpu_env, t0);
8589                break;
8590            case 2:
8591                gen_helper_mttc0_vpeconf0(cpu_env, t0);
8592                break;
8593            default:
8594                goto die;
8595                break;
8596            }
8597            break;
8598        case 2:
8599            switch (sel) {
8600            case 1:
8601                gen_helper_mttc0_tcstatus(cpu_env, t0);
8602                break;
8603            case 2:
8604                gen_helper_mttc0_tcbind(cpu_env, t0);
8605                break;
8606            case 3:
8607                gen_helper_mttc0_tcrestart(cpu_env, t0);
8608                break;
8609            case 4:
8610                gen_helper_mttc0_tchalt(cpu_env, t0);
8611                break;
8612            case 5:
8613                gen_helper_mttc0_tccontext(cpu_env, t0);
8614                break;
8615            case 6:
8616                gen_helper_mttc0_tcschedule(cpu_env, t0);
8617                break;
8618            case 7:
8619                gen_helper_mttc0_tcschefback(cpu_env, t0);
8620                break;
8621            default:
8622                gen_mtc0(ctx, t0, rd, sel);
8623                break;
8624            }
8625            break;
8626        case 10:
8627            switch (sel) {
8628            case 0:
8629                gen_helper_mttc0_entryhi(cpu_env, t0);
8630                break;
8631            default:
8632                gen_mtc0(ctx, t0, rd, sel);
8633                break;
8634            }
8635            break;
8636        case 12:
8637            switch (sel) {
8638            case 0:
8639                gen_helper_mttc0_status(cpu_env, t0);
8640                break;
8641            default:
8642                gen_mtc0(ctx, t0, rd, sel);
8643                break;
8644            }
8645            break;
8646        case 13:
8647            switch (sel) {
8648            case 0:
8649                gen_helper_mttc0_cause(cpu_env, t0);
8650                break;
8651            default:
8652                goto die;
8653                break;
8654            }
8655            break;
8656        case 15:
8657            switch (sel) {
8658            case 1:
8659                gen_helper_mttc0_ebase(cpu_env, t0);
8660                break;
8661            default:
8662                goto die;
8663                break;
8664            }
8665            break;
8666        case 23:
8667            switch (sel) {
8668            case 0:
8669                gen_helper_mttc0_debug(cpu_env, t0);
8670                break;
8671            default:
8672                gen_mtc0(ctx, t0, rd, sel);
8673                break;
8674            }
8675            break;
8676        default:
8677            gen_mtc0(ctx, t0, rd, sel);
8678        }
8679    } else {
8680        switch (sel) {
8681        /* GPR registers. */
8682        case 0:
8683            gen_helper_0e1i(mttgpr, t0, rd);
8684            break;
8685        /* Auxiliary CPU registers */
8686        case 1:
8687            switch (rd) {
8688            case 0:
8689                gen_helper_0e1i(mttlo, t0, 0);
8690                break;
8691            case 1:
8692                gen_helper_0e1i(mtthi, t0, 0);
8693                break;
8694            case 2:
8695                gen_helper_0e1i(mttacx, t0, 0);
8696                break;
8697            case 4:
8698                gen_helper_0e1i(mttlo, t0, 1);
8699                break;
8700            case 5:
8701                gen_helper_0e1i(mtthi, t0, 1);
8702                break;
8703            case 6:
8704                gen_helper_0e1i(mttacx, t0, 1);
8705                break;
8706            case 8:
8707                gen_helper_0e1i(mttlo, t0, 2);
8708                break;
8709            case 9:
8710                gen_helper_0e1i(mtthi, t0, 2);
8711                break;
8712            case 10:
8713                gen_helper_0e1i(mttacx, t0, 2);
8714                break;
8715            case 12:
8716                gen_helper_0e1i(mttlo, t0, 3);
8717                break;
8718            case 13:
8719                gen_helper_0e1i(mtthi, t0, 3);
8720                break;
8721            case 14:
8722                gen_helper_0e1i(mttacx, t0, 3);
8723                break;
8724            case 16:
8725                gen_helper_mttdsp(cpu_env, t0);
8726                break;
8727            default:
8728                goto die;
8729            }
8730            break;
8731        /* Floating point (COP1). */
8732        case 2:
8733            /* XXX: For now we support only a single FPU context. */
8734            if (h == 0) {
8735                TCGv_i32 fp0 = tcg_temp_new_i32();
8736
8737                tcg_gen_trunc_tl_i32(fp0, t0);
8738                gen_store_fpr32(ctx, fp0, rd);
8739            } else {
8740                TCGv_i32 fp0 = tcg_temp_new_i32();
8741
8742                tcg_gen_trunc_tl_i32(fp0, t0);
8743                gen_store_fpr32h(ctx, fp0, rd);
8744            }
8745            break;
8746        case 3:
8747            /* XXX: For now we support only a single FPU context. */
8748            gen_helper_0e2i(ctc1, t0, tcg_constant_i32(rd), rt);
8749            /* Stop translation as we may have changed hflags */
8750            ctx->base.is_jmp = DISAS_STOP;
8751            break;
8752        /* COP2: Not implemented. */
8753        case 4:
8754        case 5:
8755            /* fall through */
8756        default:
8757            goto die;
8758        }
8759    }
8760    trace_mips_translate_tr("mttr", rd, u, sel, h);
8761    return;
8762
8763die:
8764    LOG_DISAS("mttr (reg %d u %d sel %d h %d)\n", rd, u, sel, h);
8765    gen_reserved_instruction(ctx);
8766}
8767
8768static void gen_cp0(CPUMIPSState *env, DisasContext *ctx, uint32_t opc,
8769                    int rt, int rd)
8770{
8771    const char *opn = "ldst";
8772
8773    check_cp0_enabled(ctx);
8774    switch (opc) {
8775    case OPC_MFC0:
8776        if (rt == 0) {
8777            /* Treat as NOP. */
8778            return;
8779        }
8780        gen_mfc0(ctx, cpu_gpr[rt], rd, ctx->opcode & 0x7);
8781        opn = "mfc0";
8782        break;
8783    case OPC_MTC0:
8784        {
8785            TCGv t0 = tcg_temp_new();
8786
8787            gen_load_gpr(t0, rt);
8788            gen_mtc0(ctx, t0, rd, ctx->opcode & 0x7);
8789        }
8790        opn = "mtc0";
8791        break;
8792#if defined(TARGET_MIPS64)
8793    case OPC_DMFC0:
8794        check_insn(ctx, ISA_MIPS3);
8795        if (rt == 0) {
8796            /* Treat as NOP. */
8797            return;
8798        }
8799        gen_dmfc0(ctx, cpu_gpr[rt], rd, ctx->opcode & 0x7);
8800        opn = "dmfc0";
8801        break;
8802    case OPC_DMTC0:
8803        check_insn(ctx, ISA_MIPS3);
8804        {
8805            TCGv t0 = tcg_temp_new();
8806
8807            gen_load_gpr(t0, rt);
8808            gen_dmtc0(ctx, t0, rd, ctx->opcode & 0x7);
8809        }
8810        opn = "dmtc0";
8811        break;
8812#endif
8813    case OPC_MFHC0:
8814        check_mvh(ctx);
8815        if (rt == 0) {
8816            /* Treat as NOP. */
8817            return;
8818        }
8819        gen_mfhc0(ctx, cpu_gpr[rt], rd, ctx->opcode & 0x7);
8820        opn = "mfhc0";
8821        break;
8822    case OPC_MTHC0:
8823        check_mvh(ctx);
8824        {
8825            TCGv t0 = tcg_temp_new();
8826            gen_load_gpr(t0, rt);
8827            gen_mthc0(ctx, t0, rd, ctx->opcode & 0x7);
8828        }
8829        opn = "mthc0";
8830        break;
8831    case OPC_MFTR:
8832        check_cp0_enabled(ctx);
8833        if (rd == 0) {
8834            /* Treat as NOP. */
8835            return;
8836        }
8837        gen_mftr(env, ctx, rt, rd, (ctx->opcode >> 5) & 1,
8838                 ctx->opcode & 0x7, (ctx->opcode >> 4) & 1);
8839        opn = "mftr";
8840        break;
8841    case OPC_MTTR:
8842        check_cp0_enabled(ctx);
8843        gen_mttr(env, ctx, rd, rt, (ctx->opcode >> 5) & 1,
8844                 ctx->opcode & 0x7, (ctx->opcode >> 4) & 1);
8845        opn = "mttr";
8846        break;
8847    case OPC_TLBWI:
8848        opn = "tlbwi";
8849        if (!env->tlb->helper_tlbwi) {
8850            goto die;
8851        }
8852        gen_helper_tlbwi(cpu_env);
8853        break;
8854    case OPC_TLBINV:
8855        opn = "tlbinv";
8856        if (ctx->ie >= 2) {
8857            if (!env->tlb->helper_tlbinv) {
8858                goto die;
8859            }
8860            gen_helper_tlbinv(cpu_env);
8861        } /* treat as nop if TLBINV not supported */
8862        break;
8863    case OPC_TLBINVF:
8864        opn = "tlbinvf";
8865        if (ctx->ie >= 2) {
8866            if (!env->tlb->helper_tlbinvf) {
8867                goto die;
8868            }
8869            gen_helper_tlbinvf(cpu_env);
8870        } /* treat as nop if TLBINV not supported */
8871        break;
8872    case OPC_TLBWR:
8873        opn = "tlbwr";
8874        if (!env->tlb->helper_tlbwr) {
8875            goto die;
8876        }
8877        gen_helper_tlbwr(cpu_env);
8878        break;
8879    case OPC_TLBP:
8880        opn = "tlbp";
8881        if (!env->tlb->helper_tlbp) {
8882            goto die;
8883        }
8884        gen_helper_tlbp(cpu_env);
8885        break;
8886    case OPC_TLBR:
8887        opn = "tlbr";
8888        if (!env->tlb->helper_tlbr) {
8889            goto die;
8890        }
8891        gen_helper_tlbr(cpu_env);
8892        break;
8893    case OPC_ERET: /* OPC_ERETNC */
8894        if ((ctx->insn_flags & ISA_MIPS_R6) &&
8895            (ctx->hflags & MIPS_HFLAG_BMASK)) {
8896            goto die;
8897        } else {
8898            int bit_shift = (ctx->hflags & MIPS_HFLAG_M16) ? 16 : 6;
8899            if (ctx->opcode & (1 << bit_shift)) {
8900                /* OPC_ERETNC */
8901                opn = "eretnc";
8902                check_insn(ctx, ISA_MIPS_R5);
8903                gen_helper_eretnc(cpu_env);
8904            } else {
8905                /* OPC_ERET */
8906                opn = "eret";
8907                check_insn(ctx, ISA_MIPS2);
8908                gen_helper_eret(cpu_env);
8909            }
8910            ctx->base.is_jmp = DISAS_EXIT;
8911        }
8912        break;
8913    case OPC_DERET:
8914        opn = "deret";
8915        check_insn(ctx, ISA_MIPS_R1);
8916        if ((ctx->insn_flags & ISA_MIPS_R6) &&
8917            (ctx->hflags & MIPS_HFLAG_BMASK)) {
8918            goto die;
8919        }
8920        if (!(ctx->hflags & MIPS_HFLAG_DM)) {
8921            MIPS_INVAL(opn);
8922            gen_reserved_instruction(ctx);
8923        } else {
8924            gen_helper_deret(cpu_env);
8925            ctx->base.is_jmp = DISAS_EXIT;
8926        }
8927        break;
8928    case OPC_WAIT:
8929        opn = "wait";
8930        check_insn(ctx, ISA_MIPS3 | ISA_MIPS_R1);
8931        if ((ctx->insn_flags & ISA_MIPS_R6) &&
8932            (ctx->hflags & MIPS_HFLAG_BMASK)) {
8933            goto die;
8934        }
8935        /* If we get an exception, we want to restart at next instruction */
8936        ctx->base.pc_next += 4;
8937        save_cpu_state(ctx, 1);
8938        ctx->base.pc_next -= 4;
8939        gen_helper_wait(cpu_env);
8940        ctx->base.is_jmp = DISAS_NORETURN;
8941        break;
8942    default:
8943 die:
8944        MIPS_INVAL(opn);
8945        gen_reserved_instruction(ctx);
8946        return;
8947    }
8948    (void)opn; /* avoid a compiler warning */
8949}
8950#endif /* !CONFIG_USER_ONLY */
8951
8952/* CP1 Branches (before delay slot) */
8953static void gen_compute_branch1(DisasContext *ctx, uint32_t op,
8954                                int32_t cc, int32_t offset)
8955{
8956    target_ulong btarget;
8957    TCGv_i32 t0 = tcg_temp_new_i32();
8958
8959    if ((ctx->insn_flags & ISA_MIPS_R6) && (ctx->hflags & MIPS_HFLAG_BMASK)) {
8960        gen_reserved_instruction(ctx);
8961        return;
8962    }
8963
8964    if (cc != 0) {
8965        check_insn(ctx, ISA_MIPS4 | ISA_MIPS_R1);
8966    }
8967
8968    btarget = ctx->base.pc_next + 4 + offset;
8969
8970    switch (op) {
8971    case OPC_BC1F:
8972        tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
8973        tcg_gen_not_i32(t0, t0);
8974        tcg_gen_andi_i32(t0, t0, 1);
8975        tcg_gen_extu_i32_tl(bcond, t0);
8976        goto not_likely;
8977    case OPC_BC1FL:
8978        tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
8979        tcg_gen_not_i32(t0, t0);
8980        tcg_gen_andi_i32(t0, t0, 1);
8981        tcg_gen_extu_i32_tl(bcond, t0);
8982        goto likely;
8983    case OPC_BC1T:
8984        tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
8985        tcg_gen_andi_i32(t0, t0, 1);
8986        tcg_gen_extu_i32_tl(bcond, t0);
8987        goto not_likely;
8988    case OPC_BC1TL:
8989        tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
8990        tcg_gen_andi_i32(t0, t0, 1);
8991        tcg_gen_extu_i32_tl(bcond, t0);
8992    likely:
8993        ctx->hflags |= MIPS_HFLAG_BL;
8994        break;
8995    case OPC_BC1FANY2:
8996        {
8997            TCGv_i32 t1 = tcg_temp_new_i32();
8998            tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
8999            tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc + 1));
9000            tcg_gen_nand_i32(t0, t0, t1);
9001            tcg_gen_andi_i32(t0, t0, 1);
9002            tcg_gen_extu_i32_tl(bcond, t0);
9003        }
9004        goto not_likely;
9005    case OPC_BC1TANY2:
9006        {
9007            TCGv_i32 t1 = tcg_temp_new_i32();
9008            tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
9009            tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc + 1));
9010            tcg_gen_or_i32(t0, t0, t1);
9011            tcg_gen_andi_i32(t0, t0, 1);
9012            tcg_gen_extu_i32_tl(bcond, t0);
9013        }
9014        goto not_likely;
9015    case OPC_BC1FANY4:
9016        {
9017            TCGv_i32 t1 = tcg_temp_new_i32();
9018            tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
9019            tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc + 1));
9020            tcg_gen_and_i32(t0, t0, t1);
9021            tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc + 2));
9022            tcg_gen_and_i32(t0, t0, t1);
9023            tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc + 3));
9024            tcg_gen_nand_i32(t0, t0, t1);
9025            tcg_gen_andi_i32(t0, t0, 1);
9026            tcg_gen_extu_i32_tl(bcond, t0);
9027        }
9028        goto not_likely;
9029    case OPC_BC1TANY4:
9030        {
9031            TCGv_i32 t1 = tcg_temp_new_i32();
9032            tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
9033            tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc + 1));
9034            tcg_gen_or_i32(t0, t0, t1);
9035            tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc + 2));
9036            tcg_gen_or_i32(t0, t0, t1);
9037            tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc + 3));
9038            tcg_gen_or_i32(t0, t0, t1);
9039            tcg_gen_andi_i32(t0, t0, 1);
9040            tcg_gen_extu_i32_tl(bcond, t0);
9041        }
9042    not_likely:
9043        ctx->hflags |= MIPS_HFLAG_BC;
9044        break;
9045    default:
9046        MIPS_INVAL("cp1 cond branch");
9047        gen_reserved_instruction(ctx);
9048        return;
9049    }
9050    ctx->btarget = btarget;
9051    ctx->hflags |= MIPS_HFLAG_BDS32;
9052}
9053
9054/* R6 CP1 Branches */
9055static void gen_compute_branch1_r6(DisasContext *ctx, uint32_t op,
9056                                   int32_t ft, int32_t offset,
9057                                   int delayslot_size)
9058{
9059    target_ulong btarget;
9060    TCGv_i64 t0 = tcg_temp_new_i64();
9061
9062    if (ctx->hflags & MIPS_HFLAG_BMASK) {
9063#ifdef MIPS_DEBUG_DISAS
9064        LOG_DISAS("Branch in delay / forbidden slot at PC 0x" TARGET_FMT_lx
9065                  "\n", ctx->base.pc_next);
9066#endif
9067        gen_reserved_instruction(ctx);
9068        return;
9069    }
9070
9071    gen_load_fpr64(ctx, t0, ft);
9072    tcg_gen_andi_i64(t0, t0, 1);
9073
9074    btarget = addr_add(ctx, ctx->base.pc_next + 4, offset);
9075
9076    switch (op) {
9077    case OPC_BC1EQZ:
9078        tcg_gen_xori_i64(t0, t0, 1);
9079        ctx->hflags |= MIPS_HFLAG_BC;
9080        break;
9081    case OPC_BC1NEZ:
9082        /* t0 already set */
9083        ctx->hflags |= MIPS_HFLAG_BC;
9084        break;
9085    default:
9086        MIPS_INVAL("cp1 cond branch");
9087        gen_reserved_instruction(ctx);
9088        return;
9089    }
9090
9091    tcg_gen_trunc_i64_tl(bcond, t0);
9092
9093    ctx->btarget = btarget;
9094
9095    switch (delayslot_size) {
9096    case 2:
9097        ctx->hflags |= MIPS_HFLAG_BDS16;
9098        break;
9099    case 4:
9100        ctx->hflags |= MIPS_HFLAG_BDS32;
9101        break;
9102    }
9103}
9104
9105/* Coprocessor 1 (FPU) */
9106
9107#define FOP(func, fmt) (((fmt) << 21) | (func))
9108
9109enum fopcode {
9110    OPC_ADD_S = FOP(0, FMT_S),
9111    OPC_SUB_S = FOP(1, FMT_S),
9112    OPC_MUL_S = FOP(2, FMT_S),
9113    OPC_DIV_S = FOP(3, FMT_S),
9114    OPC_SQRT_S = FOP(4, FMT_S),
9115    OPC_ABS_S = FOP(5, FMT_S),
9116    OPC_MOV_S = FOP(6, FMT_S),
9117    OPC_NEG_S = FOP(7, FMT_S),
9118    OPC_ROUND_L_S = FOP(8, FMT_S),
9119    OPC_TRUNC_L_S = FOP(9, FMT_S),
9120    OPC_CEIL_L_S = FOP(10, FMT_S),
9121    OPC_FLOOR_L_S = FOP(11, FMT_S),
9122    OPC_ROUND_W_S = FOP(12, FMT_S),
9123    OPC_TRUNC_W_S = FOP(13, FMT_S),
9124    OPC_CEIL_W_S = FOP(14, FMT_S),
9125    OPC_FLOOR_W_S = FOP(15, FMT_S),
9126    OPC_SEL_S = FOP(16, FMT_S),
9127    OPC_MOVCF_S = FOP(17, FMT_S),
9128    OPC_MOVZ_S = FOP(18, FMT_S),
9129    OPC_MOVN_S = FOP(19, FMT_S),
9130    OPC_SELEQZ_S = FOP(20, FMT_S),
9131    OPC_RECIP_S = FOP(21, FMT_S),
9132    OPC_RSQRT_S = FOP(22, FMT_S),
9133    OPC_SELNEZ_S = FOP(23, FMT_S),
9134    OPC_MADDF_S = FOP(24, FMT_S),
9135    OPC_MSUBF_S = FOP(25, FMT_S),
9136    OPC_RINT_S = FOP(26, FMT_S),
9137    OPC_CLASS_S = FOP(27, FMT_S),
9138    OPC_MIN_S = FOP(28, FMT_S),
9139    OPC_RECIP2_S = FOP(28, FMT_S),
9140    OPC_MINA_S = FOP(29, FMT_S),
9141    OPC_RECIP1_S = FOP(29, FMT_S),
9142    OPC_MAX_S = FOP(30, FMT_S),
9143    OPC_RSQRT1_S = FOP(30, FMT_S),
9144    OPC_MAXA_S = FOP(31, FMT_S),
9145    OPC_RSQRT2_S = FOP(31, FMT_S),
9146    OPC_CVT_D_S = FOP(33, FMT_S),
9147    OPC_CVT_W_S = FOP(36, FMT_S),
9148    OPC_CVT_L_S = FOP(37, FMT_S),
9149    OPC_CVT_PS_S = FOP(38, FMT_S),
9150    OPC_CMP_F_S = FOP(48, FMT_S),
9151    OPC_CMP_UN_S = FOP(49, FMT_S),
9152    OPC_CMP_EQ_S = FOP(50, FMT_S),
9153    OPC_CMP_UEQ_S = FOP(51, FMT_S),
9154    OPC_CMP_OLT_S = FOP(52, FMT_S),
9155    OPC_CMP_ULT_S = FOP(53, FMT_S),
9156    OPC_CMP_OLE_S = FOP(54, FMT_S),
9157    OPC_CMP_ULE_S = FOP(55, FMT_S),
9158    OPC_CMP_SF_S = FOP(56, FMT_S),
9159    OPC_CMP_NGLE_S = FOP(57, FMT_S),
9160    OPC_CMP_SEQ_S = FOP(58, FMT_S),
9161    OPC_CMP_NGL_S = FOP(59, FMT_S),
9162    OPC_CMP_LT_S = FOP(60, FMT_S),
9163    OPC_CMP_NGE_S = FOP(61, FMT_S),
9164    OPC_CMP_LE_S = FOP(62, FMT_S),
9165    OPC_CMP_NGT_S = FOP(63, FMT_S),
9166
9167    OPC_ADD_D = FOP(0, FMT_D),
9168    OPC_SUB_D = FOP(1, FMT_D),
9169    OPC_MUL_D = FOP(2, FMT_D),
9170    OPC_DIV_D = FOP(3, FMT_D),
9171    OPC_SQRT_D = FOP(4, FMT_D),
9172    OPC_ABS_D = FOP(5, FMT_D),
9173    OPC_MOV_D = FOP(6, FMT_D),
9174    OPC_NEG_D = FOP(7, FMT_D),
9175    OPC_ROUND_L_D = FOP(8, FMT_D),
9176    OPC_TRUNC_L_D = FOP(9, FMT_D),
9177    OPC_CEIL_L_D = FOP(10, FMT_D),
9178    OPC_FLOOR_L_D = FOP(11, FMT_D),
9179    OPC_ROUND_W_D = FOP(12, FMT_D),
9180    OPC_TRUNC_W_D = FOP(13, FMT_D),
9181    OPC_CEIL_W_D = FOP(14, FMT_D),
9182    OPC_FLOOR_W_D = FOP(15, FMT_D),
9183    OPC_SEL_D = FOP(16, FMT_D),
9184    OPC_MOVCF_D = FOP(17, FMT_D),
9185    OPC_MOVZ_D = FOP(18, FMT_D),
9186    OPC_MOVN_D = FOP(19, FMT_D),
9187    OPC_SELEQZ_D = FOP(20, FMT_D),
9188    OPC_RECIP_D = FOP(21, FMT_D),
9189    OPC_RSQRT_D = FOP(22, FMT_D),
9190    OPC_SELNEZ_D = FOP(23, FMT_D),
9191    OPC_MADDF_D = FOP(24, FMT_D),
9192    OPC_MSUBF_D = FOP(25, FMT_D),
9193    OPC_RINT_D = FOP(26, FMT_D),
9194    OPC_CLASS_D = FOP(27, FMT_D),
9195    OPC_MIN_D = FOP(28, FMT_D),
9196    OPC_RECIP2_D = FOP(28, FMT_D),
9197    OPC_MINA_D = FOP(29, FMT_D),
9198    OPC_RECIP1_D = FOP(29, FMT_D),
9199    OPC_MAX_D = FOP(30, FMT_D),
9200    OPC_RSQRT1_D = FOP(30, FMT_D),
9201    OPC_MAXA_D = FOP(31, FMT_D),
9202    OPC_RSQRT2_D = FOP(31, FMT_D),
9203    OPC_CVT_S_D = FOP(32, FMT_D),
9204    OPC_CVT_W_D = FOP(36, FMT_D),
9205    OPC_CVT_L_D = FOP(37, FMT_D),
9206    OPC_CMP_F_D = FOP(48, FMT_D),
9207    OPC_CMP_UN_D = FOP(49, FMT_D),
9208    OPC_CMP_EQ_D = FOP(50, FMT_D),
9209    OPC_CMP_UEQ_D = FOP(51, FMT_D),
9210    OPC_CMP_OLT_D = FOP(52, FMT_D),
9211    OPC_CMP_ULT_D = FOP(53, FMT_D),
9212    OPC_CMP_OLE_D = FOP(54, FMT_D),
9213    OPC_CMP_ULE_D = FOP(55, FMT_D),
9214    OPC_CMP_SF_D = FOP(56, FMT_D),
9215    OPC_CMP_NGLE_D = FOP(57, FMT_D),
9216    OPC_CMP_SEQ_D = FOP(58, FMT_D),
9217    OPC_CMP_NGL_D = FOP(59, FMT_D),
9218    OPC_CMP_LT_D = FOP(60, FMT_D),
9219    OPC_CMP_NGE_D = FOP(61, FMT_D),
9220    OPC_CMP_LE_D = FOP(62, FMT_D),
9221    OPC_CMP_NGT_D = FOP(63, FMT_D),
9222
9223    OPC_CVT_S_W = FOP(32, FMT_W),
9224    OPC_CVT_D_W = FOP(33, FMT_W),
9225    OPC_CVT_S_L = FOP(32, FMT_L),
9226    OPC_CVT_D_L = FOP(33, FMT_L),
9227    OPC_CVT_PS_PW = FOP(38, FMT_W),
9228
9229    OPC_ADD_PS = FOP(0, FMT_PS),
9230    OPC_SUB_PS = FOP(1, FMT_PS),
9231    OPC_MUL_PS = FOP(2, FMT_PS),
9232    OPC_DIV_PS = FOP(3, FMT_PS),
9233    OPC_ABS_PS = FOP(5, FMT_PS),
9234    OPC_MOV_PS = FOP(6, FMT_PS),
9235    OPC_NEG_PS = FOP(7, FMT_PS),
9236    OPC_MOVCF_PS = FOP(17, FMT_PS),
9237    OPC_MOVZ_PS = FOP(18, FMT_PS),
9238    OPC_MOVN_PS = FOP(19, FMT_PS),
9239    OPC_ADDR_PS = FOP(24, FMT_PS),
9240    OPC_MULR_PS = FOP(26, FMT_PS),
9241    OPC_RECIP2_PS = FOP(28, FMT_PS),
9242    OPC_RECIP1_PS = FOP(29, FMT_PS),
9243    OPC_RSQRT1_PS = FOP(30, FMT_PS),
9244    OPC_RSQRT2_PS = FOP(31, FMT_PS),
9245
9246    OPC_CVT_S_PU = FOP(32, FMT_PS),
9247    OPC_CVT_PW_PS = FOP(36, FMT_PS),
9248    OPC_CVT_S_PL = FOP(40, FMT_PS),
9249    OPC_PLL_PS = FOP(44, FMT_PS),
9250    OPC_PLU_PS = FOP(45, FMT_PS),
9251    OPC_PUL_PS = FOP(46, FMT_PS),
9252    OPC_PUU_PS = FOP(47, FMT_PS),
9253    OPC_CMP_F_PS = FOP(48, FMT_PS),
9254    OPC_CMP_UN_PS = FOP(49, FMT_PS),
9255    OPC_CMP_EQ_PS = FOP(50, FMT_PS),
9256    OPC_CMP_UEQ_PS = FOP(51, FMT_PS),
9257    OPC_CMP_OLT_PS = FOP(52, FMT_PS),
9258    OPC_CMP_ULT_PS = FOP(53, FMT_PS),
9259    OPC_CMP_OLE_PS = FOP(54, FMT_PS),
9260    OPC_CMP_ULE_PS = FOP(55, FMT_PS),
9261    OPC_CMP_SF_PS = FOP(56, FMT_PS),
9262    OPC_CMP_NGLE_PS = FOP(57, FMT_PS),
9263    OPC_CMP_SEQ_PS = FOP(58, FMT_PS),
9264    OPC_CMP_NGL_PS = FOP(59, FMT_PS),
9265    OPC_CMP_LT_PS = FOP(60, FMT_PS),
9266    OPC_CMP_NGE_PS = FOP(61, FMT_PS),
9267    OPC_CMP_LE_PS = FOP(62, FMT_PS),
9268    OPC_CMP_NGT_PS = FOP(63, FMT_PS),
9269};
9270
9271enum r6_f_cmp_op {
9272    R6_OPC_CMP_AF_S   = FOP(0, FMT_W),
9273    R6_OPC_CMP_UN_S   = FOP(1, FMT_W),
9274    R6_OPC_CMP_EQ_S   = FOP(2, FMT_W),
9275    R6_OPC_CMP_UEQ_S  = FOP(3, FMT_W),
9276    R6_OPC_CMP_LT_S   = FOP(4, FMT_W),
9277    R6_OPC_CMP_ULT_S  = FOP(5, FMT_W),
9278    R6_OPC_CMP_LE_S   = FOP(6, FMT_W),
9279    R6_OPC_CMP_ULE_S  = FOP(7, FMT_W),
9280    R6_OPC_CMP_SAF_S  = FOP(8, FMT_W),
9281    R6_OPC_CMP_SUN_S  = FOP(9, FMT_W),
9282    R6_OPC_CMP_SEQ_S  = FOP(10, FMT_W),
9283    R6_OPC_CMP_SEUQ_S = FOP(11, FMT_W),
9284    R6_OPC_CMP_SLT_S  = FOP(12, FMT_W),
9285    R6_OPC_CMP_SULT_S = FOP(13, FMT_W),
9286    R6_OPC_CMP_SLE_S  = FOP(14, FMT_W),
9287    R6_OPC_CMP_SULE_S = FOP(15, FMT_W),
9288    R6_OPC_CMP_OR_S   = FOP(17, FMT_W),
9289    R6_OPC_CMP_UNE_S  = FOP(18, FMT_W),
9290    R6_OPC_CMP_NE_S   = FOP(19, FMT_W),
9291    R6_OPC_CMP_SOR_S  = FOP(25, FMT_W),
9292    R6_OPC_CMP_SUNE_S = FOP(26, FMT_W),
9293    R6_OPC_CMP_SNE_S  = FOP(27, FMT_W),
9294
9295    R6_OPC_CMP_AF_D   = FOP(0, FMT_L),
9296    R6_OPC_CMP_UN_D   = FOP(1, FMT_L),
9297    R6_OPC_CMP_EQ_D   = FOP(2, FMT_L),
9298    R6_OPC_CMP_UEQ_D  = FOP(3, FMT_L),
9299    R6_OPC_CMP_LT_D   = FOP(4, FMT_L),
9300    R6_OPC_CMP_ULT_D  = FOP(5, FMT_L),
9301    R6_OPC_CMP_LE_D   = FOP(6, FMT_L),
9302    R6_OPC_CMP_ULE_D  = FOP(7, FMT_L),
9303    R6_OPC_CMP_SAF_D  = FOP(8, FMT_L),
9304    R6_OPC_CMP_SUN_D  = FOP(9, FMT_L),
9305    R6_OPC_CMP_SEQ_D  = FOP(10, FMT_L),
9306    R6_OPC_CMP_SEUQ_D = FOP(11, FMT_L),
9307    R6_OPC_CMP_SLT_D  = FOP(12, FMT_L),
9308    R6_OPC_CMP_SULT_D = FOP(13, FMT_L),
9309    R6_OPC_CMP_SLE_D  = FOP(14, FMT_L),
9310    R6_OPC_CMP_SULE_D = FOP(15, FMT_L),
9311    R6_OPC_CMP_OR_D   = FOP(17, FMT_L),
9312    R6_OPC_CMP_UNE_D  = FOP(18, FMT_L),
9313    R6_OPC_CMP_NE_D   = FOP(19, FMT_L),
9314    R6_OPC_CMP_SOR_D  = FOP(25, FMT_L),
9315    R6_OPC_CMP_SUNE_D = FOP(26, FMT_L),
9316    R6_OPC_CMP_SNE_D  = FOP(27, FMT_L),
9317};
9318
9319static void gen_cp1(DisasContext *ctx, uint32_t opc, int rt, int fs)
9320{
9321    TCGv t0 = tcg_temp_new();
9322
9323    switch (opc) {
9324    case OPC_MFC1:
9325        {
9326            TCGv_i32 fp0 = tcg_temp_new_i32();
9327
9328            gen_load_fpr32(ctx, fp0, fs);
9329            tcg_gen_ext_i32_tl(t0, fp0);
9330        }
9331        gen_store_gpr(t0, rt);
9332        break;
9333    case OPC_MTC1:
9334        gen_load_gpr(t0, rt);
9335        {
9336            TCGv_i32 fp0 = tcg_temp_new_i32();
9337
9338            tcg_gen_trunc_tl_i32(fp0, t0);
9339            gen_store_fpr32(ctx, fp0, fs);
9340        }
9341        break;
9342    case OPC_CFC1:
9343        gen_helper_1e0i(cfc1, t0, fs);
9344        gen_store_gpr(t0, rt);
9345        break;
9346    case OPC_CTC1:
9347        gen_load_gpr(t0, rt);
9348        save_cpu_state(ctx, 0);
9349        gen_helper_0e2i(ctc1, t0, tcg_constant_i32(fs), rt);
9350        /* Stop translation as we may have changed hflags */
9351        ctx->base.is_jmp = DISAS_STOP;
9352        break;
9353#if defined(TARGET_MIPS64)
9354    case OPC_DMFC1:
9355        gen_load_fpr64(ctx, t0, fs);
9356        gen_store_gpr(t0, rt);
9357        break;
9358    case OPC_DMTC1:
9359        gen_load_gpr(t0, rt);
9360        gen_store_fpr64(ctx, t0, fs);
9361        break;
9362#endif
9363    case OPC_MFHC1:
9364        {
9365            TCGv_i32 fp0 = tcg_temp_new_i32();
9366
9367            gen_load_fpr32h(ctx, fp0, fs);
9368            tcg_gen_ext_i32_tl(t0, fp0);
9369        }
9370        gen_store_gpr(t0, rt);
9371        break;
9372    case OPC_MTHC1:
9373        gen_load_gpr(t0, rt);
9374        {
9375            TCGv_i32 fp0 = tcg_temp_new_i32();
9376
9377            tcg_gen_trunc_tl_i32(fp0, t0);
9378            gen_store_fpr32h(ctx, fp0, fs);
9379        }
9380        break;
9381    default:
9382        MIPS_INVAL("cp1 move");
9383        gen_reserved_instruction(ctx);
9384        return;
9385    }
9386}
9387
9388static void gen_movci(DisasContext *ctx, int rd, int rs, int cc, int tf)
9389{
9390    TCGLabel *l1;
9391    TCGCond cond;
9392    TCGv_i32 t0;
9393
9394    if (rd == 0) {
9395        /* Treat as NOP. */
9396        return;
9397    }
9398
9399    if (tf) {
9400        cond = TCG_COND_EQ;
9401    } else {
9402        cond = TCG_COND_NE;
9403    }
9404
9405    l1 = gen_new_label();
9406    t0 = tcg_temp_new_i32();
9407    tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
9408    tcg_gen_brcondi_i32(cond, t0, 0, l1);
9409    gen_load_gpr(cpu_gpr[rd], rs);
9410    gen_set_label(l1);
9411}
9412
9413static inline void gen_movcf_s(DisasContext *ctx, int fs, int fd, int cc,
9414                               int tf)
9415{
9416    int cond;
9417    TCGv_i32 t0 = tcg_temp_new_i32();
9418    TCGLabel *l1 = gen_new_label();
9419
9420    if (tf) {
9421        cond = TCG_COND_EQ;
9422    } else {
9423        cond = TCG_COND_NE;
9424    }
9425
9426    tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
9427    tcg_gen_brcondi_i32(cond, t0, 0, l1);
9428    gen_load_fpr32(ctx, t0, fs);
9429    gen_store_fpr32(ctx, t0, fd);
9430    gen_set_label(l1);
9431}
9432
9433static inline void gen_movcf_d(DisasContext *ctx, int fs, int fd, int cc,
9434                               int tf)
9435{
9436    int cond;
9437    TCGv_i32 t0 = tcg_temp_new_i32();
9438    TCGv_i64 fp0;
9439    TCGLabel *l1 = gen_new_label();
9440
9441    if (tf) {
9442        cond = TCG_COND_EQ;
9443    } else {
9444        cond = TCG_COND_NE;
9445    }
9446
9447    tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
9448    tcg_gen_brcondi_i32(cond, t0, 0, l1);
9449    fp0 = tcg_temp_new_i64();
9450    gen_load_fpr64(ctx, fp0, fs);
9451    gen_store_fpr64(ctx, fp0, fd);
9452    gen_set_label(l1);
9453}
9454
9455static inline void gen_movcf_ps(DisasContext *ctx, int fs, int fd,
9456                                int cc, int tf)
9457{
9458    int cond;
9459    TCGv_i32 t0 = tcg_temp_new_i32();
9460    TCGLabel *l1 = gen_new_label();
9461    TCGLabel *l2 = gen_new_label();
9462
9463    if (tf) {
9464        cond = TCG_COND_EQ;
9465    } else {
9466        cond = TCG_COND_NE;
9467    }
9468
9469    tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
9470    tcg_gen_brcondi_i32(cond, t0, 0, l1);
9471    gen_load_fpr32(ctx, t0, fs);
9472    gen_store_fpr32(ctx, t0, fd);
9473    gen_set_label(l1);
9474
9475    tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc + 1));
9476    tcg_gen_brcondi_i32(cond, t0, 0, l2);
9477    gen_load_fpr32h(ctx, t0, fs);
9478    gen_store_fpr32h(ctx, t0, fd);
9479    gen_set_label(l2);
9480}
9481
9482static void gen_sel_s(DisasContext *ctx, enum fopcode op1, int fd, int ft,
9483                      int fs)
9484{
9485    TCGv_i32 t1 = tcg_constant_i32(0);
9486    TCGv_i32 fp0 = tcg_temp_new_i32();
9487    TCGv_i32 fp1 = tcg_temp_new_i32();
9488    TCGv_i32 fp2 = tcg_temp_new_i32();
9489    gen_load_fpr32(ctx, fp0, fd);
9490    gen_load_fpr32(ctx, fp1, ft);
9491    gen_load_fpr32(ctx, fp2, fs);
9492
9493    switch (op1) {
9494    case OPC_SEL_S:
9495        tcg_gen_andi_i32(fp0, fp0, 1);
9496        tcg_gen_movcond_i32(TCG_COND_NE, fp0, fp0, t1, fp1, fp2);
9497        break;
9498    case OPC_SELEQZ_S:
9499        tcg_gen_andi_i32(fp1, fp1, 1);
9500        tcg_gen_movcond_i32(TCG_COND_EQ, fp0, fp1, t1, fp2, t1);
9501        break;
9502    case OPC_SELNEZ_S:
9503        tcg_gen_andi_i32(fp1, fp1, 1);
9504        tcg_gen_movcond_i32(TCG_COND_NE, fp0, fp1, t1, fp2, t1);
9505        break;
9506    default:
9507        MIPS_INVAL("gen_sel_s");
9508        gen_reserved_instruction(ctx);
9509        break;
9510    }
9511
9512    gen_store_fpr32(ctx, fp0, fd);
9513}
9514
9515static void gen_sel_d(DisasContext *ctx, enum fopcode op1, int fd, int ft,
9516                      int fs)
9517{
9518    TCGv_i64 t1 = tcg_constant_i64(0);
9519    TCGv_i64 fp0 = tcg_temp_new_i64();
9520    TCGv_i64 fp1 = tcg_temp_new_i64();
9521    TCGv_i64 fp2 = tcg_temp_new_i64();
9522    gen_load_fpr64(ctx, fp0, fd);
9523    gen_load_fpr64(ctx, fp1, ft);
9524    gen_load_fpr64(ctx, fp2, fs);
9525
9526    switch (op1) {
9527    case OPC_SEL_D:
9528        tcg_gen_andi_i64(fp0, fp0, 1);
9529        tcg_gen_movcond_i64(TCG_COND_NE, fp0, fp0, t1, fp1, fp2);
9530        break;
9531    case OPC_SELEQZ_D:
9532        tcg_gen_andi_i64(fp1, fp1, 1);
9533        tcg_gen_movcond_i64(TCG_COND_EQ, fp0, fp1, t1, fp2, t1);
9534        break;
9535    case OPC_SELNEZ_D:
9536        tcg_gen_andi_i64(fp1, fp1, 1);
9537        tcg_gen_movcond_i64(TCG_COND_NE, fp0, fp1, t1, fp2, t1);
9538        break;
9539    default:
9540        MIPS_INVAL("gen_sel_d");
9541        gen_reserved_instruction(ctx);
9542        break;
9543    }
9544
9545    gen_store_fpr64(ctx, fp0, fd);
9546}
9547
9548static void gen_farith(DisasContext *ctx, enum fopcode op1,
9549                       int ft, int fs, int fd, int cc)
9550{
9551    uint32_t func = ctx->opcode & 0x3f;
9552    switch (op1) {
9553    case OPC_ADD_S:
9554        {
9555            TCGv_i32 fp0 = tcg_temp_new_i32();
9556            TCGv_i32 fp1 = tcg_temp_new_i32();
9557
9558            gen_load_fpr32(ctx, fp0, fs);
9559            gen_load_fpr32(ctx, fp1, ft);
9560            gen_helper_float_add_s(fp0, cpu_env, fp0, fp1);
9561            gen_store_fpr32(ctx, fp0, fd);
9562        }
9563        break;
9564    case OPC_SUB_S:
9565        {
9566            TCGv_i32 fp0 = tcg_temp_new_i32();
9567            TCGv_i32 fp1 = tcg_temp_new_i32();
9568
9569            gen_load_fpr32(ctx, fp0, fs);
9570            gen_load_fpr32(ctx, fp1, ft);
9571            gen_helper_float_sub_s(fp0, cpu_env, fp0, fp1);
9572            gen_store_fpr32(ctx, fp0, fd);
9573        }
9574        break;
9575    case OPC_MUL_S:
9576        {
9577            TCGv_i32 fp0 = tcg_temp_new_i32();
9578            TCGv_i32 fp1 = tcg_temp_new_i32();
9579
9580            gen_load_fpr32(ctx, fp0, fs);
9581            gen_load_fpr32(ctx, fp1, ft);
9582            gen_helper_float_mul_s(fp0, cpu_env, fp0, fp1);
9583            gen_store_fpr32(ctx, fp0, fd);
9584        }
9585        break;
9586    case OPC_DIV_S:
9587        {
9588            TCGv_i32 fp0 = tcg_temp_new_i32();
9589            TCGv_i32 fp1 = tcg_temp_new_i32();
9590
9591            gen_load_fpr32(ctx, fp0, fs);
9592            gen_load_fpr32(ctx, fp1, ft);
9593            gen_helper_float_div_s(fp0, cpu_env, fp0, fp1);
9594            gen_store_fpr32(ctx, fp0, fd);
9595        }
9596        break;
9597    case OPC_SQRT_S:
9598        {
9599            TCGv_i32 fp0 = tcg_temp_new_i32();
9600
9601            gen_load_fpr32(ctx, fp0, fs);
9602            gen_helper_float_sqrt_s(fp0, cpu_env, fp0);
9603            gen_store_fpr32(ctx, fp0, fd);
9604        }
9605        break;
9606    case OPC_ABS_S:
9607        {
9608            TCGv_i32 fp0 = tcg_temp_new_i32();
9609
9610            gen_load_fpr32(ctx, fp0, fs);
9611            if (ctx->abs2008) {
9612                tcg_gen_andi_i32(fp0, fp0, 0x7fffffffUL);
9613            } else {
9614                gen_helper_float_abs_s(fp0, fp0);
9615            }
9616            gen_store_fpr32(ctx, fp0, fd);
9617        }
9618        break;
9619    case OPC_MOV_S:
9620        {
9621            TCGv_i32 fp0 = tcg_temp_new_i32();
9622
9623            gen_load_fpr32(ctx, fp0, fs);
9624            gen_store_fpr32(ctx, fp0, fd);
9625        }
9626        break;
9627    case OPC_NEG_S:
9628        {
9629            TCGv_i32 fp0 = tcg_temp_new_i32();
9630
9631            gen_load_fpr32(ctx, fp0, fs);
9632            if (ctx->abs2008) {
9633                tcg_gen_xori_i32(fp0, fp0, 1UL << 31);
9634            } else {
9635                gen_helper_float_chs_s(fp0, fp0);
9636            }
9637            gen_store_fpr32(ctx, fp0, fd);
9638        }
9639        break;
9640    case OPC_ROUND_L_S:
9641        check_cp1_64bitmode(ctx);
9642        {
9643            TCGv_i32 fp32 = tcg_temp_new_i32();
9644            TCGv_i64 fp64 = tcg_temp_new_i64();
9645
9646            gen_load_fpr32(ctx, fp32, fs);
9647            if (ctx->nan2008) {
9648                gen_helper_float_round_2008_l_s(fp64, cpu_env, fp32);
9649            } else {
9650                gen_helper_float_round_l_s(fp64, cpu_env, fp32);
9651            }
9652            gen_store_fpr64(ctx, fp64, fd);
9653        }
9654        break;
9655    case OPC_TRUNC_L_S:
9656        check_cp1_64bitmode(ctx);
9657        {
9658            TCGv_i32 fp32 = tcg_temp_new_i32();
9659            TCGv_i64 fp64 = tcg_temp_new_i64();
9660
9661            gen_load_fpr32(ctx, fp32, fs);
9662            if (ctx->nan2008) {
9663                gen_helper_float_trunc_2008_l_s(fp64, cpu_env, fp32);
9664            } else {
9665                gen_helper_float_trunc_l_s(fp64, cpu_env, fp32);
9666            }
9667            gen_store_fpr64(ctx, fp64, fd);
9668        }
9669        break;
9670    case OPC_CEIL_L_S:
9671        check_cp1_64bitmode(ctx);
9672        {
9673            TCGv_i32 fp32 = tcg_temp_new_i32();
9674            TCGv_i64 fp64 = tcg_temp_new_i64();
9675
9676            gen_load_fpr32(ctx, fp32, fs);
9677            if (ctx->nan2008) {
9678                gen_helper_float_ceil_2008_l_s(fp64, cpu_env, fp32);
9679            } else {
9680                gen_helper_float_ceil_l_s(fp64, cpu_env, fp32);
9681            }
9682            gen_store_fpr64(ctx, fp64, fd);
9683        }
9684        break;
9685    case OPC_FLOOR_L_S:
9686        check_cp1_64bitmode(ctx);
9687        {
9688            TCGv_i32 fp32 = tcg_temp_new_i32();
9689            TCGv_i64 fp64 = tcg_temp_new_i64();
9690
9691            gen_load_fpr32(ctx, fp32, fs);
9692            if (ctx->nan2008) {
9693                gen_helper_float_floor_2008_l_s(fp64, cpu_env, fp32);
9694            } else {
9695                gen_helper_float_floor_l_s(fp64, cpu_env, fp32);
9696            }
9697            gen_store_fpr64(ctx, fp64, fd);
9698        }
9699        break;
9700    case OPC_ROUND_W_S:
9701        {
9702            TCGv_i32 fp0 = tcg_temp_new_i32();
9703
9704            gen_load_fpr32(ctx, fp0, fs);
9705            if (ctx->nan2008) {
9706                gen_helper_float_round_2008_w_s(fp0, cpu_env, fp0);
9707            } else {
9708                gen_helper_float_round_w_s(fp0, cpu_env, fp0);
9709            }
9710            gen_store_fpr32(ctx, fp0, fd);
9711        }
9712        break;
9713    case OPC_TRUNC_W_S:
9714        {
9715            TCGv_i32 fp0 = tcg_temp_new_i32();
9716
9717            gen_load_fpr32(ctx, fp0, fs);
9718            if (ctx->nan2008) {
9719                gen_helper_float_trunc_2008_w_s(fp0, cpu_env, fp0);
9720            } else {
9721                gen_helper_float_trunc_w_s(fp0, cpu_env, fp0);
9722            }
9723            gen_store_fpr32(ctx, fp0, fd);
9724        }
9725        break;
9726    case OPC_CEIL_W_S:
9727        {
9728            TCGv_i32 fp0 = tcg_temp_new_i32();
9729
9730            gen_load_fpr32(ctx, fp0, fs);
9731            if (ctx->nan2008) {
9732                gen_helper_float_ceil_2008_w_s(fp0, cpu_env, fp0);
9733            } else {
9734                gen_helper_float_ceil_w_s(fp0, cpu_env, fp0);
9735            }
9736            gen_store_fpr32(ctx, fp0, fd);
9737        }
9738        break;
9739    case OPC_FLOOR_W_S:
9740        {
9741            TCGv_i32 fp0 = tcg_temp_new_i32();
9742
9743            gen_load_fpr32(ctx, fp0, fs);
9744            if (ctx->nan2008) {
9745                gen_helper_float_floor_2008_w_s(fp0, cpu_env, fp0);
9746            } else {
9747                gen_helper_float_floor_w_s(fp0, cpu_env, fp0);
9748            }
9749            gen_store_fpr32(ctx, fp0, fd);
9750        }
9751        break;
9752    case OPC_SEL_S:
9753        check_insn(ctx, ISA_MIPS_R6);
9754        gen_sel_s(ctx, op1, fd, ft, fs);
9755        break;
9756    case OPC_SELEQZ_S:
9757        check_insn(ctx, ISA_MIPS_R6);
9758        gen_sel_s(ctx, op1, fd, ft, fs);
9759        break;
9760    case OPC_SELNEZ_S:
9761        check_insn(ctx, ISA_MIPS_R6);
9762        gen_sel_s(ctx, op1, fd, ft, fs);
9763        break;
9764    case OPC_MOVCF_S:
9765        check_insn_opc_removed(ctx, ISA_MIPS_R6);
9766        gen_movcf_s(ctx, fs, fd, (ft >> 2) & 0x7, ft & 0x1);
9767        break;
9768    case OPC_MOVZ_S:
9769        check_insn_opc_removed(ctx, ISA_MIPS_R6);
9770        {
9771            TCGLabel *l1 = gen_new_label();
9772            TCGv_i32 fp0;
9773
9774            if (ft != 0) {
9775                tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[ft], 0, l1);
9776            }
9777            fp0 = tcg_temp_new_i32();
9778            gen_load_fpr32(ctx, fp0, fs);
9779            gen_store_fpr32(ctx, fp0, fd);
9780            gen_set_label(l1);
9781        }
9782        break;
9783    case OPC_MOVN_S:
9784        check_insn_opc_removed(ctx, ISA_MIPS_R6);
9785        {
9786            TCGLabel *l1 = gen_new_label();
9787            TCGv_i32 fp0;
9788
9789            if (ft != 0) {
9790                tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[ft], 0, l1);
9791                fp0 = tcg_temp_new_i32();
9792                gen_load_fpr32(ctx, fp0, fs);
9793                gen_store_fpr32(ctx, fp0, fd);
9794                gen_set_label(l1);
9795            }
9796        }
9797        break;
9798    case OPC_RECIP_S:
9799        {
9800            TCGv_i32 fp0 = tcg_temp_new_i32();
9801
9802            gen_load_fpr32(ctx, fp0, fs);
9803            gen_helper_float_recip_s(fp0, cpu_env, fp0);
9804            gen_store_fpr32(ctx, fp0, fd);
9805        }
9806        break;
9807    case OPC_RSQRT_S:
9808        {
9809            TCGv_i32 fp0 = tcg_temp_new_i32();
9810
9811            gen_load_fpr32(ctx, fp0, fs);
9812            gen_helper_float_rsqrt_s(fp0, cpu_env, fp0);
9813            gen_store_fpr32(ctx, fp0, fd);
9814        }
9815        break;
9816    case OPC_MADDF_S:
9817        check_insn(ctx, ISA_MIPS_R6);
9818        {
9819            TCGv_i32 fp0 = tcg_temp_new_i32();
9820            TCGv_i32 fp1 = tcg_temp_new_i32();
9821            TCGv_i32 fp2 = tcg_temp_new_i32();
9822            gen_load_fpr32(ctx, fp0, fs);
9823            gen_load_fpr32(ctx, fp1, ft);
9824            gen_load_fpr32(ctx, fp2, fd);
9825            gen_helper_float_maddf_s(fp2, cpu_env, fp0, fp1, fp2);
9826            gen_store_fpr32(ctx, fp2, fd);
9827        }
9828        break;
9829    case OPC_MSUBF_S:
9830        check_insn(ctx, ISA_MIPS_R6);
9831        {
9832            TCGv_i32 fp0 = tcg_temp_new_i32();
9833            TCGv_i32 fp1 = tcg_temp_new_i32();
9834            TCGv_i32 fp2 = tcg_temp_new_i32();
9835            gen_load_fpr32(ctx, fp0, fs);
9836            gen_load_fpr32(ctx, fp1, ft);
9837            gen_load_fpr32(ctx, fp2, fd);
9838            gen_helper_float_msubf_s(fp2, cpu_env, fp0, fp1, fp2);
9839            gen_store_fpr32(ctx, fp2, fd);
9840        }
9841        break;
9842    case OPC_RINT_S:
9843        check_insn(ctx, ISA_MIPS_R6);
9844        {
9845            TCGv_i32 fp0 = tcg_temp_new_i32();
9846            gen_load_fpr32(ctx, fp0, fs);
9847            gen_helper_float_rint_s(fp0, cpu_env, fp0);
9848            gen_store_fpr32(ctx, fp0, fd);
9849        }
9850        break;
9851    case OPC_CLASS_S:
9852        check_insn(ctx, ISA_MIPS_R6);
9853        {
9854            TCGv_i32 fp0 = tcg_temp_new_i32();
9855            gen_load_fpr32(ctx, fp0, fs);
9856            gen_helper_float_class_s(fp0, cpu_env, fp0);
9857            gen_store_fpr32(ctx, fp0, fd);
9858        }
9859        break;
9860    case OPC_MIN_S: /* OPC_RECIP2_S */
9861        if (ctx->insn_flags & ISA_MIPS_R6) {
9862            /* OPC_MIN_S */
9863            TCGv_i32 fp0 = tcg_temp_new_i32();
9864            TCGv_i32 fp1 = tcg_temp_new_i32();
9865            TCGv_i32 fp2 = tcg_temp_new_i32();
9866            gen_load_fpr32(ctx, fp0, fs);
9867            gen_load_fpr32(ctx, fp1, ft);
9868            gen_helper_float_min_s(fp2, cpu_env, fp0, fp1);
9869            gen_store_fpr32(ctx, fp2, fd);
9870        } else {
9871            /* OPC_RECIP2_S */
9872            check_cp1_64bitmode(ctx);
9873            {
9874                TCGv_i32 fp0 = tcg_temp_new_i32();
9875                TCGv_i32 fp1 = tcg_temp_new_i32();
9876
9877                gen_load_fpr32(ctx, fp0, fs);
9878                gen_load_fpr32(ctx, fp1, ft);
9879                gen_helper_float_recip2_s(fp0, cpu_env, fp0, fp1);
9880                gen_store_fpr32(ctx, fp0, fd);
9881            }
9882        }
9883        break;
9884    case OPC_MINA_S: /* OPC_RECIP1_S */
9885        if (ctx->insn_flags & ISA_MIPS_R6) {
9886            /* OPC_MINA_S */
9887            TCGv_i32 fp0 = tcg_temp_new_i32();
9888            TCGv_i32 fp1 = tcg_temp_new_i32();
9889            TCGv_i32 fp2 = tcg_temp_new_i32();
9890            gen_load_fpr32(ctx, fp0, fs);
9891            gen_load_fpr32(ctx, fp1, ft);
9892            gen_helper_float_mina_s(fp2, cpu_env, fp0, fp1);
9893            gen_store_fpr32(ctx, fp2, fd);
9894        } else {
9895            /* OPC_RECIP1_S */
9896            check_cp1_64bitmode(ctx);
9897            {
9898                TCGv_i32 fp0 = tcg_temp_new_i32();
9899
9900                gen_load_fpr32(ctx, fp0, fs);
9901                gen_helper_float_recip1_s(fp0, cpu_env, fp0);
9902                gen_store_fpr32(ctx, fp0, fd);
9903            }
9904        }
9905        break;
9906    case OPC_MAX_S: /* OPC_RSQRT1_S */
9907        if (ctx->insn_flags & ISA_MIPS_R6) {
9908            /* OPC_MAX_S */
9909            TCGv_i32 fp0 = tcg_temp_new_i32();
9910            TCGv_i32 fp1 = tcg_temp_new_i32();
9911            gen_load_fpr32(ctx, fp0, fs);
9912            gen_load_fpr32(ctx, fp1, ft);
9913            gen_helper_float_max_s(fp1, cpu_env, fp0, fp1);
9914            gen_store_fpr32(ctx, fp1, fd);
9915        } else {
9916            /* OPC_RSQRT1_S */
9917            check_cp1_64bitmode(ctx);
9918            {
9919                TCGv_i32 fp0 = tcg_temp_new_i32();
9920
9921                gen_load_fpr32(ctx, fp0, fs);
9922                gen_helper_float_rsqrt1_s(fp0, cpu_env, fp0);
9923                gen_store_fpr32(ctx, fp0, fd);
9924            }
9925        }
9926        break;
9927    case OPC_MAXA_S: /* OPC_RSQRT2_S */
9928        if (ctx->insn_flags & ISA_MIPS_R6) {
9929            /* OPC_MAXA_S */
9930            TCGv_i32 fp0 = tcg_temp_new_i32();
9931            TCGv_i32 fp1 = tcg_temp_new_i32();
9932            gen_load_fpr32(ctx, fp0, fs);
9933            gen_load_fpr32(ctx, fp1, ft);
9934            gen_helper_float_maxa_s(fp1, cpu_env, fp0, fp1);
9935            gen_store_fpr32(ctx, fp1, fd);
9936        } else {
9937            /* OPC_RSQRT2_S */
9938            check_cp1_64bitmode(ctx);
9939            {
9940                TCGv_i32 fp0 = tcg_temp_new_i32();
9941                TCGv_i32 fp1 = tcg_temp_new_i32();
9942
9943                gen_load_fpr32(ctx, fp0, fs);
9944                gen_load_fpr32(ctx, fp1, ft);
9945                gen_helper_float_rsqrt2_s(fp0, cpu_env, fp0, fp1);
9946                gen_store_fpr32(ctx, fp0, fd);
9947            }
9948        }
9949        break;
9950    case OPC_CVT_D_S:
9951        check_cp1_registers(ctx, fd);
9952        {
9953            TCGv_i32 fp32 = tcg_temp_new_i32();
9954            TCGv_i64 fp64 = tcg_temp_new_i64();
9955
9956            gen_load_fpr32(ctx, fp32, fs);
9957            gen_helper_float_cvtd_s(fp64, cpu_env, fp32);
9958            gen_store_fpr64(ctx, fp64, fd);
9959        }
9960        break;
9961    case OPC_CVT_W_S:
9962        {
9963            TCGv_i32 fp0 = tcg_temp_new_i32();
9964
9965            gen_load_fpr32(ctx, fp0, fs);
9966            if (ctx->nan2008) {
9967                gen_helper_float_cvt_2008_w_s(fp0, cpu_env, fp0);
9968            } else {
9969                gen_helper_float_cvt_w_s(fp0, cpu_env, fp0);
9970            }
9971            gen_store_fpr32(ctx, fp0, fd);
9972        }
9973        break;
9974    case OPC_CVT_L_S:
9975        check_cp1_64bitmode(ctx);
9976        {
9977            TCGv_i32 fp32 = tcg_temp_new_i32();
9978            TCGv_i64 fp64 = tcg_temp_new_i64();
9979
9980            gen_load_fpr32(ctx, fp32, fs);
9981            if (ctx->nan2008) {
9982                gen_helper_float_cvt_2008_l_s(fp64, cpu_env, fp32);
9983            } else {
9984                gen_helper_float_cvt_l_s(fp64, cpu_env, fp32);
9985            }
9986            gen_store_fpr64(ctx, fp64, fd);
9987        }
9988        break;
9989    case OPC_CVT_PS_S:
9990        check_ps(ctx);
9991        {
9992            TCGv_i64 fp64 = tcg_temp_new_i64();
9993            TCGv_i32 fp32_0 = tcg_temp_new_i32();
9994            TCGv_i32 fp32_1 = tcg_temp_new_i32();
9995
9996            gen_load_fpr32(ctx, fp32_0, fs);
9997            gen_load_fpr32(ctx, fp32_1, ft);
9998            tcg_gen_concat_i32_i64(fp64, fp32_1, fp32_0);
9999            gen_store_fpr64(ctx, fp64, fd);
10000        }
10001        break;
10002    case OPC_CMP_F_S:
10003    case OPC_CMP_UN_S:
10004    case OPC_CMP_EQ_S:
10005    case OPC_CMP_UEQ_S:
10006    case OPC_CMP_OLT_S:
10007    case OPC_CMP_ULT_S:
10008    case OPC_CMP_OLE_S:
10009    case OPC_CMP_ULE_S:
10010    case OPC_CMP_SF_S:
10011    case OPC_CMP_NGLE_S:
10012    case OPC_CMP_SEQ_S:
10013    case OPC_CMP_NGL_S:
10014    case OPC_CMP_LT_S:
10015    case OPC_CMP_NGE_S:
10016    case OPC_CMP_LE_S:
10017    case OPC_CMP_NGT_S:
10018        check_insn_opc_removed(ctx, ISA_MIPS_R6);
10019        if (ctx->opcode & (1 << 6)) {
10020            gen_cmpabs_s(ctx, func - 48, ft, fs, cc);
10021        } else {
10022            gen_cmp_s(ctx, func - 48, ft, fs, cc);
10023        }
10024        break;
10025    case OPC_ADD_D:
10026        check_cp1_registers(ctx, fs | ft | fd);
10027        {
10028            TCGv_i64 fp0 = tcg_temp_new_i64();
10029            TCGv_i64 fp1 = tcg_temp_new_i64();
10030
10031            gen_load_fpr64(ctx, fp0, fs);
10032            gen_load_fpr64(ctx, fp1, ft);
10033            gen_helper_float_add_d(fp0, cpu_env, fp0, fp1);
10034            gen_store_fpr64(ctx, fp0, fd);
10035        }
10036        break;
10037    case OPC_SUB_D:
10038        check_cp1_registers(ctx, fs | ft | fd);
10039        {
10040            TCGv_i64 fp0 = tcg_temp_new_i64();
10041            TCGv_i64 fp1 = tcg_temp_new_i64();
10042
10043            gen_load_fpr64(ctx, fp0, fs);
10044            gen_load_fpr64(ctx, fp1, ft);
10045            gen_helper_float_sub_d(fp0, cpu_env, fp0, fp1);
10046            gen_store_fpr64(ctx, fp0, fd);
10047        }
10048        break;
10049    case OPC_MUL_D:
10050        check_cp1_registers(ctx, fs | ft | fd);
10051        {
10052            TCGv_i64 fp0 = tcg_temp_new_i64();
10053            TCGv_i64 fp1 = tcg_temp_new_i64();
10054
10055            gen_load_fpr64(ctx, fp0, fs);
10056            gen_load_fpr64(ctx, fp1, ft);
10057            gen_helper_float_mul_d(fp0, cpu_env, fp0, fp1);
10058            gen_store_fpr64(ctx, fp0, fd);
10059        }
10060        break;
10061    case OPC_DIV_D:
10062        check_cp1_registers(ctx, fs | ft | fd);
10063        {
10064            TCGv_i64 fp0 = tcg_temp_new_i64();
10065            TCGv_i64 fp1 = tcg_temp_new_i64();
10066
10067            gen_load_fpr64(ctx, fp0, fs);
10068            gen_load_fpr64(ctx, fp1, ft);
10069            gen_helper_float_div_d(fp0, cpu_env, fp0, fp1);
10070            gen_store_fpr64(ctx, fp0, fd);
10071        }
10072        break;
10073    case OPC_SQRT_D:
10074        check_cp1_registers(ctx, fs | fd);
10075        {
10076            TCGv_i64 fp0 = tcg_temp_new_i64();
10077
10078            gen_load_fpr64(ctx, fp0, fs);
10079            gen_helper_float_sqrt_d(fp0, cpu_env, fp0);
10080            gen_store_fpr64(ctx, fp0, fd);
10081        }
10082        break;
10083    case OPC_ABS_D:
10084        check_cp1_registers(ctx, fs | fd);
10085        {
10086            TCGv_i64 fp0 = tcg_temp_new_i64();
10087
10088            gen_load_fpr64(ctx, fp0, fs);
10089            if (ctx->abs2008) {
10090                tcg_gen_andi_i64(fp0, fp0, 0x7fffffffffffffffULL);
10091            } else {
10092                gen_helper_float_abs_d(fp0, fp0);
10093            }
10094            gen_store_fpr64(ctx, fp0, fd);
10095        }
10096        break;
10097    case OPC_MOV_D:
10098        check_cp1_registers(ctx, fs | fd);
10099        {
10100            TCGv_i64 fp0 = tcg_temp_new_i64();
10101
10102            gen_load_fpr64(ctx, fp0, fs);
10103            gen_store_fpr64(ctx, fp0, fd);
10104        }
10105        break;
10106    case OPC_NEG_D:
10107        check_cp1_registers(ctx, fs | fd);
10108        {
10109            TCGv_i64 fp0 = tcg_temp_new_i64();
10110
10111            gen_load_fpr64(ctx, fp0, fs);
10112            if (ctx->abs2008) {
10113                tcg_gen_xori_i64(fp0, fp0, 1ULL << 63);
10114            } else {
10115                gen_helper_float_chs_d(fp0, fp0);
10116            }
10117            gen_store_fpr64(ctx, fp0, fd);
10118        }
10119        break;
10120    case OPC_ROUND_L_D:
10121        check_cp1_64bitmode(ctx);
10122        {
10123            TCGv_i64 fp0 = tcg_temp_new_i64();
10124
10125            gen_load_fpr64(ctx, fp0, fs);
10126            if (ctx->nan2008) {
10127                gen_helper_float_round_2008_l_d(fp0, cpu_env, fp0);
10128            } else {
10129                gen_helper_float_round_l_d(fp0, cpu_env, fp0);
10130            }
10131            gen_store_fpr64(ctx, fp0, fd);
10132        }
10133        break;
10134    case OPC_TRUNC_L_D:
10135        check_cp1_64bitmode(ctx);
10136        {
10137            TCGv_i64 fp0 = tcg_temp_new_i64();
10138
10139            gen_load_fpr64(ctx, fp0, fs);
10140            if (ctx->nan2008) {
10141                gen_helper_float_trunc_2008_l_d(fp0, cpu_env, fp0);
10142            } else {
10143                gen_helper_float_trunc_l_d(fp0, cpu_env, fp0);
10144            }
10145            gen_store_fpr64(ctx, fp0, fd);
10146        }
10147        break;
10148    case OPC_CEIL_L_D:
10149        check_cp1_64bitmode(ctx);
10150        {
10151            TCGv_i64 fp0 = tcg_temp_new_i64();
10152
10153            gen_load_fpr64(ctx, fp0, fs);
10154            if (ctx->nan2008) {
10155                gen_helper_float_ceil_2008_l_d(fp0, cpu_env, fp0);
10156            } else {
10157                gen_helper_float_ceil_l_d(fp0, cpu_env, fp0);
10158            }
10159            gen_store_fpr64(ctx, fp0, fd);
10160        }
10161        break;
10162    case OPC_FLOOR_L_D:
10163        check_cp1_64bitmode(ctx);
10164        {
10165            TCGv_i64 fp0 = tcg_temp_new_i64();
10166
10167            gen_load_fpr64(ctx, fp0, fs);
10168            if (ctx->nan2008) {
10169                gen_helper_float_floor_2008_l_d(fp0, cpu_env, fp0);
10170            } else {
10171                gen_helper_float_floor_l_d(fp0, cpu_env, fp0);
10172            }
10173            gen_store_fpr64(ctx, fp0, fd);
10174        }
10175        break;
10176    case OPC_ROUND_W_D:
10177        check_cp1_registers(ctx, fs);
10178        {
10179            TCGv_i32 fp32 = tcg_temp_new_i32();
10180            TCGv_i64 fp64 = tcg_temp_new_i64();
10181
10182            gen_load_fpr64(ctx, fp64, fs);
10183            if (ctx->nan2008) {
10184                gen_helper_float_round_2008_w_d(fp32, cpu_env, fp64);
10185            } else {
10186                gen_helper_float_round_w_d(fp32, cpu_env, fp64);
10187            }
10188            gen_store_fpr32(ctx, fp32, fd);
10189        }
10190        break;
10191    case OPC_TRUNC_W_D:
10192        check_cp1_registers(ctx, fs);
10193        {
10194            TCGv_i32 fp32 = tcg_temp_new_i32();
10195            TCGv_i64 fp64 = tcg_temp_new_i64();
10196
10197            gen_load_fpr64(ctx, fp64, fs);
10198            if (ctx->nan2008) {
10199                gen_helper_float_trunc_2008_w_d(fp32, cpu_env, fp64);
10200            } else {
10201                gen_helper_float_trunc_w_d(fp32, cpu_env, fp64);
10202            }
10203            gen_store_fpr32(ctx, fp32, fd);
10204        }
10205        break;
10206    case OPC_CEIL_W_D:
10207        check_cp1_registers(ctx, fs);
10208        {
10209            TCGv_i32 fp32 = tcg_temp_new_i32();
10210            TCGv_i64 fp64 = tcg_temp_new_i64();
10211
10212            gen_load_fpr64(ctx, fp64, fs);
10213            if (ctx->nan2008) {
10214                gen_helper_float_ceil_2008_w_d(fp32, cpu_env, fp64);
10215            } else {
10216                gen_helper_float_ceil_w_d(fp32, cpu_env, fp64);
10217            }
10218            gen_store_fpr32(ctx, fp32, fd);
10219        }
10220        break;
10221    case OPC_FLOOR_W_D:
10222        check_cp1_registers(ctx, fs);
10223        {
10224            TCGv_i32 fp32 = tcg_temp_new_i32();
10225            TCGv_i64 fp64 = tcg_temp_new_i64();
10226
10227            gen_load_fpr64(ctx, fp64, fs);
10228            if (ctx->nan2008) {
10229                gen_helper_float_floor_2008_w_d(fp32, cpu_env, fp64);
10230            } else {
10231                gen_helper_float_floor_w_d(fp32, cpu_env, fp64);
10232            }
10233            gen_store_fpr32(ctx, fp32, fd);
10234        }
10235        break;
10236    case OPC_SEL_D:
10237        check_insn(ctx, ISA_MIPS_R6);
10238        gen_sel_d(ctx, op1, fd, ft, fs);
10239        break;
10240    case OPC_SELEQZ_D:
10241        check_insn(ctx, ISA_MIPS_R6);
10242        gen_sel_d(ctx, op1, fd, ft, fs);
10243        break;
10244    case OPC_SELNEZ_D:
10245        check_insn(ctx, ISA_MIPS_R6);
10246        gen_sel_d(ctx, op1, fd, ft, fs);
10247        break;
10248    case OPC_MOVCF_D:
10249        check_insn_opc_removed(ctx, ISA_MIPS_R6);
10250        gen_movcf_d(ctx, fs, fd, (ft >> 2) & 0x7, ft & 0x1);
10251        break;
10252    case OPC_MOVZ_D:
10253        check_insn_opc_removed(ctx, ISA_MIPS_R6);
10254        {
10255            TCGLabel *l1 = gen_new_label();
10256            TCGv_i64 fp0;
10257
10258            if (ft != 0) {
10259                tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[ft], 0, l1);
10260            }
10261            fp0 = tcg_temp_new_i64();
10262            gen_load_fpr64(ctx, fp0, fs);
10263            gen_store_fpr64(ctx, fp0, fd);
10264            gen_set_label(l1);
10265        }
10266        break;
10267    case OPC_MOVN_D:
10268        check_insn_opc_removed(ctx, ISA_MIPS_R6);
10269        {
10270            TCGLabel *l1 = gen_new_label();
10271            TCGv_i64 fp0;
10272
10273            if (ft != 0) {
10274                tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[ft], 0, l1);
10275                fp0 = tcg_temp_new_i64();
10276                gen_load_fpr64(ctx, fp0, fs);
10277                gen_store_fpr64(ctx, fp0, fd);
10278                gen_set_label(l1);
10279            }
10280        }
10281        break;
10282    case OPC_RECIP_D:
10283        check_cp1_registers(ctx, fs | fd);
10284        {
10285            TCGv_i64 fp0 = tcg_temp_new_i64();
10286
10287            gen_load_fpr64(ctx, fp0, fs);
10288            gen_helper_float_recip_d(fp0, cpu_env, fp0);
10289            gen_store_fpr64(ctx, fp0, fd);
10290        }
10291        break;
10292    case OPC_RSQRT_D:
10293        check_cp1_registers(ctx, fs | fd);
10294        {
10295            TCGv_i64 fp0 = tcg_temp_new_i64();
10296
10297            gen_load_fpr64(ctx, fp0, fs);
10298            gen_helper_float_rsqrt_d(fp0, cpu_env, fp0);
10299            gen_store_fpr64(ctx, fp0, fd);
10300        }
10301        break;
10302    case OPC_MADDF_D:
10303        check_insn(ctx, ISA_MIPS_R6);
10304        {
10305            TCGv_i64 fp0 = tcg_temp_new_i64();
10306            TCGv_i64 fp1 = tcg_temp_new_i64();
10307            TCGv_i64 fp2 = tcg_temp_new_i64();
10308            gen_load_fpr64(ctx, fp0, fs);
10309            gen_load_fpr64(ctx, fp1, ft);
10310            gen_load_fpr64(ctx, fp2, fd);
10311            gen_helper_float_maddf_d(fp2, cpu_env, fp0, fp1, fp2);
10312            gen_store_fpr64(ctx, fp2, fd);
10313        }
10314        break;
10315    case OPC_MSUBF_D:
10316        check_insn(ctx, ISA_MIPS_R6);
10317        {
10318            TCGv_i64 fp0 = tcg_temp_new_i64();
10319            TCGv_i64 fp1 = tcg_temp_new_i64();
10320            TCGv_i64 fp2 = tcg_temp_new_i64();
10321            gen_load_fpr64(ctx, fp0, fs);
10322            gen_load_fpr64(ctx, fp1, ft);
10323            gen_load_fpr64(ctx, fp2, fd);
10324            gen_helper_float_msubf_d(fp2, cpu_env, fp0, fp1, fp2);
10325            gen_store_fpr64(ctx, fp2, fd);
10326        }
10327        break;
10328    case OPC_RINT_D:
10329        check_insn(ctx, ISA_MIPS_R6);
10330        {
10331            TCGv_i64 fp0 = tcg_temp_new_i64();
10332            gen_load_fpr64(ctx, fp0, fs);
10333            gen_helper_float_rint_d(fp0, cpu_env, fp0);
10334            gen_store_fpr64(ctx, fp0, fd);
10335        }
10336        break;
10337    case OPC_CLASS_D:
10338        check_insn(ctx, ISA_MIPS_R6);
10339        {
10340            TCGv_i64 fp0 = tcg_temp_new_i64();
10341            gen_load_fpr64(ctx, fp0, fs);
10342            gen_helper_float_class_d(fp0, cpu_env, fp0);
10343            gen_store_fpr64(ctx, fp0, fd);
10344        }
10345        break;
10346    case OPC_MIN_D: /* OPC_RECIP2_D */
10347        if (ctx->insn_flags & ISA_MIPS_R6) {
10348            /* OPC_MIN_D */
10349            TCGv_i64 fp0 = tcg_temp_new_i64();
10350            TCGv_i64 fp1 = tcg_temp_new_i64();
10351            gen_load_fpr64(ctx, fp0, fs);
10352            gen_load_fpr64(ctx, fp1, ft);
10353            gen_helper_float_min_d(fp1, cpu_env, fp0, fp1);
10354            gen_store_fpr64(ctx, fp1, fd);
10355        } else {
10356            /* OPC_RECIP2_D */
10357            check_cp1_64bitmode(ctx);
10358            {
10359                TCGv_i64 fp0 = tcg_temp_new_i64();
10360                TCGv_i64 fp1 = tcg_temp_new_i64();
10361
10362                gen_load_fpr64(ctx, fp0, fs);
10363                gen_load_fpr64(ctx, fp1, ft);
10364                gen_helper_float_recip2_d(fp0, cpu_env, fp0, fp1);
10365                gen_store_fpr64(ctx, fp0, fd);
10366            }
10367        }
10368        break;
10369    case OPC_MINA_D: /* OPC_RECIP1_D */
10370        if (ctx->insn_flags & ISA_MIPS_R6) {
10371            /* OPC_MINA_D */
10372            TCGv_i64 fp0 = tcg_temp_new_i64();
10373            TCGv_i64 fp1 = tcg_temp_new_i64();
10374            gen_load_fpr64(ctx, fp0, fs);
10375            gen_load_fpr64(ctx, fp1, ft);
10376            gen_helper_float_mina_d(fp1, cpu_env, fp0, fp1);
10377            gen_store_fpr64(ctx, fp1, fd);
10378        } else {
10379            /* OPC_RECIP1_D */
10380            check_cp1_64bitmode(ctx);
10381            {
10382                TCGv_i64 fp0 = tcg_temp_new_i64();
10383
10384                gen_load_fpr64(ctx, fp0, fs);
10385                gen_helper_float_recip1_d(fp0, cpu_env, fp0);
10386                gen_store_fpr64(ctx, fp0, fd);
10387            }
10388        }
10389        break;
10390    case OPC_MAX_D: /*  OPC_RSQRT1_D */
10391        if (ctx->insn_flags & ISA_MIPS_R6) {
10392            /* OPC_MAX_D */
10393            TCGv_i64 fp0 = tcg_temp_new_i64();
10394            TCGv_i64 fp1 = tcg_temp_new_i64();
10395            gen_load_fpr64(ctx, fp0, fs);
10396            gen_load_fpr64(ctx, fp1, ft);
10397            gen_helper_float_max_d(fp1, cpu_env, fp0, fp1);
10398            gen_store_fpr64(ctx, fp1, fd);
10399        } else {
10400            /* OPC_RSQRT1_D */
10401            check_cp1_64bitmode(ctx);
10402            {
10403                TCGv_i64 fp0 = tcg_temp_new_i64();
10404
10405                gen_load_fpr64(ctx, fp0, fs);
10406                gen_helper_float_rsqrt1_d(fp0, cpu_env, fp0);
10407                gen_store_fpr64(ctx, fp0, fd);
10408            }
10409        }
10410        break;
10411    case OPC_MAXA_D: /* OPC_RSQRT2_D */
10412        if (ctx->insn_flags & ISA_MIPS_R6) {
10413            /* OPC_MAXA_D */
10414            TCGv_i64 fp0 = tcg_temp_new_i64();
10415            TCGv_i64 fp1 = tcg_temp_new_i64();
10416            gen_load_fpr64(ctx, fp0, fs);
10417            gen_load_fpr64(ctx, fp1, ft);
10418            gen_helper_float_maxa_d(fp1, cpu_env, fp0, fp1);
10419            gen_store_fpr64(ctx, fp1, fd);
10420        } else {
10421            /* OPC_RSQRT2_D */
10422            check_cp1_64bitmode(ctx);
10423            {
10424                TCGv_i64 fp0 = tcg_temp_new_i64();
10425                TCGv_i64 fp1 = tcg_temp_new_i64();
10426
10427                gen_load_fpr64(ctx, fp0, fs);
10428                gen_load_fpr64(ctx, fp1, ft);
10429                gen_helper_float_rsqrt2_d(fp0, cpu_env, fp0, fp1);
10430                gen_store_fpr64(ctx, fp0, fd);
10431            }
10432        }
10433        break;
10434    case OPC_CMP_F_D:
10435    case OPC_CMP_UN_D:
10436    case OPC_CMP_EQ_D:
10437    case OPC_CMP_UEQ_D:
10438    case OPC_CMP_OLT_D:
10439    case OPC_CMP_ULT_D:
10440    case OPC_CMP_OLE_D:
10441    case OPC_CMP_ULE_D:
10442    case OPC_CMP_SF_D:
10443    case OPC_CMP_NGLE_D:
10444    case OPC_CMP_SEQ_D:
10445    case OPC_CMP_NGL_D:
10446    case OPC_CMP_LT_D:
10447    case OPC_CMP_NGE_D:
10448    case OPC_CMP_LE_D:
10449    case OPC_CMP_NGT_D:
10450        check_insn_opc_removed(ctx, ISA_MIPS_R6);
10451        if (ctx->opcode & (1 << 6)) {
10452            gen_cmpabs_d(ctx, func - 48, ft, fs, cc);
10453        } else {
10454            gen_cmp_d(ctx, func - 48, ft, fs, cc);
10455        }
10456        break;
10457    case OPC_CVT_S_D:
10458        check_cp1_registers(ctx, fs);
10459        {
10460            TCGv_i32 fp32 = tcg_temp_new_i32();
10461            TCGv_i64 fp64 = tcg_temp_new_i64();
10462
10463            gen_load_fpr64(ctx, fp64, fs);
10464            gen_helper_float_cvts_d(fp32, cpu_env, fp64);
10465            gen_store_fpr32(ctx, fp32, fd);
10466        }
10467        break;
10468    case OPC_CVT_W_D:
10469        check_cp1_registers(ctx, fs);
10470        {
10471            TCGv_i32 fp32 = tcg_temp_new_i32();
10472            TCGv_i64 fp64 = tcg_temp_new_i64();
10473
10474            gen_load_fpr64(ctx, fp64, fs);
10475            if (ctx->nan2008) {
10476                gen_helper_float_cvt_2008_w_d(fp32, cpu_env, fp64);
10477            } else {
10478                gen_helper_float_cvt_w_d(fp32, cpu_env, fp64);
10479            }
10480            gen_store_fpr32(ctx, fp32, fd);
10481        }
10482        break;
10483    case OPC_CVT_L_D:
10484        check_cp1_64bitmode(ctx);
10485        {
10486            TCGv_i64 fp0 = tcg_temp_new_i64();
10487
10488            gen_load_fpr64(ctx, fp0, fs);
10489            if (ctx->nan2008) {
10490                gen_helper_float_cvt_2008_l_d(fp0, cpu_env, fp0);
10491            } else {
10492                gen_helper_float_cvt_l_d(fp0, cpu_env, fp0);
10493            }
10494            gen_store_fpr64(ctx, fp0, fd);
10495        }
10496        break;
10497    case OPC_CVT_S_W:
10498        {
10499            TCGv_i32 fp0 = tcg_temp_new_i32();
10500
10501            gen_load_fpr32(ctx, fp0, fs);
10502            gen_helper_float_cvts_w(fp0, cpu_env, fp0);
10503            gen_store_fpr32(ctx, fp0, fd);
10504        }
10505        break;
10506    case OPC_CVT_D_W:
10507        check_cp1_registers(ctx, fd);
10508        {
10509            TCGv_i32 fp32 = tcg_temp_new_i32();
10510            TCGv_i64 fp64 = tcg_temp_new_i64();
10511
10512            gen_load_fpr32(ctx, fp32, fs);
10513            gen_helper_float_cvtd_w(fp64, cpu_env, fp32);
10514            gen_store_fpr64(ctx, fp64, fd);
10515        }
10516        break;
10517    case OPC_CVT_S_L:
10518        check_cp1_64bitmode(ctx);
10519        {
10520            TCGv_i32 fp32 = tcg_temp_new_i32();
10521            TCGv_i64 fp64 = tcg_temp_new_i64();
10522
10523            gen_load_fpr64(ctx, fp64, fs);
10524            gen_helper_float_cvts_l(fp32, cpu_env, fp64);
10525            gen_store_fpr32(ctx, fp32, fd);
10526        }
10527        break;
10528    case OPC_CVT_D_L:
10529        check_cp1_64bitmode(ctx);
10530        {
10531            TCGv_i64 fp0 = tcg_temp_new_i64();
10532
10533            gen_load_fpr64(ctx, fp0, fs);
10534            gen_helper_float_cvtd_l(fp0, cpu_env, fp0);
10535            gen_store_fpr64(ctx, fp0, fd);
10536        }
10537        break;
10538    case OPC_CVT_PS_PW:
10539        check_ps(ctx);
10540        {
10541            TCGv_i64 fp0 = tcg_temp_new_i64();
10542
10543            gen_load_fpr64(ctx, fp0, fs);
10544            gen_helper_float_cvtps_pw(fp0, cpu_env, fp0);
10545            gen_store_fpr64(ctx, fp0, fd);
10546        }
10547        break;
10548    case OPC_ADD_PS:
10549        check_ps(ctx);
10550        {
10551            TCGv_i64 fp0 = tcg_temp_new_i64();
10552            TCGv_i64 fp1 = tcg_temp_new_i64();
10553
10554            gen_load_fpr64(ctx, fp0, fs);
10555            gen_load_fpr64(ctx, fp1, ft);
10556            gen_helper_float_add_ps(fp0, cpu_env, fp0, fp1);
10557            gen_store_fpr64(ctx, fp0, fd);
10558        }
10559        break;
10560    case OPC_SUB_PS:
10561        check_ps(ctx);
10562        {
10563            TCGv_i64 fp0 = tcg_temp_new_i64();
10564            TCGv_i64 fp1 = tcg_temp_new_i64();
10565
10566            gen_load_fpr64(ctx, fp0, fs);
10567            gen_load_fpr64(ctx, fp1, ft);
10568            gen_helper_float_sub_ps(fp0, cpu_env, fp0, fp1);
10569            gen_store_fpr64(ctx, fp0, fd);
10570        }
10571        break;
10572    case OPC_MUL_PS:
10573        check_ps(ctx);
10574        {
10575            TCGv_i64 fp0 = tcg_temp_new_i64();
10576            TCGv_i64 fp1 = tcg_temp_new_i64();
10577
10578            gen_load_fpr64(ctx, fp0, fs);
10579            gen_load_fpr64(ctx, fp1, ft);
10580            gen_helper_float_mul_ps(fp0, cpu_env, fp0, fp1);
10581            gen_store_fpr64(ctx, fp0, fd);
10582        }
10583        break;
10584    case OPC_ABS_PS:
10585        check_ps(ctx);
10586        {
10587            TCGv_i64 fp0 = tcg_temp_new_i64();
10588
10589            gen_load_fpr64(ctx, fp0, fs);
10590            gen_helper_float_abs_ps(fp0, fp0);
10591            gen_store_fpr64(ctx, fp0, fd);
10592        }
10593        break;
10594    case OPC_MOV_PS:
10595        check_ps(ctx);
10596        {
10597            TCGv_i64 fp0 = tcg_temp_new_i64();
10598
10599            gen_load_fpr64(ctx, fp0, fs);
10600            gen_store_fpr64(ctx, fp0, fd);
10601        }
10602        break;
10603    case OPC_NEG_PS:
10604        check_ps(ctx);
10605        {
10606            TCGv_i64 fp0 = tcg_temp_new_i64();
10607
10608            gen_load_fpr64(ctx, fp0, fs);
10609            gen_helper_float_chs_ps(fp0, fp0);
10610            gen_store_fpr64(ctx, fp0, fd);
10611        }
10612        break;
10613    case OPC_MOVCF_PS:
10614        check_ps(ctx);
10615        gen_movcf_ps(ctx, fs, fd, (ft >> 2) & 0x7, ft & 0x1);
10616        break;
10617    case OPC_MOVZ_PS:
10618        check_ps(ctx);
10619        {
10620            TCGLabel *l1 = gen_new_label();
10621            TCGv_i64 fp0;
10622
10623            if (ft != 0) {
10624                tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[ft], 0, l1);
10625            }
10626            fp0 = tcg_temp_new_i64();
10627            gen_load_fpr64(ctx, fp0, fs);
10628            gen_store_fpr64(ctx, fp0, fd);
10629            gen_set_label(l1);
10630        }
10631        break;
10632    case OPC_MOVN_PS:
10633        check_ps(ctx);
10634        {
10635            TCGLabel *l1 = gen_new_label();
10636            TCGv_i64 fp0;
10637
10638            if (ft != 0) {
10639                tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[ft], 0, l1);
10640                fp0 = tcg_temp_new_i64();
10641                gen_load_fpr64(ctx, fp0, fs);
10642                gen_store_fpr64(ctx, fp0, fd);
10643                gen_set_label(l1);
10644            }
10645        }
10646        break;
10647    case OPC_ADDR_PS:
10648        check_ps(ctx);
10649        {
10650            TCGv_i64 fp0 = tcg_temp_new_i64();
10651            TCGv_i64 fp1 = tcg_temp_new_i64();
10652
10653            gen_load_fpr64(ctx, fp0, ft);
10654            gen_load_fpr64(ctx, fp1, fs);
10655            gen_helper_float_addr_ps(fp0, cpu_env, fp0, fp1);
10656            gen_store_fpr64(ctx, fp0, fd);
10657        }
10658        break;
10659    case OPC_MULR_PS:
10660        check_ps(ctx);
10661        {
10662            TCGv_i64 fp0 = tcg_temp_new_i64();
10663            TCGv_i64 fp1 = tcg_temp_new_i64();
10664
10665            gen_load_fpr64(ctx, fp0, ft);
10666            gen_load_fpr64(ctx, fp1, fs);
10667            gen_helper_float_mulr_ps(fp0, cpu_env, fp0, fp1);
10668            gen_store_fpr64(ctx, fp0, fd);
10669        }
10670        break;
10671    case OPC_RECIP2_PS:
10672        check_ps(ctx);
10673        {
10674            TCGv_i64 fp0 = tcg_temp_new_i64();
10675            TCGv_i64 fp1 = tcg_temp_new_i64();
10676
10677            gen_load_fpr64(ctx, fp0, fs);
10678            gen_load_fpr64(ctx, fp1, ft);
10679            gen_helper_float_recip2_ps(fp0, cpu_env, fp0, fp1);
10680            gen_store_fpr64(ctx, fp0, fd);
10681        }
10682        break;
10683    case OPC_RECIP1_PS:
10684        check_ps(ctx);
10685        {
10686            TCGv_i64 fp0 = tcg_temp_new_i64();
10687
10688            gen_load_fpr64(ctx, fp0, fs);
10689            gen_helper_float_recip1_ps(fp0, cpu_env, fp0);
10690            gen_store_fpr64(ctx, fp0, fd);
10691        }
10692        break;
10693    case OPC_RSQRT1_PS:
10694        check_ps(ctx);
10695        {
10696            TCGv_i64 fp0 = tcg_temp_new_i64();
10697
10698            gen_load_fpr64(ctx, fp0, fs);
10699            gen_helper_float_rsqrt1_ps(fp0, cpu_env, fp0);
10700            gen_store_fpr64(ctx, fp0, fd);
10701        }
10702        break;
10703    case OPC_RSQRT2_PS:
10704        check_ps(ctx);
10705        {
10706            TCGv_i64 fp0 = tcg_temp_new_i64();
10707            TCGv_i64 fp1 = tcg_temp_new_i64();
10708
10709            gen_load_fpr64(ctx, fp0, fs);
10710            gen_load_fpr64(ctx, fp1, ft);
10711            gen_helper_float_rsqrt2_ps(fp0, cpu_env, fp0, fp1);
10712            gen_store_fpr64(ctx, fp0, fd);
10713        }
10714        break;
10715    case OPC_CVT_S_PU:
10716        check_cp1_64bitmode(ctx);
10717        {
10718            TCGv_i32 fp0 = tcg_temp_new_i32();
10719
10720            gen_load_fpr32h(ctx, fp0, fs);
10721            gen_helper_float_cvts_pu(fp0, cpu_env, fp0);
10722            gen_store_fpr32(ctx, fp0, fd);
10723        }
10724        break;
10725    case OPC_CVT_PW_PS:
10726        check_ps(ctx);
10727        {
10728            TCGv_i64 fp0 = tcg_temp_new_i64();
10729
10730            gen_load_fpr64(ctx, fp0, fs);
10731            gen_helper_float_cvtpw_ps(fp0, cpu_env, fp0);
10732            gen_store_fpr64(ctx, fp0, fd);
10733        }
10734        break;
10735    case OPC_CVT_S_PL:
10736        check_cp1_64bitmode(ctx);
10737        {
10738            TCGv_i32 fp0 = tcg_temp_new_i32();
10739
10740            gen_load_fpr32(ctx, fp0, fs);
10741            gen_helper_float_cvts_pl(fp0, cpu_env, fp0);
10742            gen_store_fpr32(ctx, fp0, fd);
10743        }
10744        break;
10745    case OPC_PLL_PS:
10746        check_ps(ctx);
10747        {
10748            TCGv_i32 fp0 = tcg_temp_new_i32();
10749            TCGv_i32 fp1 = tcg_temp_new_i32();
10750
10751            gen_load_fpr32(ctx, fp0, fs);
10752            gen_load_fpr32(ctx, fp1, ft);
10753            gen_store_fpr32h(ctx, fp0, fd);
10754            gen_store_fpr32(ctx, fp1, fd);
10755        }
10756        break;
10757    case OPC_PLU_PS:
10758        check_ps(ctx);
10759        {
10760            TCGv_i32 fp0 = tcg_temp_new_i32();
10761            TCGv_i32 fp1 = tcg_temp_new_i32();
10762
10763            gen_load_fpr32(ctx, fp0, fs);
10764            gen_load_fpr32h(ctx, fp1, ft);
10765            gen_store_fpr32(ctx, fp1, fd);
10766            gen_store_fpr32h(ctx, fp0, fd);
10767        }
10768        break;
10769    case OPC_PUL_PS:
10770        check_ps(ctx);
10771        {
10772            TCGv_i32 fp0 = tcg_temp_new_i32();
10773            TCGv_i32 fp1 = tcg_temp_new_i32();
10774
10775            gen_load_fpr32h(ctx, fp0, fs);
10776            gen_load_fpr32(ctx, fp1, ft);
10777            gen_store_fpr32(ctx, fp1, fd);
10778            gen_store_fpr32h(ctx, fp0, fd);
10779        }
10780        break;
10781    case OPC_PUU_PS:
10782        check_ps(ctx);
10783        {
10784            TCGv_i32 fp0 = tcg_temp_new_i32();
10785            TCGv_i32 fp1 = tcg_temp_new_i32();
10786
10787            gen_load_fpr32h(ctx, fp0, fs);
10788            gen_load_fpr32h(ctx, fp1, ft);
10789            gen_store_fpr32(ctx, fp1, fd);
10790            gen_store_fpr32h(ctx, fp0, fd);
10791        }
10792        break;
10793    case OPC_CMP_F_PS:
10794    case OPC_CMP_UN_PS:
10795    case OPC_CMP_EQ_PS:
10796    case OPC_CMP_UEQ_PS:
10797    case OPC_CMP_OLT_PS:
10798    case OPC_CMP_ULT_PS:
10799    case OPC_CMP_OLE_PS:
10800    case OPC_CMP_ULE_PS:
10801    case OPC_CMP_SF_PS:
10802    case OPC_CMP_NGLE_PS:
10803    case OPC_CMP_SEQ_PS:
10804    case OPC_CMP_NGL_PS:
10805    case OPC_CMP_LT_PS:
10806    case OPC_CMP_NGE_PS:
10807    case OPC_CMP_LE_PS:
10808    case OPC_CMP_NGT_PS:
10809        if (ctx->opcode & (1 << 6)) {
10810            gen_cmpabs_ps(ctx, func - 48, ft, fs, cc);
10811        } else {
10812            gen_cmp_ps(ctx, func - 48, ft, fs, cc);
10813        }
10814        break;
10815    default:
10816        MIPS_INVAL("farith");
10817        gen_reserved_instruction(ctx);
10818        return;
10819    }
10820}
10821
10822/* Coprocessor 3 (FPU) */
10823static void gen_flt3_ldst(DisasContext *ctx, uint32_t opc,
10824                          int fd, int fs, int base, int index)
10825{
10826    TCGv t0 = tcg_temp_new();
10827
10828    if (base == 0) {
10829        gen_load_gpr(t0, index);
10830    } else if (index == 0) {
10831        gen_load_gpr(t0, base);
10832    } else {
10833        gen_op_addr_add(ctx, t0, cpu_gpr[base], cpu_gpr[index]);
10834    }
10835    /*
10836     * Don't do NOP if destination is zero: we must perform the actual
10837     * memory access.
10838     */
10839    switch (opc) {
10840    case OPC_LWXC1:
10841        check_cop1x(ctx);
10842        {
10843            TCGv_i32 fp0 = tcg_temp_new_i32();
10844
10845            tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TESL);
10846            tcg_gen_trunc_tl_i32(fp0, t0);
10847            gen_store_fpr32(ctx, fp0, fd);
10848        }
10849        break;
10850    case OPC_LDXC1:
10851        check_cop1x(ctx);
10852        check_cp1_registers(ctx, fd);
10853        {
10854            TCGv_i64 fp0 = tcg_temp_new_i64();
10855            tcg_gen_qemu_ld_i64(fp0, t0, ctx->mem_idx, MO_TEUQ);
10856            gen_store_fpr64(ctx, fp0, fd);
10857        }
10858        break;
10859    case OPC_LUXC1:
10860        check_cp1_64bitmode(ctx);
10861        tcg_gen_andi_tl(t0, t0, ~0x7);
10862        {
10863            TCGv_i64 fp0 = tcg_temp_new_i64();
10864
10865            tcg_gen_qemu_ld_i64(fp0, t0, ctx->mem_idx, MO_TEUQ);
10866            gen_store_fpr64(ctx, fp0, fd);
10867        }
10868        break;
10869    case OPC_SWXC1:
10870        check_cop1x(ctx);
10871        {
10872            TCGv_i32 fp0 = tcg_temp_new_i32();
10873            gen_load_fpr32(ctx, fp0, fs);
10874            tcg_gen_qemu_st_i32(fp0, t0, ctx->mem_idx, MO_TEUL);
10875        }
10876        break;
10877    case OPC_SDXC1:
10878        check_cop1x(ctx);
10879        check_cp1_registers(ctx, fs);
10880        {
10881            TCGv_i64 fp0 = tcg_temp_new_i64();
10882            gen_load_fpr64(ctx, fp0, fs);
10883            tcg_gen_qemu_st_i64(fp0, t0, ctx->mem_idx, MO_TEUQ);
10884        }
10885        break;
10886    case OPC_SUXC1:
10887        check_cp1_64bitmode(ctx);
10888        tcg_gen_andi_tl(t0, t0, ~0x7);
10889        {
10890            TCGv_i64 fp0 = tcg_temp_new_i64();
10891            gen_load_fpr64(ctx, fp0, fs);
10892            tcg_gen_qemu_st_i64(fp0, t0, ctx->mem_idx, MO_TEUQ);
10893        }
10894        break;
10895    }
10896}
10897
10898static void gen_flt3_arith(DisasContext *ctx, uint32_t opc,
10899                           int fd, int fr, int fs, int ft)
10900{
10901    switch (opc) {
10902    case OPC_ALNV_PS:
10903        check_ps(ctx);
10904        {
10905            TCGv t0 = tcg_temp_new();
10906            TCGv_i32 fp = tcg_temp_new_i32();
10907            TCGv_i32 fph = tcg_temp_new_i32();
10908            TCGLabel *l1 = gen_new_label();
10909            TCGLabel *l2 = gen_new_label();
10910
10911            gen_load_gpr(t0, fr);
10912            tcg_gen_andi_tl(t0, t0, 0x7);
10913
10914            tcg_gen_brcondi_tl(TCG_COND_NE, t0, 0, l1);
10915            gen_load_fpr32(ctx, fp, fs);
10916            gen_load_fpr32h(ctx, fph, fs);
10917            gen_store_fpr32(ctx, fp, fd);
10918            gen_store_fpr32h(ctx, fph, fd);
10919            tcg_gen_br(l2);
10920            gen_set_label(l1);
10921            tcg_gen_brcondi_tl(TCG_COND_NE, t0, 4, l2);
10922            if (cpu_is_bigendian(ctx)) {
10923                gen_load_fpr32(ctx, fp, fs);
10924                gen_load_fpr32h(ctx, fph, ft);
10925                gen_store_fpr32h(ctx, fp, fd);
10926                gen_store_fpr32(ctx, fph, fd);
10927            } else {
10928                gen_load_fpr32h(ctx, fph, fs);
10929                gen_load_fpr32(ctx, fp, ft);
10930                gen_store_fpr32(ctx, fph, fd);
10931                gen_store_fpr32h(ctx, fp, fd);
10932            }
10933            gen_set_label(l2);
10934        }
10935        break;
10936    case OPC_MADD_S:
10937        check_cop1x(ctx);
10938        {
10939            TCGv_i32 fp0 = tcg_temp_new_i32();
10940            TCGv_i32 fp1 = tcg_temp_new_i32();
10941            TCGv_i32 fp2 = tcg_temp_new_i32();
10942
10943            gen_load_fpr32(ctx, fp0, fs);
10944            gen_load_fpr32(ctx, fp1, ft);
10945            gen_load_fpr32(ctx, fp2, fr);
10946            gen_helper_float_madd_s(fp2, cpu_env, fp0, fp1, fp2);
10947            gen_store_fpr32(ctx, fp2, fd);
10948        }
10949        break;
10950    case OPC_MADD_D:
10951        check_cop1x(ctx);
10952        check_cp1_registers(ctx, fd | fs | ft | fr);
10953        {
10954            TCGv_i64 fp0 = tcg_temp_new_i64();
10955            TCGv_i64 fp1 = tcg_temp_new_i64();
10956            TCGv_i64 fp2 = tcg_temp_new_i64();
10957
10958            gen_load_fpr64(ctx, fp0, fs);
10959            gen_load_fpr64(ctx, fp1, ft);
10960            gen_load_fpr64(ctx, fp2, fr);
10961            gen_helper_float_madd_d(fp2, cpu_env, fp0, fp1, fp2);
10962            gen_store_fpr64(ctx, fp2, fd);
10963        }
10964        break;
10965    case OPC_MADD_PS:
10966        check_ps(ctx);
10967        {
10968            TCGv_i64 fp0 = tcg_temp_new_i64();
10969            TCGv_i64 fp1 = tcg_temp_new_i64();
10970            TCGv_i64 fp2 = tcg_temp_new_i64();
10971
10972            gen_load_fpr64(ctx, fp0, fs);
10973            gen_load_fpr64(ctx, fp1, ft);
10974            gen_load_fpr64(ctx, fp2, fr);
10975            gen_helper_float_madd_ps(fp2, cpu_env, fp0, fp1, fp2);
10976            gen_store_fpr64(ctx, fp2, fd);
10977        }
10978        break;
10979    case OPC_MSUB_S:
10980        check_cop1x(ctx);
10981        {
10982            TCGv_i32 fp0 = tcg_temp_new_i32();
10983            TCGv_i32 fp1 = tcg_temp_new_i32();
10984            TCGv_i32 fp2 = tcg_temp_new_i32();
10985
10986            gen_load_fpr32(ctx, fp0, fs);
10987            gen_load_fpr32(ctx, fp1, ft);
10988            gen_load_fpr32(ctx, fp2, fr);
10989            gen_helper_float_msub_s(fp2, cpu_env, fp0, fp1, fp2);
10990            gen_store_fpr32(ctx, fp2, fd);
10991        }
10992        break;
10993    case OPC_MSUB_D:
10994        check_cop1x(ctx);
10995        check_cp1_registers(ctx, fd | fs | ft | fr);
10996        {
10997            TCGv_i64 fp0 = tcg_temp_new_i64();
10998            TCGv_i64 fp1 = tcg_temp_new_i64();
10999            TCGv_i64 fp2 = tcg_temp_new_i64();
11000
11001            gen_load_fpr64(ctx, fp0, fs);
11002            gen_load_fpr64(ctx, fp1, ft);
11003            gen_load_fpr64(ctx, fp2, fr);
11004            gen_helper_float_msub_d(fp2, cpu_env, fp0, fp1, fp2);
11005            gen_store_fpr64(ctx, fp2, fd);
11006        }
11007        break;
11008    case OPC_MSUB_PS:
11009        check_ps(ctx);
11010        {
11011            TCGv_i64 fp0 = tcg_temp_new_i64();
11012            TCGv_i64 fp1 = tcg_temp_new_i64();
11013            TCGv_i64 fp2 = tcg_temp_new_i64();
11014
11015            gen_load_fpr64(ctx, fp0, fs);
11016            gen_load_fpr64(ctx, fp1, ft);
11017            gen_load_fpr64(ctx, fp2, fr);
11018            gen_helper_float_msub_ps(fp2, cpu_env, fp0, fp1, fp2);
11019            gen_store_fpr64(ctx, fp2, fd);
11020        }
11021        break;
11022    case OPC_NMADD_S:
11023        check_cop1x(ctx);
11024        {
11025            TCGv_i32 fp0 = tcg_temp_new_i32();
11026            TCGv_i32 fp1 = tcg_temp_new_i32();
11027            TCGv_i32 fp2 = tcg_temp_new_i32();
11028
11029            gen_load_fpr32(ctx, fp0, fs);
11030            gen_load_fpr32(ctx, fp1, ft);
11031            gen_load_fpr32(ctx, fp2, fr);
11032            gen_helper_float_nmadd_s(fp2, cpu_env, fp0, fp1, fp2);
11033            gen_store_fpr32(ctx, fp2, fd);
11034        }
11035        break;
11036    case OPC_NMADD_D:
11037        check_cop1x(ctx);
11038        check_cp1_registers(ctx, fd | fs | ft | fr);
11039        {
11040            TCGv_i64 fp0 = tcg_temp_new_i64();
11041            TCGv_i64 fp1 = tcg_temp_new_i64();
11042            TCGv_i64 fp2 = tcg_temp_new_i64();
11043
11044            gen_load_fpr64(ctx, fp0, fs);
11045            gen_load_fpr64(ctx, fp1, ft);
11046            gen_load_fpr64(ctx, fp2, fr);
11047            gen_helper_float_nmadd_d(fp2, cpu_env, fp0, fp1, fp2);
11048            gen_store_fpr64(ctx, fp2, fd);
11049        }
11050        break;
11051    case OPC_NMADD_PS:
11052        check_ps(ctx);
11053        {
11054            TCGv_i64 fp0 = tcg_temp_new_i64();
11055            TCGv_i64 fp1 = tcg_temp_new_i64();
11056            TCGv_i64 fp2 = tcg_temp_new_i64();
11057
11058            gen_load_fpr64(ctx, fp0, fs);
11059            gen_load_fpr64(ctx, fp1, ft);
11060            gen_load_fpr64(ctx, fp2, fr);
11061            gen_helper_float_nmadd_ps(fp2, cpu_env, fp0, fp1, fp2);
11062            gen_store_fpr64(ctx, fp2, fd);
11063        }
11064        break;
11065    case OPC_NMSUB_S:
11066        check_cop1x(ctx);
11067        {
11068            TCGv_i32 fp0 = tcg_temp_new_i32();
11069            TCGv_i32 fp1 = tcg_temp_new_i32();
11070            TCGv_i32 fp2 = tcg_temp_new_i32();
11071
11072            gen_load_fpr32(ctx, fp0, fs);
11073            gen_load_fpr32(ctx, fp1, ft);
11074            gen_load_fpr32(ctx, fp2, fr);
11075            gen_helper_float_nmsub_s(fp2, cpu_env, fp0, fp1, fp2);
11076            gen_store_fpr32(ctx, fp2, fd);
11077        }
11078        break;
11079    case OPC_NMSUB_D:
11080        check_cop1x(ctx);
11081        check_cp1_registers(ctx, fd | fs | ft | fr);
11082        {
11083            TCGv_i64 fp0 = tcg_temp_new_i64();
11084            TCGv_i64 fp1 = tcg_temp_new_i64();
11085            TCGv_i64 fp2 = tcg_temp_new_i64();
11086
11087            gen_load_fpr64(ctx, fp0, fs);
11088            gen_load_fpr64(ctx, fp1, ft);
11089            gen_load_fpr64(ctx, fp2, fr);
11090            gen_helper_float_nmsub_d(fp2, cpu_env, fp0, fp1, fp2);
11091            gen_store_fpr64(ctx, fp2, fd);
11092        }
11093        break;
11094    case OPC_NMSUB_PS:
11095        check_ps(ctx);
11096        {
11097            TCGv_i64 fp0 = tcg_temp_new_i64();
11098            TCGv_i64 fp1 = tcg_temp_new_i64();
11099            TCGv_i64 fp2 = tcg_temp_new_i64();
11100
11101            gen_load_fpr64(ctx, fp0, fs);
11102            gen_load_fpr64(ctx, fp1, ft);
11103            gen_load_fpr64(ctx, fp2, fr);
11104            gen_helper_float_nmsub_ps(fp2, cpu_env, fp0, fp1, fp2);
11105            gen_store_fpr64(ctx, fp2, fd);
11106        }
11107        break;
11108    default:
11109        MIPS_INVAL("flt3_arith");
11110        gen_reserved_instruction(ctx);
11111        return;
11112    }
11113}
11114
11115void gen_rdhwr(DisasContext *ctx, int rt, int rd, int sel)
11116{
11117    TCGv t0;
11118
11119#if !defined(CONFIG_USER_ONLY)
11120    /*
11121     * The Linux kernel will emulate rdhwr if it's not supported natively.
11122     * Therefore only check the ISA in system mode.
11123     */
11124    check_insn(ctx, ISA_MIPS_R2);
11125#endif
11126    t0 = tcg_temp_new();
11127
11128    switch (rd) {
11129    case 0:
11130        gen_helper_rdhwr_cpunum(t0, cpu_env);
11131        gen_store_gpr(t0, rt);
11132        break;
11133    case 1:
11134        gen_helper_rdhwr_synci_step(t0, cpu_env);
11135        gen_store_gpr(t0, rt);
11136        break;
11137    case 2:
11138        translator_io_start(&ctx->base);
11139        gen_helper_rdhwr_cc(t0, cpu_env);
11140        gen_store_gpr(t0, rt);
11141        /*
11142         * Break the TB to be able to take timer interrupts immediately
11143         * after reading count. DISAS_STOP isn't sufficient, we need to ensure
11144         * we break completely out of translated code.
11145         */
11146        gen_save_pc(ctx->base.pc_next + 4);
11147        ctx->base.is_jmp = DISAS_EXIT;
11148        break;
11149    case 3:
11150        gen_helper_rdhwr_ccres(t0, cpu_env);
11151        gen_store_gpr(t0, rt);
11152        break;
11153    case 4:
11154        check_insn(ctx, ISA_MIPS_R6);
11155        if (sel != 0) {
11156            /*
11157             * Performance counter registers are not implemented other than
11158             * control register 0.
11159             */
11160            generate_exception(ctx, EXCP_RI);
11161        }
11162        gen_helper_rdhwr_performance(t0, cpu_env);
11163        gen_store_gpr(t0, rt);
11164        break;
11165    case 5:
11166        check_insn(ctx, ISA_MIPS_R6);
11167        gen_helper_rdhwr_xnp(t0, cpu_env);
11168        gen_store_gpr(t0, rt);
11169        break;
11170    case 29:
11171#if defined(CONFIG_USER_ONLY)
11172        tcg_gen_ld_tl(t0, cpu_env,
11173                      offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
11174        gen_store_gpr(t0, rt);
11175        break;
11176#else
11177        if ((ctx->hflags & MIPS_HFLAG_CP0) ||
11178            (ctx->hflags & MIPS_HFLAG_HWRENA_ULR)) {
11179            tcg_gen_ld_tl(t0, cpu_env,
11180                          offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
11181            gen_store_gpr(t0, rt);
11182        } else {
11183            gen_reserved_instruction(ctx);
11184        }
11185        break;
11186#endif
11187    default:            /* Invalid */
11188        MIPS_INVAL("rdhwr");
11189        gen_reserved_instruction(ctx);
11190        break;
11191    }
11192}
11193
11194static inline void clear_branch_hflags(DisasContext *ctx)
11195{
11196    ctx->hflags &= ~MIPS_HFLAG_BMASK;
11197    if (ctx->base.is_jmp == DISAS_NEXT) {
11198        save_cpu_state(ctx, 0);
11199    } else {
11200        /*
11201         * It is not safe to save ctx->hflags as hflags may be changed
11202         * in execution time by the instruction in delay / forbidden slot.
11203         */
11204        tcg_gen_andi_i32(hflags, hflags, ~MIPS_HFLAG_BMASK);
11205    }
11206}
11207
11208static void gen_branch(DisasContext *ctx, int insn_bytes)
11209{
11210    if (ctx->hflags & MIPS_HFLAG_BMASK) {
11211        int proc_hflags = ctx->hflags & MIPS_HFLAG_BMASK;
11212        /* Branches completion */
11213        clear_branch_hflags(ctx);
11214        ctx->base.is_jmp = DISAS_NORETURN;
11215        /* FIXME: Need to clear can_do_io.  */
11216        switch (proc_hflags & MIPS_HFLAG_BMASK_BASE) {
11217        case MIPS_HFLAG_FBNSLOT:
11218            gen_goto_tb(ctx, 0, ctx->base.pc_next + insn_bytes);
11219            break;
11220        case MIPS_HFLAG_B:
11221            /* unconditional branch */
11222            if (proc_hflags & MIPS_HFLAG_BX) {
11223                tcg_gen_xori_i32(hflags, hflags, MIPS_HFLAG_M16);
11224            }
11225            gen_goto_tb(ctx, 0, ctx->btarget);
11226            break;
11227        case MIPS_HFLAG_BL:
11228            /* blikely taken case */
11229            gen_goto_tb(ctx, 0, ctx->btarget);
11230            break;
11231        case MIPS_HFLAG_BC:
11232            /* Conditional branch */
11233            {
11234                TCGLabel *l1 = gen_new_label();
11235
11236                tcg_gen_brcondi_tl(TCG_COND_NE, bcond, 0, l1);
11237                gen_goto_tb(ctx, 1, ctx->base.pc_next + insn_bytes);
11238                gen_set_label(l1);
11239                gen_goto_tb(ctx, 0, ctx->btarget);
11240            }
11241            break;
11242        case MIPS_HFLAG_BR:
11243            /* unconditional branch to register */
11244            if (ctx->insn_flags & (ASE_MIPS16 | ASE_MICROMIPS)) {
11245                TCGv t0 = tcg_temp_new();
11246                TCGv_i32 t1 = tcg_temp_new_i32();
11247
11248                tcg_gen_andi_tl(t0, btarget, 0x1);
11249                tcg_gen_trunc_tl_i32(t1, t0);
11250                tcg_gen_andi_i32(hflags, hflags, ~(uint32_t)MIPS_HFLAG_M16);
11251                tcg_gen_shli_i32(t1, t1, MIPS_HFLAG_M16_SHIFT);
11252                tcg_gen_or_i32(hflags, hflags, t1);
11253
11254                tcg_gen_andi_tl(cpu_PC, btarget, ~(target_ulong)0x1);
11255            } else {
11256                tcg_gen_mov_tl(cpu_PC, btarget);
11257            }
11258            tcg_gen_lookup_and_goto_ptr();
11259            break;
11260        default:
11261            LOG_DISAS("unknown branch 0x%x\n", proc_hflags);
11262            gen_reserved_instruction(ctx);
11263        }
11264    }
11265}
11266
11267/* Compact Branches */
11268static void gen_compute_compact_branch(DisasContext *ctx, uint32_t opc,
11269                                       int rs, int rt, int32_t offset)
11270{
11271    int bcond_compute = 0;
11272    TCGv t0 = tcg_temp_new();
11273    TCGv t1 = tcg_temp_new();
11274    int m16_lowbit = (ctx->hflags & MIPS_HFLAG_M16) != 0;
11275
11276    if (ctx->hflags & MIPS_HFLAG_BMASK) {
11277#ifdef MIPS_DEBUG_DISAS
11278        LOG_DISAS("Branch in delay / forbidden slot at PC 0x" TARGET_FMT_lx
11279                  "\n", ctx->base.pc_next);
11280#endif
11281        gen_reserved_instruction(ctx);
11282        return;
11283    }
11284
11285    /* Load needed operands and calculate btarget */
11286    switch (opc) {
11287    /* compact branch */
11288    case OPC_BOVC: /* OPC_BEQZALC, OPC_BEQC */
11289    case OPC_BNVC: /* OPC_BNEZALC, OPC_BNEC */
11290        gen_load_gpr(t0, rs);
11291        gen_load_gpr(t1, rt);
11292        bcond_compute = 1;
11293        ctx->btarget = addr_add(ctx, ctx->base.pc_next + 4, offset);
11294        if (rs <= rt && rs == 0) {
11295            /* OPC_BEQZALC, OPC_BNEZALC */
11296            tcg_gen_movi_tl(cpu_gpr[31], ctx->base.pc_next + 4 + m16_lowbit);
11297        }
11298        break;
11299    case OPC_BLEZC: /* OPC_BGEZC, OPC_BGEC */
11300    case OPC_BGTZC: /* OPC_BLTZC, OPC_BLTC */
11301        gen_load_gpr(t0, rs);
11302        gen_load_gpr(t1, rt);
11303        bcond_compute = 1;
11304        ctx->btarget = addr_add(ctx, ctx->base.pc_next + 4, offset);
11305        break;
11306    case OPC_BLEZALC: /* OPC_BGEZALC, OPC_BGEUC */
11307    case OPC_BGTZALC: /* OPC_BLTZALC, OPC_BLTUC */
11308        if (rs == 0 || rs == rt) {
11309            /* OPC_BLEZALC, OPC_BGEZALC */
11310            /* OPC_BGTZALC, OPC_BLTZALC */
11311            tcg_gen_movi_tl(cpu_gpr[31], ctx->base.pc_next + 4 + m16_lowbit);
11312        }
11313        gen_load_gpr(t0, rs);
11314        gen_load_gpr(t1, rt);
11315        bcond_compute = 1;
11316        ctx->btarget = addr_add(ctx, ctx->base.pc_next + 4, offset);
11317        break;
11318    case OPC_BC:
11319    case OPC_BALC:
11320        ctx->btarget = addr_add(ctx, ctx->base.pc_next + 4, offset);
11321        break;
11322    case OPC_BEQZC:
11323    case OPC_BNEZC:
11324        if (rs != 0) {
11325            /* OPC_BEQZC, OPC_BNEZC */
11326            gen_load_gpr(t0, rs);
11327            bcond_compute = 1;
11328            ctx->btarget = addr_add(ctx, ctx->base.pc_next + 4, offset);
11329        } else {
11330            /* OPC_JIC, OPC_JIALC */
11331            TCGv tbase = tcg_temp_new();
11332            TCGv toffset = tcg_constant_tl(offset);
11333
11334            gen_load_gpr(tbase, rt);
11335            gen_op_addr_add(ctx, btarget, tbase, toffset);
11336        }
11337        break;
11338    default:
11339        MIPS_INVAL("Compact branch/jump");
11340        gen_reserved_instruction(ctx);
11341        return;
11342    }
11343
11344    if (bcond_compute == 0) {
11345        /* Unconditional compact branch */
11346        switch (opc) {
11347        case OPC_JIALC:
11348            tcg_gen_movi_tl(cpu_gpr[31], ctx->base.pc_next + 4 + m16_lowbit);
11349            /* Fallthrough */
11350        case OPC_JIC:
11351            ctx->hflags |= MIPS_HFLAG_BR;
11352            break;
11353        case OPC_BALC:
11354            tcg_gen_movi_tl(cpu_gpr[31], ctx->base.pc_next + 4 + m16_lowbit);
11355            /* Fallthrough */
11356        case OPC_BC:
11357            ctx->hflags |= MIPS_HFLAG_B;
11358            break;
11359        default:
11360            MIPS_INVAL("Compact branch/jump");
11361            gen_reserved_instruction(ctx);
11362            return;
11363        }
11364
11365        /* Generating branch here as compact branches don't have delay slot */
11366        gen_branch(ctx, 4);
11367    } else {
11368        /* Conditional compact branch */
11369        TCGLabel *fs = gen_new_label();
11370        save_cpu_state(ctx, 0);
11371
11372        switch (opc) {
11373        case OPC_BLEZALC: /* OPC_BGEZALC, OPC_BGEUC */
11374            if (rs == 0 && rt != 0) {
11375                /* OPC_BLEZALC */
11376                tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LE), t1, 0, fs);
11377            } else if (rs != 0 && rt != 0 && rs == rt) {
11378                /* OPC_BGEZALC */
11379                tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GE), t1, 0, fs);
11380            } else {
11381                /* OPC_BGEUC */
11382                tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_GEU), t0, t1, fs);
11383            }
11384            break;
11385        case OPC_BGTZALC: /* OPC_BLTZALC, OPC_BLTUC */
11386            if (rs == 0 && rt != 0) {
11387                /* OPC_BGTZALC */
11388                tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GT), t1, 0, fs);
11389            } else if (rs != 0 && rt != 0 && rs == rt) {
11390                /* OPC_BLTZALC */
11391                tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LT), t1, 0, fs);
11392            } else {
11393                /* OPC_BLTUC */
11394                tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_LTU), t0, t1, fs);
11395            }
11396            break;
11397        case OPC_BLEZC: /* OPC_BGEZC, OPC_BGEC */
11398            if (rs == 0 && rt != 0) {
11399                /* OPC_BLEZC */
11400                tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LE), t1, 0, fs);
11401            } else if (rs != 0 && rt != 0 && rs == rt) {
11402                /* OPC_BGEZC */
11403                tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GE), t1, 0, fs);
11404            } else {
11405                /* OPC_BGEC */
11406                tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_GE), t0, t1, fs);
11407            }
11408            break;
11409        case OPC_BGTZC: /* OPC_BLTZC, OPC_BLTC */
11410            if (rs == 0 && rt != 0) {
11411                /* OPC_BGTZC */
11412                tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GT), t1, 0, fs);
11413            } else if (rs != 0 && rt != 0 && rs == rt) {
11414                /* OPC_BLTZC */
11415                tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LT), t1, 0, fs);
11416            } else {
11417                /* OPC_BLTC */
11418                tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_LT), t0, t1, fs);
11419            }
11420            break;
11421        case OPC_BOVC: /* OPC_BEQZALC, OPC_BEQC */
11422        case OPC_BNVC: /* OPC_BNEZALC, OPC_BNEC */
11423            if (rs >= rt) {
11424                /* OPC_BOVC, OPC_BNVC */
11425                TCGv t2 = tcg_temp_new();
11426                TCGv t3 = tcg_temp_new();
11427                TCGv t4 = tcg_temp_new();
11428                TCGv input_overflow = tcg_temp_new();
11429
11430                gen_load_gpr(t0, rs);
11431                gen_load_gpr(t1, rt);
11432                tcg_gen_ext32s_tl(t2, t0);
11433                tcg_gen_setcond_tl(TCG_COND_NE, input_overflow, t2, t0);
11434                tcg_gen_ext32s_tl(t3, t1);
11435                tcg_gen_setcond_tl(TCG_COND_NE, t4, t3, t1);
11436                tcg_gen_or_tl(input_overflow, input_overflow, t4);
11437
11438                tcg_gen_add_tl(t4, t2, t3);
11439                tcg_gen_ext32s_tl(t4, t4);
11440                tcg_gen_xor_tl(t2, t2, t3);
11441                tcg_gen_xor_tl(t3, t4, t3);
11442                tcg_gen_andc_tl(t2, t3, t2);
11443                tcg_gen_setcondi_tl(TCG_COND_LT, t4, t2, 0);
11444                tcg_gen_or_tl(t4, t4, input_overflow);
11445                if (opc == OPC_BOVC) {
11446                    /* OPC_BOVC */
11447                    tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_NE), t4, 0, fs);
11448                } else {
11449                    /* OPC_BNVC */
11450                    tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_EQ), t4, 0, fs);
11451                }
11452            } else if (rs < rt && rs == 0) {
11453                /* OPC_BEQZALC, OPC_BNEZALC */
11454                if (opc == OPC_BEQZALC) {
11455                    /* OPC_BEQZALC */
11456                    tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_EQ), t1, 0, fs);
11457                } else {
11458                    /* OPC_BNEZALC */
11459                    tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_NE), t1, 0, fs);
11460                }
11461            } else {
11462                /* OPC_BEQC, OPC_BNEC */
11463                if (opc == OPC_BEQC) {
11464                    /* OPC_BEQC */
11465                    tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_EQ), t0, t1, fs);
11466                } else {
11467                    /* OPC_BNEC */
11468                    tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_NE), t0, t1, fs);
11469                }
11470            }
11471            break;
11472        case OPC_BEQZC:
11473            tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_EQ), t0, 0, fs);
11474            break;
11475        case OPC_BNEZC:
11476            tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_NE), t0, 0, fs);
11477            break;
11478        default:
11479            MIPS_INVAL("Compact conditional branch/jump");
11480            gen_reserved_instruction(ctx);
11481            return;
11482        }
11483
11484        /* Generating branch here as compact branches don't have delay slot */
11485        gen_goto_tb(ctx, 1, ctx->btarget);
11486        gen_set_label(fs);
11487
11488        ctx->hflags |= MIPS_HFLAG_FBNSLOT;
11489    }
11490}
11491
11492void gen_addiupc(DisasContext *ctx, int rx, int imm,
11493                 int is_64_bit, int extended)
11494{
11495    TCGv t0;
11496
11497    if (extended && (ctx->hflags & MIPS_HFLAG_BMASK)) {
11498        gen_reserved_instruction(ctx);
11499        return;
11500    }
11501
11502    t0 = tcg_temp_new();
11503
11504    tcg_gen_movi_tl(t0, pc_relative_pc(ctx));
11505    tcg_gen_addi_tl(cpu_gpr[rx], t0, imm);
11506    if (!is_64_bit) {
11507        tcg_gen_ext32s_tl(cpu_gpr[rx], cpu_gpr[rx]);
11508    }
11509}
11510
11511static void gen_cache_operation(DisasContext *ctx, uint32_t op, int base,
11512                                int16_t offset)
11513{
11514    TCGv_i32 t0 = tcg_constant_i32(op);
11515    TCGv t1 = tcg_temp_new();
11516    gen_base_offset_addr(ctx, t1, base, offset);
11517    gen_helper_cache(cpu_env, t1, t0);
11518}
11519
11520static inline bool is_uhi(DisasContext *ctx, int sdbbp_code)
11521{
11522#ifdef CONFIG_USER_ONLY
11523    return false;
11524#else
11525    bool is_user = (ctx->hflags & MIPS_HFLAG_KSU) == MIPS_HFLAG_UM;
11526    return semihosting_enabled(is_user) && sdbbp_code == 1;
11527#endif
11528}
11529
11530void gen_ldxs(DisasContext *ctx, int base, int index, int rd)
11531{
11532    TCGv t0 = tcg_temp_new();
11533    TCGv t1 = tcg_temp_new();
11534
11535    gen_load_gpr(t0, base);
11536
11537    if (index != 0) {
11538        gen_load_gpr(t1, index);
11539        tcg_gen_shli_tl(t1, t1, 2);
11540        gen_op_addr_add(ctx, t0, t1, t0);
11541    }
11542
11543    tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TESL);
11544    gen_store_gpr(t1, rd);
11545}
11546
11547static void gen_sync(int stype)
11548{
11549    TCGBar tcg_mo = TCG_BAR_SC;
11550
11551    switch (stype) {
11552    case 0x4: /* SYNC_WMB */
11553        tcg_mo |= TCG_MO_ST_ST;
11554        break;
11555    case 0x10: /* SYNC_MB */
11556        tcg_mo |= TCG_MO_ALL;
11557        break;
11558    case 0x11: /* SYNC_ACQUIRE */
11559        tcg_mo |= TCG_MO_LD_LD | TCG_MO_LD_ST;
11560        break;
11561    case 0x12: /* SYNC_RELEASE */
11562        tcg_mo |= TCG_MO_ST_ST | TCG_MO_LD_ST;
11563        break;
11564    case 0x13: /* SYNC_RMB */
11565        tcg_mo |= TCG_MO_LD_LD;
11566        break;
11567    default:
11568        tcg_mo |= TCG_MO_ALL;
11569        break;
11570    }
11571
11572    tcg_gen_mb(tcg_mo);
11573}
11574
11575/* ISA extensions (ASEs) */
11576
11577/* MIPS16 extension to MIPS32 */
11578#include "mips16e_translate.c.inc"
11579
11580/* microMIPS extension to MIPS32/MIPS64 */
11581
11582/*
11583 * Values for microMIPS fmt field.  Variable-width, depending on which
11584 * formats the instruction supports.
11585 */
11586enum {
11587    FMT_SD_S = 0,
11588    FMT_SD_D = 1,
11589
11590    FMT_SDPS_S = 0,
11591    FMT_SDPS_D = 1,
11592    FMT_SDPS_PS = 2,
11593
11594    FMT_SWL_S = 0,
11595    FMT_SWL_W = 1,
11596    FMT_SWL_L = 2,
11597
11598    FMT_DWL_D = 0,
11599    FMT_DWL_W = 1,
11600    FMT_DWL_L = 2
11601};
11602
11603#include "micromips_translate.c.inc"
11604
11605#include "nanomips_translate.c.inc"
11606
11607/* MIPSDSP functions. */
11608
11609/* Indexed load is not for DSP only */
11610static void gen_mips_lx(DisasContext *ctx, uint32_t opc,
11611                        int rd, int base, int offset)
11612{
11613    TCGv t0;
11614
11615    if (!(ctx->insn_flags & INSN_OCTEON)) {
11616        check_dsp(ctx);
11617    }
11618    t0 = tcg_temp_new();
11619
11620    if (base == 0) {
11621        gen_load_gpr(t0, offset);
11622    } else if (offset == 0) {
11623        gen_load_gpr(t0, base);
11624    } else {
11625        gen_op_addr_add(ctx, t0, cpu_gpr[base], cpu_gpr[offset]);
11626    }
11627
11628    switch (opc) {
11629    case OPC_LBUX:
11630        tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_UB);
11631        gen_store_gpr(t0, rd);
11632        break;
11633    case OPC_LHX:
11634        tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TESW);
11635        gen_store_gpr(t0, rd);
11636        break;
11637    case OPC_LWX:
11638        tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TESL);
11639        gen_store_gpr(t0, rd);
11640        break;
11641#if defined(TARGET_MIPS64)
11642    case OPC_LDX:
11643        tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEUQ);
11644        gen_store_gpr(t0, rd);
11645        break;
11646#endif
11647    }
11648}
11649
11650static void gen_mipsdsp_arith(DisasContext *ctx, uint32_t op1, uint32_t op2,
11651                              int ret, int v1, int v2)
11652{
11653    TCGv v1_t;
11654    TCGv v2_t;
11655
11656    if (ret == 0) {
11657        /* Treat as NOP. */
11658        return;
11659    }
11660
11661    v1_t = tcg_temp_new();
11662    v2_t = tcg_temp_new();
11663
11664    gen_load_gpr(v1_t, v1);
11665    gen_load_gpr(v2_t, v2);
11666
11667    switch (op1) {
11668    /* OPC_MULT_G_2E is equal OPC_ADDUH_QB_DSP */
11669    case OPC_MULT_G_2E:
11670        check_dsp_r2(ctx);
11671        switch (op2) {
11672        case OPC_ADDUH_QB:
11673            gen_helper_adduh_qb(cpu_gpr[ret], v1_t, v2_t);
11674            break;
11675        case OPC_ADDUH_R_QB:
11676            gen_helper_adduh_r_qb(cpu_gpr[ret], v1_t, v2_t);
11677            break;
11678        case OPC_ADDQH_PH:
11679            gen_helper_addqh_ph(cpu_gpr[ret], v1_t, v2_t);
11680            break;
11681        case OPC_ADDQH_R_PH:
11682            gen_helper_addqh_r_ph(cpu_gpr[ret], v1_t, v2_t);
11683            break;
11684        case OPC_ADDQH_W:
11685            gen_helper_addqh_w(cpu_gpr[ret], v1_t, v2_t);
11686            break;
11687        case OPC_ADDQH_R_W:
11688            gen_helper_addqh_r_w(cpu_gpr[ret], v1_t, v2_t);
11689            break;
11690        case OPC_SUBUH_QB:
11691            gen_helper_subuh_qb(cpu_gpr[ret], v1_t, v2_t);
11692            break;
11693        case OPC_SUBUH_R_QB:
11694            gen_helper_subuh_r_qb(cpu_gpr[ret], v1_t, v2_t);
11695            break;
11696        case OPC_SUBQH_PH:
11697            gen_helper_subqh_ph(cpu_gpr[ret], v1_t, v2_t);
11698            break;
11699        case OPC_SUBQH_R_PH:
11700            gen_helper_subqh_r_ph(cpu_gpr[ret], v1_t, v2_t);
11701            break;
11702        case OPC_SUBQH_W:
11703            gen_helper_subqh_w(cpu_gpr[ret], v1_t, v2_t);
11704            break;
11705        case OPC_SUBQH_R_W:
11706            gen_helper_subqh_r_w(cpu_gpr[ret], v1_t, v2_t);
11707            break;
11708        }
11709        break;
11710    case OPC_ABSQ_S_PH_DSP:
11711        switch (op2) {
11712        case OPC_ABSQ_S_QB:
11713            check_dsp_r2(ctx);
11714            gen_helper_absq_s_qb(cpu_gpr[ret], v2_t, cpu_env);
11715            break;
11716        case OPC_ABSQ_S_PH:
11717            check_dsp(ctx);
11718            gen_helper_absq_s_ph(cpu_gpr[ret], v2_t, cpu_env);
11719            break;
11720        case OPC_ABSQ_S_W:
11721            check_dsp(ctx);
11722            gen_helper_absq_s_w(cpu_gpr[ret], v2_t, cpu_env);
11723            break;
11724        case OPC_PRECEQ_W_PHL:
11725            check_dsp(ctx);
11726            tcg_gen_andi_tl(cpu_gpr[ret], v2_t, 0xFFFF0000);
11727            tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]);
11728            break;
11729        case OPC_PRECEQ_W_PHR:
11730            check_dsp(ctx);
11731            tcg_gen_andi_tl(cpu_gpr[ret], v2_t, 0x0000FFFF);
11732            tcg_gen_shli_tl(cpu_gpr[ret], cpu_gpr[ret], 16);
11733            tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]);
11734            break;
11735        case OPC_PRECEQU_PH_QBL:
11736            check_dsp(ctx);
11737            gen_helper_precequ_ph_qbl(cpu_gpr[ret], v2_t);
11738            break;
11739        case OPC_PRECEQU_PH_QBR:
11740            check_dsp(ctx);
11741            gen_helper_precequ_ph_qbr(cpu_gpr[ret], v2_t);
11742            break;
11743        case OPC_PRECEQU_PH_QBLA:
11744            check_dsp(ctx);
11745            gen_helper_precequ_ph_qbla(cpu_gpr[ret], v2_t);
11746            break;
11747        case OPC_PRECEQU_PH_QBRA:
11748            check_dsp(ctx);
11749            gen_helper_precequ_ph_qbra(cpu_gpr[ret], v2_t);
11750            break;
11751        case OPC_PRECEU_PH_QBL:
11752            check_dsp(ctx);
11753            gen_helper_preceu_ph_qbl(cpu_gpr[ret], v2_t);
11754            break;
11755        case OPC_PRECEU_PH_QBR:
11756            check_dsp(ctx);
11757            gen_helper_preceu_ph_qbr(cpu_gpr[ret], v2_t);
11758            break;
11759        case OPC_PRECEU_PH_QBLA:
11760            check_dsp(ctx);
11761            gen_helper_preceu_ph_qbla(cpu_gpr[ret], v2_t);
11762            break;
11763        case OPC_PRECEU_PH_QBRA:
11764            check_dsp(ctx);
11765            gen_helper_preceu_ph_qbra(cpu_gpr[ret], v2_t);
11766            break;
11767        }
11768        break;
11769    case OPC_ADDU_QB_DSP:
11770        switch (op2) {
11771        case OPC_ADDQ_PH:
11772            check_dsp(ctx);
11773            gen_helper_addq_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
11774            break;
11775        case OPC_ADDQ_S_PH:
11776            check_dsp(ctx);
11777            gen_helper_addq_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
11778            break;
11779        case OPC_ADDQ_S_W:
11780            check_dsp(ctx);
11781            gen_helper_addq_s_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
11782            break;
11783        case OPC_ADDU_QB:
11784            check_dsp(ctx);
11785            gen_helper_addu_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
11786            break;
11787        case OPC_ADDU_S_QB:
11788            check_dsp(ctx);
11789            gen_helper_addu_s_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
11790            break;
11791        case OPC_ADDU_PH:
11792            check_dsp_r2(ctx);
11793            gen_helper_addu_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
11794            break;
11795        case OPC_ADDU_S_PH:
11796            check_dsp_r2(ctx);
11797            gen_helper_addu_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
11798            break;
11799        case OPC_SUBQ_PH:
11800            check_dsp(ctx);
11801            gen_helper_subq_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
11802            break;
11803        case OPC_SUBQ_S_PH:
11804            check_dsp(ctx);
11805            gen_helper_subq_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
11806            break;
11807        case OPC_SUBQ_S_W:
11808            check_dsp(ctx);
11809            gen_helper_subq_s_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
11810            break;
11811        case OPC_SUBU_QB:
11812            check_dsp(ctx);
11813            gen_helper_subu_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
11814            break;
11815        case OPC_SUBU_S_QB:
11816            check_dsp(ctx);
11817            gen_helper_subu_s_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
11818            break;
11819        case OPC_SUBU_PH:
11820            check_dsp_r2(ctx);
11821            gen_helper_subu_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
11822            break;
11823        case OPC_SUBU_S_PH:
11824            check_dsp_r2(ctx);
11825            gen_helper_subu_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
11826            break;
11827        case OPC_ADDSC:
11828            check_dsp(ctx);
11829            gen_helper_addsc(cpu_gpr[ret], v1_t, v2_t, cpu_env);
11830            break;
11831        case OPC_ADDWC:
11832            check_dsp(ctx);
11833            gen_helper_addwc(cpu_gpr[ret], v1_t, v2_t, cpu_env);
11834            break;
11835        case OPC_MODSUB:
11836            check_dsp(ctx);
11837            gen_helper_modsub(cpu_gpr[ret], v1_t, v2_t);
11838            break;
11839        case OPC_RADDU_W_QB:
11840            check_dsp(ctx);
11841            gen_helper_raddu_w_qb(cpu_gpr[ret], v1_t);
11842            break;
11843        }
11844        break;
11845    case OPC_CMPU_EQ_QB_DSP:
11846        switch (op2) {
11847        case OPC_PRECR_QB_PH:
11848            check_dsp_r2(ctx);
11849            gen_helper_precr_qb_ph(cpu_gpr[ret], v1_t, v2_t);
11850            break;
11851        case OPC_PRECRQ_QB_PH:
11852            check_dsp(ctx);
11853            gen_helper_precrq_qb_ph(cpu_gpr[ret], v1_t, v2_t);
11854            break;
11855        case OPC_PRECR_SRA_PH_W:
11856            check_dsp_r2(ctx);
11857            {
11858                TCGv_i32 sa_t = tcg_constant_i32(v2);
11859                gen_helper_precr_sra_ph_w(cpu_gpr[ret], sa_t, v1_t,
11860                                          cpu_gpr[ret]);
11861                break;
11862            }
11863        case OPC_PRECR_SRA_R_PH_W:
11864            check_dsp_r2(ctx);
11865            {
11866                TCGv_i32 sa_t = tcg_constant_i32(v2);
11867                gen_helper_precr_sra_r_ph_w(cpu_gpr[ret], sa_t, v1_t,
11868                                            cpu_gpr[ret]);
11869                break;
11870            }
11871        case OPC_PRECRQ_PH_W:
11872            check_dsp(ctx);
11873            gen_helper_precrq_ph_w(cpu_gpr[ret], v1_t, v2_t);
11874            break;
11875        case OPC_PRECRQ_RS_PH_W:
11876            check_dsp(ctx);
11877            gen_helper_precrq_rs_ph_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
11878            break;
11879        case OPC_PRECRQU_S_QB_PH:
11880            check_dsp(ctx);
11881            gen_helper_precrqu_s_qb_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
11882            break;
11883        }
11884        break;
11885#ifdef TARGET_MIPS64
11886    case OPC_ABSQ_S_QH_DSP:
11887        switch (op2) {
11888        case OPC_PRECEQ_L_PWL:
11889            check_dsp(ctx);
11890            tcg_gen_andi_tl(cpu_gpr[ret], v2_t, 0xFFFFFFFF00000000ull);
11891            break;
11892        case OPC_PRECEQ_L_PWR:
11893            check_dsp(ctx);
11894            tcg_gen_shli_tl(cpu_gpr[ret], v2_t, 32);
11895            break;
11896        case OPC_PRECEQ_PW_QHL:
11897            check_dsp(ctx);
11898            gen_helper_preceq_pw_qhl(cpu_gpr[ret], v2_t);
11899            break;
11900        case OPC_PRECEQ_PW_QHR:
11901            check_dsp(ctx);
11902            gen_helper_preceq_pw_qhr(cpu_gpr[ret], v2_t);
11903            break;
11904        case OPC_PRECEQ_PW_QHLA:
11905            check_dsp(ctx);
11906            gen_helper_preceq_pw_qhla(cpu_gpr[ret], v2_t);
11907            break;
11908        case OPC_PRECEQ_PW_QHRA:
11909            check_dsp(ctx);
11910            gen_helper_preceq_pw_qhra(cpu_gpr[ret], v2_t);
11911            break;
11912        case OPC_PRECEQU_QH_OBL:
11913            check_dsp(ctx);
11914            gen_helper_precequ_qh_obl(cpu_gpr[ret], v2_t);
11915            break;
11916        case OPC_PRECEQU_QH_OBR:
11917            check_dsp(ctx);
11918            gen_helper_precequ_qh_obr(cpu_gpr[ret], v2_t);
11919            break;
11920        case OPC_PRECEQU_QH_OBLA:
11921            check_dsp(ctx);
11922            gen_helper_precequ_qh_obla(cpu_gpr[ret], v2_t);
11923            break;
11924        case OPC_PRECEQU_QH_OBRA:
11925            check_dsp(ctx);
11926            gen_helper_precequ_qh_obra(cpu_gpr[ret], v2_t);
11927            break;
11928        case OPC_PRECEU_QH_OBL:
11929            check_dsp(ctx);
11930            gen_helper_preceu_qh_obl(cpu_gpr[ret], v2_t);
11931            break;
11932        case OPC_PRECEU_QH_OBR:
11933            check_dsp(ctx);
11934            gen_helper_preceu_qh_obr(cpu_gpr[ret], v2_t);
11935            break;
11936        case OPC_PRECEU_QH_OBLA:
11937            check_dsp(ctx);
11938            gen_helper_preceu_qh_obla(cpu_gpr[ret], v2_t);
11939            break;
11940        case OPC_PRECEU_QH_OBRA:
11941            check_dsp(ctx);
11942            gen_helper_preceu_qh_obra(cpu_gpr[ret], v2_t);
11943            break;
11944        case OPC_ABSQ_S_OB:
11945            check_dsp_r2(ctx);
11946            gen_helper_absq_s_ob(cpu_gpr[ret], v2_t, cpu_env);
11947            break;
11948        case OPC_ABSQ_S_PW:
11949            check_dsp(ctx);
11950            gen_helper_absq_s_pw(cpu_gpr[ret], v2_t, cpu_env);
11951            break;
11952        case OPC_ABSQ_S_QH:
11953            check_dsp(ctx);
11954            gen_helper_absq_s_qh(cpu_gpr[ret], v2_t, cpu_env);
11955            break;
11956        }
11957        break;
11958    case OPC_ADDU_OB_DSP:
11959        switch (op2) {
11960        case OPC_RADDU_L_OB:
11961            check_dsp(ctx);
11962            gen_helper_raddu_l_ob(cpu_gpr[ret], v1_t);
11963            break;
11964        case OPC_SUBQ_PW:
11965            check_dsp(ctx);
11966            gen_helper_subq_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
11967            break;
11968        case OPC_SUBQ_S_PW:
11969            check_dsp(ctx);
11970            gen_helper_subq_s_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
11971            break;
11972        case OPC_SUBQ_QH:
11973            check_dsp(ctx);
11974            gen_helper_subq_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
11975            break;
11976        case OPC_SUBQ_S_QH:
11977            check_dsp(ctx);
11978            gen_helper_subq_s_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
11979            break;
11980        case OPC_SUBU_OB:
11981            check_dsp(ctx);
11982            gen_helper_subu_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
11983            break;
11984        case OPC_SUBU_S_OB:
11985            check_dsp(ctx);
11986            gen_helper_subu_s_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
11987            break;
11988        case OPC_SUBU_QH:
11989            check_dsp_r2(ctx);
11990            gen_helper_subu_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
11991            break;
11992        case OPC_SUBU_S_QH:
11993            check_dsp_r2(ctx);
11994            gen_helper_subu_s_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
11995            break;
11996        case OPC_SUBUH_OB:
11997            check_dsp_r2(ctx);
11998            gen_helper_subuh_ob(cpu_gpr[ret], v1_t, v2_t);
11999            break;
12000        case OPC_SUBUH_R_OB:
12001            check_dsp_r2(ctx);
12002            gen_helper_subuh_r_ob(cpu_gpr[ret], v1_t, v2_t);
12003            break;
12004        case OPC_ADDQ_PW:
12005            check_dsp(ctx);
12006            gen_helper_addq_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12007            break;
12008        case OPC_ADDQ_S_PW:
12009            check_dsp(ctx);
12010            gen_helper_addq_s_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12011            break;
12012        case OPC_ADDQ_QH:
12013            check_dsp(ctx);
12014            gen_helper_addq_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12015            break;
12016        case OPC_ADDQ_S_QH:
12017            check_dsp(ctx);
12018            gen_helper_addq_s_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12019            break;
12020        case OPC_ADDU_OB:
12021            check_dsp(ctx);
12022            gen_helper_addu_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12023            break;
12024        case OPC_ADDU_S_OB:
12025            check_dsp(ctx);
12026            gen_helper_addu_s_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12027            break;
12028        case OPC_ADDU_QH:
12029            check_dsp_r2(ctx);
12030            gen_helper_addu_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12031            break;
12032        case OPC_ADDU_S_QH:
12033            check_dsp_r2(ctx);
12034            gen_helper_addu_s_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12035            break;
12036        case OPC_ADDUH_OB:
12037            check_dsp_r2(ctx);
12038            gen_helper_adduh_ob(cpu_gpr[ret], v1_t, v2_t);
12039            break;
12040        case OPC_ADDUH_R_OB:
12041            check_dsp_r2(ctx);
12042            gen_helper_adduh_r_ob(cpu_gpr[ret], v1_t, v2_t);
12043            break;
12044        }
12045        break;
12046    case OPC_CMPU_EQ_OB_DSP:
12047        switch (op2) {
12048        case OPC_PRECR_OB_QH:
12049            check_dsp_r2(ctx);
12050            gen_helper_precr_ob_qh(cpu_gpr[ret], v1_t, v2_t);
12051            break;
12052        case OPC_PRECR_SRA_QH_PW:
12053            check_dsp_r2(ctx);
12054            {
12055                TCGv_i32 ret_t = tcg_constant_i32(ret);
12056                gen_helper_precr_sra_qh_pw(v2_t, v1_t, v2_t, ret_t);
12057                break;
12058            }
12059        case OPC_PRECR_SRA_R_QH_PW:
12060            check_dsp_r2(ctx);
12061            {
12062                TCGv_i32 sa_v = tcg_constant_i32(ret);
12063                gen_helper_precr_sra_r_qh_pw(v2_t, v1_t, v2_t, sa_v);
12064                break;
12065            }
12066        case OPC_PRECRQ_OB_QH:
12067            check_dsp(ctx);
12068            gen_helper_precrq_ob_qh(cpu_gpr[ret], v1_t, v2_t);
12069            break;
12070        case OPC_PRECRQ_PW_L:
12071            check_dsp(ctx);
12072            gen_helper_precrq_pw_l(cpu_gpr[ret], v1_t, v2_t);
12073            break;
12074        case OPC_PRECRQ_QH_PW:
12075            check_dsp(ctx);
12076            gen_helper_precrq_qh_pw(cpu_gpr[ret], v1_t, v2_t);
12077            break;
12078        case OPC_PRECRQ_RS_QH_PW:
12079            check_dsp(ctx);
12080            gen_helper_precrq_rs_qh_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12081            break;
12082        case OPC_PRECRQU_S_OB_QH:
12083            check_dsp(ctx);
12084            gen_helper_precrqu_s_ob_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12085            break;
12086        }
12087        break;
12088#endif
12089    }
12090}
12091
12092static void gen_mipsdsp_shift(DisasContext *ctx, uint32_t opc,
12093                              int ret, int v1, int v2)
12094{
12095    uint32_t op2;
12096    TCGv t0;
12097    TCGv v1_t;
12098    TCGv v2_t;
12099
12100    if (ret == 0) {
12101        /* Treat as NOP. */
12102        return;
12103    }
12104
12105    t0 = tcg_temp_new();
12106    v1_t = tcg_temp_new();
12107    v2_t = tcg_temp_new();
12108
12109    tcg_gen_movi_tl(t0, v1);
12110    gen_load_gpr(v1_t, v1);
12111    gen_load_gpr(v2_t, v2);
12112
12113    switch (opc) {
12114    case OPC_SHLL_QB_DSP:
12115        {
12116            op2 = MASK_SHLL_QB(ctx->opcode);
12117            switch (op2) {
12118            case OPC_SHLL_QB:
12119                check_dsp(ctx);
12120                gen_helper_shll_qb(cpu_gpr[ret], t0, v2_t, cpu_env);
12121                break;
12122            case OPC_SHLLV_QB:
12123                check_dsp(ctx);
12124                gen_helper_shll_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12125                break;
12126            case OPC_SHLL_PH:
12127                check_dsp(ctx);
12128                gen_helper_shll_ph(cpu_gpr[ret], t0, v2_t, cpu_env);
12129                break;
12130            case OPC_SHLLV_PH:
12131                check_dsp(ctx);
12132                gen_helper_shll_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12133                break;
12134            case OPC_SHLL_S_PH:
12135                check_dsp(ctx);
12136                gen_helper_shll_s_ph(cpu_gpr[ret], t0, v2_t, cpu_env);
12137                break;
12138            case OPC_SHLLV_S_PH:
12139                check_dsp(ctx);
12140                gen_helper_shll_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12141                break;
12142            case OPC_SHLL_S_W:
12143                check_dsp(ctx);
12144                gen_helper_shll_s_w(cpu_gpr[ret], t0, v2_t, cpu_env);
12145                break;
12146            case OPC_SHLLV_S_W:
12147                check_dsp(ctx);
12148                gen_helper_shll_s_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12149                break;
12150            case OPC_SHRL_QB:
12151                check_dsp(ctx);
12152                gen_helper_shrl_qb(cpu_gpr[ret], t0, v2_t);
12153                break;
12154            case OPC_SHRLV_QB:
12155                check_dsp(ctx);
12156                gen_helper_shrl_qb(cpu_gpr[ret], v1_t, v2_t);
12157                break;
12158            case OPC_SHRL_PH:
12159                check_dsp_r2(ctx);
12160                gen_helper_shrl_ph(cpu_gpr[ret], t0, v2_t);
12161                break;
12162            case OPC_SHRLV_PH:
12163                check_dsp_r2(ctx);
12164                gen_helper_shrl_ph(cpu_gpr[ret], v1_t, v2_t);
12165                break;
12166            case OPC_SHRA_QB:
12167                check_dsp_r2(ctx);
12168                gen_helper_shra_qb(cpu_gpr[ret], t0, v2_t);
12169                break;
12170            case OPC_SHRA_R_QB:
12171                check_dsp_r2(ctx);
12172                gen_helper_shra_r_qb(cpu_gpr[ret], t0, v2_t);
12173                break;
12174            case OPC_SHRAV_QB:
12175                check_dsp_r2(ctx);
12176                gen_helper_shra_qb(cpu_gpr[ret], v1_t, v2_t);
12177                break;
12178            case OPC_SHRAV_R_QB:
12179                check_dsp_r2(ctx);
12180                gen_helper_shra_r_qb(cpu_gpr[ret], v1_t, v2_t);
12181                break;
12182            case OPC_SHRA_PH:
12183                check_dsp(ctx);
12184                gen_helper_shra_ph(cpu_gpr[ret], t0, v2_t);
12185                break;
12186            case OPC_SHRA_R_PH:
12187                check_dsp(ctx);
12188                gen_helper_shra_r_ph(cpu_gpr[ret], t0, v2_t);
12189                break;
12190            case OPC_SHRAV_PH:
12191                check_dsp(ctx);
12192                gen_helper_shra_ph(cpu_gpr[ret], v1_t, v2_t);
12193                break;
12194            case OPC_SHRAV_R_PH:
12195                check_dsp(ctx);
12196                gen_helper_shra_r_ph(cpu_gpr[ret], v1_t, v2_t);
12197                break;
12198            case OPC_SHRA_R_W:
12199                check_dsp(ctx);
12200                gen_helper_shra_r_w(cpu_gpr[ret], t0, v2_t);
12201                break;
12202            case OPC_SHRAV_R_W:
12203                check_dsp(ctx);
12204                gen_helper_shra_r_w(cpu_gpr[ret], v1_t, v2_t);
12205                break;
12206            default:            /* Invalid */
12207                MIPS_INVAL("MASK SHLL.QB");
12208                gen_reserved_instruction(ctx);
12209                break;
12210            }
12211            break;
12212        }
12213#ifdef TARGET_MIPS64
12214    case OPC_SHLL_OB_DSP:
12215        op2 = MASK_SHLL_OB(ctx->opcode);
12216        switch (op2) {
12217        case OPC_SHLL_PW:
12218            check_dsp(ctx);
12219            gen_helper_shll_pw(cpu_gpr[ret], v2_t, t0, cpu_env);
12220            break;
12221        case OPC_SHLLV_PW:
12222            check_dsp(ctx);
12223            gen_helper_shll_pw(cpu_gpr[ret], v2_t, v1_t, cpu_env);
12224            break;
12225        case OPC_SHLL_S_PW:
12226            check_dsp(ctx);
12227            gen_helper_shll_s_pw(cpu_gpr[ret], v2_t, t0, cpu_env);
12228            break;
12229        case OPC_SHLLV_S_PW:
12230            check_dsp(ctx);
12231            gen_helper_shll_s_pw(cpu_gpr[ret], v2_t, v1_t, cpu_env);
12232            break;
12233        case OPC_SHLL_OB:
12234            check_dsp(ctx);
12235            gen_helper_shll_ob(cpu_gpr[ret], v2_t, t0, cpu_env);
12236            break;
12237        case OPC_SHLLV_OB:
12238            check_dsp(ctx);
12239            gen_helper_shll_ob(cpu_gpr[ret], v2_t, v1_t, cpu_env);
12240            break;
12241        case OPC_SHLL_QH:
12242            check_dsp(ctx);
12243            gen_helper_shll_qh(cpu_gpr[ret], v2_t, t0, cpu_env);
12244            break;
12245        case OPC_SHLLV_QH:
12246            check_dsp(ctx);
12247            gen_helper_shll_qh(cpu_gpr[ret], v2_t, v1_t, cpu_env);
12248            break;
12249        case OPC_SHLL_S_QH:
12250            check_dsp(ctx);
12251            gen_helper_shll_s_qh(cpu_gpr[ret], v2_t, t0, cpu_env);
12252            break;
12253        case OPC_SHLLV_S_QH:
12254            check_dsp(ctx);
12255            gen_helper_shll_s_qh(cpu_gpr[ret], v2_t, v1_t, cpu_env);
12256            break;
12257        case OPC_SHRA_OB:
12258            check_dsp_r2(ctx);
12259            gen_helper_shra_ob(cpu_gpr[ret], v2_t, t0);
12260            break;
12261        case OPC_SHRAV_OB:
12262            check_dsp_r2(ctx);
12263            gen_helper_shra_ob(cpu_gpr[ret], v2_t, v1_t);
12264            break;
12265        case OPC_SHRA_R_OB:
12266            check_dsp_r2(ctx);
12267            gen_helper_shra_r_ob(cpu_gpr[ret], v2_t, t0);
12268            break;
12269        case OPC_SHRAV_R_OB:
12270            check_dsp_r2(ctx);
12271            gen_helper_shra_r_ob(cpu_gpr[ret], v2_t, v1_t);
12272            break;
12273        case OPC_SHRA_PW:
12274            check_dsp(ctx);
12275            gen_helper_shra_pw(cpu_gpr[ret], v2_t, t0);
12276            break;
12277        case OPC_SHRAV_PW:
12278            check_dsp(ctx);
12279            gen_helper_shra_pw(cpu_gpr[ret], v2_t, v1_t);
12280            break;
12281        case OPC_SHRA_R_PW:
12282            check_dsp(ctx);
12283            gen_helper_shra_r_pw(cpu_gpr[ret], v2_t, t0);
12284            break;
12285        case OPC_SHRAV_R_PW:
12286            check_dsp(ctx);
12287            gen_helper_shra_r_pw(cpu_gpr[ret], v2_t, v1_t);
12288            break;
12289        case OPC_SHRA_QH:
12290            check_dsp(ctx);
12291            gen_helper_shra_qh(cpu_gpr[ret], v2_t, t0);
12292            break;
12293        case OPC_SHRAV_QH:
12294            check_dsp(ctx);
12295            gen_helper_shra_qh(cpu_gpr[ret], v2_t, v1_t);
12296            break;
12297        case OPC_SHRA_R_QH:
12298            check_dsp(ctx);
12299            gen_helper_shra_r_qh(cpu_gpr[ret], v2_t, t0);
12300            break;
12301        case OPC_SHRAV_R_QH:
12302            check_dsp(ctx);
12303            gen_helper_shra_r_qh(cpu_gpr[ret], v2_t, v1_t);
12304            break;
12305        case OPC_SHRL_OB:
12306            check_dsp(ctx);
12307            gen_helper_shrl_ob(cpu_gpr[ret], v2_t, t0);
12308            break;
12309        case OPC_SHRLV_OB:
12310            check_dsp(ctx);
12311            gen_helper_shrl_ob(cpu_gpr[ret], v2_t, v1_t);
12312            break;
12313        case OPC_SHRL_QH:
12314            check_dsp_r2(ctx);
12315            gen_helper_shrl_qh(cpu_gpr[ret], v2_t, t0);
12316            break;
12317        case OPC_SHRLV_QH:
12318            check_dsp_r2(ctx);
12319            gen_helper_shrl_qh(cpu_gpr[ret], v2_t, v1_t);
12320            break;
12321        default:            /* Invalid */
12322            MIPS_INVAL("MASK SHLL.OB");
12323            gen_reserved_instruction(ctx);
12324            break;
12325        }
12326        break;
12327#endif
12328    }
12329}
12330
12331static void gen_mipsdsp_multiply(DisasContext *ctx, uint32_t op1, uint32_t op2,
12332                                 int ret, int v1, int v2, int check_ret)
12333{
12334    TCGv_i32 t0;
12335    TCGv v1_t;
12336    TCGv v2_t;
12337
12338    if ((ret == 0) && (check_ret == 1)) {
12339        /* Treat as NOP. */
12340        return;
12341    }
12342
12343    t0 = tcg_temp_new_i32();
12344    v1_t = tcg_temp_new();
12345    v2_t = tcg_temp_new();
12346
12347    tcg_gen_movi_i32(t0, ret);
12348    gen_load_gpr(v1_t, v1);
12349    gen_load_gpr(v2_t, v2);
12350
12351    switch (op1) {
12352    /*
12353     * OPC_MULT_G_2E, OPC_ADDUH_QB_DSP, OPC_MUL_PH_DSP have
12354     * the same mask and op1.
12355     */
12356    case OPC_MULT_G_2E:
12357        check_dsp_r2(ctx);
12358        switch (op2) {
12359        case  OPC_MUL_PH:
12360            gen_helper_mul_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12361            break;
12362        case  OPC_MUL_S_PH:
12363            gen_helper_mul_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12364            break;
12365        case OPC_MULQ_S_W:
12366            gen_helper_mulq_s_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12367            break;
12368        case OPC_MULQ_RS_W:
12369            gen_helper_mulq_rs_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12370            break;
12371        }
12372        break;
12373    case OPC_DPA_W_PH_DSP:
12374        switch (op2) {
12375        case OPC_DPAU_H_QBL:
12376            check_dsp(ctx);
12377            gen_helper_dpau_h_qbl(t0, v1_t, v2_t, cpu_env);
12378            break;
12379        case OPC_DPAU_H_QBR:
12380            check_dsp(ctx);
12381            gen_helper_dpau_h_qbr(t0, v1_t, v2_t, cpu_env);
12382            break;
12383        case OPC_DPSU_H_QBL:
12384            check_dsp(ctx);
12385            gen_helper_dpsu_h_qbl(t0, v1_t, v2_t, cpu_env);
12386            break;
12387        case OPC_DPSU_H_QBR:
12388            check_dsp(ctx);
12389            gen_helper_dpsu_h_qbr(t0, v1_t, v2_t, cpu_env);
12390            break;
12391        case OPC_DPA_W_PH:
12392            check_dsp_r2(ctx);
12393            gen_helper_dpa_w_ph(t0, v1_t, v2_t, cpu_env);
12394            break;
12395        case OPC_DPAX_W_PH:
12396            check_dsp_r2(ctx);
12397            gen_helper_dpax_w_ph(t0, v1_t, v2_t, cpu_env);
12398            break;
12399        case OPC_DPAQ_S_W_PH:
12400            check_dsp(ctx);
12401            gen_helper_dpaq_s_w_ph(t0, v1_t, v2_t, cpu_env);
12402            break;
12403        case OPC_DPAQX_S_W_PH:
12404            check_dsp_r2(ctx);
12405            gen_helper_dpaqx_s_w_ph(t0, v1_t, v2_t, cpu_env);
12406            break;
12407        case OPC_DPAQX_SA_W_PH:
12408            check_dsp_r2(ctx);
12409            gen_helper_dpaqx_sa_w_ph(t0, v1_t, v2_t, cpu_env);
12410            break;
12411        case OPC_DPS_W_PH:
12412            check_dsp_r2(ctx);
12413            gen_helper_dps_w_ph(t0, v1_t, v2_t, cpu_env);
12414            break;
12415        case OPC_DPSX_W_PH:
12416            check_dsp_r2(ctx);
12417            gen_helper_dpsx_w_ph(t0, v1_t, v2_t, cpu_env);
12418            break;
12419        case OPC_DPSQ_S_W_PH:
12420            check_dsp(ctx);
12421            gen_helper_dpsq_s_w_ph(t0, v1_t, v2_t, cpu_env);
12422            break;
12423        case OPC_DPSQX_S_W_PH:
12424            check_dsp_r2(ctx);
12425            gen_helper_dpsqx_s_w_ph(t0, v1_t, v2_t, cpu_env);
12426            break;
12427        case OPC_DPSQX_SA_W_PH:
12428            check_dsp_r2(ctx);
12429            gen_helper_dpsqx_sa_w_ph(t0, v1_t, v2_t, cpu_env);
12430            break;
12431        case OPC_MULSAQ_S_W_PH:
12432            check_dsp(ctx);
12433            gen_helper_mulsaq_s_w_ph(t0, v1_t, v2_t, cpu_env);
12434            break;
12435        case OPC_DPAQ_SA_L_W:
12436            check_dsp(ctx);
12437            gen_helper_dpaq_sa_l_w(t0, v1_t, v2_t, cpu_env);
12438            break;
12439        case OPC_DPSQ_SA_L_W:
12440            check_dsp(ctx);
12441            gen_helper_dpsq_sa_l_w(t0, v1_t, v2_t, cpu_env);
12442            break;
12443        case OPC_MAQ_S_W_PHL:
12444            check_dsp(ctx);
12445            gen_helper_maq_s_w_phl(t0, v1_t, v2_t, cpu_env);
12446            break;
12447        case OPC_MAQ_S_W_PHR:
12448            check_dsp(ctx);
12449            gen_helper_maq_s_w_phr(t0, v1_t, v2_t, cpu_env);
12450            break;
12451        case OPC_MAQ_SA_W_PHL:
12452            check_dsp(ctx);
12453            gen_helper_maq_sa_w_phl(t0, v1_t, v2_t, cpu_env);
12454            break;
12455        case OPC_MAQ_SA_W_PHR:
12456            check_dsp(ctx);
12457            gen_helper_maq_sa_w_phr(t0, v1_t, v2_t, cpu_env);
12458            break;
12459        case OPC_MULSA_W_PH:
12460            check_dsp_r2(ctx);
12461            gen_helper_mulsa_w_ph(t0, v1_t, v2_t, cpu_env);
12462            break;
12463        }
12464        break;
12465#ifdef TARGET_MIPS64
12466    case OPC_DPAQ_W_QH_DSP:
12467        {
12468            int ac = ret & 0x03;
12469            tcg_gen_movi_i32(t0, ac);
12470
12471            switch (op2) {
12472            case OPC_DMADD:
12473                check_dsp(ctx);
12474                gen_helper_dmadd(v1_t, v2_t, t0, cpu_env);
12475                break;
12476            case OPC_DMADDU:
12477                check_dsp(ctx);
12478                gen_helper_dmaddu(v1_t, v2_t, t0, cpu_env);
12479                break;
12480            case OPC_DMSUB:
12481                check_dsp(ctx);
12482                gen_helper_dmsub(v1_t, v2_t, t0, cpu_env);
12483                break;
12484            case OPC_DMSUBU:
12485                check_dsp(ctx);
12486                gen_helper_dmsubu(v1_t, v2_t, t0, cpu_env);
12487                break;
12488            case OPC_DPA_W_QH:
12489                check_dsp_r2(ctx);
12490                gen_helper_dpa_w_qh(v1_t, v2_t, t0, cpu_env);
12491                break;
12492            case OPC_DPAQ_S_W_QH:
12493                check_dsp(ctx);
12494                gen_helper_dpaq_s_w_qh(v1_t, v2_t, t0, cpu_env);
12495                break;
12496            case OPC_DPAQ_SA_L_PW:
12497                check_dsp(ctx);
12498                gen_helper_dpaq_sa_l_pw(v1_t, v2_t, t0, cpu_env);
12499                break;
12500            case OPC_DPAU_H_OBL:
12501                check_dsp(ctx);
12502                gen_helper_dpau_h_obl(v1_t, v2_t, t0, cpu_env);
12503                break;
12504            case OPC_DPAU_H_OBR:
12505                check_dsp(ctx);
12506                gen_helper_dpau_h_obr(v1_t, v2_t, t0, cpu_env);
12507                break;
12508            case OPC_DPS_W_QH:
12509                check_dsp_r2(ctx);
12510                gen_helper_dps_w_qh(v1_t, v2_t, t0, cpu_env);
12511                break;
12512            case OPC_DPSQ_S_W_QH:
12513                check_dsp(ctx);
12514                gen_helper_dpsq_s_w_qh(v1_t, v2_t, t0, cpu_env);
12515                break;
12516            case OPC_DPSQ_SA_L_PW:
12517                check_dsp(ctx);
12518                gen_helper_dpsq_sa_l_pw(v1_t, v2_t, t0, cpu_env);
12519                break;
12520            case OPC_DPSU_H_OBL:
12521                check_dsp(ctx);
12522                gen_helper_dpsu_h_obl(v1_t, v2_t, t0, cpu_env);
12523                break;
12524            case OPC_DPSU_H_OBR:
12525                check_dsp(ctx);
12526                gen_helper_dpsu_h_obr(v1_t, v2_t, t0, cpu_env);
12527                break;
12528            case OPC_MAQ_S_L_PWL:
12529                check_dsp(ctx);
12530                gen_helper_maq_s_l_pwl(v1_t, v2_t, t0, cpu_env);
12531                break;
12532            case OPC_MAQ_S_L_PWR:
12533                check_dsp(ctx);
12534                gen_helper_maq_s_l_pwr(v1_t, v2_t, t0, cpu_env);
12535                break;
12536            case OPC_MAQ_S_W_QHLL:
12537                check_dsp(ctx);
12538                gen_helper_maq_s_w_qhll(v1_t, v2_t, t0, cpu_env);
12539                break;
12540            case OPC_MAQ_SA_W_QHLL:
12541                check_dsp(ctx);
12542                gen_helper_maq_sa_w_qhll(v1_t, v2_t, t0, cpu_env);
12543                break;
12544            case OPC_MAQ_S_W_QHLR:
12545                check_dsp(ctx);
12546                gen_helper_maq_s_w_qhlr(v1_t, v2_t, t0, cpu_env);
12547                break;
12548            case OPC_MAQ_SA_W_QHLR:
12549                check_dsp(ctx);
12550                gen_helper_maq_sa_w_qhlr(v1_t, v2_t, t0, cpu_env);
12551                break;
12552            case OPC_MAQ_S_W_QHRL:
12553                check_dsp(ctx);
12554                gen_helper_maq_s_w_qhrl(v1_t, v2_t, t0, cpu_env);
12555                break;
12556            case OPC_MAQ_SA_W_QHRL:
12557                check_dsp(ctx);
12558                gen_helper_maq_sa_w_qhrl(v1_t, v2_t, t0, cpu_env);
12559                break;
12560            case OPC_MAQ_S_W_QHRR:
12561                check_dsp(ctx);
12562                gen_helper_maq_s_w_qhrr(v1_t, v2_t, t0, cpu_env);
12563                break;
12564            case OPC_MAQ_SA_W_QHRR:
12565                check_dsp(ctx);
12566                gen_helper_maq_sa_w_qhrr(v1_t, v2_t, t0, cpu_env);
12567                break;
12568            case OPC_MULSAQ_S_L_PW:
12569                check_dsp(ctx);
12570                gen_helper_mulsaq_s_l_pw(v1_t, v2_t, t0, cpu_env);
12571                break;
12572            case OPC_MULSAQ_S_W_QH:
12573                check_dsp(ctx);
12574                gen_helper_mulsaq_s_w_qh(v1_t, v2_t, t0, cpu_env);
12575                break;
12576            }
12577        }
12578        break;
12579#endif
12580    case OPC_ADDU_QB_DSP:
12581        switch (op2) {
12582        case OPC_MULEU_S_PH_QBL:
12583            check_dsp(ctx);
12584            gen_helper_muleu_s_ph_qbl(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12585            break;
12586        case OPC_MULEU_S_PH_QBR:
12587            check_dsp(ctx);
12588            gen_helper_muleu_s_ph_qbr(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12589            break;
12590        case OPC_MULQ_RS_PH:
12591            check_dsp(ctx);
12592            gen_helper_mulq_rs_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12593            break;
12594        case OPC_MULEQ_S_W_PHL:
12595            check_dsp(ctx);
12596            gen_helper_muleq_s_w_phl(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12597            break;
12598        case OPC_MULEQ_S_W_PHR:
12599            check_dsp(ctx);
12600            gen_helper_muleq_s_w_phr(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12601            break;
12602        case OPC_MULQ_S_PH:
12603            check_dsp_r2(ctx);
12604            gen_helper_mulq_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12605            break;
12606        }
12607        break;
12608#ifdef TARGET_MIPS64
12609    case OPC_ADDU_OB_DSP:
12610        switch (op2) {
12611        case OPC_MULEQ_S_PW_QHL:
12612            check_dsp(ctx);
12613            gen_helper_muleq_s_pw_qhl(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12614            break;
12615        case OPC_MULEQ_S_PW_QHR:
12616            check_dsp(ctx);
12617            gen_helper_muleq_s_pw_qhr(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12618            break;
12619        case OPC_MULEU_S_QH_OBL:
12620            check_dsp(ctx);
12621            gen_helper_muleu_s_qh_obl(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12622            break;
12623        case OPC_MULEU_S_QH_OBR:
12624            check_dsp(ctx);
12625            gen_helper_muleu_s_qh_obr(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12626            break;
12627        case OPC_MULQ_RS_QH:
12628            check_dsp(ctx);
12629            gen_helper_mulq_rs_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12630            break;
12631        }
12632        break;
12633#endif
12634    }
12635}
12636
12637static void gen_mipsdsp_bitinsn(DisasContext *ctx, uint32_t op1, uint32_t op2,
12638                                int ret, int val)
12639{
12640    int16_t imm;
12641    TCGv t0;
12642    TCGv val_t;
12643
12644    if (ret == 0) {
12645        /* Treat as NOP. */
12646        return;
12647    }
12648
12649    t0 = tcg_temp_new();
12650    val_t = tcg_temp_new();
12651    gen_load_gpr(val_t, val);
12652
12653    switch (op1) {
12654    case OPC_ABSQ_S_PH_DSP:
12655        switch (op2) {
12656        case OPC_BITREV:
12657            check_dsp(ctx);
12658            gen_helper_bitrev(cpu_gpr[ret], val_t);
12659            break;
12660        case OPC_REPL_QB:
12661            check_dsp(ctx);
12662            {
12663                target_long result;
12664                imm = (ctx->opcode >> 16) & 0xFF;
12665                result = (uint32_t)imm << 24 |
12666                         (uint32_t)imm << 16 |
12667                         (uint32_t)imm << 8  |
12668                         (uint32_t)imm;
12669                result = (int32_t)result;
12670                tcg_gen_movi_tl(cpu_gpr[ret], result);
12671            }
12672            break;
12673        case OPC_REPLV_QB:
12674            check_dsp(ctx);
12675            tcg_gen_ext8u_tl(cpu_gpr[ret], val_t);
12676            tcg_gen_shli_tl(t0, cpu_gpr[ret], 8);
12677            tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
12678            tcg_gen_shli_tl(t0, cpu_gpr[ret], 16);
12679            tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
12680            tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]);
12681            break;
12682        case OPC_REPL_PH:
12683            check_dsp(ctx);
12684            {
12685                imm = (ctx->opcode >> 16) & 0x03FF;
12686                imm = (int16_t)(imm << 6) >> 6;
12687                tcg_gen_movi_tl(cpu_gpr[ret], \
12688                                (target_long)((int32_t)imm << 16 | \
12689                                (uint16_t)imm));
12690            }
12691            break;
12692        case OPC_REPLV_PH:
12693            check_dsp(ctx);
12694            tcg_gen_ext16u_tl(cpu_gpr[ret], val_t);
12695            tcg_gen_shli_tl(t0, cpu_gpr[ret], 16);
12696            tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
12697            tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]);
12698            break;
12699        }
12700        break;
12701#ifdef TARGET_MIPS64
12702    case OPC_ABSQ_S_QH_DSP:
12703        switch (op2) {
12704        case OPC_REPL_OB:
12705            check_dsp(ctx);
12706            {
12707                target_long temp;
12708
12709                imm = (ctx->opcode >> 16) & 0xFF;
12710                temp = ((uint64_t)imm << 8) | (uint64_t)imm;
12711                temp = (temp << 16) | temp;
12712                temp = (temp << 32) | temp;
12713                tcg_gen_movi_tl(cpu_gpr[ret], temp);
12714                break;
12715            }
12716        case OPC_REPL_PW:
12717            check_dsp(ctx);
12718            {
12719                target_long temp;
12720
12721                imm = (ctx->opcode >> 16) & 0x03FF;
12722                imm = (int16_t)(imm << 6) >> 6;
12723                temp = ((target_long)imm << 32) \
12724                       | ((target_long)imm & 0xFFFFFFFF);
12725                tcg_gen_movi_tl(cpu_gpr[ret], temp);
12726                break;
12727            }
12728        case OPC_REPL_QH:
12729            check_dsp(ctx);
12730            {
12731                target_long temp;
12732
12733                imm = (ctx->opcode >> 16) & 0x03FF;
12734                imm = (int16_t)(imm << 6) >> 6;
12735
12736                temp = ((uint64_t)(uint16_t)imm << 48) |
12737                       ((uint64_t)(uint16_t)imm << 32) |
12738                       ((uint64_t)(uint16_t)imm << 16) |
12739                       (uint64_t)(uint16_t)imm;
12740                tcg_gen_movi_tl(cpu_gpr[ret], temp);
12741                break;
12742            }
12743        case OPC_REPLV_OB:
12744            check_dsp(ctx);
12745            tcg_gen_ext8u_tl(cpu_gpr[ret], val_t);
12746            tcg_gen_shli_tl(t0, cpu_gpr[ret], 8);
12747            tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
12748            tcg_gen_shli_tl(t0, cpu_gpr[ret], 16);
12749            tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
12750            tcg_gen_shli_tl(t0, cpu_gpr[ret], 32);
12751            tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
12752            break;
12753        case OPC_REPLV_PW:
12754            check_dsp(ctx);
12755            tcg_gen_ext32u_i64(cpu_gpr[ret], val_t);
12756            tcg_gen_shli_tl(t0, cpu_gpr[ret], 32);
12757            tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
12758            break;
12759        case OPC_REPLV_QH:
12760            check_dsp(ctx);
12761            tcg_gen_ext16u_tl(cpu_gpr[ret], val_t);
12762            tcg_gen_shli_tl(t0, cpu_gpr[ret], 16);
12763            tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
12764            tcg_gen_shli_tl(t0, cpu_gpr[ret], 32);
12765            tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
12766            break;
12767        }
12768        break;
12769#endif
12770    }
12771}
12772
12773static void gen_mipsdsp_add_cmp_pick(DisasContext *ctx,
12774                                     uint32_t op1, uint32_t op2,
12775                                     int ret, int v1, int v2, int check_ret)
12776{
12777    TCGv t1;
12778    TCGv v1_t;
12779    TCGv v2_t;
12780
12781    if ((ret == 0) && (check_ret == 1)) {
12782        /* Treat as NOP. */
12783        return;
12784    }
12785
12786    t1 = tcg_temp_new();
12787    v1_t = tcg_temp_new();
12788    v2_t = tcg_temp_new();
12789
12790    gen_load_gpr(v1_t, v1);
12791    gen_load_gpr(v2_t, v2);
12792
12793    switch (op1) {
12794    case OPC_CMPU_EQ_QB_DSP:
12795        switch (op2) {
12796        case OPC_CMPU_EQ_QB:
12797            check_dsp(ctx);
12798            gen_helper_cmpu_eq_qb(v1_t, v2_t, cpu_env);
12799            break;
12800        case OPC_CMPU_LT_QB:
12801            check_dsp(ctx);
12802            gen_helper_cmpu_lt_qb(v1_t, v2_t, cpu_env);
12803            break;
12804        case OPC_CMPU_LE_QB:
12805            check_dsp(ctx);
12806            gen_helper_cmpu_le_qb(v1_t, v2_t, cpu_env);
12807            break;
12808        case OPC_CMPGU_EQ_QB:
12809            check_dsp(ctx);
12810            gen_helper_cmpgu_eq_qb(cpu_gpr[ret], v1_t, v2_t);
12811            break;
12812        case OPC_CMPGU_LT_QB:
12813            check_dsp(ctx);
12814            gen_helper_cmpgu_lt_qb(cpu_gpr[ret], v1_t, v2_t);
12815            break;
12816        case OPC_CMPGU_LE_QB:
12817            check_dsp(ctx);
12818            gen_helper_cmpgu_le_qb(cpu_gpr[ret], v1_t, v2_t);
12819            break;
12820        case OPC_CMPGDU_EQ_QB:
12821            check_dsp_r2(ctx);
12822            gen_helper_cmpgu_eq_qb(t1, v1_t, v2_t);
12823            tcg_gen_mov_tl(cpu_gpr[ret], t1);
12824            tcg_gen_andi_tl(cpu_dspctrl, cpu_dspctrl, 0xF0FFFFFF);
12825            tcg_gen_shli_tl(t1, t1, 24);
12826            tcg_gen_or_tl(cpu_dspctrl, cpu_dspctrl, t1);
12827            break;
12828        case OPC_CMPGDU_LT_QB:
12829            check_dsp_r2(ctx);
12830            gen_helper_cmpgu_lt_qb(t1, v1_t, v2_t);
12831            tcg_gen_mov_tl(cpu_gpr[ret], t1);
12832            tcg_gen_andi_tl(cpu_dspctrl, cpu_dspctrl, 0xF0FFFFFF);
12833            tcg_gen_shli_tl(t1, t1, 24);
12834            tcg_gen_or_tl(cpu_dspctrl, cpu_dspctrl, t1);
12835            break;
12836        case OPC_CMPGDU_LE_QB:
12837            check_dsp_r2(ctx);
12838            gen_helper_cmpgu_le_qb(t1, v1_t, v2_t);
12839            tcg_gen_mov_tl(cpu_gpr[ret], t1);
12840            tcg_gen_andi_tl(cpu_dspctrl, cpu_dspctrl, 0xF0FFFFFF);
12841            tcg_gen_shli_tl(t1, t1, 24);
12842            tcg_gen_or_tl(cpu_dspctrl, cpu_dspctrl, t1);
12843            break;
12844        case OPC_CMP_EQ_PH:
12845            check_dsp(ctx);
12846            gen_helper_cmp_eq_ph(v1_t, v2_t, cpu_env);
12847            break;
12848        case OPC_CMP_LT_PH:
12849            check_dsp(ctx);
12850            gen_helper_cmp_lt_ph(v1_t, v2_t, cpu_env);
12851            break;
12852        case OPC_CMP_LE_PH:
12853            check_dsp(ctx);
12854            gen_helper_cmp_le_ph(v1_t, v2_t, cpu_env);
12855            break;
12856        case OPC_PICK_QB:
12857            check_dsp(ctx);
12858            gen_helper_pick_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12859            break;
12860        case OPC_PICK_PH:
12861            check_dsp(ctx);
12862            gen_helper_pick_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12863            break;
12864        case OPC_PACKRL_PH:
12865            check_dsp(ctx);
12866            gen_helper_packrl_ph(cpu_gpr[ret], v1_t, v2_t);
12867            break;
12868        }
12869        break;
12870#ifdef TARGET_MIPS64
12871    case OPC_CMPU_EQ_OB_DSP:
12872        switch (op2) {
12873        case OPC_CMP_EQ_PW:
12874            check_dsp(ctx);
12875            gen_helper_cmp_eq_pw(v1_t, v2_t, cpu_env);
12876            break;
12877        case OPC_CMP_LT_PW:
12878            check_dsp(ctx);
12879            gen_helper_cmp_lt_pw(v1_t, v2_t, cpu_env);
12880            break;
12881        case OPC_CMP_LE_PW:
12882            check_dsp(ctx);
12883            gen_helper_cmp_le_pw(v1_t, v2_t, cpu_env);
12884            break;
12885        case OPC_CMP_EQ_QH:
12886            check_dsp(ctx);
12887            gen_helper_cmp_eq_qh(v1_t, v2_t, cpu_env);
12888            break;
12889        case OPC_CMP_LT_QH:
12890            check_dsp(ctx);
12891            gen_helper_cmp_lt_qh(v1_t, v2_t, cpu_env);
12892            break;
12893        case OPC_CMP_LE_QH:
12894            check_dsp(ctx);
12895            gen_helper_cmp_le_qh(v1_t, v2_t, cpu_env);
12896            break;
12897        case OPC_CMPGDU_EQ_OB:
12898            check_dsp_r2(ctx);
12899            gen_helper_cmpgdu_eq_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12900            break;
12901        case OPC_CMPGDU_LT_OB:
12902            check_dsp_r2(ctx);
12903            gen_helper_cmpgdu_lt_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12904            break;
12905        case OPC_CMPGDU_LE_OB:
12906            check_dsp_r2(ctx);
12907            gen_helper_cmpgdu_le_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12908            break;
12909        case OPC_CMPGU_EQ_OB:
12910            check_dsp(ctx);
12911            gen_helper_cmpgu_eq_ob(cpu_gpr[ret], v1_t, v2_t);
12912            break;
12913        case OPC_CMPGU_LT_OB:
12914            check_dsp(ctx);
12915            gen_helper_cmpgu_lt_ob(cpu_gpr[ret], v1_t, v2_t);
12916            break;
12917        case OPC_CMPGU_LE_OB:
12918            check_dsp(ctx);
12919            gen_helper_cmpgu_le_ob(cpu_gpr[ret], v1_t, v2_t);
12920            break;
12921        case OPC_CMPU_EQ_OB:
12922            check_dsp(ctx);
12923            gen_helper_cmpu_eq_ob(v1_t, v2_t, cpu_env);
12924            break;
12925        case OPC_CMPU_LT_OB:
12926            check_dsp(ctx);
12927            gen_helper_cmpu_lt_ob(v1_t, v2_t, cpu_env);
12928            break;
12929        case OPC_CMPU_LE_OB:
12930            check_dsp(ctx);
12931            gen_helper_cmpu_le_ob(v1_t, v2_t, cpu_env);
12932            break;
12933        case OPC_PACKRL_PW:
12934            check_dsp(ctx);
12935            gen_helper_packrl_pw(cpu_gpr[ret], v1_t, v2_t);
12936            break;
12937        case OPC_PICK_OB:
12938            check_dsp(ctx);
12939            gen_helper_pick_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12940            break;
12941        case OPC_PICK_PW:
12942            check_dsp(ctx);
12943            gen_helper_pick_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12944            break;
12945        case OPC_PICK_QH:
12946            check_dsp(ctx);
12947            gen_helper_pick_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12948            break;
12949        }
12950        break;
12951#endif
12952    }
12953}
12954
12955static void gen_mipsdsp_append(CPUMIPSState *env, DisasContext *ctx,
12956                               uint32_t op1, int rt, int rs, int sa)
12957{
12958    TCGv t0;
12959
12960    check_dsp_r2(ctx);
12961
12962    if (rt == 0) {
12963        /* Treat as NOP. */
12964        return;
12965    }
12966
12967    t0 = tcg_temp_new();
12968    gen_load_gpr(t0, rs);
12969
12970    switch (op1) {
12971    case OPC_APPEND_DSP:
12972        switch (MASK_APPEND(ctx->opcode)) {
12973        case OPC_APPEND:
12974            if (sa != 0) {
12975                tcg_gen_deposit_tl(cpu_gpr[rt], t0, cpu_gpr[rt], sa, 32 - sa);
12976            }
12977            tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
12978            break;
12979        case OPC_PREPEND:
12980            if (sa != 0) {
12981                tcg_gen_ext32u_tl(cpu_gpr[rt], cpu_gpr[rt]);
12982                tcg_gen_shri_tl(cpu_gpr[rt], cpu_gpr[rt], sa);
12983                tcg_gen_shli_tl(t0, t0, 32 - sa);
12984                tcg_gen_or_tl(cpu_gpr[rt], cpu_gpr[rt], t0);
12985            }
12986            tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
12987            break;
12988        case OPC_BALIGN:
12989            sa &= 3;
12990            if (sa != 0 && sa != 2) {
12991                tcg_gen_shli_tl(cpu_gpr[rt], cpu_gpr[rt], 8 * sa);
12992                tcg_gen_ext32u_tl(t0, t0);
12993                tcg_gen_shri_tl(t0, t0, 8 * (4 - sa));
12994                tcg_gen_or_tl(cpu_gpr[rt], cpu_gpr[rt], t0);
12995            }
12996            tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
12997            break;
12998        default:            /* Invalid */
12999            MIPS_INVAL("MASK APPEND");
13000            gen_reserved_instruction(ctx);
13001            break;
13002        }
13003        break;
13004#ifdef TARGET_MIPS64
13005    case OPC_DAPPEND_DSP:
13006        switch (MASK_DAPPEND(ctx->opcode)) {
13007        case OPC_DAPPEND:
13008            if (sa != 0) {
13009                tcg_gen_deposit_tl(cpu_gpr[rt], t0, cpu_gpr[rt], sa, 64 - sa);
13010            }
13011            break;
13012        case OPC_PREPENDD:
13013            tcg_gen_shri_tl(cpu_gpr[rt], cpu_gpr[rt], 0x20 | sa);
13014            tcg_gen_shli_tl(t0, t0, 64 - (0x20 | sa));
13015            tcg_gen_or_tl(cpu_gpr[rt], t0, t0);
13016            break;
13017        case OPC_PREPENDW:
13018            if (sa != 0) {
13019                tcg_gen_shri_tl(cpu_gpr[rt], cpu_gpr[rt], sa);
13020                tcg_gen_shli_tl(t0, t0, 64 - sa);
13021                tcg_gen_or_tl(cpu_gpr[rt], cpu_gpr[rt], t0);
13022            }
13023            break;
13024        case OPC_DBALIGN:
13025            sa &= 7;
13026            if (sa != 0 && sa != 2 && sa != 4) {
13027                tcg_gen_shli_tl(cpu_gpr[rt], cpu_gpr[rt], 8 * sa);
13028                tcg_gen_shri_tl(t0, t0, 8 * (8 - sa));
13029                tcg_gen_or_tl(cpu_gpr[rt], cpu_gpr[rt], t0);
13030            }
13031            break;
13032        default:            /* Invalid */
13033            MIPS_INVAL("MASK DAPPEND");
13034            gen_reserved_instruction(ctx);
13035            break;
13036        }
13037        break;
13038#endif
13039    }
13040}
13041
13042static void gen_mipsdsp_accinsn(DisasContext *ctx, uint32_t op1, uint32_t op2,
13043                                int ret, int v1, int v2, int check_ret)
13044
13045{
13046    TCGv t0;
13047    TCGv t1;
13048    TCGv v1_t;
13049    int16_t imm;
13050
13051    if ((ret == 0) && (check_ret == 1)) {
13052        /* Treat as NOP. */
13053        return;
13054    }
13055
13056    t0 = tcg_temp_new();
13057    t1 = tcg_temp_new();
13058    v1_t = tcg_temp_new();
13059
13060    gen_load_gpr(v1_t, v1);
13061
13062    switch (op1) {
13063    case OPC_EXTR_W_DSP:
13064        check_dsp(ctx);
13065        switch (op2) {
13066        case OPC_EXTR_W:
13067            tcg_gen_movi_tl(t0, v2);
13068            tcg_gen_movi_tl(t1, v1);
13069            gen_helper_extr_w(cpu_gpr[ret], t0, t1, cpu_env);
13070            break;
13071        case OPC_EXTR_R_W:
13072            tcg_gen_movi_tl(t0, v2);
13073            tcg_gen_movi_tl(t1, v1);
13074            gen_helper_extr_r_w(cpu_gpr[ret], t0, t1, cpu_env);
13075            break;
13076        case OPC_EXTR_RS_W:
13077            tcg_gen_movi_tl(t0, v2);
13078            tcg_gen_movi_tl(t1, v1);
13079            gen_helper_extr_rs_w(cpu_gpr[ret], t0, t1, cpu_env);
13080            break;
13081        case OPC_EXTR_S_H:
13082            tcg_gen_movi_tl(t0, v2);
13083            tcg_gen_movi_tl(t1, v1);
13084            gen_helper_extr_s_h(cpu_gpr[ret], t0, t1, cpu_env);
13085            break;
13086        case OPC_EXTRV_S_H:
13087            tcg_gen_movi_tl(t0, v2);
13088            gen_helper_extr_s_h(cpu_gpr[ret], t0, v1_t, cpu_env);
13089            break;
13090        case OPC_EXTRV_W:
13091            tcg_gen_movi_tl(t0, v2);
13092            gen_helper_extr_w(cpu_gpr[ret], t0, v1_t, cpu_env);
13093            break;
13094        case OPC_EXTRV_R_W:
13095            tcg_gen_movi_tl(t0, v2);
13096            gen_helper_extr_r_w(cpu_gpr[ret], t0, v1_t, cpu_env);
13097            break;
13098        case OPC_EXTRV_RS_W:
13099            tcg_gen_movi_tl(t0, v2);
13100            gen_helper_extr_rs_w(cpu_gpr[ret], t0, v1_t, cpu_env);
13101            break;
13102        case OPC_EXTP:
13103            tcg_gen_movi_tl(t0, v2);
13104            tcg_gen_movi_tl(t1, v1);
13105            gen_helper_extp(cpu_gpr[ret], t0, t1, cpu_env);
13106            break;
13107        case OPC_EXTPV:
13108            tcg_gen_movi_tl(t0, v2);
13109            gen_helper_extp(cpu_gpr[ret], t0, v1_t, cpu_env);
13110            break;
13111        case OPC_EXTPDP:
13112            tcg_gen_movi_tl(t0, v2);
13113            tcg_gen_movi_tl(t1, v1);
13114            gen_helper_extpdp(cpu_gpr[ret], t0, t1, cpu_env);
13115            break;
13116        case OPC_EXTPDPV:
13117            tcg_gen_movi_tl(t0, v2);
13118            gen_helper_extpdp(cpu_gpr[ret], t0, v1_t, cpu_env);
13119            break;
13120        case OPC_SHILO:
13121            imm = (ctx->opcode >> 20) & 0x3F;
13122            tcg_gen_movi_tl(t0, ret);
13123            tcg_gen_movi_tl(t1, imm);
13124            gen_helper_shilo(t0, t1, cpu_env);
13125            break;
13126        case OPC_SHILOV:
13127            tcg_gen_movi_tl(t0, ret);
13128            gen_helper_shilo(t0, v1_t, cpu_env);
13129            break;
13130        case OPC_MTHLIP:
13131            tcg_gen_movi_tl(t0, ret);
13132            gen_helper_mthlip(t0, v1_t, cpu_env);
13133            break;
13134        case OPC_WRDSP:
13135            imm = (ctx->opcode >> 11) & 0x3FF;
13136            tcg_gen_movi_tl(t0, imm);
13137            gen_helper_wrdsp(v1_t, t0, cpu_env);
13138            break;
13139        case OPC_RDDSP:
13140            imm = (ctx->opcode >> 16) & 0x03FF;
13141            tcg_gen_movi_tl(t0, imm);
13142            gen_helper_rddsp(cpu_gpr[ret], t0, cpu_env);
13143            break;
13144        }
13145        break;
13146#ifdef TARGET_MIPS64
13147    case OPC_DEXTR_W_DSP:
13148        check_dsp(ctx);
13149        switch (op2) {
13150        case OPC_DMTHLIP:
13151            tcg_gen_movi_tl(t0, ret);
13152            gen_helper_dmthlip(v1_t, t0, cpu_env);
13153            break;
13154        case OPC_DSHILO:
13155            {
13156                int shift = (ctx->opcode >> 19) & 0x7F;
13157                int ac = (ctx->opcode >> 11) & 0x03;
13158                tcg_gen_movi_tl(t0, shift);
13159                tcg_gen_movi_tl(t1, ac);
13160                gen_helper_dshilo(t0, t1, cpu_env);
13161                break;
13162            }
13163        case OPC_DSHILOV:
13164            {
13165                int ac = (ctx->opcode >> 11) & 0x03;
13166                tcg_gen_movi_tl(t0, ac);
13167                gen_helper_dshilo(v1_t, t0, cpu_env);
13168                break;
13169            }
13170        case OPC_DEXTP:
13171            tcg_gen_movi_tl(t0, v2);
13172            tcg_gen_movi_tl(t1, v1);
13173
13174            gen_helper_dextp(cpu_gpr[ret], t0, t1, cpu_env);
13175            break;
13176        case OPC_DEXTPV:
13177            tcg_gen_movi_tl(t0, v2);
13178            gen_helper_dextp(cpu_gpr[ret], t0, v1_t, cpu_env);
13179            break;
13180        case OPC_DEXTPDP:
13181            tcg_gen_movi_tl(t0, v2);
13182            tcg_gen_movi_tl(t1, v1);
13183            gen_helper_dextpdp(cpu_gpr[ret], t0, t1, cpu_env);
13184            break;
13185        case OPC_DEXTPDPV:
13186            tcg_gen_movi_tl(t0, v2);
13187            gen_helper_dextpdp(cpu_gpr[ret], t0, v1_t, cpu_env);
13188            break;
13189        case OPC_DEXTR_L:
13190            tcg_gen_movi_tl(t0, v2);
13191            tcg_gen_movi_tl(t1, v1);
13192            gen_helper_dextr_l(cpu_gpr[ret], t0, t1, cpu_env);
13193            break;
13194        case OPC_DEXTR_R_L:
13195            tcg_gen_movi_tl(t0, v2);
13196            tcg_gen_movi_tl(t1, v1);
13197            gen_helper_dextr_r_l(cpu_gpr[ret], t0, t1, cpu_env);
13198            break;
13199        case OPC_DEXTR_RS_L:
13200            tcg_gen_movi_tl(t0, v2);
13201            tcg_gen_movi_tl(t1, v1);
13202            gen_helper_dextr_rs_l(cpu_gpr[ret], t0, t1, cpu_env);
13203            break;
13204        case OPC_DEXTR_W:
13205            tcg_gen_movi_tl(t0, v2);
13206            tcg_gen_movi_tl(t1, v1);
13207            gen_helper_dextr_w(cpu_gpr[ret], t0, t1, cpu_env);
13208            break;
13209        case OPC_DEXTR_R_W:
13210            tcg_gen_movi_tl(t0, v2);
13211            tcg_gen_movi_tl(t1, v1);
13212            gen_helper_dextr_r_w(cpu_gpr[ret], t0, t1, cpu_env);
13213            break;
13214        case OPC_DEXTR_RS_W:
13215            tcg_gen_movi_tl(t0, v2);
13216            tcg_gen_movi_tl(t1, v1);
13217            gen_helper_dextr_rs_w(cpu_gpr[ret], t0, t1, cpu_env);
13218            break;
13219        case OPC_DEXTR_S_H:
13220            tcg_gen_movi_tl(t0, v2);
13221            tcg_gen_movi_tl(t1, v1);
13222            gen_helper_dextr_s_h(cpu_gpr[ret], t0, t1, cpu_env);
13223            break;
13224        case OPC_DEXTRV_S_H:
13225            tcg_gen_movi_tl(t0, v2);
13226            gen_helper_dextr_s_h(cpu_gpr[ret], t0, v1_t, cpu_env);
13227            break;
13228        case OPC_DEXTRV_L:
13229            tcg_gen_movi_tl(t0, v2);
13230            gen_helper_dextr_l(cpu_gpr[ret], t0, v1_t, cpu_env);
13231            break;
13232        case OPC_DEXTRV_R_L:
13233            tcg_gen_movi_tl(t0, v2);
13234            gen_helper_dextr_r_l(cpu_gpr[ret], t0, v1_t, cpu_env);
13235            break;
13236        case OPC_DEXTRV_RS_L:
13237            tcg_gen_movi_tl(t0, v2);
13238            gen_helper_dextr_rs_l(cpu_gpr[ret], t0, v1_t, cpu_env);
13239            break;
13240        case OPC_DEXTRV_W:
13241            tcg_gen_movi_tl(t0, v2);
13242            gen_helper_dextr_w(cpu_gpr[ret], t0, v1_t, cpu_env);
13243            break;
13244        case OPC_DEXTRV_R_W:
13245            tcg_gen_movi_tl(t0, v2);
13246            gen_helper_dextr_r_w(cpu_gpr[ret], t0, v1_t, cpu_env);
13247            break;
13248        case OPC_DEXTRV_RS_W:
13249            tcg_gen_movi_tl(t0, v2);
13250            gen_helper_dextr_rs_w(cpu_gpr[ret], t0, v1_t, cpu_env);
13251            break;
13252        }
13253        break;
13254#endif
13255    }
13256}
13257
13258/* End MIPSDSP functions. */
13259
13260static void decode_opc_special_r6(CPUMIPSState *env, DisasContext *ctx)
13261{
13262    int rs, rt, rd, sa;
13263    uint32_t op1, op2;
13264
13265    rs = (ctx->opcode >> 21) & 0x1f;
13266    rt = (ctx->opcode >> 16) & 0x1f;
13267    rd = (ctx->opcode >> 11) & 0x1f;
13268    sa = (ctx->opcode >> 6) & 0x1f;
13269
13270    op1 = MASK_SPECIAL(ctx->opcode);
13271    switch (op1) {
13272    case OPC_MULT:
13273    case OPC_MULTU:
13274    case OPC_DIV:
13275    case OPC_DIVU:
13276        op2 = MASK_R6_MULDIV(ctx->opcode);
13277        switch (op2) {
13278        case R6_OPC_MUL:
13279        case R6_OPC_MUH:
13280        case R6_OPC_MULU:
13281        case R6_OPC_MUHU:
13282        case R6_OPC_DIV:
13283        case R6_OPC_MOD:
13284        case R6_OPC_DIVU:
13285        case R6_OPC_MODU:
13286            gen_r6_muldiv(ctx, op2, rd, rs, rt);
13287            break;
13288        default:
13289            MIPS_INVAL("special_r6 muldiv");
13290            gen_reserved_instruction(ctx);
13291            break;
13292        }
13293        break;
13294    case OPC_SELEQZ:
13295    case OPC_SELNEZ:
13296        gen_cond_move(ctx, op1, rd, rs, rt);
13297        break;
13298    case R6_OPC_CLO:
13299    case R6_OPC_CLZ:
13300        if (rt == 0 && sa == 1) {
13301            /*
13302             * Major opcode and function field is shared with preR6 MFHI/MTHI.
13303             * We need additionally to check other fields.
13304             */
13305            gen_cl(ctx, op1, rd, rs);
13306        } else {
13307            gen_reserved_instruction(ctx);
13308        }
13309        break;
13310    case R6_OPC_SDBBP:
13311        if (is_uhi(ctx, extract32(ctx->opcode, 6, 20))) {
13312            ctx->base.is_jmp = DISAS_SEMIHOST;
13313        } else {
13314            if (ctx->hflags & MIPS_HFLAG_SBRI) {
13315                gen_reserved_instruction(ctx);
13316            } else {
13317                generate_exception_end(ctx, EXCP_DBp);
13318            }
13319        }
13320        break;
13321#if defined(TARGET_MIPS64)
13322    case R6_OPC_DCLO:
13323    case R6_OPC_DCLZ:
13324        if (rt == 0 && sa == 1) {
13325            /*
13326             * Major opcode and function field is shared with preR6 MFHI/MTHI.
13327             * We need additionally to check other fields.
13328             */
13329            check_mips_64(ctx);
13330            gen_cl(ctx, op1, rd, rs);
13331        } else {
13332            gen_reserved_instruction(ctx);
13333        }
13334        break;
13335    case OPC_DMULT:
13336    case OPC_DMULTU:
13337    case OPC_DDIV:
13338    case OPC_DDIVU:
13339
13340        op2 = MASK_R6_MULDIV(ctx->opcode);
13341        switch (op2) {
13342        case R6_OPC_DMUL:
13343        case R6_OPC_DMUH:
13344        case R6_OPC_DMULU:
13345        case R6_OPC_DMUHU:
13346        case R6_OPC_DDIV:
13347        case R6_OPC_DMOD:
13348        case R6_OPC_DDIVU:
13349        case R6_OPC_DMODU:
13350            check_mips_64(ctx);
13351            gen_r6_muldiv(ctx, op2, rd, rs, rt);
13352            break;
13353        default:
13354            MIPS_INVAL("special_r6 muldiv");
13355            gen_reserved_instruction(ctx);
13356            break;
13357        }
13358        break;
13359#endif
13360    default:            /* Invalid */
13361        MIPS_INVAL("special_r6");
13362        gen_reserved_instruction(ctx);
13363        break;
13364    }
13365}
13366
13367static void decode_opc_special_tx79(CPUMIPSState *env, DisasContext *ctx)
13368{
13369    int rs = extract32(ctx->opcode, 21, 5);
13370    int rt = extract32(ctx->opcode, 16, 5);
13371    int rd = extract32(ctx->opcode, 11, 5);
13372    uint32_t op1 = MASK_SPECIAL(ctx->opcode);
13373
13374    switch (op1) {
13375    case OPC_MOVN:         /* Conditional move */
13376    case OPC_MOVZ:
13377        gen_cond_move(ctx, op1, rd, rs, rt);
13378        break;
13379    case OPC_MFHI:          /* Move from HI/LO */
13380    case OPC_MFLO:
13381        gen_HILO(ctx, op1, 0, rd);
13382        break;
13383    case OPC_MTHI:
13384    case OPC_MTLO:          /* Move to HI/LO */
13385        gen_HILO(ctx, op1, 0, rs);
13386        break;
13387    case OPC_MULT:
13388    case OPC_MULTU:
13389        gen_mul_txx9(ctx, op1, rd, rs, rt);
13390        break;
13391    case OPC_DIV:
13392    case OPC_DIVU:
13393        gen_muldiv(ctx, op1, 0, rs, rt);
13394        break;
13395#if defined(TARGET_MIPS64)
13396    case OPC_DMULT:
13397    case OPC_DMULTU:
13398    case OPC_DDIV:
13399    case OPC_DDIVU:
13400        check_insn_opc_user_only(ctx, INSN_R5900);
13401        gen_muldiv(ctx, op1, 0, rs, rt);
13402        break;
13403#endif
13404    case OPC_JR:
13405        gen_compute_branch(ctx, op1, 4, rs, 0, 0, 4);
13406        break;
13407    default:            /* Invalid */
13408        MIPS_INVAL("special_tx79");
13409        gen_reserved_instruction(ctx);
13410        break;
13411    }
13412}
13413
13414static void decode_opc_special_legacy(CPUMIPSState *env, DisasContext *ctx)
13415{
13416    int rs, rt, rd;
13417    uint32_t op1;
13418
13419    rs = (ctx->opcode >> 21) & 0x1f;
13420    rt = (ctx->opcode >> 16) & 0x1f;
13421    rd = (ctx->opcode >> 11) & 0x1f;
13422
13423    op1 = MASK_SPECIAL(ctx->opcode);
13424    switch (op1) {
13425    case OPC_MOVN:         /* Conditional move */
13426    case OPC_MOVZ:
13427        check_insn(ctx, ISA_MIPS4 | ISA_MIPS_R1 |
13428                   INSN_LOONGSON2E | INSN_LOONGSON2F);
13429        gen_cond_move(ctx, op1, rd, rs, rt);
13430        break;
13431    case OPC_MFHI:          /* Move from HI/LO */
13432    case OPC_MFLO:
13433        gen_HILO(ctx, op1, rs & 3, rd);
13434        break;
13435    case OPC_MTHI:
13436    case OPC_MTLO:          /* Move to HI/LO */
13437        gen_HILO(ctx, op1, rd & 3, rs);
13438        break;
13439    case OPC_MOVCI:
13440        check_insn(ctx, ISA_MIPS4 | ISA_MIPS_R1);
13441        if (env->CP0_Config1 & (1 << CP0C1_FP)) {
13442            check_cp1_enabled(ctx);
13443            gen_movci(ctx, rd, rs, (ctx->opcode >> 18) & 0x7,
13444                      (ctx->opcode >> 16) & 1);
13445        } else {
13446            generate_exception_err(ctx, EXCP_CpU, 1);
13447        }
13448        break;
13449    case OPC_MULT:
13450    case OPC_MULTU:
13451        gen_muldiv(ctx, op1, rd & 3, rs, rt);
13452        break;
13453    case OPC_DIV:
13454    case OPC_DIVU:
13455        gen_muldiv(ctx, op1, 0, rs, rt);
13456        break;
13457#if defined(TARGET_MIPS64)
13458    case OPC_DMULT:
13459    case OPC_DMULTU:
13460    case OPC_DDIV:
13461    case OPC_DDIVU:
13462        check_insn(ctx, ISA_MIPS3);
13463        check_mips_64(ctx);
13464        gen_muldiv(ctx, op1, 0, rs, rt);
13465        break;
13466#endif
13467    case OPC_JR:
13468        gen_compute_branch(ctx, op1, 4, rs, 0, 0, 4);
13469        break;
13470    case OPC_SPIM:
13471#ifdef MIPS_STRICT_STANDARD
13472        MIPS_INVAL("SPIM");
13473        gen_reserved_instruction(ctx);
13474#else
13475        /* Implemented as RI exception for now. */
13476        MIPS_INVAL("spim (unofficial)");
13477        gen_reserved_instruction(ctx);
13478#endif
13479        break;
13480    default:            /* Invalid */
13481        MIPS_INVAL("special_legacy");
13482        gen_reserved_instruction(ctx);
13483        break;
13484    }
13485}
13486
13487static void decode_opc_special(CPUMIPSState *env, DisasContext *ctx)
13488{
13489    int rs, rt, rd, sa;
13490    uint32_t op1;
13491
13492    rs = (ctx->opcode >> 21) & 0x1f;
13493    rt = (ctx->opcode >> 16) & 0x1f;
13494    rd = (ctx->opcode >> 11) & 0x1f;
13495    sa = (ctx->opcode >> 6) & 0x1f;
13496
13497    op1 = MASK_SPECIAL(ctx->opcode);
13498    switch (op1) {
13499    case OPC_SLL:          /* Shift with immediate */
13500        if (sa == 5 && rd == 0 &&
13501            rs == 0 && rt == 0) { /* PAUSE */
13502            if ((ctx->insn_flags & ISA_MIPS_R6) &&
13503                (ctx->hflags & MIPS_HFLAG_BMASK)) {
13504                gen_reserved_instruction(ctx);
13505                break;
13506            }
13507        }
13508        /* Fallthrough */
13509    case OPC_SRA:
13510        gen_shift_imm(ctx, op1, rd, rt, sa);
13511        break;
13512    case OPC_SRL:
13513        switch ((ctx->opcode >> 21) & 0x1f) {
13514        case 1:
13515            /* rotr is decoded as srl on non-R2 CPUs */
13516            if (ctx->insn_flags & ISA_MIPS_R2) {
13517                op1 = OPC_ROTR;
13518            }
13519            /* Fallthrough */
13520        case 0:
13521            gen_shift_imm(ctx, op1, rd, rt, sa);
13522            break;
13523        default:
13524            gen_reserved_instruction(ctx);
13525            break;
13526        }
13527        break;
13528    case OPC_ADD:
13529    case OPC_ADDU:
13530    case OPC_SUB:
13531    case OPC_SUBU:
13532        gen_arith(ctx, op1, rd, rs, rt);
13533        break;
13534    case OPC_SLLV:         /* Shifts */
13535    case OPC_SRAV:
13536        gen_shift(ctx, op1, rd, rs, rt);
13537        break;
13538    case OPC_SRLV:
13539        switch ((ctx->opcode >> 6) & 0x1f) {
13540        case 1:
13541            /* rotrv is decoded as srlv on non-R2 CPUs */
13542            if (ctx->insn_flags & ISA_MIPS_R2) {
13543                op1 = OPC_ROTRV;
13544            }
13545            /* Fallthrough */
13546        case 0:
13547            gen_shift(ctx, op1, rd, rs, rt);
13548            break;
13549        default:
13550            gen_reserved_instruction(ctx);
13551            break;
13552        }
13553        break;
13554    case OPC_SLT:          /* Set on less than */
13555    case OPC_SLTU:
13556        gen_slt(ctx, op1, rd, rs, rt);
13557        break;
13558    case OPC_AND:          /* Logic*/
13559    case OPC_OR:
13560    case OPC_NOR:
13561    case OPC_XOR:
13562        gen_logic(ctx, op1, rd, rs, rt);
13563        break;
13564    case OPC_JALR:
13565        gen_compute_branch(ctx, op1, 4, rs, rd, sa, 4);
13566        break;
13567    case OPC_TGE: /* Traps */
13568    case OPC_TGEU:
13569    case OPC_TLT:
13570    case OPC_TLTU:
13571    case OPC_TEQ:
13572    case OPC_TNE:
13573        check_insn(ctx, ISA_MIPS2);
13574        gen_trap(ctx, op1, rs, rt, -1, extract32(ctx->opcode, 6, 10));
13575        break;
13576    case OPC_PMON:
13577        /* Pmon entry point, also R4010 selsl */
13578#ifdef MIPS_STRICT_STANDARD
13579        MIPS_INVAL("PMON / selsl");
13580        gen_reserved_instruction(ctx);
13581#else
13582        gen_helper_pmon(cpu_env, tcg_constant_i32(sa));
13583#endif
13584        break;
13585    case OPC_SYSCALL:
13586        generate_exception_end(ctx, EXCP_SYSCALL);
13587        break;
13588    case OPC_BREAK:
13589        generate_exception_break(ctx, extract32(ctx->opcode, 6, 20));
13590        break;
13591    case OPC_SYNC:
13592        check_insn(ctx, ISA_MIPS2);
13593        gen_sync(extract32(ctx->opcode, 6, 5));
13594        break;
13595
13596#if defined(TARGET_MIPS64)
13597        /* MIPS64 specific opcodes */
13598    case OPC_DSLL:
13599    case OPC_DSRA:
13600    case OPC_DSLL32:
13601    case OPC_DSRA32:
13602        check_insn(ctx, ISA_MIPS3);
13603        check_mips_64(ctx);
13604        gen_shift_imm(ctx, op1, rd, rt, sa);
13605        break;
13606    case OPC_DSRL:
13607        switch ((ctx->opcode >> 21) & 0x1f) {
13608        case 1:
13609            /* drotr is decoded as dsrl on non-R2 CPUs */
13610            if (ctx->insn_flags & ISA_MIPS_R2) {
13611                op1 = OPC_DROTR;
13612            }
13613            /* Fallthrough */
13614        case 0:
13615            check_insn(ctx, ISA_MIPS3);
13616            check_mips_64(ctx);
13617            gen_shift_imm(ctx, op1, rd, rt, sa);
13618            break;
13619        default:
13620            gen_reserved_instruction(ctx);
13621            break;
13622        }
13623        break;
13624    case OPC_DSRL32:
13625        switch ((ctx->opcode >> 21) & 0x1f) {
13626        case 1:
13627            /* drotr32 is decoded as dsrl32 on non-R2 CPUs */
13628            if (ctx->insn_flags & ISA_MIPS_R2) {
13629                op1 = OPC_DROTR32;
13630            }
13631            /* Fallthrough */
13632        case 0:
13633            check_insn(ctx, ISA_MIPS3);
13634            check_mips_64(ctx);
13635            gen_shift_imm(ctx, op1, rd, rt, sa);
13636            break;
13637        default:
13638            gen_reserved_instruction(ctx);
13639            break;
13640        }
13641        break;
13642    case OPC_DADD:
13643    case OPC_DADDU:
13644    case OPC_DSUB:
13645    case OPC_DSUBU:
13646        check_insn(ctx, ISA_MIPS3);
13647        check_mips_64(ctx);
13648        gen_arith(ctx, op1, rd, rs, rt);
13649        break;
13650    case OPC_DSLLV:
13651    case OPC_DSRAV:
13652        check_insn(ctx, ISA_MIPS3);
13653        check_mips_64(ctx);
13654        gen_shift(ctx, op1, rd, rs, rt);
13655        break;
13656    case OPC_DSRLV:
13657        switch ((ctx->opcode >> 6) & 0x1f) {
13658        case 1:
13659            /* drotrv is decoded as dsrlv on non-R2 CPUs */
13660            if (ctx->insn_flags & ISA_MIPS_R2) {
13661                op1 = OPC_DROTRV;
13662            }
13663            /* Fallthrough */
13664        case 0:
13665            check_insn(ctx, ISA_MIPS3);
13666            check_mips_64(ctx);
13667            gen_shift(ctx, op1, rd, rs, rt);
13668            break;
13669        default:
13670            gen_reserved_instruction(ctx);
13671            break;
13672        }
13673        break;
13674#endif
13675    default:
13676        if (ctx->insn_flags & ISA_MIPS_R6) {
13677            decode_opc_special_r6(env, ctx);
13678        } else if (ctx->insn_flags & INSN_R5900) {
13679            decode_opc_special_tx79(env, ctx);
13680        } else {
13681            decode_opc_special_legacy(env, ctx);
13682        }
13683    }
13684}
13685
13686
13687static void decode_opc_special2_legacy(CPUMIPSState *env, DisasContext *ctx)
13688{
13689    int rs, rt, rd;
13690    uint32_t op1;
13691
13692    rs = (ctx->opcode >> 21) & 0x1f;
13693    rt = (ctx->opcode >> 16) & 0x1f;
13694    rd = (ctx->opcode >> 11) & 0x1f;
13695
13696    op1 = MASK_SPECIAL2(ctx->opcode);
13697    switch (op1) {
13698    case OPC_MADD: /* Multiply and add/sub */
13699    case OPC_MADDU:
13700    case OPC_MSUB:
13701    case OPC_MSUBU:
13702        check_insn(ctx, ISA_MIPS_R1);
13703        gen_muldiv(ctx, op1, rd & 3, rs, rt);
13704        break;
13705    case OPC_MUL:
13706        gen_arith(ctx, op1, rd, rs, rt);
13707        break;
13708    case OPC_DIV_G_2F:
13709    case OPC_DIVU_G_2F:
13710    case OPC_MULT_G_2F:
13711    case OPC_MULTU_G_2F:
13712    case OPC_MOD_G_2F:
13713    case OPC_MODU_G_2F:
13714        check_insn(ctx, INSN_LOONGSON2F | ASE_LEXT);
13715        gen_loongson_integer(ctx, op1, rd, rs, rt);
13716        break;
13717    case OPC_CLO:
13718    case OPC_CLZ:
13719        check_insn(ctx, ISA_MIPS_R1);
13720        gen_cl(ctx, op1, rd, rs);
13721        break;
13722    case OPC_SDBBP:
13723        if (is_uhi(ctx, extract32(ctx->opcode, 6, 20))) {
13724            ctx->base.is_jmp = DISAS_SEMIHOST;
13725        } else {
13726            /*
13727             * XXX: not clear which exception should be raised
13728             *      when in debug mode...
13729             */
13730            check_insn(ctx, ISA_MIPS_R1);
13731            generate_exception_end(ctx, EXCP_DBp);
13732        }
13733        break;
13734#if defined(TARGET_MIPS64)
13735    case OPC_DCLO:
13736    case OPC_DCLZ:
13737        check_insn(ctx, ISA_MIPS_R1);
13738        check_mips_64(ctx);
13739        gen_cl(ctx, op1, rd, rs);
13740        break;
13741    case OPC_DMULT_G_2F:
13742    case OPC_DMULTU_G_2F:
13743    case OPC_DDIV_G_2F:
13744    case OPC_DDIVU_G_2F:
13745    case OPC_DMOD_G_2F:
13746    case OPC_DMODU_G_2F:
13747        check_insn(ctx, INSN_LOONGSON2F | ASE_LEXT);
13748        gen_loongson_integer(ctx, op1, rd, rs, rt);
13749        break;
13750#endif
13751    default:            /* Invalid */
13752        MIPS_INVAL("special2_legacy");
13753        gen_reserved_instruction(ctx);
13754        break;
13755    }
13756}
13757
13758static void decode_opc_special3_r6(CPUMIPSState *env, DisasContext *ctx)
13759{
13760    int rs, rt, rd, sa;
13761    uint32_t op1, op2;
13762    int16_t imm;
13763
13764    rs = (ctx->opcode >> 21) & 0x1f;
13765    rt = (ctx->opcode >> 16) & 0x1f;
13766    rd = (ctx->opcode >> 11) & 0x1f;
13767    sa = (ctx->opcode >> 6) & 0x1f;
13768    imm = (int16_t)ctx->opcode >> 7;
13769
13770    op1 = MASK_SPECIAL3(ctx->opcode);
13771    switch (op1) {
13772    case R6_OPC_PREF:
13773        if (rt >= 24) {
13774            /* hint codes 24-31 are reserved and signal RI */
13775            gen_reserved_instruction(ctx);
13776        }
13777        /* Treat as NOP. */
13778        break;
13779    case R6_OPC_CACHE:
13780        check_cp0_enabled(ctx);
13781        if (ctx->hflags & MIPS_HFLAG_ITC_CACHE) {
13782            gen_cache_operation(ctx, rt, rs, imm);
13783        }
13784        break;
13785    case R6_OPC_SC:
13786        gen_st_cond(ctx, rt, rs, imm, MO_TESL, false);
13787        break;
13788    case R6_OPC_LL:
13789        gen_ld(ctx, op1, rt, rs, imm);
13790        break;
13791    case OPC_BSHFL:
13792        {
13793            if (rd == 0) {
13794                /* Treat as NOP. */
13795                break;
13796            }
13797            op2 = MASK_BSHFL(ctx->opcode);
13798            switch (op2) {
13799            case OPC_ALIGN:
13800            case OPC_ALIGN_1:
13801            case OPC_ALIGN_2:
13802            case OPC_ALIGN_3:
13803                gen_align(ctx, 32, rd, rs, rt, sa & 3);
13804                break;
13805            case OPC_BITSWAP:
13806                gen_bitswap(ctx, op2, rd, rt);
13807                break;
13808            }
13809        }
13810        break;
13811#ifndef CONFIG_USER_ONLY
13812    case OPC_GINV:
13813        if (unlikely(ctx->gi <= 1)) {
13814            gen_reserved_instruction(ctx);
13815        }
13816        check_cp0_enabled(ctx);
13817        switch ((ctx->opcode >> 6) & 3) {
13818        case 0:    /* GINVI */
13819            /* Treat as NOP. */
13820            break;
13821        case 2:    /* GINVT */
13822            gen_helper_0e1i(ginvt, cpu_gpr[rs], extract32(ctx->opcode, 8, 2));
13823            break;
13824        default:
13825            gen_reserved_instruction(ctx);
13826            break;
13827        }
13828        break;
13829#endif
13830#if defined(TARGET_MIPS64)
13831    case R6_OPC_SCD:
13832        gen_st_cond(ctx, rt, rs, imm, MO_TEUQ, false);
13833        break;
13834    case R6_OPC_LLD:
13835        gen_ld(ctx, op1, rt, rs, imm);
13836        break;
13837    case OPC_DBSHFL:
13838        check_mips_64(ctx);
13839        {
13840            if (rd == 0) {
13841                /* Treat as NOP. */
13842                break;
13843            }
13844            op2 = MASK_DBSHFL(ctx->opcode);
13845            switch (op2) {
13846            case OPC_DALIGN:
13847            case OPC_DALIGN_1:
13848            case OPC_DALIGN_2:
13849            case OPC_DALIGN_3:
13850            case OPC_DALIGN_4:
13851            case OPC_DALIGN_5:
13852            case OPC_DALIGN_6:
13853            case OPC_DALIGN_7:
13854                gen_align(ctx, 64, rd, rs, rt, sa & 7);
13855                break;
13856            case OPC_DBITSWAP:
13857                gen_bitswap(ctx, op2, rd, rt);
13858                break;
13859            }
13860
13861        }
13862        break;
13863#endif
13864    default:            /* Invalid */
13865        MIPS_INVAL("special3_r6");
13866        gen_reserved_instruction(ctx);
13867        break;
13868    }
13869}
13870
13871static void decode_opc_special3_legacy(CPUMIPSState *env, DisasContext *ctx)
13872{
13873    int rs, rt, rd;
13874    uint32_t op1, op2;
13875
13876    rs = (ctx->opcode >> 21) & 0x1f;
13877    rt = (ctx->opcode >> 16) & 0x1f;
13878    rd = (ctx->opcode >> 11) & 0x1f;
13879
13880    op1 = MASK_SPECIAL3(ctx->opcode);
13881    switch (op1) {
13882    case OPC_DIV_G_2E:
13883    case OPC_DIVU_G_2E:
13884    case OPC_MOD_G_2E:
13885    case OPC_MODU_G_2E:
13886    case OPC_MULT_G_2E:
13887    case OPC_MULTU_G_2E:
13888        /*
13889         * OPC_MULT_G_2E, OPC_ADDUH_QB_DSP, OPC_MUL_PH_DSP have
13890         * the same mask and op1.
13891         */
13892        if ((ctx->insn_flags & ASE_DSP_R2) && (op1 == OPC_MULT_G_2E)) {
13893            op2 = MASK_ADDUH_QB(ctx->opcode);
13894            switch (op2) {
13895            case OPC_ADDUH_QB:
13896            case OPC_ADDUH_R_QB:
13897            case OPC_ADDQH_PH:
13898            case OPC_ADDQH_R_PH:
13899            case OPC_ADDQH_W:
13900            case OPC_ADDQH_R_W:
13901            case OPC_SUBUH_QB:
13902            case OPC_SUBUH_R_QB:
13903            case OPC_SUBQH_PH:
13904            case OPC_SUBQH_R_PH:
13905            case OPC_SUBQH_W:
13906            case OPC_SUBQH_R_W:
13907                gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
13908                break;
13909            case OPC_MUL_PH:
13910            case OPC_MUL_S_PH:
13911            case OPC_MULQ_S_W:
13912            case OPC_MULQ_RS_W:
13913                gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 1);
13914                break;
13915            default:
13916                MIPS_INVAL("MASK ADDUH.QB");
13917                gen_reserved_instruction(ctx);
13918                break;
13919            }
13920        } else if (ctx->insn_flags & INSN_LOONGSON2E) {
13921            gen_loongson_integer(ctx, op1, rd, rs, rt);
13922        } else {
13923            gen_reserved_instruction(ctx);
13924        }
13925        break;
13926    case OPC_LX_DSP:
13927        op2 = MASK_LX(ctx->opcode);
13928        switch (op2) {
13929#if defined(TARGET_MIPS64)
13930        case OPC_LDX:
13931#endif
13932        case OPC_LBUX:
13933        case OPC_LHX:
13934        case OPC_LWX:
13935            gen_mips_lx(ctx, op2, rd, rs, rt);
13936            break;
13937        default:            /* Invalid */
13938            MIPS_INVAL("MASK LX");
13939            gen_reserved_instruction(ctx);
13940            break;
13941        }
13942        break;
13943    case OPC_ABSQ_S_PH_DSP:
13944        op2 = MASK_ABSQ_S_PH(ctx->opcode);
13945        switch (op2) {
13946        case OPC_ABSQ_S_QB:
13947        case OPC_ABSQ_S_PH:
13948        case OPC_ABSQ_S_W:
13949        case OPC_PRECEQ_W_PHL:
13950        case OPC_PRECEQ_W_PHR:
13951        case OPC_PRECEQU_PH_QBL:
13952        case OPC_PRECEQU_PH_QBR:
13953        case OPC_PRECEQU_PH_QBLA:
13954        case OPC_PRECEQU_PH_QBRA:
13955        case OPC_PRECEU_PH_QBL:
13956        case OPC_PRECEU_PH_QBR:
13957        case OPC_PRECEU_PH_QBLA:
13958        case OPC_PRECEU_PH_QBRA:
13959            gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
13960            break;
13961        case OPC_BITREV:
13962        case OPC_REPL_QB:
13963        case OPC_REPLV_QB:
13964        case OPC_REPL_PH:
13965        case OPC_REPLV_PH:
13966            gen_mipsdsp_bitinsn(ctx, op1, op2, rd, rt);
13967            break;
13968        default:
13969            MIPS_INVAL("MASK ABSQ_S.PH");
13970            gen_reserved_instruction(ctx);
13971            break;
13972        }
13973        break;
13974    case OPC_ADDU_QB_DSP:
13975        op2 = MASK_ADDU_QB(ctx->opcode);
13976        switch (op2) {
13977        case OPC_ADDQ_PH:
13978        case OPC_ADDQ_S_PH:
13979        case OPC_ADDQ_S_W:
13980        case OPC_ADDU_QB:
13981        case OPC_ADDU_S_QB:
13982        case OPC_ADDU_PH:
13983        case OPC_ADDU_S_PH:
13984        case OPC_SUBQ_PH:
13985        case OPC_SUBQ_S_PH:
13986        case OPC_SUBQ_S_W:
13987        case OPC_SUBU_QB:
13988        case OPC_SUBU_S_QB:
13989        case OPC_SUBU_PH:
13990        case OPC_SUBU_S_PH:
13991        case OPC_ADDSC:
13992        case OPC_ADDWC:
13993        case OPC_MODSUB:
13994        case OPC_RADDU_W_QB:
13995            gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
13996            break;
13997        case OPC_MULEU_S_PH_QBL:
13998        case OPC_MULEU_S_PH_QBR:
13999        case OPC_MULQ_RS_PH:
14000        case OPC_MULEQ_S_W_PHL:
14001        case OPC_MULEQ_S_W_PHR:
14002        case OPC_MULQ_S_PH:
14003            gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 1);
14004            break;
14005        default:            /* Invalid */
14006            MIPS_INVAL("MASK ADDU.QB");
14007            gen_reserved_instruction(ctx);
14008            break;
14009
14010        }
14011        break;
14012    case OPC_CMPU_EQ_QB_DSP:
14013        op2 = MASK_CMPU_EQ_QB(ctx->opcode);
14014        switch (op2) {
14015        case OPC_PRECR_SRA_PH_W:
14016        case OPC_PRECR_SRA_R_PH_W:
14017            gen_mipsdsp_arith(ctx, op1, op2, rt, rs, rd);
14018            break;
14019        case OPC_PRECR_QB_PH:
14020        case OPC_PRECRQ_QB_PH:
14021        case OPC_PRECRQ_PH_W:
14022        case OPC_PRECRQ_RS_PH_W:
14023        case OPC_PRECRQU_S_QB_PH:
14024            gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
14025            break;
14026        case OPC_CMPU_EQ_QB:
14027        case OPC_CMPU_LT_QB:
14028        case OPC_CMPU_LE_QB:
14029        case OPC_CMP_EQ_PH:
14030        case OPC_CMP_LT_PH:
14031        case OPC_CMP_LE_PH:
14032            gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 0);
14033            break;
14034        case OPC_CMPGU_EQ_QB:
14035        case OPC_CMPGU_LT_QB:
14036        case OPC_CMPGU_LE_QB:
14037        case OPC_CMPGDU_EQ_QB:
14038        case OPC_CMPGDU_LT_QB:
14039        case OPC_CMPGDU_LE_QB:
14040        case OPC_PICK_QB:
14041        case OPC_PICK_PH:
14042        case OPC_PACKRL_PH:
14043            gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 1);
14044            break;
14045        default:            /* Invalid */
14046            MIPS_INVAL("MASK CMPU.EQ.QB");
14047            gen_reserved_instruction(ctx);
14048            break;
14049        }
14050        break;
14051    case OPC_SHLL_QB_DSP:
14052        gen_mipsdsp_shift(ctx, op1, rd, rs, rt);
14053        break;
14054    case OPC_DPA_W_PH_DSP:
14055        op2 = MASK_DPA_W_PH(ctx->opcode);
14056        switch (op2) {
14057        case OPC_DPAU_H_QBL:
14058        case OPC_DPAU_H_QBR:
14059        case OPC_DPSU_H_QBL:
14060        case OPC_DPSU_H_QBR:
14061        case OPC_DPA_W_PH:
14062        case OPC_DPAX_W_PH:
14063        case OPC_DPAQ_S_W_PH:
14064        case OPC_DPAQX_S_W_PH:
14065        case OPC_DPAQX_SA_W_PH:
14066        case OPC_DPS_W_PH:
14067        case OPC_DPSX_W_PH:
14068        case OPC_DPSQ_S_W_PH:
14069        case OPC_DPSQX_S_W_PH:
14070        case OPC_DPSQX_SA_W_PH:
14071        case OPC_MULSAQ_S_W_PH:
14072        case OPC_DPAQ_SA_L_W:
14073        case OPC_DPSQ_SA_L_W:
14074        case OPC_MAQ_S_W_PHL:
14075        case OPC_MAQ_S_W_PHR:
14076        case OPC_MAQ_SA_W_PHL:
14077        case OPC_MAQ_SA_W_PHR:
14078        case OPC_MULSA_W_PH:
14079            gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 0);
14080            break;
14081        default:            /* Invalid */
14082            MIPS_INVAL("MASK DPAW.PH");
14083            gen_reserved_instruction(ctx);
14084            break;
14085        }
14086        break;
14087    case OPC_INSV_DSP:
14088        op2 = MASK_INSV(ctx->opcode);
14089        switch (op2) {
14090        case OPC_INSV:
14091            check_dsp(ctx);
14092            {
14093                TCGv t0, t1;
14094
14095                if (rt == 0) {
14096                    break;
14097                }
14098
14099                t0 = tcg_temp_new();
14100                t1 = tcg_temp_new();
14101
14102                gen_load_gpr(t0, rt);
14103                gen_load_gpr(t1, rs);
14104
14105                gen_helper_insv(cpu_gpr[rt], cpu_env, t1, t0);
14106                break;
14107            }
14108        default:            /* Invalid */
14109            MIPS_INVAL("MASK INSV");
14110            gen_reserved_instruction(ctx);
14111            break;
14112        }
14113        break;
14114    case OPC_APPEND_DSP:
14115        gen_mipsdsp_append(env, ctx, op1, rt, rs, rd);
14116        break;
14117    case OPC_EXTR_W_DSP:
14118        op2 = MASK_EXTR_W(ctx->opcode);
14119        switch (op2) {
14120        case OPC_EXTR_W:
14121        case OPC_EXTR_R_W:
14122        case OPC_EXTR_RS_W:
14123        case OPC_EXTR_S_H:
14124        case OPC_EXTRV_S_H:
14125        case OPC_EXTRV_W:
14126        case OPC_EXTRV_R_W:
14127        case OPC_EXTRV_RS_W:
14128        case OPC_EXTP:
14129        case OPC_EXTPV:
14130        case OPC_EXTPDP:
14131        case OPC_EXTPDPV:
14132            gen_mipsdsp_accinsn(ctx, op1, op2, rt, rs, rd, 1);
14133            break;
14134        case OPC_RDDSP:
14135            gen_mipsdsp_accinsn(ctx, op1, op2, rd, rs, rt, 1);
14136            break;
14137        case OPC_SHILO:
14138        case OPC_SHILOV:
14139        case OPC_MTHLIP:
14140        case OPC_WRDSP:
14141            gen_mipsdsp_accinsn(ctx, op1, op2, rd, rs, rt, 0);
14142            break;
14143        default:            /* Invalid */
14144            MIPS_INVAL("MASK EXTR.W");
14145            gen_reserved_instruction(ctx);
14146            break;
14147        }
14148        break;
14149#if defined(TARGET_MIPS64)
14150    case OPC_DDIV_G_2E:
14151    case OPC_DDIVU_G_2E:
14152    case OPC_DMULT_G_2E:
14153    case OPC_DMULTU_G_2E:
14154    case OPC_DMOD_G_2E:
14155    case OPC_DMODU_G_2E:
14156        check_insn(ctx, INSN_LOONGSON2E);
14157        gen_loongson_integer(ctx, op1, rd, rs, rt);
14158        break;
14159    case OPC_ABSQ_S_QH_DSP:
14160        op2 = MASK_ABSQ_S_QH(ctx->opcode);
14161        switch (op2) {
14162        case OPC_PRECEQ_L_PWL:
14163        case OPC_PRECEQ_L_PWR:
14164        case OPC_PRECEQ_PW_QHL:
14165        case OPC_PRECEQ_PW_QHR:
14166        case OPC_PRECEQ_PW_QHLA:
14167        case OPC_PRECEQ_PW_QHRA:
14168        case OPC_PRECEQU_QH_OBL:
14169        case OPC_PRECEQU_QH_OBR:
14170        case OPC_PRECEQU_QH_OBLA:
14171        case OPC_PRECEQU_QH_OBRA:
14172        case OPC_PRECEU_QH_OBL:
14173        case OPC_PRECEU_QH_OBR:
14174        case OPC_PRECEU_QH_OBLA:
14175        case OPC_PRECEU_QH_OBRA:
14176        case OPC_ABSQ_S_OB:
14177        case OPC_ABSQ_S_PW:
14178        case OPC_ABSQ_S_QH:
14179            gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
14180            break;
14181        case OPC_REPL_OB:
14182        case OPC_REPL_PW:
14183        case OPC_REPL_QH:
14184        case OPC_REPLV_OB:
14185        case OPC_REPLV_PW:
14186        case OPC_REPLV_QH:
14187            gen_mipsdsp_bitinsn(ctx, op1, op2, rd, rt);
14188            break;
14189        default:            /* Invalid */
14190            MIPS_INVAL("MASK ABSQ_S.QH");
14191            gen_reserved_instruction(ctx);
14192            break;
14193        }
14194        break;
14195    case OPC_ADDU_OB_DSP:
14196        op2 = MASK_ADDU_OB(ctx->opcode);
14197        switch (op2) {
14198        case OPC_RADDU_L_OB:
14199        case OPC_SUBQ_PW:
14200        case OPC_SUBQ_S_PW:
14201        case OPC_SUBQ_QH:
14202        case OPC_SUBQ_S_QH:
14203        case OPC_SUBU_OB:
14204        case OPC_SUBU_S_OB:
14205        case OPC_SUBU_QH:
14206        case OPC_SUBU_S_QH:
14207        case OPC_SUBUH_OB:
14208        case OPC_SUBUH_R_OB:
14209        case OPC_ADDQ_PW:
14210        case OPC_ADDQ_S_PW:
14211        case OPC_ADDQ_QH:
14212        case OPC_ADDQ_S_QH:
14213        case OPC_ADDU_OB:
14214        case OPC_ADDU_S_OB:
14215        case OPC_ADDU_QH:
14216        case OPC_ADDU_S_QH:
14217        case OPC_ADDUH_OB:
14218        case OPC_ADDUH_R_OB:
14219            gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
14220            break;
14221        case OPC_MULEQ_S_PW_QHL:
14222        case OPC_MULEQ_S_PW_QHR:
14223        case OPC_MULEU_S_QH_OBL:
14224        case OPC_MULEU_S_QH_OBR:
14225        case OPC_MULQ_RS_QH:
14226            gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 1);
14227            break;
14228        default:            /* Invalid */
14229            MIPS_INVAL("MASK ADDU.OB");
14230            gen_reserved_instruction(ctx);
14231            break;
14232        }
14233        break;
14234    case OPC_CMPU_EQ_OB_DSP:
14235        op2 = MASK_CMPU_EQ_OB(ctx->opcode);
14236        switch (op2) {
14237        case OPC_PRECR_SRA_QH_PW:
14238        case OPC_PRECR_SRA_R_QH_PW:
14239            /* Return value is rt. */
14240            gen_mipsdsp_arith(ctx, op1, op2, rt, rs, rd);
14241            break;
14242        case OPC_PRECR_OB_QH:
14243        case OPC_PRECRQ_OB_QH:
14244        case OPC_PRECRQ_PW_L:
14245        case OPC_PRECRQ_QH_PW:
14246        case OPC_PRECRQ_RS_QH_PW:
14247        case OPC_PRECRQU_S_OB_QH:
14248            gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
14249            break;
14250        case OPC_CMPU_EQ_OB:
14251        case OPC_CMPU_LT_OB:
14252        case OPC_CMPU_LE_OB:
14253        case OPC_CMP_EQ_QH:
14254        case OPC_CMP_LT_QH:
14255        case OPC_CMP_LE_QH:
14256        case OPC_CMP_EQ_PW:
14257        case OPC_CMP_LT_PW:
14258        case OPC_CMP_LE_PW:
14259            gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 0);
14260            break;
14261        case OPC_CMPGDU_EQ_OB:
14262        case OPC_CMPGDU_LT_OB:
14263        case OPC_CMPGDU_LE_OB:
14264        case OPC_CMPGU_EQ_OB:
14265        case OPC_CMPGU_LT_OB:
14266        case OPC_CMPGU_LE_OB:
14267        case OPC_PACKRL_PW:
14268        case OPC_PICK_OB:
14269        case OPC_PICK_PW:
14270        case OPC_PICK_QH:
14271            gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 1);
14272            break;
14273        default:            /* Invalid */
14274            MIPS_INVAL("MASK CMPU_EQ.OB");
14275            gen_reserved_instruction(ctx);
14276            break;
14277        }
14278        break;
14279    case OPC_DAPPEND_DSP:
14280        gen_mipsdsp_append(env, ctx, op1, rt, rs, rd);
14281        break;
14282    case OPC_DEXTR_W_DSP:
14283        op2 = MASK_DEXTR_W(ctx->opcode);
14284        switch (op2) {
14285        case OPC_DEXTP:
14286        case OPC_DEXTPDP:
14287        case OPC_DEXTPDPV:
14288        case OPC_DEXTPV:
14289        case OPC_DEXTR_L:
14290        case OPC_DEXTR_R_L:
14291        case OPC_DEXTR_RS_L:
14292        case OPC_DEXTR_W:
14293        case OPC_DEXTR_R_W:
14294        case OPC_DEXTR_RS_W:
14295        case OPC_DEXTR_S_H:
14296        case OPC_DEXTRV_L:
14297        case OPC_DEXTRV_R_L:
14298        case OPC_DEXTRV_RS_L:
14299        case OPC_DEXTRV_S_H:
14300        case OPC_DEXTRV_W:
14301        case OPC_DEXTRV_R_W:
14302        case OPC_DEXTRV_RS_W:
14303            gen_mipsdsp_accinsn(ctx, op1, op2, rt, rs, rd, 1);
14304            break;
14305        case OPC_DMTHLIP:
14306        case OPC_DSHILO:
14307        case OPC_DSHILOV:
14308            gen_mipsdsp_accinsn(ctx, op1, op2, rd, rs, rt, 0);
14309            break;
14310        default:            /* Invalid */
14311            MIPS_INVAL("MASK EXTR.W");
14312            gen_reserved_instruction(ctx);
14313            break;
14314        }
14315        break;
14316    case OPC_DPAQ_W_QH_DSP:
14317        op2 = MASK_DPAQ_W_QH(ctx->opcode);
14318        switch (op2) {
14319        case OPC_DPAU_H_OBL:
14320        case OPC_DPAU_H_OBR:
14321        case OPC_DPSU_H_OBL:
14322        case OPC_DPSU_H_OBR:
14323        case OPC_DPA_W_QH:
14324        case OPC_DPAQ_S_W_QH:
14325        case OPC_DPS_W_QH:
14326        case OPC_DPSQ_S_W_QH:
14327        case OPC_MULSAQ_S_W_QH:
14328        case OPC_DPAQ_SA_L_PW:
14329        case OPC_DPSQ_SA_L_PW:
14330        case OPC_MULSAQ_S_L_PW:
14331            gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 0);
14332            break;
14333        case OPC_MAQ_S_W_QHLL:
14334        case OPC_MAQ_S_W_QHLR:
14335        case OPC_MAQ_S_W_QHRL:
14336        case OPC_MAQ_S_W_QHRR:
14337        case OPC_MAQ_SA_W_QHLL:
14338        case OPC_MAQ_SA_W_QHLR:
14339        case OPC_MAQ_SA_W_QHRL:
14340        case OPC_MAQ_SA_W_QHRR:
14341        case OPC_MAQ_S_L_PWL:
14342        case OPC_MAQ_S_L_PWR:
14343        case OPC_DMADD:
14344        case OPC_DMADDU:
14345        case OPC_DMSUB:
14346        case OPC_DMSUBU:
14347            gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 0);
14348            break;
14349        default:            /* Invalid */
14350            MIPS_INVAL("MASK DPAQ.W.QH");
14351            gen_reserved_instruction(ctx);
14352            break;
14353        }
14354        break;
14355    case OPC_DINSV_DSP:
14356        op2 = MASK_INSV(ctx->opcode);
14357        switch (op2) {
14358        case OPC_DINSV:
14359        {
14360            TCGv t0, t1;
14361
14362            check_dsp(ctx);
14363
14364            if (rt == 0) {
14365                break;
14366            }
14367
14368            t0 = tcg_temp_new();
14369            t1 = tcg_temp_new();
14370
14371            gen_load_gpr(t0, rt);
14372            gen_load_gpr(t1, rs);
14373
14374            gen_helper_dinsv(cpu_gpr[rt], cpu_env, t1, t0);
14375            break;
14376        }
14377        default:            /* Invalid */
14378            MIPS_INVAL("MASK DINSV");
14379            gen_reserved_instruction(ctx);
14380            break;
14381        }
14382        break;
14383    case OPC_SHLL_OB_DSP:
14384        gen_mipsdsp_shift(ctx, op1, rd, rs, rt);
14385        break;
14386#endif
14387    default:            /* Invalid */
14388        MIPS_INVAL("special3_legacy");
14389        gen_reserved_instruction(ctx);
14390        break;
14391    }
14392}
14393
14394
14395#if defined(TARGET_MIPS64)
14396
14397static void decode_mmi(CPUMIPSState *env, DisasContext *ctx)
14398{
14399    uint32_t opc = MASK_MMI(ctx->opcode);
14400    int rs = extract32(ctx->opcode, 21, 5);
14401    int rt = extract32(ctx->opcode, 16, 5);
14402    int rd = extract32(ctx->opcode, 11, 5);
14403
14404    switch (opc) {
14405    case MMI_OPC_MULT1:
14406    case MMI_OPC_MULTU1:
14407    case MMI_OPC_MADD:
14408    case MMI_OPC_MADDU:
14409    case MMI_OPC_MADD1:
14410    case MMI_OPC_MADDU1:
14411        gen_mul_txx9(ctx, opc, rd, rs, rt);
14412        break;
14413    case MMI_OPC_DIV1:
14414    case MMI_OPC_DIVU1:
14415        gen_div1_tx79(ctx, opc, rs, rt);
14416        break;
14417    default:
14418        MIPS_INVAL("TX79 MMI class");
14419        gen_reserved_instruction(ctx);
14420        break;
14421    }
14422}
14423
14424static void gen_mmi_sq(DisasContext *ctx, int base, int rt, int offset)
14425{
14426    gen_reserved_instruction(ctx);    /* TODO: MMI_OPC_SQ */
14427}
14428
14429/*
14430 * The TX79-specific instruction Store Quadword
14431 *
14432 * +--------+-------+-------+------------------------+
14433 * | 011111 |  base |   rt  |           offset       | SQ
14434 * +--------+-------+-------+------------------------+
14435 *      6       5       5                 16
14436 *
14437 * has the same opcode as the Read Hardware Register instruction
14438 *
14439 * +--------+-------+-------+-------+-------+--------+
14440 * | 011111 | 00000 |   rt  |   rd  | 00000 | 111011 | RDHWR
14441 * +--------+-------+-------+-------+-------+--------+
14442 *      6       5       5       5       5        6
14443 *
14444 * that is required, trapped and emulated by the Linux kernel. However, all
14445 * RDHWR encodings yield address error exceptions on the TX79 since the SQ
14446 * offset is odd. Therefore all valid SQ instructions can execute normally.
14447 * In user mode, QEMU must verify the upper and lower 11 bits to distinguish
14448 * between SQ and RDHWR, as the Linux kernel does.
14449 */
14450static void decode_mmi_sq(CPUMIPSState *env, DisasContext *ctx)
14451{
14452    int base = extract32(ctx->opcode, 21, 5);
14453    int rt = extract32(ctx->opcode, 16, 5);
14454    int offset = extract32(ctx->opcode, 0, 16);
14455
14456#ifdef CONFIG_USER_ONLY
14457    uint32_t op1 = MASK_SPECIAL3(ctx->opcode);
14458    uint32_t op2 = extract32(ctx->opcode, 6, 5);
14459
14460    if (base == 0 && op2 == 0 && op1 == OPC_RDHWR) {
14461        int rd = extract32(ctx->opcode, 11, 5);
14462
14463        gen_rdhwr(ctx, rt, rd, 0);
14464        return;
14465    }
14466#endif
14467
14468    gen_mmi_sq(ctx, base, rt, offset);
14469}
14470
14471#endif
14472
14473static void decode_opc_special3(CPUMIPSState *env, DisasContext *ctx)
14474{
14475    int rs, rt, rd, sa;
14476    uint32_t op1, op2;
14477    int16_t imm;
14478
14479    rs = (ctx->opcode >> 21) & 0x1f;
14480    rt = (ctx->opcode >> 16) & 0x1f;
14481    rd = (ctx->opcode >> 11) & 0x1f;
14482    sa = (ctx->opcode >> 6) & 0x1f;
14483    imm = sextract32(ctx->opcode, 7, 9);
14484
14485    op1 = MASK_SPECIAL3(ctx->opcode);
14486
14487    /*
14488     * EVA loads and stores overlap Loongson 2E instructions decoded by
14489     * decode_opc_special3_legacy(), so be careful to allow their decoding when
14490     * EVA is absent.
14491     */
14492    if (ctx->eva) {
14493        switch (op1) {
14494        case OPC_LWLE:
14495        case OPC_LWRE:
14496        case OPC_LBUE:
14497        case OPC_LHUE:
14498        case OPC_LBE:
14499        case OPC_LHE:
14500        case OPC_LLE:
14501        case OPC_LWE:
14502            check_cp0_enabled(ctx);
14503            gen_ld(ctx, op1, rt, rs, imm);
14504            return;
14505        case OPC_SWLE:
14506        case OPC_SWRE:
14507        case OPC_SBE:
14508        case OPC_SHE:
14509        case OPC_SWE:
14510            check_cp0_enabled(ctx);
14511            gen_st(ctx, op1, rt, rs, imm);
14512            return;
14513        case OPC_SCE:
14514            check_cp0_enabled(ctx);
14515            gen_st_cond(ctx, rt, rs, imm, MO_TESL, true);
14516            return;
14517        case OPC_CACHEE:
14518            check_eva(ctx);
14519            check_cp0_enabled(ctx);
14520            if (ctx->hflags & MIPS_HFLAG_ITC_CACHE) {
14521                gen_cache_operation(ctx, rt, rs, imm);
14522            }
14523            return;
14524        case OPC_PREFE:
14525            check_cp0_enabled(ctx);
14526            /* Treat as NOP. */
14527            return;
14528        }
14529    }
14530
14531    switch (op1) {
14532    case OPC_EXT:
14533    case OPC_INS:
14534        check_insn(ctx, ISA_MIPS_R2);
14535        gen_bitops(ctx, op1, rt, rs, sa, rd);
14536        break;
14537    case OPC_BSHFL:
14538        op2 = MASK_BSHFL(ctx->opcode);
14539        switch (op2) {
14540        case OPC_ALIGN:
14541        case OPC_ALIGN_1:
14542        case OPC_ALIGN_2:
14543        case OPC_ALIGN_3:
14544        case OPC_BITSWAP:
14545            check_insn(ctx, ISA_MIPS_R6);
14546            decode_opc_special3_r6(env, ctx);
14547            break;
14548        default:
14549            check_insn(ctx, ISA_MIPS_R2);
14550            gen_bshfl(ctx, op2, rt, rd);
14551            break;
14552        }
14553        break;
14554#if defined(TARGET_MIPS64)
14555    case OPC_DEXTM:
14556    case OPC_DEXTU:
14557    case OPC_DEXT:
14558    case OPC_DINSM:
14559    case OPC_DINSU:
14560    case OPC_DINS:
14561        check_insn(ctx, ISA_MIPS_R2);
14562        check_mips_64(ctx);
14563        gen_bitops(ctx, op1, rt, rs, sa, rd);
14564        break;
14565    case OPC_DBSHFL:
14566        op2 = MASK_DBSHFL(ctx->opcode);
14567        switch (op2) {
14568        case OPC_DALIGN:
14569        case OPC_DALIGN_1:
14570        case OPC_DALIGN_2:
14571        case OPC_DALIGN_3:
14572        case OPC_DALIGN_4:
14573        case OPC_DALIGN_5:
14574        case OPC_DALIGN_6:
14575        case OPC_DALIGN_7:
14576        case OPC_DBITSWAP:
14577            check_insn(ctx, ISA_MIPS_R6);
14578            decode_opc_special3_r6(env, ctx);
14579            break;
14580        default:
14581            check_insn(ctx, ISA_MIPS_R2);
14582            check_mips_64(ctx);
14583            op2 = MASK_DBSHFL(ctx->opcode);
14584            gen_bshfl(ctx, op2, rt, rd);
14585            break;
14586        }
14587        break;
14588#endif
14589    case OPC_RDHWR:
14590        gen_rdhwr(ctx, rt, rd, extract32(ctx->opcode, 6, 3));
14591        break;
14592    case OPC_FORK:
14593        check_mt(ctx);
14594        {
14595            TCGv t0 = tcg_temp_new();
14596            TCGv t1 = tcg_temp_new();
14597
14598            gen_load_gpr(t0, rt);
14599            gen_load_gpr(t1, rs);
14600            gen_helper_fork(t0, t1);
14601        }
14602        break;
14603    case OPC_YIELD:
14604        check_mt(ctx);
14605        {
14606            TCGv t0 = tcg_temp_new();
14607
14608            gen_load_gpr(t0, rs);
14609            gen_helper_yield(t0, cpu_env, t0);
14610            gen_store_gpr(t0, rd);
14611        }
14612        break;
14613    default:
14614        if (ctx->insn_flags & ISA_MIPS_R6) {
14615            decode_opc_special3_r6(env, ctx);
14616        } else {
14617            decode_opc_special3_legacy(env, ctx);
14618        }
14619    }
14620}
14621
14622static bool decode_opc_legacy(CPUMIPSState *env, DisasContext *ctx)
14623{
14624    int32_t offset;
14625    int rs, rt, rd, sa;
14626    uint32_t op, op1;
14627    int16_t imm;
14628
14629    op = MASK_OP_MAJOR(ctx->opcode);
14630    rs = (ctx->opcode >> 21) & 0x1f;
14631    rt = (ctx->opcode >> 16) & 0x1f;
14632    rd = (ctx->opcode >> 11) & 0x1f;
14633    sa = (ctx->opcode >> 6) & 0x1f;
14634    imm = (int16_t)ctx->opcode;
14635    switch (op) {
14636    case OPC_SPECIAL:
14637        decode_opc_special(env, ctx);
14638        break;
14639    case OPC_SPECIAL2:
14640#if defined(TARGET_MIPS64)
14641        if ((ctx->insn_flags & INSN_R5900) && (ctx->insn_flags & ASE_MMI)) {
14642            decode_mmi(env, ctx);
14643            break;
14644        }
14645#endif
14646        if (TARGET_LONG_BITS == 32 && (ctx->insn_flags & ASE_MXU)) {
14647            if (decode_ase_mxu(ctx, ctx->opcode)) {
14648                break;
14649            }
14650        }
14651        decode_opc_special2_legacy(env, ctx);
14652        break;
14653    case OPC_SPECIAL3:
14654#if defined(TARGET_MIPS64)
14655        if (ctx->insn_flags & INSN_R5900) {
14656            decode_mmi_sq(env, ctx);    /* MMI_OPC_SQ */
14657        } else {
14658            decode_opc_special3(env, ctx);
14659        }
14660#else
14661        decode_opc_special3(env, ctx);
14662#endif
14663        break;
14664    case OPC_REGIMM:
14665        op1 = MASK_REGIMM(ctx->opcode);
14666        switch (op1) {
14667        case OPC_BLTZL: /* REGIMM branches */
14668        case OPC_BGEZL:
14669        case OPC_BLTZALL:
14670        case OPC_BGEZALL:
14671            check_insn(ctx, ISA_MIPS2);
14672            check_insn_opc_removed(ctx, ISA_MIPS_R6);
14673            /* Fallthrough */
14674        case OPC_BLTZ:
14675        case OPC_BGEZ:
14676            gen_compute_branch(ctx, op1, 4, rs, -1, imm << 2, 4);
14677            break;
14678        case OPC_BLTZAL:
14679        case OPC_BGEZAL:
14680            if (ctx->insn_flags & ISA_MIPS_R6) {
14681                if (rs == 0) {
14682                    /* OPC_NAL, OPC_BAL */
14683                    gen_compute_branch(ctx, op1, 4, 0, -1, imm << 2, 4);
14684                } else {
14685                    gen_reserved_instruction(ctx);
14686                }
14687            } else {
14688                gen_compute_branch(ctx, op1, 4, rs, -1, imm << 2, 4);
14689            }
14690            break;
14691        case OPC_TGEI: /* REGIMM traps */
14692        case OPC_TGEIU:
14693        case OPC_TLTI:
14694        case OPC_TLTIU:
14695        case OPC_TEQI:
14696        case OPC_TNEI:
14697            check_insn(ctx, ISA_MIPS2);
14698            check_insn_opc_removed(ctx, ISA_MIPS_R6);
14699            gen_trap(ctx, op1, rs, -1, imm, 0);
14700            break;
14701        case OPC_SIGRIE:
14702            check_insn(ctx, ISA_MIPS_R6);
14703            gen_reserved_instruction(ctx);
14704            break;
14705        case OPC_SYNCI:
14706            check_insn(ctx, ISA_MIPS_R2);
14707            /*
14708             * Break the TB to be able to sync copied instructions
14709             * immediately.
14710             */
14711            ctx->base.is_jmp = DISAS_STOP;
14712            break;
14713        case OPC_BPOSGE32:    /* MIPS DSP branch */
14714#if defined(TARGET_MIPS64)
14715        case OPC_BPOSGE64:
14716#endif
14717            check_dsp(ctx);
14718            gen_compute_branch(ctx, op1, 4, -1, -2, (int32_t)imm << 2, 4);
14719            break;
14720#if defined(TARGET_MIPS64)
14721        case OPC_DAHI:
14722            check_insn(ctx, ISA_MIPS_R6);
14723            check_mips_64(ctx);
14724            if (rs != 0) {
14725                tcg_gen_addi_tl(cpu_gpr[rs], cpu_gpr[rs], (int64_t)imm << 32);
14726            }
14727            break;
14728        case OPC_DATI:
14729            check_insn(ctx, ISA_MIPS_R6);
14730            check_mips_64(ctx);
14731            if (rs != 0) {
14732                tcg_gen_addi_tl(cpu_gpr[rs], cpu_gpr[rs], (int64_t)imm << 48);
14733            }
14734            break;
14735#endif
14736        default:            /* Invalid */
14737            MIPS_INVAL("regimm");
14738            gen_reserved_instruction(ctx);
14739            break;
14740        }
14741        break;
14742    case OPC_CP0:
14743        check_cp0_enabled(ctx);
14744        op1 = MASK_CP0(ctx->opcode);
14745        switch (op1) {
14746        case OPC_MFC0:
14747        case OPC_MTC0:
14748        case OPC_MFTR:
14749        case OPC_MTTR:
14750        case OPC_MFHC0:
14751        case OPC_MTHC0:
14752#if defined(TARGET_MIPS64)
14753        case OPC_DMFC0:
14754        case OPC_DMTC0:
14755#endif
14756#ifndef CONFIG_USER_ONLY
14757            gen_cp0(env, ctx, op1, rt, rd);
14758#endif /* !CONFIG_USER_ONLY */
14759            break;
14760        case OPC_C0:
14761        case OPC_C0_1:
14762        case OPC_C0_2:
14763        case OPC_C0_3:
14764        case OPC_C0_4:
14765        case OPC_C0_5:
14766        case OPC_C0_6:
14767        case OPC_C0_7:
14768        case OPC_C0_8:
14769        case OPC_C0_9:
14770        case OPC_C0_A:
14771        case OPC_C0_B:
14772        case OPC_C0_C:
14773        case OPC_C0_D:
14774        case OPC_C0_E:
14775        case OPC_C0_F:
14776#ifndef CONFIG_USER_ONLY
14777            gen_cp0(env, ctx, MASK_C0(ctx->opcode), rt, rd);
14778#endif /* !CONFIG_USER_ONLY */
14779            break;
14780        case OPC_MFMC0:
14781#ifndef CONFIG_USER_ONLY
14782            {
14783                uint32_t op2;
14784                TCGv t0 = tcg_temp_new();
14785
14786                op2 = MASK_MFMC0(ctx->opcode);
14787                switch (op2) {
14788                case OPC_DMT:
14789                    check_cp0_mt(ctx);
14790                    gen_helper_dmt(t0);
14791                    gen_store_gpr(t0, rt);
14792                    break;
14793                case OPC_EMT:
14794                    check_cp0_mt(ctx);
14795                    gen_helper_emt(t0);
14796                    gen_store_gpr(t0, rt);
14797                    break;
14798                case OPC_DVPE:
14799                    check_cp0_mt(ctx);
14800                    gen_helper_dvpe(t0, cpu_env);
14801                    gen_store_gpr(t0, rt);
14802                    break;
14803                case OPC_EVPE:
14804                    check_cp0_mt(ctx);
14805                    gen_helper_evpe(t0, cpu_env);
14806                    gen_store_gpr(t0, rt);
14807                    break;
14808                case OPC_DVP:
14809                    check_insn(ctx, ISA_MIPS_R6);
14810                    if (ctx->vp) {
14811                        gen_helper_dvp(t0, cpu_env);
14812                        gen_store_gpr(t0, rt);
14813                    }
14814                    break;
14815                case OPC_EVP:
14816                    check_insn(ctx, ISA_MIPS_R6);
14817                    if (ctx->vp) {
14818                        gen_helper_evp(t0, cpu_env);
14819                        gen_store_gpr(t0, rt);
14820                    }
14821                    break;
14822                case OPC_DI:
14823                    check_insn(ctx, ISA_MIPS_R2);
14824                    save_cpu_state(ctx, 1);
14825                    gen_helper_di(t0, cpu_env);
14826                    gen_store_gpr(t0, rt);
14827                    /*
14828                     * Stop translation as we may have switched
14829                     * the execution mode.
14830                     */
14831                    ctx->base.is_jmp = DISAS_STOP;
14832                    break;
14833                case OPC_EI:
14834                    check_insn(ctx, ISA_MIPS_R2);
14835                    save_cpu_state(ctx, 1);
14836                    gen_helper_ei(t0, cpu_env);
14837                    gen_store_gpr(t0, rt);
14838                    /*
14839                     * DISAS_STOP isn't sufficient, we need to ensure we break
14840                     * out of translated code to check for pending interrupts.
14841                     */
14842                    gen_save_pc(ctx->base.pc_next + 4);
14843                    ctx->base.is_jmp = DISAS_EXIT;
14844                    break;
14845                default:            /* Invalid */
14846                    MIPS_INVAL("mfmc0");
14847                    gen_reserved_instruction(ctx);
14848                    break;
14849                }
14850            }
14851#endif /* !CONFIG_USER_ONLY */
14852            break;
14853        case OPC_RDPGPR:
14854            check_insn(ctx, ISA_MIPS_R2);
14855            gen_load_srsgpr(rt, rd);
14856            break;
14857        case OPC_WRPGPR:
14858            check_insn(ctx, ISA_MIPS_R2);
14859            gen_store_srsgpr(rt, rd);
14860            break;
14861        default:
14862            MIPS_INVAL("cp0");
14863            gen_reserved_instruction(ctx);
14864            break;
14865        }
14866        break;
14867    case OPC_BOVC: /* OPC_BEQZALC, OPC_BEQC, OPC_ADDI */
14868        if (ctx->insn_flags & ISA_MIPS_R6) {
14869            /* OPC_BOVC, OPC_BEQZALC, OPC_BEQC */
14870            gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
14871        } else {
14872            /* OPC_ADDI */
14873            /* Arithmetic with immediate opcode */
14874            gen_arith_imm(ctx, op, rt, rs, imm);
14875        }
14876        break;
14877    case OPC_ADDIU:
14878         gen_arith_imm(ctx, op, rt, rs, imm);
14879         break;
14880    case OPC_SLTI: /* Set on less than with immediate opcode */
14881    case OPC_SLTIU:
14882         gen_slt_imm(ctx, op, rt, rs, imm);
14883         break;
14884    case OPC_ANDI: /* Arithmetic with immediate opcode */
14885    case OPC_LUI: /* OPC_AUI */
14886    case OPC_ORI:
14887    case OPC_XORI:
14888         gen_logic_imm(ctx, op, rt, rs, imm);
14889         break;
14890    case OPC_J: /* Jump */
14891    case OPC_JAL:
14892         offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 2;
14893         gen_compute_branch(ctx, op, 4, rs, rt, offset, 4);
14894         break;
14895    /* Branch */
14896    case OPC_BLEZC: /* OPC_BGEZC, OPC_BGEC, OPC_BLEZL */
14897        if (ctx->insn_flags & ISA_MIPS_R6) {
14898            if (rt == 0) {
14899                gen_reserved_instruction(ctx);
14900                break;
14901            }
14902            /* OPC_BLEZC, OPC_BGEZC, OPC_BGEC */
14903            gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
14904        } else {
14905            /* OPC_BLEZL */
14906            gen_compute_branch(ctx, op, 4, rs, rt, imm << 2, 4);
14907        }
14908        break;
14909    case OPC_BGTZC: /* OPC_BLTZC, OPC_BLTC, OPC_BGTZL */
14910        if (ctx->insn_flags & ISA_MIPS_R6) {
14911            if (rt == 0) {
14912                gen_reserved_instruction(ctx);
14913                break;
14914            }
14915            /* OPC_BGTZC, OPC_BLTZC, OPC_BLTC */
14916            gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
14917        } else {
14918            /* OPC_BGTZL */
14919            gen_compute_branch(ctx, op, 4, rs, rt, imm << 2, 4);
14920        }
14921        break;
14922    case OPC_BLEZALC: /* OPC_BGEZALC, OPC_BGEUC, OPC_BLEZ */
14923        if (rt == 0) {
14924            /* OPC_BLEZ */
14925            gen_compute_branch(ctx, op, 4, rs, rt, imm << 2, 4);
14926        } else {
14927            check_insn(ctx, ISA_MIPS_R6);
14928            /* OPC_BLEZALC, OPC_BGEZALC, OPC_BGEUC */
14929            gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
14930        }
14931        break;
14932    case OPC_BGTZALC: /* OPC_BLTZALC, OPC_BLTUC, OPC_BGTZ */
14933        if (rt == 0) {
14934            /* OPC_BGTZ */
14935            gen_compute_branch(ctx, op, 4, rs, rt, imm << 2, 4);
14936        } else {
14937            check_insn(ctx, ISA_MIPS_R6);
14938            /* OPC_BGTZALC, OPC_BLTZALC, OPC_BLTUC */
14939            gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
14940        }
14941        break;
14942    case OPC_BEQL:
14943    case OPC_BNEL:
14944        check_insn(ctx, ISA_MIPS2);
14945         check_insn_opc_removed(ctx, ISA_MIPS_R6);
14946        /* Fallthrough */
14947    case OPC_BEQ:
14948    case OPC_BNE:
14949         gen_compute_branch(ctx, op, 4, rs, rt, imm << 2, 4);
14950         break;
14951    case OPC_LL: /* Load and stores */
14952        check_insn(ctx, ISA_MIPS2);
14953        if (ctx->insn_flags & INSN_R5900) {
14954            check_insn_opc_user_only(ctx, INSN_R5900);
14955        }
14956        /* Fallthrough */
14957    case OPC_LWL:
14958    case OPC_LWR:
14959    case OPC_LB:
14960    case OPC_LH:
14961    case OPC_LW:
14962    case OPC_LWPC:
14963    case OPC_LBU:
14964    case OPC_LHU:
14965         gen_ld(ctx, op, rt, rs, imm);
14966         break;
14967    case OPC_SWL:
14968    case OPC_SWR:
14969    case OPC_SB:
14970    case OPC_SH:
14971    case OPC_SW:
14972         gen_st(ctx, op, rt, rs, imm);
14973         break;
14974    case OPC_SC:
14975        check_insn(ctx, ISA_MIPS2);
14976        if (ctx->insn_flags & INSN_R5900) {
14977            check_insn_opc_user_only(ctx, INSN_R5900);
14978        }
14979        gen_st_cond(ctx, rt, rs, imm, MO_TESL, false);
14980        break;
14981    case OPC_CACHE:
14982        check_cp0_enabled(ctx);
14983        check_insn(ctx, ISA_MIPS3 | ISA_MIPS_R1);
14984        if (ctx->hflags & MIPS_HFLAG_ITC_CACHE) {
14985            gen_cache_operation(ctx, rt, rs, imm);
14986        }
14987        /* Treat as NOP. */
14988        break;
14989    case OPC_PREF:
14990        check_insn(ctx, ISA_MIPS4 | ISA_MIPS_R1 | INSN_R5900);
14991        /* Treat as NOP. */
14992        break;
14993
14994    /* Floating point (COP1). */
14995    case OPC_LWC1:
14996    case OPC_LDC1:
14997    case OPC_SWC1:
14998    case OPC_SDC1:
14999        gen_cop1_ldst(ctx, op, rt, rs, imm);
15000        break;
15001
15002    case OPC_CP1:
15003        op1 = MASK_CP1(ctx->opcode);
15004
15005        switch (op1) {
15006        case OPC_MFHC1:
15007        case OPC_MTHC1:
15008            check_cp1_enabled(ctx);
15009            check_insn(ctx, ISA_MIPS_R2);
15010            /* fall through */
15011        case OPC_MFC1:
15012        case OPC_CFC1:
15013        case OPC_MTC1:
15014        case OPC_CTC1:
15015            check_cp1_enabled(ctx);
15016            gen_cp1(ctx, op1, rt, rd);
15017            break;
15018#if defined(TARGET_MIPS64)
15019        case OPC_DMFC1:
15020        case OPC_DMTC1:
15021            check_cp1_enabled(ctx);
15022            check_insn(ctx, ISA_MIPS3);
15023            check_mips_64(ctx);
15024            gen_cp1(ctx, op1, rt, rd);
15025            break;
15026#endif
15027        case OPC_BC1EQZ: /* OPC_BC1ANY2 */
15028            check_cp1_enabled(ctx);
15029            if (ctx->insn_flags & ISA_MIPS_R6) {
15030                /* OPC_BC1EQZ */
15031                gen_compute_branch1_r6(ctx, MASK_CP1(ctx->opcode),
15032                                       rt, imm << 2, 4);
15033            } else {
15034                /* OPC_BC1ANY2 */
15035                check_cop1x(ctx);
15036                check_insn(ctx, ASE_MIPS3D);
15037                gen_compute_branch1(ctx, MASK_BC1(ctx->opcode),
15038                                    (rt >> 2) & 0x7, imm << 2);
15039            }
15040            break;
15041        case OPC_BC1NEZ:
15042            check_cp1_enabled(ctx);
15043            check_insn(ctx, ISA_MIPS_R6);
15044            gen_compute_branch1_r6(ctx, MASK_CP1(ctx->opcode),
15045                                   rt, imm << 2, 4);
15046            break;
15047        case OPC_BC1ANY4:
15048            check_cp1_enabled(ctx);
15049            check_insn_opc_removed(ctx, ISA_MIPS_R6);
15050            check_cop1x(ctx);
15051            check_insn(ctx, ASE_MIPS3D);
15052            /* fall through */
15053        case OPC_BC1:
15054            check_cp1_enabled(ctx);
15055            check_insn_opc_removed(ctx, ISA_MIPS_R6);
15056            gen_compute_branch1(ctx, MASK_BC1(ctx->opcode),
15057                                (rt >> 2) & 0x7, imm << 2);
15058            break;
15059        case OPC_PS_FMT:
15060            check_ps(ctx);
15061            /* fall through */
15062        case OPC_S_FMT:
15063        case OPC_D_FMT:
15064            check_cp1_enabled(ctx);
15065            gen_farith(ctx, ctx->opcode & FOP(0x3f, 0x1f), rt, rd, sa,
15066                       (imm >> 8) & 0x7);
15067            break;
15068        case OPC_W_FMT:
15069        case OPC_L_FMT:
15070        {
15071            int r6_op = ctx->opcode & FOP(0x3f, 0x1f);
15072            check_cp1_enabled(ctx);
15073            if (ctx->insn_flags & ISA_MIPS_R6) {
15074                switch (r6_op) {
15075                case R6_OPC_CMP_AF_S:
15076                case R6_OPC_CMP_UN_S:
15077                case R6_OPC_CMP_EQ_S:
15078                case R6_OPC_CMP_UEQ_S:
15079                case R6_OPC_CMP_LT_S:
15080                case R6_OPC_CMP_ULT_S:
15081                case R6_OPC_CMP_LE_S:
15082                case R6_OPC_CMP_ULE_S:
15083                case R6_OPC_CMP_SAF_S:
15084                case R6_OPC_CMP_SUN_S:
15085                case R6_OPC_CMP_SEQ_S:
15086                case R6_OPC_CMP_SEUQ_S:
15087                case R6_OPC_CMP_SLT_S:
15088                case R6_OPC_CMP_SULT_S:
15089                case R6_OPC_CMP_SLE_S:
15090                case R6_OPC_CMP_SULE_S:
15091                case R6_OPC_CMP_OR_S:
15092                case R6_OPC_CMP_UNE_S:
15093                case R6_OPC_CMP_NE_S:
15094                case R6_OPC_CMP_SOR_S:
15095                case R6_OPC_CMP_SUNE_S:
15096                case R6_OPC_CMP_SNE_S:
15097                    gen_r6_cmp_s(ctx, ctx->opcode & 0x1f, rt, rd, sa);
15098                    break;
15099                case R6_OPC_CMP_AF_D:
15100                case R6_OPC_CMP_UN_D:
15101                case R6_OPC_CMP_EQ_D:
15102                case R6_OPC_CMP_UEQ_D:
15103                case R6_OPC_CMP_LT_D:
15104                case R6_OPC_CMP_ULT_D:
15105                case R6_OPC_CMP_LE_D:
15106                case R6_OPC_CMP_ULE_D:
15107                case R6_OPC_CMP_SAF_D:
15108                case R6_OPC_CMP_SUN_D:
15109                case R6_OPC_CMP_SEQ_D:
15110                case R6_OPC_CMP_SEUQ_D:
15111                case R6_OPC_CMP_SLT_D:
15112                case R6_OPC_CMP_SULT_D:
15113                case R6_OPC_CMP_SLE_D:
15114                case R6_OPC_CMP_SULE_D:
15115                case R6_OPC_CMP_OR_D:
15116                case R6_OPC_CMP_UNE_D:
15117                case R6_OPC_CMP_NE_D:
15118                case R6_OPC_CMP_SOR_D:
15119                case R6_OPC_CMP_SUNE_D:
15120                case R6_OPC_CMP_SNE_D:
15121                    gen_r6_cmp_d(ctx, ctx->opcode & 0x1f, rt, rd, sa);
15122                    break;
15123                default:
15124                    gen_farith(ctx, ctx->opcode & FOP(0x3f, 0x1f),
15125                               rt, rd, sa, (imm >> 8) & 0x7);
15126
15127                    break;
15128                }
15129            } else {
15130                gen_farith(ctx, ctx->opcode & FOP(0x3f, 0x1f), rt, rd, sa,
15131                           (imm >> 8) & 0x7);
15132            }
15133            break;
15134        }
15135        default:
15136            MIPS_INVAL("cp1");
15137            gen_reserved_instruction(ctx);
15138            break;
15139        }
15140        break;
15141
15142    /* Compact branches [R6] and COP2 [non-R6] */
15143    case OPC_BC: /* OPC_LWC2 */
15144    case OPC_BALC: /* OPC_SWC2 */
15145        if (ctx->insn_flags & ISA_MIPS_R6) {
15146            /* OPC_BC, OPC_BALC */
15147            gen_compute_compact_branch(ctx, op, 0, 0,
15148                                       sextract32(ctx->opcode << 2, 0, 28));
15149        } else if (ctx->insn_flags & ASE_LEXT) {
15150            gen_loongson_lswc2(ctx, rt, rs, rd);
15151        } else {
15152            /* OPC_LWC2, OPC_SWC2 */
15153            /* COP2: Not implemented. */
15154            generate_exception_err(ctx, EXCP_CpU, 2);
15155        }
15156        break;
15157    case OPC_BEQZC: /* OPC_JIC, OPC_LDC2 */
15158    case OPC_BNEZC: /* OPC_JIALC, OPC_SDC2 */
15159        if (ctx->insn_flags & ISA_MIPS_R6) {
15160            if (rs != 0) {
15161                /* OPC_BEQZC, OPC_BNEZC */
15162                gen_compute_compact_branch(ctx, op, rs, 0,
15163                                           sextract32(ctx->opcode << 2, 0, 23));
15164            } else {
15165                /* OPC_JIC, OPC_JIALC */
15166                gen_compute_compact_branch(ctx, op, 0, rt, imm);
15167            }
15168        } else if (ctx->insn_flags & ASE_LEXT) {
15169            gen_loongson_lsdc2(ctx, rt, rs, rd);
15170        } else {
15171            /* OPC_LWC2, OPC_SWC2 */
15172            /* COP2: Not implemented. */
15173            generate_exception_err(ctx, EXCP_CpU, 2);
15174        }
15175        break;
15176    case OPC_CP2:
15177        check_insn(ctx, ASE_LMMI);
15178        /* Note that these instructions use different fields.  */
15179        gen_loongson_multimedia(ctx, sa, rd, rt);
15180        break;
15181
15182    case OPC_CP3:
15183        if (ctx->CP0_Config1 & (1 << CP0C1_FP)) {
15184            check_cp1_enabled(ctx);
15185            op1 = MASK_CP3(ctx->opcode);
15186            switch (op1) {
15187            case OPC_LUXC1:
15188            case OPC_SUXC1:
15189                check_insn(ctx, ISA_MIPS5 | ISA_MIPS_R2);
15190                /* Fallthrough */
15191            case OPC_LWXC1:
15192            case OPC_LDXC1:
15193            case OPC_SWXC1:
15194            case OPC_SDXC1:
15195                check_insn(ctx, ISA_MIPS4 | ISA_MIPS_R2);
15196                gen_flt3_ldst(ctx, op1, sa, rd, rs, rt);
15197                break;
15198            case OPC_PREFX:
15199                check_insn(ctx, ISA_MIPS4 | ISA_MIPS_R2);
15200                /* Treat as NOP. */
15201                break;
15202            case OPC_ALNV_PS:
15203                check_insn(ctx, ISA_MIPS5 | ISA_MIPS_R2);
15204                /* Fallthrough */
15205            case OPC_MADD_S:
15206            case OPC_MADD_D:
15207            case OPC_MADD_PS:
15208            case OPC_MSUB_S:
15209            case OPC_MSUB_D:
15210            case OPC_MSUB_PS:
15211            case OPC_NMADD_S:
15212            case OPC_NMADD_D:
15213            case OPC_NMADD_PS:
15214            case OPC_NMSUB_S:
15215            case OPC_NMSUB_D:
15216            case OPC_NMSUB_PS:
15217                check_insn(ctx, ISA_MIPS4 | ISA_MIPS_R2);
15218                gen_flt3_arith(ctx, op1, sa, rs, rd, rt);
15219                break;
15220            default:
15221                MIPS_INVAL("cp3");
15222                gen_reserved_instruction(ctx);
15223                break;
15224            }
15225        } else {
15226            generate_exception_err(ctx, EXCP_CpU, 1);
15227        }
15228        break;
15229
15230#if defined(TARGET_MIPS64)
15231    /* MIPS64 opcodes */
15232    case OPC_LLD:
15233        if (ctx->insn_flags & INSN_R5900) {
15234            check_insn_opc_user_only(ctx, INSN_R5900);
15235        }
15236        /* fall through */
15237    case OPC_LDL:
15238    case OPC_LDR:
15239    case OPC_LWU:
15240    case OPC_LD:
15241        check_insn(ctx, ISA_MIPS3);
15242        check_mips_64(ctx);
15243        gen_ld(ctx, op, rt, rs, imm);
15244        break;
15245    case OPC_SDL:
15246    case OPC_SDR:
15247    case OPC_SD:
15248        check_insn(ctx, ISA_MIPS3);
15249        check_mips_64(ctx);
15250        gen_st(ctx, op, rt, rs, imm);
15251        break;
15252    case OPC_SCD:
15253        check_insn(ctx, ISA_MIPS3);
15254        if (ctx->insn_flags & INSN_R5900) {
15255            check_insn_opc_user_only(ctx, INSN_R5900);
15256        }
15257        check_mips_64(ctx);
15258        gen_st_cond(ctx, rt, rs, imm, MO_TEUQ, false);
15259        break;
15260    case OPC_BNVC: /* OPC_BNEZALC, OPC_BNEC, OPC_DADDI */
15261        if (ctx->insn_flags & ISA_MIPS_R6) {
15262            /* OPC_BNVC, OPC_BNEZALC, OPC_BNEC */
15263            gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
15264        } else {
15265            /* OPC_DADDI */
15266            check_insn(ctx, ISA_MIPS3);
15267            check_mips_64(ctx);
15268            gen_arith_imm(ctx, op, rt, rs, imm);
15269        }
15270        break;
15271    case OPC_DADDIU:
15272        check_insn(ctx, ISA_MIPS3);
15273        check_mips_64(ctx);
15274        gen_arith_imm(ctx, op, rt, rs, imm);
15275        break;
15276#else
15277    case OPC_BNVC: /* OPC_BNEZALC, OPC_BNEC */
15278        if (ctx->insn_flags & ISA_MIPS_R6) {
15279            gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
15280        } else {
15281            MIPS_INVAL("major opcode");
15282            gen_reserved_instruction(ctx);
15283        }
15284        break;
15285#endif
15286    case OPC_DAUI: /* OPC_JALX */
15287        if (ctx->insn_flags & ISA_MIPS_R6) {
15288#if defined(TARGET_MIPS64)
15289            /* OPC_DAUI */
15290            check_mips_64(ctx);
15291            if (rs == 0) {
15292                generate_exception(ctx, EXCP_RI);
15293            } else if (rt != 0) {
15294                TCGv t0 = tcg_temp_new();
15295                gen_load_gpr(t0, rs);
15296                tcg_gen_addi_tl(cpu_gpr[rt], t0, imm << 16);
15297            }
15298#else
15299            gen_reserved_instruction(ctx);
15300            MIPS_INVAL("major opcode");
15301#endif
15302        } else {
15303            /* OPC_JALX */
15304            check_insn(ctx, ASE_MIPS16 | ASE_MICROMIPS);
15305            offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 2;
15306            gen_compute_branch(ctx, op, 4, rs, rt, offset, 4);
15307        }
15308        break;
15309    case OPC_MDMX:
15310        /* MDMX: Not implemented. */
15311        break;
15312    case OPC_PCREL:
15313        check_insn(ctx, ISA_MIPS_R6);
15314        gen_pcrel(ctx, ctx->opcode, ctx->base.pc_next, rs);
15315        break;
15316    default:            /* Invalid */
15317        MIPS_INVAL("major opcode");
15318        return false;
15319    }
15320    return true;
15321}
15322
15323static void decode_opc(CPUMIPSState *env, DisasContext *ctx)
15324{
15325    /* make sure instructions are on a word boundary */
15326    if (ctx->base.pc_next & 0x3) {
15327        env->CP0_BadVAddr = ctx->base.pc_next;
15328        generate_exception_err(ctx, EXCP_AdEL, EXCP_INST_NOTAVAIL);
15329        return;
15330    }
15331
15332    /* Handle blikely not taken case */
15333    if ((ctx->hflags & MIPS_HFLAG_BMASK_BASE) == MIPS_HFLAG_BL) {
15334        TCGLabel *l1 = gen_new_label();
15335
15336        tcg_gen_brcondi_tl(TCG_COND_NE, bcond, 0, l1);
15337        tcg_gen_movi_i32(hflags, ctx->hflags & ~MIPS_HFLAG_BMASK);
15338        gen_goto_tb(ctx, 1, ctx->base.pc_next + 4);
15339        gen_set_label(l1);
15340    }
15341
15342    /* Transition to the auto-generated decoder.  */
15343
15344    /* Vendor specific extensions */
15345    if (cpu_supports_isa(env, INSN_R5900) && decode_ext_txx9(ctx, ctx->opcode)) {
15346        return;
15347    }
15348    if (cpu_supports_isa(env, INSN_VR54XX) && decode_ext_vr54xx(ctx, ctx->opcode)) {
15349        return;
15350    }
15351#if defined(TARGET_MIPS64)
15352    if (ase_lcsr_available(env) && decode_ase_lcsr(ctx, ctx->opcode)) {
15353        return;
15354    }
15355    if (cpu_supports_isa(env, INSN_OCTEON) && decode_ext_octeon(ctx, ctx->opcode)) {
15356        return;
15357    }
15358#endif
15359
15360    /* ISA extensions */
15361    if (ase_msa_available(env) && decode_ase_msa(ctx, ctx->opcode)) {
15362        return;
15363    }
15364
15365    /* ISA (from latest to oldest) */
15366    if (cpu_supports_isa(env, ISA_MIPS_R6) && decode_isa_rel6(ctx, ctx->opcode)) {
15367        return;
15368    }
15369
15370    if (decode_opc_legacy(env, ctx)) {
15371        return;
15372    }
15373
15374    gen_reserved_instruction(ctx);
15375}
15376
15377static void mips_tr_init_disas_context(DisasContextBase *dcbase, CPUState *cs)
15378{
15379    DisasContext *ctx = container_of(dcbase, DisasContext, base);
15380    CPUMIPSState *env = cs->env_ptr;
15381
15382    ctx->page_start = ctx->base.pc_first & TARGET_PAGE_MASK;
15383    ctx->saved_pc = -1;
15384    ctx->insn_flags = env->insn_flags;
15385    ctx->CP0_Config0 = env->CP0_Config0;
15386    ctx->CP0_Config1 = env->CP0_Config1;
15387    ctx->CP0_Config2 = env->CP0_Config2;
15388    ctx->CP0_Config3 = env->CP0_Config3;
15389    ctx->CP0_Config5 = env->CP0_Config5;
15390    ctx->btarget = 0;
15391    ctx->kscrexist = (env->CP0_Config4 >> CP0C4_KScrExist) & 0xff;
15392    ctx->rxi = (env->CP0_Config3 >> CP0C3_RXI) & 1;
15393    ctx->ie = (env->CP0_Config4 >> CP0C4_IE) & 3;
15394    ctx->bi = (env->CP0_Config3 >> CP0C3_BI) & 1;
15395    ctx->bp = (env->CP0_Config3 >> CP0C3_BP) & 1;
15396    ctx->PAMask = env->PAMask;
15397    ctx->mvh = (env->CP0_Config5 >> CP0C5_MVH) & 1;
15398    ctx->eva = (env->CP0_Config5 >> CP0C5_EVA) & 1;
15399    ctx->sc = (env->CP0_Config3 >> CP0C3_SC) & 1;
15400    ctx->CP0_LLAddr_shift = env->CP0_LLAddr_shift;
15401    ctx->cmgcr = (env->CP0_Config3 >> CP0C3_CMGCR) & 1;
15402    /* Restore delay slot state from the tb context.  */
15403    ctx->hflags = (uint32_t)ctx->base.tb->flags; /* FIXME: maybe use 64 bits? */
15404    ctx->ulri = (env->CP0_Config3 >> CP0C3_ULRI) & 1;
15405    ctx->ps = ((env->active_fpu.fcr0 >> FCR0_PS) & 1) ||
15406             (env->insn_flags & (INSN_LOONGSON2E | INSN_LOONGSON2F));
15407    ctx->vp = (env->CP0_Config5 >> CP0C5_VP) & 1;
15408    ctx->mrp = (env->CP0_Config5 >> CP0C5_MRP) & 1;
15409    ctx->nan2008 = (env->active_fpu.fcr31 >> FCR31_NAN2008) & 1;
15410    ctx->abs2008 = (env->active_fpu.fcr31 >> FCR31_ABS2008) & 1;
15411    ctx->mi = (env->CP0_Config5 >> CP0C5_MI) & 1;
15412    ctx->gi = (env->CP0_Config5 >> CP0C5_GI) & 3;
15413    restore_cpu_state(env, ctx);
15414#ifdef CONFIG_USER_ONLY
15415        ctx->mem_idx = MIPS_HFLAG_UM;
15416#else
15417        ctx->mem_idx = hflags_mmu_index(ctx->hflags);
15418#endif
15419    ctx->default_tcg_memop_mask = (!(ctx->insn_flags & ISA_NANOMIPS32) &&
15420                                  (ctx->insn_flags & (ISA_MIPS_R6 |
15421                                  INSN_LOONGSON3A))) ? MO_UNALN : MO_ALIGN;
15422
15423    /*
15424     * Execute a branch and its delay slot as a single instruction.
15425     * This is what GDB expects and is consistent with what the
15426     * hardware does (e.g. if a delay slot instruction faults, the
15427     * reported PC is the PC of the branch).
15428     */
15429    if (ctx->base.singlestep_enabled && (ctx->hflags & MIPS_HFLAG_BMASK)) {
15430        ctx->base.max_insns = 2;
15431    }
15432
15433    LOG_DISAS("\ntb %p idx %d hflags %04x\n", ctx->base.tb, ctx->mem_idx,
15434              ctx->hflags);
15435}
15436
15437static void mips_tr_tb_start(DisasContextBase *dcbase, CPUState *cs)
15438{
15439}
15440
15441static void mips_tr_insn_start(DisasContextBase *dcbase, CPUState *cs)
15442{
15443    DisasContext *ctx = container_of(dcbase, DisasContext, base);
15444
15445    tcg_gen_insn_start(ctx->base.pc_next, ctx->hflags & MIPS_HFLAG_BMASK,
15446                       ctx->btarget);
15447}
15448
15449static void mips_tr_translate_insn(DisasContextBase *dcbase, CPUState *cs)
15450{
15451    CPUMIPSState *env = cs->env_ptr;
15452    DisasContext *ctx = container_of(dcbase, DisasContext, base);
15453    int insn_bytes;
15454    int is_slot;
15455
15456    is_slot = ctx->hflags & MIPS_HFLAG_BMASK;
15457    if (ctx->insn_flags & ISA_NANOMIPS32) {
15458        ctx->opcode = translator_lduw(env, &ctx->base, ctx->base.pc_next);
15459        insn_bytes = decode_isa_nanomips(env, ctx);
15460    } else if (!(ctx->hflags & MIPS_HFLAG_M16)) {
15461        ctx->opcode = translator_ldl(env, &ctx->base, ctx->base.pc_next);
15462        insn_bytes = 4;
15463        decode_opc(env, ctx);
15464    } else if (ctx->insn_flags & ASE_MICROMIPS) {
15465        ctx->opcode = translator_lduw(env, &ctx->base, ctx->base.pc_next);
15466        insn_bytes = decode_isa_micromips(env, ctx);
15467    } else if (ctx->insn_flags & ASE_MIPS16) {
15468        ctx->opcode = translator_lduw(env, &ctx->base, ctx->base.pc_next);
15469        insn_bytes = decode_ase_mips16e(env, ctx);
15470    } else {
15471        gen_reserved_instruction(ctx);
15472        g_assert(ctx->base.is_jmp == DISAS_NORETURN);
15473        return;
15474    }
15475
15476    if (ctx->hflags & MIPS_HFLAG_BMASK) {
15477        if (!(ctx->hflags & (MIPS_HFLAG_BDS16 | MIPS_HFLAG_BDS32 |
15478                             MIPS_HFLAG_FBNSLOT))) {
15479            /*
15480             * Force to generate branch as there is neither delay nor
15481             * forbidden slot.
15482             */
15483            is_slot = 1;
15484        }
15485        if ((ctx->hflags & MIPS_HFLAG_M16) &&
15486            (ctx->hflags & MIPS_HFLAG_FBNSLOT)) {
15487            /*
15488             * Force to generate branch as microMIPS R6 doesn't restrict
15489             * branches in the forbidden slot.
15490             */
15491            is_slot = 1;
15492        }
15493    }
15494    if (is_slot) {
15495        gen_branch(ctx, insn_bytes);
15496    }
15497    if (ctx->base.is_jmp == DISAS_SEMIHOST) {
15498        generate_exception_err(ctx, EXCP_SEMIHOST, insn_bytes);
15499    }
15500    ctx->base.pc_next += insn_bytes;
15501
15502    if (ctx->base.is_jmp != DISAS_NEXT) {
15503        return;
15504    }
15505
15506    /*
15507     * End the TB on (most) page crossings.
15508     * See mips_tr_init_disas_context about single-stepping a branch
15509     * together with its delay slot.
15510     */
15511    if (ctx->base.pc_next - ctx->page_start >= TARGET_PAGE_SIZE
15512        && !ctx->base.singlestep_enabled) {
15513        ctx->base.is_jmp = DISAS_TOO_MANY;
15514    }
15515}
15516
15517static void mips_tr_tb_stop(DisasContextBase *dcbase, CPUState *cs)
15518{
15519    DisasContext *ctx = container_of(dcbase, DisasContext, base);
15520
15521    switch (ctx->base.is_jmp) {
15522    case DISAS_STOP:
15523        gen_save_pc(ctx->base.pc_next);
15524        tcg_gen_lookup_and_goto_ptr();
15525        break;
15526    case DISAS_NEXT:
15527    case DISAS_TOO_MANY:
15528        save_cpu_state(ctx, 0);
15529        gen_goto_tb(ctx, 0, ctx->base.pc_next);
15530        break;
15531    case DISAS_EXIT:
15532        tcg_gen_exit_tb(NULL, 0);
15533        break;
15534    case DISAS_NORETURN:
15535        break;
15536    default:
15537        g_assert_not_reached();
15538    }
15539}
15540
15541static void mips_tr_disas_log(const DisasContextBase *dcbase,
15542                              CPUState *cs, FILE *logfile)
15543{
15544    fprintf(logfile, "IN: %s\n", lookup_symbol(dcbase->pc_first));
15545    target_disas(logfile, cs, dcbase->pc_first, dcbase->tb->size);
15546}
15547
15548static const TranslatorOps mips_tr_ops = {
15549    .init_disas_context = mips_tr_init_disas_context,
15550    .tb_start           = mips_tr_tb_start,
15551    .insn_start         = mips_tr_insn_start,
15552    .translate_insn     = mips_tr_translate_insn,
15553    .tb_stop            = mips_tr_tb_stop,
15554    .disas_log          = mips_tr_disas_log,
15555};
15556
15557void gen_intermediate_code(CPUState *cs, TranslationBlock *tb, int *max_insns,
15558                           target_ulong pc, void *host_pc)
15559{
15560    DisasContext ctx;
15561
15562    translator_loop(cs, tb, max_insns, pc, host_pc, &mips_tr_ops, &ctx.base);
15563}
15564
15565void mips_tcg_init(void)
15566{
15567    int i;
15568
15569    cpu_gpr[0] = NULL;
15570    for (i = 1; i < 32; i++)
15571        cpu_gpr[i] = tcg_global_mem_new(cpu_env,
15572                                        offsetof(CPUMIPSState,
15573                                                 active_tc.gpr[i]),
15574                                        regnames[i]);
15575#if defined(TARGET_MIPS64)
15576    cpu_gpr_hi[0] = NULL;
15577
15578    for (unsigned i = 1; i < 32; i++) {
15579        g_autofree char *rname = g_strdup_printf("%s[hi]", regnames[i]);
15580
15581        cpu_gpr_hi[i] = tcg_global_mem_new_i64(cpu_env,
15582                                               offsetof(CPUMIPSState,
15583                                                        active_tc.gpr_hi[i]),
15584                                               rname);
15585    }
15586#endif /* !TARGET_MIPS64 */
15587    for (i = 0; i < 32; i++) {
15588        int off = offsetof(CPUMIPSState, active_fpu.fpr[i].wr.d[0]);
15589
15590        fpu_f64[i] = tcg_global_mem_new_i64(cpu_env, off, fregnames[i]);
15591    }
15592    msa_translate_init();
15593    cpu_PC = tcg_global_mem_new(cpu_env,
15594                                offsetof(CPUMIPSState, active_tc.PC), "PC");
15595    for (i = 0; i < MIPS_DSP_ACC; i++) {
15596        cpu_HI[i] = tcg_global_mem_new(cpu_env,
15597                                       offsetof(CPUMIPSState, active_tc.HI[i]),
15598                                       regnames_HI[i]);
15599        cpu_LO[i] = tcg_global_mem_new(cpu_env,
15600                                       offsetof(CPUMIPSState, active_tc.LO[i]),
15601                                       regnames_LO[i]);
15602    }
15603    cpu_dspctrl = tcg_global_mem_new(cpu_env,
15604                                     offsetof(CPUMIPSState,
15605                                              active_tc.DSPControl),
15606                                     "DSPControl");
15607    bcond = tcg_global_mem_new(cpu_env,
15608                               offsetof(CPUMIPSState, bcond), "bcond");
15609    btarget = tcg_global_mem_new(cpu_env,
15610                                 offsetof(CPUMIPSState, btarget), "btarget");
15611    hflags = tcg_global_mem_new_i32(cpu_env,
15612                                    offsetof(CPUMIPSState, hflags), "hflags");
15613
15614    fpu_fcr0 = tcg_global_mem_new_i32(cpu_env,
15615                                      offsetof(CPUMIPSState, active_fpu.fcr0),
15616                                      "fcr0");
15617    fpu_fcr31 = tcg_global_mem_new_i32(cpu_env,
15618                                       offsetof(CPUMIPSState, active_fpu.fcr31),
15619                                       "fcr31");
15620    cpu_lladdr = tcg_global_mem_new(cpu_env, offsetof(CPUMIPSState, lladdr),
15621                                    "lladdr");
15622    cpu_llval = tcg_global_mem_new(cpu_env, offsetof(CPUMIPSState, llval),
15623                                   "llval");
15624
15625    if (TARGET_LONG_BITS == 32) {
15626        mxu_translate_init();
15627    }
15628}
15629
15630void mips_restore_state_to_opc(CPUState *cs,
15631                               const TranslationBlock *tb,
15632                               const uint64_t *data)
15633{
15634    MIPSCPU *cpu = MIPS_CPU(cs);
15635    CPUMIPSState *env = &cpu->env;
15636
15637    env->active_tc.PC = data[0];
15638    env->hflags &= ~MIPS_HFLAG_BMASK;
15639    env->hflags |= data[1];
15640    switch (env->hflags & MIPS_HFLAG_BMASK_BASE) {
15641    case MIPS_HFLAG_BR:
15642        break;
15643    case MIPS_HFLAG_BC:
15644    case MIPS_HFLAG_BL:
15645    case MIPS_HFLAG_B:
15646        env->btarget = data[2];
15647        break;
15648    }
15649}
15650