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 "cpu.h"
  27#include "internal.h"
  28#include "tcg/tcg-op.h"
  29#include "exec/translator.h"
  30#include "exec/helper-proto.h"
  31#include "exec/helper-gen.h"
  32#include "semihosting/semihost.h"
  33
  34#include "trace.h"
  35#include "exec/translator.h"
  36#include "exec/log.h"
  37#include "qemu/qemu-print.h"
  38#include "fpu_helper.h"
  39#include "translate.h"
  40
  41/*
  42 * Many sysemu-only helpers are not reachable for user-only.
  43 * Define stub generators here, so that we need not either sprinkle
  44 * ifdefs through the translator, nor provide the helper function.
  45 */
  46#define STUB_HELPER(NAME, ...) \
  47    static inline void gen_helper_##NAME(__VA_ARGS__) \
  48    { g_assert_not_reached(); }
  49
  50#ifdef CONFIG_USER_ONLY
  51STUB_HELPER(cache, TCGv_env env, TCGv val, TCGv_i32 reg)
  52#endif
  53
  54enum {
  55    /* indirect opcode tables */
  56    OPC_SPECIAL  = (0x00 << 26),
  57    OPC_REGIMM   = (0x01 << 26),
  58    OPC_CP0      = (0x10 << 26),
  59    OPC_CP2      = (0x12 << 26),
  60    OPC_CP3      = (0x13 << 26),
  61    OPC_SPECIAL2 = (0x1C << 26),
  62    OPC_SPECIAL3 = (0x1F << 26),
  63    /* arithmetic with immediate */
  64    OPC_ADDI     = (0x08 << 26),
  65    OPC_ADDIU    = (0x09 << 26),
  66    OPC_SLTI     = (0x0A << 26),
  67    OPC_SLTIU    = (0x0B << 26),
  68    /* logic with immediate */
  69    OPC_ANDI     = (0x0C << 26),
  70    OPC_ORI      = (0x0D << 26),
  71    OPC_XORI     = (0x0E << 26),
  72    OPC_LUI      = (0x0F << 26),
  73    /* arithmetic with immediate */
  74    OPC_DADDI    = (0x18 << 26),
  75    OPC_DADDIU   = (0x19 << 26),
  76    /* Jump and branches */
  77    OPC_J        = (0x02 << 26),
  78    OPC_JAL      = (0x03 << 26),
  79    OPC_BEQ      = (0x04 << 26),  /* Unconditional if rs = rt = 0 (B) */
  80    OPC_BEQL     = (0x14 << 26),
  81    OPC_BNE      = (0x05 << 26),
  82    OPC_BNEL     = (0x15 << 26),
  83    OPC_BLEZ     = (0x06 << 26),
  84    OPC_BLEZL    = (0x16 << 26),
  85    OPC_BGTZ     = (0x07 << 26),
  86    OPC_BGTZL    = (0x17 << 26),
  87    OPC_JALX     = (0x1D << 26),
  88    OPC_DAUI     = (0x1D << 26),
  89    /* Load and stores */
  90    OPC_LDL      = (0x1A << 26),
  91    OPC_LDR      = (0x1B << 26),
  92    OPC_LB       = (0x20 << 26),
  93    OPC_LH       = (0x21 << 26),
  94    OPC_LWL      = (0x22 << 26),
  95    OPC_LW       = (0x23 << 26),
  96    OPC_LWPC     = OPC_LW | 0x5,
  97    OPC_LBU      = (0x24 << 26),
  98    OPC_LHU      = (0x25 << 26),
  99    OPC_LWR      = (0x26 << 26),
 100    OPC_LWU      = (0x27 << 26),
 101    OPC_SB       = (0x28 << 26),
 102    OPC_SH       = (0x29 << 26),
 103    OPC_SWL      = (0x2A << 26),
 104    OPC_SW       = (0x2B << 26),
 105    OPC_SDL      = (0x2C << 26),
 106    OPC_SDR      = (0x2D << 26),
 107    OPC_SWR      = (0x2E << 26),
 108    OPC_LL       = (0x30 << 26),
 109    OPC_LLD      = (0x34 << 26),
 110    OPC_LD       = (0x37 << 26),
 111    OPC_LDPC     = OPC_LD | 0x5,
 112    OPC_SC       = (0x38 << 26),
 113    OPC_SCD      = (0x3C << 26),
 114    OPC_SD       = (0x3F << 26),
 115    /* Floating point load/store */
 116    OPC_LWC1     = (0x31 << 26),
 117    OPC_LWC2     = (0x32 << 26),
 118    OPC_LDC1     = (0x35 << 26),
 119    OPC_LDC2     = (0x36 << 26),
 120    OPC_SWC1     = (0x39 << 26),
 121    OPC_SWC2     = (0x3A << 26),
 122    OPC_SDC1     = (0x3D << 26),
 123    OPC_SDC2     = (0x3E << 26),
 124    /* Compact Branches */
 125    OPC_BLEZALC  = (0x06 << 26),
 126    OPC_BGEZALC  = (0x06 << 26),
 127    OPC_BGEUC    = (0x06 << 26),
 128    OPC_BGTZALC  = (0x07 << 26),
 129    OPC_BLTZALC  = (0x07 << 26),
 130    OPC_BLTUC    = (0x07 << 26),
 131    OPC_BOVC     = (0x08 << 26),
 132    OPC_BEQZALC  = (0x08 << 26),
 133    OPC_BEQC     = (0x08 << 26),
 134    OPC_BLEZC    = (0x16 << 26),
 135    OPC_BGEZC    = (0x16 << 26),
 136    OPC_BGEC     = (0x16 << 26),
 137    OPC_BGTZC    = (0x17 << 26),
 138    OPC_BLTZC    = (0x17 << 26),
 139    OPC_BLTC     = (0x17 << 26),
 140    OPC_BNVC     = (0x18 << 26),
 141    OPC_BNEZALC  = (0x18 << 26),
 142    OPC_BNEC     = (0x18 << 26),
 143    OPC_BC       = (0x32 << 26),
 144    OPC_BEQZC    = (0x36 << 26),
 145    OPC_JIC      = (0x36 << 26),
 146    OPC_BALC     = (0x3A << 26),
 147    OPC_BNEZC    = (0x3E << 26),
 148    OPC_JIALC    = (0x3E << 26),
 149    /* MDMX ASE specific */
 150    OPC_MDMX     = (0x1E << 26),
 151    /* Cache and prefetch */
 152    OPC_CACHE    = (0x2F << 26),
 153    OPC_PREF     = (0x33 << 26),
 154    /* PC-relative address computation / loads */
 155    OPC_PCREL    = (0x3B << 26),
 156};
 157
 158/* PC-relative address computation / loads  */
 159#define MASK_OPC_PCREL_TOP2BITS(op) (MASK_OP_MAJOR(op) | (op & (3 << 19)))
 160#define MASK_OPC_PCREL_TOP5BITS(op) (MASK_OP_MAJOR(op) | (op & (0x1f << 16)))
 161enum {
 162    /* Instructions determined by bits 19 and 20 */
 163    OPC_ADDIUPC = OPC_PCREL | (0 << 19),
 164    R6_OPC_LWPC = OPC_PCREL | (1 << 19),
 165    OPC_LWUPC   = OPC_PCREL | (2 << 19),
 166
 167    /* Instructions determined by bits 16 ... 20 */
 168    OPC_AUIPC   = OPC_PCREL | (0x1e << 16),
 169    OPC_ALUIPC  = OPC_PCREL | (0x1f << 16),
 170
 171    /* Other */
 172    R6_OPC_LDPC = OPC_PCREL | (6 << 18),
 173};
 174
 175/* MIPS special opcodes */
 176#define MASK_SPECIAL(op)            (MASK_OP_MAJOR(op) | (op & 0x3F))
 177
 178enum {
 179    /* Shifts */
 180    OPC_SLL      = 0x00 | OPC_SPECIAL,
 181    /* NOP is SLL r0, r0, 0   */
 182    /* SSNOP is SLL r0, r0, 1 */
 183    /* EHB is SLL r0, r0, 3 */
 184    OPC_SRL      = 0x02 | OPC_SPECIAL, /* also ROTR */
 185    OPC_ROTR     = OPC_SRL | (1 << 21),
 186    OPC_SRA      = 0x03 | OPC_SPECIAL,
 187    OPC_SLLV     = 0x04 | OPC_SPECIAL,
 188    OPC_SRLV     = 0x06 | OPC_SPECIAL, /* also ROTRV */
 189    OPC_ROTRV    = OPC_SRLV | (1 << 6),
 190    OPC_SRAV     = 0x07 | OPC_SPECIAL,
 191    OPC_DSLLV    = 0x14 | OPC_SPECIAL,
 192    OPC_DSRLV    = 0x16 | OPC_SPECIAL, /* also DROTRV */
 193    OPC_DROTRV   = OPC_DSRLV | (1 << 6),
 194    OPC_DSRAV    = 0x17 | OPC_SPECIAL,
 195    OPC_DSLL     = 0x38 | OPC_SPECIAL,
 196    OPC_DSRL     = 0x3A | OPC_SPECIAL, /* also DROTR */
 197    OPC_DROTR    = OPC_DSRL | (1 << 21),
 198    OPC_DSRA     = 0x3B | OPC_SPECIAL,
 199    OPC_DSLL32   = 0x3C | OPC_SPECIAL,
 200    OPC_DSRL32   = 0x3E | OPC_SPECIAL, /* also DROTR32 */
 201    OPC_DROTR32  = OPC_DSRL32 | (1 << 21),
 202    OPC_DSRA32   = 0x3F | OPC_SPECIAL,
 203    /* Multiplication / division */
 204    OPC_MULT     = 0x18 | OPC_SPECIAL,
 205    OPC_MULTU    = 0x19 | OPC_SPECIAL,
 206    OPC_DIV      = 0x1A | OPC_SPECIAL,
 207    OPC_DIVU     = 0x1B | OPC_SPECIAL,
 208    OPC_DMULT    = 0x1C | OPC_SPECIAL,
 209    OPC_DMULTU   = 0x1D | OPC_SPECIAL,
 210    OPC_DDIV     = 0x1E | OPC_SPECIAL,
 211    OPC_DDIVU    = 0x1F | OPC_SPECIAL,
 212
 213    /* 2 registers arithmetic / logic */
 214    OPC_ADD      = 0x20 | OPC_SPECIAL,
 215    OPC_ADDU     = 0x21 | OPC_SPECIAL,
 216    OPC_SUB      = 0x22 | OPC_SPECIAL,
 217    OPC_SUBU     = 0x23 | OPC_SPECIAL,
 218    OPC_AND      = 0x24 | OPC_SPECIAL,
 219    OPC_OR       = 0x25 | OPC_SPECIAL,
 220    OPC_XOR      = 0x26 | OPC_SPECIAL,
 221    OPC_NOR      = 0x27 | OPC_SPECIAL,
 222    OPC_SLT      = 0x2A | OPC_SPECIAL,
 223    OPC_SLTU     = 0x2B | OPC_SPECIAL,
 224    OPC_DADD     = 0x2C | OPC_SPECIAL,
 225    OPC_DADDU    = 0x2D | OPC_SPECIAL,
 226    OPC_DSUB     = 0x2E | OPC_SPECIAL,
 227    OPC_DSUBU    = 0x2F | OPC_SPECIAL,
 228    /* Jumps */
 229    OPC_JR       = 0x08 | OPC_SPECIAL, /* Also JR.HB */
 230    OPC_JALR     = 0x09 | OPC_SPECIAL, /* Also JALR.HB */
 231    /* Traps */
 232    OPC_TGE      = 0x30 | OPC_SPECIAL,
 233    OPC_TGEU     = 0x31 | OPC_SPECIAL,
 234    OPC_TLT      = 0x32 | OPC_SPECIAL,
 235    OPC_TLTU     = 0x33 | OPC_SPECIAL,
 236    OPC_TEQ      = 0x34 | OPC_SPECIAL,
 237    OPC_TNE      = 0x36 | OPC_SPECIAL,
 238    /* HI / LO registers load & stores */
 239    OPC_MFHI     = 0x10 | OPC_SPECIAL,
 240    OPC_MTHI     = 0x11 | OPC_SPECIAL,
 241    OPC_MFLO     = 0x12 | OPC_SPECIAL,
 242    OPC_MTLO     = 0x13 | OPC_SPECIAL,
 243    /* Conditional moves */
 244    OPC_MOVZ     = 0x0A | OPC_SPECIAL,
 245    OPC_MOVN     = 0x0B | OPC_SPECIAL,
 246
 247    OPC_SELEQZ   = 0x35 | OPC_SPECIAL,
 248    OPC_SELNEZ   = 0x37 | OPC_SPECIAL,
 249
 250    OPC_MOVCI    = 0x01 | OPC_SPECIAL,
 251
 252    /* Special */
 253    OPC_PMON     = 0x05 | OPC_SPECIAL, /* unofficial */
 254    OPC_SYSCALL  = 0x0C | OPC_SPECIAL,
 255    OPC_BREAK    = 0x0D | OPC_SPECIAL,
 256    OPC_SPIM     = 0x0E | OPC_SPECIAL, /* unofficial */
 257    OPC_SYNC     = 0x0F | OPC_SPECIAL,
 258
 259    OPC_SPECIAL28_RESERVED = 0x28 | OPC_SPECIAL,
 260    OPC_SPECIAL29_RESERVED = 0x29 | OPC_SPECIAL,
 261    OPC_SPECIAL39_RESERVED = 0x39 | OPC_SPECIAL,
 262    OPC_SPECIAL3D_RESERVED = 0x3D | OPC_SPECIAL,
 263};
 264
 265/*
 266 * R6 Multiply and Divide instructions have the same opcode
 267 * and function field as legacy OPC_MULT[U]/OPC_DIV[U]
 268 */
 269#define MASK_R6_MULDIV(op)          (MASK_SPECIAL(op) | (op & (0x7ff)))
 270
 271enum {
 272    R6_OPC_MUL   = OPC_MULT  | (2 << 6),
 273    R6_OPC_MUH   = OPC_MULT  | (3 << 6),
 274    R6_OPC_MULU  = OPC_MULTU | (2 << 6),
 275    R6_OPC_MUHU  = OPC_MULTU | (3 << 6),
 276    R6_OPC_DIV   = OPC_DIV   | (2 << 6),
 277    R6_OPC_MOD   = OPC_DIV   | (3 << 6),
 278    R6_OPC_DIVU  = OPC_DIVU  | (2 << 6),
 279    R6_OPC_MODU  = OPC_DIVU  | (3 << 6),
 280
 281    R6_OPC_DMUL   = OPC_DMULT  | (2 << 6),
 282    R6_OPC_DMUH   = OPC_DMULT  | (3 << 6),
 283    R6_OPC_DMULU  = OPC_DMULTU | (2 << 6),
 284    R6_OPC_DMUHU  = OPC_DMULTU | (3 << 6),
 285    R6_OPC_DDIV   = OPC_DDIV   | (2 << 6),
 286    R6_OPC_DMOD   = OPC_DDIV   | (3 << 6),
 287    R6_OPC_DDIVU  = OPC_DDIVU  | (2 << 6),
 288    R6_OPC_DMODU  = OPC_DDIVU  | (3 << 6),
 289
 290    R6_OPC_CLZ      = 0x10 | OPC_SPECIAL,
 291    R6_OPC_CLO      = 0x11 | OPC_SPECIAL,
 292    R6_OPC_DCLZ     = 0x12 | OPC_SPECIAL,
 293    R6_OPC_DCLO     = 0x13 | OPC_SPECIAL,
 294    R6_OPC_SDBBP    = 0x0e | OPC_SPECIAL,
 295};
 296
 297/* REGIMM (rt field) opcodes */
 298#define MASK_REGIMM(op)             (MASK_OP_MAJOR(op) | (op & (0x1F << 16)))
 299
 300enum {
 301    OPC_BLTZ     = (0x00 << 16) | OPC_REGIMM,
 302    OPC_BLTZL    = (0x02 << 16) | OPC_REGIMM,
 303    OPC_BGEZ     = (0x01 << 16) | OPC_REGIMM,
 304    OPC_BGEZL    = (0x03 << 16) | OPC_REGIMM,
 305    OPC_BLTZAL   = (0x10 << 16) | OPC_REGIMM,
 306    OPC_BLTZALL  = (0x12 << 16) | OPC_REGIMM,
 307    OPC_BGEZAL   = (0x11 << 16) | OPC_REGIMM,
 308    OPC_BGEZALL  = (0x13 << 16) | OPC_REGIMM,
 309    OPC_TGEI     = (0x08 << 16) | OPC_REGIMM,
 310    OPC_TGEIU    = (0x09 << 16) | OPC_REGIMM,
 311    OPC_TLTI     = (0x0A << 16) | OPC_REGIMM,
 312    OPC_TLTIU    = (0x0B << 16) | OPC_REGIMM,
 313    OPC_TEQI     = (0x0C << 16) | OPC_REGIMM,
 314    OPC_TNEI     = (0x0E << 16) | OPC_REGIMM,
 315    OPC_SIGRIE   = (0x17 << 16) | OPC_REGIMM,
 316    OPC_SYNCI    = (0x1F << 16) | OPC_REGIMM,
 317
 318    OPC_DAHI     = (0x06 << 16) | OPC_REGIMM,
 319    OPC_DATI     = (0x1e << 16) | OPC_REGIMM,
 320};
 321
 322/* Special2 opcodes */
 323#define MASK_SPECIAL2(op)           (MASK_OP_MAJOR(op) | (op & 0x3F))
 324
 325enum {
 326    /* Multiply & xxx operations */
 327    OPC_MADD     = 0x00 | OPC_SPECIAL2,
 328    OPC_MADDU    = 0x01 | OPC_SPECIAL2,
 329    OPC_MUL      = 0x02 | OPC_SPECIAL2,
 330    OPC_MSUB     = 0x04 | OPC_SPECIAL2,
 331    OPC_MSUBU    = 0x05 | OPC_SPECIAL2,
 332    /* Loongson 2F */
 333    OPC_MULT_G_2F   = 0x10 | OPC_SPECIAL2,
 334    OPC_DMULT_G_2F  = 0x11 | OPC_SPECIAL2,
 335    OPC_MULTU_G_2F  = 0x12 | OPC_SPECIAL2,
 336    OPC_DMULTU_G_2F = 0x13 | OPC_SPECIAL2,
 337    OPC_DIV_G_2F    = 0x14 | OPC_SPECIAL2,
 338    OPC_DDIV_G_2F   = 0x15 | OPC_SPECIAL2,
 339    OPC_DIVU_G_2F   = 0x16 | OPC_SPECIAL2,
 340    OPC_DDIVU_G_2F  = 0x17 | OPC_SPECIAL2,
 341    OPC_MOD_G_2F    = 0x1c | OPC_SPECIAL2,
 342    OPC_DMOD_G_2F   = 0x1d | OPC_SPECIAL2,
 343    OPC_MODU_G_2F   = 0x1e | OPC_SPECIAL2,
 344    OPC_DMODU_G_2F  = 0x1f | OPC_SPECIAL2,
 345    /* Misc */
 346    OPC_CLZ      = 0x20 | OPC_SPECIAL2,
 347    OPC_CLO      = 0x21 | OPC_SPECIAL2,
 348    OPC_DCLZ     = 0x24 | OPC_SPECIAL2,
 349    OPC_DCLO     = 0x25 | OPC_SPECIAL2,
 350    /* Special */
 351    OPC_SDBBP    = 0x3F | OPC_SPECIAL2,
 352};
 353
 354/* Special3 opcodes */
 355#define MASK_SPECIAL3(op)           (MASK_OP_MAJOR(op) | (op & 0x3F))
 356
 357enum {
 358    OPC_EXT      = 0x00 | OPC_SPECIAL3,
 359    OPC_DEXTM    = 0x01 | OPC_SPECIAL3,
 360    OPC_DEXTU    = 0x02 | OPC_SPECIAL3,
 361    OPC_DEXT     = 0x03 | OPC_SPECIAL3,
 362    OPC_INS      = 0x04 | OPC_SPECIAL3,
 363    OPC_DINSM    = 0x05 | OPC_SPECIAL3,
 364    OPC_DINSU    = 0x06 | OPC_SPECIAL3,
 365    OPC_DINS     = 0x07 | OPC_SPECIAL3,
 366    OPC_FORK     = 0x08 | OPC_SPECIAL3,
 367    OPC_YIELD    = 0x09 | OPC_SPECIAL3,
 368    OPC_BSHFL    = 0x20 | OPC_SPECIAL3,
 369    OPC_DBSHFL   = 0x24 | OPC_SPECIAL3,
 370    OPC_RDHWR    = 0x3B | OPC_SPECIAL3,
 371    OPC_GINV     = 0x3D | OPC_SPECIAL3,
 372
 373    /* Loongson 2E */
 374    OPC_MULT_G_2E   = 0x18 | OPC_SPECIAL3,
 375    OPC_MULTU_G_2E  = 0x19 | OPC_SPECIAL3,
 376    OPC_DIV_G_2E    = 0x1A | OPC_SPECIAL3,
 377    OPC_DIVU_G_2E   = 0x1B | OPC_SPECIAL3,
 378    OPC_DMULT_G_2E  = 0x1C | OPC_SPECIAL3,
 379    OPC_DMULTU_G_2E = 0x1D | OPC_SPECIAL3,
 380    OPC_DDIV_G_2E   = 0x1E | OPC_SPECIAL3,
 381    OPC_DDIVU_G_2E  = 0x1F | OPC_SPECIAL3,
 382    OPC_MOD_G_2E    = 0x22 | OPC_SPECIAL3,
 383    OPC_MODU_G_2E   = 0x23 | OPC_SPECIAL3,
 384    OPC_DMOD_G_2E   = 0x26 | OPC_SPECIAL3,
 385    OPC_DMODU_G_2E  = 0x27 | OPC_SPECIAL3,
 386
 387    /* MIPS DSP Load */
 388    OPC_LX_DSP         = 0x0A | OPC_SPECIAL3,
 389    /* MIPS DSP Arithmetic */
 390    OPC_ADDU_QB_DSP    = 0x10 | OPC_SPECIAL3,
 391    OPC_ADDU_OB_DSP    = 0x14 | OPC_SPECIAL3,
 392    OPC_ABSQ_S_PH_DSP  = 0x12 | OPC_SPECIAL3,
 393    OPC_ABSQ_S_QH_DSP  = 0x16 | OPC_SPECIAL3,
 394    /* OPC_ADDUH_QB_DSP is same as OPC_MULT_G_2E.  */
 395    /* OPC_ADDUH_QB_DSP   = 0x18 | OPC_SPECIAL3,  */
 396    OPC_CMPU_EQ_QB_DSP = 0x11 | OPC_SPECIAL3,
 397    OPC_CMPU_EQ_OB_DSP = 0x15 | OPC_SPECIAL3,
 398    /* MIPS DSP GPR-Based Shift Sub-class */
 399    OPC_SHLL_QB_DSP    = 0x13 | OPC_SPECIAL3,
 400    OPC_SHLL_OB_DSP    = 0x17 | OPC_SPECIAL3,
 401    /* MIPS DSP Multiply Sub-class insns */
 402    /* OPC_MUL_PH_DSP is same as OPC_ADDUH_QB_DSP.  */
 403    /* OPC_MUL_PH_DSP     = 0x18 | OPC_SPECIAL3,  */
 404    OPC_DPA_W_PH_DSP   = 0x30 | OPC_SPECIAL3,
 405    OPC_DPAQ_W_QH_DSP  = 0x34 | OPC_SPECIAL3,
 406    /* DSP Bit/Manipulation Sub-class */
 407    OPC_INSV_DSP       = 0x0C | OPC_SPECIAL3,
 408    OPC_DINSV_DSP      = 0x0D | OPC_SPECIAL3,
 409    /* MIPS DSP Append Sub-class */
 410    OPC_APPEND_DSP     = 0x31 | OPC_SPECIAL3,
 411    OPC_DAPPEND_DSP    = 0x35 | OPC_SPECIAL3,
 412    /* MIPS DSP Accumulator and DSPControl Access Sub-class */
 413    OPC_EXTR_W_DSP     = 0x38 | OPC_SPECIAL3,
 414    OPC_DEXTR_W_DSP    = 0x3C | OPC_SPECIAL3,
 415
 416    /* EVA */
 417    OPC_LWLE           = 0x19 | OPC_SPECIAL3,
 418    OPC_LWRE           = 0x1A | OPC_SPECIAL3,
 419    OPC_CACHEE         = 0x1B | OPC_SPECIAL3,
 420    OPC_SBE            = 0x1C | OPC_SPECIAL3,
 421    OPC_SHE            = 0x1D | OPC_SPECIAL3,
 422    OPC_SCE            = 0x1E | OPC_SPECIAL3,
 423    OPC_SWE            = 0x1F | OPC_SPECIAL3,
 424    OPC_SWLE           = 0x21 | OPC_SPECIAL3,
 425    OPC_SWRE           = 0x22 | OPC_SPECIAL3,
 426    OPC_PREFE          = 0x23 | OPC_SPECIAL3,
 427    OPC_LBUE           = 0x28 | OPC_SPECIAL3,
 428    OPC_LHUE           = 0x29 | OPC_SPECIAL3,
 429    OPC_LBE            = 0x2C | OPC_SPECIAL3,
 430    OPC_LHE            = 0x2D | OPC_SPECIAL3,
 431    OPC_LLE            = 0x2E | OPC_SPECIAL3,
 432    OPC_LWE            = 0x2F | OPC_SPECIAL3,
 433
 434    /* R6 */
 435    R6_OPC_PREF        = 0x35 | OPC_SPECIAL3,
 436    R6_OPC_CACHE       = 0x25 | OPC_SPECIAL3,
 437    R6_OPC_LL          = 0x36 | OPC_SPECIAL3,
 438    R6_OPC_SC          = 0x26 | OPC_SPECIAL3,
 439    R6_OPC_LLD         = 0x37 | OPC_SPECIAL3,
 440    R6_OPC_SCD         = 0x27 | OPC_SPECIAL3,
 441};
 442
 443/* Loongson EXT load/store quad word opcodes */
 444#define MASK_LOONGSON_GSLSQ(op)           (MASK_OP_MAJOR(op) | (op & 0x8020))
 445enum {
 446    OPC_GSLQ        = 0x0020 | OPC_LWC2,
 447    OPC_GSLQC1      = 0x8020 | OPC_LWC2,
 448    OPC_GSSHFL      = OPC_LWC2,
 449    OPC_GSSQ        = 0x0020 | OPC_SWC2,
 450    OPC_GSSQC1      = 0x8020 | OPC_SWC2,
 451    OPC_GSSHFS      = OPC_SWC2,
 452};
 453
 454/* Loongson EXT shifted load/store opcodes */
 455#define MASK_LOONGSON_GSSHFLS(op)         (MASK_OP_MAJOR(op) | (op & 0xc03f))
 456enum {
 457    OPC_GSLWLC1     = 0x4 | OPC_GSSHFL,
 458    OPC_GSLWRC1     = 0x5 | OPC_GSSHFL,
 459    OPC_GSLDLC1     = 0x6 | OPC_GSSHFL,
 460    OPC_GSLDRC1     = 0x7 | OPC_GSSHFL,
 461    OPC_GSSWLC1     = 0x4 | OPC_GSSHFS,
 462    OPC_GSSWRC1     = 0x5 | OPC_GSSHFS,
 463    OPC_GSSDLC1     = 0x6 | OPC_GSSHFS,
 464    OPC_GSSDRC1     = 0x7 | OPC_GSSHFS,
 465};
 466
 467/* Loongson EXT LDC2/SDC2 opcodes */
 468#define MASK_LOONGSON_LSDC2(op)           (MASK_OP_MAJOR(op) | (op & 0x7))
 469
 470enum {
 471    OPC_GSLBX      = 0x0 | OPC_LDC2,
 472    OPC_GSLHX      = 0x1 | OPC_LDC2,
 473    OPC_GSLWX      = 0x2 | OPC_LDC2,
 474    OPC_GSLDX      = 0x3 | OPC_LDC2,
 475    OPC_GSLWXC1    = 0x6 | OPC_LDC2,
 476    OPC_GSLDXC1    = 0x7 | OPC_LDC2,
 477    OPC_GSSBX      = 0x0 | OPC_SDC2,
 478    OPC_GSSHX      = 0x1 | OPC_SDC2,
 479    OPC_GSSWX      = 0x2 | OPC_SDC2,
 480    OPC_GSSDX      = 0x3 | OPC_SDC2,
 481    OPC_GSSWXC1    = 0x6 | OPC_SDC2,
 482    OPC_GSSDXC1    = 0x7 | OPC_SDC2,
 483};
 484
 485/* BSHFL opcodes */
 486#define MASK_BSHFL(op)              (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
 487
 488enum {
 489    OPC_WSBH      = (0x02 << 6) | OPC_BSHFL,
 490    OPC_SEB       = (0x10 << 6) | OPC_BSHFL,
 491    OPC_SEH       = (0x18 << 6) | OPC_BSHFL,
 492    OPC_ALIGN     = (0x08 << 6) | OPC_BSHFL, /* 010.bp (010.00 to 010.11) */
 493    OPC_ALIGN_1   = (0x09 << 6) | OPC_BSHFL,
 494    OPC_ALIGN_2   = (0x0A << 6) | OPC_BSHFL,
 495    OPC_ALIGN_3   = (0x0B << 6) | OPC_BSHFL,
 496    OPC_BITSWAP   = (0x00 << 6) | OPC_BSHFL  /* 00000 */
 497};
 498
 499/* DBSHFL opcodes */
 500#define MASK_DBSHFL(op)             (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
 501
 502enum {
 503    OPC_DSBH       = (0x02 << 6) | OPC_DBSHFL,
 504    OPC_DSHD       = (0x05 << 6) | OPC_DBSHFL,
 505    OPC_DALIGN     = (0x08 << 6) | OPC_DBSHFL, /* 01.bp (01.000 to 01.111) */
 506    OPC_DALIGN_1   = (0x09 << 6) | OPC_DBSHFL,
 507    OPC_DALIGN_2   = (0x0A << 6) | OPC_DBSHFL,
 508    OPC_DALIGN_3   = (0x0B << 6) | OPC_DBSHFL,
 509    OPC_DALIGN_4   = (0x0C << 6) | OPC_DBSHFL,
 510    OPC_DALIGN_5   = (0x0D << 6) | OPC_DBSHFL,
 511    OPC_DALIGN_6   = (0x0E << 6) | OPC_DBSHFL,
 512    OPC_DALIGN_7   = (0x0F << 6) | OPC_DBSHFL,
 513    OPC_DBITSWAP   = (0x00 << 6) | OPC_DBSHFL, /* 00000 */
 514};
 515
 516/* MIPS DSP REGIMM opcodes */
 517enum {
 518    OPC_BPOSGE32 = (0x1C << 16) | OPC_REGIMM,
 519    OPC_BPOSGE64 = (0x1D << 16) | OPC_REGIMM,
 520};
 521
 522#define MASK_LX(op)                 (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
 523/* MIPS DSP Load */
 524enum {
 525    OPC_LBUX = (0x06 << 6) | OPC_LX_DSP,
 526    OPC_LHX  = (0x04 << 6) | OPC_LX_DSP,
 527    OPC_LWX  = (0x00 << 6) | OPC_LX_DSP,
 528    OPC_LDX = (0x08 << 6) | OPC_LX_DSP,
 529};
 530
 531#define MASK_ADDU_QB(op)            (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
 532enum {
 533    /* MIPS DSP Arithmetic Sub-class */
 534    OPC_ADDQ_PH        = (0x0A << 6) | OPC_ADDU_QB_DSP,
 535    OPC_ADDQ_S_PH      = (0x0E << 6) | OPC_ADDU_QB_DSP,
 536    OPC_ADDQ_S_W       = (0x16 << 6) | OPC_ADDU_QB_DSP,
 537    OPC_ADDU_QB        = (0x00 << 6) | OPC_ADDU_QB_DSP,
 538    OPC_ADDU_S_QB      = (0x04 << 6) | OPC_ADDU_QB_DSP,
 539    OPC_ADDU_PH        = (0x08 << 6) | OPC_ADDU_QB_DSP,
 540    OPC_ADDU_S_PH      = (0x0C << 6) | OPC_ADDU_QB_DSP,
 541    OPC_SUBQ_PH        = (0x0B << 6) | OPC_ADDU_QB_DSP,
 542    OPC_SUBQ_S_PH      = (0x0F << 6) | OPC_ADDU_QB_DSP,
 543    OPC_SUBQ_S_W       = (0x17 << 6) | OPC_ADDU_QB_DSP,
 544    OPC_SUBU_QB        = (0x01 << 6) | OPC_ADDU_QB_DSP,
 545    OPC_SUBU_S_QB      = (0x05 << 6) | OPC_ADDU_QB_DSP,
 546    OPC_SUBU_PH        = (0x09 << 6) | OPC_ADDU_QB_DSP,
 547    OPC_SUBU_S_PH      = (0x0D << 6) | OPC_ADDU_QB_DSP,
 548    OPC_ADDSC          = (0x10 << 6) | OPC_ADDU_QB_DSP,
 549    OPC_ADDWC          = (0x11 << 6) | OPC_ADDU_QB_DSP,
 550    OPC_MODSUB         = (0x12 << 6) | OPC_ADDU_QB_DSP,
 551    OPC_RADDU_W_QB     = (0x14 << 6) | OPC_ADDU_QB_DSP,
 552    /* MIPS DSP Multiply Sub-class insns */
 553    OPC_MULEU_S_PH_QBL = (0x06 << 6) | OPC_ADDU_QB_DSP,
 554    OPC_MULEU_S_PH_QBR = (0x07 << 6) | OPC_ADDU_QB_DSP,
 555    OPC_MULQ_RS_PH     = (0x1F << 6) | OPC_ADDU_QB_DSP,
 556    OPC_MULEQ_S_W_PHL  = (0x1C << 6) | OPC_ADDU_QB_DSP,
 557    OPC_MULEQ_S_W_PHR  = (0x1D << 6) | OPC_ADDU_QB_DSP,
 558    OPC_MULQ_S_PH      = (0x1E << 6) | OPC_ADDU_QB_DSP,
 559};
 560
 561#define OPC_ADDUH_QB_DSP OPC_MULT_G_2E
 562#define MASK_ADDUH_QB(op)           (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
 563enum {
 564    /* MIPS DSP Arithmetic Sub-class */
 565    OPC_ADDUH_QB   = (0x00 << 6) | OPC_ADDUH_QB_DSP,
 566    OPC_ADDUH_R_QB = (0x02 << 6) | OPC_ADDUH_QB_DSP,
 567    OPC_ADDQH_PH   = (0x08 << 6) | OPC_ADDUH_QB_DSP,
 568    OPC_ADDQH_R_PH = (0x0A << 6) | OPC_ADDUH_QB_DSP,
 569    OPC_ADDQH_W    = (0x10 << 6) | OPC_ADDUH_QB_DSP,
 570    OPC_ADDQH_R_W  = (0x12 << 6) | OPC_ADDUH_QB_DSP,
 571    OPC_SUBUH_QB   = (0x01 << 6) | OPC_ADDUH_QB_DSP,
 572    OPC_SUBUH_R_QB = (0x03 << 6) | OPC_ADDUH_QB_DSP,
 573    OPC_SUBQH_PH   = (0x09 << 6) | OPC_ADDUH_QB_DSP,
 574    OPC_SUBQH_R_PH = (0x0B << 6) | OPC_ADDUH_QB_DSP,
 575    OPC_SUBQH_W    = (0x11 << 6) | OPC_ADDUH_QB_DSP,
 576    OPC_SUBQH_R_W  = (0x13 << 6) | OPC_ADDUH_QB_DSP,
 577    /* MIPS DSP Multiply Sub-class insns */
 578    OPC_MUL_PH     = (0x0C << 6) | OPC_ADDUH_QB_DSP,
 579    OPC_MUL_S_PH   = (0x0E << 6) | OPC_ADDUH_QB_DSP,
 580    OPC_MULQ_S_W   = (0x16 << 6) | OPC_ADDUH_QB_DSP,
 581    OPC_MULQ_RS_W  = (0x17 << 6) | OPC_ADDUH_QB_DSP,
 582};
 583
 584#define MASK_ABSQ_S_PH(op)          (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
 585enum {
 586    /* MIPS DSP Arithmetic Sub-class */
 587    OPC_ABSQ_S_QB       = (0x01 << 6) | OPC_ABSQ_S_PH_DSP,
 588    OPC_ABSQ_S_PH       = (0x09 << 6) | OPC_ABSQ_S_PH_DSP,
 589    OPC_ABSQ_S_W        = (0x11 << 6) | OPC_ABSQ_S_PH_DSP,
 590    OPC_PRECEQ_W_PHL    = (0x0C << 6) | OPC_ABSQ_S_PH_DSP,
 591    OPC_PRECEQ_W_PHR    = (0x0D << 6) | OPC_ABSQ_S_PH_DSP,
 592    OPC_PRECEQU_PH_QBL  = (0x04 << 6) | OPC_ABSQ_S_PH_DSP,
 593    OPC_PRECEQU_PH_QBR  = (0x05 << 6) | OPC_ABSQ_S_PH_DSP,
 594    OPC_PRECEQU_PH_QBLA = (0x06 << 6) | OPC_ABSQ_S_PH_DSP,
 595    OPC_PRECEQU_PH_QBRA = (0x07 << 6) | OPC_ABSQ_S_PH_DSP,
 596    OPC_PRECEU_PH_QBL   = (0x1C << 6) | OPC_ABSQ_S_PH_DSP,
 597    OPC_PRECEU_PH_QBR   = (0x1D << 6) | OPC_ABSQ_S_PH_DSP,
 598    OPC_PRECEU_PH_QBLA  = (0x1E << 6) | OPC_ABSQ_S_PH_DSP,
 599    OPC_PRECEU_PH_QBRA  = (0x1F << 6) | OPC_ABSQ_S_PH_DSP,
 600    /* DSP Bit/Manipulation Sub-class */
 601    OPC_BITREV          = (0x1B << 6) | OPC_ABSQ_S_PH_DSP,
 602    OPC_REPL_QB         = (0x02 << 6) | OPC_ABSQ_S_PH_DSP,
 603    OPC_REPLV_QB        = (0x03 << 6) | OPC_ABSQ_S_PH_DSP,
 604    OPC_REPL_PH         = (0x0A << 6) | OPC_ABSQ_S_PH_DSP,
 605    OPC_REPLV_PH        = (0x0B << 6) | OPC_ABSQ_S_PH_DSP,
 606};
 607
 608#define MASK_CMPU_EQ_QB(op)         (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
 609enum {
 610    /* MIPS DSP Arithmetic Sub-class */
 611    OPC_PRECR_QB_PH      = (0x0D << 6) | OPC_CMPU_EQ_QB_DSP,
 612    OPC_PRECRQ_QB_PH     = (0x0C << 6) | OPC_CMPU_EQ_QB_DSP,
 613    OPC_PRECR_SRA_PH_W   = (0x1E << 6) | OPC_CMPU_EQ_QB_DSP,
 614    OPC_PRECR_SRA_R_PH_W = (0x1F << 6) | OPC_CMPU_EQ_QB_DSP,
 615    OPC_PRECRQ_PH_W      = (0x14 << 6) | OPC_CMPU_EQ_QB_DSP,
 616    OPC_PRECRQ_RS_PH_W   = (0x15 << 6) | OPC_CMPU_EQ_QB_DSP,
 617    OPC_PRECRQU_S_QB_PH  = (0x0F << 6) | OPC_CMPU_EQ_QB_DSP,
 618    /* DSP Compare-Pick Sub-class */
 619    OPC_CMPU_EQ_QB       = (0x00 << 6) | OPC_CMPU_EQ_QB_DSP,
 620    OPC_CMPU_LT_QB       = (0x01 << 6) | OPC_CMPU_EQ_QB_DSP,
 621    OPC_CMPU_LE_QB       = (0x02 << 6) | OPC_CMPU_EQ_QB_DSP,
 622    OPC_CMPGU_EQ_QB      = (0x04 << 6) | OPC_CMPU_EQ_QB_DSP,
 623    OPC_CMPGU_LT_QB      = (0x05 << 6) | OPC_CMPU_EQ_QB_DSP,
 624    OPC_CMPGU_LE_QB      = (0x06 << 6) | OPC_CMPU_EQ_QB_DSP,
 625    OPC_CMPGDU_EQ_QB     = (0x18 << 6) | OPC_CMPU_EQ_QB_DSP,
 626    OPC_CMPGDU_LT_QB     = (0x19 << 6) | OPC_CMPU_EQ_QB_DSP,
 627    OPC_CMPGDU_LE_QB     = (0x1A << 6) | OPC_CMPU_EQ_QB_DSP,
 628    OPC_CMP_EQ_PH        = (0x08 << 6) | OPC_CMPU_EQ_QB_DSP,
 629    OPC_CMP_LT_PH        = (0x09 << 6) | OPC_CMPU_EQ_QB_DSP,
 630    OPC_CMP_LE_PH        = (0x0A << 6) | OPC_CMPU_EQ_QB_DSP,
 631    OPC_PICK_QB          = (0x03 << 6) | OPC_CMPU_EQ_QB_DSP,
 632    OPC_PICK_PH          = (0x0B << 6) | OPC_CMPU_EQ_QB_DSP,
 633    OPC_PACKRL_PH        = (0x0E << 6) | OPC_CMPU_EQ_QB_DSP,
 634};
 635
 636#define MASK_SHLL_QB(op)            (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
 637enum {
 638    /* MIPS DSP GPR-Based Shift Sub-class */
 639    OPC_SHLL_QB    = (0x00 << 6) | OPC_SHLL_QB_DSP,
 640    OPC_SHLLV_QB   = (0x02 << 6) | OPC_SHLL_QB_DSP,
 641    OPC_SHLL_PH    = (0x08 << 6) | OPC_SHLL_QB_DSP,
 642    OPC_SHLLV_PH   = (0x0A << 6) | OPC_SHLL_QB_DSP,
 643    OPC_SHLL_S_PH  = (0x0C << 6) | OPC_SHLL_QB_DSP,
 644    OPC_SHLLV_S_PH = (0x0E << 6) | OPC_SHLL_QB_DSP,
 645    OPC_SHLL_S_W   = (0x14 << 6) | OPC_SHLL_QB_DSP,
 646    OPC_SHLLV_S_W  = (0x16 << 6) | OPC_SHLL_QB_DSP,
 647    OPC_SHRL_QB    = (0x01 << 6) | OPC_SHLL_QB_DSP,
 648    OPC_SHRLV_QB   = (0x03 << 6) | OPC_SHLL_QB_DSP,
 649    OPC_SHRL_PH    = (0x19 << 6) | OPC_SHLL_QB_DSP,
 650    OPC_SHRLV_PH   = (0x1B << 6) | OPC_SHLL_QB_DSP,
 651    OPC_SHRA_QB    = (0x04 << 6) | OPC_SHLL_QB_DSP,
 652    OPC_SHRA_R_QB  = (0x05 << 6) | OPC_SHLL_QB_DSP,
 653    OPC_SHRAV_QB   = (0x06 << 6) | OPC_SHLL_QB_DSP,
 654    OPC_SHRAV_R_QB = (0x07 << 6) | OPC_SHLL_QB_DSP,
 655    OPC_SHRA_PH    = (0x09 << 6) | OPC_SHLL_QB_DSP,
 656    OPC_SHRAV_PH   = (0x0B << 6) | OPC_SHLL_QB_DSP,
 657    OPC_SHRA_R_PH  = (0x0D << 6) | OPC_SHLL_QB_DSP,
 658    OPC_SHRAV_R_PH = (0x0F << 6) | OPC_SHLL_QB_DSP,
 659    OPC_SHRA_R_W   = (0x15 << 6) | OPC_SHLL_QB_DSP,
 660    OPC_SHRAV_R_W  = (0x17 << 6) | OPC_SHLL_QB_DSP,
 661};
 662
 663#define MASK_DPA_W_PH(op)           (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
 664enum {
 665    /* MIPS DSP Multiply Sub-class insns */
 666    OPC_DPAU_H_QBL    = (0x03 << 6) | OPC_DPA_W_PH_DSP,
 667    OPC_DPAU_H_QBR    = (0x07 << 6) | OPC_DPA_W_PH_DSP,
 668    OPC_DPSU_H_QBL    = (0x0B << 6) | OPC_DPA_W_PH_DSP,
 669    OPC_DPSU_H_QBR    = (0x0F << 6) | OPC_DPA_W_PH_DSP,
 670    OPC_DPA_W_PH      = (0x00 << 6) | OPC_DPA_W_PH_DSP,
 671    OPC_DPAX_W_PH     = (0x08 << 6) | OPC_DPA_W_PH_DSP,
 672    OPC_DPAQ_S_W_PH   = (0x04 << 6) | OPC_DPA_W_PH_DSP,
 673    OPC_DPAQX_S_W_PH  = (0x18 << 6) | OPC_DPA_W_PH_DSP,
 674    OPC_DPAQX_SA_W_PH = (0x1A << 6) | OPC_DPA_W_PH_DSP,
 675    OPC_DPS_W_PH      = (0x01 << 6) | OPC_DPA_W_PH_DSP,
 676    OPC_DPSX_W_PH     = (0x09 << 6) | OPC_DPA_W_PH_DSP,
 677    OPC_DPSQ_S_W_PH   = (0x05 << 6) | OPC_DPA_W_PH_DSP,
 678    OPC_DPSQX_S_W_PH  = (0x19 << 6) | OPC_DPA_W_PH_DSP,
 679    OPC_DPSQX_SA_W_PH = (0x1B << 6) | OPC_DPA_W_PH_DSP,
 680    OPC_MULSAQ_S_W_PH = (0x06 << 6) | OPC_DPA_W_PH_DSP,
 681    OPC_DPAQ_SA_L_W   = (0x0C << 6) | OPC_DPA_W_PH_DSP,
 682    OPC_DPSQ_SA_L_W   = (0x0D << 6) | OPC_DPA_W_PH_DSP,
 683    OPC_MAQ_S_W_PHL   = (0x14 << 6) | OPC_DPA_W_PH_DSP,
 684    OPC_MAQ_S_W_PHR   = (0x16 << 6) | OPC_DPA_W_PH_DSP,
 685    OPC_MAQ_SA_W_PHL  = (0x10 << 6) | OPC_DPA_W_PH_DSP,
 686    OPC_MAQ_SA_W_PHR  = (0x12 << 6) | OPC_DPA_W_PH_DSP,
 687    OPC_MULSA_W_PH    = (0x02 << 6) | OPC_DPA_W_PH_DSP,
 688};
 689
 690#define MASK_INSV(op)               (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
 691enum {
 692    /* DSP Bit/Manipulation Sub-class */
 693    OPC_INSV = (0x00 << 6) | OPC_INSV_DSP,
 694};
 695
 696#define MASK_APPEND(op)             (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
 697enum {
 698    /* MIPS DSP Append Sub-class */
 699    OPC_APPEND  = (0x00 << 6) | OPC_APPEND_DSP,
 700    OPC_PREPEND = (0x01 << 6) | OPC_APPEND_DSP,
 701    OPC_BALIGN  = (0x10 << 6) | OPC_APPEND_DSP,
 702};
 703
 704#define MASK_EXTR_W(op)             (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
 705enum {
 706    /* MIPS DSP Accumulator and DSPControl Access Sub-class */
 707    OPC_EXTR_W     = (0x00 << 6) | OPC_EXTR_W_DSP,
 708    OPC_EXTR_R_W   = (0x04 << 6) | OPC_EXTR_W_DSP,
 709    OPC_EXTR_RS_W  = (0x06 << 6) | OPC_EXTR_W_DSP,
 710    OPC_EXTR_S_H   = (0x0E << 6) | OPC_EXTR_W_DSP,
 711    OPC_EXTRV_S_H  = (0x0F << 6) | OPC_EXTR_W_DSP,
 712    OPC_EXTRV_W    = (0x01 << 6) | OPC_EXTR_W_DSP,
 713    OPC_EXTRV_R_W  = (0x05 << 6) | OPC_EXTR_W_DSP,
 714    OPC_EXTRV_RS_W = (0x07 << 6) | OPC_EXTR_W_DSP,
 715    OPC_EXTP       = (0x02 << 6) | OPC_EXTR_W_DSP,
 716    OPC_EXTPV      = (0x03 << 6) | OPC_EXTR_W_DSP,
 717    OPC_EXTPDP     = (0x0A << 6) | OPC_EXTR_W_DSP,
 718    OPC_EXTPDPV    = (0x0B << 6) | OPC_EXTR_W_DSP,
 719    OPC_SHILO      = (0x1A << 6) | OPC_EXTR_W_DSP,
 720    OPC_SHILOV     = (0x1B << 6) | OPC_EXTR_W_DSP,
 721    OPC_MTHLIP     = (0x1F << 6) | OPC_EXTR_W_DSP,
 722    OPC_WRDSP      = (0x13 << 6) | OPC_EXTR_W_DSP,
 723    OPC_RDDSP      = (0x12 << 6) | OPC_EXTR_W_DSP,
 724};
 725
 726#define MASK_ABSQ_S_QH(op)          (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
 727enum {
 728    /* MIPS DSP Arithmetic Sub-class */
 729    OPC_PRECEQ_L_PWL    = (0x14 << 6) | OPC_ABSQ_S_QH_DSP,
 730    OPC_PRECEQ_L_PWR    = (0x15 << 6) | OPC_ABSQ_S_QH_DSP,
 731    OPC_PRECEQ_PW_QHL   = (0x0C << 6) | OPC_ABSQ_S_QH_DSP,
 732    OPC_PRECEQ_PW_QHR   = (0x0D << 6) | OPC_ABSQ_S_QH_DSP,
 733    OPC_PRECEQ_PW_QHLA  = (0x0E << 6) | OPC_ABSQ_S_QH_DSP,
 734    OPC_PRECEQ_PW_QHRA  = (0x0F << 6) | OPC_ABSQ_S_QH_DSP,
 735    OPC_PRECEQU_QH_OBL  = (0x04 << 6) | OPC_ABSQ_S_QH_DSP,
 736    OPC_PRECEQU_QH_OBR  = (0x05 << 6) | OPC_ABSQ_S_QH_DSP,
 737    OPC_PRECEQU_QH_OBLA = (0x06 << 6) | OPC_ABSQ_S_QH_DSP,
 738    OPC_PRECEQU_QH_OBRA = (0x07 << 6) | OPC_ABSQ_S_QH_DSP,
 739    OPC_PRECEU_QH_OBL   = (0x1C << 6) | OPC_ABSQ_S_QH_DSP,
 740    OPC_PRECEU_QH_OBR   = (0x1D << 6) | OPC_ABSQ_S_QH_DSP,
 741    OPC_PRECEU_QH_OBLA  = (0x1E << 6) | OPC_ABSQ_S_QH_DSP,
 742    OPC_PRECEU_QH_OBRA  = (0x1F << 6) | OPC_ABSQ_S_QH_DSP,
 743    OPC_ABSQ_S_OB       = (0x01 << 6) | OPC_ABSQ_S_QH_DSP,
 744    OPC_ABSQ_S_PW       = (0x11 << 6) | OPC_ABSQ_S_QH_DSP,
 745    OPC_ABSQ_S_QH       = (0x09 << 6) | OPC_ABSQ_S_QH_DSP,
 746    /* DSP Bit/Manipulation Sub-class */
 747    OPC_REPL_OB         = (0x02 << 6) | OPC_ABSQ_S_QH_DSP,
 748    OPC_REPL_PW         = (0x12 << 6) | OPC_ABSQ_S_QH_DSP,
 749    OPC_REPL_QH         = (0x0A << 6) | OPC_ABSQ_S_QH_DSP,
 750    OPC_REPLV_OB        = (0x03 << 6) | OPC_ABSQ_S_QH_DSP,
 751    OPC_REPLV_PW        = (0x13 << 6) | OPC_ABSQ_S_QH_DSP,
 752    OPC_REPLV_QH        = (0x0B << 6) | OPC_ABSQ_S_QH_DSP,
 753};
 754
 755#define MASK_ADDU_OB(op)            (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
 756enum {
 757    /* MIPS DSP Multiply Sub-class insns */
 758    OPC_MULEQ_S_PW_QHL = (0x1C << 6) | OPC_ADDU_OB_DSP,
 759    OPC_MULEQ_S_PW_QHR = (0x1D << 6) | OPC_ADDU_OB_DSP,
 760    OPC_MULEU_S_QH_OBL = (0x06 << 6) | OPC_ADDU_OB_DSP,
 761    OPC_MULEU_S_QH_OBR = (0x07 << 6) | OPC_ADDU_OB_DSP,
 762    OPC_MULQ_RS_QH     = (0x1F << 6) | OPC_ADDU_OB_DSP,
 763    /* MIPS DSP Arithmetic Sub-class */
 764    OPC_RADDU_L_OB     = (0x14 << 6) | OPC_ADDU_OB_DSP,
 765    OPC_SUBQ_PW        = (0x13 << 6) | OPC_ADDU_OB_DSP,
 766    OPC_SUBQ_S_PW      = (0x17 << 6) | OPC_ADDU_OB_DSP,
 767    OPC_SUBQ_QH        = (0x0B << 6) | OPC_ADDU_OB_DSP,
 768    OPC_SUBQ_S_QH      = (0x0F << 6) | OPC_ADDU_OB_DSP,
 769    OPC_SUBU_OB        = (0x01 << 6) | OPC_ADDU_OB_DSP,
 770    OPC_SUBU_S_OB      = (0x05 << 6) | OPC_ADDU_OB_DSP,
 771    OPC_SUBU_QH        = (0x09 << 6) | OPC_ADDU_OB_DSP,
 772    OPC_SUBU_S_QH      = (0x0D << 6) | OPC_ADDU_OB_DSP,
 773    OPC_SUBUH_OB       = (0x19 << 6) | OPC_ADDU_OB_DSP,
 774    OPC_SUBUH_R_OB     = (0x1B << 6) | OPC_ADDU_OB_DSP,
 775    OPC_ADDQ_PW        = (0x12 << 6) | OPC_ADDU_OB_DSP,
 776    OPC_ADDQ_S_PW      = (0x16 << 6) | OPC_ADDU_OB_DSP,
 777    OPC_ADDQ_QH        = (0x0A << 6) | OPC_ADDU_OB_DSP,
 778    OPC_ADDQ_S_QH      = (0x0E << 6) | OPC_ADDU_OB_DSP,
 779    OPC_ADDU_OB        = (0x00 << 6) | OPC_ADDU_OB_DSP,
 780    OPC_ADDU_S_OB      = (0x04 << 6) | OPC_ADDU_OB_DSP,
 781    OPC_ADDU_QH        = (0x08 << 6) | OPC_ADDU_OB_DSP,
 782    OPC_ADDU_S_QH      = (0x0C << 6) | OPC_ADDU_OB_DSP,
 783    OPC_ADDUH_OB       = (0x18 << 6) | OPC_ADDU_OB_DSP,
 784    OPC_ADDUH_R_OB     = (0x1A << 6) | OPC_ADDU_OB_DSP,
 785};
 786
 787#define MASK_CMPU_EQ_OB(op)         (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
 788enum {
 789    /* DSP Compare-Pick Sub-class */
 790    OPC_CMP_EQ_PW         = (0x10 << 6) | OPC_CMPU_EQ_OB_DSP,
 791    OPC_CMP_LT_PW         = (0x11 << 6) | OPC_CMPU_EQ_OB_DSP,
 792    OPC_CMP_LE_PW         = (0x12 << 6) | OPC_CMPU_EQ_OB_DSP,
 793    OPC_CMP_EQ_QH         = (0x08 << 6) | OPC_CMPU_EQ_OB_DSP,
 794    OPC_CMP_LT_QH         = (0x09 << 6) | OPC_CMPU_EQ_OB_DSP,
 795    OPC_CMP_LE_QH         = (0x0A << 6) | OPC_CMPU_EQ_OB_DSP,
 796    OPC_CMPGDU_EQ_OB      = (0x18 << 6) | OPC_CMPU_EQ_OB_DSP,
 797    OPC_CMPGDU_LT_OB      = (0x19 << 6) | OPC_CMPU_EQ_OB_DSP,
 798    OPC_CMPGDU_LE_OB      = (0x1A << 6) | OPC_CMPU_EQ_OB_DSP,
 799    OPC_CMPGU_EQ_OB       = (0x04 << 6) | OPC_CMPU_EQ_OB_DSP,
 800    OPC_CMPGU_LT_OB       = (0x05 << 6) | OPC_CMPU_EQ_OB_DSP,
 801    OPC_CMPGU_LE_OB       = (0x06 << 6) | OPC_CMPU_EQ_OB_DSP,
 802    OPC_CMPU_EQ_OB        = (0x00 << 6) | OPC_CMPU_EQ_OB_DSP,
 803    OPC_CMPU_LT_OB        = (0x01 << 6) | OPC_CMPU_EQ_OB_DSP,
 804    OPC_CMPU_LE_OB        = (0x02 << 6) | OPC_CMPU_EQ_OB_DSP,
 805    OPC_PACKRL_PW         = (0x0E << 6) | OPC_CMPU_EQ_OB_DSP,
 806    OPC_PICK_OB           = (0x03 << 6) | OPC_CMPU_EQ_OB_DSP,
 807    OPC_PICK_PW           = (0x13 << 6) | OPC_CMPU_EQ_OB_DSP,
 808    OPC_PICK_QH           = (0x0B << 6) | OPC_CMPU_EQ_OB_DSP,
 809    /* MIPS DSP Arithmetic Sub-class */
 810    OPC_PRECR_OB_QH       = (0x0D << 6) | OPC_CMPU_EQ_OB_DSP,
 811    OPC_PRECR_SRA_QH_PW   = (0x1E << 6) | OPC_CMPU_EQ_OB_DSP,
 812    OPC_PRECR_SRA_R_QH_PW = (0x1F << 6) | OPC_CMPU_EQ_OB_DSP,
 813    OPC_PRECRQ_OB_QH      = (0x0C << 6) | OPC_CMPU_EQ_OB_DSP,
 814    OPC_PRECRQ_PW_L       = (0x1C << 6) | OPC_CMPU_EQ_OB_DSP,
 815    OPC_PRECRQ_QH_PW      = (0x14 << 6) | OPC_CMPU_EQ_OB_DSP,
 816    OPC_PRECRQ_RS_QH_PW   = (0x15 << 6) | OPC_CMPU_EQ_OB_DSP,
 817    OPC_PRECRQU_S_OB_QH   = (0x0F << 6) | OPC_CMPU_EQ_OB_DSP,
 818};
 819
 820#define MASK_DAPPEND(op)            (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
 821enum {
 822    /* DSP Append Sub-class */
 823    OPC_DAPPEND  = (0x00 << 6) | OPC_DAPPEND_DSP,
 824    OPC_PREPENDD = (0x03 << 6) | OPC_DAPPEND_DSP,
 825    OPC_PREPENDW = (0x01 << 6) | OPC_DAPPEND_DSP,
 826    OPC_DBALIGN  = (0x10 << 6) | OPC_DAPPEND_DSP,
 827};
 828
 829#define MASK_DEXTR_W(op)            (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
 830enum {
 831    /* MIPS DSP Accumulator and DSPControl Access Sub-class */
 832    OPC_DMTHLIP     = (0x1F << 6) | OPC_DEXTR_W_DSP,
 833    OPC_DSHILO      = (0x1A << 6) | OPC_DEXTR_W_DSP,
 834    OPC_DEXTP       = (0x02 << 6) | OPC_DEXTR_W_DSP,
 835    OPC_DEXTPDP     = (0x0A << 6) | OPC_DEXTR_W_DSP,
 836    OPC_DEXTPDPV    = (0x0B << 6) | OPC_DEXTR_W_DSP,
 837    OPC_DEXTPV      = (0x03 << 6) | OPC_DEXTR_W_DSP,
 838    OPC_DEXTR_L     = (0x10 << 6) | OPC_DEXTR_W_DSP,
 839    OPC_DEXTR_R_L   = (0x14 << 6) | OPC_DEXTR_W_DSP,
 840    OPC_DEXTR_RS_L  = (0x16 << 6) | OPC_DEXTR_W_DSP,
 841    OPC_DEXTR_W     = (0x00 << 6) | OPC_DEXTR_W_DSP,
 842    OPC_DEXTR_R_W   = (0x04 << 6) | OPC_DEXTR_W_DSP,
 843    OPC_DEXTR_RS_W  = (0x06 << 6) | OPC_DEXTR_W_DSP,
 844    OPC_DEXTR_S_H   = (0x0E << 6) | OPC_DEXTR_W_DSP,
 845    OPC_DEXTRV_L    = (0x11 << 6) | OPC_DEXTR_W_DSP,
 846    OPC_DEXTRV_R_L  = (0x15 << 6) | OPC_DEXTR_W_DSP,
 847    OPC_DEXTRV_RS_L = (0x17 << 6) | OPC_DEXTR_W_DSP,
 848    OPC_DEXTRV_S_H  = (0x0F << 6) | OPC_DEXTR_W_DSP,
 849    OPC_DEXTRV_W    = (0x01 << 6) | OPC_DEXTR_W_DSP,
 850    OPC_DEXTRV_R_W  = (0x05 << 6) | OPC_DEXTR_W_DSP,
 851    OPC_DEXTRV_RS_W = (0x07 << 6) | OPC_DEXTR_W_DSP,
 852    OPC_DSHILOV     = (0x1B << 6) | OPC_DEXTR_W_DSP,
 853};
 854
 855#define MASK_DINSV(op)              (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
 856enum {
 857    /* DSP Bit/Manipulation Sub-class */
 858    OPC_DINSV = (0x00 << 6) | OPC_DINSV_DSP,
 859};
 860
 861#define MASK_DPAQ_W_QH(op)          (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
 862enum {
 863    /* MIPS DSP Multiply Sub-class insns */
 864    OPC_DMADD         = (0x19 << 6) | OPC_DPAQ_W_QH_DSP,
 865    OPC_DMADDU        = (0x1D << 6) | OPC_DPAQ_W_QH_DSP,
 866    OPC_DMSUB         = (0x1B << 6) | OPC_DPAQ_W_QH_DSP,
 867    OPC_DMSUBU        = (0x1F << 6) | OPC_DPAQ_W_QH_DSP,
 868    OPC_DPA_W_QH      = (0x00 << 6) | OPC_DPAQ_W_QH_DSP,
 869    OPC_DPAQ_S_W_QH   = (0x04 << 6) | OPC_DPAQ_W_QH_DSP,
 870    OPC_DPAQ_SA_L_PW  = (0x0C << 6) | OPC_DPAQ_W_QH_DSP,
 871    OPC_DPAU_H_OBL    = (0x03 << 6) | OPC_DPAQ_W_QH_DSP,
 872    OPC_DPAU_H_OBR    = (0x07 << 6) | OPC_DPAQ_W_QH_DSP,
 873    OPC_DPS_W_QH      = (0x01 << 6) | OPC_DPAQ_W_QH_DSP,
 874    OPC_DPSQ_S_W_QH   = (0x05 << 6) | OPC_DPAQ_W_QH_DSP,
 875    OPC_DPSQ_SA_L_PW  = (0x0D << 6) | OPC_DPAQ_W_QH_DSP,
 876    OPC_DPSU_H_OBL    = (0x0B << 6) | OPC_DPAQ_W_QH_DSP,
 877    OPC_DPSU_H_OBR    = (0x0F << 6) | OPC_DPAQ_W_QH_DSP,
 878    OPC_MAQ_S_L_PWL   = (0x1C << 6) | OPC_DPAQ_W_QH_DSP,
 879    OPC_MAQ_S_L_PWR   = (0x1E << 6) | OPC_DPAQ_W_QH_DSP,
 880    OPC_MAQ_S_W_QHLL  = (0x14 << 6) | OPC_DPAQ_W_QH_DSP,
 881    OPC_MAQ_SA_W_QHLL = (0x10 << 6) | OPC_DPAQ_W_QH_DSP,
 882    OPC_MAQ_S_W_QHLR  = (0x15 << 6) | OPC_DPAQ_W_QH_DSP,
 883    OPC_MAQ_SA_W_QHLR = (0x11 << 6) | OPC_DPAQ_W_QH_DSP,
 884    OPC_MAQ_S_W_QHRL  = (0x16 << 6) | OPC_DPAQ_W_QH_DSP,
 885    OPC_MAQ_SA_W_QHRL = (0x12 << 6) | OPC_DPAQ_W_QH_DSP,
 886    OPC_MAQ_S_W_QHRR  = (0x17 << 6) | OPC_DPAQ_W_QH_DSP,
 887    OPC_MAQ_SA_W_QHRR = (0x13 << 6) | OPC_DPAQ_W_QH_DSP,
 888    OPC_MULSAQ_S_L_PW = (0x0E << 6) | OPC_DPAQ_W_QH_DSP,
 889    OPC_MULSAQ_S_W_QH = (0x06 << 6) | OPC_DPAQ_W_QH_DSP,
 890};
 891
 892#define MASK_SHLL_OB(op)            (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
 893enum {
 894    /* MIPS DSP GPR-Based Shift Sub-class */
 895    OPC_SHLL_PW    = (0x10 << 6) | OPC_SHLL_OB_DSP,
 896    OPC_SHLL_S_PW  = (0x14 << 6) | OPC_SHLL_OB_DSP,
 897    OPC_SHLLV_OB   = (0x02 << 6) | OPC_SHLL_OB_DSP,
 898    OPC_SHLLV_PW   = (0x12 << 6) | OPC_SHLL_OB_DSP,
 899    OPC_SHLLV_S_PW = (0x16 << 6) | OPC_SHLL_OB_DSP,
 900    OPC_SHLLV_QH   = (0x0A << 6) | OPC_SHLL_OB_DSP,
 901    OPC_SHLLV_S_QH = (0x0E << 6) | OPC_SHLL_OB_DSP,
 902    OPC_SHRA_PW    = (0x11 << 6) | OPC_SHLL_OB_DSP,
 903    OPC_SHRA_R_PW  = (0x15 << 6) | OPC_SHLL_OB_DSP,
 904    OPC_SHRAV_OB   = (0x06 << 6) | OPC_SHLL_OB_DSP,
 905    OPC_SHRAV_R_OB = (0x07 << 6) | OPC_SHLL_OB_DSP,
 906    OPC_SHRAV_PW   = (0x13 << 6) | OPC_SHLL_OB_DSP,
 907    OPC_SHRAV_R_PW = (0x17 << 6) | OPC_SHLL_OB_DSP,
 908    OPC_SHRAV_QH   = (0x0B << 6) | OPC_SHLL_OB_DSP,
 909    OPC_SHRAV_R_QH = (0x0F << 6) | OPC_SHLL_OB_DSP,
 910    OPC_SHRLV_OB   = (0x03 << 6) | OPC_SHLL_OB_DSP,
 911    OPC_SHRLV_QH   = (0x1B << 6) | OPC_SHLL_OB_DSP,
 912    OPC_SHLL_OB    = (0x00 << 6) | OPC_SHLL_OB_DSP,
 913    OPC_SHLL_QH    = (0x08 << 6) | OPC_SHLL_OB_DSP,
 914    OPC_SHLL_S_QH  = (0x0C << 6) | OPC_SHLL_OB_DSP,
 915    OPC_SHRA_OB    = (0x04 << 6) | OPC_SHLL_OB_DSP,
 916    OPC_SHRA_R_OB  = (0x05 << 6) | OPC_SHLL_OB_DSP,
 917    OPC_SHRA_QH    = (0x09 << 6) | OPC_SHLL_OB_DSP,
 918    OPC_SHRA_R_QH  = (0x0D << 6) | OPC_SHLL_OB_DSP,
 919    OPC_SHRL_OB    = (0x01 << 6) | OPC_SHLL_OB_DSP,
 920    OPC_SHRL_QH    = (0x19 << 6) | OPC_SHLL_OB_DSP,
 921};
 922
 923/* Coprocessor 0 (rs field) */
 924#define MASK_CP0(op)                (MASK_OP_MAJOR(op) | (op & (0x1F << 21)))
 925
 926enum {
 927    OPC_MFC0     = (0x00 << 21) | OPC_CP0,
 928    OPC_DMFC0    = (0x01 << 21) | OPC_CP0,
 929    OPC_MFHC0    = (0x02 << 21) | OPC_CP0,
 930    OPC_MTC0     = (0x04 << 21) | OPC_CP0,
 931    OPC_DMTC0    = (0x05 << 21) | OPC_CP0,
 932    OPC_MTHC0    = (0x06 << 21) | OPC_CP0,
 933    OPC_MFTR     = (0x08 << 21) | OPC_CP0,
 934    OPC_RDPGPR   = (0x0A << 21) | OPC_CP0,
 935    OPC_MFMC0    = (0x0B << 21) | OPC_CP0,
 936    OPC_MTTR     = (0x0C << 21) | OPC_CP0,
 937    OPC_WRPGPR   = (0x0E << 21) | OPC_CP0,
 938    OPC_C0       = (0x10 << 21) | OPC_CP0,
 939    OPC_C0_1     = (0x11 << 21) | OPC_CP0,
 940    OPC_C0_2     = (0x12 << 21) | OPC_CP0,
 941    OPC_C0_3     = (0x13 << 21) | OPC_CP0,
 942    OPC_C0_4     = (0x14 << 21) | OPC_CP0,
 943    OPC_C0_5     = (0x15 << 21) | OPC_CP0,
 944    OPC_C0_6     = (0x16 << 21) | OPC_CP0,
 945    OPC_C0_7     = (0x17 << 21) | OPC_CP0,
 946    OPC_C0_8     = (0x18 << 21) | OPC_CP0,
 947    OPC_C0_9     = (0x19 << 21) | OPC_CP0,
 948    OPC_C0_A     = (0x1A << 21) | OPC_CP0,
 949    OPC_C0_B     = (0x1B << 21) | OPC_CP0,
 950    OPC_C0_C     = (0x1C << 21) | OPC_CP0,
 951    OPC_C0_D     = (0x1D << 21) | OPC_CP0,
 952    OPC_C0_E     = (0x1E << 21) | OPC_CP0,
 953    OPC_C0_F     = (0x1F << 21) | OPC_CP0,
 954};
 955
 956/* MFMC0 opcodes */
 957#define MASK_MFMC0(op)              (MASK_CP0(op) | (op & 0xFFFF))
 958
 959enum {
 960    OPC_DMT      = 0x01 | (0 << 5) | (0x0F << 6) | (0x01 << 11) | OPC_MFMC0,
 961    OPC_EMT      = 0x01 | (1 << 5) | (0x0F << 6) | (0x01 << 11) | OPC_MFMC0,
 962    OPC_DVPE     = 0x01 | (0 << 5) | OPC_MFMC0,
 963    OPC_EVPE     = 0x01 | (1 << 5) | OPC_MFMC0,
 964    OPC_DI       = (0 << 5) | (0x0C << 11) | OPC_MFMC0,
 965    OPC_EI       = (1 << 5) | (0x0C << 11) | OPC_MFMC0,
 966    OPC_DVP      = 0x04 | (0 << 3) | (1 << 5) | (0 << 11) | OPC_MFMC0,
 967    OPC_EVP      = 0x04 | (0 << 3) | (0 << 5) | (0 << 11) | OPC_MFMC0,
 968};
 969
 970/* Coprocessor 0 (with rs == C0) */
 971#define MASK_C0(op)                 (MASK_CP0(op) | (op & 0x3F))
 972
 973enum {
 974    OPC_TLBR     = 0x01 | OPC_C0,
 975    OPC_TLBWI    = 0x02 | OPC_C0,
 976    OPC_TLBINV   = 0x03 | OPC_C0,
 977    OPC_TLBINVF  = 0x04 | OPC_C0,
 978    OPC_TLBWR    = 0x06 | OPC_C0,
 979    OPC_TLBP     = 0x08 | OPC_C0,
 980    OPC_RFE      = 0x10 | OPC_C0,
 981    OPC_ERET     = 0x18 | OPC_C0,
 982    OPC_DERET    = 0x1F | OPC_C0,
 983    OPC_WAIT     = 0x20 | OPC_C0,
 984};
 985
 986#define MASK_CP2(op)                (MASK_OP_MAJOR(op) | (op & (0x1F << 21)))
 987
 988enum {
 989    OPC_MFC2    = (0x00 << 21) | OPC_CP2,
 990    OPC_DMFC2   = (0x01 << 21) | OPC_CP2,
 991    OPC_CFC2    = (0x02 << 21) | OPC_CP2,
 992    OPC_MFHC2   = (0x03 << 21) | OPC_CP2,
 993    OPC_MTC2    = (0x04 << 21) | OPC_CP2,
 994    OPC_DMTC2   = (0x05 << 21) | OPC_CP2,
 995    OPC_CTC2    = (0x06 << 21) | OPC_CP2,
 996    OPC_MTHC2   = (0x07 << 21) | OPC_CP2,
 997    OPC_BC2     = (0x08 << 21) | OPC_CP2,
 998    OPC_BC2EQZ  = (0x09 << 21) | OPC_CP2,
 999    OPC_BC2NEZ  = (0x0D << 21) | OPC_CP2,
1000};
1001
1002#define MASK_LMMI(op)    (MASK_OP_MAJOR(op) | (op & (0x1F << 21)) | (op & 0x1F))
1003
1004enum {
1005    OPC_PADDSH      = (24 << 21) | (0x00) | OPC_CP2,
1006    OPC_PADDUSH     = (25 << 21) | (0x00) | OPC_CP2,
1007    OPC_PADDH       = (26 << 21) | (0x00) | OPC_CP2,
1008    OPC_PADDW       = (27 << 21) | (0x00) | OPC_CP2,
1009    OPC_PADDSB      = (28 << 21) | (0x00) | OPC_CP2,
1010    OPC_PADDUSB     = (29 << 21) | (0x00) | OPC_CP2,
1011    OPC_PADDB       = (30 << 21) | (0x00) | OPC_CP2,
1012    OPC_PADDD       = (31 << 21) | (0x00) | OPC_CP2,
1013
1014    OPC_PSUBSH      = (24 << 21) | (0x01) | OPC_CP2,
1015    OPC_PSUBUSH     = (25 << 21) | (0x01) | OPC_CP2,
1016    OPC_PSUBH       = (26 << 21) | (0x01) | OPC_CP2,
1017    OPC_PSUBW       = (27 << 21) | (0x01) | OPC_CP2,
1018    OPC_PSUBSB      = (28 << 21) | (0x01) | OPC_CP2,
1019    OPC_PSUBUSB     = (29 << 21) | (0x01) | OPC_CP2,
1020    OPC_PSUBB       = (30 << 21) | (0x01) | OPC_CP2,
1021    OPC_PSUBD       = (31 << 21) | (0x01) | OPC_CP2,
1022
1023    OPC_PSHUFH      = (24 << 21) | (0x02) | OPC_CP2,
1024    OPC_PACKSSWH    = (25 << 21) | (0x02) | OPC_CP2,
1025    OPC_PACKSSHB    = (26 << 21) | (0x02) | OPC_CP2,
1026    OPC_PACKUSHB    = (27 << 21) | (0x02) | OPC_CP2,
1027    OPC_XOR_CP2     = (28 << 21) | (0x02) | OPC_CP2,
1028    OPC_NOR_CP2     = (29 << 21) | (0x02) | OPC_CP2,
1029    OPC_AND_CP2     = (30 << 21) | (0x02) | OPC_CP2,
1030    OPC_PANDN       = (31 << 21) | (0x02) | OPC_CP2,
1031
1032    OPC_PUNPCKLHW   = (24 << 21) | (0x03) | OPC_CP2,
1033    OPC_PUNPCKHHW   = (25 << 21) | (0x03) | OPC_CP2,
1034    OPC_PUNPCKLBH   = (26 << 21) | (0x03) | OPC_CP2,
1035    OPC_PUNPCKHBH   = (27 << 21) | (0x03) | OPC_CP2,
1036    OPC_PINSRH_0    = (28 << 21) | (0x03) | OPC_CP2,
1037    OPC_PINSRH_1    = (29 << 21) | (0x03) | OPC_CP2,
1038    OPC_PINSRH_2    = (30 << 21) | (0x03) | OPC_CP2,
1039    OPC_PINSRH_3    = (31 << 21) | (0x03) | OPC_CP2,
1040
1041    OPC_PAVGH       = (24 << 21) | (0x08) | OPC_CP2,
1042    OPC_PAVGB       = (25 << 21) | (0x08) | OPC_CP2,
1043    OPC_PMAXSH      = (26 << 21) | (0x08) | OPC_CP2,
1044    OPC_PMINSH      = (27 << 21) | (0x08) | OPC_CP2,
1045    OPC_PMAXUB      = (28 << 21) | (0x08) | OPC_CP2,
1046    OPC_PMINUB      = (29 << 21) | (0x08) | OPC_CP2,
1047
1048    OPC_PCMPEQW     = (24 << 21) | (0x09) | OPC_CP2,
1049    OPC_PCMPGTW     = (25 << 21) | (0x09) | OPC_CP2,
1050    OPC_PCMPEQH     = (26 << 21) | (0x09) | OPC_CP2,
1051    OPC_PCMPGTH     = (27 << 21) | (0x09) | OPC_CP2,
1052    OPC_PCMPEQB     = (28 << 21) | (0x09) | OPC_CP2,
1053    OPC_PCMPGTB     = (29 << 21) | (0x09) | OPC_CP2,
1054
1055    OPC_PSLLW       = (24 << 21) | (0x0A) | OPC_CP2,
1056    OPC_PSLLH       = (25 << 21) | (0x0A) | OPC_CP2,
1057    OPC_PMULLH      = (26 << 21) | (0x0A) | OPC_CP2,
1058    OPC_PMULHH      = (27 << 21) | (0x0A) | OPC_CP2,
1059    OPC_PMULUW      = (28 << 21) | (0x0A) | OPC_CP2,
1060    OPC_PMULHUH     = (29 << 21) | (0x0A) | OPC_CP2,
1061
1062    OPC_PSRLW       = (24 << 21) | (0x0B) | OPC_CP2,
1063    OPC_PSRLH       = (25 << 21) | (0x0B) | OPC_CP2,
1064    OPC_PSRAW       = (26 << 21) | (0x0B) | OPC_CP2,
1065    OPC_PSRAH       = (27 << 21) | (0x0B) | OPC_CP2,
1066    OPC_PUNPCKLWD   = (28 << 21) | (0x0B) | OPC_CP2,
1067    OPC_PUNPCKHWD   = (29 << 21) | (0x0B) | OPC_CP2,
1068
1069    OPC_ADDU_CP2    = (24 << 21) | (0x0C) | OPC_CP2,
1070    OPC_OR_CP2      = (25 << 21) | (0x0C) | OPC_CP2,
1071    OPC_ADD_CP2     = (26 << 21) | (0x0C) | OPC_CP2,
1072    OPC_DADD_CP2    = (27 << 21) | (0x0C) | OPC_CP2,
1073    OPC_SEQU_CP2    = (28 << 21) | (0x0C) | OPC_CP2,
1074    OPC_SEQ_CP2     = (29 << 21) | (0x0C) | OPC_CP2,
1075
1076    OPC_SUBU_CP2    = (24 << 21) | (0x0D) | OPC_CP2,
1077    OPC_PASUBUB     = (25 << 21) | (0x0D) | OPC_CP2,
1078    OPC_SUB_CP2     = (26 << 21) | (0x0D) | OPC_CP2,
1079    OPC_DSUB_CP2    = (27 << 21) | (0x0D) | OPC_CP2,
1080    OPC_SLTU_CP2    = (28 << 21) | (0x0D) | OPC_CP2,
1081    OPC_SLT_CP2     = (29 << 21) | (0x0D) | OPC_CP2,
1082
1083    OPC_SLL_CP2     = (24 << 21) | (0x0E) | OPC_CP2,
1084    OPC_DSLL_CP2    = (25 << 21) | (0x0E) | OPC_CP2,
1085    OPC_PEXTRH      = (26 << 21) | (0x0E) | OPC_CP2,
1086    OPC_PMADDHW     = (27 << 21) | (0x0E) | OPC_CP2,
1087    OPC_SLEU_CP2    = (28 << 21) | (0x0E) | OPC_CP2,
1088    OPC_SLE_CP2     = (29 << 21) | (0x0E) | OPC_CP2,
1089
1090    OPC_SRL_CP2     = (24 << 21) | (0x0F) | OPC_CP2,
1091    OPC_DSRL_CP2    = (25 << 21) | (0x0F) | OPC_CP2,
1092    OPC_SRA_CP2     = (26 << 21) | (0x0F) | OPC_CP2,
1093    OPC_DSRA_CP2    = (27 << 21) | (0x0F) | OPC_CP2,
1094    OPC_BIADD       = (28 << 21) | (0x0F) | OPC_CP2,
1095    OPC_PMOVMSKB    = (29 << 21) | (0x0F) | OPC_CP2,
1096};
1097
1098
1099#define MASK_CP3(op)                (MASK_OP_MAJOR(op) | (op & 0x3F))
1100
1101enum {
1102    OPC_LWXC1       = 0x00 | OPC_CP3,
1103    OPC_LDXC1       = 0x01 | OPC_CP3,
1104    OPC_LUXC1       = 0x05 | OPC_CP3,
1105    OPC_SWXC1       = 0x08 | OPC_CP3,
1106    OPC_SDXC1       = 0x09 | OPC_CP3,
1107    OPC_SUXC1       = 0x0D | OPC_CP3,
1108    OPC_PREFX       = 0x0F | OPC_CP3,
1109    OPC_ALNV_PS     = 0x1E | OPC_CP3,
1110    OPC_MADD_S      = 0x20 | OPC_CP3,
1111    OPC_MADD_D      = 0x21 | OPC_CP3,
1112    OPC_MADD_PS     = 0x26 | OPC_CP3,
1113    OPC_MSUB_S      = 0x28 | OPC_CP3,
1114    OPC_MSUB_D      = 0x29 | OPC_CP3,
1115    OPC_MSUB_PS     = 0x2E | OPC_CP3,
1116    OPC_NMADD_S     = 0x30 | OPC_CP3,
1117    OPC_NMADD_D     = 0x31 | OPC_CP3,
1118    OPC_NMADD_PS    = 0x36 | OPC_CP3,
1119    OPC_NMSUB_S     = 0x38 | OPC_CP3,
1120    OPC_NMSUB_D     = 0x39 | OPC_CP3,
1121    OPC_NMSUB_PS    = 0x3E | OPC_CP3,
1122};
1123
1124/*
1125 *     MMI (MultiMedia Instruction) encodings
1126 *     ======================================
1127 *
1128 * MMI instructions encoding table keys:
1129 *
1130 *     *   This code is reserved for future use. An attempt to execute it
1131 *         causes a Reserved Instruction exception.
1132 *     %   This code indicates an instruction class. The instruction word
1133 *         must be further decoded by examining additional tables that show
1134 *         the values for other instruction fields.
1135 *     #   This code is reserved for the unsupported instructions DMULT,
1136 *         DMULTU, DDIV, DDIVU, LL, LLD, SC, SCD, LWC2 and SWC2. An attempt
1137 *         to execute it causes a Reserved Instruction exception.
1138 *
1139 * MMI instructions encoded by opcode field (MMI, LQ, SQ):
1140 *
1141 *  31    26                                        0
1142 * +--------+----------------------------------------+
1143 * | opcode |                                        |
1144 * +--------+----------------------------------------+
1145 *
1146 *   opcode  bits 28..26
1147 *     bits |   0   |   1   |   2   |   3   |   4   |   5   |   6   |   7
1148 *   31..29 |  000  |  001  |  010  |  011  |  100  |  101  |  110  |  111
1149 *   -------+-------+-------+-------+-------+-------+-------+-------+-------
1150 *    0 000 |SPECIAL| REGIMM|   J   |  JAL  |  BEQ  |  BNE  |  BLEZ |  BGTZ
1151 *    1 001 |  ADDI | ADDIU |  SLTI | SLTIU |  ANDI |  ORI  |  XORI |  LUI
1152 *    2 010 |  COP0 |  COP1 |   *   |   *   |  BEQL |  BNEL | BLEZL | BGTZL
1153 *    3 011 | DADDI | DADDIU|  LDL  |  LDR  |  MMI% |   *   |   LQ  |   SQ
1154 *    4 100 |   LB  |   LH  |  LWL  |   LW  |  LBU  |  LHU  |  LWR  |  LWU
1155 *    5 101 |   SB  |   SH  |  SWL  |   SW  |  SDL  |  SDR  |  SWR  | CACHE
1156 *    6 110 |   #   |  LWC1 |   #   |  PREF |   #   |  LDC1 |   #   |   LD
1157 *    7 111 |   #   |  SWC1 |   #   |   *   |   #   |  SDC1 |   #   |   SD
1158 */
1159
1160enum {
1161    MMI_OPC_CLASS_MMI = 0x1C << 26,    /* Same as OPC_SPECIAL2 */
1162    MMI_OPC_SQ        = 0x1F << 26,    /* Same as OPC_SPECIAL3 */
1163};
1164
1165/*
1166 * MMI instructions with opcode field = MMI:
1167 *
1168 *  31    26                                 5      0
1169 * +--------+-------------------------------+--------+
1170 * |   MMI  |                               |function|
1171 * +--------+-------------------------------+--------+
1172 *
1173 * function  bits 2..0
1174 *     bits |   0   |   1   |   2   |   3   |   4   |   5   |   6   |   7
1175 *     5..3 |  000  |  001  |  010  |  011  |  100  |  101  |  110  |  111
1176 *   -------+-------+-------+-------+-------+-------+-------+-------+-------
1177 *    0 000 |  MADD | MADDU |   *   |   *   | PLZCW |   *   |   *   |   *
1178 *    1 001 | MMI0% | MMI2% |   *   |   *   |   *   |   *   |   *   |   *
1179 *    2 010 | MFHI1 | MTHI1 | MFLO1 | MTLO1 |   *   |   *   |   *   |   *
1180 *    3 011 | MULT1 | MULTU1|  DIV1 | DIVU1 |   *   |   *   |   *   |   *
1181 *    4 100 | MADD1 | MADDU1|   *   |   *   |   *   |   *   |   *   |   *
1182 *    5 101 | MMI1% | MMI3% |   *   |   *   |   *   |   *   |   *   |   *
1183 *    6 110 | PMFHL | PMTHL |   *   |   *   | PSLLH |   *   | PSRLH | PSRAH
1184 *    7 111 |   *   |   *   |   *   |   *   | PSLLW |   *   | PSRLW | PSRAW
1185 */
1186
1187#define MASK_MMI(op) (MASK_OP_MAJOR(op) | ((op) & 0x3F))
1188enum {
1189    MMI_OPC_MADD       = 0x00 | MMI_OPC_CLASS_MMI, /* Same as OPC_MADD */
1190    MMI_OPC_MADDU      = 0x01 | MMI_OPC_CLASS_MMI, /* Same as OPC_MADDU */
1191    MMI_OPC_MULT1      = 0x18 | MMI_OPC_CLASS_MMI, /* Same minor as OPC_MULT */
1192    MMI_OPC_MULTU1     = 0x19 | MMI_OPC_CLASS_MMI, /* Same min. as OPC_MULTU */
1193    MMI_OPC_DIV1       = 0x1A | MMI_OPC_CLASS_MMI, /* Same minor as OPC_DIV  */
1194    MMI_OPC_DIVU1      = 0x1B | MMI_OPC_CLASS_MMI, /* Same minor as OPC_DIVU */
1195    MMI_OPC_MADD1      = 0x20 | MMI_OPC_CLASS_MMI,
1196    MMI_OPC_MADDU1     = 0x21 | MMI_OPC_CLASS_MMI,
1197};
1198
1199/* global register indices */
1200TCGv cpu_gpr[32], cpu_PC;
1201/*
1202 * For CPUs using 128-bit GPR registers, we put the lower halves in cpu_gpr[])
1203 * and the upper halves in cpu_gpr_hi[].
1204 */
1205TCGv_i64 cpu_gpr_hi[32];
1206TCGv cpu_HI[MIPS_DSP_ACC], cpu_LO[MIPS_DSP_ACC];
1207static TCGv cpu_dspctrl, btarget;
1208TCGv bcond;
1209static TCGv cpu_lladdr, cpu_llval;
1210static TCGv_i32 hflags;
1211TCGv_i32 fpu_fcr0, fpu_fcr31;
1212TCGv_i64 fpu_f64[32];
1213
1214#include "exec/gen-icount.h"
1215
1216#define DISAS_STOP       DISAS_TARGET_0
1217#define DISAS_EXIT       DISAS_TARGET_1
1218
1219static const char regnames_HI[][4] = {
1220    "HI0", "HI1", "HI2", "HI3",
1221};
1222
1223static const char regnames_LO[][4] = {
1224    "LO0", "LO1", "LO2", "LO3",
1225};
1226
1227/* General purpose registers moves. */
1228void gen_load_gpr(TCGv t, int reg)
1229{
1230    if (reg == 0) {
1231        tcg_gen_movi_tl(t, 0);
1232    } else {
1233        tcg_gen_mov_tl(t, cpu_gpr[reg]);
1234    }
1235}
1236
1237void gen_store_gpr(TCGv t, int reg)
1238{
1239    if (reg != 0) {
1240        tcg_gen_mov_tl(cpu_gpr[reg], t);
1241    }
1242}
1243
1244#if defined(TARGET_MIPS64)
1245void gen_load_gpr_hi(TCGv_i64 t, int reg)
1246{
1247    if (reg == 0) {
1248        tcg_gen_movi_i64(t, 0);
1249    } else {
1250        tcg_gen_mov_i64(t, cpu_gpr_hi[reg]);
1251    }
1252}
1253
1254void gen_store_gpr_hi(TCGv_i64 t, int reg)
1255{
1256    if (reg != 0) {
1257        tcg_gen_mov_i64(cpu_gpr_hi[reg], t);
1258    }
1259}
1260#endif /* TARGET_MIPS64 */
1261
1262/* Moves to/from shadow registers. */
1263static inline void gen_load_srsgpr(int from, int to)
1264{
1265    TCGv t0 = tcg_temp_new();
1266
1267    if (from == 0) {
1268        tcg_gen_movi_tl(t0, 0);
1269    } else {
1270        TCGv_i32 t2 = tcg_temp_new_i32();
1271        TCGv_ptr addr = tcg_temp_new_ptr();
1272
1273        tcg_gen_ld_i32(t2, cpu_env, offsetof(CPUMIPSState, CP0_SRSCtl));
1274        tcg_gen_shri_i32(t2, t2, CP0SRSCtl_PSS);
1275        tcg_gen_andi_i32(t2, t2, 0xf);
1276        tcg_gen_muli_i32(t2, t2, sizeof(target_ulong) * 32);
1277        tcg_gen_ext_i32_ptr(addr, t2);
1278        tcg_gen_add_ptr(addr, cpu_env, addr);
1279
1280        tcg_gen_ld_tl(t0, addr, sizeof(target_ulong) * from);
1281        tcg_temp_free_ptr(addr);
1282        tcg_temp_free_i32(t2);
1283    }
1284    gen_store_gpr(t0, to);
1285    tcg_temp_free(t0);
1286}
1287
1288static inline void gen_store_srsgpr(int from, int to)
1289{
1290    if (to != 0) {
1291        TCGv t0 = tcg_temp_new();
1292        TCGv_i32 t2 = tcg_temp_new_i32();
1293        TCGv_ptr addr = tcg_temp_new_ptr();
1294
1295        gen_load_gpr(t0, from);
1296        tcg_gen_ld_i32(t2, cpu_env, offsetof(CPUMIPSState, CP0_SRSCtl));
1297        tcg_gen_shri_i32(t2, t2, CP0SRSCtl_PSS);
1298        tcg_gen_andi_i32(t2, t2, 0xf);
1299        tcg_gen_muli_i32(t2, t2, sizeof(target_ulong) * 32);
1300        tcg_gen_ext_i32_ptr(addr, t2);
1301        tcg_gen_add_ptr(addr, cpu_env, addr);
1302
1303        tcg_gen_st_tl(t0, addr, sizeof(target_ulong) * to);
1304        tcg_temp_free_ptr(addr);
1305        tcg_temp_free_i32(t2);
1306        tcg_temp_free(t0);
1307    }
1308}
1309
1310/* Tests */
1311static inline void gen_save_pc(target_ulong pc)
1312{
1313    tcg_gen_movi_tl(cpu_PC, pc);
1314}
1315
1316static inline void save_cpu_state(DisasContext *ctx, int do_save_pc)
1317{
1318    LOG_DISAS("hflags %08x saved %08x\n", ctx->hflags, ctx->saved_hflags);
1319    if (do_save_pc && ctx->base.pc_next != ctx->saved_pc) {
1320        gen_save_pc(ctx->base.pc_next);
1321        ctx->saved_pc = ctx->base.pc_next;
1322    }
1323    if (ctx->hflags != ctx->saved_hflags) {
1324        tcg_gen_movi_i32(hflags, ctx->hflags);
1325        ctx->saved_hflags = ctx->hflags;
1326        switch (ctx->hflags & MIPS_HFLAG_BMASK_BASE) {
1327        case MIPS_HFLAG_BR:
1328            break;
1329        case MIPS_HFLAG_BC:
1330        case MIPS_HFLAG_BL:
1331        case MIPS_HFLAG_B:
1332            tcg_gen_movi_tl(btarget, ctx->btarget);
1333            break;
1334        }
1335    }
1336}
1337
1338static inline void restore_cpu_state(CPUMIPSState *env, DisasContext *ctx)
1339{
1340    ctx->saved_hflags = ctx->hflags;
1341    switch (ctx->hflags & MIPS_HFLAG_BMASK_BASE) {
1342    case MIPS_HFLAG_BR:
1343        break;
1344    case MIPS_HFLAG_BC:
1345    case MIPS_HFLAG_BL:
1346    case MIPS_HFLAG_B:
1347        ctx->btarget = env->btarget;
1348        break;
1349    }
1350}
1351
1352void generate_exception_err(DisasContext *ctx, int excp, int err)
1353{
1354    save_cpu_state(ctx, 1);
1355    gen_helper_raise_exception_err(cpu_env, tcg_constant_i32(excp),
1356                                   tcg_constant_i32(err));
1357    ctx->base.is_jmp = DISAS_NORETURN;
1358}
1359
1360void generate_exception(DisasContext *ctx, int excp)
1361{
1362    gen_helper_raise_exception(cpu_env, tcg_constant_i32(excp));
1363}
1364
1365void generate_exception_end(DisasContext *ctx, int excp)
1366{
1367    generate_exception_err(ctx, excp, 0);
1368}
1369
1370void generate_exception_break(DisasContext *ctx, int code)
1371{
1372#ifdef CONFIG_USER_ONLY
1373    /* Pass the break code along to cpu_loop. */
1374    tcg_gen_st_i32(tcg_constant_i32(code), cpu_env,
1375                   offsetof(CPUMIPSState, error_code));
1376#endif
1377    generate_exception_end(ctx, EXCP_BREAK);
1378}
1379
1380void gen_reserved_instruction(DisasContext *ctx)
1381{
1382    generate_exception_end(ctx, EXCP_RI);
1383}
1384
1385/* Floating point register moves. */
1386void gen_load_fpr32(DisasContext *ctx, TCGv_i32 t, int reg)
1387{
1388    if (ctx->hflags & MIPS_HFLAG_FRE) {
1389        generate_exception(ctx, EXCP_RI);
1390    }
1391    tcg_gen_extrl_i64_i32(t, fpu_f64[reg]);
1392}
1393
1394void gen_store_fpr32(DisasContext *ctx, TCGv_i32 t, int reg)
1395{
1396    TCGv_i64 t64;
1397    if (ctx->hflags & MIPS_HFLAG_FRE) {
1398        generate_exception(ctx, EXCP_RI);
1399    }
1400    t64 = tcg_temp_new_i64();
1401    tcg_gen_extu_i32_i64(t64, t);
1402    tcg_gen_deposit_i64(fpu_f64[reg], fpu_f64[reg], t64, 0, 32);
1403    tcg_temp_free_i64(t64);
1404}
1405
1406static void gen_load_fpr32h(DisasContext *ctx, TCGv_i32 t, int reg)
1407{
1408    if (ctx->hflags & MIPS_HFLAG_F64) {
1409        tcg_gen_extrh_i64_i32(t, fpu_f64[reg]);
1410    } else {
1411        gen_load_fpr32(ctx, t, reg | 1);
1412    }
1413}
1414
1415static void gen_store_fpr32h(DisasContext *ctx, TCGv_i32 t, int reg)
1416{
1417    if (ctx->hflags & MIPS_HFLAG_F64) {
1418        TCGv_i64 t64 = tcg_temp_new_i64();
1419        tcg_gen_extu_i32_i64(t64, t);
1420        tcg_gen_deposit_i64(fpu_f64[reg], fpu_f64[reg], t64, 32, 32);
1421        tcg_temp_free_i64(t64);
1422    } else {
1423        gen_store_fpr32(ctx, t, reg | 1);
1424    }
1425}
1426
1427void gen_load_fpr64(DisasContext *ctx, TCGv_i64 t, int reg)
1428{
1429    if (ctx->hflags & MIPS_HFLAG_F64) {
1430        tcg_gen_mov_i64(t, fpu_f64[reg]);
1431    } else {
1432        tcg_gen_concat32_i64(t, fpu_f64[reg & ~1], fpu_f64[reg | 1]);
1433    }
1434}
1435
1436void gen_store_fpr64(DisasContext *ctx, TCGv_i64 t, int reg)
1437{
1438    if (ctx->hflags & MIPS_HFLAG_F64) {
1439        tcg_gen_mov_i64(fpu_f64[reg], t);
1440    } else {
1441        TCGv_i64 t0;
1442        tcg_gen_deposit_i64(fpu_f64[reg & ~1], fpu_f64[reg & ~1], t, 0, 32);
1443        t0 = tcg_temp_new_i64();
1444        tcg_gen_shri_i64(t0, t, 32);
1445        tcg_gen_deposit_i64(fpu_f64[reg | 1], fpu_f64[reg | 1], t0, 0, 32);
1446        tcg_temp_free_i64(t0);
1447    }
1448}
1449
1450int get_fp_bit(int cc)
1451{
1452    if (cc) {
1453        return 24 + cc;
1454    } else {
1455        return 23;
1456    }
1457}
1458
1459/* Addresses computation */
1460void gen_op_addr_add(DisasContext *ctx, TCGv ret, TCGv arg0, TCGv arg1)
1461{
1462    tcg_gen_add_tl(ret, arg0, arg1);
1463
1464#if defined(TARGET_MIPS64)
1465    if (ctx->hflags & MIPS_HFLAG_AWRAP) {
1466        tcg_gen_ext32s_i64(ret, ret);
1467    }
1468#endif
1469}
1470
1471static inline void gen_op_addr_addi(DisasContext *ctx, TCGv ret, TCGv base,
1472                                    target_long ofs)
1473{
1474    tcg_gen_addi_tl(ret, base, ofs);
1475
1476#if defined(TARGET_MIPS64)
1477    if (ctx->hflags & MIPS_HFLAG_AWRAP) {
1478        tcg_gen_ext32s_i64(ret, ret);
1479    }
1480#endif
1481}
1482
1483/* Addresses computation (translation time) */
1484static target_long addr_add(DisasContext *ctx, target_long base,
1485                            target_long offset)
1486{
1487    target_long sum = base + offset;
1488
1489#if defined(TARGET_MIPS64)
1490    if (ctx->hflags & MIPS_HFLAG_AWRAP) {
1491        sum = (int32_t)sum;
1492    }
1493#endif
1494    return sum;
1495}
1496
1497/* Sign-extract the low 32-bits to a target_long.  */
1498void gen_move_low32(TCGv ret, TCGv_i64 arg)
1499{
1500#if defined(TARGET_MIPS64)
1501    tcg_gen_ext32s_i64(ret, arg);
1502#else
1503    tcg_gen_extrl_i64_i32(ret, arg);
1504#endif
1505}
1506
1507/* Sign-extract the high 32-bits to a target_long.  */
1508void gen_move_high32(TCGv ret, TCGv_i64 arg)
1509{
1510#if defined(TARGET_MIPS64)
1511    tcg_gen_sari_i64(ret, arg, 32);
1512#else
1513    tcg_gen_extrh_i64_i32(ret, arg);
1514#endif
1515}
1516
1517bool check_cp0_enabled(DisasContext *ctx)
1518{
1519    if (unlikely(!(ctx->hflags & MIPS_HFLAG_CP0))) {
1520        generate_exception_end(ctx, EXCP_CpU);
1521        return false;
1522    }
1523    return true;
1524}
1525
1526void check_cp1_enabled(DisasContext *ctx)
1527{
1528    if (unlikely(!(ctx->hflags & MIPS_HFLAG_FPU))) {
1529        generate_exception_err(ctx, EXCP_CpU, 1);
1530    }
1531}
1532
1533/*
1534 * Verify that the processor is running with COP1X instructions enabled.
1535 * This is associated with the nabla symbol in the MIPS32 and MIPS64
1536 * opcode tables.
1537 */
1538void check_cop1x(DisasContext *ctx)
1539{
1540    if (unlikely(!(ctx->hflags & MIPS_HFLAG_COP1X))) {
1541        gen_reserved_instruction(ctx);
1542    }
1543}
1544
1545/*
1546 * Verify that the processor is running with 64-bit floating-point
1547 * operations enabled.
1548 */
1549void check_cp1_64bitmode(DisasContext *ctx)
1550{
1551    if (unlikely(~ctx->hflags & (MIPS_HFLAG_F64 | MIPS_HFLAG_COP1X))) {
1552        gen_reserved_instruction(ctx);
1553    }
1554}
1555
1556/*
1557 * Verify if floating point register is valid; an operation is not defined
1558 * if bit 0 of any register specification is set and the FR bit in the
1559 * Status register equals zero, since the register numbers specify an
1560 * even-odd pair of adjacent coprocessor general registers. When the FR bit
1561 * in the Status register equals one, both even and odd register numbers
1562 * are valid. This limitation exists only for 64 bit wide (d,l,ps) registers.
1563 *
1564 * Multiple 64 bit wide registers can be checked by calling
1565 * gen_op_cp1_registers(freg1 | freg2 | ... | fregN);
1566 */
1567void check_cp1_registers(DisasContext *ctx, int regs)
1568{
1569    if (unlikely(!(ctx->hflags & MIPS_HFLAG_F64) && (regs & 1))) {
1570        gen_reserved_instruction(ctx);
1571    }
1572}
1573
1574/*
1575 * Verify that the processor is running with DSP instructions enabled.
1576 * This is enabled by CP0 Status register MX(24) bit.
1577 */
1578static inline void check_dsp(DisasContext *ctx)
1579{
1580    if (unlikely(!(ctx->hflags & MIPS_HFLAG_DSP))) {
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_r2(DisasContext *ctx)
1590{
1591    if (unlikely(!(ctx->hflags & MIPS_HFLAG_DSP_R2))) {
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
1600static inline void check_dsp_r3(DisasContext *ctx)
1601{
1602    if (unlikely(!(ctx->hflags & MIPS_HFLAG_DSP_R3))) {
1603        if (ctx->insn_flags & ASE_DSP) {
1604            generate_exception_end(ctx, EXCP_DSPDIS);
1605        } else {
1606            gen_reserved_instruction(ctx);
1607        }
1608    }
1609}
1610
1611/*
1612 * This code generates a "reserved instruction" exception if the
1613 * CPU does not support the instruction set corresponding to flags.
1614 */
1615void check_insn(DisasContext *ctx, uint64_t flags)
1616{
1617    if (unlikely(!(ctx->insn_flags & flags))) {
1618        gen_reserved_instruction(ctx);
1619    }
1620}
1621
1622/*
1623 * This code generates a "reserved instruction" exception if the
1624 * CPU has corresponding flag set which indicates that the instruction
1625 * has been removed.
1626 */
1627static inline void check_insn_opc_removed(DisasContext *ctx, uint64_t flags)
1628{
1629    if (unlikely(ctx->insn_flags & flags)) {
1630        gen_reserved_instruction(ctx);
1631    }
1632}
1633
1634/*
1635 * The Linux kernel traps certain reserved instruction exceptions to
1636 * emulate the corresponding instructions. QEMU is the kernel in user
1637 * mode, so those traps are emulated by accepting the instructions.
1638 *
1639 * A reserved instruction exception is generated for flagged CPUs if
1640 * QEMU runs in system mode.
1641 */
1642static inline void check_insn_opc_user_only(DisasContext *ctx, uint64_t flags)
1643{
1644#ifndef CONFIG_USER_ONLY
1645    check_insn_opc_removed(ctx, flags);
1646#endif
1647}
1648
1649/*
1650 * This code generates a "reserved instruction" exception if the
1651 * CPU does not support 64-bit paired-single (PS) floating point data type.
1652 */
1653static inline void check_ps(DisasContext *ctx)
1654{
1655    if (unlikely(!ctx->ps)) {
1656        generate_exception(ctx, EXCP_RI);
1657    }
1658    check_cp1_64bitmode(ctx);
1659}
1660
1661/*
1662 * This code generates a "reserved instruction" exception if cpu is not
1663 * 64-bit or 64-bit instructions are not enabled.
1664 */
1665void check_mips_64(DisasContext *ctx)
1666{
1667    if (unlikely((TARGET_LONG_BITS != 64) || !(ctx->hflags & MIPS_HFLAG_64))) {
1668        gen_reserved_instruction(ctx);
1669    }
1670}
1671
1672#ifndef CONFIG_USER_ONLY
1673static inline void check_mvh(DisasContext *ctx)
1674{
1675    if (unlikely(!ctx->mvh)) {
1676        generate_exception(ctx, EXCP_RI);
1677    }
1678}
1679#endif
1680
1681/*
1682 * This code generates a "reserved instruction" exception if the
1683 * Config5 XNP bit is set.
1684 */
1685static inline void check_xnp(DisasContext *ctx)
1686{
1687    if (unlikely(ctx->CP0_Config5 & (1 << CP0C5_XNP))) {
1688        gen_reserved_instruction(ctx);
1689    }
1690}
1691
1692#ifndef CONFIG_USER_ONLY
1693/*
1694 * This code generates a "reserved instruction" exception if the
1695 * Config3 PW bit is NOT set.
1696 */
1697static inline void check_pw(DisasContext *ctx)
1698{
1699    if (unlikely(!(ctx->CP0_Config3 & (1 << CP0C3_PW)))) {
1700        gen_reserved_instruction(ctx);
1701    }
1702}
1703#endif
1704
1705/*
1706 * This code generates a "reserved instruction" exception if the
1707 * Config3 MT bit is NOT set.
1708 */
1709static inline void check_mt(DisasContext *ctx)
1710{
1711    if (unlikely(!(ctx->CP0_Config3 & (1 << CP0C3_MT)))) {
1712        gen_reserved_instruction(ctx);
1713    }
1714}
1715
1716#ifndef CONFIG_USER_ONLY
1717/*
1718 * This code generates a "coprocessor unusable" exception if CP0 is not
1719 * available, and, if that is not the case, generates a "reserved instruction"
1720 * exception if the Config5 MT bit is NOT set. This is needed for availability
1721 * control of some of MT ASE instructions.
1722 */
1723static inline void check_cp0_mt(DisasContext *ctx)
1724{
1725    if (unlikely(!(ctx->hflags & MIPS_HFLAG_CP0))) {
1726        generate_exception_end(ctx, EXCP_CpU);
1727    } else {
1728        if (unlikely(!(ctx->CP0_Config3 & (1 << CP0C3_MT)))) {
1729            gen_reserved_instruction(ctx);
1730        }
1731    }
1732}
1733#endif
1734
1735/*
1736 * This code generates a "reserved instruction" exception if the
1737 * Config5 NMS bit is set.
1738 */
1739static inline void check_nms(DisasContext *ctx)
1740{
1741    if (unlikely(ctx->CP0_Config5 & (1 << CP0C5_NMS))) {
1742        gen_reserved_instruction(ctx);
1743    }
1744}
1745
1746/*
1747 * This code generates a "reserved instruction" exception if the
1748 * Config5 NMS bit is set, and Config1 DL, Config1 IL, Config2 SL,
1749 * Config2 TL, and Config5 L2C are unset.
1750 */
1751static inline void check_nms_dl_il_sl_tl_l2c(DisasContext *ctx)
1752{
1753    if (unlikely((ctx->CP0_Config5 & (1 << CP0C5_NMS)) &&
1754                 !(ctx->CP0_Config1 & (1 << CP0C1_DL)) &&
1755                 !(ctx->CP0_Config1 & (1 << CP0C1_IL)) &&
1756                 !(ctx->CP0_Config2 & (1 << CP0C2_SL)) &&
1757                 !(ctx->CP0_Config2 & (1 << CP0C2_TL)) &&
1758                 !(ctx->CP0_Config5 & (1 << CP0C5_L2C)))) {
1759        gen_reserved_instruction(ctx);
1760    }
1761}
1762
1763/*
1764 * This code generates a "reserved instruction" exception if the
1765 * Config5 EVA bit is NOT set.
1766 */
1767static inline void check_eva(DisasContext *ctx)
1768{
1769    if (unlikely(!(ctx->CP0_Config5 & (1 << CP0C5_EVA)))) {
1770        gen_reserved_instruction(ctx);
1771    }
1772}
1773
1774
1775/*
1776 * Define small wrappers for gen_load_fpr* so that we have a uniform
1777 * calling interface for 32 and 64-bit FPRs.  No sense in changing
1778 * all callers for gen_load_fpr32 when we need the CTX parameter for
1779 * this one use.
1780 */
1781#define gen_ldcmp_fpr32(ctx, x, y) gen_load_fpr32(ctx, x, y)
1782#define gen_ldcmp_fpr64(ctx, x, y) gen_load_fpr64(ctx, x, y)
1783#define FOP_CONDS(type, abs, fmt, ifmt, bits)                                 \
1784static inline void gen_cmp ## type ## _ ## fmt(DisasContext *ctx, int n,      \
1785                                               int ft, int fs, int cc)        \
1786{                                                                             \
1787    TCGv_i##bits fp0 = tcg_temp_new_i##bits();                                \
1788    TCGv_i##bits fp1 = tcg_temp_new_i##bits();                                \
1789    switch (ifmt) {                                                           \
1790    case FMT_PS:                                                              \
1791        check_ps(ctx);                                                        \
1792        break;                                                                \
1793    case FMT_D:                                                               \
1794        if (abs) {                                                            \
1795            check_cop1x(ctx);                                                 \
1796        }                                                                     \
1797        check_cp1_registers(ctx, fs | ft);                                    \
1798        break;                                                                \
1799    case FMT_S:                                                               \
1800        if (abs) {                                                            \
1801            check_cop1x(ctx);                                                 \
1802        }                                                                     \
1803        break;                                                                \
1804    }                                                                         \
1805    gen_ldcmp_fpr##bits(ctx, fp0, fs);                                        \
1806    gen_ldcmp_fpr##bits(ctx, fp1, ft);                                        \
1807    switch (n) {                                                              \
1808    case  0:                                                                  \
1809        gen_helper_0e2i(cmp ## type ## _ ## fmt ## _f, fp0, fp1, cc);         \
1810    break;                                                                    \
1811    case  1:                                                                  \
1812        gen_helper_0e2i(cmp ## type ## _ ## fmt ## _un, fp0, fp1, cc);        \
1813    break;                                                                    \
1814    case  2:                                                                  \
1815        gen_helper_0e2i(cmp ## type ## _ ## fmt ## _eq, fp0, fp1, cc);        \
1816    break;                                                                    \
1817    case  3:                                                                  \
1818        gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ueq, fp0, fp1, cc);       \
1819    break;                                                                    \
1820    case  4:                                                                  \
1821        gen_helper_0e2i(cmp ## type ## _ ## fmt ## _olt, fp0, fp1, cc);       \
1822    break;                                                                    \
1823    case  5:                                                                  \
1824        gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ult, fp0, fp1, cc);       \
1825    break;                                                                    \
1826    case  6:                                                                  \
1827        gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ole, fp0, fp1, cc);       \
1828    break;                                                                    \
1829    case  7:                                                                  \
1830        gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ule, fp0, fp1, cc);       \
1831    break;                                                                    \
1832    case  8:                                                                  \
1833        gen_helper_0e2i(cmp ## type ## _ ## fmt ## _sf, fp0, fp1, cc);        \
1834    break;                                                                    \
1835    case  9:                                                                  \
1836        gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ngle, fp0, fp1, cc);      \
1837    break;                                                                    \
1838    case 10:                                                                  \
1839        gen_helper_0e2i(cmp ## type ## _ ## fmt ## _seq, fp0, fp1, cc);       \
1840    break;                                                                    \
1841    case 11:                                                                  \
1842        gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ngl, fp0, fp1, cc);       \
1843    break;                                                                    \
1844    case 12:                                                                  \
1845        gen_helper_0e2i(cmp ## type ## _ ## fmt ## _lt, fp0, fp1, cc);        \
1846    break;                                                                    \
1847    case 13:                                                                  \
1848        gen_helper_0e2i(cmp ## type ## _ ## fmt ## _nge, fp0, fp1, cc);       \
1849    break;                                                                    \
1850    case 14:                                                                  \
1851        gen_helper_0e2i(cmp ## type ## _ ## fmt ## _le, fp0, fp1, cc);        \
1852    break;                                                                    \
1853    case 15:                                                                  \
1854        gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ngt, fp0, fp1, cc);       \
1855    break;                                                                    \
1856    default:                                                                  \
1857        abort();                                                              \
1858    }                                                                         \
1859    tcg_temp_free_i##bits(fp0);                                               \
1860    tcg_temp_free_i##bits(fp1);                                               \
1861}
1862
1863FOP_CONDS(, 0, d, FMT_D, 64)
1864FOP_CONDS(abs, 1, d, FMT_D, 64)
1865FOP_CONDS(, 0, s, FMT_S, 32)
1866FOP_CONDS(abs, 1, s, FMT_S, 32)
1867FOP_CONDS(, 0, ps, FMT_PS, 64)
1868FOP_CONDS(abs, 1, ps, FMT_PS, 64)
1869#undef FOP_CONDS
1870
1871#define FOP_CONDNS(fmt, ifmt, bits, STORE)                              \
1872static inline void gen_r6_cmp_ ## fmt(DisasContext *ctx, int n,         \
1873                                      int ft, int fs, int fd)           \
1874{                                                                       \
1875    TCGv_i ## bits fp0 = tcg_temp_new_i ## bits();                      \
1876    TCGv_i ## bits fp1 = tcg_temp_new_i ## bits();                      \
1877    if (ifmt == FMT_D) {                                                \
1878        check_cp1_registers(ctx, fs | ft | fd);                         \
1879    }                                                                   \
1880    gen_ldcmp_fpr ## bits(ctx, fp0, fs);                                \
1881    gen_ldcmp_fpr ## bits(ctx, fp1, ft);                                \
1882    switch (n) {                                                        \
1883    case  0:                                                            \
1884        gen_helper_r6_cmp_ ## fmt ## _af(fp0, cpu_env, fp0, fp1);       \
1885        break;                                                          \
1886    case  1:                                                            \
1887        gen_helper_r6_cmp_ ## fmt ## _un(fp0, cpu_env, fp0, fp1);       \
1888        break;                                                          \
1889    case  2:                                                            \
1890        gen_helper_r6_cmp_ ## fmt ## _eq(fp0, cpu_env, fp0, fp1);       \
1891        break;                                                          \
1892    case  3:                                                            \
1893        gen_helper_r6_cmp_ ## fmt ## _ueq(fp0, cpu_env, fp0, fp1);      \
1894        break;                                                          \
1895    case  4:                                                            \
1896        gen_helper_r6_cmp_ ## fmt ## _lt(fp0, cpu_env, fp0, fp1);       \
1897        break;                                                          \
1898    case  5:                                                            \
1899        gen_helper_r6_cmp_ ## fmt ## _ult(fp0, cpu_env, fp0, fp1);      \
1900        break;                                                          \
1901    case  6:                                                            \
1902        gen_helper_r6_cmp_ ## fmt ## _le(fp0, cpu_env, fp0, fp1);       \
1903        break;                                                          \
1904    case  7:                                                            \
1905        gen_helper_r6_cmp_ ## fmt ## _ule(fp0, cpu_env, fp0, fp1);      \
1906        break;                                                          \
1907    case  8:                                                            \
1908        gen_helper_r6_cmp_ ## fmt ## _saf(fp0, cpu_env, fp0, fp1);      \
1909        break;                                                          \
1910    case  9:                                                            \
1911        gen_helper_r6_cmp_ ## fmt ## _sun(fp0, cpu_env, fp0, fp1);      \
1912        break;                                                          \
1913    case 10:                                                            \
1914        gen_helper_r6_cmp_ ## fmt ## _seq(fp0, cpu_env, fp0, fp1);      \
1915        break;                                                          \
1916    case 11:                                                            \
1917        gen_helper_r6_cmp_ ## fmt ## _sueq(fp0, cpu_env, fp0, fp1);     \
1918        break;                                                          \
1919    case 12:                                                            \
1920        gen_helper_r6_cmp_ ## fmt ## _slt(fp0, cpu_env, fp0, fp1);      \
1921        break;                                                          \
1922    case 13:                                                            \
1923        gen_helper_r6_cmp_ ## fmt ## _sult(fp0, cpu_env, fp0, fp1);     \
1924        break;                                                          \
1925    case 14:                                                            \
1926        gen_helper_r6_cmp_ ## fmt ## _sle(fp0, cpu_env, fp0, fp1);      \
1927        break;                                                          \
1928    case 15:                                                            \
1929        gen_helper_r6_cmp_ ## fmt ## _sule(fp0, cpu_env, fp0, fp1);     \
1930        break;                                                          \
1931    case 17:                                                            \
1932        gen_helper_r6_cmp_ ## fmt ## _or(fp0, cpu_env, fp0, fp1);       \
1933        break;                                                          \
1934    case 18:                                                            \
1935        gen_helper_r6_cmp_ ## fmt ## _une(fp0, cpu_env, fp0, fp1);      \
1936        break;                                                          \
1937    case 19:                                                            \
1938        gen_helper_r6_cmp_ ## fmt ## _ne(fp0, cpu_env, fp0, fp1);       \
1939        break;                                                          \
1940    case 25:                                                            \
1941        gen_helper_r6_cmp_ ## fmt ## _sor(fp0, cpu_env, fp0, fp1);      \
1942        break;                                                          \
1943    case 26:                                                            \
1944        gen_helper_r6_cmp_ ## fmt ## _sune(fp0, cpu_env, fp0, fp1);     \
1945        break;                                                          \
1946    case 27:                                                            \
1947        gen_helper_r6_cmp_ ## fmt ## _sne(fp0, cpu_env, fp0, fp1);      \
1948        break;                                                          \
1949    default:                                                            \
1950        abort();                                                        \
1951    }                                                                   \
1952    STORE;                                                              \
1953    tcg_temp_free_i ## bits(fp0);                                       \
1954    tcg_temp_free_i ## bits(fp1);                                       \
1955}
1956
1957FOP_CONDNS(d, FMT_D, 64, gen_store_fpr64(ctx, fp0, fd))
1958FOP_CONDNS(s, FMT_S, 32, gen_store_fpr32(ctx, fp0, fd))
1959#undef FOP_CONDNS
1960#undef gen_ldcmp_fpr32
1961#undef gen_ldcmp_fpr64
1962
1963/* load/store instructions. */
1964#ifdef CONFIG_USER_ONLY
1965#define OP_LD_ATOMIC(insn, fname)                                          \
1966static inline void op_ld_##insn(TCGv ret, TCGv arg1, int mem_idx,          \
1967                                DisasContext *ctx)                         \
1968{                                                                          \
1969    TCGv t0 = tcg_temp_new();                                              \
1970    tcg_gen_mov_tl(t0, arg1);                                              \
1971    tcg_gen_qemu_##fname(ret, arg1, ctx->mem_idx);                         \
1972    tcg_gen_st_tl(t0, cpu_env, offsetof(CPUMIPSState, lladdr));            \
1973    tcg_gen_st_tl(ret, cpu_env, offsetof(CPUMIPSState, llval));            \
1974    tcg_temp_free(t0);                                                     \
1975}
1976#else
1977#define OP_LD_ATOMIC(insn, fname)                                          \
1978static inline void op_ld_##insn(TCGv ret, TCGv arg1, int mem_idx,          \
1979                                DisasContext *ctx)                         \
1980{                                                                          \
1981    gen_helper_##insn(ret, cpu_env, arg1, tcg_constant_i32(mem_idx));      \
1982}
1983#endif
1984OP_LD_ATOMIC(ll, ld32s);
1985#if defined(TARGET_MIPS64)
1986OP_LD_ATOMIC(lld, ld64);
1987#endif
1988#undef OP_LD_ATOMIC
1989
1990void gen_base_offset_addr(DisasContext *ctx, TCGv addr, int base, int offset)
1991{
1992    if (base == 0) {
1993        tcg_gen_movi_tl(addr, offset);
1994    } else if (offset == 0) {
1995        gen_load_gpr(addr, base);
1996    } else {
1997        tcg_gen_movi_tl(addr, offset);
1998        gen_op_addr_add(ctx, addr, cpu_gpr[base], addr);
1999    }
2000}
2001
2002static target_ulong pc_relative_pc(DisasContext *ctx)
2003{
2004    target_ulong pc = ctx->base.pc_next;
2005
2006    if (ctx->hflags & MIPS_HFLAG_BMASK) {
2007        int branch_bytes = ctx->hflags & MIPS_HFLAG_BDS16 ? 2 : 4;
2008
2009        pc -= branch_bytes;
2010    }
2011
2012    pc &= ~(target_ulong)3;
2013    return pc;
2014}
2015
2016/* Load */
2017static void gen_ld(DisasContext *ctx, uint32_t opc,
2018                   int rt, int base, int offset)
2019{
2020    TCGv t0, t1, t2;
2021    int mem_idx = ctx->mem_idx;
2022
2023    if (rt == 0 && ctx->insn_flags & (INSN_LOONGSON2E | INSN_LOONGSON2F |
2024                                      INSN_LOONGSON3A)) {
2025        /*
2026         * Loongson CPU uses a load to zero register for prefetch.
2027         * We emulate it as a NOP. On other CPU we must perform the
2028         * actual memory access.
2029         */
2030        return;
2031    }
2032
2033    t0 = tcg_temp_new();
2034    gen_base_offset_addr(ctx, t0, base, offset);
2035
2036    switch (opc) {
2037#if defined(TARGET_MIPS64)
2038    case OPC_LWU:
2039        tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TEUL |
2040                           ctx->default_tcg_memop_mask);
2041        gen_store_gpr(t0, rt);
2042        break;
2043    case OPC_LD:
2044        tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TEUQ |
2045                           ctx->default_tcg_memop_mask);
2046        gen_store_gpr(t0, rt);
2047        break;
2048    case OPC_LLD:
2049    case R6_OPC_LLD:
2050        op_ld_lld(t0, t0, mem_idx, ctx);
2051        gen_store_gpr(t0, rt);
2052        break;
2053    case OPC_LDL:
2054        t1 = tcg_temp_new();
2055        /*
2056         * Do a byte access to possibly trigger a page
2057         * fault with the unaligned address.
2058         */
2059        tcg_gen_qemu_ld_tl(t1, t0, mem_idx, MO_UB);
2060        tcg_gen_andi_tl(t1, t0, 7);
2061        if (!cpu_is_bigendian(ctx)) {
2062            tcg_gen_xori_tl(t1, t1, 7);
2063        }
2064        tcg_gen_shli_tl(t1, t1, 3);
2065        tcg_gen_andi_tl(t0, t0, ~7);
2066        tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TEUQ);
2067        tcg_gen_shl_tl(t0, t0, t1);
2068        t2 = tcg_const_tl(-1);
2069        tcg_gen_shl_tl(t2, t2, t1);
2070        gen_load_gpr(t1, rt);
2071        tcg_gen_andc_tl(t1, t1, t2);
2072        tcg_temp_free(t2);
2073        tcg_gen_or_tl(t0, t0, t1);
2074        tcg_temp_free(t1);
2075        gen_store_gpr(t0, rt);
2076        break;
2077    case OPC_LDR:
2078        t1 = tcg_temp_new();
2079        /*
2080         * Do a byte access to possibly trigger a page
2081         * fault with the unaligned address.
2082         */
2083        tcg_gen_qemu_ld_tl(t1, t0, mem_idx, MO_UB);
2084        tcg_gen_andi_tl(t1, t0, 7);
2085        if (cpu_is_bigendian(ctx)) {
2086            tcg_gen_xori_tl(t1, t1, 7);
2087        }
2088        tcg_gen_shli_tl(t1, t1, 3);
2089        tcg_gen_andi_tl(t0, t0, ~7);
2090        tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TEUQ);
2091        tcg_gen_shr_tl(t0, t0, t1);
2092        tcg_gen_xori_tl(t1, t1, 63);
2093        t2 = tcg_const_tl(0xfffffffffffffffeull);
2094        tcg_gen_shl_tl(t2, t2, t1);
2095        gen_load_gpr(t1, rt);
2096        tcg_gen_and_tl(t1, t1, t2);
2097        tcg_temp_free(t2);
2098        tcg_gen_or_tl(t0, t0, t1);
2099        tcg_temp_free(t1);
2100        gen_store_gpr(t0, rt);
2101        break;
2102    case OPC_LDPC:
2103        t1 = tcg_const_tl(pc_relative_pc(ctx));
2104        gen_op_addr_add(ctx, t0, t0, t1);
2105        tcg_temp_free(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_const_tl(pc_relative_pc(ctx));
2112        gen_op_addr_add(ctx, t0, t0, t1);
2113        tcg_temp_free(t1);
2114        tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TESL);
2115        gen_store_gpr(t0, rt);
2116        break;
2117    case OPC_LWE:
2118        mem_idx = MIPS_HFLAG_UM;
2119        /* fall through */
2120    case OPC_LW:
2121        tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TESL |
2122                           ctx->default_tcg_memop_mask);
2123        gen_store_gpr(t0, rt);
2124        break;
2125    case OPC_LHE:
2126        mem_idx = MIPS_HFLAG_UM;
2127        /* fall through */
2128    case OPC_LH:
2129        tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TESW |
2130                           ctx->default_tcg_memop_mask);
2131        gen_store_gpr(t0, rt);
2132        break;
2133    case OPC_LHUE:
2134        mem_idx = MIPS_HFLAG_UM;
2135        /* fall through */
2136    case OPC_LHU:
2137        tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TEUW |
2138                           ctx->default_tcg_memop_mask);
2139        gen_store_gpr(t0, rt);
2140        break;
2141    case OPC_LBE:
2142        mem_idx = MIPS_HFLAG_UM;
2143        /* fall through */
2144    case OPC_LB:
2145        tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_SB);
2146        gen_store_gpr(t0, rt);
2147        break;
2148    case OPC_LBUE:
2149        mem_idx = MIPS_HFLAG_UM;
2150        /* fall through */
2151    case OPC_LBU:
2152        tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_UB);
2153        gen_store_gpr(t0, rt);
2154        break;
2155    case OPC_LWLE:
2156        mem_idx = MIPS_HFLAG_UM;
2157        /* fall through */
2158    case OPC_LWL:
2159        t1 = tcg_temp_new();
2160        /*
2161         * Do a byte access to possibly trigger a page
2162         * fault with the unaligned address.
2163         */
2164        tcg_gen_qemu_ld_tl(t1, t0, mem_idx, MO_UB);
2165        tcg_gen_andi_tl(t1, t0, 3);
2166        if (!cpu_is_bigendian(ctx)) {
2167            tcg_gen_xori_tl(t1, t1, 3);
2168        }
2169        tcg_gen_shli_tl(t1, t1, 3);
2170        tcg_gen_andi_tl(t0, t0, ~3);
2171        tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TEUL);
2172        tcg_gen_shl_tl(t0, t0, t1);
2173        t2 = tcg_const_tl(-1);
2174        tcg_gen_shl_tl(t2, t2, t1);
2175        gen_load_gpr(t1, rt);
2176        tcg_gen_andc_tl(t1, t1, t2);
2177        tcg_temp_free(t2);
2178        tcg_gen_or_tl(t0, t0, t1);
2179        tcg_temp_free(t1);
2180        tcg_gen_ext32s_tl(t0, t0);
2181        gen_store_gpr(t0, rt);
2182        break;
2183    case OPC_LWRE:
2184        mem_idx = MIPS_HFLAG_UM;
2185        /* fall through */
2186    case OPC_LWR:
2187        t1 = tcg_temp_new();
2188        /*
2189         * Do a byte access to possibly trigger a page
2190         * fault with the unaligned address.
2191         */
2192        tcg_gen_qemu_ld_tl(t1, t0, mem_idx, MO_UB);
2193        tcg_gen_andi_tl(t1, t0, 3);
2194        if (cpu_is_bigendian(ctx)) {
2195            tcg_gen_xori_tl(t1, t1, 3);
2196        }
2197        tcg_gen_shli_tl(t1, t1, 3);
2198        tcg_gen_andi_tl(t0, t0, ~3);
2199        tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TEUL);
2200        tcg_gen_shr_tl(t0, t0, t1);
2201        tcg_gen_xori_tl(t1, t1, 31);
2202        t2 = tcg_const_tl(0xfffffffeull);
2203        tcg_gen_shl_tl(t2, t2, t1);
2204        gen_load_gpr(t1, rt);
2205        tcg_gen_and_tl(t1, t1, t2);
2206        tcg_temp_free(t2);
2207        tcg_gen_or_tl(t0, t0, t1);
2208        tcg_temp_free(t1);
2209        tcg_gen_ext32s_tl(t0, t0);
2210        gen_store_gpr(t0, rt);
2211        break;
2212    case OPC_LLE:
2213        mem_idx = MIPS_HFLAG_UM;
2214        /* fall through */
2215    case OPC_LL:
2216    case R6_OPC_LL:
2217        op_ld_ll(t0, t0, mem_idx, ctx);
2218        gen_store_gpr(t0, rt);
2219        break;
2220    }
2221    tcg_temp_free(t0);
2222}
2223
2224/* Store */
2225static void gen_st(DisasContext *ctx, uint32_t opc, int rt,
2226                   int base, int offset)
2227{
2228    TCGv t0 = tcg_temp_new();
2229    TCGv t1 = tcg_temp_new();
2230    int mem_idx = ctx->mem_idx;
2231
2232    gen_base_offset_addr(ctx, t0, base, offset);
2233    gen_load_gpr(t1, rt);
2234    switch (opc) {
2235#if defined(TARGET_MIPS64)
2236    case OPC_SD:
2237        tcg_gen_qemu_st_tl(t1, t0, mem_idx, MO_TEUQ |
2238                           ctx->default_tcg_memop_mask);
2239        break;
2240    case OPC_SDL:
2241        gen_helper_0e2i(sdl, t1, t0, mem_idx);
2242        break;
2243    case OPC_SDR:
2244        gen_helper_0e2i(sdr, t1, t0, mem_idx);
2245        break;
2246#endif
2247    case OPC_SWE:
2248        mem_idx = MIPS_HFLAG_UM;
2249        /* fall through */
2250    case OPC_SW:
2251        tcg_gen_qemu_st_tl(t1, t0, mem_idx, MO_TEUL |
2252                           ctx->default_tcg_memop_mask);
2253        break;
2254    case OPC_SHE:
2255        mem_idx = MIPS_HFLAG_UM;
2256        /* fall through */
2257    case OPC_SH:
2258        tcg_gen_qemu_st_tl(t1, t0, mem_idx, MO_TEUW |
2259                           ctx->default_tcg_memop_mask);
2260        break;
2261    case OPC_SBE:
2262        mem_idx = MIPS_HFLAG_UM;
2263        /* fall through */
2264    case OPC_SB:
2265        tcg_gen_qemu_st_tl(t1, t0, mem_idx, MO_8);
2266        break;
2267    case OPC_SWLE:
2268        mem_idx = MIPS_HFLAG_UM;
2269        /* fall through */
2270    case OPC_SWL:
2271        gen_helper_0e2i(swl, t1, t0, mem_idx);
2272        break;
2273    case OPC_SWRE:
2274        mem_idx = MIPS_HFLAG_UM;
2275        /* fall through */
2276    case OPC_SWR:
2277        gen_helper_0e2i(swr, t1, t0, mem_idx);
2278        break;
2279    }
2280    tcg_temp_free(t0);
2281    tcg_temp_free(t1);
2282}
2283
2284
2285/* Store conditional */
2286static void gen_st_cond(DisasContext *ctx, int rt, int base, int offset,
2287                        MemOp tcg_mo, bool eva)
2288{
2289    TCGv addr, t0, val;
2290    TCGLabel *l1 = gen_new_label();
2291    TCGLabel *done = gen_new_label();
2292
2293    t0 = tcg_temp_new();
2294    addr = tcg_temp_new();
2295    /* compare the address against that of the preceding LL */
2296    gen_base_offset_addr(ctx, addr, base, offset);
2297    tcg_gen_brcond_tl(TCG_COND_EQ, addr, cpu_lladdr, l1);
2298    tcg_temp_free(addr);
2299    tcg_gen_movi_tl(t0, 0);
2300    gen_store_gpr(t0, rt);
2301    tcg_gen_br(done);
2302
2303    gen_set_label(l1);
2304    /* generate cmpxchg */
2305    val = tcg_temp_new();
2306    gen_load_gpr(val, rt);
2307    tcg_gen_atomic_cmpxchg_tl(t0, cpu_lladdr, cpu_llval, val,
2308                              eva ? MIPS_HFLAG_UM : ctx->mem_idx, tcg_mo);
2309    tcg_gen_setcond_tl(TCG_COND_EQ, t0, t0, cpu_llval);
2310    gen_store_gpr(t0, rt);
2311    tcg_temp_free(val);
2312
2313    gen_set_label(done);
2314    tcg_temp_free(t0);
2315}
2316
2317/* Load and store */
2318static void gen_flt_ldst(DisasContext *ctx, uint32_t opc, int ft,
2319                         TCGv t0)
2320{
2321    /*
2322     * Don't do NOP if destination is zero: we must perform the actual
2323     * memory access.
2324     */
2325    switch (opc) {
2326    case OPC_LWC1:
2327        {
2328            TCGv_i32 fp0 = tcg_temp_new_i32();
2329            tcg_gen_qemu_ld_i32(fp0, t0, ctx->mem_idx, MO_TESL |
2330                                ctx->default_tcg_memop_mask);
2331            gen_store_fpr32(ctx, fp0, ft);
2332            tcg_temp_free_i32(fp0);
2333        }
2334        break;
2335    case OPC_SWC1:
2336        {
2337            TCGv_i32 fp0 = tcg_temp_new_i32();
2338            gen_load_fpr32(ctx, fp0, ft);
2339            tcg_gen_qemu_st_i32(fp0, t0, ctx->mem_idx, MO_TEUL |
2340                                ctx->default_tcg_memop_mask);
2341            tcg_temp_free_i32(fp0);
2342        }
2343        break;
2344    case OPC_LDC1:
2345        {
2346            TCGv_i64 fp0 = tcg_temp_new_i64();
2347            tcg_gen_qemu_ld_i64(fp0, t0, ctx->mem_idx, MO_TEUQ |
2348                                ctx->default_tcg_memop_mask);
2349            gen_store_fpr64(ctx, fp0, ft);
2350            tcg_temp_free_i64(fp0);
2351        }
2352        break;
2353    case OPC_SDC1:
2354        {
2355            TCGv_i64 fp0 = tcg_temp_new_i64();
2356            gen_load_fpr64(ctx, fp0, ft);
2357            tcg_gen_qemu_st_i64(fp0, t0, ctx->mem_idx, MO_TEUQ |
2358                                ctx->default_tcg_memop_mask);
2359            tcg_temp_free_i64(fp0);
2360        }
2361        break;
2362    default:
2363        MIPS_INVAL("flt_ldst");
2364        gen_reserved_instruction(ctx);
2365        break;
2366    }
2367}
2368
2369static void gen_cop1_ldst(DisasContext *ctx, uint32_t op, int rt,
2370                          int rs, int16_t imm)
2371{
2372    TCGv t0 = tcg_temp_new();
2373
2374    if (ctx->CP0_Config1 & (1 << CP0C1_FP)) {
2375        check_cp1_enabled(ctx);
2376        switch (op) {
2377        case OPC_LDC1:
2378        case OPC_SDC1:
2379            check_insn(ctx, ISA_MIPS2);
2380            /* Fallthrough */
2381        default:
2382            gen_base_offset_addr(ctx, t0, rs, imm);
2383            gen_flt_ldst(ctx, op, rt, t0);
2384        }
2385    } else {
2386        generate_exception_err(ctx, EXCP_CpU, 1);
2387    }
2388    tcg_temp_free(t0);
2389}
2390
2391/* Arithmetic with immediate operand */
2392static void gen_arith_imm(DisasContext *ctx, uint32_t opc,
2393                          int rt, int rs, int imm)
2394{
2395    target_ulong uimm = (target_long)imm; /* Sign extend to 32/64 bits */
2396
2397    if (rt == 0 && opc != OPC_ADDI && opc != OPC_DADDI) {
2398        /*
2399         * If no destination, treat it as a NOP.
2400         * For addi, we must generate the overflow exception when needed.
2401         */
2402        return;
2403    }
2404    switch (opc) {
2405    case OPC_ADDI:
2406        {
2407            TCGv t0 = tcg_temp_local_new();
2408            TCGv t1 = tcg_temp_new();
2409            TCGv t2 = tcg_temp_new();
2410            TCGLabel *l1 = gen_new_label();
2411
2412            gen_load_gpr(t1, rs);
2413            tcg_gen_addi_tl(t0, t1, uimm);
2414            tcg_gen_ext32s_tl(t0, t0);
2415
2416            tcg_gen_xori_tl(t1, t1, ~uimm);
2417            tcg_gen_xori_tl(t2, t0, uimm);
2418            tcg_gen_and_tl(t1, t1, t2);
2419            tcg_temp_free(t2);
2420            tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
2421            tcg_temp_free(t1);
2422            /* operands of same sign, result different sign */
2423            generate_exception(ctx, EXCP_OVERFLOW);
2424            gen_set_label(l1);
2425            tcg_gen_ext32s_tl(t0, t0);
2426            gen_store_gpr(t0, rt);
2427            tcg_temp_free(t0);
2428        }
2429        break;
2430    case OPC_ADDIU:
2431        if (rs != 0) {
2432            tcg_gen_addi_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
2433            tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
2434        } else {
2435            tcg_gen_movi_tl(cpu_gpr[rt], uimm);
2436        }
2437        break;
2438#if defined(TARGET_MIPS64)
2439    case OPC_DADDI:
2440        {
2441            TCGv t0 = tcg_temp_local_new();
2442            TCGv t1 = tcg_temp_new();
2443            TCGv t2 = tcg_temp_new();
2444            TCGLabel *l1 = gen_new_label();
2445
2446            gen_load_gpr(t1, rs);
2447            tcg_gen_addi_tl(t0, t1, uimm);
2448
2449            tcg_gen_xori_tl(t1, t1, ~uimm);
2450            tcg_gen_xori_tl(t2, t0, uimm);
2451            tcg_gen_and_tl(t1, t1, t2);
2452            tcg_temp_free(t2);
2453            tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
2454            tcg_temp_free(t1);
2455            /* operands of same sign, result different sign */
2456            generate_exception(ctx, EXCP_OVERFLOW);
2457            gen_set_label(l1);
2458            gen_store_gpr(t0, rt);
2459            tcg_temp_free(t0);
2460        }
2461        break;
2462    case OPC_DADDIU:
2463        if (rs != 0) {
2464            tcg_gen_addi_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
2465        } else {
2466            tcg_gen_movi_tl(cpu_gpr[rt], uimm);
2467        }
2468        break;
2469#endif
2470    }
2471}
2472
2473/* Logic with immediate operand */
2474static void gen_logic_imm(DisasContext *ctx, uint32_t opc,
2475                          int rt, int rs, int16_t imm)
2476{
2477    target_ulong uimm;
2478
2479    if (rt == 0) {
2480        /* If no destination, treat it as a NOP. */
2481        return;
2482    }
2483    uimm = (uint16_t)imm;
2484    switch (opc) {
2485    case OPC_ANDI:
2486        if (likely(rs != 0)) {
2487            tcg_gen_andi_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
2488        } else {
2489            tcg_gen_movi_tl(cpu_gpr[rt], 0);
2490        }
2491        break;
2492    case OPC_ORI:
2493        if (rs != 0) {
2494            tcg_gen_ori_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
2495        } else {
2496            tcg_gen_movi_tl(cpu_gpr[rt], uimm);
2497        }
2498        break;
2499    case OPC_XORI:
2500        if (likely(rs != 0)) {
2501            tcg_gen_xori_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
2502        } else {
2503            tcg_gen_movi_tl(cpu_gpr[rt], uimm);
2504        }
2505        break;
2506    case OPC_LUI:
2507        if (rs != 0 && (ctx->insn_flags & ISA_MIPS_R6)) {
2508            /* OPC_AUI */
2509            tcg_gen_addi_tl(cpu_gpr[rt], cpu_gpr[rs], imm << 16);
2510            tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
2511        } else {
2512            tcg_gen_movi_tl(cpu_gpr[rt], imm << 16);
2513        }
2514        break;
2515
2516    default:
2517        break;
2518    }
2519}
2520
2521/* Set on less than with immediate operand */
2522static void gen_slt_imm(DisasContext *ctx, uint32_t opc,
2523                        int rt, int rs, int16_t imm)
2524{
2525    target_ulong uimm = (target_long)imm; /* Sign extend to 32/64 bits */
2526    TCGv t0;
2527
2528    if (rt == 0) {
2529        /* If no destination, treat it as a NOP. */
2530        return;
2531    }
2532    t0 = tcg_temp_new();
2533    gen_load_gpr(t0, rs);
2534    switch (opc) {
2535    case OPC_SLTI:
2536        tcg_gen_setcondi_tl(TCG_COND_LT, cpu_gpr[rt], t0, uimm);
2537        break;
2538    case OPC_SLTIU:
2539        tcg_gen_setcondi_tl(TCG_COND_LTU, cpu_gpr[rt], t0, uimm);
2540        break;
2541    }
2542    tcg_temp_free(t0);
2543}
2544
2545/* Shifts with immediate operand */
2546static void gen_shift_imm(DisasContext *ctx, uint32_t opc,
2547                          int rt, int rs, int16_t imm)
2548{
2549    target_ulong uimm = ((uint16_t)imm) & 0x1f;
2550    TCGv t0;
2551
2552    if (rt == 0) {
2553        /* If no destination, treat it as a NOP. */
2554        return;
2555    }
2556
2557    t0 = tcg_temp_new();
2558    gen_load_gpr(t0, rs);
2559    switch (opc) {
2560    case OPC_SLL:
2561        tcg_gen_shli_tl(t0, t0, uimm);
2562        tcg_gen_ext32s_tl(cpu_gpr[rt], t0);
2563        break;
2564    case OPC_SRA:
2565        tcg_gen_sari_tl(cpu_gpr[rt], t0, uimm);
2566        break;
2567    case OPC_SRL:
2568        if (uimm != 0) {
2569            tcg_gen_ext32u_tl(t0, t0);
2570            tcg_gen_shri_tl(cpu_gpr[rt], t0, uimm);
2571        } else {
2572            tcg_gen_ext32s_tl(cpu_gpr[rt], t0);
2573        }
2574        break;
2575    case OPC_ROTR:
2576        if (uimm != 0) {
2577            TCGv_i32 t1 = tcg_temp_new_i32();
2578
2579            tcg_gen_trunc_tl_i32(t1, t0);
2580            tcg_gen_rotri_i32(t1, t1, uimm);
2581            tcg_gen_ext_i32_tl(cpu_gpr[rt], t1);
2582            tcg_temp_free_i32(t1);
2583        } else {
2584            tcg_gen_ext32s_tl(cpu_gpr[rt], t0);
2585        }
2586        break;
2587#if defined(TARGET_MIPS64)
2588    case OPC_DSLL:
2589        tcg_gen_shli_tl(cpu_gpr[rt], t0, uimm);
2590        break;
2591    case OPC_DSRA:
2592        tcg_gen_sari_tl(cpu_gpr[rt], t0, uimm);
2593        break;
2594    case OPC_DSRL:
2595        tcg_gen_shri_tl(cpu_gpr[rt], t0, uimm);
2596        break;
2597    case OPC_DROTR:
2598        if (uimm != 0) {
2599            tcg_gen_rotri_tl(cpu_gpr[rt], t0, uimm);
2600        } else {
2601            tcg_gen_mov_tl(cpu_gpr[rt], t0);
2602        }
2603        break;
2604    case OPC_DSLL32:
2605        tcg_gen_shli_tl(cpu_gpr[rt], t0, uimm + 32);
2606        break;
2607    case OPC_DSRA32:
2608        tcg_gen_sari_tl(cpu_gpr[rt], t0, uimm + 32);
2609        break;
2610    case OPC_DSRL32:
2611        tcg_gen_shri_tl(cpu_gpr[rt], t0, uimm + 32);
2612        break;
2613    case OPC_DROTR32:
2614        tcg_gen_rotri_tl(cpu_gpr[rt], t0, uimm + 32);
2615        break;
2616#endif
2617    }
2618    tcg_temp_free(t0);
2619}
2620
2621/* Arithmetic */
2622static void gen_arith(DisasContext *ctx, uint32_t opc,
2623                      int rd, int rs, int rt)
2624{
2625    if (rd == 0 && opc != OPC_ADD && opc != OPC_SUB
2626       && opc != OPC_DADD && opc != OPC_DSUB) {
2627        /*
2628         * If no destination, treat it as a NOP.
2629         * For add & sub, we must generate the overflow exception when needed.
2630         */
2631        return;
2632    }
2633
2634    switch (opc) {
2635    case OPC_ADD:
2636        {
2637            TCGv t0 = tcg_temp_local_new();
2638            TCGv t1 = tcg_temp_new();
2639            TCGv t2 = tcg_temp_new();
2640            TCGLabel *l1 = gen_new_label();
2641
2642            gen_load_gpr(t1, rs);
2643            gen_load_gpr(t2, rt);
2644            tcg_gen_add_tl(t0, t1, t2);
2645            tcg_gen_ext32s_tl(t0, t0);
2646            tcg_gen_xor_tl(t1, t1, t2);
2647            tcg_gen_xor_tl(t2, t0, t2);
2648            tcg_gen_andc_tl(t1, t2, t1);
2649            tcg_temp_free(t2);
2650            tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
2651            tcg_temp_free(t1);
2652            /* operands of same sign, result different sign */
2653            generate_exception(ctx, EXCP_OVERFLOW);
2654            gen_set_label(l1);
2655            gen_store_gpr(t0, rd);
2656            tcg_temp_free(t0);
2657        }
2658        break;
2659    case OPC_ADDU:
2660        if (rs != 0 && rt != 0) {
2661            tcg_gen_add_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2662            tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
2663        } else if (rs == 0 && rt != 0) {
2664            tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
2665        } else if (rs != 0 && rt == 0) {
2666            tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
2667        } else {
2668            tcg_gen_movi_tl(cpu_gpr[rd], 0);
2669        }
2670        break;
2671    case OPC_SUB:
2672        {
2673            TCGv t0 = tcg_temp_local_new();
2674            TCGv t1 = tcg_temp_new();
2675            TCGv t2 = tcg_temp_new();
2676            TCGLabel *l1 = gen_new_label();
2677
2678            gen_load_gpr(t1, rs);
2679            gen_load_gpr(t2, rt);
2680            tcg_gen_sub_tl(t0, t1, t2);
2681            tcg_gen_ext32s_tl(t0, t0);
2682            tcg_gen_xor_tl(t2, t1, t2);
2683            tcg_gen_xor_tl(t1, t0, t1);
2684            tcg_gen_and_tl(t1, t1, t2);
2685            tcg_temp_free(t2);
2686            tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
2687            tcg_temp_free(t1);
2688            /*
2689             * operands of different sign, first operand and the result
2690             * of different sign
2691             */
2692            generate_exception(ctx, EXCP_OVERFLOW);
2693            gen_set_label(l1);
2694            gen_store_gpr(t0, rd);
2695            tcg_temp_free(t0);
2696        }
2697        break;
2698    case OPC_SUBU:
2699        if (rs != 0 && rt != 0) {
2700            tcg_gen_sub_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2701            tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
2702        } else if (rs == 0 && rt != 0) {
2703            tcg_gen_neg_tl(cpu_gpr[rd], cpu_gpr[rt]);
2704            tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
2705        } else if (rs != 0 && rt == 0) {
2706            tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
2707        } else {
2708            tcg_gen_movi_tl(cpu_gpr[rd], 0);
2709        }
2710        break;
2711#if defined(TARGET_MIPS64)
2712    case OPC_DADD:
2713        {
2714            TCGv t0 = tcg_temp_local_new();
2715            TCGv t1 = tcg_temp_new();
2716            TCGv t2 = tcg_temp_new();
2717            TCGLabel *l1 = gen_new_label();
2718
2719            gen_load_gpr(t1, rs);
2720            gen_load_gpr(t2, rt);
2721            tcg_gen_add_tl(t0, t1, t2);
2722            tcg_gen_xor_tl(t1, t1, t2);
2723            tcg_gen_xor_tl(t2, t0, t2);
2724            tcg_gen_andc_tl(t1, t2, t1);
2725            tcg_temp_free(t2);
2726            tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
2727            tcg_temp_free(t1);
2728            /* operands of same sign, result different sign */
2729            generate_exception(ctx, EXCP_OVERFLOW);
2730            gen_set_label(l1);
2731            gen_store_gpr(t0, rd);
2732            tcg_temp_free(t0);
2733        }
2734        break;
2735    case OPC_DADDU:
2736        if (rs != 0 && rt != 0) {
2737            tcg_gen_add_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2738        } else if (rs == 0 && rt != 0) {
2739            tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
2740        } else if (rs != 0 && rt == 0) {
2741            tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
2742        } else {
2743            tcg_gen_movi_tl(cpu_gpr[rd], 0);
2744        }
2745        break;
2746    case OPC_DSUB:
2747        {
2748            TCGv t0 = tcg_temp_local_new();
2749            TCGv t1 = tcg_temp_new();
2750            TCGv t2 = tcg_temp_new();
2751            TCGLabel *l1 = gen_new_label();
2752
2753            gen_load_gpr(t1, rs);
2754            gen_load_gpr(t2, rt);
2755            tcg_gen_sub_tl(t0, t1, t2);
2756            tcg_gen_xor_tl(t2, t1, t2);
2757            tcg_gen_xor_tl(t1, t0, t1);
2758            tcg_gen_and_tl(t1, t1, t2);
2759            tcg_temp_free(t2);
2760            tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
2761            tcg_temp_free(t1);
2762            /*
2763             * Operands of different sign, first operand and result different
2764             * sign.
2765             */
2766            generate_exception(ctx, EXCP_OVERFLOW);
2767            gen_set_label(l1);
2768            gen_store_gpr(t0, rd);
2769            tcg_temp_free(t0);
2770        }
2771        break;
2772    case OPC_DSUBU:
2773        if (rs != 0 && rt != 0) {
2774            tcg_gen_sub_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2775        } else if (rs == 0 && rt != 0) {
2776            tcg_gen_neg_tl(cpu_gpr[rd], cpu_gpr[rt]);
2777        } else if (rs != 0 && rt == 0) {
2778            tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
2779        } else {
2780            tcg_gen_movi_tl(cpu_gpr[rd], 0);
2781        }
2782        break;
2783#endif
2784    case OPC_MUL:
2785        if (likely(rs != 0 && rt != 0)) {
2786            tcg_gen_mul_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2787            tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
2788        } else {
2789            tcg_gen_movi_tl(cpu_gpr[rd], 0);
2790        }
2791        break;
2792    }
2793}
2794
2795/* Conditional move */
2796static void gen_cond_move(DisasContext *ctx, uint32_t opc,
2797                          int rd, int rs, int rt)
2798{
2799    TCGv t0, t1, t2;
2800
2801    if (rd == 0) {
2802        /* If no destination, treat it as a NOP. */
2803        return;
2804    }
2805
2806    t0 = tcg_temp_new();
2807    gen_load_gpr(t0, rt);
2808    t1 = tcg_const_tl(0);
2809    t2 = tcg_temp_new();
2810    gen_load_gpr(t2, rs);
2811    switch (opc) {
2812    case OPC_MOVN:
2813        tcg_gen_movcond_tl(TCG_COND_NE, cpu_gpr[rd], t0, t1, t2, cpu_gpr[rd]);
2814        break;
2815    case OPC_MOVZ:
2816        tcg_gen_movcond_tl(TCG_COND_EQ, cpu_gpr[rd], t0, t1, t2, cpu_gpr[rd]);
2817        break;
2818    case OPC_SELNEZ:
2819        tcg_gen_movcond_tl(TCG_COND_NE, cpu_gpr[rd], t0, t1, t2, t1);
2820        break;
2821    case OPC_SELEQZ:
2822        tcg_gen_movcond_tl(TCG_COND_EQ, cpu_gpr[rd], t0, t1, t2, t1);
2823        break;
2824    }
2825    tcg_temp_free(t2);
2826    tcg_temp_free(t1);
2827    tcg_temp_free(t0);
2828}
2829
2830/* Logic */
2831static void gen_logic(DisasContext *ctx, uint32_t opc,
2832                      int rd, int rs, int rt)
2833{
2834    if (rd == 0) {
2835        /* If no destination, treat it as a NOP. */
2836        return;
2837    }
2838
2839    switch (opc) {
2840    case OPC_AND:
2841        if (likely(rs != 0 && rt != 0)) {
2842            tcg_gen_and_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2843        } else {
2844            tcg_gen_movi_tl(cpu_gpr[rd], 0);
2845        }
2846        break;
2847    case OPC_NOR:
2848        if (rs != 0 && rt != 0) {
2849            tcg_gen_nor_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2850        } else if (rs == 0 && rt != 0) {
2851            tcg_gen_not_tl(cpu_gpr[rd], cpu_gpr[rt]);
2852        } else if (rs != 0 && rt == 0) {
2853            tcg_gen_not_tl(cpu_gpr[rd], cpu_gpr[rs]);
2854        } else {
2855            tcg_gen_movi_tl(cpu_gpr[rd], ~((target_ulong)0));
2856        }
2857        break;
2858    case OPC_OR:
2859        if (likely(rs != 0 && rt != 0)) {
2860            tcg_gen_or_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2861        } else if (rs == 0 && rt != 0) {
2862            tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
2863        } else if (rs != 0 && rt == 0) {
2864            tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
2865        } else {
2866            tcg_gen_movi_tl(cpu_gpr[rd], 0);
2867        }
2868        break;
2869    case OPC_XOR:
2870        if (likely(rs != 0 && rt != 0)) {
2871            tcg_gen_xor_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2872        } else if (rs == 0 && rt != 0) {
2873            tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
2874        } else if (rs != 0 && rt == 0) {
2875            tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
2876        } else {
2877            tcg_gen_movi_tl(cpu_gpr[rd], 0);
2878        }
2879        break;
2880    }
2881}
2882
2883/* Set on lower than */
2884static void gen_slt(DisasContext *ctx, uint32_t opc,
2885                    int rd, int rs, int rt)
2886{
2887    TCGv t0, t1;
2888
2889    if (rd == 0) {
2890        /* If no destination, treat it as a NOP. */
2891        return;
2892    }
2893
2894    t0 = tcg_temp_new();
2895    t1 = tcg_temp_new();
2896    gen_load_gpr(t0, rs);
2897    gen_load_gpr(t1, rt);
2898    switch (opc) {
2899    case OPC_SLT:
2900        tcg_gen_setcond_tl(TCG_COND_LT, cpu_gpr[rd], t0, t1);
2901        break;
2902    case OPC_SLTU:
2903        tcg_gen_setcond_tl(TCG_COND_LTU, cpu_gpr[rd], t0, t1);
2904        break;
2905    }
2906    tcg_temp_free(t0);
2907    tcg_temp_free(t1);
2908}
2909
2910/* Shifts */
2911static void gen_shift(DisasContext *ctx, uint32_t opc,
2912                      int rd, int rs, int rt)
2913{
2914    TCGv t0, t1;
2915
2916    if (rd == 0) {
2917        /*
2918         * If no destination, treat it as a NOP.
2919         * For add & sub, we must generate the overflow exception when needed.
2920         */
2921        return;
2922    }
2923
2924    t0 = tcg_temp_new();
2925    t1 = tcg_temp_new();
2926    gen_load_gpr(t0, rs);
2927    gen_load_gpr(t1, rt);
2928    switch (opc) {
2929    case OPC_SLLV:
2930        tcg_gen_andi_tl(t0, t0, 0x1f);
2931        tcg_gen_shl_tl(t0, t1, t0);
2932        tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
2933        break;
2934    case OPC_SRAV:
2935        tcg_gen_andi_tl(t0, t0, 0x1f);
2936        tcg_gen_sar_tl(cpu_gpr[rd], t1, t0);
2937        break;
2938    case OPC_SRLV:
2939        tcg_gen_ext32u_tl(t1, t1);
2940        tcg_gen_andi_tl(t0, t0, 0x1f);
2941        tcg_gen_shr_tl(t0, t1, t0);
2942        tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
2943        break;
2944    case OPC_ROTRV:
2945        {
2946            TCGv_i32 t2 = tcg_temp_new_i32();
2947            TCGv_i32 t3 = tcg_temp_new_i32();
2948
2949            tcg_gen_trunc_tl_i32(t2, t0);
2950            tcg_gen_trunc_tl_i32(t3, t1);
2951            tcg_gen_andi_i32(t2, t2, 0x1f);
2952            tcg_gen_rotr_i32(t2, t3, t2);
2953            tcg_gen_ext_i32_tl(cpu_gpr[rd], t2);
2954            tcg_temp_free_i32(t2);
2955            tcg_temp_free_i32(t3);
2956        }
2957        break;
2958#if defined(TARGET_MIPS64)
2959    case OPC_DSLLV:
2960        tcg_gen_andi_tl(t0, t0, 0x3f);
2961        tcg_gen_shl_tl(cpu_gpr[rd], t1, t0);
2962        break;
2963    case OPC_DSRAV:
2964        tcg_gen_andi_tl(t0, t0, 0x3f);
2965        tcg_gen_sar_tl(cpu_gpr[rd], t1, t0);
2966        break;
2967    case OPC_DSRLV:
2968        tcg_gen_andi_tl(t0, t0, 0x3f);
2969        tcg_gen_shr_tl(cpu_gpr[rd], t1, t0);
2970        break;
2971    case OPC_DROTRV:
2972        tcg_gen_andi_tl(t0, t0, 0x3f);
2973        tcg_gen_rotr_tl(cpu_gpr[rd], t1, t0);
2974        break;
2975#endif
2976    }
2977    tcg_temp_free(t0);
2978    tcg_temp_free(t1);
2979}
2980
2981/* Arithmetic on HI/LO registers */
2982static void gen_HILO(DisasContext *ctx, uint32_t opc, int acc, int reg)
2983{
2984    if (reg == 0 && (opc == OPC_MFHI || opc == OPC_MFLO)) {
2985        /* Treat as NOP. */
2986        return;
2987    }
2988
2989    if (acc != 0) {
2990        check_dsp(ctx);
2991    }
2992
2993    switch (opc) {
2994    case OPC_MFHI:
2995#if defined(TARGET_MIPS64)
2996        if (acc != 0) {
2997            tcg_gen_ext32s_tl(cpu_gpr[reg], cpu_HI[acc]);
2998        } else
2999#endif
3000        {
3001            tcg_gen_mov_tl(cpu_gpr[reg], cpu_HI[acc]);
3002        }
3003        break;
3004    case OPC_MFLO:
3005#if defined(TARGET_MIPS64)
3006        if (acc != 0) {
3007            tcg_gen_ext32s_tl(cpu_gpr[reg], cpu_LO[acc]);
3008        } else
3009#endif
3010        {
3011            tcg_gen_mov_tl(cpu_gpr[reg], cpu_LO[acc]);
3012        }
3013        break;
3014    case OPC_MTHI:
3015        if (reg != 0) {
3016#if defined(TARGET_MIPS64)
3017            if (acc != 0) {
3018                tcg_gen_ext32s_tl(cpu_HI[acc], cpu_gpr[reg]);
3019            } else
3020#endif
3021            {
3022                tcg_gen_mov_tl(cpu_HI[acc], cpu_gpr[reg]);
3023            }
3024        } else {
3025            tcg_gen_movi_tl(cpu_HI[acc], 0);
3026        }
3027        break;
3028    case OPC_MTLO:
3029        if (reg != 0) {
3030#if defined(TARGET_MIPS64)
3031            if (acc != 0) {
3032                tcg_gen_ext32s_tl(cpu_LO[acc], cpu_gpr[reg]);
3033            } else
3034#endif
3035            {
3036                tcg_gen_mov_tl(cpu_LO[acc], cpu_gpr[reg]);
3037            }
3038        } else {
3039            tcg_gen_movi_tl(cpu_LO[acc], 0);
3040        }
3041        break;
3042    }
3043}
3044
3045static inline void gen_r6_ld(target_long addr, int reg, int memidx,
3046                             MemOp memop)
3047{
3048    TCGv t0 = tcg_const_tl(addr);
3049    tcg_gen_qemu_ld_tl(t0, t0, memidx, memop);
3050    gen_store_gpr(t0, reg);
3051    tcg_temp_free(t0);
3052}
3053
3054static inline void gen_pcrel(DisasContext *ctx, int opc, target_ulong pc,
3055                             int rs)
3056{
3057    target_long offset;
3058    target_long addr;
3059
3060    switch (MASK_OPC_PCREL_TOP2BITS(opc)) {
3061    case OPC_ADDIUPC:
3062        if (rs != 0) {
3063            offset = sextract32(ctx->opcode << 2, 0, 21);
3064            addr = addr_add(ctx, pc, offset);
3065            tcg_gen_movi_tl(cpu_gpr[rs], addr);
3066        }
3067        break;
3068    case R6_OPC_LWPC:
3069        offset = sextract32(ctx->opcode << 2, 0, 21);
3070        addr = addr_add(ctx, pc, offset);
3071        gen_r6_ld(addr, rs, ctx->mem_idx, MO_TESL);
3072        break;
3073#if defined(TARGET_MIPS64)
3074    case OPC_LWUPC:
3075        check_mips_64(ctx);
3076        offset = sextract32(ctx->opcode << 2, 0, 21);
3077        addr = addr_add(ctx, pc, offset);
3078        gen_r6_ld(addr, rs, ctx->mem_idx, MO_TEUL);
3079        break;
3080#endif
3081    default:
3082        switch (MASK_OPC_PCREL_TOP5BITS(opc)) {
3083        case OPC_AUIPC:
3084            if (rs != 0) {
3085                offset = sextract32(ctx->opcode, 0, 16) << 16;
3086                addr = addr_add(ctx, pc, offset);
3087                tcg_gen_movi_tl(cpu_gpr[rs], addr);
3088            }
3089            break;
3090        case OPC_ALUIPC:
3091            if (rs != 0) {
3092                offset = sextract32(ctx->opcode, 0, 16) << 16;
3093                addr = ~0xFFFF & addr_add(ctx, pc, offset);
3094                tcg_gen_movi_tl(cpu_gpr[rs], addr);
3095            }
3096            break;
3097#if defined(TARGET_MIPS64)
3098        case R6_OPC_LDPC: /* bits 16 and 17 are part of immediate */
3099        case R6_OPC_LDPC + (1 << 16):
3100        case R6_OPC_LDPC + (2 << 16):
3101        case R6_OPC_LDPC + (3 << 16):
3102            check_mips_64(ctx);
3103            offset = sextract32(ctx->opcode << 3, 0, 21);
3104            addr = addr_add(ctx, (pc & ~0x7), offset);
3105            gen_r6_ld(addr, rs, ctx->mem_idx, MO_TEUQ);
3106            break;
3107#endif
3108        default:
3109            MIPS_INVAL("OPC_PCREL");
3110            gen_reserved_instruction(ctx);
3111            break;
3112        }
3113        break;
3114    }
3115}
3116
3117static void gen_r6_muldiv(DisasContext *ctx, int opc, int rd, int rs, int rt)
3118{
3119    TCGv t0, t1;
3120
3121    if (rd == 0) {
3122        /* Treat as NOP. */
3123        return;
3124    }
3125
3126    t0 = tcg_temp_new();
3127    t1 = tcg_temp_new();
3128
3129    gen_load_gpr(t0, rs);
3130    gen_load_gpr(t1, rt);
3131
3132    switch (opc) {
3133    case R6_OPC_DIV:
3134        {
3135            TCGv t2 = tcg_temp_new();
3136            TCGv t3 = tcg_temp_new();
3137            tcg_gen_ext32s_tl(t0, t0);
3138            tcg_gen_ext32s_tl(t1, t1);
3139            tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, INT_MIN);
3140            tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1);
3141            tcg_gen_and_tl(t2, t2, t3);
3142            tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
3143            tcg_gen_or_tl(t2, t2, t3);
3144            tcg_gen_movi_tl(t3, 0);
3145            tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
3146            tcg_gen_div_tl(cpu_gpr[rd], t0, t1);
3147            tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3148            tcg_temp_free(t3);
3149            tcg_temp_free(t2);
3150        }
3151        break;
3152    case R6_OPC_MOD:
3153        {
3154            TCGv t2 = tcg_temp_new();
3155            TCGv t3 = tcg_temp_new();
3156            tcg_gen_ext32s_tl(t0, t0);
3157            tcg_gen_ext32s_tl(t1, t1);
3158            tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, INT_MIN);
3159            tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1);
3160            tcg_gen_and_tl(t2, t2, t3);
3161            tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
3162            tcg_gen_or_tl(t2, t2, t3);
3163            tcg_gen_movi_tl(t3, 0);
3164            tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
3165            tcg_gen_rem_tl(cpu_gpr[rd], t0, t1);
3166            tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3167            tcg_temp_free(t3);
3168            tcg_temp_free(t2);
3169        }
3170        break;
3171    case R6_OPC_DIVU:
3172        {
3173            TCGv t2 = tcg_const_tl(0);
3174            TCGv t3 = tcg_const_tl(1);
3175            tcg_gen_ext32u_tl(t0, t0);
3176            tcg_gen_ext32u_tl(t1, t1);
3177            tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
3178            tcg_gen_divu_tl(cpu_gpr[rd], t0, t1);
3179            tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3180            tcg_temp_free(t3);
3181            tcg_temp_free(t2);
3182        }
3183        break;
3184    case R6_OPC_MODU:
3185        {
3186            TCGv t2 = tcg_const_tl(0);
3187            TCGv t3 = tcg_const_tl(1);
3188            tcg_gen_ext32u_tl(t0, t0);
3189            tcg_gen_ext32u_tl(t1, t1);
3190            tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
3191            tcg_gen_remu_tl(cpu_gpr[rd], t0, t1);
3192            tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3193            tcg_temp_free(t3);
3194            tcg_temp_free(t2);
3195        }
3196        break;
3197    case R6_OPC_MUL:
3198        {
3199            TCGv_i32 t2 = tcg_temp_new_i32();
3200            TCGv_i32 t3 = tcg_temp_new_i32();
3201            tcg_gen_trunc_tl_i32(t2, t0);
3202            tcg_gen_trunc_tl_i32(t3, t1);
3203            tcg_gen_mul_i32(t2, t2, t3);
3204            tcg_gen_ext_i32_tl(cpu_gpr[rd], t2);
3205            tcg_temp_free_i32(t2);
3206            tcg_temp_free_i32(t3);
3207        }
3208        break;
3209    case R6_OPC_MUH:
3210        {
3211            TCGv_i32 t2 = tcg_temp_new_i32();
3212            TCGv_i32 t3 = tcg_temp_new_i32();
3213            tcg_gen_trunc_tl_i32(t2, t0);
3214            tcg_gen_trunc_tl_i32(t3, t1);
3215            tcg_gen_muls2_i32(t2, t3, t2, t3);
3216            tcg_gen_ext_i32_tl(cpu_gpr[rd], t3);
3217            tcg_temp_free_i32(t2);
3218            tcg_temp_free_i32(t3);
3219        }
3220        break;
3221    case R6_OPC_MULU:
3222        {
3223            TCGv_i32 t2 = tcg_temp_new_i32();
3224            TCGv_i32 t3 = tcg_temp_new_i32();
3225            tcg_gen_trunc_tl_i32(t2, t0);
3226            tcg_gen_trunc_tl_i32(t3, t1);
3227            tcg_gen_mul_i32(t2, t2, t3);
3228            tcg_gen_ext_i32_tl(cpu_gpr[rd], t2);
3229            tcg_temp_free_i32(t2);
3230            tcg_temp_free_i32(t3);
3231        }
3232        break;
3233    case R6_OPC_MUHU:
3234        {
3235            TCGv_i32 t2 = tcg_temp_new_i32();
3236            TCGv_i32 t3 = tcg_temp_new_i32();
3237            tcg_gen_trunc_tl_i32(t2, t0);
3238            tcg_gen_trunc_tl_i32(t3, t1);
3239            tcg_gen_mulu2_i32(t2, t3, t2, t3);
3240            tcg_gen_ext_i32_tl(cpu_gpr[rd], t3);
3241            tcg_temp_free_i32(t2);
3242            tcg_temp_free_i32(t3);
3243        }
3244        break;
3245#if defined(TARGET_MIPS64)
3246    case R6_OPC_DDIV:
3247        {
3248            TCGv t2 = tcg_temp_new();
3249            TCGv t3 = tcg_temp_new();
3250            tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, -1LL << 63);
3251            tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1LL);
3252            tcg_gen_and_tl(t2, t2, t3);
3253            tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
3254            tcg_gen_or_tl(t2, t2, t3);
3255            tcg_gen_movi_tl(t3, 0);
3256            tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
3257            tcg_gen_div_tl(cpu_gpr[rd], t0, t1);
3258            tcg_temp_free(t3);
3259            tcg_temp_free(t2);
3260        }
3261        break;
3262    case R6_OPC_DMOD:
3263        {
3264            TCGv t2 = tcg_temp_new();
3265            TCGv t3 = tcg_temp_new();
3266            tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, -1LL << 63);
3267            tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1LL);
3268            tcg_gen_and_tl(t2, t2, t3);
3269            tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
3270            tcg_gen_or_tl(t2, t2, t3);
3271            tcg_gen_movi_tl(t3, 0);
3272            tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
3273            tcg_gen_rem_tl(cpu_gpr[rd], t0, t1);
3274            tcg_temp_free(t3);
3275            tcg_temp_free(t2);
3276        }
3277        break;
3278    case R6_OPC_DDIVU:
3279        {
3280            TCGv t2 = tcg_const_tl(0);
3281            TCGv t3 = tcg_const_tl(1);
3282            tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
3283            tcg_gen_divu_i64(cpu_gpr[rd], t0, t1);
3284            tcg_temp_free(t3);
3285            tcg_temp_free(t2);
3286        }
3287        break;
3288    case R6_OPC_DMODU:
3289        {
3290            TCGv t2 = tcg_const_tl(0);
3291            TCGv t3 = tcg_const_tl(1);
3292            tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
3293            tcg_gen_remu_i64(cpu_gpr[rd], t0, t1);
3294            tcg_temp_free(t3);
3295            tcg_temp_free(t2);
3296        }
3297        break;
3298    case R6_OPC_DMUL:
3299        tcg_gen_mul_i64(cpu_gpr[rd], t0, t1);
3300        break;
3301    case R6_OPC_DMUH:
3302        {
3303            TCGv t2 = tcg_temp_new();
3304            tcg_gen_muls2_i64(t2, cpu_gpr[rd], t0, t1);
3305            tcg_temp_free(t2);
3306        }
3307        break;
3308    case R6_OPC_DMULU:
3309        tcg_gen_mul_i64(cpu_gpr[rd], t0, t1);
3310        break;
3311    case R6_OPC_DMUHU:
3312        {
3313            TCGv t2 = tcg_temp_new();
3314            tcg_gen_mulu2_i64(t2, cpu_gpr[rd], t0, t1);
3315            tcg_temp_free(t2);
3316        }
3317        break;
3318#endif
3319    default:
3320        MIPS_INVAL("r6 mul/div");
3321        gen_reserved_instruction(ctx);
3322        goto out;
3323    }
3324 out:
3325    tcg_temp_free(t0);
3326    tcg_temp_free(t1);
3327}
3328
3329#if defined(TARGET_MIPS64)
3330static void gen_div1_tx79(DisasContext *ctx, uint32_t opc, int rs, int rt)
3331{
3332    TCGv t0, t1;
3333
3334    t0 = tcg_temp_new();
3335    t1 = tcg_temp_new();
3336
3337    gen_load_gpr(t0, rs);
3338    gen_load_gpr(t1, rt);
3339
3340    switch (opc) {
3341    case MMI_OPC_DIV1:
3342        {
3343            TCGv t2 = tcg_temp_new();
3344            TCGv t3 = tcg_temp_new();
3345            tcg_gen_ext32s_tl(t0, t0);
3346            tcg_gen_ext32s_tl(t1, t1);
3347            tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, INT_MIN);
3348            tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1);
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[1], t0, t1);
3355            tcg_gen_rem_tl(cpu_HI[1], t0, t1);
3356            tcg_gen_ext32s_tl(cpu_LO[1], cpu_LO[1]);
3357            tcg_gen_ext32s_tl(cpu_HI[1], cpu_HI[1]);
3358            tcg_temp_free(t3);
3359            tcg_temp_free(t2);
3360        }
3361        break;
3362    case MMI_OPC_DIVU1:
3363        {
3364            TCGv t2 = tcg_const_tl(0);
3365            TCGv t3 = tcg_const_tl(1);
3366            tcg_gen_ext32u_tl(t0, t0);
3367            tcg_gen_ext32u_tl(t1, t1);
3368            tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
3369            tcg_gen_divu_tl(cpu_LO[1], t0, t1);
3370            tcg_gen_remu_tl(cpu_HI[1], t0, t1);
3371            tcg_gen_ext32s_tl(cpu_LO[1], cpu_LO[1]);
3372            tcg_gen_ext32s_tl(cpu_HI[1], cpu_HI[1]);
3373            tcg_temp_free(t3);
3374            tcg_temp_free(t2);
3375        }
3376        break;
3377    default:
3378        MIPS_INVAL("div1 TX79");
3379        gen_reserved_instruction(ctx);
3380        goto out;
3381    }
3382 out:
3383    tcg_temp_free(t0);
3384    tcg_temp_free(t1);
3385}
3386#endif
3387
3388static void gen_muldiv(DisasContext *ctx, uint32_t opc,
3389                       int acc, int rs, int rt)
3390{
3391    TCGv t0, t1;
3392
3393    t0 = tcg_temp_new();
3394    t1 = tcg_temp_new();
3395
3396    gen_load_gpr(t0, rs);
3397    gen_load_gpr(t1, rt);
3398
3399    if (acc != 0) {
3400        check_dsp(ctx);
3401    }
3402
3403    switch (opc) {
3404    case OPC_DIV:
3405        {
3406            TCGv t2 = tcg_temp_new();
3407            TCGv t3 = tcg_temp_new();
3408            tcg_gen_ext32s_tl(t0, t0);
3409            tcg_gen_ext32s_tl(t1, t1);
3410            tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, INT_MIN);
3411            tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1);
3412            tcg_gen_and_tl(t2, t2, t3);
3413            tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
3414            tcg_gen_or_tl(t2, t2, t3);
3415            tcg_gen_movi_tl(t3, 0);
3416            tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
3417            tcg_gen_div_tl(cpu_LO[acc], t0, t1);
3418            tcg_gen_rem_tl(cpu_HI[acc], t0, t1);
3419            tcg_gen_ext32s_tl(cpu_LO[acc], cpu_LO[acc]);
3420            tcg_gen_ext32s_tl(cpu_HI[acc], cpu_HI[acc]);
3421            tcg_temp_free(t3);
3422            tcg_temp_free(t2);
3423        }
3424        break;
3425    case OPC_DIVU:
3426        {
3427            TCGv t2 = tcg_const_tl(0);
3428            TCGv t3 = tcg_const_tl(1);
3429            tcg_gen_ext32u_tl(t0, t0);
3430            tcg_gen_ext32u_tl(t1, t1);
3431            tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
3432            tcg_gen_divu_tl(cpu_LO[acc], t0, t1);
3433            tcg_gen_remu_tl(cpu_HI[acc], t0, t1);
3434            tcg_gen_ext32s_tl(cpu_LO[acc], cpu_LO[acc]);
3435            tcg_gen_ext32s_tl(cpu_HI[acc], cpu_HI[acc]);
3436            tcg_temp_free(t3);
3437            tcg_temp_free(t2);
3438        }
3439        break;
3440    case OPC_MULT:
3441        {
3442            TCGv_i32 t2 = tcg_temp_new_i32();
3443            TCGv_i32 t3 = tcg_temp_new_i32();
3444            tcg_gen_trunc_tl_i32(t2, t0);
3445            tcg_gen_trunc_tl_i32(t3, t1);
3446            tcg_gen_muls2_i32(t2, t3, t2, t3);
3447            tcg_gen_ext_i32_tl(cpu_LO[acc], t2);
3448            tcg_gen_ext_i32_tl(cpu_HI[acc], t3);
3449            tcg_temp_free_i32(t2);
3450            tcg_temp_free_i32(t3);
3451        }
3452        break;
3453    case OPC_MULTU:
3454        {
3455            TCGv_i32 t2 = tcg_temp_new_i32();
3456            TCGv_i32 t3 = tcg_temp_new_i32();
3457            tcg_gen_trunc_tl_i32(t2, t0);
3458            tcg_gen_trunc_tl_i32(t3, t1);
3459            tcg_gen_mulu2_i32(t2, t3, t2, t3);
3460            tcg_gen_ext_i32_tl(cpu_LO[acc], t2);
3461            tcg_gen_ext_i32_tl(cpu_HI[acc], t3);
3462            tcg_temp_free_i32(t2);
3463            tcg_temp_free_i32(t3);
3464        }
3465        break;
3466#if defined(TARGET_MIPS64)
3467    case OPC_DDIV:
3468        {
3469            TCGv t2 = tcg_temp_new();
3470            TCGv t3 = tcg_temp_new();
3471            tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, -1LL << 63);
3472            tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1LL);
3473            tcg_gen_and_tl(t2, t2, t3);
3474            tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
3475            tcg_gen_or_tl(t2, t2, t3);
3476            tcg_gen_movi_tl(t3, 0);
3477            tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
3478            tcg_gen_div_tl(cpu_LO[acc], t0, t1);
3479            tcg_gen_rem_tl(cpu_HI[acc], t0, t1);
3480            tcg_temp_free(t3);
3481            tcg_temp_free(t2);
3482        }
3483        break;
3484    case OPC_DDIVU:
3485        {
3486            TCGv t2 = tcg_const_tl(0);
3487            TCGv t3 = tcg_const_tl(1);
3488            tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
3489            tcg_gen_divu_i64(cpu_LO[acc], t0, t1);
3490            tcg_gen_remu_i64(cpu_HI[acc], t0, t1);
3491            tcg_temp_free(t3);
3492            tcg_temp_free(t2);
3493        }
3494        break;
3495    case OPC_DMULT:
3496        tcg_gen_muls2_i64(cpu_LO[acc], cpu_HI[acc], t0, t1);
3497        break;
3498    case OPC_DMULTU:
3499        tcg_gen_mulu2_i64(cpu_LO[acc], cpu_HI[acc], t0, t1);
3500        break;
3501#endif
3502    case OPC_MADD:
3503        {
3504            TCGv_i64 t2 = tcg_temp_new_i64();
3505            TCGv_i64 t3 = tcg_temp_new_i64();
3506
3507            tcg_gen_ext_tl_i64(t2, t0);
3508            tcg_gen_ext_tl_i64(t3, t1);
3509            tcg_gen_mul_i64(t2, t2, t3);
3510            tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
3511            tcg_gen_add_i64(t2, t2, t3);
3512            tcg_temp_free_i64(t3);
3513            gen_move_low32(cpu_LO[acc], t2);
3514            gen_move_high32(cpu_HI[acc], t2);
3515            tcg_temp_free_i64(t2);
3516        }
3517        break;
3518    case OPC_MADDU:
3519        {
3520            TCGv_i64 t2 = tcg_temp_new_i64();
3521            TCGv_i64 t3 = tcg_temp_new_i64();
3522
3523            tcg_gen_ext32u_tl(t0, t0);
3524            tcg_gen_ext32u_tl(t1, t1);
3525            tcg_gen_extu_tl_i64(t2, t0);
3526            tcg_gen_extu_tl_i64(t3, t1);
3527            tcg_gen_mul_i64(t2, t2, t3);
3528            tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
3529            tcg_gen_add_i64(t2, t2, t3);
3530            tcg_temp_free_i64(t3);
3531            gen_move_low32(cpu_LO[acc], t2);
3532            gen_move_high32(cpu_HI[acc], t2);
3533            tcg_temp_free_i64(t2);
3534        }
3535        break;
3536    case OPC_MSUB:
3537        {
3538            TCGv_i64 t2 = tcg_temp_new_i64();
3539            TCGv_i64 t3 = tcg_temp_new_i64();
3540
3541            tcg_gen_ext_tl_i64(t2, t0);
3542            tcg_gen_ext_tl_i64(t3, t1);
3543            tcg_gen_mul_i64(t2, t2, t3);
3544            tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
3545            tcg_gen_sub_i64(t2, t3, t2);
3546            tcg_temp_free_i64(t3);
3547            gen_move_low32(cpu_LO[acc], t2);
3548            gen_move_high32(cpu_HI[acc], t2);
3549            tcg_temp_free_i64(t2);
3550        }
3551        break;
3552    case OPC_MSUBU:
3553        {
3554            TCGv_i64 t2 = tcg_temp_new_i64();
3555            TCGv_i64 t3 = tcg_temp_new_i64();
3556
3557            tcg_gen_ext32u_tl(t0, t0);
3558            tcg_gen_ext32u_tl(t1, t1);
3559            tcg_gen_extu_tl_i64(t2, t0);
3560            tcg_gen_extu_tl_i64(t3, t1);
3561            tcg_gen_mul_i64(t2, t2, t3);
3562            tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
3563            tcg_gen_sub_i64(t2, t3, t2);
3564            tcg_temp_free_i64(t3);
3565            gen_move_low32(cpu_LO[acc], t2);
3566            gen_move_high32(cpu_HI[acc], t2);
3567            tcg_temp_free_i64(t2);
3568        }
3569        break;
3570    default:
3571        MIPS_INVAL("mul/div");
3572        gen_reserved_instruction(ctx);
3573        goto out;
3574    }
3575 out:
3576    tcg_temp_free(t0);
3577    tcg_temp_free(t1);
3578}
3579
3580/*
3581 * These MULT[U] and MADD[U] instructions implemented in for example
3582 * the Toshiba/Sony R5900 and the Toshiba TX19, TX39 and TX79 core
3583 * architectures are special three-operand variants with the syntax
3584 *
3585 *     MULT[U][1] rd, rs, rt
3586 *
3587 * such that
3588 *
3589 *     (rd, LO, HI) <- rs * rt
3590 *
3591 * and
3592 *
3593 *     MADD[U][1] rd, rs, rt
3594 *
3595 * such that
3596 *
3597 *     (rd, LO, HI) <- (LO, HI) + rs * rt
3598 *
3599 * where the low-order 32-bits of the result is placed into both the
3600 * GPR rd and the special register LO. The high-order 32-bits of the
3601 * result is placed into the special register HI.
3602 *
3603 * If the GPR rd is omitted in assembly language, it is taken to be 0,
3604 * which is the zero register that always reads as 0.
3605 */
3606static void gen_mul_txx9(DisasContext *ctx, uint32_t opc,
3607                         int rd, int rs, int rt)
3608{
3609    TCGv t0 = tcg_temp_new();
3610    TCGv t1 = tcg_temp_new();
3611    int acc = 0;
3612
3613    gen_load_gpr(t0, rs);
3614    gen_load_gpr(t1, rt);
3615
3616    switch (opc) {
3617    case MMI_OPC_MULT1:
3618        acc = 1;
3619        /* Fall through */
3620    case OPC_MULT:
3621        {
3622            TCGv_i32 t2 = tcg_temp_new_i32();
3623            TCGv_i32 t3 = tcg_temp_new_i32();
3624            tcg_gen_trunc_tl_i32(t2, t0);
3625            tcg_gen_trunc_tl_i32(t3, t1);
3626            tcg_gen_muls2_i32(t2, t3, t2, t3);
3627            if (rd) {
3628                tcg_gen_ext_i32_tl(cpu_gpr[rd], t2);
3629            }
3630            tcg_gen_ext_i32_tl(cpu_LO[acc], t2);
3631            tcg_gen_ext_i32_tl(cpu_HI[acc], t3);
3632            tcg_temp_free_i32(t2);
3633            tcg_temp_free_i32(t3);
3634        }
3635        break;
3636    case MMI_OPC_MULTU1:
3637        acc = 1;
3638        /* Fall through */
3639    case OPC_MULTU:
3640        {
3641            TCGv_i32 t2 = tcg_temp_new_i32();
3642            TCGv_i32 t3 = tcg_temp_new_i32();
3643            tcg_gen_trunc_tl_i32(t2, t0);
3644            tcg_gen_trunc_tl_i32(t3, t1);
3645            tcg_gen_mulu2_i32(t2, t3, t2, t3);
3646            if (rd) {
3647                tcg_gen_ext_i32_tl(cpu_gpr[rd], t2);
3648            }
3649            tcg_gen_ext_i32_tl(cpu_LO[acc], t2);
3650            tcg_gen_ext_i32_tl(cpu_HI[acc], t3);
3651            tcg_temp_free_i32(t2);
3652            tcg_temp_free_i32(t3);
3653        }
3654        break;
3655    case MMI_OPC_MADD1:
3656        acc = 1;
3657        /* Fall through */
3658    case MMI_OPC_MADD:
3659        {
3660            TCGv_i64 t2 = tcg_temp_new_i64();
3661            TCGv_i64 t3 = tcg_temp_new_i64();
3662
3663            tcg_gen_ext_tl_i64(t2, t0);
3664            tcg_gen_ext_tl_i64(t3, t1);
3665            tcg_gen_mul_i64(t2, t2, t3);
3666            tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
3667            tcg_gen_add_i64(t2, t2, t3);
3668            tcg_temp_free_i64(t3);
3669            gen_move_low32(cpu_LO[acc], t2);
3670            gen_move_high32(cpu_HI[acc], t2);
3671            if (rd) {
3672                gen_move_low32(cpu_gpr[rd], t2);
3673            }
3674            tcg_temp_free_i64(t2);
3675        }
3676        break;
3677    case MMI_OPC_MADDU1:
3678        acc = 1;
3679        /* Fall through */
3680    case MMI_OPC_MADDU:
3681        {
3682            TCGv_i64 t2 = tcg_temp_new_i64();
3683            TCGv_i64 t3 = tcg_temp_new_i64();
3684
3685            tcg_gen_ext32u_tl(t0, t0);
3686            tcg_gen_ext32u_tl(t1, t1);
3687            tcg_gen_extu_tl_i64(t2, t0);
3688            tcg_gen_extu_tl_i64(t3, t1);
3689            tcg_gen_mul_i64(t2, t2, t3);
3690            tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
3691            tcg_gen_add_i64(t2, t2, t3);
3692            tcg_temp_free_i64(t3);
3693            gen_move_low32(cpu_LO[acc], t2);
3694            gen_move_high32(cpu_HI[acc], t2);
3695            if (rd) {
3696                gen_move_low32(cpu_gpr[rd], t2);
3697            }
3698            tcg_temp_free_i64(t2);
3699        }
3700        break;
3701    default:
3702        MIPS_INVAL("mul/madd TXx9");
3703        gen_reserved_instruction(ctx);
3704        goto out;
3705    }
3706
3707 out:
3708    tcg_temp_free(t0);
3709    tcg_temp_free(t1);
3710}
3711
3712static void gen_cl(DisasContext *ctx, uint32_t opc,
3713                   int rd, int rs)
3714{
3715    TCGv t0;
3716
3717    if (rd == 0) {
3718        /* Treat as NOP. */
3719        return;
3720    }
3721    t0 = cpu_gpr[rd];
3722    gen_load_gpr(t0, rs);
3723
3724    switch (opc) {
3725    case OPC_CLO:
3726    case R6_OPC_CLO:
3727#if defined(TARGET_MIPS64)
3728    case OPC_DCLO:
3729    case R6_OPC_DCLO:
3730#endif
3731        tcg_gen_not_tl(t0, t0);
3732        break;
3733    }
3734
3735    switch (opc) {
3736    case OPC_CLO:
3737    case R6_OPC_CLO:
3738    case OPC_CLZ:
3739    case R6_OPC_CLZ:
3740        tcg_gen_ext32u_tl(t0, t0);
3741        tcg_gen_clzi_tl(t0, t0, TARGET_LONG_BITS);
3742        tcg_gen_subi_tl(t0, t0, TARGET_LONG_BITS - 32);
3743        break;
3744#if defined(TARGET_MIPS64)
3745    case OPC_DCLO:
3746    case R6_OPC_DCLO:
3747    case OPC_DCLZ:
3748    case R6_OPC_DCLZ:
3749        tcg_gen_clzi_i64(t0, t0, 64);
3750        break;
3751#endif
3752    }
3753}
3754
3755/* Godson integer instructions */
3756static void gen_loongson_integer(DisasContext *ctx, uint32_t opc,
3757                                 int rd, int rs, int rt)
3758{
3759    TCGv t0, t1;
3760
3761    if (rd == 0) {
3762        /* Treat as NOP. */
3763        return;
3764    }
3765
3766    switch (opc) {
3767    case OPC_MULT_G_2E:
3768    case OPC_MULT_G_2F:
3769    case OPC_MULTU_G_2E:
3770    case OPC_MULTU_G_2F:
3771#if defined(TARGET_MIPS64)
3772    case OPC_DMULT_G_2E:
3773    case OPC_DMULT_G_2F:
3774    case OPC_DMULTU_G_2E:
3775    case OPC_DMULTU_G_2F:
3776#endif
3777        t0 = tcg_temp_new();
3778        t1 = tcg_temp_new();
3779        break;
3780    default:
3781        t0 = tcg_temp_local_new();
3782        t1 = tcg_temp_local_new();
3783        break;
3784    }
3785
3786    gen_load_gpr(t0, rs);
3787    gen_load_gpr(t1, rt);
3788
3789    switch (opc) {
3790    case OPC_MULT_G_2E:
3791    case OPC_MULT_G_2F:
3792        tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
3793        tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3794        break;
3795    case OPC_MULTU_G_2E:
3796    case OPC_MULTU_G_2F:
3797        tcg_gen_ext32u_tl(t0, t0);
3798        tcg_gen_ext32u_tl(t1, t1);
3799        tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
3800        tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3801        break;
3802    case OPC_DIV_G_2E:
3803    case OPC_DIV_G_2F:
3804        {
3805            TCGLabel *l1 = gen_new_label();
3806            TCGLabel *l2 = gen_new_label();
3807            TCGLabel *l3 = gen_new_label();
3808            tcg_gen_ext32s_tl(t0, t0);
3809            tcg_gen_ext32s_tl(t1, t1);
3810            tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
3811            tcg_gen_movi_tl(cpu_gpr[rd], 0);
3812            tcg_gen_br(l3);
3813            gen_set_label(l1);
3814            tcg_gen_brcondi_tl(TCG_COND_NE, t0, INT_MIN, l2);
3815            tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1, l2);
3816            tcg_gen_mov_tl(cpu_gpr[rd], t0);
3817            tcg_gen_br(l3);
3818            gen_set_label(l2);
3819            tcg_gen_div_tl(cpu_gpr[rd], t0, t1);
3820            tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3821            gen_set_label(l3);
3822        }
3823        break;
3824    case OPC_DIVU_G_2E:
3825    case OPC_DIVU_G_2F:
3826        {
3827            TCGLabel *l1 = gen_new_label();
3828            TCGLabel *l2 = gen_new_label();
3829            tcg_gen_ext32u_tl(t0, t0);
3830            tcg_gen_ext32u_tl(t1, t1);
3831            tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
3832            tcg_gen_movi_tl(cpu_gpr[rd], 0);
3833            tcg_gen_br(l2);
3834            gen_set_label(l1);
3835            tcg_gen_divu_tl(cpu_gpr[rd], t0, t1);
3836            tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3837            gen_set_label(l2);
3838        }
3839        break;
3840    case OPC_MOD_G_2E:
3841    case OPC_MOD_G_2F:
3842        {
3843            TCGLabel *l1 = gen_new_label();
3844            TCGLabel *l2 = gen_new_label();
3845            TCGLabel *l3 = gen_new_label();
3846            tcg_gen_ext32u_tl(t0, t0);
3847            tcg_gen_ext32u_tl(t1, t1);
3848            tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
3849            tcg_gen_brcondi_tl(TCG_COND_NE, t0, INT_MIN, l2);
3850            tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1, l2);
3851            gen_set_label(l1);
3852            tcg_gen_movi_tl(cpu_gpr[rd], 0);
3853            tcg_gen_br(l3);
3854            gen_set_label(l2);
3855            tcg_gen_rem_tl(cpu_gpr[rd], t0, t1);
3856            tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3857            gen_set_label(l3);
3858        }
3859        break;
3860    case OPC_MODU_G_2E:
3861    case OPC_MODU_G_2F:
3862        {
3863            TCGLabel *l1 = gen_new_label();
3864            TCGLabel *l2 = gen_new_label();
3865            tcg_gen_ext32u_tl(t0, t0);
3866            tcg_gen_ext32u_tl(t1, t1);
3867            tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
3868            tcg_gen_movi_tl(cpu_gpr[rd], 0);
3869            tcg_gen_br(l2);
3870            gen_set_label(l1);
3871            tcg_gen_remu_tl(cpu_gpr[rd], t0, t1);
3872            tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3873            gen_set_label(l2);
3874        }
3875        break;
3876#if defined(TARGET_MIPS64)
3877    case OPC_DMULT_G_2E:
3878    case OPC_DMULT_G_2F:
3879        tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
3880        break;
3881    case OPC_DMULTU_G_2E:
3882    case OPC_DMULTU_G_2F:
3883        tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
3884        break;
3885    case OPC_DDIV_G_2E:
3886    case OPC_DDIV_G_2F:
3887        {
3888            TCGLabel *l1 = gen_new_label();
3889            TCGLabel *l2 = gen_new_label();
3890            TCGLabel *l3 = gen_new_label();
3891            tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
3892            tcg_gen_movi_tl(cpu_gpr[rd], 0);
3893            tcg_gen_br(l3);
3894            gen_set_label(l1);
3895            tcg_gen_brcondi_tl(TCG_COND_NE, t0, -1LL << 63, l2);
3896            tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1LL, l2);
3897            tcg_gen_mov_tl(cpu_gpr[rd], t0);
3898            tcg_gen_br(l3);
3899            gen_set_label(l2);
3900            tcg_gen_div_tl(cpu_gpr[rd], t0, t1);
3901            gen_set_label(l3);
3902        }
3903        break;
3904    case OPC_DDIVU_G_2E:
3905    case OPC_DDIVU_G_2F:
3906        {
3907            TCGLabel *l1 = gen_new_label();
3908            TCGLabel *l2 = gen_new_label();
3909            tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
3910            tcg_gen_movi_tl(cpu_gpr[rd], 0);
3911            tcg_gen_br(l2);
3912            gen_set_label(l1);
3913            tcg_gen_divu_tl(cpu_gpr[rd], t0, t1);
3914            gen_set_label(l2);
3915        }
3916        break;
3917    case OPC_DMOD_G_2E:
3918    case OPC_DMOD_G_2F:
3919        {
3920            TCGLabel *l1 = gen_new_label();
3921            TCGLabel *l2 = gen_new_label();
3922            TCGLabel *l3 = gen_new_label();
3923            tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
3924            tcg_gen_brcondi_tl(TCG_COND_NE, t0, -1LL << 63, l2);
3925            tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1LL, l2);
3926            gen_set_label(l1);
3927            tcg_gen_movi_tl(cpu_gpr[rd], 0);
3928            tcg_gen_br(l3);
3929            gen_set_label(l2);
3930            tcg_gen_rem_tl(cpu_gpr[rd], t0, t1);
3931            gen_set_label(l3);
3932        }
3933        break;
3934    case OPC_DMODU_G_2E:
3935    case OPC_DMODU_G_2F:
3936        {
3937            TCGLabel *l1 = gen_new_label();
3938            TCGLabel *l2 = gen_new_label();
3939            tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
3940            tcg_gen_movi_tl(cpu_gpr[rd], 0);
3941            tcg_gen_br(l2);
3942            gen_set_label(l1);
3943            tcg_gen_remu_tl(cpu_gpr[rd], t0, t1);
3944            gen_set_label(l2);
3945        }
3946        break;
3947#endif
3948    }
3949
3950    tcg_temp_free(t0);
3951    tcg_temp_free(t1);
3952}
3953
3954/* Loongson multimedia instructions */
3955static void gen_loongson_multimedia(DisasContext *ctx, int rd, int rs, int rt)
3956{
3957    uint32_t opc, shift_max;
3958    TCGv_i64 t0, t1;
3959    TCGCond cond;
3960
3961    opc = MASK_LMMI(ctx->opcode);
3962    switch (opc) {
3963    case OPC_ADD_CP2:
3964    case OPC_SUB_CP2:
3965    case OPC_DADD_CP2:
3966    case OPC_DSUB_CP2:
3967        t0 = tcg_temp_local_new_i64();
3968        t1 = tcg_temp_local_new_i64();
3969        break;
3970    default:
3971        t0 = tcg_temp_new_i64();
3972        t1 = tcg_temp_new_i64();
3973        break;
3974    }
3975
3976    check_cp1_enabled(ctx);
3977    gen_load_fpr64(ctx, t0, rs);
3978    gen_load_fpr64(ctx, t1, rt);
3979
3980    switch (opc) {
3981    case OPC_PADDSH:
3982        gen_helper_paddsh(t0, t0, t1);
3983        break;
3984    case OPC_PADDUSH:
3985        gen_helper_paddush(t0, t0, t1);
3986        break;
3987    case OPC_PADDH:
3988        gen_helper_paddh(t0, t0, t1);
3989        break;
3990    case OPC_PADDW:
3991        gen_helper_paddw(t0, t0, t1);
3992        break;
3993    case OPC_PADDSB:
3994        gen_helper_paddsb(t0, t0, t1);
3995        break;
3996    case OPC_PADDUSB:
3997        gen_helper_paddusb(t0, t0, t1);
3998        break;
3999    case OPC_PADDB:
4000        gen_helper_paddb(t0, t0, t1);
4001        break;
4002
4003    case OPC_PSUBSH:
4004        gen_helper_psubsh(t0, t0, t1);
4005        break;
4006    case OPC_PSUBUSH:
4007        gen_helper_psubush(t0, t0, t1);
4008        break;
4009    case OPC_PSUBH:
4010        gen_helper_psubh(t0, t0, t1);
4011        break;
4012    case OPC_PSUBW:
4013        gen_helper_psubw(t0, t0, t1);
4014        break;
4015    case OPC_PSUBSB:
4016        gen_helper_psubsb(t0, t0, t1);
4017        break;
4018    case OPC_PSUBUSB:
4019        gen_helper_psubusb(t0, t0, t1);
4020        break;
4021    case OPC_PSUBB:
4022        gen_helper_psubb(t0, t0, t1);
4023        break;
4024
4025    case OPC_PSHUFH:
4026        gen_helper_pshufh(t0, t0, t1);
4027        break;
4028    case OPC_PACKSSWH:
4029        gen_helper_packsswh(t0, t0, t1);
4030        break;
4031    case OPC_PACKSSHB:
4032        gen_helper_packsshb(t0, t0, t1);
4033        break;
4034    case OPC_PACKUSHB:
4035        gen_helper_packushb(t0, t0, t1);
4036        break;
4037
4038    case OPC_PUNPCKLHW:
4039        gen_helper_punpcklhw(t0, t0, t1);
4040        break;
4041    case OPC_PUNPCKHHW:
4042        gen_helper_punpckhhw(t0, t0, t1);
4043        break;
4044    case OPC_PUNPCKLBH:
4045        gen_helper_punpcklbh(t0, t0, t1);
4046        break;
4047    case OPC_PUNPCKHBH:
4048        gen_helper_punpckhbh(t0, t0, t1);
4049        break;
4050    case OPC_PUNPCKLWD:
4051        gen_helper_punpcklwd(t0, t0, t1);
4052        break;
4053    case OPC_PUNPCKHWD:
4054        gen_helper_punpckhwd(t0, t0, t1);
4055        break;
4056
4057    case OPC_PAVGH:
4058        gen_helper_pavgh(t0, t0, t1);
4059        break;
4060    case OPC_PAVGB:
4061        gen_helper_pavgb(t0, t0, t1);
4062        break;
4063    case OPC_PMAXSH:
4064        gen_helper_pmaxsh(t0, t0, t1);
4065        break;
4066    case OPC_PMINSH:
4067        gen_helper_pminsh(t0, t0, t1);
4068        break;
4069    case OPC_PMAXUB:
4070        gen_helper_pmaxub(t0, t0, t1);
4071        break;
4072    case OPC_PMINUB:
4073        gen_helper_pminub(t0, t0, t1);
4074        break;
4075
4076    case OPC_PCMPEQW:
4077        gen_helper_pcmpeqw(t0, t0, t1);
4078        break;
4079    case OPC_PCMPGTW:
4080        gen_helper_pcmpgtw(t0, t0, t1);
4081        break;
4082    case OPC_PCMPEQH:
4083        gen_helper_pcmpeqh(t0, t0, t1);
4084        break;
4085    case OPC_PCMPGTH:
4086        gen_helper_pcmpgth(t0, t0, t1);
4087        break;
4088    case OPC_PCMPEQB:
4089        gen_helper_pcmpeqb(t0, t0, t1);
4090        break;
4091    case OPC_PCMPGTB:
4092        gen_helper_pcmpgtb(t0, t0, t1);
4093        break;
4094
4095    case OPC_PSLLW:
4096        gen_helper_psllw(t0, t0, t1);
4097        break;
4098    case OPC_PSLLH:
4099        gen_helper_psllh(t0, t0, t1);
4100        break;
4101    case OPC_PSRLW:
4102        gen_helper_psrlw(t0, t0, t1);
4103        break;
4104    case OPC_PSRLH:
4105        gen_helper_psrlh(t0, t0, t1);
4106        break;
4107    case OPC_PSRAW:
4108        gen_helper_psraw(t0, t0, t1);
4109        break;
4110    case OPC_PSRAH:
4111        gen_helper_psrah(t0, t0, t1);
4112        break;
4113
4114    case OPC_PMULLH:
4115        gen_helper_pmullh(t0, t0, t1);
4116        break;
4117    case OPC_PMULHH:
4118        gen_helper_pmulhh(t0, t0, t1);
4119        break;
4120    case OPC_PMULHUH:
4121        gen_helper_pmulhuh(t0, t0, t1);
4122        break;
4123    case OPC_PMADDHW:
4124        gen_helper_pmaddhw(t0, t0, t1);
4125        break;
4126
4127    case OPC_PASUBUB:
4128        gen_helper_pasubub(t0, t0, t1);
4129        break;
4130    case OPC_BIADD:
4131        gen_helper_biadd(t0, t0);
4132        break;
4133    case OPC_PMOVMSKB:
4134        gen_helper_pmovmskb(t0, t0);
4135        break;
4136
4137    case OPC_PADDD:
4138        tcg_gen_add_i64(t0, t0, t1);
4139        break;
4140    case OPC_PSUBD:
4141        tcg_gen_sub_i64(t0, t0, t1);
4142        break;
4143    case OPC_XOR_CP2:
4144        tcg_gen_xor_i64(t0, t0, t1);
4145        break;
4146    case OPC_NOR_CP2:
4147        tcg_gen_nor_i64(t0, t0, t1);
4148        break;
4149    case OPC_AND_CP2:
4150        tcg_gen_and_i64(t0, t0, t1);
4151        break;
4152    case OPC_OR_CP2:
4153        tcg_gen_or_i64(t0, t0, t1);
4154        break;
4155
4156    case OPC_PANDN:
4157        tcg_gen_andc_i64(t0, t1, t0);
4158        break;
4159
4160    case OPC_PINSRH_0:
4161        tcg_gen_deposit_i64(t0, t0, t1, 0, 16);
4162        break;
4163    case OPC_PINSRH_1:
4164        tcg_gen_deposit_i64(t0, t0, t1, 16, 16);
4165        break;
4166    case OPC_PINSRH_2:
4167        tcg_gen_deposit_i64(t0, t0, t1, 32, 16);
4168        break;
4169    case OPC_PINSRH_3:
4170        tcg_gen_deposit_i64(t0, t0, t1, 48, 16);
4171        break;
4172
4173    case OPC_PEXTRH:
4174        tcg_gen_andi_i64(t1, t1, 3);
4175        tcg_gen_shli_i64(t1, t1, 4);
4176        tcg_gen_shr_i64(t0, t0, t1);
4177        tcg_gen_ext16u_i64(t0, t0);
4178        break;
4179
4180    case OPC_ADDU_CP2:
4181        tcg_gen_add_i64(t0, t0, t1);
4182        tcg_gen_ext32s_i64(t0, t0);
4183        break;
4184    case OPC_SUBU_CP2:
4185        tcg_gen_sub_i64(t0, t0, t1);
4186        tcg_gen_ext32s_i64(t0, t0);
4187        break;
4188
4189    case OPC_SLL_CP2:
4190        shift_max = 32;
4191        goto do_shift;
4192    case OPC_SRL_CP2:
4193        shift_max = 32;
4194        goto do_shift;
4195    case OPC_SRA_CP2:
4196        shift_max = 32;
4197        goto do_shift;
4198    case OPC_DSLL_CP2:
4199        shift_max = 64;
4200        goto do_shift;
4201    case OPC_DSRL_CP2:
4202        shift_max = 64;
4203        goto do_shift;
4204    case OPC_DSRA_CP2:
4205        shift_max = 64;
4206        goto do_shift;
4207    do_shift:
4208        /* Make sure shift count isn't TCG undefined behaviour.  */
4209        tcg_gen_andi_i64(t1, t1, shift_max - 1);
4210
4211        switch (opc) {
4212        case OPC_SLL_CP2:
4213        case OPC_DSLL_CP2:
4214            tcg_gen_shl_i64(t0, t0, t1);
4215            break;
4216        case OPC_SRA_CP2:
4217        case OPC_DSRA_CP2:
4218            /*
4219             * Since SRA is UndefinedResult without sign-extended inputs,
4220             * we can treat SRA and DSRA the same.
4221             */
4222            tcg_gen_sar_i64(t0, t0, t1);
4223            break;
4224        case OPC_SRL_CP2:
4225            /* We want to shift in zeros for SRL; zero-extend first.  */
4226            tcg_gen_ext32u_i64(t0, t0);
4227            /* FALLTHRU */
4228        case OPC_DSRL_CP2:
4229            tcg_gen_shr_i64(t0, t0, t1);
4230            break;
4231        }
4232
4233        if (shift_max == 32) {
4234            tcg_gen_ext32s_i64(t0, t0);
4235        }
4236
4237        /* Shifts larger than MAX produce zero.  */
4238        tcg_gen_setcondi_i64(TCG_COND_LTU, t1, t1, shift_max);
4239        tcg_gen_neg_i64(t1, t1);
4240        tcg_gen_and_i64(t0, t0, t1);
4241        break;
4242
4243    case OPC_ADD_CP2:
4244    case OPC_DADD_CP2:
4245        {
4246            TCGv_i64 t2 = tcg_temp_new_i64();
4247            TCGLabel *lab = gen_new_label();
4248
4249            tcg_gen_mov_i64(t2, t0);
4250            tcg_gen_add_i64(t0, t1, t2);
4251            if (opc == OPC_ADD_CP2) {
4252                tcg_gen_ext32s_i64(t0, t0);
4253            }
4254            tcg_gen_xor_i64(t1, t1, t2);
4255            tcg_gen_xor_i64(t2, t2, t0);
4256            tcg_gen_andc_i64(t1, t2, t1);
4257            tcg_temp_free_i64(t2);
4258            tcg_gen_brcondi_i64(TCG_COND_GE, t1, 0, lab);
4259            generate_exception(ctx, EXCP_OVERFLOW);
4260            gen_set_label(lab);
4261            break;
4262        }
4263
4264    case OPC_SUB_CP2:
4265    case OPC_DSUB_CP2:
4266        {
4267            TCGv_i64 t2 = tcg_temp_new_i64();
4268            TCGLabel *lab = gen_new_label();
4269
4270            tcg_gen_mov_i64(t2, t0);
4271            tcg_gen_sub_i64(t0, t1, t2);
4272            if (opc == OPC_SUB_CP2) {
4273                tcg_gen_ext32s_i64(t0, t0);
4274            }
4275            tcg_gen_xor_i64(t1, t1, t2);
4276            tcg_gen_xor_i64(t2, t2, t0);
4277            tcg_gen_and_i64(t1, t1, t2);
4278            tcg_temp_free_i64(t2);
4279            tcg_gen_brcondi_i64(TCG_COND_GE, t1, 0, lab);
4280            generate_exception(ctx, EXCP_OVERFLOW);
4281            gen_set_label(lab);
4282            break;
4283        }
4284
4285    case OPC_PMULUW:
4286        tcg_gen_ext32u_i64(t0, t0);
4287        tcg_gen_ext32u_i64(t1, t1);
4288        tcg_gen_mul_i64(t0, t0, t1);
4289        break;
4290
4291    case OPC_SEQU_CP2:
4292    case OPC_SEQ_CP2:
4293        cond = TCG_COND_EQ;
4294        goto do_cc_cond;
4295        break;
4296    case OPC_SLTU_CP2:
4297        cond = TCG_COND_LTU;
4298        goto do_cc_cond;
4299        break;
4300    case OPC_SLT_CP2:
4301        cond = TCG_COND_LT;
4302        goto do_cc_cond;
4303        break;
4304    case OPC_SLEU_CP2:
4305        cond = TCG_COND_LEU;
4306        goto do_cc_cond;
4307        break;
4308    case OPC_SLE_CP2:
4309        cond = TCG_COND_LE;
4310    do_cc_cond:
4311        {
4312            int cc = (ctx->opcode >> 8) & 0x7;
4313            TCGv_i64 t64 = tcg_temp_new_i64();
4314            TCGv_i32 t32 = tcg_temp_new_i32();
4315
4316            tcg_gen_setcond_i64(cond, t64, t0, t1);
4317            tcg_gen_extrl_i64_i32(t32, t64);
4318            tcg_gen_deposit_i32(fpu_fcr31, fpu_fcr31, t32,
4319                                get_fp_bit(cc), 1);
4320
4321            tcg_temp_free_i32(t32);
4322            tcg_temp_free_i64(t64);
4323        }
4324        goto no_rd;
4325        break;
4326    default:
4327        MIPS_INVAL("loongson_cp2");
4328        gen_reserved_instruction(ctx);
4329        return;
4330    }
4331
4332    gen_store_fpr64(ctx, t0, rd);
4333
4334no_rd:
4335    tcg_temp_free_i64(t0);
4336    tcg_temp_free_i64(t1);
4337}
4338
4339static void gen_loongson_lswc2(DisasContext *ctx, int rt,
4340                               int rs, int rd)
4341{
4342    TCGv t0, t1, t2;
4343    TCGv_i32 fp0;
4344#if defined(TARGET_MIPS64)
4345    int lsq_rt1 = ctx->opcode & 0x1f;
4346    int lsq_offset = sextract32(ctx->opcode, 6, 9) << 4;
4347#endif
4348    int shf_offset = sextract32(ctx->opcode, 6, 8);
4349
4350    t0 = tcg_temp_new();
4351
4352    switch (MASK_LOONGSON_GSLSQ(ctx->opcode)) {
4353#if defined(TARGET_MIPS64)
4354    case OPC_GSLQ:
4355        t1 = tcg_temp_new();
4356        gen_base_offset_addr(ctx, t0, rs, lsq_offset);
4357        tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TEUQ |
4358                           ctx->default_tcg_memop_mask);
4359        gen_base_offset_addr(ctx, t0, rs, lsq_offset + 8);
4360        tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEUQ |
4361                           ctx->default_tcg_memop_mask);
4362        gen_store_gpr(t1, rt);
4363        gen_store_gpr(t0, lsq_rt1);
4364        tcg_temp_free(t1);
4365        break;
4366    case OPC_GSLQC1:
4367        check_cp1_enabled(ctx);
4368        t1 = tcg_temp_new();
4369        gen_base_offset_addr(ctx, t0, rs, lsq_offset);
4370        tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TEUQ |
4371                           ctx->default_tcg_memop_mask);
4372        gen_base_offset_addr(ctx, t0, rs, lsq_offset + 8);
4373        tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEUQ |
4374                           ctx->default_tcg_memop_mask);
4375        gen_store_fpr64(ctx, t1, rt);
4376        gen_store_fpr64(ctx, t0, lsq_rt1);
4377        tcg_temp_free(t1);
4378        break;
4379    case OPC_GSSQ:
4380        t1 = tcg_temp_new();
4381        gen_base_offset_addr(ctx, t0, rs, lsq_offset);
4382        gen_load_gpr(t1, rt);
4383        tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUQ |
4384                           ctx->default_tcg_memop_mask);
4385        gen_base_offset_addr(ctx, t0, rs, lsq_offset + 8);
4386        gen_load_gpr(t1, lsq_rt1);
4387        tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUQ |
4388                           ctx->default_tcg_memop_mask);
4389        tcg_temp_free(t1);
4390        break;
4391    case OPC_GSSQC1:
4392        check_cp1_enabled(ctx);
4393        t1 = tcg_temp_new();
4394        gen_base_offset_addr(ctx, t0, rs, lsq_offset);
4395        gen_load_fpr64(ctx, t1, rt);
4396        tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUQ |
4397                           ctx->default_tcg_memop_mask);
4398        gen_base_offset_addr(ctx, t0, rs, lsq_offset + 8);
4399        gen_load_fpr64(ctx, t1, lsq_rt1);
4400        tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUQ |
4401                           ctx->default_tcg_memop_mask);
4402        tcg_temp_free(t1);
4403        break;
4404#endif
4405    case OPC_GSSHFL:
4406        switch (MASK_LOONGSON_GSSHFLS(ctx->opcode)) {
4407        case OPC_GSLWLC1:
4408            check_cp1_enabled(ctx);
4409            gen_base_offset_addr(ctx, t0, rs, shf_offset);
4410            t1 = tcg_temp_new();
4411            tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_UB);
4412            tcg_gen_andi_tl(t1, t0, 3);
4413            if (!cpu_is_bigendian(ctx)) {
4414                tcg_gen_xori_tl(t1, t1, 3);
4415            }
4416            tcg_gen_shli_tl(t1, t1, 3);
4417            tcg_gen_andi_tl(t0, t0, ~3);
4418            tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEUL);
4419            tcg_gen_shl_tl(t0, t0, t1);
4420            t2 = tcg_const_tl(-1);
4421            tcg_gen_shl_tl(t2, t2, t1);
4422            fp0 = tcg_temp_new_i32();
4423            gen_load_fpr32(ctx, fp0, rt);
4424            tcg_gen_ext_i32_tl(t1, fp0);
4425            tcg_gen_andc_tl(t1, t1, t2);
4426            tcg_temp_free(t2);
4427            tcg_gen_or_tl(t0, t0, t1);
4428            tcg_temp_free(t1);
4429#if defined(TARGET_MIPS64)
4430            tcg_gen_extrl_i64_i32(fp0, t0);
4431#else
4432            tcg_gen_ext32s_tl(fp0, t0);
4433#endif
4434            gen_store_fpr32(ctx, fp0, rt);
4435            tcg_temp_free_i32(fp0);
4436            break;
4437        case OPC_GSLWRC1:
4438            check_cp1_enabled(ctx);
4439            gen_base_offset_addr(ctx, t0, rs, shf_offset);
4440            t1 = tcg_temp_new();
4441            tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_UB);
4442            tcg_gen_andi_tl(t1, t0, 3);
4443            if (cpu_is_bigendian(ctx)) {
4444                tcg_gen_xori_tl(t1, t1, 3);
4445            }
4446            tcg_gen_shli_tl(t1, t1, 3);
4447            tcg_gen_andi_tl(t0, t0, ~3);
4448            tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEUL);
4449            tcg_gen_shr_tl(t0, t0, t1);
4450            tcg_gen_xori_tl(t1, t1, 31);
4451            t2 = tcg_const_tl(0xfffffffeull);
4452            tcg_gen_shl_tl(t2, t2, t1);
4453            fp0 = tcg_temp_new_i32();
4454            gen_load_fpr32(ctx, fp0, rt);
4455            tcg_gen_ext_i32_tl(t1, fp0);
4456            tcg_gen_and_tl(t1, t1, t2);
4457            tcg_temp_free(t2);
4458            tcg_gen_or_tl(t0, t0, t1);
4459            tcg_temp_free(t1);
4460#if defined(TARGET_MIPS64)
4461            tcg_gen_extrl_i64_i32(fp0, t0);
4462#else
4463            tcg_gen_ext32s_tl(fp0, t0);
4464#endif
4465            gen_store_fpr32(ctx, fp0, rt);
4466            tcg_temp_free_i32(fp0);
4467            break;
4468#if defined(TARGET_MIPS64)
4469        case OPC_GSLDLC1:
4470            check_cp1_enabled(ctx);
4471            gen_base_offset_addr(ctx, t0, rs, shf_offset);
4472            t1 = tcg_temp_new();
4473            tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_UB);
4474            tcg_gen_andi_tl(t1, t0, 7);
4475            if (!cpu_is_bigendian(ctx)) {
4476                tcg_gen_xori_tl(t1, t1, 7);
4477            }
4478            tcg_gen_shli_tl(t1, t1, 3);
4479            tcg_gen_andi_tl(t0, t0, ~7);
4480            tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEUQ);
4481            tcg_gen_shl_tl(t0, t0, t1);
4482            t2 = tcg_const_tl(-1);
4483            tcg_gen_shl_tl(t2, t2, t1);
4484            gen_load_fpr64(ctx, t1, rt);
4485            tcg_gen_andc_tl(t1, t1, t2);
4486            tcg_temp_free(t2);
4487            tcg_gen_or_tl(t0, t0, t1);
4488            tcg_temp_free(t1);
4489            gen_store_fpr64(ctx, t0, rt);
4490            break;
4491        case OPC_GSLDRC1:
4492            check_cp1_enabled(ctx);
4493            gen_base_offset_addr(ctx, t0, rs, shf_offset);
4494            t1 = tcg_temp_new();
4495            tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_UB);
4496            tcg_gen_andi_tl(t1, t0, 7);
4497            if (cpu_is_bigendian(ctx)) {
4498                tcg_gen_xori_tl(t1, t1, 7);
4499            }
4500            tcg_gen_shli_tl(t1, t1, 3);
4501            tcg_gen_andi_tl(t0, t0, ~7);
4502            tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEUQ);
4503            tcg_gen_shr_tl(t0, t0, t1);
4504            tcg_gen_xori_tl(t1, t1, 63);
4505            t2 = tcg_const_tl(0xfffffffffffffffeull);
4506            tcg_gen_shl_tl(t2, t2, t1);
4507            gen_load_fpr64(ctx, t1, rt);
4508            tcg_gen_and_tl(t1, t1, t2);
4509            tcg_temp_free(t2);
4510            tcg_gen_or_tl(t0, t0, t1);
4511            tcg_temp_free(t1);
4512            gen_store_fpr64(ctx, t0, rt);
4513            break;
4514#endif
4515        default:
4516            MIPS_INVAL("loongson_gsshfl");
4517            gen_reserved_instruction(ctx);
4518            break;
4519        }
4520        break;
4521    case OPC_GSSHFS:
4522        switch (MASK_LOONGSON_GSSHFLS(ctx->opcode)) {
4523        case OPC_GSSWLC1:
4524            check_cp1_enabled(ctx);
4525            t1 = tcg_temp_new();
4526            gen_base_offset_addr(ctx, t0, rs, shf_offset);
4527            fp0 = tcg_temp_new_i32();
4528            gen_load_fpr32(ctx, fp0, rt);
4529            tcg_gen_ext_i32_tl(t1, fp0);
4530            gen_helper_0e2i(swl, t1, t0, ctx->mem_idx);
4531            tcg_temp_free_i32(fp0);
4532            tcg_temp_free(t1);
4533            break;
4534        case OPC_GSSWRC1:
4535            check_cp1_enabled(ctx);
4536            t1 = tcg_temp_new();
4537            gen_base_offset_addr(ctx, t0, rs, shf_offset);
4538            fp0 = tcg_temp_new_i32();
4539            gen_load_fpr32(ctx, fp0, rt);
4540            tcg_gen_ext_i32_tl(t1, fp0);
4541            gen_helper_0e2i(swr, t1, t0, ctx->mem_idx);
4542            tcg_temp_free_i32(fp0);
4543            tcg_temp_free(t1);
4544            break;
4545#if defined(TARGET_MIPS64)
4546        case OPC_GSSDLC1:
4547            check_cp1_enabled(ctx);
4548            t1 = tcg_temp_new();
4549            gen_base_offset_addr(ctx, t0, rs, shf_offset);
4550            gen_load_fpr64(ctx, t1, rt);
4551            gen_helper_0e2i(sdl, t1, t0, ctx->mem_idx);
4552            tcg_temp_free(t1);
4553            break;
4554        case OPC_GSSDRC1:
4555            check_cp1_enabled(ctx);
4556            t1 = tcg_temp_new();
4557            gen_base_offset_addr(ctx, t0, rs, shf_offset);
4558            gen_load_fpr64(ctx, t1, rt);
4559            gen_helper_0e2i(sdr, t1, t0, ctx->mem_idx);
4560            tcg_temp_free(t1);
4561            break;
4562#endif
4563        default:
4564            MIPS_INVAL("loongson_gsshfs");
4565            gen_reserved_instruction(ctx);
4566            break;
4567        }
4568        break;
4569    default:
4570        MIPS_INVAL("loongson_gslsq");
4571        gen_reserved_instruction(ctx);
4572        break;
4573    }
4574    tcg_temp_free(t0);
4575}
4576
4577/* Loongson EXT LDC2/SDC2 */
4578static void gen_loongson_lsdc2(DisasContext *ctx, int rt,
4579                               int rs, int rd)
4580{
4581    int offset = sextract32(ctx->opcode, 3, 8);
4582    uint32_t opc = MASK_LOONGSON_LSDC2(ctx->opcode);
4583    TCGv t0, t1;
4584    TCGv_i32 fp0;
4585
4586    /* Pre-conditions */
4587    switch (opc) {
4588    case OPC_GSLBX:
4589    case OPC_GSLHX:
4590    case OPC_GSLWX:
4591    case OPC_GSLDX:
4592        /* prefetch, implement as NOP */
4593        if (rt == 0) {
4594            return;
4595        }
4596        break;
4597    case OPC_GSSBX:
4598    case OPC_GSSHX:
4599    case OPC_GSSWX:
4600    case OPC_GSSDX:
4601        break;
4602    case OPC_GSLWXC1:
4603#if defined(TARGET_MIPS64)
4604    case OPC_GSLDXC1:
4605#endif
4606        check_cp1_enabled(ctx);
4607        /* prefetch, implement as NOP */
4608        if (rt == 0) {
4609            return;
4610        }
4611        break;
4612    case OPC_GSSWXC1:
4613#if defined(TARGET_MIPS64)
4614    case OPC_GSSDXC1:
4615#endif
4616        check_cp1_enabled(ctx);
4617        break;
4618    default:
4619        MIPS_INVAL("loongson_lsdc2");
4620        gen_reserved_instruction(ctx);
4621        return;
4622        break;
4623    }
4624
4625    t0 = tcg_temp_new();
4626
4627    gen_base_offset_addr(ctx, t0, rs, offset);
4628    gen_op_addr_add(ctx, t0, cpu_gpr[rd], t0);
4629
4630    switch (opc) {
4631    case OPC_GSLBX:
4632        tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_SB);
4633        gen_store_gpr(t0, rt);
4634        break;
4635    case OPC_GSLHX:
4636        tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TESW |
4637                           ctx->default_tcg_memop_mask);
4638        gen_store_gpr(t0, rt);
4639        break;
4640    case OPC_GSLWX:
4641        gen_base_offset_addr(ctx, t0, rs, offset);
4642        if (rd) {
4643            gen_op_addr_add(ctx, t0, cpu_gpr[rd], t0);
4644        }
4645        tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TESL |
4646                           ctx->default_tcg_memop_mask);
4647        gen_store_gpr(t0, rt);
4648        break;
4649#if defined(TARGET_MIPS64)
4650    case OPC_GSLDX:
4651        gen_base_offset_addr(ctx, t0, rs, offset);
4652        if (rd) {
4653            gen_op_addr_add(ctx, t0, cpu_gpr[rd], t0);
4654        }
4655        tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEUQ |
4656                           ctx->default_tcg_memop_mask);
4657        gen_store_gpr(t0, rt);
4658        break;
4659#endif
4660    case OPC_GSLWXC1:
4661        gen_base_offset_addr(ctx, t0, rs, offset);
4662        if (rd) {
4663            gen_op_addr_add(ctx, t0, cpu_gpr[rd], t0);
4664        }
4665        fp0 = tcg_temp_new_i32();
4666        tcg_gen_qemu_ld_i32(fp0, t0, ctx->mem_idx, MO_TESL |
4667                            ctx->default_tcg_memop_mask);
4668        gen_store_fpr32(ctx, fp0, rt);
4669        tcg_temp_free_i32(fp0);
4670        break;
4671#if defined(TARGET_MIPS64)
4672    case OPC_GSLDXC1:
4673        gen_base_offset_addr(ctx, t0, rs, offset);
4674        if (rd) {
4675            gen_op_addr_add(ctx, t0, cpu_gpr[rd], t0);
4676        }
4677        tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEUQ |
4678                           ctx->default_tcg_memop_mask);
4679        gen_store_fpr64(ctx, t0, rt);
4680        break;
4681#endif
4682    case OPC_GSSBX:
4683        t1 = tcg_temp_new();
4684        gen_load_gpr(t1, rt);
4685        tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_SB);
4686        tcg_temp_free(t1);
4687        break;
4688    case OPC_GSSHX:
4689        t1 = tcg_temp_new();
4690        gen_load_gpr(t1, rt);
4691        tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUW |
4692                           ctx->default_tcg_memop_mask);
4693        tcg_temp_free(t1);
4694        break;
4695    case OPC_GSSWX:
4696        t1 = tcg_temp_new();
4697        gen_load_gpr(t1, rt);
4698        tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL |
4699                           ctx->default_tcg_memop_mask);
4700        tcg_temp_free(t1);
4701        break;
4702#if defined(TARGET_MIPS64)
4703    case OPC_GSSDX:
4704        t1 = tcg_temp_new();
4705        gen_load_gpr(t1, rt);
4706        tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUQ |
4707                           ctx->default_tcg_memop_mask);
4708        tcg_temp_free(t1);
4709        break;
4710#endif
4711    case OPC_GSSWXC1:
4712        fp0 = tcg_temp_new_i32();
4713        gen_load_fpr32(ctx, fp0, rt);
4714        tcg_gen_qemu_st_i32(fp0, t0, ctx->mem_idx, MO_TEUL |
4715                            ctx->default_tcg_memop_mask);
4716        tcg_temp_free_i32(fp0);
4717        break;
4718#if defined(TARGET_MIPS64)
4719    case OPC_GSSDXC1:
4720        t1 = tcg_temp_new();
4721        gen_load_fpr64(ctx, t1, rt);
4722        tcg_gen_qemu_st_i64(t1, t0, ctx->mem_idx, MO_TEUQ |
4723                            ctx->default_tcg_memop_mask);
4724        tcg_temp_free(t1);
4725        break;
4726#endif
4727    default:
4728        break;
4729    }
4730
4731    tcg_temp_free(t0);
4732}
4733
4734/* Traps */
4735static void gen_trap(DisasContext *ctx, uint32_t opc,
4736                     int rs, int rt, int16_t imm, int code)
4737{
4738    int cond;
4739    TCGv t0 = tcg_temp_new();
4740    TCGv t1 = tcg_temp_new();
4741
4742    cond = 0;
4743    /* Load needed operands */
4744    switch (opc) {
4745    case OPC_TEQ:
4746    case OPC_TGE:
4747    case OPC_TGEU:
4748    case OPC_TLT:
4749    case OPC_TLTU:
4750    case OPC_TNE:
4751        /* Compare two registers */
4752        if (rs != rt) {
4753            gen_load_gpr(t0, rs);
4754            gen_load_gpr(t1, rt);
4755            cond = 1;
4756        }
4757        break;
4758    case OPC_TEQI:
4759    case OPC_TGEI:
4760    case OPC_TGEIU:
4761    case OPC_TLTI:
4762    case OPC_TLTIU:
4763    case OPC_TNEI:
4764        /* Compare register to immediate */
4765        if (rs != 0 || imm != 0) {
4766            gen_load_gpr(t0, rs);
4767            tcg_gen_movi_tl(t1, (int32_t)imm);
4768            cond = 1;
4769        }
4770        break;
4771    }
4772    if (cond == 0) {
4773        switch (opc) {
4774        case OPC_TEQ:   /* rs == rs */
4775        case OPC_TEQI:  /* r0 == 0  */
4776        case OPC_TGE:   /* rs >= rs */
4777        case OPC_TGEI:  /* r0 >= 0  */
4778        case OPC_TGEU:  /* rs >= rs unsigned */
4779        case OPC_TGEIU: /* r0 >= 0  unsigned */
4780            /* Always trap */
4781#ifdef CONFIG_USER_ONLY
4782            /* Pass the break code along to cpu_loop. */
4783            tcg_gen_st_i32(tcg_constant_i32(code), cpu_env,
4784                           offsetof(CPUMIPSState, error_code));
4785#endif
4786            generate_exception_end(ctx, EXCP_TRAP);
4787            break;
4788        case OPC_TLT:   /* rs < rs           */
4789        case OPC_TLTI:  /* r0 < 0            */
4790        case OPC_TLTU:  /* rs < rs unsigned  */
4791        case OPC_TLTIU: /* r0 < 0  unsigned  */
4792        case OPC_TNE:   /* rs != rs          */
4793        case OPC_TNEI:  /* r0 != 0           */
4794            /* Never trap: treat as NOP. */
4795            break;
4796        }
4797    } else {
4798        TCGLabel *l1 = gen_new_label();
4799
4800        switch (opc) {
4801        case OPC_TEQ:
4802        case OPC_TEQI:
4803            tcg_gen_brcond_tl(TCG_COND_NE, t0, t1, l1);
4804            break;
4805        case OPC_TGE:
4806        case OPC_TGEI:
4807            tcg_gen_brcond_tl(TCG_COND_LT, t0, t1, l1);
4808            break;
4809        case OPC_TGEU:
4810        case OPC_TGEIU:
4811            tcg_gen_brcond_tl(TCG_COND_LTU, t0, t1, l1);
4812            break;
4813        case OPC_TLT:
4814        case OPC_TLTI:
4815            tcg_gen_brcond_tl(TCG_COND_GE, t0, t1, l1);
4816            break;
4817        case OPC_TLTU:
4818        case OPC_TLTIU:
4819            tcg_gen_brcond_tl(TCG_COND_GEU, t0, t1, l1);
4820            break;
4821        case OPC_TNE:
4822        case OPC_TNEI:
4823            tcg_gen_brcond_tl(TCG_COND_EQ, t0, t1, l1);
4824            break;
4825        }
4826#ifdef CONFIG_USER_ONLY
4827        /* Pass the break code along to cpu_loop. */
4828        tcg_gen_st_i32(tcg_constant_i32(code), cpu_env,
4829                       offsetof(CPUMIPSState, error_code));
4830#endif
4831        /* Like save_cpu_state, only don't update saved values. */
4832        if (ctx->base.pc_next != ctx->saved_pc) {
4833            gen_save_pc(ctx->base.pc_next);
4834        }
4835        if (ctx->hflags != ctx->saved_hflags) {
4836            tcg_gen_movi_i32(hflags, ctx->hflags);
4837        }
4838        generate_exception(ctx, EXCP_TRAP);
4839        gen_set_label(l1);
4840    }
4841    tcg_temp_free(t0);
4842    tcg_temp_free(t1);
4843}
4844
4845static void gen_goto_tb(DisasContext *ctx, int n, target_ulong dest)
4846{
4847    if (translator_use_goto_tb(&ctx->base, dest)) {
4848        tcg_gen_goto_tb(n);
4849        gen_save_pc(dest);
4850        tcg_gen_exit_tb(ctx->base.tb, n);
4851    } else {
4852        gen_save_pc(dest);
4853        tcg_gen_lookup_and_goto_ptr();
4854    }
4855}
4856
4857/* Branches (before delay slot) */
4858static void gen_compute_branch(DisasContext *ctx, uint32_t opc,
4859                               int insn_bytes,
4860                               int rs, int rt, int32_t offset,
4861                               int delayslot_size)
4862{
4863    target_ulong btgt = -1;
4864    int blink = 0;
4865    int bcond_compute = 0;
4866    TCGv t0 = tcg_temp_new();
4867    TCGv t1 = tcg_temp_new();
4868
4869    if (ctx->hflags & MIPS_HFLAG_BMASK) {
4870#ifdef MIPS_DEBUG_DISAS
4871        LOG_DISAS("Branch in delay / forbidden slot at PC 0x"
4872                  TARGET_FMT_lx "\n", ctx->base.pc_next);
4873#endif
4874        gen_reserved_instruction(ctx);
4875        goto out;
4876    }
4877
4878    /* Load needed operands */
4879    switch (opc) {
4880    case OPC_BEQ:
4881    case OPC_BEQL:
4882    case OPC_BNE:
4883    case OPC_BNEL:
4884        /* Compare two registers */
4885        if (rs != rt) {
4886            gen_load_gpr(t0, rs);
4887            gen_load_gpr(t1, rt);
4888            bcond_compute = 1;
4889        }
4890        btgt = ctx->base.pc_next + insn_bytes + offset;
4891        break;
4892    case OPC_BGEZ:
4893    case OPC_BGEZAL:
4894    case OPC_BGEZALL:
4895    case OPC_BGEZL:
4896    case OPC_BGTZ:
4897    case OPC_BGTZL:
4898    case OPC_BLEZ:
4899    case OPC_BLEZL:
4900    case OPC_BLTZ:
4901    case OPC_BLTZAL:
4902    case OPC_BLTZALL:
4903    case OPC_BLTZL:
4904        /* Compare to zero */
4905        if (rs != 0) {
4906            gen_load_gpr(t0, rs);
4907            bcond_compute = 1;
4908        }
4909        btgt = ctx->base.pc_next + insn_bytes + offset;
4910        break;
4911    case OPC_BPOSGE32:
4912#if defined(TARGET_MIPS64)
4913    case OPC_BPOSGE64:
4914        tcg_gen_andi_tl(t0, cpu_dspctrl, 0x7F);
4915#else
4916        tcg_gen_andi_tl(t0, cpu_dspctrl, 0x3F);
4917#endif
4918        bcond_compute = 1;
4919        btgt = ctx->base.pc_next + insn_bytes + offset;
4920        break;
4921    case OPC_J:
4922    case OPC_JAL:
4923    case OPC_JALX:
4924        /* Jump to immediate */
4925        btgt = ((ctx->base.pc_next + insn_bytes) & (int32_t)0xF0000000) |
4926            (uint32_t)offset;
4927        break;
4928    case OPC_JR:
4929    case OPC_JALR:
4930        /* Jump to register */
4931        if (offset != 0 && offset != 16) {
4932            /*
4933             * Hint = 0 is JR/JALR, hint 16 is JR.HB/JALR.HB, the
4934             * others are reserved.
4935             */
4936            MIPS_INVAL("jump hint");
4937            gen_reserved_instruction(ctx);
4938            goto out;
4939        }
4940        gen_load_gpr(btarget, rs);
4941        break;
4942    default:
4943        MIPS_INVAL("branch/jump");
4944        gen_reserved_instruction(ctx);
4945        goto out;
4946    }
4947    if (bcond_compute == 0) {
4948        /* No condition to be computed */
4949        switch (opc) {
4950        case OPC_BEQ:     /* rx == rx        */
4951        case OPC_BEQL:    /* rx == rx likely */
4952        case OPC_BGEZ:    /* 0 >= 0          */
4953        case OPC_BGEZL:   /* 0 >= 0 likely   */
4954        case OPC_BLEZ:    /* 0 <= 0          */
4955        case OPC_BLEZL:   /* 0 <= 0 likely   */
4956            /* Always take */
4957            ctx->hflags |= MIPS_HFLAG_B;
4958            break;
4959        case OPC_BGEZAL:  /* 0 >= 0          */
4960        case OPC_BGEZALL: /* 0 >= 0 likely   */
4961            /* Always take and link */
4962            blink = 31;
4963            ctx->hflags |= MIPS_HFLAG_B;
4964            break;
4965        case OPC_BNE:     /* rx != rx        */
4966        case OPC_BGTZ:    /* 0 > 0           */
4967        case OPC_BLTZ:    /* 0 < 0           */
4968            /* Treat as NOP. */
4969            goto out;
4970        case OPC_BLTZAL:  /* 0 < 0           */
4971            /*
4972             * Handle as an unconditional branch to get correct delay
4973             * slot checking.
4974             */
4975            blink = 31;
4976            btgt = ctx->base.pc_next + insn_bytes + delayslot_size;
4977            ctx->hflags |= MIPS_HFLAG_B;
4978            break;
4979        case OPC_BLTZALL: /* 0 < 0 likely */
4980            tcg_gen_movi_tl(cpu_gpr[31], ctx->base.pc_next + 8);
4981            /* Skip the instruction in the delay slot */
4982            ctx->base.pc_next += 4;
4983            goto out;
4984        case OPC_BNEL:    /* rx != rx likely */
4985        case OPC_BGTZL:   /* 0 > 0 likely */
4986        case OPC_BLTZL:   /* 0 < 0 likely */
4987            /* Skip the instruction in the delay slot */
4988            ctx->base.pc_next += 4;
4989            goto out;
4990        case OPC_J:
4991            ctx->hflags |= MIPS_HFLAG_B;
4992            break;
4993        case OPC_JALX:
4994            ctx->hflags |= MIPS_HFLAG_BX;
4995            /* Fallthrough */
4996        case OPC_JAL:
4997            blink = 31;
4998            ctx->hflags |= MIPS_HFLAG_B;
4999            break;
5000        case OPC_JR:
5001            ctx->hflags |= MIPS_HFLAG_BR;
5002            break;
5003        case OPC_JALR:
5004            blink = rt;
5005            ctx->hflags |= MIPS_HFLAG_BR;
5006            break;
5007        default:
5008            MIPS_INVAL("branch/jump");
5009            gen_reserved_instruction(ctx);
5010            goto out;
5011        }
5012    } else {
5013        switch (opc) {
5014        case OPC_BEQ:
5015            tcg_gen_setcond_tl(TCG_COND_EQ, bcond, t0, t1);
5016            goto not_likely;
5017        case OPC_BEQL:
5018            tcg_gen_setcond_tl(TCG_COND_EQ, bcond, t0, t1);
5019            goto likely;
5020        case OPC_BNE:
5021            tcg_gen_setcond_tl(TCG_COND_NE, bcond, t0, t1);
5022            goto not_likely;
5023        case OPC_BNEL:
5024            tcg_gen_setcond_tl(TCG_COND_NE, bcond, t0, t1);
5025            goto likely;
5026        case OPC_BGEZ:
5027            tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
5028            goto not_likely;
5029        case OPC_BGEZL:
5030            tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
5031            goto likely;
5032        case OPC_BGEZAL:
5033            tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
5034            blink = 31;
5035            goto not_likely;
5036        case OPC_BGEZALL:
5037            tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
5038            blink = 31;
5039            goto likely;
5040        case OPC_BGTZ:
5041            tcg_gen_setcondi_tl(TCG_COND_GT, bcond, t0, 0);
5042            goto not_likely;
5043        case OPC_BGTZL:
5044            tcg_gen_setcondi_tl(TCG_COND_GT, bcond, t0, 0);
5045            goto likely;
5046        case OPC_BLEZ:
5047            tcg_gen_setcondi_tl(TCG_COND_LE, bcond, t0, 0);
5048            goto not_likely;
5049        case OPC_BLEZL:
5050            tcg_gen_setcondi_tl(TCG_COND_LE, bcond, t0, 0);
5051            goto likely;
5052        case OPC_BLTZ:
5053            tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
5054            goto not_likely;
5055        case OPC_BLTZL:
5056            tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
5057            goto likely;
5058        case OPC_BPOSGE32:
5059            tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 32);
5060            goto not_likely;
5061#if defined(TARGET_MIPS64)
5062        case OPC_BPOSGE64:
5063            tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 64);
5064            goto not_likely;
5065#endif
5066        case OPC_BLTZAL:
5067            tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
5068            blink = 31;
5069        not_likely:
5070            ctx->hflags |= MIPS_HFLAG_BC;
5071            break;
5072        case OPC_BLTZALL:
5073            tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
5074            blink = 31;
5075        likely:
5076            ctx->hflags |= MIPS_HFLAG_BL;
5077            break;
5078        default:
5079            MIPS_INVAL("conditional branch/jump");
5080            gen_reserved_instruction(ctx);
5081            goto out;
5082        }
5083    }
5084
5085    ctx->btarget = btgt;
5086
5087    switch (delayslot_size) {
5088    case 2:
5089        ctx->hflags |= MIPS_HFLAG_BDS16;
5090        break;
5091    case 4:
5092        ctx->hflags |= MIPS_HFLAG_BDS32;
5093        break;
5094    }
5095
5096    if (blink > 0) {
5097        int post_delay = insn_bytes + delayslot_size;
5098        int lowbit = !!(ctx->hflags & MIPS_HFLAG_M16);
5099
5100        tcg_gen_movi_tl(cpu_gpr[blink],
5101                        ctx->base.pc_next + post_delay + lowbit);
5102    }
5103
5104 out:
5105    if (insn_bytes == 2) {
5106        ctx->hflags |= MIPS_HFLAG_B16;
5107    }
5108    tcg_temp_free(t0);
5109    tcg_temp_free(t1);
5110}
5111
5112
5113/* special3 bitfield operations */
5114static void gen_bitops(DisasContext *ctx, uint32_t opc, int rt,
5115                       int rs, int lsb, int msb)
5116{
5117    TCGv t0 = tcg_temp_new();
5118    TCGv t1 = tcg_temp_new();
5119
5120    gen_load_gpr(t1, rs);
5121    switch (opc) {
5122    case OPC_EXT:
5123        if (lsb + msb > 31) {
5124            goto fail;
5125        }
5126        if (msb != 31) {
5127            tcg_gen_extract_tl(t0, t1, lsb, msb + 1);
5128        } else {
5129            /*
5130             * The two checks together imply that lsb == 0,
5131             * so this is a simple sign-extension.
5132             */
5133            tcg_gen_ext32s_tl(t0, t1);
5134        }
5135        break;
5136#if defined(TARGET_MIPS64)
5137    case OPC_DEXTU:
5138        lsb += 32;
5139        goto do_dext;
5140    case OPC_DEXTM:
5141        msb += 32;
5142        goto do_dext;
5143    case OPC_DEXT:
5144    do_dext:
5145        if (lsb + msb > 63) {
5146            goto fail;
5147        }
5148        tcg_gen_extract_tl(t0, t1, lsb, msb + 1);
5149        break;
5150#endif
5151    case OPC_INS:
5152        if (lsb > msb) {
5153            goto fail;
5154        }
5155        gen_load_gpr(t0, rt);
5156        tcg_gen_deposit_tl(t0, t0, t1, lsb, msb - lsb + 1);
5157        tcg_gen_ext32s_tl(t0, t0);
5158        break;
5159#if defined(TARGET_MIPS64)
5160    case OPC_DINSU:
5161        lsb += 32;
5162        /* FALLTHRU */
5163    case OPC_DINSM:
5164        msb += 32;
5165        /* FALLTHRU */
5166    case OPC_DINS:
5167        if (lsb > msb) {
5168            goto fail;
5169        }
5170        gen_load_gpr(t0, rt);
5171        tcg_gen_deposit_tl(t0, t0, t1, lsb, msb - lsb + 1);
5172        break;
5173#endif
5174    default:
5175fail:
5176        MIPS_INVAL("bitops");
5177        gen_reserved_instruction(ctx);
5178        tcg_temp_free(t0);
5179        tcg_temp_free(t1);
5180        return;
5181    }
5182    gen_store_gpr(t0, rt);
5183    tcg_temp_free(t0);
5184    tcg_temp_free(t1);
5185}
5186
5187static void gen_bshfl(DisasContext *ctx, uint32_t op2, int rt, int rd)
5188{
5189    TCGv t0;
5190
5191    if (rd == 0) {
5192        /* If no destination, treat it as a NOP. */
5193        return;
5194    }
5195
5196    t0 = tcg_temp_new();
5197    gen_load_gpr(t0, rt);
5198    switch (op2) {
5199    case OPC_WSBH:
5200        {
5201            TCGv t1 = tcg_temp_new();
5202            TCGv t2 = tcg_const_tl(0x00FF00FF);
5203
5204            tcg_gen_shri_tl(t1, t0, 8);
5205            tcg_gen_and_tl(t1, t1, t2);
5206            tcg_gen_and_tl(t0, t0, t2);
5207            tcg_gen_shli_tl(t0, t0, 8);
5208            tcg_gen_or_tl(t0, t0, t1);
5209            tcg_temp_free(t2);
5210            tcg_temp_free(t1);
5211            tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
5212        }
5213        break;
5214    case OPC_SEB:
5215        tcg_gen_ext8s_tl(cpu_gpr[rd], t0);
5216        break;
5217    case OPC_SEH:
5218        tcg_gen_ext16s_tl(cpu_gpr[rd], t0);
5219        break;
5220#if defined(TARGET_MIPS64)
5221    case OPC_DSBH:
5222        {
5223            TCGv t1 = tcg_temp_new();
5224            TCGv t2 = tcg_const_tl(0x00FF00FF00FF00FFULL);
5225
5226            tcg_gen_shri_tl(t1, t0, 8);
5227            tcg_gen_and_tl(t1, t1, t2);
5228            tcg_gen_and_tl(t0, t0, t2);
5229            tcg_gen_shli_tl(t0, t0, 8);
5230            tcg_gen_or_tl(cpu_gpr[rd], t0, t1);
5231            tcg_temp_free(t2);
5232            tcg_temp_free(t1);
5233        }
5234        break;
5235    case OPC_DSHD:
5236        {
5237            TCGv t1 = tcg_temp_new();
5238            TCGv t2 = tcg_const_tl(0x0000FFFF0000FFFFULL);
5239
5240            tcg_gen_shri_tl(t1, t0, 16);
5241            tcg_gen_and_tl(t1, t1, t2);
5242            tcg_gen_and_tl(t0, t0, t2);
5243            tcg_gen_shli_tl(t0, t0, 16);
5244            tcg_gen_or_tl(t0, t0, t1);
5245            tcg_gen_shri_tl(t1, t0, 32);
5246            tcg_gen_shli_tl(t0, t0, 32);
5247            tcg_gen_or_tl(cpu_gpr[rd], t0, t1);
5248            tcg_temp_free(t2);
5249            tcg_temp_free(t1);
5250        }
5251        break;
5252#endif
5253    default:
5254        MIPS_INVAL("bsfhl");
5255        gen_reserved_instruction(ctx);
5256        tcg_temp_free(t0);
5257        return;
5258    }
5259    tcg_temp_free(t0);
5260}
5261
5262static void gen_align_bits(DisasContext *ctx, int wordsz, int rd, int rs,
5263                           int rt, int bits)
5264{
5265    TCGv t0;
5266    if (rd == 0) {
5267        /* Treat as NOP. */
5268        return;
5269    }
5270    t0 = tcg_temp_new();
5271    if (bits == 0 || bits == wordsz) {
5272        if (bits == 0) {
5273            gen_load_gpr(t0, rt);
5274        } else {
5275            gen_load_gpr(t0, rs);
5276        }
5277        switch (wordsz) {
5278        case 32:
5279            tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
5280            break;
5281#if defined(TARGET_MIPS64)
5282        case 64:
5283            tcg_gen_mov_tl(cpu_gpr[rd], t0);
5284            break;
5285#endif
5286        }
5287    } else {
5288        TCGv t1 = tcg_temp_new();
5289        gen_load_gpr(t0, rt);
5290        gen_load_gpr(t1, rs);
5291        switch (wordsz) {
5292        case 32:
5293            {
5294                TCGv_i64 t2 = tcg_temp_new_i64();
5295                tcg_gen_concat_tl_i64(t2, t1, t0);
5296                tcg_gen_shri_i64(t2, t2, 32 - bits);
5297                gen_move_low32(cpu_gpr[rd], t2);
5298                tcg_temp_free_i64(t2);
5299            }
5300            break;
5301#if defined(TARGET_MIPS64)
5302        case 64:
5303            tcg_gen_shli_tl(t0, t0, bits);
5304            tcg_gen_shri_tl(t1, t1, 64 - bits);
5305            tcg_gen_or_tl(cpu_gpr[rd], t1, t0);
5306            break;
5307#endif
5308        }
5309        tcg_temp_free(t1);
5310    }
5311
5312    tcg_temp_free(t0);
5313}
5314
5315void gen_align(DisasContext *ctx, int wordsz, int rd, int rs, int rt, int bp)
5316{
5317    gen_align_bits(ctx, wordsz, rd, rs, rt, bp * 8);
5318}
5319
5320static void gen_bitswap(DisasContext *ctx, int opc, int rd, int rt)
5321{
5322    TCGv t0;
5323    if (rd == 0) {
5324        /* Treat as NOP. */
5325        return;
5326    }
5327    t0 = tcg_temp_new();
5328    gen_load_gpr(t0, rt);
5329    switch (opc) {
5330    case OPC_BITSWAP:
5331        gen_helper_bitswap(cpu_gpr[rd], t0);
5332        break;
5333#if defined(TARGET_MIPS64)
5334    case OPC_DBITSWAP:
5335        gen_helper_dbitswap(cpu_gpr[rd], t0);
5336        break;
5337#endif
5338    }
5339    tcg_temp_free(t0);
5340}
5341
5342#ifndef CONFIG_USER_ONLY
5343/* CP0 (MMU and control) */
5344static inline void gen_mthc0_entrylo(TCGv arg, target_ulong off)
5345{
5346    TCGv_i64 t0 = tcg_temp_new_i64();
5347    TCGv_i64 t1 = tcg_temp_new_i64();
5348
5349    tcg_gen_ext_tl_i64(t0, arg);
5350    tcg_gen_ld_i64(t1, cpu_env, off);
5351#if defined(TARGET_MIPS64)
5352    tcg_gen_deposit_i64(t1, t1, t0, 30, 32);
5353#else
5354    tcg_gen_concat32_i64(t1, t1, t0);
5355#endif
5356    tcg_gen_st_i64(t1, cpu_env, off);
5357    tcg_temp_free_i64(t1);
5358    tcg_temp_free_i64(t0);
5359}
5360
5361static inline void gen_mthc0_store64(TCGv arg, target_ulong off)
5362{
5363    TCGv_i64 t0 = tcg_temp_new_i64();
5364    TCGv_i64 t1 = tcg_temp_new_i64();
5365
5366    tcg_gen_ext_tl_i64(t0, arg);
5367    tcg_gen_ld_i64(t1, cpu_env, off);
5368    tcg_gen_concat32_i64(t1, t1, t0);
5369    tcg_gen_st_i64(t1, cpu_env, off);
5370    tcg_temp_free_i64(t1);
5371    tcg_temp_free_i64(t0);
5372}
5373
5374static inline void gen_mfhc0_entrylo(TCGv arg, target_ulong off)
5375{
5376    TCGv_i64 t0 = tcg_temp_new_i64();
5377
5378    tcg_gen_ld_i64(t0, cpu_env, off);
5379#if defined(TARGET_MIPS64)
5380    tcg_gen_shri_i64(t0, t0, 30);
5381#else
5382    tcg_gen_shri_i64(t0, t0, 32);
5383#endif
5384    gen_move_low32(arg, t0);
5385    tcg_temp_free_i64(t0);
5386}
5387
5388static inline void gen_mfhc0_load64(TCGv arg, target_ulong off, int shift)
5389{
5390    TCGv_i64 t0 = tcg_temp_new_i64();
5391
5392    tcg_gen_ld_i64(t0, cpu_env, off);
5393    tcg_gen_shri_i64(t0, t0, 32 + shift);
5394    gen_move_low32(arg, t0);
5395    tcg_temp_free_i64(t0);
5396}
5397
5398static inline void gen_mfc0_load32(TCGv arg, target_ulong off)
5399{
5400    TCGv_i32 t0 = tcg_temp_new_i32();
5401
5402    tcg_gen_ld_i32(t0, cpu_env, off);
5403    tcg_gen_ext_i32_tl(arg, t0);
5404    tcg_temp_free_i32(t0);
5405}
5406
5407static inline void gen_mfc0_load64(TCGv arg, target_ulong off)
5408{
5409    tcg_gen_ld_tl(arg, cpu_env, off);
5410    tcg_gen_ext32s_tl(arg, arg);
5411}
5412
5413static inline void gen_mtc0_store32(TCGv arg, target_ulong off)
5414{
5415    TCGv_i32 t0 = tcg_temp_new_i32();
5416
5417    tcg_gen_trunc_tl_i32(t0, arg);
5418    tcg_gen_st_i32(t0, cpu_env, off);
5419    tcg_temp_free_i32(t0);
5420}
5421
5422#define CP0_CHECK(c)                            \
5423    do {                                        \
5424        if (!(c)) {                             \
5425            goto cp0_unimplemented;             \
5426        }                                       \
5427    } while (0)
5428
5429static void gen_mfhc0(DisasContext *ctx, TCGv arg, int reg, int sel)
5430{
5431    const char *register_name = "invalid";
5432
5433    switch (reg) {
5434    case CP0_REGISTER_02:
5435        switch (sel) {
5436        case 0:
5437            CP0_CHECK(ctx->hflags & MIPS_HFLAG_ELPA);
5438            gen_mfhc0_entrylo(arg, offsetof(CPUMIPSState, CP0_EntryLo0));
5439            register_name = "EntryLo0";
5440            break;
5441        default:
5442            goto cp0_unimplemented;
5443        }
5444        break;
5445    case CP0_REGISTER_03:
5446        switch (sel) {
5447        case CP0_REG03__ENTRYLO1:
5448            CP0_CHECK(ctx->hflags & MIPS_HFLAG_ELPA);
5449            gen_mfhc0_entrylo(arg, offsetof(CPUMIPSState, CP0_EntryLo1));
5450            register_name = "EntryLo1";
5451            break;
5452        default:
5453            goto cp0_unimplemented;
5454        }
5455        break;
5456    case CP0_REGISTER_09:
5457        switch (sel) {
5458        case CP0_REG09__SAAR:
5459            CP0_CHECK(ctx->saar);
5460            gen_helper_mfhc0_saar(arg, cpu_env);
5461            register_name = "SAAR";
5462            break;
5463        default:
5464            goto cp0_unimplemented;
5465        }
5466        break;
5467    case CP0_REGISTER_17:
5468        switch (sel) {
5469        case CP0_REG17__LLADDR:
5470            gen_mfhc0_load64(arg, offsetof(CPUMIPSState, CP0_LLAddr),
5471                             ctx->CP0_LLAddr_shift);
5472            register_name = "LLAddr";
5473            break;
5474        case CP0_REG17__MAAR:
5475            CP0_CHECK(ctx->mrp);
5476            gen_helper_mfhc0_maar(arg, cpu_env);
5477            register_name = "MAAR";
5478            break;
5479        default:
5480            goto cp0_unimplemented;
5481        }
5482        break;
5483    case CP0_REGISTER_19:
5484        switch (sel) {
5485        case CP0_REG19__WATCHHI0:
5486        case CP0_REG19__WATCHHI1:
5487        case CP0_REG19__WATCHHI2:
5488        case CP0_REG19__WATCHHI3:
5489        case CP0_REG19__WATCHHI4:
5490        case CP0_REG19__WATCHHI5:
5491        case CP0_REG19__WATCHHI6:
5492        case CP0_REG19__WATCHHI7:
5493            /* upper 32 bits are only available when Config5MI != 0 */
5494            CP0_CHECK(ctx->mi);
5495            gen_mfhc0_load64(arg, offsetof(CPUMIPSState, CP0_WatchHi[sel]), 0);
5496            register_name = "WatchHi";
5497            break;
5498        default:
5499            goto cp0_unimplemented;
5500        }
5501        break;
5502    case CP0_REGISTER_28:
5503        switch (sel) {
5504        case 0:
5505        case 2:
5506        case 4:
5507        case 6:
5508            gen_mfhc0_load64(arg, offsetof(CPUMIPSState, CP0_TagLo), 0);
5509            register_name = "TagLo";
5510            break;
5511        default:
5512            goto cp0_unimplemented;
5513        }
5514        break;
5515    default:
5516        goto cp0_unimplemented;
5517    }
5518    trace_mips_translate_c0("mfhc0", register_name, reg, sel);
5519    return;
5520
5521cp0_unimplemented:
5522    qemu_log_mask(LOG_UNIMP, "mfhc0 %s (reg %d sel %d)\n",
5523                  register_name, reg, sel);
5524    tcg_gen_movi_tl(arg, 0);
5525}
5526
5527static void gen_mthc0(DisasContext *ctx, TCGv arg, int reg, int sel)
5528{
5529    const char *register_name = "invalid";
5530    uint64_t mask = ctx->PAMask >> 36;
5531
5532    switch (reg) {
5533    case CP0_REGISTER_02:
5534        switch (sel) {
5535        case 0:
5536            CP0_CHECK(ctx->hflags & MIPS_HFLAG_ELPA);
5537            tcg_gen_andi_tl(arg, arg, mask);
5538            gen_mthc0_entrylo(arg, offsetof(CPUMIPSState, CP0_EntryLo0));
5539            register_name = "EntryLo0";
5540            break;
5541        default:
5542            goto cp0_unimplemented;
5543        }
5544        break;
5545    case CP0_REGISTER_03:
5546        switch (sel) {
5547        case CP0_REG03__ENTRYLO1:
5548            CP0_CHECK(ctx->hflags & MIPS_HFLAG_ELPA);
5549            tcg_gen_andi_tl(arg, arg, mask);
5550            gen_mthc0_entrylo(arg, offsetof(CPUMIPSState, CP0_EntryLo1));
5551            register_name = "EntryLo1";
5552            break;
5553        default:
5554            goto cp0_unimplemented;
5555        }
5556        break;
5557    case CP0_REGISTER_09:
5558        switch (sel) {
5559        case CP0_REG09__SAAR:
5560            CP0_CHECK(ctx->saar);
5561            gen_helper_mthc0_saar(cpu_env, arg);
5562            register_name = "SAAR";
5563            break;
5564        default:
5565            goto cp0_unimplemented;
5566        }
5567        break;
5568    case CP0_REGISTER_17:
5569        switch (sel) {
5570        case CP0_REG17__LLADDR:
5571            /*
5572             * LLAddr is read-only (the only exception is bit 0 if LLB is
5573             * supported); the CP0_LLAddr_rw_bitmask does not seem to be
5574             * relevant for modern MIPS cores supporting MTHC0, therefore
5575             * treating MTHC0 to LLAddr as NOP.
5576             */
5577            register_name = "LLAddr";
5578            break;
5579        case CP0_REG17__MAAR:
5580            CP0_CHECK(ctx->mrp);
5581            gen_helper_mthc0_maar(cpu_env, arg);
5582            register_name = "MAAR";
5583            break;
5584        default:
5585            goto cp0_unimplemented;
5586        }
5587        break;
5588    case CP0_REGISTER_19:
5589        switch (sel) {
5590        case CP0_REG19__WATCHHI0:
5591        case CP0_REG19__WATCHHI1:
5592        case CP0_REG19__WATCHHI2:
5593        case CP0_REG19__WATCHHI3:
5594        case CP0_REG19__WATCHHI4:
5595        case CP0_REG19__WATCHHI5:
5596        case CP0_REG19__WATCHHI6:
5597        case CP0_REG19__WATCHHI7:
5598            /* upper 32 bits are only available when Config5MI != 0 */
5599            CP0_CHECK(ctx->mi);
5600            gen_helper_0e1i(mthc0_watchhi, arg, sel);
5601            register_name = "WatchHi";
5602            break;
5603        default:
5604            goto cp0_unimplemented;
5605        }
5606        break;
5607    case CP0_REGISTER_28:
5608        switch (sel) {
5609        case 0:
5610        case 2:
5611        case 4:
5612        case 6:
5613            tcg_gen_andi_tl(arg, arg, mask);
5614            gen_mthc0_store64(arg, offsetof(CPUMIPSState, CP0_TagLo));
5615            register_name = "TagLo";
5616            break;
5617        default:
5618            goto cp0_unimplemented;
5619        }
5620        break;
5621    default:
5622        goto cp0_unimplemented;
5623    }
5624    trace_mips_translate_c0("mthc0", register_name, reg, sel);
5625    return;
5626
5627cp0_unimplemented:
5628    qemu_log_mask(LOG_UNIMP, "mthc0 %s (reg %d sel %d)\n",
5629                  register_name, reg, sel);
5630}
5631
5632static inline void gen_mfc0_unimplemented(DisasContext *ctx, TCGv arg)
5633{
5634    if (ctx->insn_flags & ISA_MIPS_R6) {
5635        tcg_gen_movi_tl(arg, 0);
5636    } else {
5637        tcg_gen_movi_tl(arg, ~0);
5638    }
5639}
5640
5641static void gen_mfc0(DisasContext *ctx, TCGv arg, int reg, int sel)
5642{
5643    const char *register_name = "invalid";
5644
5645    if (sel != 0) {
5646        check_insn(ctx, ISA_MIPS_R1);
5647    }
5648
5649    switch (reg) {
5650    case CP0_REGISTER_00:
5651        switch (sel) {
5652        case CP0_REG00__INDEX:
5653            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Index));
5654            register_name = "Index";
5655            break;
5656        case CP0_REG00__MVPCONTROL:
5657            CP0_CHECK(ctx->insn_flags & ASE_MT);
5658            gen_helper_mfc0_mvpcontrol(arg, cpu_env);
5659            register_name = "MVPControl";
5660            break;
5661        case CP0_REG00__MVPCONF0:
5662            CP0_CHECK(ctx->insn_flags & ASE_MT);
5663            gen_helper_mfc0_mvpconf0(arg, cpu_env);
5664            register_name = "MVPConf0";
5665            break;
5666        case CP0_REG00__MVPCONF1:
5667            CP0_CHECK(ctx->insn_flags & ASE_MT);
5668            gen_helper_mfc0_mvpconf1(arg, cpu_env);
5669            register_name = "MVPConf1";
5670            break;
5671        case CP0_REG00__VPCONTROL:
5672            CP0_CHECK(ctx->vp);
5673            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPControl));
5674            register_name = "VPControl";
5675            break;
5676        default:
5677            goto cp0_unimplemented;
5678        }
5679        break;
5680    case CP0_REGISTER_01:
5681        switch (sel) {
5682        case CP0_REG01__RANDOM:
5683            CP0_CHECK(!(ctx->insn_flags & ISA_MIPS_R6));
5684            gen_helper_mfc0_random(arg, cpu_env);
5685            register_name = "Random";
5686            break;
5687        case CP0_REG01__VPECONTROL:
5688            CP0_CHECK(ctx->insn_flags & ASE_MT);
5689            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEControl));
5690            register_name = "VPEControl";
5691            break;
5692        case CP0_REG01__VPECONF0:
5693            CP0_CHECK(ctx->insn_flags & ASE_MT);
5694            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf0));
5695            register_name = "VPEConf0";
5696            break;
5697        case CP0_REG01__VPECONF1:
5698            CP0_CHECK(ctx->insn_flags & ASE_MT);
5699            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf1));
5700            register_name = "VPEConf1";
5701            break;
5702        case CP0_REG01__YQMASK:
5703            CP0_CHECK(ctx->insn_flags & ASE_MT);
5704            gen_mfc0_load64(arg, offsetof(CPUMIPSState, CP0_YQMask));
5705            register_name = "YQMask";
5706            break;
5707        case CP0_REG01__VPESCHEDULE:
5708            CP0_CHECK(ctx->insn_flags & ASE_MT);
5709            gen_mfc0_load64(arg, offsetof(CPUMIPSState, CP0_VPESchedule));
5710            register_name = "VPESchedule";
5711            break;
5712        case CP0_REG01__VPESCHEFBACK:
5713            CP0_CHECK(ctx->insn_flags & ASE_MT);
5714            gen_mfc0_load64(arg, offsetof(CPUMIPSState, CP0_VPEScheFBack));
5715            register_name = "VPEScheFBack";
5716            break;
5717        case CP0_REG01__VPEOPT:
5718            CP0_CHECK(ctx->insn_flags & ASE_MT);
5719            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEOpt));
5720            register_name = "VPEOpt";
5721            break;
5722        default:
5723            goto cp0_unimplemented;
5724        }
5725        break;
5726    case CP0_REGISTER_02:
5727        switch (sel) {
5728        case CP0_REG02__ENTRYLO0:
5729            {
5730                TCGv_i64 tmp = tcg_temp_new_i64();
5731                tcg_gen_ld_i64(tmp, cpu_env,
5732                               offsetof(CPUMIPSState, CP0_EntryLo0));
5733#if defined(TARGET_MIPS64)
5734                if (ctx->rxi) {
5735                    /* Move RI/XI fields to bits 31:30 */
5736                    tcg_gen_shri_tl(arg, tmp, CP0EnLo_XI);
5737                    tcg_gen_deposit_tl(tmp, tmp, arg, 30, 2);
5738                }
5739#endif
5740                gen_move_low32(arg, tmp);
5741                tcg_temp_free_i64(tmp);
5742            }
5743            register_name = "EntryLo0";
5744            break;
5745        case CP0_REG02__TCSTATUS:
5746            CP0_CHECK(ctx->insn_flags & ASE_MT);
5747            gen_helper_mfc0_tcstatus(arg, cpu_env);
5748            register_name = "TCStatus";
5749            break;
5750        case CP0_REG02__TCBIND:
5751            CP0_CHECK(ctx->insn_flags & ASE_MT);
5752            gen_helper_mfc0_tcbind(arg, cpu_env);
5753            register_name = "TCBind";
5754            break;
5755        case CP0_REG02__TCRESTART:
5756            CP0_CHECK(ctx->insn_flags & ASE_MT);
5757            gen_helper_mfc0_tcrestart(arg, cpu_env);
5758            register_name = "TCRestart";
5759            break;
5760        case CP0_REG02__TCHALT:
5761            CP0_CHECK(ctx->insn_flags & ASE_MT);
5762            gen_helper_mfc0_tchalt(arg, cpu_env);
5763            register_name = "TCHalt";
5764            break;
5765        case CP0_REG02__TCCONTEXT:
5766            CP0_CHECK(ctx->insn_flags & ASE_MT);
5767            gen_helper_mfc0_tccontext(arg, cpu_env);
5768            register_name = "TCContext";
5769            break;
5770        case CP0_REG02__TCSCHEDULE:
5771            CP0_CHECK(ctx->insn_flags & ASE_MT);
5772            gen_helper_mfc0_tcschedule(arg, cpu_env);
5773            register_name = "TCSchedule";
5774            break;
5775        case CP0_REG02__TCSCHEFBACK:
5776            CP0_CHECK(ctx->insn_flags & ASE_MT);
5777            gen_helper_mfc0_tcschefback(arg, cpu_env);
5778            register_name = "TCScheFBack";
5779            break;
5780        default:
5781            goto cp0_unimplemented;
5782        }
5783        break;
5784    case CP0_REGISTER_03:
5785        switch (sel) {
5786        case CP0_REG03__ENTRYLO1:
5787            {
5788                TCGv_i64 tmp = tcg_temp_new_i64();
5789                tcg_gen_ld_i64(tmp, cpu_env,
5790                               offsetof(CPUMIPSState, CP0_EntryLo1));
5791#if defined(TARGET_MIPS64)
5792                if (ctx->rxi) {
5793                    /* Move RI/XI fields to bits 31:30 */
5794                    tcg_gen_shri_tl(arg, tmp, CP0EnLo_XI);
5795                    tcg_gen_deposit_tl(tmp, tmp, arg, 30, 2);
5796                }
5797#endif
5798                gen_move_low32(arg, tmp);
5799                tcg_temp_free_i64(tmp);
5800            }
5801            register_name = "EntryLo1";
5802            break;
5803        case CP0_REG03__GLOBALNUM:
5804            CP0_CHECK(ctx->vp);
5805            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_GlobalNumber));
5806            register_name = "GlobalNumber";
5807            break;
5808        default:
5809            goto cp0_unimplemented;
5810        }
5811        break;
5812    case CP0_REGISTER_04:
5813        switch (sel) {
5814        case CP0_REG04__CONTEXT:
5815            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_Context));
5816            tcg_gen_ext32s_tl(arg, arg);
5817            register_name = "Context";
5818            break;
5819        case CP0_REG04__CONTEXTCONFIG:
5820            /* SmartMIPS ASE */
5821            /* gen_helper_mfc0_contextconfig(arg); */
5822            register_name = "ContextConfig";
5823            goto cp0_unimplemented;
5824        case CP0_REG04__USERLOCAL:
5825            CP0_CHECK(ctx->ulri);
5826            tcg_gen_ld_tl(arg, cpu_env,
5827                          offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
5828            tcg_gen_ext32s_tl(arg, arg);
5829            register_name = "UserLocal";
5830            break;
5831        case CP0_REG04__MMID:
5832            CP0_CHECK(ctx->mi);
5833            gen_helper_mtc0_memorymapid(cpu_env, arg);
5834            register_name = "MMID";
5835            break;
5836        default:
5837            goto cp0_unimplemented;
5838        }
5839        break;
5840    case CP0_REGISTER_05:
5841        switch (sel) {
5842        case CP0_REG05__PAGEMASK:
5843            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageMask));
5844            register_name = "PageMask";
5845            break;
5846        case CP0_REG05__PAGEGRAIN:
5847            check_insn(ctx, ISA_MIPS_R2);
5848            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageGrain));
5849            register_name = "PageGrain";
5850            break;
5851        case CP0_REG05__SEGCTL0:
5852            CP0_CHECK(ctx->sc);
5853            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_SegCtl0));
5854            tcg_gen_ext32s_tl(arg, arg);
5855            register_name = "SegCtl0";
5856            break;
5857        case CP0_REG05__SEGCTL1:
5858            CP0_CHECK(ctx->sc);
5859            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_SegCtl1));
5860            tcg_gen_ext32s_tl(arg, arg);
5861            register_name = "SegCtl1";
5862            break;
5863        case CP0_REG05__SEGCTL2:
5864            CP0_CHECK(ctx->sc);
5865            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_SegCtl2));
5866            tcg_gen_ext32s_tl(arg, arg);
5867            register_name = "SegCtl2";
5868            break;
5869        case CP0_REG05__PWBASE:
5870            check_pw(ctx);
5871            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PWBase));
5872            register_name = "PWBase";
5873            break;
5874        case CP0_REG05__PWFIELD:
5875            check_pw(ctx);
5876            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PWField));
5877            register_name = "PWField";
5878            break;
5879        case CP0_REG05__PWSIZE:
5880            check_pw(ctx);
5881            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PWSize));
5882            register_name = "PWSize";
5883            break;
5884        default:
5885            goto cp0_unimplemented;
5886        }
5887        break;
5888    case CP0_REGISTER_06:
5889        switch (sel) {
5890        case CP0_REG06__WIRED:
5891            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Wired));
5892            register_name = "Wired";
5893            break;
5894        case CP0_REG06__SRSCONF0:
5895            check_insn(ctx, ISA_MIPS_R2);
5896            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf0));
5897            register_name = "SRSConf0";
5898            break;
5899        case CP0_REG06__SRSCONF1:
5900            check_insn(ctx, ISA_MIPS_R2);
5901            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf1));
5902            register_name = "SRSConf1";
5903            break;
5904        case CP0_REG06__SRSCONF2:
5905            check_insn(ctx, ISA_MIPS_R2);
5906            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf2));
5907            register_name = "SRSConf2";
5908            break;
5909        case CP0_REG06__SRSCONF3:
5910            check_insn(ctx, ISA_MIPS_R2);
5911            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf3));
5912            register_name = "SRSConf3";
5913            break;
5914        case CP0_REG06__SRSCONF4:
5915            check_insn(ctx, ISA_MIPS_R2);
5916            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf4));
5917            register_name = "SRSConf4";
5918            break;
5919        case CP0_REG06__PWCTL:
5920            check_pw(ctx);
5921            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PWCtl));
5922            register_name = "PWCtl";
5923            break;
5924        default:
5925            goto cp0_unimplemented;
5926        }
5927        break;
5928    case CP0_REGISTER_07:
5929        switch (sel) {
5930        case CP0_REG07__HWRENA:
5931            check_insn(ctx, ISA_MIPS_R2);
5932            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_HWREna));
5933            register_name = "HWREna";
5934            break;
5935        default:
5936            goto cp0_unimplemented;
5937        }
5938        break;
5939    case CP0_REGISTER_08:
5940        switch (sel) {
5941        case CP0_REG08__BADVADDR:
5942            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_BadVAddr));
5943            tcg_gen_ext32s_tl(arg, arg);
5944            register_name = "BadVAddr";
5945            break;
5946        case CP0_REG08__BADINSTR:
5947            CP0_CHECK(ctx->bi);
5948            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_BadInstr));
5949            register_name = "BadInstr";
5950            break;
5951        case CP0_REG08__BADINSTRP:
5952            CP0_CHECK(ctx->bp);
5953            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_BadInstrP));
5954            register_name = "BadInstrP";
5955            break;
5956        case CP0_REG08__BADINSTRX:
5957            CP0_CHECK(ctx->bi);
5958            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_BadInstrX));
5959            tcg_gen_andi_tl(arg, arg, ~0xffff);
5960            register_name = "BadInstrX";
5961            break;
5962        default:
5963            goto cp0_unimplemented;
5964        }
5965        break;
5966    case CP0_REGISTER_09:
5967        switch (sel) {
5968        case CP0_REG09__COUNT:
5969            /* Mark as an IO operation because we read the time.  */
5970            if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
5971                gen_io_start();
5972            }
5973            gen_helper_mfc0_count(arg, cpu_env);
5974            /*
5975             * Break the TB to be able to take timer interrupts immediately
5976             * after reading count. DISAS_STOP isn't sufficient, we need to
5977             * ensure we break completely out of translated code.
5978             */
5979            gen_save_pc(ctx->base.pc_next + 4);
5980            ctx->base.is_jmp = DISAS_EXIT;
5981            register_name = "Count";
5982            break;
5983        case CP0_REG09__SAARI:
5984            CP0_CHECK(ctx->saar);
5985            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SAARI));
5986            register_name = "SAARI";
5987            break;
5988        case CP0_REG09__SAAR:
5989            CP0_CHECK(ctx->saar);
5990            gen_helper_mfc0_saar(arg, cpu_env);
5991            register_name = "SAAR";
5992            break;
5993        default:
5994            goto cp0_unimplemented;
5995        }
5996        break;
5997    case CP0_REGISTER_10:
5998        switch (sel) {
5999        case CP0_REG10__ENTRYHI:
6000            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryHi));
6001            tcg_gen_ext32s_tl(arg, arg);
6002            register_name = "EntryHi";
6003            break;
6004        default:
6005            goto cp0_unimplemented;
6006        }
6007        break;
6008    case CP0_REGISTER_11:
6009        switch (sel) {
6010        case CP0_REG11__COMPARE:
6011            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Compare));
6012            register_name = "Compare";
6013            break;
6014        /* 6,7 are implementation dependent */
6015        default:
6016            goto cp0_unimplemented;
6017        }
6018        break;
6019    case CP0_REGISTER_12:
6020        switch (sel) {
6021        case CP0_REG12__STATUS:
6022            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Status));
6023            register_name = "Status";
6024            break;
6025        case CP0_REG12__INTCTL:
6026            check_insn(ctx, ISA_MIPS_R2);
6027            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_IntCtl));
6028            register_name = "IntCtl";
6029            break;
6030        case CP0_REG12__SRSCTL:
6031            check_insn(ctx, ISA_MIPS_R2);
6032            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSCtl));
6033            register_name = "SRSCtl";
6034            break;
6035        case CP0_REG12__SRSMAP:
6036            check_insn(ctx, ISA_MIPS_R2);
6037            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSMap));
6038            register_name = "SRSMap";
6039            break;
6040        default:
6041            goto cp0_unimplemented;
6042       }
6043        break;
6044    case CP0_REGISTER_13:
6045        switch (sel) {
6046        case CP0_REG13__CAUSE:
6047            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Cause));
6048            register_name = "Cause";
6049            break;
6050        default:
6051            goto cp0_unimplemented;
6052       }
6053        break;
6054    case CP0_REGISTER_14:
6055        switch (sel) {
6056        case CP0_REG14__EPC:
6057            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EPC));
6058            tcg_gen_ext32s_tl(arg, arg);
6059            register_name = "EPC";
6060            break;
6061        default:
6062            goto cp0_unimplemented;
6063        }
6064        break;
6065    case CP0_REGISTER_15:
6066        switch (sel) {
6067        case CP0_REG15__PRID:
6068            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PRid));
6069            register_name = "PRid";
6070            break;
6071        case CP0_REG15__EBASE:
6072            check_insn(ctx, ISA_MIPS_R2);
6073            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EBase));
6074            tcg_gen_ext32s_tl(arg, arg);
6075            register_name = "EBase";
6076            break;
6077        case CP0_REG15__CMGCRBASE:
6078            check_insn(ctx, ISA_MIPS_R2);
6079            CP0_CHECK(ctx->cmgcr);
6080            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_CMGCRBase));
6081            tcg_gen_ext32s_tl(arg, arg);
6082            register_name = "CMGCRBase";
6083            break;
6084        default:
6085            goto cp0_unimplemented;
6086       }
6087        break;
6088    case CP0_REGISTER_16:
6089        switch (sel) {
6090        case CP0_REG16__CONFIG:
6091            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config0));
6092            register_name = "Config";
6093            break;
6094        case CP0_REG16__CONFIG1:
6095            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config1));
6096            register_name = "Config1";
6097            break;
6098        case CP0_REG16__CONFIG2:
6099            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config2));
6100            register_name = "Config2";
6101            break;
6102        case CP0_REG16__CONFIG3:
6103            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config3));
6104            register_name = "Config3";
6105            break;
6106        case CP0_REG16__CONFIG4:
6107            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config4));
6108            register_name = "Config4";
6109            break;
6110        case CP0_REG16__CONFIG5:
6111            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config5));
6112            register_name = "Config5";
6113            break;
6114        /* 6,7 are implementation dependent */
6115        case CP0_REG16__CONFIG6:
6116            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config6));
6117            register_name = "Config6";
6118            break;
6119        case CP0_REG16__CONFIG7:
6120            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config7));
6121            register_name = "Config7";
6122            break;
6123        default:
6124            goto cp0_unimplemented;
6125        }
6126        break;
6127    case CP0_REGISTER_17:
6128        switch (sel) {
6129        case CP0_REG17__LLADDR:
6130            gen_helper_mfc0_lladdr(arg, cpu_env);
6131            register_name = "LLAddr";
6132            break;
6133        case CP0_REG17__MAAR:
6134            CP0_CHECK(ctx->mrp);
6135            gen_helper_mfc0_maar(arg, cpu_env);
6136            register_name = "MAAR";
6137            break;
6138        case CP0_REG17__MAARI:
6139            CP0_CHECK(ctx->mrp);
6140            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_MAARI));
6141            register_name = "MAARI";
6142            break;
6143        default:
6144            goto cp0_unimplemented;
6145        }
6146        break;
6147    case CP0_REGISTER_18:
6148        switch (sel) {
6149        case CP0_REG18__WATCHLO0:
6150        case CP0_REG18__WATCHLO1:
6151        case CP0_REG18__WATCHLO2:
6152        case CP0_REG18__WATCHLO3:
6153        case CP0_REG18__WATCHLO4:
6154        case CP0_REG18__WATCHLO5:
6155        case CP0_REG18__WATCHLO6:
6156        case CP0_REG18__WATCHLO7:
6157            CP0_CHECK(ctx->CP0_Config1 & (1 << CP0C1_WR));
6158            gen_helper_1e0i(mfc0_watchlo, arg, sel);
6159            register_name = "WatchLo";
6160            break;
6161        default:
6162            goto cp0_unimplemented;
6163        }
6164        break;
6165    case CP0_REGISTER_19:
6166        switch (sel) {
6167        case CP0_REG19__WATCHHI0:
6168        case CP0_REG19__WATCHHI1:
6169        case CP0_REG19__WATCHHI2:
6170        case CP0_REG19__WATCHHI3:
6171        case CP0_REG19__WATCHHI4:
6172        case CP0_REG19__WATCHHI5:
6173        case CP0_REG19__WATCHHI6:
6174        case CP0_REG19__WATCHHI7:
6175            CP0_CHECK(ctx->CP0_Config1 & (1 << CP0C1_WR));
6176            gen_helper_1e0i(mfc0_watchhi, arg, sel);
6177            register_name = "WatchHi";
6178            break;
6179        default:
6180            goto cp0_unimplemented;
6181        }
6182        break;
6183    case CP0_REGISTER_20:
6184        switch (sel) {
6185        case CP0_REG20__XCONTEXT:
6186#if defined(TARGET_MIPS64)
6187            check_insn(ctx, ISA_MIPS3);
6188            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_XContext));
6189            tcg_gen_ext32s_tl(arg, arg);
6190            register_name = "XContext";
6191            break;
6192#endif
6193        default:
6194            goto cp0_unimplemented;
6195        }
6196        break;
6197    case CP0_REGISTER_21:
6198       /* Officially reserved, but sel 0 is used for R1x000 framemask */
6199        CP0_CHECK(!(ctx->insn_flags & ISA_MIPS_R6));
6200        switch (sel) {
6201        case 0:
6202            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Framemask));
6203            register_name = "Framemask";
6204            break;
6205        default:
6206            goto cp0_unimplemented;
6207        }
6208        break;
6209    case CP0_REGISTER_22:
6210        tcg_gen_movi_tl(arg, 0); /* unimplemented */
6211        register_name = "'Diagnostic"; /* implementation dependent */
6212        break;
6213    case CP0_REGISTER_23:
6214        switch (sel) {
6215        case CP0_REG23__DEBUG:
6216            gen_helper_mfc0_debug(arg, cpu_env); /* EJTAG support */
6217            register_name = "Debug";
6218            break;
6219        case CP0_REG23__TRACECONTROL:
6220            /* PDtrace support */
6221            /* gen_helper_mfc0_tracecontrol(arg);  */
6222            register_name = "TraceControl";
6223            goto cp0_unimplemented;
6224        case CP0_REG23__TRACECONTROL2:
6225            /* PDtrace support */
6226            /* gen_helper_mfc0_tracecontrol2(arg); */
6227            register_name = "TraceControl2";
6228            goto cp0_unimplemented;
6229        case CP0_REG23__USERTRACEDATA1:
6230            /* PDtrace support */
6231            /* gen_helper_mfc0_usertracedata1(arg);*/
6232            register_name = "UserTraceData1";
6233            goto cp0_unimplemented;
6234        case CP0_REG23__TRACEIBPC:
6235            /* PDtrace support */
6236            /* gen_helper_mfc0_traceibpc(arg);     */
6237            register_name = "TraceIBPC";
6238            goto cp0_unimplemented;
6239        case CP0_REG23__TRACEDBPC:
6240            /* PDtrace support */
6241            /* gen_helper_mfc0_tracedbpc(arg);     */
6242            register_name = "TraceDBPC";
6243            goto cp0_unimplemented;
6244        default:
6245            goto cp0_unimplemented;
6246        }
6247        break;
6248    case CP0_REGISTER_24:
6249        switch (sel) {
6250        case CP0_REG24__DEPC:
6251            /* EJTAG support */
6252            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_DEPC));
6253            tcg_gen_ext32s_tl(arg, arg);
6254            register_name = "DEPC";
6255            break;
6256        default:
6257            goto cp0_unimplemented;
6258        }
6259        break;
6260    case CP0_REGISTER_25:
6261        switch (sel) {
6262        case CP0_REG25__PERFCTL0:
6263            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Performance0));
6264            register_name = "Performance0";
6265            break;
6266        case CP0_REG25__PERFCNT0:
6267            /* gen_helper_mfc0_performance1(arg); */
6268            register_name = "Performance1";
6269            goto cp0_unimplemented;
6270        case CP0_REG25__PERFCTL1:
6271            /* gen_helper_mfc0_performance2(arg); */
6272            register_name = "Performance2";
6273            goto cp0_unimplemented;
6274        case CP0_REG25__PERFCNT1:
6275            /* gen_helper_mfc0_performance3(arg); */
6276            register_name = "Performance3";
6277            goto cp0_unimplemented;
6278        case CP0_REG25__PERFCTL2:
6279            /* gen_helper_mfc0_performance4(arg); */
6280            register_name = "Performance4";
6281            goto cp0_unimplemented;
6282        case CP0_REG25__PERFCNT2:
6283            /* gen_helper_mfc0_performance5(arg); */
6284            register_name = "Performance5";
6285            goto cp0_unimplemented;
6286        case CP0_REG25__PERFCTL3:
6287            /* gen_helper_mfc0_performance6(arg); */
6288            register_name = "Performance6";
6289            goto cp0_unimplemented;
6290        case CP0_REG25__PERFCNT3:
6291            /* gen_helper_mfc0_performance7(arg); */
6292            register_name = "Performance7";
6293            goto cp0_unimplemented;
6294        default:
6295            goto cp0_unimplemented;
6296        }
6297        break;
6298    case CP0_REGISTER_26:
6299        switch (sel) {
6300        case CP0_REG26__ERRCTL:
6301            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_ErrCtl));
6302            register_name = "ErrCtl";
6303            break;
6304        default:
6305            goto cp0_unimplemented;
6306        }
6307        break;
6308    case CP0_REGISTER_27:
6309        switch (sel) {
6310        case CP0_REG27__CACHERR:
6311            tcg_gen_movi_tl(arg, 0); /* unimplemented */
6312            register_name = "CacheErr";
6313            break;
6314        default:
6315            goto cp0_unimplemented;
6316        }
6317        break;
6318    case CP0_REGISTER_28:
6319        switch (sel) {
6320        case CP0_REG28__TAGLO:
6321        case CP0_REG28__TAGLO1:
6322        case CP0_REG28__TAGLO2:
6323        case CP0_REG28__TAGLO3:
6324            {
6325                TCGv_i64 tmp = tcg_temp_new_i64();
6326                tcg_gen_ld_i64(tmp, cpu_env, offsetof(CPUMIPSState, CP0_TagLo));
6327                gen_move_low32(arg, tmp);
6328                tcg_temp_free_i64(tmp);
6329            }
6330            register_name = "TagLo";
6331            break;
6332        case CP0_REG28__DATALO:
6333        case CP0_REG28__DATALO1:
6334        case CP0_REG28__DATALO2:
6335        case CP0_REG28__DATALO3:
6336            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataLo));
6337            register_name = "DataLo";
6338            break;
6339        default:
6340            goto cp0_unimplemented;
6341        }
6342        break;
6343    case CP0_REGISTER_29:
6344        switch (sel) {
6345        case CP0_REG29__TAGHI:
6346        case CP0_REG29__TAGHI1:
6347        case CP0_REG29__TAGHI2:
6348        case CP0_REG29__TAGHI3:
6349            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_TagHi));
6350            register_name = "TagHi";
6351            break;
6352        case CP0_REG29__DATAHI:
6353        case CP0_REG29__DATAHI1:
6354        case CP0_REG29__DATAHI2:
6355        case CP0_REG29__DATAHI3:
6356            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataHi));
6357            register_name = "DataHi";
6358            break;
6359        default:
6360            goto cp0_unimplemented;
6361        }
6362        break;
6363    case CP0_REGISTER_30:
6364        switch (sel) {
6365        case CP0_REG30__ERROREPC:
6366            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_ErrorEPC));
6367            tcg_gen_ext32s_tl(arg, arg);
6368            register_name = "ErrorEPC";
6369            break;
6370        default:
6371            goto cp0_unimplemented;
6372        }
6373        break;
6374    case CP0_REGISTER_31:
6375        switch (sel) {
6376        case CP0_REG31__DESAVE:
6377            /* EJTAG support */
6378            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DESAVE));
6379            register_name = "DESAVE";
6380            break;
6381        case CP0_REG31__KSCRATCH1:
6382        case CP0_REG31__KSCRATCH2:
6383        case CP0_REG31__KSCRATCH3:
6384        case CP0_REG31__KSCRATCH4:
6385        case CP0_REG31__KSCRATCH5:
6386        case CP0_REG31__KSCRATCH6:
6387            CP0_CHECK(ctx->kscrexist & (1 << sel));
6388            tcg_gen_ld_tl(arg, cpu_env,
6389                          offsetof(CPUMIPSState, CP0_KScratch[sel - 2]));
6390            tcg_gen_ext32s_tl(arg, arg);
6391            register_name = "KScratch";
6392            break;
6393        default:
6394            goto cp0_unimplemented;
6395        }
6396        break;
6397    default:
6398       goto cp0_unimplemented;
6399    }
6400    trace_mips_translate_c0("mfc0", register_name, reg, sel);
6401    return;
6402
6403cp0_unimplemented:
6404    qemu_log_mask(LOG_UNIMP, "mfc0 %s (reg %d sel %d)\n",
6405                  register_name, reg, sel);
6406    gen_mfc0_unimplemented(ctx, arg);
6407}
6408
6409static void gen_mtc0(DisasContext *ctx, TCGv arg, int reg, int sel)
6410{
6411    const char *register_name = "invalid";
6412
6413    if (sel != 0) {
6414        check_insn(ctx, ISA_MIPS_R1);
6415    }
6416
6417    if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
6418        gen_io_start();
6419    }
6420
6421    switch (reg) {
6422    case CP0_REGISTER_00:
6423        switch (sel) {
6424        case CP0_REG00__INDEX:
6425            gen_helper_mtc0_index(cpu_env, arg);
6426            register_name = "Index";
6427            break;
6428        case CP0_REG00__MVPCONTROL:
6429            CP0_CHECK(ctx->insn_flags & ASE_MT);
6430            gen_helper_mtc0_mvpcontrol(cpu_env, arg);
6431            register_name = "MVPControl";
6432            break;
6433        case CP0_REG00__MVPCONF0:
6434            CP0_CHECK(ctx->insn_flags & ASE_MT);
6435            /* ignored */
6436            register_name = "MVPConf0";
6437            break;
6438        case CP0_REG00__MVPCONF1:
6439            CP0_CHECK(ctx->insn_flags & ASE_MT);
6440            /* ignored */
6441            register_name = "MVPConf1";
6442            break;
6443        case CP0_REG00__VPCONTROL:
6444            CP0_CHECK(ctx->vp);
6445            /* ignored */
6446            register_name = "VPControl";
6447            break;
6448        default:
6449            goto cp0_unimplemented;
6450        }
6451        break;
6452    case CP0_REGISTER_01:
6453        switch (sel) {
6454        case CP0_REG01__RANDOM:
6455            /* ignored */
6456            register_name = "Random";
6457            break;
6458        case CP0_REG01__VPECONTROL:
6459            CP0_CHECK(ctx->insn_flags & ASE_MT);
6460            gen_helper_mtc0_vpecontrol(cpu_env, arg);
6461            register_name = "VPEControl";
6462            break;
6463        case CP0_REG01__VPECONF0:
6464            CP0_CHECK(ctx->insn_flags & ASE_MT);
6465            gen_helper_mtc0_vpeconf0(cpu_env, arg);
6466            register_name = "VPEConf0";
6467            break;
6468        case CP0_REG01__VPECONF1:
6469            CP0_CHECK(ctx->insn_flags & ASE_MT);
6470            gen_helper_mtc0_vpeconf1(cpu_env, arg);
6471            register_name = "VPEConf1";
6472            break;
6473        case CP0_REG01__YQMASK:
6474            CP0_CHECK(ctx->insn_flags & ASE_MT);
6475            gen_helper_mtc0_yqmask(cpu_env, arg);
6476            register_name = "YQMask";
6477            break;
6478        case CP0_REG01__VPESCHEDULE:
6479            CP0_CHECK(ctx->insn_flags & ASE_MT);
6480            tcg_gen_st_tl(arg, cpu_env,
6481                          offsetof(CPUMIPSState, CP0_VPESchedule));
6482            register_name = "VPESchedule";
6483            break;
6484        case CP0_REG01__VPESCHEFBACK:
6485            CP0_CHECK(ctx->insn_flags & ASE_MT);
6486            tcg_gen_st_tl(arg, cpu_env,
6487                          offsetof(CPUMIPSState, CP0_VPEScheFBack));
6488            register_name = "VPEScheFBack";
6489            break;
6490        case CP0_REG01__VPEOPT:
6491            CP0_CHECK(ctx->insn_flags & ASE_MT);
6492            gen_helper_mtc0_vpeopt(cpu_env, arg);
6493            register_name = "VPEOpt";
6494            break;
6495        default:
6496            goto cp0_unimplemented;
6497        }
6498        break;
6499    case CP0_REGISTER_02:
6500        switch (sel) {
6501        case CP0_REG02__ENTRYLO0:
6502            gen_helper_mtc0_entrylo0(cpu_env, arg);
6503            register_name = "EntryLo0";
6504            break;
6505        case CP0_REG02__TCSTATUS:
6506            CP0_CHECK(ctx->insn_flags & ASE_MT);
6507            gen_helper_mtc0_tcstatus(cpu_env, arg);
6508            register_name = "TCStatus";
6509            break;
6510        case CP0_REG02__TCBIND:
6511            CP0_CHECK(ctx->insn_flags & ASE_MT);
6512            gen_helper_mtc0_tcbind(cpu_env, arg);
6513            register_name = "TCBind";
6514            break;
6515        case CP0_REG02__TCRESTART:
6516            CP0_CHECK(ctx->insn_flags & ASE_MT);
6517            gen_helper_mtc0_tcrestart(cpu_env, arg);
6518            register_name = "TCRestart";
6519            break;
6520        case CP0_REG02__TCHALT:
6521            CP0_CHECK(ctx->insn_flags & ASE_MT);
6522            gen_helper_mtc0_tchalt(cpu_env, arg);
6523            register_name = "TCHalt";
6524            break;
6525        case CP0_REG02__TCCONTEXT:
6526            CP0_CHECK(ctx->insn_flags & ASE_MT);
6527            gen_helper_mtc0_tccontext(cpu_env, arg);
6528            register_name = "TCContext";
6529            break;
6530        case CP0_REG02__TCSCHEDULE:
6531            CP0_CHECK(ctx->insn_flags & ASE_MT);
6532            gen_helper_mtc0_tcschedule(cpu_env, arg);
6533            register_name = "TCSchedule";
6534            break;
6535        case CP0_REG02__TCSCHEFBACK:
6536            CP0_CHECK(ctx->insn_flags & ASE_MT);
6537            gen_helper_mtc0_tcschefback(cpu_env, arg);
6538            register_name = "TCScheFBack";
6539            break;
6540        default:
6541            goto cp0_unimplemented;
6542        }
6543        break;
6544    case CP0_REGISTER_03:
6545        switch (sel) {
6546        case CP0_REG03__ENTRYLO1:
6547            gen_helper_mtc0_entrylo1(cpu_env, arg);
6548            register_name = "EntryLo1";
6549            break;
6550        case CP0_REG03__GLOBALNUM:
6551            CP0_CHECK(ctx->vp);
6552            /* ignored */
6553            register_name = "GlobalNumber";
6554            break;
6555        default:
6556            goto cp0_unimplemented;
6557        }
6558        break;
6559    case CP0_REGISTER_04:
6560        switch (sel) {
6561        case CP0_REG04__CONTEXT:
6562            gen_helper_mtc0_context(cpu_env, arg);
6563            register_name = "Context";
6564            break;
6565        case CP0_REG04__CONTEXTCONFIG:
6566            /* SmartMIPS ASE */
6567            /* gen_helper_mtc0_contextconfig(arg); */
6568            register_name = "ContextConfig";
6569            goto cp0_unimplemented;
6570        case CP0_REG04__USERLOCAL:
6571            CP0_CHECK(ctx->ulri);
6572            tcg_gen_st_tl(arg, cpu_env,
6573                          offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
6574            register_name = "UserLocal";
6575            break;
6576        case CP0_REG04__MMID:
6577            CP0_CHECK(ctx->mi);
6578            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_MemoryMapID));
6579            register_name = "MMID";
6580            break;
6581        default:
6582            goto cp0_unimplemented;
6583        }
6584        break;
6585    case CP0_REGISTER_05:
6586        switch (sel) {
6587        case CP0_REG05__PAGEMASK:
6588            gen_helper_mtc0_pagemask(cpu_env, arg);
6589            register_name = "PageMask";
6590            break;
6591        case CP0_REG05__PAGEGRAIN:
6592            check_insn(ctx, ISA_MIPS_R2);
6593            gen_helper_mtc0_pagegrain(cpu_env, arg);
6594            register_name = "PageGrain";
6595            ctx->base.is_jmp = DISAS_STOP;
6596            break;
6597        case CP0_REG05__SEGCTL0:
6598            CP0_CHECK(ctx->sc);
6599            gen_helper_mtc0_segctl0(cpu_env, arg);
6600            register_name = "SegCtl0";
6601            break;
6602        case CP0_REG05__SEGCTL1:
6603            CP0_CHECK(ctx->sc);
6604            gen_helper_mtc0_segctl1(cpu_env, arg);
6605            register_name = "SegCtl1";
6606            break;
6607        case CP0_REG05__SEGCTL2:
6608            CP0_CHECK(ctx->sc);
6609            gen_helper_mtc0_segctl2(cpu_env, arg);
6610            register_name = "SegCtl2";
6611            break;
6612        case CP0_REG05__PWBASE:
6613            check_pw(ctx);
6614            gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_PWBase));
6615            register_name = "PWBase";
6616            break;
6617        case CP0_REG05__PWFIELD:
6618            check_pw(ctx);
6619            gen_helper_mtc0_pwfield(cpu_env, arg);
6620            register_name = "PWField";
6621            break;
6622        case CP0_REG05__PWSIZE:
6623            check_pw(ctx);
6624            gen_helper_mtc0_pwsize(cpu_env, arg);
6625            register_name = "PWSize";
6626            break;
6627        default:
6628            goto cp0_unimplemented;
6629        }
6630        break;
6631    case CP0_REGISTER_06:
6632        switch (sel) {
6633        case CP0_REG06__WIRED:
6634            gen_helper_mtc0_wired(cpu_env, arg);
6635            register_name = "Wired";
6636            break;
6637        case CP0_REG06__SRSCONF0:
6638            check_insn(ctx, ISA_MIPS_R2);
6639            gen_helper_mtc0_srsconf0(cpu_env, arg);
6640            register_name = "SRSConf0";
6641            break;
6642        case CP0_REG06__SRSCONF1:
6643            check_insn(ctx, ISA_MIPS_R2);
6644            gen_helper_mtc0_srsconf1(cpu_env, arg);
6645            register_name = "SRSConf1";
6646            break;
6647        case CP0_REG06__SRSCONF2:
6648            check_insn(ctx, ISA_MIPS_R2);
6649            gen_helper_mtc0_srsconf2(cpu_env, arg);
6650            register_name = "SRSConf2";
6651            break;
6652        case CP0_REG06__SRSCONF3:
6653            check_insn(ctx, ISA_MIPS_R2);
6654            gen_helper_mtc0_srsconf3(cpu_env, arg);
6655            register_name = "SRSConf3";
6656            break;
6657        case CP0_REG06__SRSCONF4:
6658            check_insn(ctx, ISA_MIPS_R2);
6659            gen_helper_mtc0_srsconf4(cpu_env, arg);
6660            register_name = "SRSConf4";
6661            break;
6662        case CP0_REG06__PWCTL:
6663            check_pw(ctx);
6664            gen_helper_mtc0_pwctl(cpu_env, arg);
6665            register_name = "PWCtl";
6666            break;
6667        default:
6668            goto cp0_unimplemented;
6669        }
6670        break;
6671    case CP0_REGISTER_07:
6672        switch (sel) {
6673        case CP0_REG07__HWRENA:
6674            check_insn(ctx, ISA_MIPS_R2);
6675            gen_helper_mtc0_hwrena(cpu_env, arg);
6676            ctx->base.is_jmp = DISAS_STOP;
6677            register_name = "HWREna";
6678            break;
6679        default:
6680            goto cp0_unimplemented;
6681        }
6682        break;
6683    case CP0_REGISTER_08:
6684        switch (sel) {
6685        case CP0_REG08__BADVADDR:
6686            /* ignored */
6687            register_name = "BadVAddr";
6688            break;
6689        case CP0_REG08__BADINSTR:
6690            /* ignored */
6691            register_name = "BadInstr";
6692            break;
6693        case CP0_REG08__BADINSTRP:
6694            /* ignored */
6695            register_name = "BadInstrP";
6696            break;
6697        case CP0_REG08__BADINSTRX:
6698            /* ignored */
6699            register_name = "BadInstrX";
6700            break;
6701        default:
6702            goto cp0_unimplemented;
6703        }
6704        break;
6705    case CP0_REGISTER_09:
6706        switch (sel) {
6707        case CP0_REG09__COUNT:
6708            gen_helper_mtc0_count(cpu_env, arg);
6709            register_name = "Count";
6710            break;
6711        case CP0_REG09__SAARI:
6712            CP0_CHECK(ctx->saar);
6713            gen_helper_mtc0_saari(cpu_env, arg);
6714            register_name = "SAARI";
6715            break;
6716        case CP0_REG09__SAAR:
6717            CP0_CHECK(ctx->saar);
6718            gen_helper_mtc0_saar(cpu_env, arg);
6719            register_name = "SAAR";
6720            break;
6721        default:
6722            goto cp0_unimplemented;
6723        }
6724        break;
6725    case CP0_REGISTER_10:
6726        switch (sel) {
6727        case CP0_REG10__ENTRYHI:
6728            gen_helper_mtc0_entryhi(cpu_env, arg);
6729            register_name = "EntryHi";
6730            break;
6731        default:
6732            goto cp0_unimplemented;
6733        }
6734        break;
6735    case CP0_REGISTER_11:
6736        switch (sel) {
6737        case CP0_REG11__COMPARE:
6738            gen_helper_mtc0_compare(cpu_env, arg);
6739            register_name = "Compare";
6740            break;
6741        /* 6,7 are implementation dependent */
6742        default:
6743            goto cp0_unimplemented;
6744        }
6745        break;
6746    case CP0_REGISTER_12:
6747        switch (sel) {
6748        case CP0_REG12__STATUS:
6749            save_cpu_state(ctx, 1);
6750            gen_helper_mtc0_status(cpu_env, arg);
6751            /* DISAS_STOP isn't good enough here, hflags may have changed. */
6752            gen_save_pc(ctx->base.pc_next + 4);
6753            ctx->base.is_jmp = DISAS_EXIT;
6754            register_name = "Status";
6755            break;
6756        case CP0_REG12__INTCTL:
6757            check_insn(ctx, ISA_MIPS_R2);
6758            gen_helper_mtc0_intctl(cpu_env, arg);
6759            /* Stop translation as we may have switched the execution mode */
6760            ctx->base.is_jmp = DISAS_STOP;
6761            register_name = "IntCtl";
6762            break;
6763        case CP0_REG12__SRSCTL:
6764            check_insn(ctx, ISA_MIPS_R2);
6765            gen_helper_mtc0_srsctl(cpu_env, arg);
6766            /* Stop translation as we may have switched the execution mode */
6767            ctx->base.is_jmp = DISAS_STOP;
6768            register_name = "SRSCtl";
6769            break;
6770        case CP0_REG12__SRSMAP:
6771            check_insn(ctx, ISA_MIPS_R2);
6772            gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_SRSMap));
6773            /* Stop translation as we may have switched the execution mode */
6774            ctx->base.is_jmp = DISAS_STOP;
6775            register_name = "SRSMap";
6776            break;
6777        default:
6778            goto cp0_unimplemented;
6779        }
6780        break;
6781    case CP0_REGISTER_13:
6782        switch (sel) {
6783        case CP0_REG13__CAUSE:
6784            save_cpu_state(ctx, 1);
6785            gen_helper_mtc0_cause(cpu_env, arg);
6786            /*
6787             * Stop translation as we may have triggered an interrupt.
6788             * DISAS_STOP isn't sufficient, we need to ensure we break out of
6789             * translated code to check for pending interrupts.
6790             */
6791            gen_save_pc(ctx->base.pc_next + 4);
6792            ctx->base.is_jmp = DISAS_EXIT;
6793            register_name = "Cause";
6794            break;
6795        default:
6796            goto cp0_unimplemented;
6797        }
6798        break;
6799    case CP0_REGISTER_14:
6800        switch (sel) {
6801        case CP0_REG14__EPC:
6802            tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EPC));
6803            register_name = "EPC";
6804            break;
6805        default:
6806            goto cp0_unimplemented;
6807        }
6808        break;
6809    case CP0_REGISTER_15:
6810        switch (sel) {
6811        case CP0_REG15__PRID:
6812            /* ignored */
6813            register_name = "PRid";
6814            break;
6815        case CP0_REG15__EBASE:
6816            check_insn(ctx, ISA_MIPS_R2);
6817            gen_helper_mtc0_ebase(cpu_env, arg);
6818            register_name = "EBase";
6819            break;
6820        default:
6821            goto cp0_unimplemented;
6822        }
6823        break;
6824    case CP0_REGISTER_16:
6825        switch (sel) {
6826        case CP0_REG16__CONFIG:
6827            gen_helper_mtc0_config0(cpu_env, arg);
6828            register_name = "Config";
6829            /* Stop translation as we may have switched the execution mode */
6830            ctx->base.is_jmp = DISAS_STOP;
6831            break;
6832        case CP0_REG16__CONFIG1:
6833            /* ignored, read only */
6834            register_name = "Config1";
6835            break;
6836        case CP0_REG16__CONFIG2:
6837            gen_helper_mtc0_config2(cpu_env, arg);
6838            register_name = "Config2";
6839            /* Stop translation as we may have switched the execution mode */
6840            ctx->base.is_jmp = DISAS_STOP;
6841            break;
6842        case CP0_REG16__CONFIG3:
6843            gen_helper_mtc0_config3(cpu_env, arg);
6844            register_name = "Config3";
6845            /* Stop translation as we may have switched the execution mode */
6846            ctx->base.is_jmp = DISAS_STOP;
6847            break;
6848        case CP0_REG16__CONFIG4:
6849            gen_helper_mtc0_config4(cpu_env, arg);
6850            register_name = "Config4";
6851            ctx->base.is_jmp = DISAS_STOP;
6852            break;
6853        case CP0_REG16__CONFIG5:
6854            gen_helper_mtc0_config5(cpu_env, arg);
6855            register_name = "Config5";
6856            /* Stop translation as we may have switched the execution mode */
6857            ctx->base.is_jmp = DISAS_STOP;
6858            break;
6859        /* 6,7 are implementation dependent */
6860        case CP0_REG16__CONFIG6:
6861            /* ignored */
6862            register_name = "Config6";
6863            break;
6864        case CP0_REG16__CONFIG7:
6865            /* ignored */
6866            register_name = "Config7";
6867            break;
6868        default:
6869            register_name = "Invalid config selector";
6870            goto cp0_unimplemented;
6871        }
6872        break;
6873    case CP0_REGISTER_17:
6874        switch (sel) {
6875        case CP0_REG17__LLADDR:
6876            gen_helper_mtc0_lladdr(cpu_env, arg);
6877            register_name = "LLAddr";
6878            break;
6879        case CP0_REG17__MAAR:
6880            CP0_CHECK(ctx->mrp);
6881            gen_helper_mtc0_maar(cpu_env, arg);
6882            register_name = "MAAR";
6883            break;
6884        case CP0_REG17__MAARI:
6885            CP0_CHECK(ctx->mrp);
6886            gen_helper_mtc0_maari(cpu_env, arg);
6887            register_name = "MAARI";
6888            break;
6889        default:
6890            goto cp0_unimplemented;
6891        }
6892        break;
6893    case CP0_REGISTER_18:
6894        switch (sel) {
6895        case CP0_REG18__WATCHLO0:
6896        case CP0_REG18__WATCHLO1:
6897        case CP0_REG18__WATCHLO2:
6898        case CP0_REG18__WATCHLO3:
6899        case CP0_REG18__WATCHLO4:
6900        case CP0_REG18__WATCHLO5:
6901        case CP0_REG18__WATCHLO6:
6902        case CP0_REG18__WATCHLO7:
6903            CP0_CHECK(ctx->CP0_Config1 & (1 << CP0C1_WR));
6904            gen_helper_0e1i(mtc0_watchlo, arg, sel);
6905            register_name = "WatchLo";
6906            break;
6907        default:
6908            goto cp0_unimplemented;
6909        }
6910        break;
6911    case CP0_REGISTER_19:
6912        switch (sel) {
6913        case CP0_REG19__WATCHHI0:
6914        case CP0_REG19__WATCHHI1:
6915        case CP0_REG19__WATCHHI2:
6916        case CP0_REG19__WATCHHI3:
6917        case CP0_REG19__WATCHHI4:
6918        case CP0_REG19__WATCHHI5:
6919        case CP0_REG19__WATCHHI6:
6920        case CP0_REG19__WATCHHI7:
6921            CP0_CHECK(ctx->CP0_Config1 & (1 << CP0C1_WR));
6922            gen_helper_0e1i(mtc0_watchhi, arg, sel);
6923            register_name = "WatchHi";
6924            break;
6925        default:
6926            goto cp0_unimplemented;
6927        }
6928        break;
6929    case CP0_REGISTER_20:
6930        switch (sel) {
6931        case CP0_REG20__XCONTEXT:
6932#if defined(TARGET_MIPS64)
6933            check_insn(ctx, ISA_MIPS3);
6934            gen_helper_mtc0_xcontext(cpu_env, arg);
6935            register_name = "XContext";
6936            break;
6937#endif
6938        default:
6939            goto cp0_unimplemented;
6940        }
6941        break;
6942    case CP0_REGISTER_21:
6943       /* Officially reserved, but sel 0 is used for R1x000 framemask */
6944        CP0_CHECK(!(ctx->insn_flags & ISA_MIPS_R6));
6945        switch (sel) {
6946        case 0:
6947            gen_helper_mtc0_framemask(cpu_env, arg);
6948            register_name = "Framemask";
6949            break;
6950        default:
6951            goto cp0_unimplemented;
6952        }
6953        break;
6954    case CP0_REGISTER_22:
6955        /* ignored */
6956        register_name = "Diagnostic"; /* implementation dependent */
6957        break;
6958    case CP0_REGISTER_23:
6959        switch (sel) {
6960        case CP0_REG23__DEBUG:
6961            gen_helper_mtc0_debug(cpu_env, arg); /* EJTAG support */
6962            /* DISAS_STOP isn't good enough here, hflags may have changed. */
6963            gen_save_pc(ctx->base.pc_next + 4);
6964            ctx->base.is_jmp = DISAS_EXIT;
6965            register_name = "Debug";
6966            break;
6967        case CP0_REG23__TRACECONTROL:
6968            /* PDtrace support */
6969            /* gen_helper_mtc0_tracecontrol(cpu_env, arg);  */
6970            register_name = "TraceControl";
6971            /* Stop translation as we may have switched the execution mode */
6972            ctx->base.is_jmp = DISAS_STOP;
6973            goto cp0_unimplemented;
6974        case CP0_REG23__TRACECONTROL2:
6975            /* PDtrace support */
6976            /* gen_helper_mtc0_tracecontrol2(cpu_env, arg); */
6977            register_name = "TraceControl2";
6978            /* Stop translation as we may have switched the execution mode */
6979            ctx->base.is_jmp = DISAS_STOP;
6980            goto cp0_unimplemented;
6981        case CP0_REG23__USERTRACEDATA1:
6982            /* Stop translation as we may have switched the execution mode */
6983            ctx->base.is_jmp = DISAS_STOP;
6984            /* PDtrace support */
6985            /* gen_helper_mtc0_usertracedata1(cpu_env, arg);*/
6986            register_name = "UserTraceData";
6987            /* Stop translation as we may have switched the execution mode */
6988            ctx->base.is_jmp = DISAS_STOP;
6989            goto cp0_unimplemented;
6990        case CP0_REG23__TRACEIBPC:
6991            /* PDtrace support */
6992            /* gen_helper_mtc0_traceibpc(cpu_env, arg);     */
6993            /* Stop translation as we may have switched the execution mode */
6994            ctx->base.is_jmp = DISAS_STOP;
6995            register_name = "TraceIBPC";
6996            goto cp0_unimplemented;
6997        case CP0_REG23__TRACEDBPC:
6998            /* PDtrace support */
6999            /* gen_helper_mtc0_tracedbpc(cpu_env, arg);     */
7000            /* Stop translation as we may have switched the execution mode */
7001            ctx->base.is_jmp = DISAS_STOP;
7002            register_name = "TraceDBPC";
7003            goto cp0_unimplemented;
7004        default:
7005            goto cp0_unimplemented;
7006        }
7007        break;
7008    case CP0_REGISTER_24:
7009        switch (sel) {
7010        case CP0_REG24__DEPC:
7011            /* EJTAG support */
7012            tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_DEPC));
7013            register_name = "DEPC";
7014            break;
7015        default:
7016            goto cp0_unimplemented;
7017        }
7018        break;
7019    case CP0_REGISTER_25:
7020        switch (sel) {
7021        case CP0_REG25__PERFCTL0:
7022            gen_helper_mtc0_performance0(cpu_env, arg);
7023            register_name = "Performance0";
7024            break;
7025        case CP0_REG25__PERFCNT0:
7026            /* gen_helper_mtc0_performance1(arg); */
7027            register_name = "Performance1";
7028            goto cp0_unimplemented;
7029        case CP0_REG25__PERFCTL1:
7030            /* gen_helper_mtc0_performance2(arg); */
7031            register_name = "Performance2";
7032            goto cp0_unimplemented;
7033        case CP0_REG25__PERFCNT1:
7034            /* gen_helper_mtc0_performance3(arg); */
7035            register_name = "Performance3";
7036            goto cp0_unimplemented;
7037        case CP0_REG25__PERFCTL2:
7038            /* gen_helper_mtc0_performance4(arg); */
7039            register_name = "Performance4";
7040            goto cp0_unimplemented;
7041        case CP0_REG25__PERFCNT2:
7042            /* gen_helper_mtc0_performance5(arg); */
7043            register_name = "Performance5";
7044            goto cp0_unimplemented;
7045        case CP0_REG25__PERFCTL3:
7046            /* gen_helper_mtc0_performance6(arg); */
7047            register_name = "Performance6";
7048            goto cp0_unimplemented;
7049        case CP0_REG25__PERFCNT3:
7050            /* gen_helper_mtc0_performance7(arg); */
7051            register_name = "Performance7";
7052            goto cp0_unimplemented;
7053        default:
7054            goto cp0_unimplemented;
7055        }
7056       break;
7057    case CP0_REGISTER_26:
7058        switch (sel) {
7059        case CP0_REG26__ERRCTL:
7060            gen_helper_mtc0_errctl(cpu_env, arg);
7061            ctx->base.is_jmp = DISAS_STOP;
7062            register_name = "ErrCtl";
7063            break;
7064        default:
7065            goto cp0_unimplemented;
7066        }
7067        break;
7068    case CP0_REGISTER_27:
7069        switch (sel) {
7070        case CP0_REG27__CACHERR:
7071            /* ignored */
7072            register_name = "CacheErr";
7073            break;
7074        default:
7075            goto cp0_unimplemented;
7076        }
7077       break;
7078    case CP0_REGISTER_28:
7079        switch (sel) {
7080        case CP0_REG28__TAGLO:
7081        case CP0_REG28__TAGLO1:
7082        case CP0_REG28__TAGLO2:
7083        case CP0_REG28__TAGLO3:
7084            gen_helper_mtc0_taglo(cpu_env, arg);
7085            register_name = "TagLo";
7086            break;
7087        case CP0_REG28__DATALO:
7088        case CP0_REG28__DATALO1:
7089        case CP0_REG28__DATALO2:
7090        case CP0_REG28__DATALO3:
7091            gen_helper_mtc0_datalo(cpu_env, arg);
7092            register_name = "DataLo";
7093            break;
7094        default:
7095            goto cp0_unimplemented;
7096        }
7097        break;
7098    case CP0_REGISTER_29:
7099        switch (sel) {
7100        case CP0_REG29__TAGHI:
7101        case CP0_REG29__TAGHI1:
7102        case CP0_REG29__TAGHI2:
7103        case CP0_REG29__TAGHI3:
7104            gen_helper_mtc0_taghi(cpu_env, arg);
7105            register_name = "TagHi";
7106            break;
7107        case CP0_REG29__DATAHI:
7108        case CP0_REG29__DATAHI1:
7109        case CP0_REG29__DATAHI2:
7110        case CP0_REG29__DATAHI3:
7111            gen_helper_mtc0_datahi(cpu_env, arg);
7112            register_name = "DataHi";
7113            break;
7114        default:
7115            register_name = "invalid sel";
7116            goto cp0_unimplemented;
7117        }
7118       break;
7119    case CP0_REGISTER_30:
7120        switch (sel) {
7121        case CP0_REG30__ERROREPC:
7122            tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_ErrorEPC));
7123            register_name = "ErrorEPC";
7124            break;
7125        default:
7126            goto cp0_unimplemented;
7127        }
7128        break;
7129    case CP0_REGISTER_31:
7130        switch (sel) {
7131        case CP0_REG31__DESAVE:
7132            /* EJTAG support */
7133            gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_DESAVE));
7134            register_name = "DESAVE";
7135            break;
7136        case CP0_REG31__KSCRATCH1:
7137        case CP0_REG31__KSCRATCH2:
7138        case CP0_REG31__KSCRATCH3:
7139        case CP0_REG31__KSCRATCH4:
7140        case CP0_REG31__KSCRATCH5:
7141        case CP0_REG31__KSCRATCH6:
7142            CP0_CHECK(ctx->kscrexist & (1 << sel));
7143            tcg_gen_st_tl(arg, cpu_env,
7144                          offsetof(CPUMIPSState, CP0_KScratch[sel - 2]));
7145            register_name = "KScratch";
7146            break;
7147        default:
7148            goto cp0_unimplemented;
7149        }
7150        break;
7151    default:
7152       goto cp0_unimplemented;
7153    }
7154    trace_mips_translate_c0("mtc0", register_name, reg, sel);
7155
7156    /* For simplicity assume that all writes can cause interrupts.  */
7157    if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
7158        /*
7159         * DISAS_STOP isn't sufficient, we need to ensure we break out of
7160         * translated code to check for pending interrupts.
7161         */
7162        gen_save_pc(ctx->base.pc_next + 4);
7163        ctx->base.is_jmp = DISAS_EXIT;
7164    }
7165    return;
7166
7167cp0_unimplemented:
7168    qemu_log_mask(LOG_UNIMP, "mtc0 %s (reg %d sel %d)\n",
7169                  register_name, reg, sel);
7170}
7171
7172#if defined(TARGET_MIPS64)
7173static void gen_dmfc0(DisasContext *ctx, TCGv arg, int reg, int sel)
7174{
7175    const char *register_name = "invalid";
7176
7177    if (sel != 0) {
7178        check_insn(ctx, ISA_MIPS_R1);
7179    }
7180
7181    switch (reg) {
7182    case CP0_REGISTER_00:
7183        switch (sel) {
7184        case CP0_REG00__INDEX:
7185            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Index));
7186            register_name = "Index";
7187            break;
7188        case CP0_REG00__MVPCONTROL:
7189            CP0_CHECK(ctx->insn_flags & ASE_MT);
7190            gen_helper_mfc0_mvpcontrol(arg, cpu_env);
7191            register_name = "MVPControl";
7192            break;
7193        case CP0_REG00__MVPCONF0:
7194            CP0_CHECK(ctx->insn_flags & ASE_MT);
7195            gen_helper_mfc0_mvpconf0(arg, cpu_env);
7196            register_name = "MVPConf0";
7197            break;
7198        case CP0_REG00__MVPCONF1:
7199            CP0_CHECK(ctx->insn_flags & ASE_MT);
7200            gen_helper_mfc0_mvpconf1(arg, cpu_env);
7201            register_name = "MVPConf1";
7202            break;
7203        case CP0_REG00__VPCONTROL:
7204            CP0_CHECK(ctx->vp);
7205            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPControl));
7206            register_name = "VPControl";
7207            break;
7208        default:
7209            goto cp0_unimplemented;
7210        }
7211        break;
7212    case CP0_REGISTER_01:
7213        switch (sel) {
7214        case CP0_REG01__RANDOM:
7215            CP0_CHECK(!(ctx->insn_flags & ISA_MIPS_R6));
7216            gen_helper_mfc0_random(arg, cpu_env);
7217            register_name = "Random";
7218            break;
7219        case CP0_REG01__VPECONTROL:
7220            CP0_CHECK(ctx->insn_flags & ASE_MT);
7221            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEControl));
7222            register_name = "VPEControl";
7223            break;
7224        case CP0_REG01__VPECONF0:
7225            CP0_CHECK(ctx->insn_flags & ASE_MT);
7226            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf0));
7227            register_name = "VPEConf0";
7228            break;
7229        case CP0_REG01__VPECONF1:
7230            CP0_CHECK(ctx->insn_flags & ASE_MT);
7231            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf1));
7232            register_name = "VPEConf1";
7233            break;
7234        case CP0_REG01__YQMASK:
7235            CP0_CHECK(ctx->insn_flags & ASE_MT);
7236            tcg_gen_ld_tl(arg, cpu_env,
7237                          offsetof(CPUMIPSState, CP0_YQMask));
7238            register_name = "YQMask";
7239            break;
7240        case CP0_REG01__VPESCHEDULE:
7241            CP0_CHECK(ctx->insn_flags & ASE_MT);
7242            tcg_gen_ld_tl(arg, cpu_env,
7243                          offsetof(CPUMIPSState, CP0_VPESchedule));
7244            register_name = "VPESchedule";
7245            break;
7246        case CP0_REG01__VPESCHEFBACK:
7247            CP0_CHECK(ctx->insn_flags & ASE_MT);
7248            tcg_gen_ld_tl(arg, cpu_env,
7249                          offsetof(CPUMIPSState, CP0_VPEScheFBack));
7250            register_name = "VPEScheFBack";
7251            break;
7252        case CP0_REG01__VPEOPT:
7253            CP0_CHECK(ctx->insn_flags & ASE_MT);
7254            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEOpt));
7255            register_name = "VPEOpt";
7256            break;
7257        default:
7258            goto cp0_unimplemented;
7259        }
7260        break;
7261    case CP0_REGISTER_02:
7262        switch (sel) {
7263        case CP0_REG02__ENTRYLO0:
7264            tcg_gen_ld_tl(arg, cpu_env,
7265                          offsetof(CPUMIPSState, CP0_EntryLo0));
7266            register_name = "EntryLo0";
7267            break;
7268        case CP0_REG02__TCSTATUS:
7269            CP0_CHECK(ctx->insn_flags & ASE_MT);
7270            gen_helper_mfc0_tcstatus(arg, cpu_env);
7271            register_name = "TCStatus";
7272            break;
7273        case CP0_REG02__TCBIND:
7274            CP0_CHECK(ctx->insn_flags & ASE_MT);
7275            gen_helper_mfc0_tcbind(arg, cpu_env);
7276            register_name = "TCBind";
7277            break;
7278        case CP0_REG02__TCRESTART:
7279            CP0_CHECK(ctx->insn_flags & ASE_MT);
7280            gen_helper_dmfc0_tcrestart(arg, cpu_env);
7281            register_name = "TCRestart";
7282            break;
7283        case CP0_REG02__TCHALT:
7284            CP0_CHECK(ctx->insn_flags & ASE_MT);
7285            gen_helper_dmfc0_tchalt(arg, cpu_env);
7286            register_name = "TCHalt";
7287            break;
7288        case CP0_REG02__TCCONTEXT:
7289            CP0_CHECK(ctx->insn_flags & ASE_MT);
7290            gen_helper_dmfc0_tccontext(arg, cpu_env);
7291            register_name = "TCContext";
7292            break;
7293        case CP0_REG02__TCSCHEDULE:
7294            CP0_CHECK(ctx->insn_flags & ASE_MT);
7295            gen_helper_dmfc0_tcschedule(arg, cpu_env);
7296            register_name = "TCSchedule";
7297            break;
7298        case CP0_REG02__TCSCHEFBACK:
7299            CP0_CHECK(ctx->insn_flags & ASE_MT);
7300            gen_helper_dmfc0_tcschefback(arg, cpu_env);
7301            register_name = "TCScheFBack";
7302            break;
7303        default:
7304            goto cp0_unimplemented;
7305        }
7306        break;
7307    case CP0_REGISTER_03:
7308        switch (sel) {
7309        case CP0_REG03__ENTRYLO1:
7310            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryLo1));
7311            register_name = "EntryLo1";
7312            break;
7313        case CP0_REG03__GLOBALNUM:
7314            CP0_CHECK(ctx->vp);
7315            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_GlobalNumber));
7316            register_name = "GlobalNumber";
7317            break;
7318        default:
7319            goto cp0_unimplemented;
7320        }
7321        break;
7322    case CP0_REGISTER_04:
7323        switch (sel) {
7324        case CP0_REG04__CONTEXT:
7325            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_Context));
7326            register_name = "Context";
7327            break;
7328        case CP0_REG04__CONTEXTCONFIG:
7329            /* SmartMIPS ASE */
7330            /* gen_helper_dmfc0_contextconfig(arg); */
7331            register_name = "ContextConfig";
7332            goto cp0_unimplemented;
7333        case CP0_REG04__USERLOCAL:
7334            CP0_CHECK(ctx->ulri);
7335            tcg_gen_ld_tl(arg, cpu_env,
7336                          offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
7337            register_name = "UserLocal";
7338            break;
7339        case CP0_REG04__MMID:
7340            CP0_CHECK(ctx->mi);
7341            gen_helper_mtc0_memorymapid(cpu_env, arg);
7342            register_name = "MMID";
7343            break;
7344        default:
7345            goto cp0_unimplemented;
7346        }
7347        break;
7348    case CP0_REGISTER_05:
7349        switch (sel) {
7350        case CP0_REG05__PAGEMASK:
7351            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageMask));
7352            register_name = "PageMask";
7353            break;
7354        case CP0_REG05__PAGEGRAIN:
7355            check_insn(ctx, ISA_MIPS_R2);
7356            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageGrain));
7357            register_name = "PageGrain";
7358            break;
7359        case CP0_REG05__SEGCTL0:
7360            CP0_CHECK(ctx->sc);
7361            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_SegCtl0));
7362            register_name = "SegCtl0";
7363            break;
7364        case CP0_REG05__SEGCTL1:
7365            CP0_CHECK(ctx->sc);
7366            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_SegCtl1));
7367            register_name = "SegCtl1";
7368            break;
7369        case CP0_REG05__SEGCTL2:
7370            CP0_CHECK(ctx->sc);
7371            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_SegCtl2));
7372            register_name = "SegCtl2";
7373            break;
7374        case CP0_REG05__PWBASE:
7375            check_pw(ctx);
7376            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_PWBase));
7377            register_name = "PWBase";
7378            break;
7379        case CP0_REG05__PWFIELD:
7380            check_pw(ctx);
7381            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_PWField));
7382            register_name = "PWField";
7383            break;
7384        case CP0_REG05__PWSIZE:
7385            check_pw(ctx);
7386            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_PWSize));
7387            register_name = "PWSize";
7388            break;
7389        default:
7390            goto cp0_unimplemented;
7391        }
7392        break;
7393    case CP0_REGISTER_06:
7394        switch (sel) {
7395        case CP0_REG06__WIRED:
7396            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Wired));
7397            register_name = "Wired";
7398            break;
7399        case CP0_REG06__SRSCONF0:
7400            check_insn(ctx, ISA_MIPS_R2);
7401            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf0));
7402            register_name = "SRSConf0";
7403            break;
7404        case CP0_REG06__SRSCONF1:
7405            check_insn(ctx, ISA_MIPS_R2);
7406            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf1));
7407            register_name = "SRSConf1";
7408            break;
7409        case CP0_REG06__SRSCONF2:
7410            check_insn(ctx, ISA_MIPS_R2);
7411            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf2));
7412            register_name = "SRSConf2";
7413            break;
7414        case CP0_REG06__SRSCONF3:
7415            check_insn(ctx, ISA_MIPS_R2);
7416            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf3));
7417            register_name = "SRSConf3";
7418            break;
7419        case CP0_REG06__SRSCONF4:
7420            check_insn(ctx, ISA_MIPS_R2);
7421            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf4));
7422            register_name = "SRSConf4";
7423            break;
7424        case CP0_REG06__PWCTL:
7425            check_pw(ctx);
7426            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PWCtl));
7427            register_name = "PWCtl";
7428            break;
7429        default:
7430            goto cp0_unimplemented;
7431        }
7432        break;
7433    case CP0_REGISTER_07:
7434        switch (sel) {
7435        case CP0_REG07__HWRENA:
7436            check_insn(ctx, ISA_MIPS_R2);
7437            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_HWREna));
7438            register_name = "HWREna";
7439            break;
7440        default:
7441            goto cp0_unimplemented;
7442        }
7443        break;
7444    case CP0_REGISTER_08:
7445        switch (sel) {
7446        case CP0_REG08__BADVADDR:
7447            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_BadVAddr));
7448            register_name = "BadVAddr";
7449            break;
7450        case CP0_REG08__BADINSTR:
7451            CP0_CHECK(ctx->bi);
7452            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_BadInstr));
7453            register_name = "BadInstr";
7454            break;
7455        case CP0_REG08__BADINSTRP:
7456            CP0_CHECK(ctx->bp);
7457            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_BadInstrP));
7458            register_name = "BadInstrP";
7459            break;
7460        case CP0_REG08__BADINSTRX:
7461            CP0_CHECK(ctx->bi);
7462            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_BadInstrX));
7463            tcg_gen_andi_tl(arg, arg, ~0xffff);
7464            register_name = "BadInstrX";
7465            break;
7466        default:
7467            goto cp0_unimplemented;
7468        }
7469        break;
7470    case CP0_REGISTER_09:
7471        switch (sel) {
7472        case CP0_REG09__COUNT:
7473            /* Mark as an IO operation because we read the time.  */
7474            if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
7475                gen_io_start();
7476            }
7477            gen_helper_mfc0_count(arg, cpu_env);
7478            /*
7479             * Break the TB to be able to take timer interrupts immediately
7480             * after reading count. DISAS_STOP isn't sufficient, we need to
7481             * ensure we break completely out of translated code.
7482             */
7483            gen_save_pc(ctx->base.pc_next + 4);
7484            ctx->base.is_jmp = DISAS_EXIT;
7485            register_name = "Count";
7486            break;
7487        case CP0_REG09__SAARI:
7488            CP0_CHECK(ctx->saar);
7489            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SAARI));
7490            register_name = "SAARI";
7491            break;
7492        case CP0_REG09__SAAR:
7493            CP0_CHECK(ctx->saar);
7494            gen_helper_dmfc0_saar(arg, cpu_env);
7495            register_name = "SAAR";
7496            break;
7497        default:
7498            goto cp0_unimplemented;
7499        }
7500        break;
7501    case CP0_REGISTER_10:
7502        switch (sel) {
7503        case CP0_REG10__ENTRYHI:
7504            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryHi));
7505            register_name = "EntryHi";
7506            break;
7507        default:
7508            goto cp0_unimplemented;
7509        }
7510        break;
7511    case CP0_REGISTER_11:
7512        switch (sel) {
7513        case CP0_REG11__COMPARE:
7514            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Compare));
7515            register_name = "Compare";
7516            break;
7517        /* 6,7 are implementation dependent */
7518        default:
7519            goto cp0_unimplemented;
7520        }
7521        break;
7522    case CP0_REGISTER_12:
7523        switch (sel) {
7524        case CP0_REG12__STATUS:
7525            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Status));
7526            register_name = "Status";
7527            break;
7528        case CP0_REG12__INTCTL:
7529            check_insn(ctx, ISA_MIPS_R2);
7530            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_IntCtl));
7531            register_name = "IntCtl";
7532            break;
7533        case CP0_REG12__SRSCTL:
7534            check_insn(ctx, ISA_MIPS_R2);
7535            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSCtl));
7536            register_name = "SRSCtl";
7537            break;
7538        case CP0_REG12__SRSMAP:
7539            check_insn(ctx, ISA_MIPS_R2);
7540            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSMap));
7541            register_name = "SRSMap";
7542            break;
7543        default:
7544            goto cp0_unimplemented;
7545        }
7546        break;
7547    case CP0_REGISTER_13:
7548        switch (sel) {
7549        case CP0_REG13__CAUSE:
7550            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Cause));
7551            register_name = "Cause";
7552            break;
7553        default:
7554            goto cp0_unimplemented;
7555        }
7556        break;
7557    case CP0_REGISTER_14:
7558        switch (sel) {
7559        case CP0_REG14__EPC:
7560            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EPC));
7561            register_name = "EPC";
7562            break;
7563        default:
7564            goto cp0_unimplemented;
7565        }
7566        break;
7567    case CP0_REGISTER_15:
7568        switch (sel) {
7569        case CP0_REG15__PRID:
7570            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PRid));
7571            register_name = "PRid";
7572            break;
7573        case CP0_REG15__EBASE:
7574            check_insn(ctx, ISA_MIPS_R2);
7575            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EBase));
7576            register_name = "EBase";
7577            break;
7578        case CP0_REG15__CMGCRBASE:
7579            check_insn(ctx, ISA_MIPS_R2);
7580            CP0_CHECK(ctx->cmgcr);
7581            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_CMGCRBase));
7582            register_name = "CMGCRBase";
7583            break;
7584        default:
7585            goto cp0_unimplemented;
7586        }
7587        break;
7588    case CP0_REGISTER_16:
7589        switch (sel) {
7590        case CP0_REG16__CONFIG:
7591            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config0));
7592            register_name = "Config";
7593            break;
7594        case CP0_REG16__CONFIG1:
7595            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config1));
7596            register_name = "Config1";
7597            break;
7598        case CP0_REG16__CONFIG2:
7599            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config2));
7600            register_name = "Config2";
7601            break;
7602        case CP0_REG16__CONFIG3:
7603            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config3));
7604            register_name = "Config3";
7605            break;
7606        case CP0_REG16__CONFIG4:
7607            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config4));
7608            register_name = "Config4";
7609            break;
7610        case CP0_REG16__CONFIG5:
7611            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config5));
7612            register_name = "Config5";
7613            break;
7614        /* 6,7 are implementation dependent */
7615        case CP0_REG16__CONFIG6:
7616            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config6));
7617            register_name = "Config6";
7618            break;
7619        case CP0_REG16__CONFIG7:
7620            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config7));
7621            register_name = "Config7";
7622            break;
7623        default:
7624            goto cp0_unimplemented;
7625        }
7626        break;
7627    case CP0_REGISTER_17:
7628        switch (sel) {
7629        case CP0_REG17__LLADDR:
7630            gen_helper_dmfc0_lladdr(arg, cpu_env);
7631            register_name = "LLAddr";
7632            break;
7633        case CP0_REG17__MAAR:
7634            CP0_CHECK(ctx->mrp);
7635            gen_helper_dmfc0_maar(arg, cpu_env);
7636            register_name = "MAAR";
7637            break;
7638        case CP0_REG17__MAARI:
7639            CP0_CHECK(ctx->mrp);
7640            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_MAARI));
7641            register_name = "MAARI";
7642            break;
7643        default:
7644            goto cp0_unimplemented;
7645        }
7646        break;
7647    case CP0_REGISTER_18:
7648        switch (sel) {
7649        case CP0_REG18__WATCHLO0:
7650        case CP0_REG18__WATCHLO1:
7651        case CP0_REG18__WATCHLO2:
7652        case CP0_REG18__WATCHLO3:
7653        case CP0_REG18__WATCHLO4:
7654        case CP0_REG18__WATCHLO5:
7655        case CP0_REG18__WATCHLO6:
7656        case CP0_REG18__WATCHLO7:
7657            CP0_CHECK(ctx->CP0_Config1 & (1 << CP0C1_WR));
7658            gen_helper_1e0i(dmfc0_watchlo, arg, sel);
7659            register_name = "WatchLo";
7660            break;
7661        default:
7662            goto cp0_unimplemented;
7663        }
7664        break;
7665    case CP0_REGISTER_19:
7666        switch (sel) {
7667        case CP0_REG19__WATCHHI0:
7668        case CP0_REG19__WATCHHI1:
7669        case CP0_REG19__WATCHHI2:
7670        case CP0_REG19__WATCHHI3:
7671        case CP0_REG19__WATCHHI4:
7672        case CP0_REG19__WATCHHI5:
7673        case CP0_REG19__WATCHHI6:
7674        case CP0_REG19__WATCHHI7:
7675            CP0_CHECK(ctx->CP0_Config1 & (1 << CP0C1_WR));
7676            gen_helper_1e0i(dmfc0_watchhi, arg, sel);
7677            register_name = "WatchHi";
7678            break;
7679        default:
7680            goto cp0_unimplemented;
7681        }
7682        break;
7683    case CP0_REGISTER_20:
7684        switch (sel) {
7685        case CP0_REG20__XCONTEXT:
7686            check_insn(ctx, ISA_MIPS3);
7687            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_XContext));
7688            register_name = "XContext";
7689            break;
7690        default:
7691            goto cp0_unimplemented;
7692        }
7693        break;
7694    case CP0_REGISTER_21:
7695        /* Officially reserved, but sel 0 is used for R1x000 framemask */
7696        CP0_CHECK(!(ctx->insn_flags & ISA_MIPS_R6));
7697        switch (sel) {
7698        case 0:
7699            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Framemask));
7700            register_name = "Framemask";
7701            break;
7702        default:
7703            goto cp0_unimplemented;
7704        }
7705        break;
7706    case CP0_REGISTER_22:
7707        tcg_gen_movi_tl(arg, 0); /* unimplemented */
7708        register_name = "'Diagnostic"; /* implementation dependent */
7709        break;
7710    case CP0_REGISTER_23:
7711        switch (sel) {
7712        case CP0_REG23__DEBUG:
7713            gen_helper_mfc0_debug(arg, cpu_env); /* EJTAG support */
7714            register_name = "Debug";
7715            break;
7716        case CP0_REG23__TRACECONTROL:
7717            /* PDtrace support */
7718            /* gen_helper_dmfc0_tracecontrol(arg, cpu_env);  */
7719            register_name = "TraceControl";
7720            goto cp0_unimplemented;
7721        case CP0_REG23__TRACECONTROL2:
7722            /* PDtrace support */
7723            /* gen_helper_dmfc0_tracecontrol2(arg, cpu_env); */
7724            register_name = "TraceControl2";
7725            goto cp0_unimplemented;
7726        case CP0_REG23__USERTRACEDATA1:
7727            /* PDtrace support */
7728            /* gen_helper_dmfc0_usertracedata1(arg, cpu_env);*/
7729            register_name = "UserTraceData1";
7730            goto cp0_unimplemented;
7731        case CP0_REG23__TRACEIBPC:
7732            /* PDtrace support */
7733            /* gen_helper_dmfc0_traceibpc(arg, cpu_env);     */
7734            register_name = "TraceIBPC";
7735            goto cp0_unimplemented;
7736        case CP0_REG23__TRACEDBPC:
7737            /* PDtrace support */
7738            /* gen_helper_dmfc0_tracedbpc(arg, cpu_env);     */
7739            register_name = "TraceDBPC";
7740            goto cp0_unimplemented;
7741        default:
7742            goto cp0_unimplemented;
7743        }
7744        break;
7745    case CP0_REGISTER_24:
7746        switch (sel) {
7747        case CP0_REG24__DEPC:
7748            /* EJTAG support */
7749            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_DEPC));
7750            register_name = "DEPC";
7751            break;
7752        default:
7753            goto cp0_unimplemented;
7754        }
7755        break;
7756    case CP0_REGISTER_25:
7757        switch (sel) {
7758        case CP0_REG25__PERFCTL0:
7759            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Performance0));
7760            register_name = "Performance0";
7761            break;
7762        case CP0_REG25__PERFCNT0:
7763            /* gen_helper_dmfc0_performance1(arg); */
7764            register_name = "Performance1";
7765            goto cp0_unimplemented;
7766        case CP0_REG25__PERFCTL1:
7767            /* gen_helper_dmfc0_performance2(arg); */
7768            register_name = "Performance2";
7769            goto cp0_unimplemented;
7770        case CP0_REG25__PERFCNT1:
7771            /* gen_helper_dmfc0_performance3(arg); */
7772            register_name = "Performance3";
7773            goto cp0_unimplemented;
7774        case CP0_REG25__PERFCTL2:
7775            /* gen_helper_dmfc0_performance4(arg); */
7776            register_name = "Performance4";
7777            goto cp0_unimplemented;
7778        case CP0_REG25__PERFCNT2:
7779            /* gen_helper_dmfc0_performance5(arg); */
7780            register_name = "Performance5";
7781            goto cp0_unimplemented;
7782        case CP0_REG25__PERFCTL3:
7783            /* gen_helper_dmfc0_performance6(arg); */
7784            register_name = "Performance6";
7785            goto cp0_unimplemented;
7786        case CP0_REG25__PERFCNT3:
7787            /* gen_helper_dmfc0_performance7(arg); */
7788            register_name = "Performance7";
7789            goto cp0_unimplemented;
7790        default:
7791            goto cp0_unimplemented;
7792        }
7793        break;
7794    case CP0_REGISTER_26:
7795        switch (sel) {
7796        case CP0_REG26__ERRCTL:
7797            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_ErrCtl));
7798            register_name = "ErrCtl";
7799            break;
7800        default:
7801            goto cp0_unimplemented;
7802        }
7803        break;
7804    case CP0_REGISTER_27:
7805        switch (sel) {
7806        /* ignored */
7807        case CP0_REG27__CACHERR:
7808            tcg_gen_movi_tl(arg, 0); /* unimplemented */
7809            register_name = "CacheErr";
7810            break;
7811        default:
7812            goto cp0_unimplemented;
7813        }
7814        break;
7815    case CP0_REGISTER_28:
7816        switch (sel) {
7817        case CP0_REG28__TAGLO:
7818        case CP0_REG28__TAGLO1:
7819        case CP0_REG28__TAGLO2:
7820        case CP0_REG28__TAGLO3:
7821            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_TagLo));
7822            register_name = "TagLo";
7823            break;
7824        case CP0_REG28__DATALO:
7825        case CP0_REG28__DATALO1:
7826        case CP0_REG28__DATALO2:
7827        case CP0_REG28__DATALO3:
7828            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataLo));
7829            register_name = "DataLo";
7830            break;
7831        default:
7832            goto cp0_unimplemented;
7833        }
7834        break;
7835    case CP0_REGISTER_29:
7836        switch (sel) {
7837        case CP0_REG29__TAGHI:
7838        case CP0_REG29__TAGHI1:
7839        case CP0_REG29__TAGHI2:
7840        case CP0_REG29__TAGHI3:
7841            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_TagHi));
7842            register_name = "TagHi";
7843            break;
7844        case CP0_REG29__DATAHI:
7845        case CP0_REG29__DATAHI1:
7846        case CP0_REG29__DATAHI2:
7847        case CP0_REG29__DATAHI3:
7848            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataHi));
7849            register_name = "DataHi";
7850            break;
7851        default:
7852            goto cp0_unimplemented;
7853        }
7854        break;
7855    case CP0_REGISTER_30:
7856        switch (sel) {
7857        case CP0_REG30__ERROREPC:
7858            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_ErrorEPC));
7859            register_name = "ErrorEPC";
7860            break;
7861        default:
7862            goto cp0_unimplemented;
7863        }
7864        break;
7865    case CP0_REGISTER_31:
7866        switch (sel) {
7867        case CP0_REG31__DESAVE:
7868            /* EJTAG support */
7869            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DESAVE));
7870            register_name = "DESAVE";
7871            break;
7872        case CP0_REG31__KSCRATCH1:
7873        case CP0_REG31__KSCRATCH2:
7874        case CP0_REG31__KSCRATCH3:
7875        case CP0_REG31__KSCRATCH4:
7876        case CP0_REG31__KSCRATCH5:
7877        case CP0_REG31__KSCRATCH6:
7878            CP0_CHECK(ctx->kscrexist & (1 << sel));
7879            tcg_gen_ld_tl(arg, cpu_env,
7880                          offsetof(CPUMIPSState, CP0_KScratch[sel - 2]));
7881            register_name = "KScratch";
7882            break;
7883        default:
7884            goto cp0_unimplemented;
7885        }
7886        break;
7887    default:
7888        goto cp0_unimplemented;
7889    }
7890    trace_mips_translate_c0("dmfc0", register_name, reg, sel);
7891    return;
7892
7893cp0_unimplemented:
7894    qemu_log_mask(LOG_UNIMP, "dmfc0 %s (reg %d sel %d)\n",
7895                  register_name, reg, sel);
7896    gen_mfc0_unimplemented(ctx, arg);
7897}
7898
7899static void gen_dmtc0(DisasContext *ctx, TCGv arg, int reg, int sel)
7900{
7901    const char *register_name = "invalid";
7902
7903    if (sel != 0) {
7904        check_insn(ctx, ISA_MIPS_R1);
7905    }
7906
7907    if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
7908        gen_io_start();
7909    }
7910
7911    switch (reg) {
7912    case CP0_REGISTER_00:
7913        switch (sel) {
7914        case CP0_REG00__INDEX:
7915            gen_helper_mtc0_index(cpu_env, arg);
7916            register_name = "Index";
7917            break;
7918        case CP0_REG00__MVPCONTROL:
7919            CP0_CHECK(ctx->insn_flags & ASE_MT);
7920            gen_helper_mtc0_mvpcontrol(cpu_env, arg);
7921            register_name = "MVPControl";
7922            break;
7923        case CP0_REG00__MVPCONF0:
7924            CP0_CHECK(ctx->insn_flags & ASE_MT);
7925            /* ignored */
7926            register_name = "MVPConf0";
7927            break;
7928        case CP0_REG00__MVPCONF1:
7929            CP0_CHECK(ctx->insn_flags & ASE_MT);
7930            /* ignored */
7931            register_name = "MVPConf1";
7932            break;
7933        case CP0_REG00__VPCONTROL:
7934            CP0_CHECK(ctx->vp);
7935            /* ignored */
7936            register_name = "VPControl";
7937            break;
7938        default:
7939            goto cp0_unimplemented;
7940        }
7941        break;
7942    case CP0_REGISTER_01:
7943        switch (sel) {
7944        case CP0_REG01__RANDOM:
7945            /* ignored */
7946            register_name = "Random";
7947            break;
7948        case CP0_REG01__VPECONTROL:
7949            CP0_CHECK(ctx->insn_flags & ASE_MT);
7950            gen_helper_mtc0_vpecontrol(cpu_env, arg);
7951            register_name = "VPEControl";
7952            break;
7953        case CP0_REG01__VPECONF0:
7954            CP0_CHECK(ctx->insn_flags & ASE_MT);
7955            gen_helper_mtc0_vpeconf0(cpu_env, arg);
7956            register_name = "VPEConf0";
7957            break;
7958        case CP0_REG01__VPECONF1:
7959            CP0_CHECK(ctx->insn_flags & ASE_MT);
7960            gen_helper_mtc0_vpeconf1(cpu_env, arg);
7961            register_name = "VPEConf1";
7962            break;
7963        case CP0_REG01__YQMASK:
7964            CP0_CHECK(ctx->insn_flags & ASE_MT);
7965            gen_helper_mtc0_yqmask(cpu_env, arg);
7966            register_name = "YQMask";
7967            break;
7968        case CP0_REG01__VPESCHEDULE:
7969            CP0_CHECK(ctx->insn_flags & ASE_MT);
7970            tcg_gen_st_tl(arg, cpu_env,
7971                          offsetof(CPUMIPSState, CP0_VPESchedule));
7972            register_name = "VPESchedule";
7973            break;
7974        case CP0_REG01__VPESCHEFBACK:
7975            CP0_CHECK(ctx->insn_flags & ASE_MT);
7976            tcg_gen_st_tl(arg, cpu_env,
7977                          offsetof(CPUMIPSState, CP0_VPEScheFBack));
7978            register_name = "VPEScheFBack";
7979            break;
7980        case CP0_REG01__VPEOPT:
7981            CP0_CHECK(ctx->insn_flags & ASE_MT);
7982            gen_helper_mtc0_vpeopt(cpu_env, arg);
7983            register_name = "VPEOpt";
7984            break;
7985        default:
7986            goto cp0_unimplemented;
7987        }
7988        break;
7989    case CP0_REGISTER_02:
7990        switch (sel) {
7991        case CP0_REG02__ENTRYLO0:
7992            gen_helper_dmtc0_entrylo0(cpu_env, arg);
7993            register_name = "EntryLo0";
7994            break;
7995        case CP0_REG02__TCSTATUS:
7996            CP0_CHECK(ctx->insn_flags & ASE_MT);
7997            gen_helper_mtc0_tcstatus(cpu_env, arg);
7998            register_name = "TCStatus";
7999            break;
8000        case CP0_REG02__TCBIND:
8001            CP0_CHECK(ctx->insn_flags & ASE_MT);
8002            gen_helper_mtc0_tcbind(cpu_env, arg);
8003            register_name = "TCBind";
8004            break;
8005        case CP0_REG02__TCRESTART:
8006            CP0_CHECK(ctx->insn_flags & ASE_MT);
8007            gen_helper_mtc0_tcrestart(cpu_env, arg);
8008            register_name = "TCRestart";
8009            break;
8010        case CP0_REG02__TCHALT:
8011            CP0_CHECK(ctx->insn_flags & ASE_MT);
8012            gen_helper_mtc0_tchalt(cpu_env, arg);
8013            register_name = "TCHalt";
8014            break;
8015        case CP0_REG02__TCCONTEXT:
8016            CP0_CHECK(ctx->insn_flags & ASE_MT);
8017            gen_helper_mtc0_tccontext(cpu_env, arg);
8018            register_name = "TCContext";
8019            break;
8020        case CP0_REG02__TCSCHEDULE:
8021            CP0_CHECK(ctx->insn_flags & ASE_MT);
8022            gen_helper_mtc0_tcschedule(cpu_env, arg);
8023            register_name = "TCSchedule";
8024            break;
8025        case CP0_REG02__TCSCHEFBACK:
8026            CP0_CHECK(ctx->insn_flags & ASE_MT);
8027            gen_helper_mtc0_tcschefback(cpu_env, arg);
8028            register_name = "TCScheFBack";
8029            break;
8030        default:
8031            goto cp0_unimplemented;
8032        }
8033        break;
8034    case CP0_REGISTER_03:
8035        switch (sel) {
8036        case CP0_REG03__ENTRYLO1:
8037            gen_helper_dmtc0_entrylo1(cpu_env, arg);
8038            register_name = "EntryLo1";
8039            break;
8040        case CP0_REG03__GLOBALNUM:
8041            CP0_CHECK(ctx->vp);
8042            /* ignored */
8043            register_name = "GlobalNumber";
8044            break;
8045        default:
8046            goto cp0_unimplemented;
8047        }
8048        break;
8049    case CP0_REGISTER_04:
8050        switch (sel) {
8051        case CP0_REG04__CONTEXT:
8052            gen_helper_mtc0_context(cpu_env, arg);
8053            register_name = "Context";
8054            break;
8055        case CP0_REG04__CONTEXTCONFIG:
8056            /* SmartMIPS ASE */
8057            /* gen_helper_dmtc0_contextconfig(arg); */
8058            register_name = "ContextConfig";
8059            goto cp0_unimplemented;
8060        case CP0_REG04__USERLOCAL:
8061            CP0_CHECK(ctx->ulri);
8062            tcg_gen_st_tl(arg, cpu_env,
8063                          offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
8064            register_name = "UserLocal";
8065            break;
8066        case CP0_REG04__MMID:
8067            CP0_CHECK(ctx->mi);
8068            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_MemoryMapID));
8069            register_name = "MMID";
8070            break;
8071        default:
8072            goto cp0_unimplemented;
8073        }
8074        break;
8075    case CP0_REGISTER_05:
8076        switch (sel) {
8077        case CP0_REG05__PAGEMASK:
8078            gen_helper_mtc0_pagemask(cpu_env, arg);
8079            register_name = "PageMask";
8080            break;
8081        case CP0_REG05__PAGEGRAIN:
8082            check_insn(ctx, ISA_MIPS_R2);
8083            gen_helper_mtc0_pagegrain(cpu_env, arg);
8084            register_name = "PageGrain";
8085            break;
8086        case CP0_REG05__SEGCTL0:
8087            CP0_CHECK(ctx->sc);
8088            gen_helper_mtc0_segctl0(cpu_env, arg);
8089            register_name = "SegCtl0";
8090            break;
8091        case CP0_REG05__SEGCTL1:
8092            CP0_CHECK(ctx->sc);
8093            gen_helper_mtc0_segctl1(cpu_env, arg);
8094            register_name = "SegCtl1";
8095            break;
8096        case CP0_REG05__SEGCTL2:
8097            CP0_CHECK(ctx->sc);
8098            gen_helper_mtc0_segctl2(cpu_env, arg);
8099            register_name = "SegCtl2";
8100            break;
8101        case CP0_REG05__PWBASE:
8102            check_pw(ctx);
8103            tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_PWBase));
8104            register_name = "PWBase";
8105            break;
8106        case CP0_REG05__PWFIELD:
8107            check_pw(ctx);
8108            gen_helper_mtc0_pwfield(cpu_env, arg);
8109            register_name = "PWField";
8110            break;
8111        case CP0_REG05__PWSIZE:
8112            check_pw(ctx);
8113            gen_helper_mtc0_pwsize(cpu_env, arg);
8114            register_name = "PWSize";
8115            break;
8116        default:
8117            goto cp0_unimplemented;
8118        }
8119        break;
8120    case CP0_REGISTER_06:
8121        switch (sel) {
8122        case CP0_REG06__WIRED:
8123            gen_helper_mtc0_wired(cpu_env, arg);
8124            register_name = "Wired";
8125            break;
8126        case CP0_REG06__SRSCONF0:
8127            check_insn(ctx, ISA_MIPS_R2);
8128            gen_helper_mtc0_srsconf0(cpu_env, arg);
8129            register_name = "SRSConf0";
8130            break;
8131        case CP0_REG06__SRSCONF1:
8132            check_insn(ctx, ISA_MIPS_R2);
8133            gen_helper_mtc0_srsconf1(cpu_env, arg);
8134            register_name = "SRSConf1";
8135            break;
8136        case CP0_REG06__SRSCONF2:
8137            check_insn(ctx, ISA_MIPS_R2);
8138            gen_helper_mtc0_srsconf2(cpu_env, arg);
8139            register_name = "SRSConf2";
8140            break;
8141        case CP0_REG06__SRSCONF3:
8142            check_insn(ctx, ISA_MIPS_R2);
8143            gen_helper_mtc0_srsconf3(cpu_env, arg);
8144            register_name = "SRSConf3";
8145            break;
8146        case CP0_REG06__SRSCONF4:
8147            check_insn(ctx, ISA_MIPS_R2);
8148            gen_helper_mtc0_srsconf4(cpu_env, arg);
8149            register_name = "SRSConf4";
8150            break;
8151        case CP0_REG06__PWCTL:
8152            check_pw(ctx);
8153            gen_helper_mtc0_pwctl(cpu_env, arg);
8154            register_name = "PWCtl";
8155            break;
8156        default:
8157            goto cp0_unimplemented;
8158        }
8159        break;
8160    case CP0_REGISTER_07:
8161        switch (sel) {
8162        case CP0_REG07__HWRENA:
8163            check_insn(ctx, ISA_MIPS_R2);
8164            gen_helper_mtc0_hwrena(cpu_env, arg);
8165            ctx->base.is_jmp = DISAS_STOP;
8166            register_name = "HWREna";
8167            break;
8168        default:
8169            goto cp0_unimplemented;
8170        }
8171        break;
8172    case CP0_REGISTER_08:
8173        switch (sel) {
8174        case CP0_REG08__BADVADDR:
8175            /* ignored */
8176            register_name = "BadVAddr";
8177            break;
8178        case CP0_REG08__BADINSTR:
8179            /* ignored */
8180            register_name = "BadInstr";
8181            break;
8182        case CP0_REG08__BADINSTRP:
8183            /* ignored */
8184            register_name = "BadInstrP";
8185            break;
8186        case CP0_REG08__BADINSTRX:
8187            /* ignored */
8188            register_name = "BadInstrX";
8189            break;
8190        default:
8191            goto cp0_unimplemented;
8192        }
8193        break;
8194    case CP0_REGISTER_09:
8195        switch (sel) {
8196        case CP0_REG09__COUNT:
8197            gen_helper_mtc0_count(cpu_env, arg);
8198            register_name = "Count";
8199            break;
8200        case CP0_REG09__SAARI:
8201            CP0_CHECK(ctx->saar);
8202            gen_helper_mtc0_saari(cpu_env, arg);
8203            register_name = "SAARI";
8204            break;
8205        case CP0_REG09__SAAR:
8206            CP0_CHECK(ctx->saar);
8207            gen_helper_mtc0_saar(cpu_env, arg);
8208            register_name = "SAAR";
8209            break;
8210        default:
8211            goto cp0_unimplemented;
8212        }
8213        /* Stop translation as we may have switched the execution mode */
8214        ctx->base.is_jmp = DISAS_STOP;
8215        break;
8216    case CP0_REGISTER_10:
8217        switch (sel) {
8218        case CP0_REG10__ENTRYHI:
8219            gen_helper_mtc0_entryhi(cpu_env, arg);
8220            register_name = "EntryHi";
8221            break;
8222        default:
8223            goto cp0_unimplemented;
8224        }
8225        break;
8226    case CP0_REGISTER_11:
8227        switch (sel) {
8228        case CP0_REG11__COMPARE:
8229            gen_helper_mtc0_compare(cpu_env, arg);
8230            register_name = "Compare";
8231            break;
8232        /* 6,7 are implementation dependent */
8233        default:
8234            goto cp0_unimplemented;
8235        }
8236        /* Stop translation as we may have switched the execution mode */
8237        ctx->base.is_jmp = DISAS_STOP;
8238        break;
8239    case CP0_REGISTER_12:
8240        switch (sel) {
8241        case CP0_REG12__STATUS:
8242            save_cpu_state(ctx, 1);
8243            gen_helper_mtc0_status(cpu_env, arg);
8244            /* DISAS_STOP isn't good enough here, hflags may have changed. */
8245            gen_save_pc(ctx->base.pc_next + 4);
8246            ctx->base.is_jmp = DISAS_EXIT;
8247            register_name = "Status";
8248            break;
8249        case CP0_REG12__INTCTL:
8250            check_insn(ctx, ISA_MIPS_R2);
8251            gen_helper_mtc0_intctl(cpu_env, arg);
8252            /* Stop translation as we may have switched the execution mode */
8253            ctx->base.is_jmp = DISAS_STOP;
8254            register_name = "IntCtl";
8255            break;
8256        case CP0_REG12__SRSCTL:
8257            check_insn(ctx, ISA_MIPS_R2);
8258            gen_helper_mtc0_srsctl(cpu_env, arg);
8259            /* Stop translation as we may have switched the execution mode */
8260            ctx->base.is_jmp = DISAS_STOP;
8261            register_name = "SRSCtl";
8262            break;
8263        case CP0_REG12__SRSMAP:
8264            check_insn(ctx, ISA_MIPS_R2);
8265            gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_SRSMap));
8266            /* Stop translation as we may have switched the execution mode */
8267            ctx->base.is_jmp = DISAS_STOP;
8268            register_name = "SRSMap";
8269            break;
8270        default:
8271            goto cp0_unimplemented;
8272        }
8273        break;
8274    case CP0_REGISTER_13:
8275        switch (sel) {
8276        case CP0_REG13__CAUSE:
8277            save_cpu_state(ctx, 1);
8278            gen_helper_mtc0_cause(cpu_env, arg);
8279            /*
8280             * Stop translation as we may have triggered an interrupt.
8281             * DISAS_STOP isn't sufficient, we need to ensure we break out of
8282             * translated code to check for pending interrupts.
8283             */
8284            gen_save_pc(ctx->base.pc_next + 4);
8285            ctx->base.is_jmp = DISAS_EXIT;
8286            register_name = "Cause";
8287            break;
8288        default:
8289            goto cp0_unimplemented;
8290        }
8291        break;
8292    case CP0_REGISTER_14:
8293        switch (sel) {
8294        case CP0_REG14__EPC:
8295            tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EPC));
8296            register_name = "EPC";
8297            break;
8298        default:
8299            goto cp0_unimplemented;
8300        }
8301        break;
8302    case CP0_REGISTER_15:
8303        switch (sel) {
8304        case CP0_REG15__PRID:
8305            /* ignored */
8306            register_name = "PRid";
8307            break;
8308        case CP0_REG15__EBASE:
8309            check_insn(ctx, ISA_MIPS_R2);
8310            gen_helper_mtc0_ebase(cpu_env, arg);
8311            register_name = "EBase";
8312            break;
8313        default:
8314            goto cp0_unimplemented;
8315        }
8316        break;
8317    case CP0_REGISTER_16:
8318        switch (sel) {
8319        case CP0_REG16__CONFIG:
8320            gen_helper_mtc0_config0(cpu_env, arg);
8321            register_name = "Config";
8322            /* Stop translation as we may have switched the execution mode */
8323            ctx->base.is_jmp = DISAS_STOP;
8324            break;
8325        case CP0_REG16__CONFIG1:
8326            /* ignored, read only */
8327            register_name = "Config1";
8328            break;
8329        case CP0_REG16__CONFIG2:
8330            gen_helper_mtc0_config2(cpu_env, arg);
8331            register_name = "Config2";
8332            /* Stop translation as we may have switched the execution mode */
8333            ctx->base.is_jmp = DISAS_STOP;
8334            break;
8335        case CP0_REG16__CONFIG3:
8336            gen_helper_mtc0_config3(cpu_env, arg);
8337            register_name = "Config3";
8338            /* Stop translation as we may have switched the execution mode */
8339            ctx->base.is_jmp = DISAS_STOP;
8340            break;
8341        case CP0_REG16__CONFIG4:
8342            /* currently ignored */
8343            register_name = "Config4";
8344            break;
8345        case CP0_REG16__CONFIG5:
8346            gen_helper_mtc0_config5(cpu_env, arg);
8347            register_name = "Config5";
8348            /* Stop translation as we may have switched the execution mode */
8349            ctx->base.is_jmp = DISAS_STOP;
8350            break;
8351        /* 6,7 are implementation dependent */
8352        default:
8353            register_name = "Invalid config selector";
8354            goto cp0_unimplemented;
8355        }
8356        break;
8357    case CP0_REGISTER_17:
8358        switch (sel) {
8359        case CP0_REG17__LLADDR:
8360            gen_helper_mtc0_lladdr(cpu_env, arg);
8361            register_name = "LLAddr";
8362            break;
8363        case CP0_REG17__MAAR:
8364            CP0_CHECK(ctx->mrp);
8365            gen_helper_mtc0_maar(cpu_env, arg);
8366            register_name = "MAAR";
8367            break;
8368        case CP0_REG17__MAARI:
8369            CP0_CHECK(ctx->mrp);
8370            gen_helper_mtc0_maari(cpu_env, arg);
8371            register_name = "MAARI";
8372            break;
8373        default:
8374            goto cp0_unimplemented;
8375        }
8376        break;
8377    case CP0_REGISTER_18:
8378        switch (sel) {
8379        case CP0_REG18__WATCHLO0:
8380        case CP0_REG18__WATCHLO1:
8381        case CP0_REG18__WATCHLO2:
8382        case CP0_REG18__WATCHLO3:
8383        case CP0_REG18__WATCHLO4:
8384        case CP0_REG18__WATCHLO5:
8385        case CP0_REG18__WATCHLO6:
8386        case CP0_REG18__WATCHLO7:
8387            CP0_CHECK(ctx->CP0_Config1 & (1 << CP0C1_WR));
8388            gen_helper_0e1i(mtc0_watchlo, arg, sel);
8389            register_name = "WatchLo";
8390            break;
8391        default:
8392            goto cp0_unimplemented;
8393        }
8394        break;
8395    case CP0_REGISTER_19:
8396        switch (sel) {
8397        case CP0_REG19__WATCHHI0:
8398        case CP0_REG19__WATCHHI1:
8399        case CP0_REG19__WATCHHI2:
8400        case CP0_REG19__WATCHHI3:
8401        case CP0_REG19__WATCHHI4:
8402        case CP0_REG19__WATCHHI5:
8403        case CP0_REG19__WATCHHI6:
8404        case CP0_REG19__WATCHHI7:
8405            CP0_CHECK(ctx->CP0_Config1 & (1 << CP0C1_WR));
8406            gen_helper_0e1i(mtc0_watchhi, arg, sel);
8407            register_name = "WatchHi";
8408            break;
8409        default:
8410            goto cp0_unimplemented;
8411        }
8412        break;
8413    case CP0_REGISTER_20:
8414        switch (sel) {
8415        case CP0_REG20__XCONTEXT:
8416            check_insn(ctx, ISA_MIPS3);
8417            gen_helper_mtc0_xcontext(cpu_env, arg);
8418            register_name = "XContext";
8419            break;
8420        default:
8421            goto cp0_unimplemented;
8422        }
8423        break;
8424    case CP0_REGISTER_21:
8425       /* Officially reserved, but sel 0 is used for R1x000 framemask */
8426        CP0_CHECK(!(ctx->insn_flags & ISA_MIPS_R6));
8427        switch (sel) {
8428        case 0:
8429            gen_helper_mtc0_framemask(cpu_env, arg);
8430            register_name = "Framemask";
8431            break;
8432        default:
8433            goto cp0_unimplemented;
8434        }
8435        break;
8436    case CP0_REGISTER_22:
8437        /* ignored */
8438        register_name = "Diagnostic"; /* implementation dependent */
8439        break;
8440    case CP0_REGISTER_23:
8441        switch (sel) {
8442        case CP0_REG23__DEBUG:
8443            gen_helper_mtc0_debug(cpu_env, arg); /* EJTAG support */
8444            /* DISAS_STOP isn't good enough here, hflags may have changed. */
8445            gen_save_pc(ctx->base.pc_next + 4);
8446            ctx->base.is_jmp = DISAS_EXIT;
8447            register_name = "Debug";
8448            break;
8449        case CP0_REG23__TRACECONTROL:
8450            /* PDtrace support */
8451            /* gen_helper_mtc0_tracecontrol(cpu_env, arg);  */
8452            /* Stop translation as we may have switched the execution mode */
8453            ctx->base.is_jmp = DISAS_STOP;
8454            register_name = "TraceControl";
8455            goto cp0_unimplemented;
8456        case CP0_REG23__TRACECONTROL2:
8457            /* PDtrace support */
8458            /* gen_helper_mtc0_tracecontrol2(cpu_env, arg); */
8459            /* Stop translation as we may have switched the execution mode */
8460            ctx->base.is_jmp = DISAS_STOP;
8461            register_name = "TraceControl2";
8462            goto cp0_unimplemented;
8463        case CP0_REG23__USERTRACEDATA1:
8464            /* PDtrace support */
8465            /* gen_helper_mtc0_usertracedata1(cpu_env, arg);*/
8466            /* Stop translation as we may have switched the execution mode */
8467            ctx->base.is_jmp = DISAS_STOP;
8468            register_name = "UserTraceData1";
8469            goto cp0_unimplemented;
8470        case CP0_REG23__TRACEIBPC:
8471            /* PDtrace support */
8472            /* gen_helper_mtc0_traceibpc(cpu_env, arg);     */
8473            /* Stop translation as we may have switched the execution mode */
8474            ctx->base.is_jmp = DISAS_STOP;
8475            register_name = "TraceIBPC";
8476            goto cp0_unimplemented;
8477        case CP0_REG23__TRACEDBPC:
8478            /* PDtrace support */
8479            /* gen_helper_mtc0_tracedbpc(cpu_env, arg);     */
8480            /* Stop translation as we may have switched the execution mode */
8481            ctx->base.is_jmp = DISAS_STOP;
8482            register_name = "TraceDBPC";
8483            goto cp0_unimplemented;
8484        default:
8485            goto cp0_unimplemented;
8486        }
8487        break;
8488    case CP0_REGISTER_24:
8489        switch (sel) {
8490        case CP0_REG24__DEPC:
8491            /* EJTAG support */
8492            tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_DEPC));
8493            register_name = "DEPC";
8494            break;
8495        default:
8496            goto cp0_unimplemented;
8497        }
8498        break;
8499    case CP0_REGISTER_25:
8500        switch (sel) {
8501        case CP0_REG25__PERFCTL0:
8502            gen_helper_mtc0_performance0(cpu_env, arg);
8503            register_name = "Performance0";
8504            break;
8505        case CP0_REG25__PERFCNT0:
8506            /* gen_helper_mtc0_performance1(cpu_env, arg); */
8507            register_name = "Performance1";
8508            goto cp0_unimplemented;
8509        case CP0_REG25__PERFCTL1:
8510            /* gen_helper_mtc0_performance2(cpu_env, arg); */
8511            register_name = "Performance2";
8512            goto cp0_unimplemented;
8513        case CP0_REG25__PERFCNT1:
8514            /* gen_helper_mtc0_performance3(cpu_env, arg); */
8515            register_name = "Performance3";
8516            goto cp0_unimplemented;
8517        case CP0_REG25__PERFCTL2:
8518            /* gen_helper_mtc0_performance4(cpu_env, arg); */
8519            register_name = "Performance4";
8520            goto cp0_unimplemented;
8521        case CP0_REG25__PERFCNT2:
8522            /* gen_helper_mtc0_performance5(cpu_env, arg); */
8523            register_name = "Performance5";
8524            goto cp0_unimplemented;
8525        case CP0_REG25__PERFCTL3:
8526            /* gen_helper_mtc0_performance6(cpu_env, arg); */
8527            register_name = "Performance6";
8528            goto cp0_unimplemented;
8529        case CP0_REG25__PERFCNT3:
8530            /* gen_helper_mtc0_performance7(cpu_env, arg); */
8531            register_name = "Performance7";
8532            goto cp0_unimplemented;
8533        default:
8534            goto cp0_unimplemented;
8535        }
8536        break;
8537    case CP0_REGISTER_26:
8538        switch (sel) {
8539        case CP0_REG26__ERRCTL:
8540            gen_helper_mtc0_errctl(cpu_env, arg);
8541            ctx->base.is_jmp = DISAS_STOP;
8542            register_name = "ErrCtl";
8543            break;
8544        default:
8545            goto cp0_unimplemented;
8546        }
8547        break;
8548    case CP0_REGISTER_27:
8549        switch (sel) {
8550        case CP0_REG27__CACHERR:
8551            /* ignored */
8552            register_name = "CacheErr";
8553            break;
8554        default:
8555            goto cp0_unimplemented;
8556        }
8557        break;
8558    case CP0_REGISTER_28:
8559        switch (sel) {
8560        case CP0_REG28__TAGLO:
8561        case CP0_REG28__TAGLO1:
8562        case CP0_REG28__TAGLO2:
8563        case CP0_REG28__TAGLO3:
8564            gen_helper_mtc0_taglo(cpu_env, arg);
8565            register_name = "TagLo";
8566            break;
8567        case CP0_REG28__DATALO:
8568        case CP0_REG28__DATALO1:
8569        case CP0_REG28__DATALO2:
8570        case CP0_REG28__DATALO3:
8571            gen_helper_mtc0_datalo(cpu_env, arg);
8572            register_name = "DataLo";
8573            break;
8574        default:
8575            goto cp0_unimplemented;
8576        }
8577        break;
8578    case CP0_REGISTER_29:
8579        switch (sel) {
8580        case CP0_REG29__TAGHI:
8581        case CP0_REG29__TAGHI1:
8582        case CP0_REG29__TAGHI2:
8583        case CP0_REG29__TAGHI3:
8584            gen_helper_mtc0_taghi(cpu_env, arg);
8585            register_name = "TagHi";
8586            break;
8587        case CP0_REG29__DATAHI:
8588        case CP0_REG29__DATAHI1:
8589        case CP0_REG29__DATAHI2:
8590        case CP0_REG29__DATAHI3:
8591            gen_helper_mtc0_datahi(cpu_env, arg);
8592            register_name = "DataHi";
8593            break;
8594        default:
8595            register_name = "invalid sel";
8596            goto cp0_unimplemented;
8597        }
8598        break;
8599    case CP0_REGISTER_30:
8600        switch (sel) {
8601        case CP0_REG30__ERROREPC:
8602            tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_ErrorEPC));
8603            register_name = "ErrorEPC";
8604            break;
8605        default:
8606            goto cp0_unimplemented;
8607        }
8608        break;
8609    case CP0_REGISTER_31:
8610        switch (sel) {
8611        case CP0_REG31__DESAVE:
8612            /* EJTAG support */
8613            gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_DESAVE));
8614            register_name = "DESAVE";
8615            break;
8616        case CP0_REG31__KSCRATCH1:
8617        case CP0_REG31__KSCRATCH2:
8618        case CP0_REG31__KSCRATCH3:
8619        case CP0_REG31__KSCRATCH4:
8620        case CP0_REG31__KSCRATCH5:
8621        case CP0_REG31__KSCRATCH6:
8622            CP0_CHECK(ctx->kscrexist & (1 << sel));
8623            tcg_gen_st_tl(arg, cpu_env,
8624                          offsetof(CPUMIPSState, CP0_KScratch[sel - 2]));
8625            register_name = "KScratch";
8626            break;
8627        default:
8628            goto cp0_unimplemented;
8629        }
8630        break;
8631    default:
8632        goto cp0_unimplemented;
8633    }
8634    trace_mips_translate_c0("dmtc0", register_name, reg, sel);
8635
8636    /* For simplicity assume that all writes can cause interrupts.  */
8637    if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
8638        /*
8639         * DISAS_STOP isn't sufficient, we need to ensure we break out of
8640         * translated code to check for pending interrupts.
8641         */
8642        gen_save_pc(ctx->base.pc_next + 4);
8643        ctx->base.is_jmp = DISAS_EXIT;
8644    }
8645    return;
8646
8647cp0_unimplemented:
8648    qemu_log_mask(LOG_UNIMP, "dmtc0 %s (reg %d sel %d)\n",
8649                  register_name, reg, sel);
8650}
8651#endif /* TARGET_MIPS64 */
8652
8653static void gen_mftr(CPUMIPSState *env, DisasContext *ctx, int rt, int rd,
8654                     int u, int sel, int h)
8655{
8656    int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
8657    TCGv t0 = tcg_temp_local_new();
8658
8659    if ((env->CP0_VPEConf0 & (1 << CP0VPEC0_MVP)) == 0 &&
8660        ((env->tcs[other_tc].CP0_TCBind & (0xf << CP0TCBd_CurVPE)) !=
8661         (env->active_tc.CP0_TCBind & (0xf << CP0TCBd_CurVPE)))) {
8662        tcg_gen_movi_tl(t0, -1);
8663    } else if ((env->CP0_VPEControl & (0xff << CP0VPECo_TargTC)) >
8664               (env->mvp->CP0_MVPConf0 & (0xff << CP0MVPC0_PTC))) {
8665        tcg_gen_movi_tl(t0, -1);
8666    } else if (u == 0) {
8667        switch (rt) {
8668        case 1:
8669            switch (sel) {
8670            case 1:
8671                gen_helper_mftc0_vpecontrol(t0, cpu_env);
8672                break;
8673            case 2:
8674                gen_helper_mftc0_vpeconf0(t0, cpu_env);
8675                break;
8676            default:
8677                goto die;
8678                break;
8679            }
8680            break;
8681        case 2:
8682            switch (sel) {
8683            case 1:
8684                gen_helper_mftc0_tcstatus(t0, cpu_env);
8685                break;
8686            case 2:
8687                gen_helper_mftc0_tcbind(t0, cpu_env);
8688                break;
8689            case 3:
8690                gen_helper_mftc0_tcrestart(t0, cpu_env);
8691                break;
8692            case 4:
8693                gen_helper_mftc0_tchalt(t0, cpu_env);
8694                break;
8695            case 5:
8696                gen_helper_mftc0_tccontext(t0, cpu_env);
8697                break;
8698            case 6:
8699                gen_helper_mftc0_tcschedule(t0, cpu_env);
8700                break;
8701            case 7:
8702                gen_helper_mftc0_tcschefback(t0, cpu_env);
8703                break;
8704            default:
8705                gen_mfc0(ctx, t0, rt, sel);
8706                break;
8707            }
8708            break;
8709        case 10:
8710            switch (sel) {
8711            case 0:
8712                gen_helper_mftc0_entryhi(t0, cpu_env);
8713                break;
8714            default:
8715                gen_mfc0(ctx, t0, rt, sel);
8716                break;
8717            }
8718            break;
8719        case 12:
8720            switch (sel) {
8721            case 0:
8722                gen_helper_mftc0_status(t0, cpu_env);
8723                break;
8724            default:
8725                gen_mfc0(ctx, t0, rt, sel);
8726                break;
8727            }
8728            break;
8729        case 13:
8730            switch (sel) {
8731            case 0:
8732                gen_helper_mftc0_cause(t0, cpu_env);
8733                break;
8734            default:
8735                goto die;
8736                break;
8737            }
8738            break;
8739        case 14:
8740            switch (sel) {
8741            case 0:
8742                gen_helper_mftc0_epc(t0, cpu_env);
8743                break;
8744            default:
8745                goto die;
8746                break;
8747            }
8748            break;
8749        case 15:
8750            switch (sel) {
8751            case 1:
8752                gen_helper_mftc0_ebase(t0, cpu_env);
8753                break;
8754            default:
8755                goto die;
8756                break;
8757            }
8758            break;
8759        case 16:
8760            switch (sel) {
8761            case 0:
8762            case 1:
8763            case 2:
8764            case 3:
8765            case 4:
8766            case 5:
8767            case 6:
8768            case 7:
8769                gen_helper_mftc0_configx(t0, cpu_env, tcg_const_tl(sel));
8770                break;
8771            default:
8772                goto die;
8773                break;
8774            }
8775            break;
8776        case 23:
8777            switch (sel) {
8778            case 0:
8779                gen_helper_mftc0_debug(t0, cpu_env);
8780                break;
8781            default:
8782                gen_mfc0(ctx, t0, rt, sel);
8783                break;
8784            }
8785            break;
8786        default:
8787            gen_mfc0(ctx, t0, rt, sel);
8788        }
8789    } else {
8790        switch (sel) {
8791        /* GPR registers. */
8792        case 0:
8793            gen_helper_1e0i(mftgpr, t0, rt);
8794            break;
8795        /* Auxiliary CPU registers */
8796        case 1:
8797            switch (rt) {
8798            case 0:
8799                gen_helper_1e0i(mftlo, t0, 0);
8800                break;
8801            case 1:
8802                gen_helper_1e0i(mfthi, t0, 0);
8803                break;
8804            case 2:
8805                gen_helper_1e0i(mftacx, t0, 0);
8806                break;
8807            case 4:
8808                gen_helper_1e0i(mftlo, t0, 1);
8809                break;
8810            case 5:
8811                gen_helper_1e0i(mfthi, t0, 1);
8812                break;
8813            case 6:
8814                gen_helper_1e0i(mftacx, t0, 1);
8815                break;
8816            case 8:
8817                gen_helper_1e0i(mftlo, t0, 2);
8818                break;
8819            case 9:
8820                gen_helper_1e0i(mfthi, t0, 2);
8821                break;
8822            case 10:
8823                gen_helper_1e0i(mftacx, t0, 2);
8824                break;
8825            case 12:
8826                gen_helper_1e0i(mftlo, t0, 3);
8827                break;
8828            case 13:
8829                gen_helper_1e0i(mfthi, t0, 3);
8830                break;
8831            case 14:
8832                gen_helper_1e0i(mftacx, t0, 3);
8833                break;
8834            case 16:
8835                gen_helper_mftdsp(t0, cpu_env);
8836                break;
8837            default:
8838                goto die;
8839            }
8840            break;
8841        /* Floating point (COP1). */
8842        case 2:
8843            /* XXX: For now we support only a single FPU context. */
8844            if (h == 0) {
8845                TCGv_i32 fp0 = tcg_temp_new_i32();
8846
8847                gen_load_fpr32(ctx, fp0, rt);
8848                tcg_gen_ext_i32_tl(t0, fp0);
8849                tcg_temp_free_i32(fp0);
8850            } else {
8851                TCGv_i32 fp0 = tcg_temp_new_i32();
8852
8853                gen_load_fpr32h(ctx, fp0, rt);
8854                tcg_gen_ext_i32_tl(t0, fp0);
8855                tcg_temp_free_i32(fp0);
8856            }
8857            break;
8858        case 3:
8859            /* XXX: For now we support only a single FPU context. */
8860            gen_helper_1e0i(cfc1, t0, rt);
8861            break;
8862        /* COP2: Not implemented. */
8863        case 4:
8864        case 5:
8865            /* fall through */
8866        default:
8867            goto die;
8868        }
8869    }
8870    trace_mips_translate_tr("mftr", rt, u, sel, h);
8871    gen_store_gpr(t0, rd);
8872    tcg_temp_free(t0);
8873    return;
8874
8875die:
8876    tcg_temp_free(t0);
8877    LOG_DISAS("mftr (reg %d u %d sel %d h %d)\n", rt, u, sel, h);
8878    gen_reserved_instruction(ctx);
8879}
8880
8881static void gen_mttr(CPUMIPSState *env, DisasContext *ctx, int rd, int rt,
8882                     int u, int sel, int h)
8883{
8884    int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
8885    TCGv t0 = tcg_temp_local_new();
8886
8887    gen_load_gpr(t0, rt);
8888    if ((env->CP0_VPEConf0 & (1 << CP0VPEC0_MVP)) == 0 &&
8889        ((env->tcs[other_tc].CP0_TCBind & (0xf << CP0TCBd_CurVPE)) !=
8890         (env->active_tc.CP0_TCBind & (0xf << CP0TCBd_CurVPE)))) {
8891        /* NOP */
8892        ;
8893    } else if ((env->CP0_VPEControl & (0xff << CP0VPECo_TargTC)) >
8894             (env->mvp->CP0_MVPConf0 & (0xff << CP0MVPC0_PTC))) {
8895        /* NOP */
8896        ;
8897    } else if (u == 0) {
8898        switch (rd) {
8899        case 1:
8900            switch (sel) {
8901            case 1:
8902                gen_helper_mttc0_vpecontrol(cpu_env, t0);
8903                break;
8904            case 2:
8905                gen_helper_mttc0_vpeconf0(cpu_env, t0);
8906                break;
8907            default:
8908                goto die;
8909                break;
8910            }
8911            break;
8912        case 2:
8913            switch (sel) {
8914            case 1:
8915                gen_helper_mttc0_tcstatus(cpu_env, t0);
8916                break;
8917            case 2:
8918                gen_helper_mttc0_tcbind(cpu_env, t0);
8919                break;
8920            case 3:
8921                gen_helper_mttc0_tcrestart(cpu_env, t0);
8922                break;
8923            case 4:
8924                gen_helper_mttc0_tchalt(cpu_env, t0);
8925                break;
8926            case 5:
8927                gen_helper_mttc0_tccontext(cpu_env, t0);
8928                break;
8929            case 6:
8930                gen_helper_mttc0_tcschedule(cpu_env, t0);
8931                break;
8932            case 7:
8933                gen_helper_mttc0_tcschefback(cpu_env, t0);
8934                break;
8935            default:
8936                gen_mtc0(ctx, t0, rd, sel);
8937                break;
8938            }
8939            break;
8940        case 10:
8941            switch (sel) {
8942            case 0:
8943                gen_helper_mttc0_entryhi(cpu_env, t0);
8944                break;
8945            default:
8946                gen_mtc0(ctx, t0, rd, sel);
8947                break;
8948            }
8949            break;
8950        case 12:
8951            switch (sel) {
8952            case 0:
8953                gen_helper_mttc0_status(cpu_env, t0);
8954                break;
8955            default:
8956                gen_mtc0(ctx, t0, rd, sel);
8957                break;
8958            }
8959            break;
8960        case 13:
8961            switch (sel) {
8962            case 0:
8963                gen_helper_mttc0_cause(cpu_env, t0);
8964                break;
8965            default:
8966                goto die;
8967                break;
8968            }
8969            break;
8970        case 15:
8971            switch (sel) {
8972            case 1:
8973                gen_helper_mttc0_ebase(cpu_env, t0);
8974                break;
8975            default:
8976                goto die;
8977                break;
8978            }
8979            break;
8980        case 23:
8981            switch (sel) {
8982            case 0:
8983                gen_helper_mttc0_debug(cpu_env, t0);
8984                break;
8985            default:
8986                gen_mtc0(ctx, t0, rd, sel);
8987                break;
8988            }
8989            break;
8990        default:
8991            gen_mtc0(ctx, t0, rd, sel);
8992        }
8993    } else {
8994        switch (sel) {
8995        /* GPR registers. */
8996        case 0:
8997            gen_helper_0e1i(mttgpr, t0, rd);
8998            break;
8999        /* Auxiliary CPU registers */
9000        case 1:
9001            switch (rd) {
9002            case 0:
9003                gen_helper_0e1i(mttlo, t0, 0);
9004                break;
9005            case 1:
9006                gen_helper_0e1i(mtthi, t0, 0);
9007                break;
9008            case 2:
9009                gen_helper_0e1i(mttacx, t0, 0);
9010                break;
9011            case 4:
9012                gen_helper_0e1i(mttlo, t0, 1);
9013                break;
9014            case 5:
9015                gen_helper_0e1i(mtthi, t0, 1);
9016                break;
9017            case 6:
9018                gen_helper_0e1i(mttacx, t0, 1);
9019                break;
9020            case 8:
9021                gen_helper_0e1i(mttlo, t0, 2);
9022                break;
9023            case 9:
9024                gen_helper_0e1i(mtthi, t0, 2);
9025                break;
9026            case 10:
9027                gen_helper_0e1i(mttacx, t0, 2);
9028                break;
9029            case 12:
9030                gen_helper_0e1i(mttlo, t0, 3);
9031                break;
9032            case 13:
9033                gen_helper_0e1i(mtthi, t0, 3);
9034                break;
9035            case 14:
9036                gen_helper_0e1i(mttacx, t0, 3);
9037                break;
9038            case 16:
9039                gen_helper_mttdsp(cpu_env, t0);
9040                break;
9041            default:
9042                goto die;
9043            }
9044            break;
9045        /* Floating point (COP1). */
9046        case 2:
9047            /* XXX: For now we support only a single FPU context. */
9048            if (h == 0) {
9049                TCGv_i32 fp0 = tcg_temp_new_i32();
9050
9051                tcg_gen_trunc_tl_i32(fp0, t0);
9052                gen_store_fpr32(ctx, fp0, rd);
9053                tcg_temp_free_i32(fp0);
9054            } else {
9055                TCGv_i32 fp0 = tcg_temp_new_i32();
9056
9057                tcg_gen_trunc_tl_i32(fp0, t0);
9058                gen_store_fpr32h(ctx, fp0, rd);
9059                tcg_temp_free_i32(fp0);
9060            }
9061            break;
9062        case 3:
9063            /* XXX: For now we support only a single FPU context. */
9064            gen_helper_0e2i(ctc1, t0, tcg_constant_i32(rd), rt);
9065            /* Stop translation as we may have changed hflags */
9066            ctx->base.is_jmp = DISAS_STOP;
9067            break;
9068        /* COP2: Not implemented. */
9069        case 4:
9070        case 5:
9071            /* fall through */
9072        default:
9073            goto die;
9074        }
9075    }
9076    trace_mips_translate_tr("mttr", rd, u, sel, h);
9077    tcg_temp_free(t0);
9078    return;
9079
9080die:
9081    tcg_temp_free(t0);
9082    LOG_DISAS("mttr (reg %d u %d sel %d h %d)\n", rd, u, sel, h);
9083    gen_reserved_instruction(ctx);
9084}
9085
9086static void gen_cp0(CPUMIPSState *env, DisasContext *ctx, uint32_t opc,
9087                    int rt, int rd)
9088{
9089    const char *opn = "ldst";
9090
9091    check_cp0_enabled(ctx);
9092    switch (opc) {
9093    case OPC_MFC0:
9094        if (rt == 0) {
9095            /* Treat as NOP. */
9096            return;
9097        }
9098        gen_mfc0(ctx, cpu_gpr[rt], rd, ctx->opcode & 0x7);
9099        opn = "mfc0";
9100        break;
9101    case OPC_MTC0:
9102        {
9103            TCGv t0 = tcg_temp_new();
9104
9105            gen_load_gpr(t0, rt);
9106            gen_mtc0(ctx, t0, rd, ctx->opcode & 0x7);
9107            tcg_temp_free(t0);
9108        }
9109        opn = "mtc0";
9110        break;
9111#if defined(TARGET_MIPS64)
9112    case OPC_DMFC0:
9113        check_insn(ctx, ISA_MIPS3);
9114        if (rt == 0) {
9115            /* Treat as NOP. */
9116            return;
9117        }
9118        gen_dmfc0(ctx, cpu_gpr[rt], rd, ctx->opcode & 0x7);
9119        opn = "dmfc0";
9120        break;
9121    case OPC_DMTC0:
9122        check_insn(ctx, ISA_MIPS3);
9123        {
9124            TCGv t0 = tcg_temp_new();
9125
9126            gen_load_gpr(t0, rt);
9127            gen_dmtc0(ctx, t0, rd, ctx->opcode & 0x7);
9128            tcg_temp_free(t0);
9129        }
9130        opn = "dmtc0";
9131        break;
9132#endif
9133    case OPC_MFHC0:
9134        check_mvh(ctx);
9135        if (rt == 0) {
9136            /* Treat as NOP. */
9137            return;
9138        }
9139        gen_mfhc0(ctx, cpu_gpr[rt], rd, ctx->opcode & 0x7);
9140        opn = "mfhc0";
9141        break;
9142    case OPC_MTHC0:
9143        check_mvh(ctx);
9144        {
9145            TCGv t0 = tcg_temp_new();
9146            gen_load_gpr(t0, rt);
9147            gen_mthc0(ctx, t0, rd, ctx->opcode & 0x7);
9148            tcg_temp_free(t0);
9149        }
9150        opn = "mthc0";
9151        break;
9152    case OPC_MFTR:
9153        check_cp0_enabled(ctx);
9154        if (rd == 0) {
9155            /* Treat as NOP. */
9156            return;
9157        }
9158        gen_mftr(env, ctx, rt, rd, (ctx->opcode >> 5) & 1,
9159                 ctx->opcode & 0x7, (ctx->opcode >> 4) & 1);
9160        opn = "mftr";
9161        break;
9162    case OPC_MTTR:
9163        check_cp0_enabled(ctx);
9164        gen_mttr(env, ctx, rd, rt, (ctx->opcode >> 5) & 1,
9165                 ctx->opcode & 0x7, (ctx->opcode >> 4) & 1);
9166        opn = "mttr";
9167        break;
9168    case OPC_TLBWI:
9169        opn = "tlbwi";
9170        if (!env->tlb->helper_tlbwi) {
9171            goto die;
9172        }
9173        gen_helper_tlbwi(cpu_env);
9174        break;
9175    case OPC_TLBINV:
9176        opn = "tlbinv";
9177        if (ctx->ie >= 2) {
9178            if (!env->tlb->helper_tlbinv) {
9179                goto die;
9180            }
9181            gen_helper_tlbinv(cpu_env);
9182        } /* treat as nop if TLBINV not supported */
9183        break;
9184    case OPC_TLBINVF:
9185        opn = "tlbinvf";
9186        if (ctx->ie >= 2) {
9187            if (!env->tlb->helper_tlbinvf) {
9188                goto die;
9189            }
9190            gen_helper_tlbinvf(cpu_env);
9191        } /* treat as nop if TLBINV not supported */
9192        break;
9193    case OPC_TLBWR:
9194        opn = "tlbwr";
9195        if (!env->tlb->helper_tlbwr) {
9196            goto die;
9197        }
9198        gen_helper_tlbwr(cpu_env);
9199        break;
9200    case OPC_TLBP:
9201        opn = "tlbp";
9202        if (!env->tlb->helper_tlbp) {
9203            goto die;
9204        }
9205        gen_helper_tlbp(cpu_env);
9206        break;
9207    case OPC_TLBR:
9208        opn = "tlbr";
9209        if (!env->tlb->helper_tlbr) {
9210            goto die;
9211        }
9212        gen_helper_tlbr(cpu_env);
9213        break;
9214    case OPC_ERET: /* OPC_ERETNC */
9215        if ((ctx->insn_flags & ISA_MIPS_R6) &&
9216            (ctx->hflags & MIPS_HFLAG_BMASK)) {
9217            goto die;
9218        } else {
9219            int bit_shift = (ctx->hflags & MIPS_HFLAG_M16) ? 16 : 6;
9220            if (ctx->opcode & (1 << bit_shift)) {
9221                /* OPC_ERETNC */
9222                opn = "eretnc";
9223                check_insn(ctx, ISA_MIPS_R5);
9224                gen_helper_eretnc(cpu_env);
9225            } else {
9226                /* OPC_ERET */
9227                opn = "eret";
9228                check_insn(ctx, ISA_MIPS2);
9229                gen_helper_eret(cpu_env);
9230            }
9231            ctx->base.is_jmp = DISAS_EXIT;
9232        }
9233        break;
9234    case OPC_DERET:
9235        opn = "deret";
9236        check_insn(ctx, ISA_MIPS_R1);
9237        if ((ctx->insn_flags & ISA_MIPS_R6) &&
9238            (ctx->hflags & MIPS_HFLAG_BMASK)) {
9239            goto die;
9240        }
9241        if (!(ctx->hflags & MIPS_HFLAG_DM)) {
9242            MIPS_INVAL(opn);
9243            gen_reserved_instruction(ctx);
9244        } else {
9245            gen_helper_deret(cpu_env);
9246            ctx->base.is_jmp = DISAS_EXIT;
9247        }
9248        break;
9249    case OPC_WAIT:
9250        opn = "wait";
9251        check_insn(ctx, ISA_MIPS3 | ISA_MIPS_R1);
9252        if ((ctx->insn_flags & ISA_MIPS_R6) &&
9253            (ctx->hflags & MIPS_HFLAG_BMASK)) {
9254            goto die;
9255        }
9256        /* If we get an exception, we want to restart at next instruction */
9257        ctx->base.pc_next += 4;
9258        save_cpu_state(ctx, 1);
9259        ctx->base.pc_next -= 4;
9260        gen_helper_wait(cpu_env);
9261        ctx->base.is_jmp = DISAS_NORETURN;
9262        break;
9263    default:
9264 die:
9265        MIPS_INVAL(opn);
9266        gen_reserved_instruction(ctx);
9267        return;
9268    }
9269    (void)opn; /* avoid a compiler warning */
9270}
9271#endif /* !CONFIG_USER_ONLY */
9272
9273/* CP1 Branches (before delay slot) */
9274static void gen_compute_branch1(DisasContext *ctx, uint32_t op,
9275                                int32_t cc, int32_t offset)
9276{
9277    target_ulong btarget;
9278    TCGv_i32 t0 = tcg_temp_new_i32();
9279
9280    if ((ctx->insn_flags & ISA_MIPS_R6) && (ctx->hflags & MIPS_HFLAG_BMASK)) {
9281        gen_reserved_instruction(ctx);
9282        goto out;
9283    }
9284
9285    if (cc != 0) {
9286        check_insn(ctx, ISA_MIPS4 | ISA_MIPS_R1);
9287    }
9288
9289    btarget = ctx->base.pc_next + 4 + offset;
9290
9291    switch (op) {
9292    case OPC_BC1F:
9293        tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
9294        tcg_gen_not_i32(t0, t0);
9295        tcg_gen_andi_i32(t0, t0, 1);
9296        tcg_gen_extu_i32_tl(bcond, t0);
9297        goto not_likely;
9298    case OPC_BC1FL:
9299        tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
9300        tcg_gen_not_i32(t0, t0);
9301        tcg_gen_andi_i32(t0, t0, 1);
9302        tcg_gen_extu_i32_tl(bcond, t0);
9303        goto likely;
9304    case OPC_BC1T:
9305        tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
9306        tcg_gen_andi_i32(t0, t0, 1);
9307        tcg_gen_extu_i32_tl(bcond, t0);
9308        goto not_likely;
9309    case OPC_BC1TL:
9310        tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
9311        tcg_gen_andi_i32(t0, t0, 1);
9312        tcg_gen_extu_i32_tl(bcond, t0);
9313    likely:
9314        ctx->hflags |= MIPS_HFLAG_BL;
9315        break;
9316    case OPC_BC1FANY2:
9317        {
9318            TCGv_i32 t1 = tcg_temp_new_i32();
9319            tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
9320            tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc + 1));
9321            tcg_gen_nand_i32(t0, t0, t1);
9322            tcg_temp_free_i32(t1);
9323            tcg_gen_andi_i32(t0, t0, 1);
9324            tcg_gen_extu_i32_tl(bcond, t0);
9325        }
9326        goto not_likely;
9327    case OPC_BC1TANY2:
9328        {
9329            TCGv_i32 t1 = tcg_temp_new_i32();
9330            tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
9331            tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc + 1));
9332            tcg_gen_or_i32(t0, t0, t1);
9333            tcg_temp_free_i32(t1);
9334            tcg_gen_andi_i32(t0, t0, 1);
9335            tcg_gen_extu_i32_tl(bcond, t0);
9336        }
9337        goto not_likely;
9338    case OPC_BC1FANY4:
9339        {
9340            TCGv_i32 t1 = tcg_temp_new_i32();
9341            tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
9342            tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc + 1));
9343            tcg_gen_and_i32(t0, t0, t1);
9344            tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc + 2));
9345            tcg_gen_and_i32(t0, t0, t1);
9346            tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc + 3));
9347            tcg_gen_nand_i32(t0, t0, t1);
9348            tcg_temp_free_i32(t1);
9349            tcg_gen_andi_i32(t0, t0, 1);
9350            tcg_gen_extu_i32_tl(bcond, t0);
9351        }
9352        goto not_likely;
9353    case OPC_BC1TANY4:
9354        {
9355            TCGv_i32 t1 = tcg_temp_new_i32();
9356            tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
9357            tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc + 1));
9358            tcg_gen_or_i32(t0, t0, t1);
9359            tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc + 2));
9360            tcg_gen_or_i32(t0, t0, t1);
9361            tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc + 3));
9362            tcg_gen_or_i32(t0, t0, t1);
9363            tcg_temp_free_i32(t1);
9364            tcg_gen_andi_i32(t0, t0, 1);
9365            tcg_gen_extu_i32_tl(bcond, t0);
9366        }
9367    not_likely:
9368        ctx->hflags |= MIPS_HFLAG_BC;
9369        break;
9370    default:
9371        MIPS_INVAL("cp1 cond branch");
9372        gen_reserved_instruction(ctx);
9373        goto out;
9374    }
9375    ctx->btarget = btarget;
9376    ctx->hflags |= MIPS_HFLAG_BDS32;
9377 out:
9378    tcg_temp_free_i32(t0);
9379}
9380
9381/* R6 CP1 Branches */
9382static void gen_compute_branch1_r6(DisasContext *ctx, uint32_t op,
9383                                   int32_t ft, int32_t offset,
9384                                   int delayslot_size)
9385{
9386    target_ulong btarget;
9387    TCGv_i64 t0 = tcg_temp_new_i64();
9388
9389    if (ctx->hflags & MIPS_HFLAG_BMASK) {
9390#ifdef MIPS_DEBUG_DISAS
9391        LOG_DISAS("Branch in delay / forbidden slot at PC 0x" TARGET_FMT_lx
9392                  "\n", ctx->base.pc_next);
9393#endif
9394        gen_reserved_instruction(ctx);
9395        goto out;
9396    }
9397
9398    gen_load_fpr64(ctx, t0, ft);
9399    tcg_gen_andi_i64(t0, t0, 1);
9400
9401    btarget = addr_add(ctx, ctx->base.pc_next + 4, offset);
9402
9403    switch (op) {
9404    case OPC_BC1EQZ:
9405        tcg_gen_xori_i64(t0, t0, 1);
9406        ctx->hflags |= MIPS_HFLAG_BC;
9407        break;
9408    case OPC_BC1NEZ:
9409        /* t0 already set */
9410        ctx->hflags |= MIPS_HFLAG_BC;
9411        break;
9412    default:
9413        MIPS_INVAL("cp1 cond branch");
9414        gen_reserved_instruction(ctx);
9415        goto out;
9416    }
9417
9418    tcg_gen_trunc_i64_tl(bcond, t0);
9419
9420    ctx->btarget = btarget;
9421
9422    switch (delayslot_size) {
9423    case 2:
9424        ctx->hflags |= MIPS_HFLAG_BDS16;
9425        break;
9426    case 4:
9427        ctx->hflags |= MIPS_HFLAG_BDS32;
9428        break;
9429    }
9430
9431out:
9432    tcg_temp_free_i64(t0);
9433}
9434
9435/* Coprocessor 1 (FPU) */
9436
9437#define FOP(func, fmt) (((fmt) << 21) | (func))
9438
9439enum fopcode {
9440    OPC_ADD_S = FOP(0, FMT_S),
9441    OPC_SUB_S = FOP(1, FMT_S),
9442    OPC_MUL_S = FOP(2, FMT_S),
9443    OPC_DIV_S = FOP(3, FMT_S),
9444    OPC_SQRT_S = FOP(4, FMT_S),
9445    OPC_ABS_S = FOP(5, FMT_S),
9446    OPC_MOV_S = FOP(6, FMT_S),
9447    OPC_NEG_S = FOP(7, FMT_S),
9448    OPC_ROUND_L_S = FOP(8, FMT_S),
9449    OPC_TRUNC_L_S = FOP(9, FMT_S),
9450    OPC_CEIL_L_S = FOP(10, FMT_S),
9451    OPC_FLOOR_L_S = FOP(11, FMT_S),
9452    OPC_ROUND_W_S = FOP(12, FMT_S),
9453    OPC_TRUNC_W_S = FOP(13, FMT_S),
9454    OPC_CEIL_W_S = FOP(14, FMT_S),
9455    OPC_FLOOR_W_S = FOP(15, FMT_S),
9456    OPC_SEL_S = FOP(16, FMT_S),
9457    OPC_MOVCF_S = FOP(17, FMT_S),
9458    OPC_MOVZ_S = FOP(18, FMT_S),
9459    OPC_MOVN_S = FOP(19, FMT_S),
9460    OPC_SELEQZ_S = FOP(20, FMT_S),
9461    OPC_RECIP_S = FOP(21, FMT_S),
9462    OPC_RSQRT_S = FOP(22, FMT_S),
9463    OPC_SELNEZ_S = FOP(23, FMT_S),
9464    OPC_MADDF_S = FOP(24, FMT_S),
9465    OPC_MSUBF_S = FOP(25, FMT_S),
9466    OPC_RINT_S = FOP(26, FMT_S),
9467    OPC_CLASS_S = FOP(27, FMT_S),
9468    OPC_MIN_S = FOP(28, FMT_S),
9469    OPC_RECIP2_S = FOP(28, FMT_S),
9470    OPC_MINA_S = FOP(29, FMT_S),
9471    OPC_RECIP1_S = FOP(29, FMT_S),
9472    OPC_MAX_S = FOP(30, FMT_S),
9473    OPC_RSQRT1_S = FOP(30, FMT_S),
9474    OPC_MAXA_S = FOP(31, FMT_S),
9475    OPC_RSQRT2_S = FOP(31, FMT_S),
9476    OPC_CVT_D_S = FOP(33, FMT_S),
9477    OPC_CVT_W_S = FOP(36, FMT_S),
9478    OPC_CVT_L_S = FOP(37, FMT_S),
9479    OPC_CVT_PS_S = FOP(38, FMT_S),
9480    OPC_CMP_F_S = FOP(48, FMT_S),
9481    OPC_CMP_UN_S = FOP(49, FMT_S),
9482    OPC_CMP_EQ_S = FOP(50, FMT_S),
9483    OPC_CMP_UEQ_S = FOP(51, FMT_S),
9484    OPC_CMP_OLT_S = FOP(52, FMT_S),
9485    OPC_CMP_ULT_S = FOP(53, FMT_S),
9486    OPC_CMP_OLE_S = FOP(54, FMT_S),
9487    OPC_CMP_ULE_S = FOP(55, FMT_S),
9488    OPC_CMP_SF_S = FOP(56, FMT_S),
9489    OPC_CMP_NGLE_S = FOP(57, FMT_S),
9490    OPC_CMP_SEQ_S = FOP(58, FMT_S),
9491    OPC_CMP_NGL_S = FOP(59, FMT_S),
9492    OPC_CMP_LT_S = FOP(60, FMT_S),
9493    OPC_CMP_NGE_S = FOP(61, FMT_S),
9494    OPC_CMP_LE_S = FOP(62, FMT_S),
9495    OPC_CMP_NGT_S = FOP(63, FMT_S),
9496
9497    OPC_ADD_D = FOP(0, FMT_D),
9498    OPC_SUB_D = FOP(1, FMT_D),
9499    OPC_MUL_D = FOP(2, FMT_D),
9500    OPC_DIV_D = FOP(3, FMT_D),
9501    OPC_SQRT_D = FOP(4, FMT_D),
9502    OPC_ABS_D = FOP(5, FMT_D),
9503    OPC_MOV_D = FOP(6, FMT_D),
9504    OPC_NEG_D = FOP(7, FMT_D),
9505    OPC_ROUND_L_D = FOP(8, FMT_D),
9506    OPC_TRUNC_L_D = FOP(9, FMT_D),
9507    OPC_CEIL_L_D = FOP(10, FMT_D),
9508    OPC_FLOOR_L_D = FOP(11, FMT_D),
9509    OPC_ROUND_W_D = FOP(12, FMT_D),
9510    OPC_TRUNC_W_D = FOP(13, FMT_D),
9511    OPC_CEIL_W_D = FOP(14, FMT_D),
9512    OPC_FLOOR_W_D = FOP(15, FMT_D),
9513    OPC_SEL_D = FOP(16, FMT_D),
9514    OPC_MOVCF_D = FOP(17, FMT_D),
9515    OPC_MOVZ_D = FOP(18, FMT_D),
9516    OPC_MOVN_D = FOP(19, FMT_D),
9517    OPC_SELEQZ_D = FOP(20, FMT_D),
9518    OPC_RECIP_D = FOP(21, FMT_D),
9519    OPC_RSQRT_D = FOP(22, FMT_D),
9520    OPC_SELNEZ_D = FOP(23, FMT_D),
9521    OPC_MADDF_D = FOP(24, FMT_D),
9522    OPC_MSUBF_D = FOP(25, FMT_D),
9523    OPC_RINT_D = FOP(26, FMT_D),
9524    OPC_CLASS_D = FOP(27, FMT_D),
9525    OPC_MIN_D = FOP(28, FMT_D),
9526    OPC_RECIP2_D = FOP(28, FMT_D),
9527    OPC_MINA_D = FOP(29, FMT_D),
9528    OPC_RECIP1_D = FOP(29, FMT_D),
9529    OPC_MAX_D = FOP(30, FMT_D),
9530    OPC_RSQRT1_D = FOP(30, FMT_D),
9531    OPC_MAXA_D = FOP(31, FMT_D),
9532    OPC_RSQRT2_D = FOP(31, FMT_D),
9533    OPC_CVT_S_D = FOP(32, FMT_D),
9534    OPC_CVT_W_D = FOP(36, FMT_D),
9535    OPC_CVT_L_D = FOP(37, FMT_D),
9536    OPC_CMP_F_D = FOP(48, FMT_D),
9537    OPC_CMP_UN_D = FOP(49, FMT_D),
9538    OPC_CMP_EQ_D = FOP(50, FMT_D),
9539    OPC_CMP_UEQ_D = FOP(51, FMT_D),
9540    OPC_CMP_OLT_D = FOP(52, FMT_D),
9541    OPC_CMP_ULT_D = FOP(53, FMT_D),
9542    OPC_CMP_OLE_D = FOP(54, FMT_D),
9543    OPC_CMP_ULE_D = FOP(55, FMT_D),
9544    OPC_CMP_SF_D = FOP(56, FMT_D),
9545    OPC_CMP_NGLE_D = FOP(57, FMT_D),
9546    OPC_CMP_SEQ_D = FOP(58, FMT_D),
9547    OPC_CMP_NGL_D = FOP(59, FMT_D),
9548    OPC_CMP_LT_D = FOP(60, FMT_D),
9549    OPC_CMP_NGE_D = FOP(61, FMT_D),
9550    OPC_CMP_LE_D = FOP(62, FMT_D),
9551    OPC_CMP_NGT_D = FOP(63, FMT_D),
9552
9553    OPC_CVT_S_W = FOP(32, FMT_W),
9554    OPC_CVT_D_W = FOP(33, FMT_W),
9555    OPC_CVT_S_L = FOP(32, FMT_L),
9556    OPC_CVT_D_L = FOP(33, FMT_L),
9557    OPC_CVT_PS_PW = FOP(38, FMT_W),
9558
9559    OPC_ADD_PS = FOP(0, FMT_PS),
9560    OPC_SUB_PS = FOP(1, FMT_PS),
9561    OPC_MUL_PS = FOP(2, FMT_PS),
9562    OPC_DIV_PS = FOP(3, FMT_PS),
9563    OPC_ABS_PS = FOP(5, FMT_PS),
9564    OPC_MOV_PS = FOP(6, FMT_PS),
9565    OPC_NEG_PS = FOP(7, FMT_PS),
9566    OPC_MOVCF_PS = FOP(17, FMT_PS),
9567    OPC_MOVZ_PS = FOP(18, FMT_PS),
9568    OPC_MOVN_PS = FOP(19, FMT_PS),
9569    OPC_ADDR_PS = FOP(24, FMT_PS),
9570    OPC_MULR_PS = FOP(26, FMT_PS),
9571    OPC_RECIP2_PS = FOP(28, FMT_PS),
9572    OPC_RECIP1_PS = FOP(29, FMT_PS),
9573    OPC_RSQRT1_PS = FOP(30, FMT_PS),
9574    OPC_RSQRT2_PS = FOP(31, FMT_PS),
9575
9576    OPC_CVT_S_PU = FOP(32, FMT_PS),
9577    OPC_CVT_PW_PS = FOP(36, FMT_PS),
9578    OPC_CVT_S_PL = FOP(40, FMT_PS),
9579    OPC_PLL_PS = FOP(44, FMT_PS),
9580    OPC_PLU_PS = FOP(45, FMT_PS),
9581    OPC_PUL_PS = FOP(46, FMT_PS),
9582    OPC_PUU_PS = FOP(47, FMT_PS),
9583    OPC_CMP_F_PS = FOP(48, FMT_PS),
9584    OPC_CMP_UN_PS = FOP(49, FMT_PS),
9585    OPC_CMP_EQ_PS = FOP(50, FMT_PS),
9586    OPC_CMP_UEQ_PS = FOP(51, FMT_PS),
9587    OPC_CMP_OLT_PS = FOP(52, FMT_PS),
9588    OPC_CMP_ULT_PS = FOP(53, FMT_PS),
9589    OPC_CMP_OLE_PS = FOP(54, FMT_PS),
9590    OPC_CMP_ULE_PS = FOP(55, FMT_PS),
9591    OPC_CMP_SF_PS = FOP(56, FMT_PS),
9592    OPC_CMP_NGLE_PS = FOP(57, FMT_PS),
9593    OPC_CMP_SEQ_PS = FOP(58, FMT_PS),
9594    OPC_CMP_NGL_PS = FOP(59, FMT_PS),
9595    OPC_CMP_LT_PS = FOP(60, FMT_PS),
9596    OPC_CMP_NGE_PS = FOP(61, FMT_PS),
9597    OPC_CMP_LE_PS = FOP(62, FMT_PS),
9598    OPC_CMP_NGT_PS = FOP(63, FMT_PS),
9599};
9600
9601enum r6_f_cmp_op {
9602    R6_OPC_CMP_AF_S   = FOP(0, FMT_W),
9603    R6_OPC_CMP_UN_S   = FOP(1, FMT_W),
9604    R6_OPC_CMP_EQ_S   = FOP(2, FMT_W),
9605    R6_OPC_CMP_UEQ_S  = FOP(3, FMT_W),
9606    R6_OPC_CMP_LT_S   = FOP(4, FMT_W),
9607    R6_OPC_CMP_ULT_S  = FOP(5, FMT_W),
9608    R6_OPC_CMP_LE_S   = FOP(6, FMT_W),
9609    R6_OPC_CMP_ULE_S  = FOP(7, FMT_W),
9610    R6_OPC_CMP_SAF_S  = FOP(8, FMT_W),
9611    R6_OPC_CMP_SUN_S  = FOP(9, FMT_W),
9612    R6_OPC_CMP_SEQ_S  = FOP(10, FMT_W),
9613    R6_OPC_CMP_SEUQ_S = FOP(11, FMT_W),
9614    R6_OPC_CMP_SLT_S  = FOP(12, FMT_W),
9615    R6_OPC_CMP_SULT_S = FOP(13, FMT_W),
9616    R6_OPC_CMP_SLE_S  = FOP(14, FMT_W),
9617    R6_OPC_CMP_SULE_S = FOP(15, FMT_W),
9618    R6_OPC_CMP_OR_S   = FOP(17, FMT_W),
9619    R6_OPC_CMP_UNE_S  = FOP(18, FMT_W),
9620    R6_OPC_CMP_NE_S   = FOP(19, FMT_W),
9621    R6_OPC_CMP_SOR_S  = FOP(25, FMT_W),
9622    R6_OPC_CMP_SUNE_S = FOP(26, FMT_W),
9623    R6_OPC_CMP_SNE_S  = FOP(27, FMT_W),
9624
9625    R6_OPC_CMP_AF_D   = FOP(0, FMT_L),
9626    R6_OPC_CMP_UN_D   = FOP(1, FMT_L),
9627    R6_OPC_CMP_EQ_D   = FOP(2, FMT_L),
9628    R6_OPC_CMP_UEQ_D  = FOP(3, FMT_L),
9629    R6_OPC_CMP_LT_D   = FOP(4, FMT_L),
9630    R6_OPC_CMP_ULT_D  = FOP(5, FMT_L),
9631    R6_OPC_CMP_LE_D   = FOP(6, FMT_L),
9632    R6_OPC_CMP_ULE_D  = FOP(7, FMT_L),
9633    R6_OPC_CMP_SAF_D  = FOP(8, FMT_L),
9634    R6_OPC_CMP_SUN_D  = FOP(9, FMT_L),
9635    R6_OPC_CMP_SEQ_D  = FOP(10, FMT_L),
9636    R6_OPC_CMP_SEUQ_D = FOP(11, FMT_L),
9637    R6_OPC_CMP_SLT_D  = FOP(12, FMT_L),
9638    R6_OPC_CMP_SULT_D = FOP(13, FMT_L),
9639    R6_OPC_CMP_SLE_D  = FOP(14, FMT_L),
9640    R6_OPC_CMP_SULE_D = FOP(15, FMT_L),
9641    R6_OPC_CMP_OR_D   = FOP(17, FMT_L),
9642    R6_OPC_CMP_UNE_D  = FOP(18, FMT_L),
9643    R6_OPC_CMP_NE_D   = FOP(19, FMT_L),
9644    R6_OPC_CMP_SOR_D  = FOP(25, FMT_L),
9645    R6_OPC_CMP_SUNE_D = FOP(26, FMT_L),
9646    R6_OPC_CMP_SNE_D  = FOP(27, FMT_L),
9647};
9648
9649static void gen_cp1(DisasContext *ctx, uint32_t opc, int rt, int fs)
9650{
9651    TCGv t0 = tcg_temp_new();
9652
9653    switch (opc) {
9654    case OPC_MFC1:
9655        {
9656            TCGv_i32 fp0 = tcg_temp_new_i32();
9657
9658            gen_load_fpr32(ctx, fp0, fs);
9659            tcg_gen_ext_i32_tl(t0, fp0);
9660            tcg_temp_free_i32(fp0);
9661        }
9662        gen_store_gpr(t0, rt);
9663        break;
9664    case OPC_MTC1:
9665        gen_load_gpr(t0, rt);
9666        {
9667            TCGv_i32 fp0 = tcg_temp_new_i32();
9668
9669            tcg_gen_trunc_tl_i32(fp0, t0);
9670            gen_store_fpr32(ctx, fp0, fs);
9671            tcg_temp_free_i32(fp0);
9672        }
9673        break;
9674    case OPC_CFC1:
9675        gen_helper_1e0i(cfc1, t0, fs);
9676        gen_store_gpr(t0, rt);
9677        break;
9678    case OPC_CTC1:
9679        gen_load_gpr(t0, rt);
9680        save_cpu_state(ctx, 0);
9681        gen_helper_0e2i(ctc1, t0, tcg_constant_i32(fs), rt);
9682        /* Stop translation as we may have changed hflags */
9683        ctx->base.is_jmp = DISAS_STOP;
9684        break;
9685#if defined(TARGET_MIPS64)
9686    case OPC_DMFC1:
9687        gen_load_fpr64(ctx, t0, fs);
9688        gen_store_gpr(t0, rt);
9689        break;
9690    case OPC_DMTC1:
9691        gen_load_gpr(t0, rt);
9692        gen_store_fpr64(ctx, t0, fs);
9693        break;
9694#endif
9695    case OPC_MFHC1:
9696        {
9697            TCGv_i32 fp0 = tcg_temp_new_i32();
9698
9699            gen_load_fpr32h(ctx, fp0, fs);
9700            tcg_gen_ext_i32_tl(t0, fp0);
9701            tcg_temp_free_i32(fp0);
9702        }
9703        gen_store_gpr(t0, rt);
9704        break;
9705    case OPC_MTHC1:
9706        gen_load_gpr(t0, rt);
9707        {
9708            TCGv_i32 fp0 = tcg_temp_new_i32();
9709
9710            tcg_gen_trunc_tl_i32(fp0, t0);
9711            gen_store_fpr32h(ctx, fp0, fs);
9712            tcg_temp_free_i32(fp0);
9713        }
9714        break;
9715    default:
9716        MIPS_INVAL("cp1 move");
9717        gen_reserved_instruction(ctx);
9718        goto out;
9719    }
9720
9721 out:
9722    tcg_temp_free(t0);
9723}
9724
9725static void gen_movci(DisasContext *ctx, int rd, int rs, int cc, int tf)
9726{
9727    TCGLabel *l1;
9728    TCGCond cond;
9729    TCGv_i32 t0;
9730
9731    if (rd == 0) {
9732        /* Treat as NOP. */
9733        return;
9734    }
9735
9736    if (tf) {
9737        cond = TCG_COND_EQ;
9738    } else {
9739        cond = TCG_COND_NE;
9740    }
9741
9742    l1 = gen_new_label();
9743    t0 = tcg_temp_new_i32();
9744    tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
9745    tcg_gen_brcondi_i32(cond, t0, 0, l1);
9746    tcg_temp_free_i32(t0);
9747    gen_load_gpr(cpu_gpr[rd], rs);
9748    gen_set_label(l1);
9749}
9750
9751static inline void gen_movcf_s(DisasContext *ctx, int fs, int fd, int cc,
9752                               int tf)
9753{
9754    int cond;
9755    TCGv_i32 t0 = tcg_temp_new_i32();
9756    TCGLabel *l1 = gen_new_label();
9757
9758    if (tf) {
9759        cond = TCG_COND_EQ;
9760    } else {
9761        cond = TCG_COND_NE;
9762    }
9763
9764    tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
9765    tcg_gen_brcondi_i32(cond, t0, 0, l1);
9766    gen_load_fpr32(ctx, t0, fs);
9767    gen_store_fpr32(ctx, t0, fd);
9768    gen_set_label(l1);
9769    tcg_temp_free_i32(t0);
9770}
9771
9772static inline void gen_movcf_d(DisasContext *ctx, int fs, int fd, int cc,
9773                               int tf)
9774{
9775    int cond;
9776    TCGv_i32 t0 = tcg_temp_new_i32();
9777    TCGv_i64 fp0;
9778    TCGLabel *l1 = gen_new_label();
9779
9780    if (tf) {
9781        cond = TCG_COND_EQ;
9782    } else {
9783        cond = TCG_COND_NE;
9784    }
9785
9786    tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
9787    tcg_gen_brcondi_i32(cond, t0, 0, l1);
9788    tcg_temp_free_i32(t0);
9789    fp0 = tcg_temp_new_i64();
9790    gen_load_fpr64(ctx, fp0, fs);
9791    gen_store_fpr64(ctx, fp0, fd);
9792    tcg_temp_free_i64(fp0);
9793    gen_set_label(l1);
9794}
9795
9796static inline void gen_movcf_ps(DisasContext *ctx, int fs, int fd,
9797                                int cc, int tf)
9798{
9799    int cond;
9800    TCGv_i32 t0 = tcg_temp_new_i32();
9801    TCGLabel *l1 = gen_new_label();
9802    TCGLabel *l2 = gen_new_label();
9803
9804    if (tf) {
9805        cond = TCG_COND_EQ;
9806    } else {
9807        cond = TCG_COND_NE;
9808    }
9809
9810    tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
9811    tcg_gen_brcondi_i32(cond, t0, 0, l1);
9812    gen_load_fpr32(ctx, t0, fs);
9813    gen_store_fpr32(ctx, t0, fd);
9814    gen_set_label(l1);
9815
9816    tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc + 1));
9817    tcg_gen_brcondi_i32(cond, t0, 0, l2);
9818    gen_load_fpr32h(ctx, t0, fs);
9819    gen_store_fpr32h(ctx, t0, fd);
9820    tcg_temp_free_i32(t0);
9821    gen_set_label(l2);
9822}
9823
9824static void gen_sel_s(DisasContext *ctx, enum fopcode op1, int fd, int ft,
9825                      int fs)
9826{
9827    TCGv_i32 t1 = tcg_const_i32(0);
9828    TCGv_i32 fp0 = tcg_temp_new_i32();
9829    TCGv_i32 fp1 = tcg_temp_new_i32();
9830    TCGv_i32 fp2 = tcg_temp_new_i32();
9831    gen_load_fpr32(ctx, fp0, fd);
9832    gen_load_fpr32(ctx, fp1, ft);
9833    gen_load_fpr32(ctx, fp2, fs);
9834
9835    switch (op1) {
9836    case OPC_SEL_S:
9837        tcg_gen_andi_i32(fp0, fp0, 1);
9838        tcg_gen_movcond_i32(TCG_COND_NE, fp0, fp0, t1, fp1, fp2);
9839        break;
9840    case OPC_SELEQZ_S:
9841        tcg_gen_andi_i32(fp1, fp1, 1);
9842        tcg_gen_movcond_i32(TCG_COND_EQ, fp0, fp1, t1, fp2, t1);
9843        break;
9844    case OPC_SELNEZ_S:
9845        tcg_gen_andi_i32(fp1, fp1, 1);
9846        tcg_gen_movcond_i32(TCG_COND_NE, fp0, fp1, t1, fp2, t1);
9847        break;
9848    default:
9849        MIPS_INVAL("gen_sel_s");
9850        gen_reserved_instruction(ctx);
9851        break;
9852    }
9853
9854    gen_store_fpr32(ctx, fp0, fd);
9855    tcg_temp_free_i32(fp2);
9856    tcg_temp_free_i32(fp1);
9857    tcg_temp_free_i32(fp0);
9858    tcg_temp_free_i32(t1);
9859}
9860
9861static void gen_sel_d(DisasContext *ctx, enum fopcode op1, int fd, int ft,
9862                      int fs)
9863{
9864    TCGv_i64 t1 = tcg_const_i64(0);
9865    TCGv_i64 fp0 = tcg_temp_new_i64();
9866    TCGv_i64 fp1 = tcg_temp_new_i64();
9867    TCGv_i64 fp2 = tcg_temp_new_i64();
9868    gen_load_fpr64(ctx, fp0, fd);
9869    gen_load_fpr64(ctx, fp1, ft);
9870    gen_load_fpr64(ctx, fp2, fs);
9871
9872    switch (op1) {
9873    case OPC_SEL_D:
9874        tcg_gen_andi_i64(fp0, fp0, 1);
9875        tcg_gen_movcond_i64(TCG_COND_NE, fp0, fp0, t1, fp1, fp2);
9876        break;
9877    case OPC_SELEQZ_D:
9878        tcg_gen_andi_i64(fp1, fp1, 1);
9879        tcg_gen_movcond_i64(TCG_COND_EQ, fp0, fp1, t1, fp2, t1);
9880        break;
9881    case OPC_SELNEZ_D:
9882        tcg_gen_andi_i64(fp1, fp1, 1);
9883        tcg_gen_movcond_i64(TCG_COND_NE, fp0, fp1, t1, fp2, t1);
9884        break;
9885    default:
9886        MIPS_INVAL("gen_sel_d");
9887        gen_reserved_instruction(ctx);
9888        break;
9889    }
9890
9891    gen_store_fpr64(ctx, fp0, fd);
9892    tcg_temp_free_i64(fp2);
9893    tcg_temp_free_i64(fp1);
9894    tcg_temp_free_i64(fp0);
9895    tcg_temp_free_i64(t1);
9896}
9897
9898static void gen_farith(DisasContext *ctx, enum fopcode op1,
9899                       int ft, int fs, int fd, int cc)
9900{
9901    uint32_t func = ctx->opcode & 0x3f;
9902    switch (op1) {
9903    case OPC_ADD_S:
9904        {
9905            TCGv_i32 fp0 = tcg_temp_new_i32();
9906            TCGv_i32 fp1 = tcg_temp_new_i32();
9907
9908            gen_load_fpr32(ctx, fp0, fs);
9909            gen_load_fpr32(ctx, fp1, ft);
9910            gen_helper_float_add_s(fp0, cpu_env, fp0, fp1);
9911            tcg_temp_free_i32(fp1);
9912            gen_store_fpr32(ctx, fp0, fd);
9913            tcg_temp_free_i32(fp0);
9914        }
9915        break;
9916    case OPC_SUB_S:
9917        {
9918            TCGv_i32 fp0 = tcg_temp_new_i32();
9919            TCGv_i32 fp1 = tcg_temp_new_i32();
9920
9921            gen_load_fpr32(ctx, fp0, fs);
9922            gen_load_fpr32(ctx, fp1, ft);
9923            gen_helper_float_sub_s(fp0, cpu_env, fp0, fp1);
9924            tcg_temp_free_i32(fp1);
9925            gen_store_fpr32(ctx, fp0, fd);
9926            tcg_temp_free_i32(fp0);
9927        }
9928        break;
9929    case OPC_MUL_S:
9930        {
9931            TCGv_i32 fp0 = tcg_temp_new_i32();
9932            TCGv_i32 fp1 = tcg_temp_new_i32();
9933
9934            gen_load_fpr32(ctx, fp0, fs);
9935            gen_load_fpr32(ctx, fp1, ft);
9936            gen_helper_float_mul_s(fp0, cpu_env, fp0, fp1);
9937            tcg_temp_free_i32(fp1);
9938            gen_store_fpr32(ctx, fp0, fd);
9939            tcg_temp_free_i32(fp0);
9940        }
9941        break;
9942    case OPC_DIV_S:
9943        {
9944            TCGv_i32 fp0 = tcg_temp_new_i32();
9945            TCGv_i32 fp1 = tcg_temp_new_i32();
9946
9947            gen_load_fpr32(ctx, fp0, fs);
9948            gen_load_fpr32(ctx, fp1, ft);
9949            gen_helper_float_div_s(fp0, cpu_env, fp0, fp1);
9950            tcg_temp_free_i32(fp1);
9951            gen_store_fpr32(ctx, fp0, fd);
9952            tcg_temp_free_i32(fp0);
9953        }
9954        break;
9955    case OPC_SQRT_S:
9956        {
9957            TCGv_i32 fp0 = tcg_temp_new_i32();
9958
9959            gen_load_fpr32(ctx, fp0, fs);
9960            gen_helper_float_sqrt_s(fp0, cpu_env, fp0);
9961            gen_store_fpr32(ctx, fp0, fd);
9962            tcg_temp_free_i32(fp0);
9963        }
9964        break;
9965    case OPC_ABS_S:
9966        {
9967            TCGv_i32 fp0 = tcg_temp_new_i32();
9968
9969            gen_load_fpr32(ctx, fp0, fs);
9970            if (ctx->abs2008) {
9971                tcg_gen_andi_i32(fp0, fp0, 0x7fffffffUL);
9972            } else {
9973                gen_helper_float_abs_s(fp0, fp0);
9974            }
9975            gen_store_fpr32(ctx, fp0, fd);
9976            tcg_temp_free_i32(fp0);
9977        }
9978        break;
9979    case OPC_MOV_S:
9980        {
9981            TCGv_i32 fp0 = tcg_temp_new_i32();
9982
9983            gen_load_fpr32(ctx, fp0, fs);
9984            gen_store_fpr32(ctx, fp0, fd);
9985            tcg_temp_free_i32(fp0);
9986        }
9987        break;
9988    case OPC_NEG_S:
9989        {
9990            TCGv_i32 fp0 = tcg_temp_new_i32();
9991
9992            gen_load_fpr32(ctx, fp0, fs);
9993            if (ctx->abs2008) {
9994                tcg_gen_xori_i32(fp0, fp0, 1UL << 31);
9995            } else {
9996                gen_helper_float_chs_s(fp0, fp0);
9997            }
9998            gen_store_fpr32(ctx, fp0, fd);
9999            tcg_temp_free_i32(fp0);
10000        }
10001        break;
10002    case OPC_ROUND_L_S:
10003        check_cp1_64bitmode(ctx);
10004        {
10005            TCGv_i32 fp32 = tcg_temp_new_i32();
10006            TCGv_i64 fp64 = tcg_temp_new_i64();
10007
10008            gen_load_fpr32(ctx, fp32, fs);
10009            if (ctx->nan2008) {
10010                gen_helper_float_round_2008_l_s(fp64, cpu_env, fp32);
10011            } else {
10012                gen_helper_float_round_l_s(fp64, cpu_env, fp32);
10013            }
10014            tcg_temp_free_i32(fp32);
10015            gen_store_fpr64(ctx, fp64, fd);
10016            tcg_temp_free_i64(fp64);
10017        }
10018        break;
10019    case OPC_TRUNC_L_S:
10020        check_cp1_64bitmode(ctx);
10021        {
10022            TCGv_i32 fp32 = tcg_temp_new_i32();
10023            TCGv_i64 fp64 = tcg_temp_new_i64();
10024
10025            gen_load_fpr32(ctx, fp32, fs);
10026            if (ctx->nan2008) {
10027                gen_helper_float_trunc_2008_l_s(fp64, cpu_env, fp32);
10028            } else {
10029                gen_helper_float_trunc_l_s(fp64, cpu_env, fp32);
10030            }
10031            tcg_temp_free_i32(fp32);
10032            gen_store_fpr64(ctx, fp64, fd);
10033            tcg_temp_free_i64(fp64);
10034        }
10035        break;
10036    case OPC_CEIL_L_S:
10037        check_cp1_64bitmode(ctx);
10038        {
10039            TCGv_i32 fp32 = tcg_temp_new_i32();
10040            TCGv_i64 fp64 = tcg_temp_new_i64();
10041
10042            gen_load_fpr32(ctx, fp32, fs);
10043            if (ctx->nan2008) {
10044                gen_helper_float_ceil_2008_l_s(fp64, cpu_env, fp32);
10045            } else {
10046                gen_helper_float_ceil_l_s(fp64, cpu_env, fp32);
10047            }
10048            tcg_temp_free_i32(fp32);
10049            gen_store_fpr64(ctx, fp64, fd);
10050            tcg_temp_free_i64(fp64);
10051        }
10052        break;
10053    case OPC_FLOOR_L_S:
10054        check_cp1_64bitmode(ctx);
10055        {
10056            TCGv_i32 fp32 = tcg_temp_new_i32();
10057            TCGv_i64 fp64 = tcg_temp_new_i64();
10058
10059            gen_load_fpr32(ctx, fp32, fs);
10060            if (ctx->nan2008) {
10061                gen_helper_float_floor_2008_l_s(fp64, cpu_env, fp32);
10062            } else {
10063                gen_helper_float_floor_l_s(fp64, cpu_env, fp32);
10064            }
10065            tcg_temp_free_i32(fp32);
10066            gen_store_fpr64(ctx, fp64, fd);
10067            tcg_temp_free_i64(fp64);
10068        }
10069        break;
10070    case OPC_ROUND_W_S:
10071        {
10072            TCGv_i32 fp0 = tcg_temp_new_i32();
10073
10074            gen_load_fpr32(ctx, fp0, fs);
10075            if (ctx->nan2008) {
10076                gen_helper_float_round_2008_w_s(fp0, cpu_env, fp0);
10077            } else {
10078                gen_helper_float_round_w_s(fp0, cpu_env, fp0);
10079            }
10080            gen_store_fpr32(ctx, fp0, fd);
10081            tcg_temp_free_i32(fp0);
10082        }
10083        break;
10084    case OPC_TRUNC_W_S:
10085        {
10086            TCGv_i32 fp0 = tcg_temp_new_i32();
10087
10088            gen_load_fpr32(ctx, fp0, fs);
10089            if (ctx->nan2008) {
10090                gen_helper_float_trunc_2008_w_s(fp0, cpu_env, fp0);
10091            } else {
10092                gen_helper_float_trunc_w_s(fp0, cpu_env, fp0);
10093            }
10094            gen_store_fpr32(ctx, fp0, fd);
10095            tcg_temp_free_i32(fp0);
10096        }
10097        break;
10098    case OPC_CEIL_W_S:
10099        {
10100            TCGv_i32 fp0 = tcg_temp_new_i32();
10101
10102            gen_load_fpr32(ctx, fp0, fs);
10103            if (ctx->nan2008) {
10104                gen_helper_float_ceil_2008_w_s(fp0, cpu_env, fp0);
10105            } else {
10106                gen_helper_float_ceil_w_s(fp0, cpu_env, fp0);
10107            }
10108            gen_store_fpr32(ctx, fp0, fd);
10109            tcg_temp_free_i32(fp0);
10110        }
10111        break;
10112    case OPC_FLOOR_W_S:
10113        {
10114            TCGv_i32 fp0 = tcg_temp_new_i32();
10115
10116            gen_load_fpr32(ctx, fp0, fs);
10117            if (ctx->nan2008) {
10118                gen_helper_float_floor_2008_w_s(fp0, cpu_env, fp0);
10119            } else {
10120                gen_helper_float_floor_w_s(fp0, cpu_env, fp0);
10121            }
10122            gen_store_fpr32(ctx, fp0, fd);
10123            tcg_temp_free_i32(fp0);
10124        }
10125        break;
10126    case OPC_SEL_S:
10127        check_insn(ctx, ISA_MIPS_R6);
10128        gen_sel_s(ctx, op1, fd, ft, fs);
10129        break;
10130    case OPC_SELEQZ_S:
10131        check_insn(ctx, ISA_MIPS_R6);
10132        gen_sel_s(ctx, op1, fd, ft, fs);
10133        break;
10134    case OPC_SELNEZ_S:
10135        check_insn(ctx, ISA_MIPS_R6);
10136        gen_sel_s(ctx, op1, fd, ft, fs);
10137        break;
10138    case OPC_MOVCF_S:
10139        check_insn_opc_removed(ctx, ISA_MIPS_R6);
10140        gen_movcf_s(ctx, fs, fd, (ft >> 2) & 0x7, ft & 0x1);
10141        break;
10142    case OPC_MOVZ_S:
10143        check_insn_opc_removed(ctx, ISA_MIPS_R6);
10144        {
10145            TCGLabel *l1 = gen_new_label();
10146            TCGv_i32 fp0;
10147
10148            if (ft != 0) {
10149                tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[ft], 0, l1);
10150            }
10151            fp0 = tcg_temp_new_i32();
10152            gen_load_fpr32(ctx, fp0, fs);
10153            gen_store_fpr32(ctx, fp0, fd);
10154            tcg_temp_free_i32(fp0);
10155            gen_set_label(l1);
10156        }
10157        break;
10158    case OPC_MOVN_S:
10159        check_insn_opc_removed(ctx, ISA_MIPS_R6);
10160        {
10161            TCGLabel *l1 = gen_new_label();
10162            TCGv_i32 fp0;
10163
10164            if (ft != 0) {
10165                tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[ft], 0, l1);
10166                fp0 = tcg_temp_new_i32();
10167                gen_load_fpr32(ctx, fp0, fs);
10168                gen_store_fpr32(ctx, fp0, fd);
10169                tcg_temp_free_i32(fp0);
10170                gen_set_label(l1);
10171            }
10172        }
10173        break;
10174    case OPC_RECIP_S:
10175        {
10176            TCGv_i32 fp0 = tcg_temp_new_i32();
10177
10178            gen_load_fpr32(ctx, fp0, fs);
10179            gen_helper_float_recip_s(fp0, cpu_env, fp0);
10180            gen_store_fpr32(ctx, fp0, fd);
10181            tcg_temp_free_i32(fp0);
10182        }
10183        break;
10184    case OPC_RSQRT_S:
10185        {
10186            TCGv_i32 fp0 = tcg_temp_new_i32();
10187
10188            gen_load_fpr32(ctx, fp0, fs);
10189            gen_helper_float_rsqrt_s(fp0, cpu_env, fp0);
10190            gen_store_fpr32(ctx, fp0, fd);
10191            tcg_temp_free_i32(fp0);
10192        }
10193        break;
10194    case OPC_MADDF_S:
10195        check_insn(ctx, ISA_MIPS_R6);
10196        {
10197            TCGv_i32 fp0 = tcg_temp_new_i32();
10198            TCGv_i32 fp1 = tcg_temp_new_i32();
10199            TCGv_i32 fp2 = tcg_temp_new_i32();
10200            gen_load_fpr32(ctx, fp0, fs);
10201            gen_load_fpr32(ctx, fp1, ft);
10202            gen_load_fpr32(ctx, fp2, fd);
10203            gen_helper_float_maddf_s(fp2, cpu_env, fp0, fp1, fp2);
10204            gen_store_fpr32(ctx, fp2, fd);
10205            tcg_temp_free_i32(fp2);
10206            tcg_temp_free_i32(fp1);
10207            tcg_temp_free_i32(fp0);
10208        }
10209        break;
10210    case OPC_MSUBF_S:
10211        check_insn(ctx, ISA_MIPS_R6);
10212        {
10213            TCGv_i32 fp0 = tcg_temp_new_i32();
10214            TCGv_i32 fp1 = tcg_temp_new_i32();
10215            TCGv_i32 fp2 = tcg_temp_new_i32();
10216            gen_load_fpr32(ctx, fp0, fs);
10217            gen_load_fpr32(ctx, fp1, ft);
10218            gen_load_fpr32(ctx, fp2, fd);
10219            gen_helper_float_msubf_s(fp2, cpu_env, fp0, fp1, fp2);
10220            gen_store_fpr32(ctx, fp2, fd);
10221            tcg_temp_free_i32(fp2);
10222            tcg_temp_free_i32(fp1);
10223            tcg_temp_free_i32(fp0);
10224        }
10225        break;
10226    case OPC_RINT_S:
10227        check_insn(ctx, ISA_MIPS_R6);
10228        {
10229            TCGv_i32 fp0 = tcg_temp_new_i32();
10230            gen_load_fpr32(ctx, fp0, fs);
10231            gen_helper_float_rint_s(fp0, cpu_env, fp0);
10232            gen_store_fpr32(ctx, fp0, fd);
10233            tcg_temp_free_i32(fp0);
10234        }
10235        break;
10236    case OPC_CLASS_S:
10237        check_insn(ctx, ISA_MIPS_R6);
10238        {
10239            TCGv_i32 fp0 = tcg_temp_new_i32();
10240            gen_load_fpr32(ctx, fp0, fs);
10241            gen_helper_float_class_s(fp0, cpu_env, fp0);
10242            gen_store_fpr32(ctx, fp0, fd);
10243            tcg_temp_free_i32(fp0);
10244        }
10245        break;
10246    case OPC_MIN_S: /* OPC_RECIP2_S */
10247        if (ctx->insn_flags & ISA_MIPS_R6) {
10248            /* OPC_MIN_S */
10249            TCGv_i32 fp0 = tcg_temp_new_i32();
10250            TCGv_i32 fp1 = tcg_temp_new_i32();
10251            TCGv_i32 fp2 = tcg_temp_new_i32();
10252            gen_load_fpr32(ctx, fp0, fs);
10253            gen_load_fpr32(ctx, fp1, ft);
10254            gen_helper_float_min_s(fp2, cpu_env, fp0, fp1);
10255            gen_store_fpr32(ctx, fp2, fd);
10256            tcg_temp_free_i32(fp2);
10257            tcg_temp_free_i32(fp1);
10258            tcg_temp_free_i32(fp0);
10259        } else {
10260            /* OPC_RECIP2_S */
10261            check_cp1_64bitmode(ctx);
10262            {
10263                TCGv_i32 fp0 = tcg_temp_new_i32();
10264                TCGv_i32 fp1 = tcg_temp_new_i32();
10265
10266                gen_load_fpr32(ctx, fp0, fs);
10267                gen_load_fpr32(ctx, fp1, ft);
10268                gen_helper_float_recip2_s(fp0, cpu_env, fp0, fp1);
10269                tcg_temp_free_i32(fp1);
10270                gen_store_fpr32(ctx, fp0, fd);
10271                tcg_temp_free_i32(fp0);
10272            }
10273        }
10274        break;
10275    case OPC_MINA_S: /* OPC_RECIP1_S */
10276        if (ctx->insn_flags & ISA_MIPS_R6) {
10277            /* OPC_MINA_S */
10278            TCGv_i32 fp0 = tcg_temp_new_i32();
10279            TCGv_i32 fp1 = tcg_temp_new_i32();
10280            TCGv_i32 fp2 = tcg_temp_new_i32();
10281            gen_load_fpr32(ctx, fp0, fs);
10282            gen_load_fpr32(ctx, fp1, ft);
10283            gen_helper_float_mina_s(fp2, cpu_env, fp0, fp1);
10284            gen_store_fpr32(ctx, fp2, fd);
10285            tcg_temp_free_i32(fp2);
10286            tcg_temp_free_i32(fp1);
10287            tcg_temp_free_i32(fp0);
10288        } else {
10289            /* OPC_RECIP1_S */
10290            check_cp1_64bitmode(ctx);
10291            {
10292                TCGv_i32 fp0 = tcg_temp_new_i32();
10293
10294                gen_load_fpr32(ctx, fp0, fs);
10295                gen_helper_float_recip1_s(fp0, cpu_env, fp0);
10296                gen_store_fpr32(ctx, fp0, fd);
10297                tcg_temp_free_i32(fp0);
10298            }
10299        }
10300        break;
10301    case OPC_MAX_S: /* OPC_RSQRT1_S */
10302        if (ctx->insn_flags & ISA_MIPS_R6) {
10303            /* OPC_MAX_S */
10304            TCGv_i32 fp0 = tcg_temp_new_i32();
10305            TCGv_i32 fp1 = tcg_temp_new_i32();
10306            gen_load_fpr32(ctx, fp0, fs);
10307            gen_load_fpr32(ctx, fp1, ft);
10308            gen_helper_float_max_s(fp1, cpu_env, fp0, fp1);
10309            gen_store_fpr32(ctx, fp1, fd);
10310            tcg_temp_free_i32(fp1);
10311            tcg_temp_free_i32(fp0);
10312        } else {
10313            /* OPC_RSQRT1_S */
10314            check_cp1_64bitmode(ctx);
10315            {
10316                TCGv_i32 fp0 = tcg_temp_new_i32();
10317
10318                gen_load_fpr32(ctx, fp0, fs);
10319                gen_helper_float_rsqrt1_s(fp0, cpu_env, fp0);
10320                gen_store_fpr32(ctx, fp0, fd);
10321                tcg_temp_free_i32(fp0);
10322            }
10323        }
10324        break;
10325    case OPC_MAXA_S: /* OPC_RSQRT2_S */
10326        if (ctx->insn_flags & ISA_MIPS_R6) {
10327            /* OPC_MAXA_S */
10328            TCGv_i32 fp0 = tcg_temp_new_i32();
10329            TCGv_i32 fp1 = tcg_temp_new_i32();
10330            gen_load_fpr32(ctx, fp0, fs);
10331            gen_load_fpr32(ctx, fp1, ft);
10332            gen_helper_float_maxa_s(fp1, cpu_env, fp0, fp1);
10333            gen_store_fpr32(ctx, fp1, fd);
10334            tcg_temp_free_i32(fp1);
10335            tcg_temp_free_i32(fp0);
10336        } else {
10337            /* OPC_RSQRT2_S */
10338            check_cp1_64bitmode(ctx);
10339            {
10340                TCGv_i32 fp0 = tcg_temp_new_i32();
10341                TCGv_i32 fp1 = tcg_temp_new_i32();
10342
10343                gen_load_fpr32(ctx, fp0, fs);
10344                gen_load_fpr32(ctx, fp1, ft);
10345                gen_helper_float_rsqrt2_s(fp0, cpu_env, fp0, fp1);
10346                tcg_temp_free_i32(fp1);
10347                gen_store_fpr32(ctx, fp0, fd);
10348                tcg_temp_free_i32(fp0);
10349            }
10350        }
10351        break;
10352    case OPC_CVT_D_S:
10353        check_cp1_registers(ctx, fd);
10354        {
10355            TCGv_i32 fp32 = tcg_temp_new_i32();
10356            TCGv_i64 fp64 = tcg_temp_new_i64();
10357
10358            gen_load_fpr32(ctx, fp32, fs);
10359            gen_helper_float_cvtd_s(fp64, cpu_env, fp32);
10360            tcg_temp_free_i32(fp32);
10361            gen_store_fpr64(ctx, fp64, fd);
10362            tcg_temp_free_i64(fp64);
10363        }
10364        break;
10365    case OPC_CVT_W_S:
10366        {
10367            TCGv_i32 fp0 = tcg_temp_new_i32();
10368
10369            gen_load_fpr32(ctx, fp0, fs);
10370            if (ctx->nan2008) {
10371                gen_helper_float_cvt_2008_w_s(fp0, cpu_env, fp0);
10372            } else {
10373                gen_helper_float_cvt_w_s(fp0, cpu_env, fp0);
10374            }
10375            gen_store_fpr32(ctx, fp0, fd);
10376            tcg_temp_free_i32(fp0);
10377        }
10378        break;
10379    case OPC_CVT_L_S:
10380        check_cp1_64bitmode(ctx);
10381        {
10382            TCGv_i32 fp32 = tcg_temp_new_i32();
10383            TCGv_i64 fp64 = tcg_temp_new_i64();
10384
10385            gen_load_fpr32(ctx, fp32, fs);
10386            if (ctx->nan2008) {
10387                gen_helper_float_cvt_2008_l_s(fp64, cpu_env, fp32);
10388            } else {
10389                gen_helper_float_cvt_l_s(fp64, cpu_env, fp32);
10390            }
10391            tcg_temp_free_i32(fp32);
10392            gen_store_fpr64(ctx, fp64, fd);
10393            tcg_temp_free_i64(fp64);
10394        }
10395        break;
10396    case OPC_CVT_PS_S:
10397        check_ps(ctx);
10398        {
10399            TCGv_i64 fp64 = tcg_temp_new_i64();
10400            TCGv_i32 fp32_0 = tcg_temp_new_i32();
10401            TCGv_i32 fp32_1 = tcg_temp_new_i32();
10402
10403            gen_load_fpr32(ctx, fp32_0, fs);
10404            gen_load_fpr32(ctx, fp32_1, ft);
10405            tcg_gen_concat_i32_i64(fp64, fp32_1, fp32_0);
10406            tcg_temp_free_i32(fp32_1);
10407            tcg_temp_free_i32(fp32_0);
10408            gen_store_fpr64(ctx, fp64, fd);
10409            tcg_temp_free_i64(fp64);
10410        }
10411        break;
10412    case OPC_CMP_F_S:
10413    case OPC_CMP_UN_S:
10414    case OPC_CMP_EQ_S:
10415    case OPC_CMP_UEQ_S:
10416    case OPC_CMP_OLT_S:
10417    case OPC_CMP_ULT_S:
10418    case OPC_CMP_OLE_S:
10419    case OPC_CMP_ULE_S:
10420    case OPC_CMP_SF_S:
10421    case OPC_CMP_NGLE_S:
10422    case OPC_CMP_SEQ_S:
10423    case OPC_CMP_NGL_S:
10424    case OPC_CMP_LT_S:
10425    case OPC_CMP_NGE_S:
10426    case OPC_CMP_LE_S:
10427    case OPC_CMP_NGT_S:
10428        check_insn_opc_removed(ctx, ISA_MIPS_R6);
10429        if (ctx->opcode & (1 << 6)) {
10430            gen_cmpabs_s(ctx, func - 48, ft, fs, cc);
10431        } else {
10432            gen_cmp_s(ctx, func - 48, ft, fs, cc);
10433        }
10434        break;
10435    case OPC_ADD_D:
10436        check_cp1_registers(ctx, fs | ft | fd);
10437        {
10438            TCGv_i64 fp0 = tcg_temp_new_i64();
10439            TCGv_i64 fp1 = tcg_temp_new_i64();
10440
10441            gen_load_fpr64(ctx, fp0, fs);
10442            gen_load_fpr64(ctx, fp1, ft);
10443            gen_helper_float_add_d(fp0, cpu_env, fp0, fp1);
10444            tcg_temp_free_i64(fp1);
10445            gen_store_fpr64(ctx, fp0, fd);
10446            tcg_temp_free_i64(fp0);
10447        }
10448        break;
10449    case OPC_SUB_D:
10450        check_cp1_registers(ctx, fs | ft | fd);
10451        {
10452            TCGv_i64 fp0 = tcg_temp_new_i64();
10453            TCGv_i64 fp1 = tcg_temp_new_i64();
10454
10455            gen_load_fpr64(ctx, fp0, fs);
10456            gen_load_fpr64(ctx, fp1, ft);
10457            gen_helper_float_sub_d(fp0, cpu_env, fp0, fp1);
10458            tcg_temp_free_i64(fp1);
10459            gen_store_fpr64(ctx, fp0, fd);
10460            tcg_temp_free_i64(fp0);
10461        }
10462        break;
10463    case OPC_MUL_D:
10464        check_cp1_registers(ctx, fs | ft | fd);
10465        {
10466            TCGv_i64 fp0 = tcg_temp_new_i64();
10467            TCGv_i64 fp1 = tcg_temp_new_i64();
10468
10469            gen_load_fpr64(ctx, fp0, fs);
10470            gen_load_fpr64(ctx, fp1, ft);
10471            gen_helper_float_mul_d(fp0, cpu_env, fp0, fp1);
10472            tcg_temp_free_i64(fp1);
10473            gen_store_fpr64(ctx, fp0, fd);
10474            tcg_temp_free_i64(fp0);
10475        }
10476        break;
10477    case OPC_DIV_D:
10478        check_cp1_registers(ctx, fs | ft | fd);
10479        {
10480            TCGv_i64 fp0 = tcg_temp_new_i64();
10481            TCGv_i64 fp1 = tcg_temp_new_i64();
10482
10483            gen_load_fpr64(ctx, fp0, fs);
10484            gen_load_fpr64(ctx, fp1, ft);
10485            gen_helper_float_div_d(fp0, cpu_env, fp0, fp1);
10486            tcg_temp_free_i64(fp1);
10487            gen_store_fpr64(ctx, fp0, fd);
10488            tcg_temp_free_i64(fp0);
10489        }
10490        break;
10491    case OPC_SQRT_D:
10492        check_cp1_registers(ctx, fs | fd);
10493        {
10494            TCGv_i64 fp0 = tcg_temp_new_i64();
10495
10496            gen_load_fpr64(ctx, fp0, fs);
10497            gen_helper_float_sqrt_d(fp0, cpu_env, fp0);
10498            gen_store_fpr64(ctx, fp0, fd);
10499            tcg_temp_free_i64(fp0);
10500        }
10501        break;
10502    case OPC_ABS_D:
10503        check_cp1_registers(ctx, fs | fd);
10504        {
10505            TCGv_i64 fp0 = tcg_temp_new_i64();
10506
10507            gen_load_fpr64(ctx, fp0, fs);
10508            if (ctx->abs2008) {
10509                tcg_gen_andi_i64(fp0, fp0, 0x7fffffffffffffffULL);
10510            } else {
10511                gen_helper_float_abs_d(fp0, fp0);
10512            }
10513            gen_store_fpr64(ctx, fp0, fd);
10514            tcg_temp_free_i64(fp0);
10515        }
10516        break;
10517    case OPC_MOV_D:
10518        check_cp1_registers(ctx, fs | fd);
10519        {
10520            TCGv_i64 fp0 = tcg_temp_new_i64();
10521
10522            gen_load_fpr64(ctx, fp0, fs);
10523            gen_store_fpr64(ctx, fp0, fd);
10524            tcg_temp_free_i64(fp0);
10525        }
10526        break;
10527    case OPC_NEG_D:
10528        check_cp1_registers(ctx, fs | fd);
10529        {
10530            TCGv_i64 fp0 = tcg_temp_new_i64();
10531
10532            gen_load_fpr64(ctx, fp0, fs);
10533            if (ctx->abs2008) {
10534                tcg_gen_xori_i64(fp0, fp0, 1ULL << 63);
10535            } else {
10536                gen_helper_float_chs_d(fp0, fp0);
10537            }
10538            gen_store_fpr64(ctx, fp0, fd);
10539            tcg_temp_free_i64(fp0);
10540        }
10541        break;
10542    case OPC_ROUND_L_D:
10543        check_cp1_64bitmode(ctx);
10544        {
10545            TCGv_i64 fp0 = tcg_temp_new_i64();
10546
10547            gen_load_fpr64(ctx, fp0, fs);
10548            if (ctx->nan2008) {
10549                gen_helper_float_round_2008_l_d(fp0, cpu_env, fp0);
10550            } else {
10551                gen_helper_float_round_l_d(fp0, cpu_env, fp0);
10552            }
10553            gen_store_fpr64(ctx, fp0, fd);
10554            tcg_temp_free_i64(fp0);
10555        }
10556        break;
10557    case OPC_TRUNC_L_D:
10558        check_cp1_64bitmode(ctx);
10559        {
10560            TCGv_i64 fp0 = tcg_temp_new_i64();
10561
10562            gen_load_fpr64(ctx, fp0, fs);
10563            if (ctx->nan2008) {
10564                gen_helper_float_trunc_2008_l_d(fp0, cpu_env, fp0);
10565            } else {
10566                gen_helper_float_trunc_l_d(fp0, cpu_env, fp0);
10567            }
10568            gen_store_fpr64(ctx, fp0, fd);
10569            tcg_temp_free_i64(fp0);
10570        }
10571        break;
10572    case OPC_CEIL_L_D:
10573        check_cp1_64bitmode(ctx);
10574        {
10575            TCGv_i64 fp0 = tcg_temp_new_i64();
10576
10577            gen_load_fpr64(ctx, fp0, fs);
10578            if (ctx->nan2008) {
10579                gen_helper_float_ceil_2008_l_d(fp0, cpu_env, fp0);
10580            } else {
10581                gen_helper_float_ceil_l_d(fp0, cpu_env, fp0);
10582            }
10583            gen_store_fpr64(ctx, fp0, fd);
10584            tcg_temp_free_i64(fp0);
10585        }
10586        break;
10587    case OPC_FLOOR_L_D:
10588        check_cp1_64bitmode(ctx);
10589        {
10590            TCGv_i64 fp0 = tcg_temp_new_i64();
10591
10592            gen_load_fpr64(ctx, fp0, fs);
10593            if (ctx->nan2008) {
10594                gen_helper_float_floor_2008_l_d(fp0, cpu_env, fp0);
10595            } else {
10596                gen_helper_float_floor_l_d(fp0, cpu_env, fp0);
10597            }
10598            gen_store_fpr64(ctx, fp0, fd);
10599            tcg_temp_free_i64(fp0);
10600        }
10601        break;
10602    case OPC_ROUND_W_D:
10603        check_cp1_registers(ctx, fs);
10604        {
10605            TCGv_i32 fp32 = tcg_temp_new_i32();
10606            TCGv_i64 fp64 = tcg_temp_new_i64();
10607
10608            gen_load_fpr64(ctx, fp64, fs);
10609            if (ctx->nan2008) {
10610                gen_helper_float_round_2008_w_d(fp32, cpu_env, fp64);
10611            } else {
10612                gen_helper_float_round_w_d(fp32, cpu_env, fp64);
10613            }
10614            tcg_temp_free_i64(fp64);
10615            gen_store_fpr32(ctx, fp32, fd);
10616            tcg_temp_free_i32(fp32);
10617        }
10618        break;
10619    case OPC_TRUNC_W_D:
10620        check_cp1_registers(ctx, fs);
10621        {
10622            TCGv_i32 fp32 = tcg_temp_new_i32();
10623            TCGv_i64 fp64 = tcg_temp_new_i64();
10624
10625            gen_load_fpr64(ctx, fp64, fs);
10626            if (ctx->nan2008) {
10627                gen_helper_float_trunc_2008_w_d(fp32, cpu_env, fp64);
10628            } else {
10629                gen_helper_float_trunc_w_d(fp32, cpu_env, fp64);
10630            }
10631            tcg_temp_free_i64(fp64);
10632            gen_store_fpr32(ctx, fp32, fd);
10633            tcg_temp_free_i32(fp32);
10634        }
10635        break;
10636    case OPC_CEIL_W_D:
10637        check_cp1_registers(ctx, fs);
10638        {
10639            TCGv_i32 fp32 = tcg_temp_new_i32();
10640            TCGv_i64 fp64 = tcg_temp_new_i64();
10641
10642            gen_load_fpr64(ctx, fp64, fs);
10643            if (ctx->nan2008) {
10644                gen_helper_float_ceil_2008_w_d(fp32, cpu_env, fp64);
10645            } else {
10646                gen_helper_float_ceil_w_d(fp32, cpu_env, fp64);
10647            }
10648            tcg_temp_free_i64(fp64);
10649            gen_store_fpr32(ctx, fp32, fd);
10650            tcg_temp_free_i32(fp32);
10651        }
10652        break;
10653    case OPC_FLOOR_W_D:
10654        check_cp1_registers(ctx, fs);
10655        {
10656            TCGv_i32 fp32 = tcg_temp_new_i32();
10657            TCGv_i64 fp64 = tcg_temp_new_i64();
10658
10659            gen_load_fpr64(ctx, fp64, fs);
10660            if (ctx->nan2008) {
10661                gen_helper_float_floor_2008_w_d(fp32, cpu_env, fp64);
10662            } else {
10663                gen_helper_float_floor_w_d(fp32, cpu_env, fp64);
10664            }
10665            tcg_temp_free_i64(fp64);
10666            gen_store_fpr32(ctx, fp32, fd);
10667            tcg_temp_free_i32(fp32);
10668        }
10669        break;
10670    case OPC_SEL_D:
10671        check_insn(ctx, ISA_MIPS_R6);
10672        gen_sel_d(ctx, op1, fd, ft, fs);
10673        break;
10674    case OPC_SELEQZ_D:
10675        check_insn(ctx, ISA_MIPS_R6);
10676        gen_sel_d(ctx, op1, fd, ft, fs);
10677        break;
10678    case OPC_SELNEZ_D:
10679        check_insn(ctx, ISA_MIPS_R6);
10680        gen_sel_d(ctx, op1, fd, ft, fs);
10681        break;
10682    case OPC_MOVCF_D:
10683        check_insn_opc_removed(ctx, ISA_MIPS_R6);
10684        gen_movcf_d(ctx, fs, fd, (ft >> 2) & 0x7, ft & 0x1);
10685        break;
10686    case OPC_MOVZ_D:
10687        check_insn_opc_removed(ctx, ISA_MIPS_R6);
10688        {
10689            TCGLabel *l1 = gen_new_label();
10690            TCGv_i64 fp0;
10691
10692            if (ft != 0) {
10693                tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[ft], 0, l1);
10694            }
10695            fp0 = tcg_temp_new_i64();
10696            gen_load_fpr64(ctx, fp0, fs);
10697            gen_store_fpr64(ctx, fp0, fd);
10698            tcg_temp_free_i64(fp0);
10699            gen_set_label(l1);
10700        }
10701        break;
10702    case OPC_MOVN_D:
10703        check_insn_opc_removed(ctx, ISA_MIPS_R6);
10704        {
10705            TCGLabel *l1 = gen_new_label();
10706            TCGv_i64 fp0;
10707
10708            if (ft != 0) {
10709                tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[ft], 0, l1);
10710                fp0 = tcg_temp_new_i64();
10711                gen_load_fpr64(ctx, fp0, fs);
10712                gen_store_fpr64(ctx, fp0, fd);
10713                tcg_temp_free_i64(fp0);
10714                gen_set_label(l1);
10715            }
10716        }
10717        break;
10718    case OPC_RECIP_D:
10719        check_cp1_registers(ctx, fs | fd);
10720        {
10721            TCGv_i64 fp0 = tcg_temp_new_i64();
10722
10723            gen_load_fpr64(ctx, fp0, fs);
10724            gen_helper_float_recip_d(fp0, cpu_env, fp0);
10725            gen_store_fpr64(ctx, fp0, fd);
10726            tcg_temp_free_i64(fp0);
10727        }
10728        break;
10729    case OPC_RSQRT_D:
10730        check_cp1_registers(ctx, fs | fd);
10731        {
10732            TCGv_i64 fp0 = tcg_temp_new_i64();
10733
10734            gen_load_fpr64(ctx, fp0, fs);
10735            gen_helper_float_rsqrt_d(fp0, cpu_env, fp0);
10736            gen_store_fpr64(ctx, fp0, fd);
10737            tcg_temp_free_i64(fp0);
10738        }
10739        break;
10740    case OPC_MADDF_D:
10741        check_insn(ctx, ISA_MIPS_R6);
10742        {
10743            TCGv_i64 fp0 = tcg_temp_new_i64();
10744            TCGv_i64 fp1 = tcg_temp_new_i64();
10745            TCGv_i64 fp2 = tcg_temp_new_i64();
10746            gen_load_fpr64(ctx, fp0, fs);
10747            gen_load_fpr64(ctx, fp1, ft);
10748            gen_load_fpr64(ctx, fp2, fd);
10749            gen_helper_float_maddf_d(fp2, cpu_env, fp0, fp1, fp2);
10750            gen_store_fpr64(ctx, fp2, fd);
10751            tcg_temp_free_i64(fp2);
10752            tcg_temp_free_i64(fp1);
10753            tcg_temp_free_i64(fp0);
10754        }
10755        break;
10756    case OPC_MSUBF_D:
10757        check_insn(ctx, ISA_MIPS_R6);
10758        {
10759            TCGv_i64 fp0 = tcg_temp_new_i64();
10760            TCGv_i64 fp1 = tcg_temp_new_i64();
10761            TCGv_i64 fp2 = tcg_temp_new_i64();
10762            gen_load_fpr64(ctx, fp0, fs);
10763            gen_load_fpr64(ctx, fp1, ft);
10764            gen_load_fpr64(ctx, fp2, fd);
10765            gen_helper_float_msubf_d(fp2, cpu_env, fp0, fp1, fp2);
10766            gen_store_fpr64(ctx, fp2, fd);
10767            tcg_temp_free_i64(fp2);
10768            tcg_temp_free_i64(fp1);
10769            tcg_temp_free_i64(fp0);
10770        }
10771        break;
10772    case OPC_RINT_D:
10773        check_insn(ctx, ISA_MIPS_R6);
10774        {
10775            TCGv_i64 fp0 = tcg_temp_new_i64();
10776            gen_load_fpr64(ctx, fp0, fs);
10777            gen_helper_float_rint_d(fp0, cpu_env, fp0);
10778            gen_store_fpr64(ctx, fp0, fd);
10779            tcg_temp_free_i64(fp0);
10780        }
10781        break;
10782    case OPC_CLASS_D:
10783        check_insn(ctx, ISA_MIPS_R6);
10784        {
10785            TCGv_i64 fp0 = tcg_temp_new_i64();
10786            gen_load_fpr64(ctx, fp0, fs);
10787            gen_helper_float_class_d(fp0, cpu_env, fp0);
10788            gen_store_fpr64(ctx, fp0, fd);
10789            tcg_temp_free_i64(fp0);
10790        }
10791        break;
10792    case OPC_MIN_D: /* OPC_RECIP2_D */
10793        if (ctx->insn_flags & ISA_MIPS_R6) {
10794            /* OPC_MIN_D */
10795            TCGv_i64 fp0 = tcg_temp_new_i64();
10796            TCGv_i64 fp1 = tcg_temp_new_i64();
10797            gen_load_fpr64(ctx, fp0, fs);
10798            gen_load_fpr64(ctx, fp1, ft);
10799            gen_helper_float_min_d(fp1, cpu_env, fp0, fp1);
10800            gen_store_fpr64(ctx, fp1, fd);
10801            tcg_temp_free_i64(fp1);
10802            tcg_temp_free_i64(fp0);
10803        } else {
10804            /* OPC_RECIP2_D */
10805            check_cp1_64bitmode(ctx);
10806            {
10807                TCGv_i64 fp0 = tcg_temp_new_i64();
10808                TCGv_i64 fp1 = tcg_temp_new_i64();
10809
10810                gen_load_fpr64(ctx, fp0, fs);
10811                gen_load_fpr64(ctx, fp1, ft);
10812                gen_helper_float_recip2_d(fp0, cpu_env, fp0, fp1);
10813                tcg_temp_free_i64(fp1);
10814                gen_store_fpr64(ctx, fp0, fd);
10815                tcg_temp_free_i64(fp0);
10816            }
10817        }
10818        break;
10819    case OPC_MINA_D: /* OPC_RECIP1_D */
10820        if (ctx->insn_flags & ISA_MIPS_R6) {
10821            /* OPC_MINA_D */
10822            TCGv_i64 fp0 = tcg_temp_new_i64();
10823            TCGv_i64 fp1 = tcg_temp_new_i64();
10824            gen_load_fpr64(ctx, fp0, fs);
10825            gen_load_fpr64(ctx, fp1, ft);
10826            gen_helper_float_mina_d(fp1, cpu_env, fp0, fp1);
10827            gen_store_fpr64(ctx, fp1, fd);
10828            tcg_temp_free_i64(fp1);
10829            tcg_temp_free_i64(fp0);
10830        } else {
10831            /* OPC_RECIP1_D */
10832            check_cp1_64bitmode(ctx);
10833            {
10834                TCGv_i64 fp0 = tcg_temp_new_i64();
10835
10836                gen_load_fpr64(ctx, fp0, fs);
10837                gen_helper_float_recip1_d(fp0, cpu_env, fp0);
10838                gen_store_fpr64(ctx, fp0, fd);
10839                tcg_temp_free_i64(fp0);
10840            }
10841        }
10842        break;
10843    case OPC_MAX_D: /*  OPC_RSQRT1_D */
10844        if (ctx->insn_flags & ISA_MIPS_R6) {
10845            /* OPC_MAX_D */
10846            TCGv_i64 fp0 = tcg_temp_new_i64();
10847            TCGv_i64 fp1 = tcg_temp_new_i64();
10848            gen_load_fpr64(ctx, fp0, fs);
10849            gen_load_fpr64(ctx, fp1, ft);
10850            gen_helper_float_max_d(fp1, cpu_env, fp0, fp1);
10851            gen_store_fpr64(ctx, fp1, fd);
10852            tcg_temp_free_i64(fp1);
10853            tcg_temp_free_i64(fp0);
10854        } else {
10855            /* OPC_RSQRT1_D */
10856            check_cp1_64bitmode(ctx);
10857            {
10858                TCGv_i64 fp0 = tcg_temp_new_i64();
10859
10860                gen_load_fpr64(ctx, fp0, fs);
10861                gen_helper_float_rsqrt1_d(fp0, cpu_env, fp0);
10862                gen_store_fpr64(ctx, fp0, fd);
10863                tcg_temp_free_i64(fp0);
10864            }
10865        }
10866        break;
10867    case OPC_MAXA_D: /* OPC_RSQRT2_D */
10868        if (ctx->insn_flags & ISA_MIPS_R6) {
10869            /* OPC_MAXA_D */
10870            TCGv_i64 fp0 = tcg_temp_new_i64();
10871            TCGv_i64 fp1 = tcg_temp_new_i64();
10872            gen_load_fpr64(ctx, fp0, fs);
10873            gen_load_fpr64(ctx, fp1, ft);
10874            gen_helper_float_maxa_d(fp1, cpu_env, fp0, fp1);
10875            gen_store_fpr64(ctx, fp1, fd);
10876            tcg_temp_free_i64(fp1);
10877            tcg_temp_free_i64(fp0);
10878        } else {
10879            /* OPC_RSQRT2_D */
10880            check_cp1_64bitmode(ctx);
10881            {
10882                TCGv_i64 fp0 = tcg_temp_new_i64();
10883                TCGv_i64 fp1 = tcg_temp_new_i64();
10884
10885                gen_load_fpr64(ctx, fp0, fs);
10886                gen_load_fpr64(ctx, fp1, ft);
10887                gen_helper_float_rsqrt2_d(fp0, cpu_env, fp0, fp1);
10888                tcg_temp_free_i64(fp1);
10889                gen_store_fpr64(ctx, fp0, fd);
10890                tcg_temp_free_i64(fp0);
10891            }
10892        }
10893        break;
10894    case OPC_CMP_F_D:
10895    case OPC_CMP_UN_D:
10896    case OPC_CMP_EQ_D:
10897    case OPC_CMP_UEQ_D:
10898    case OPC_CMP_OLT_D:
10899    case OPC_CMP_ULT_D:
10900    case OPC_CMP_OLE_D:
10901    case OPC_CMP_ULE_D:
10902    case OPC_CMP_SF_D:
10903    case OPC_CMP_NGLE_D:
10904    case OPC_CMP_SEQ_D:
10905    case OPC_CMP_NGL_D:
10906    case OPC_CMP_LT_D:
10907    case OPC_CMP_NGE_D:
10908    case OPC_CMP_LE_D:
10909    case OPC_CMP_NGT_D:
10910        check_insn_opc_removed(ctx, ISA_MIPS_R6);
10911        if (ctx->opcode & (1 << 6)) {
10912            gen_cmpabs_d(ctx, func - 48, ft, fs, cc);
10913        } else {
10914            gen_cmp_d(ctx, func - 48, ft, fs, cc);
10915        }
10916        break;
10917    case OPC_CVT_S_D:
10918        check_cp1_registers(ctx, fs);
10919        {
10920            TCGv_i32 fp32 = tcg_temp_new_i32();
10921            TCGv_i64 fp64 = tcg_temp_new_i64();
10922
10923            gen_load_fpr64(ctx, fp64, fs);
10924            gen_helper_float_cvts_d(fp32, cpu_env, fp64);
10925            tcg_temp_free_i64(fp64);
10926            gen_store_fpr32(ctx, fp32, fd);
10927            tcg_temp_free_i32(fp32);
10928        }
10929        break;
10930    case OPC_CVT_W_D:
10931        check_cp1_registers(ctx, fs);
10932        {
10933            TCGv_i32 fp32 = tcg_temp_new_i32();
10934            TCGv_i64 fp64 = tcg_temp_new_i64();
10935
10936            gen_load_fpr64(ctx, fp64, fs);
10937            if (ctx->nan2008) {
10938                gen_helper_float_cvt_2008_w_d(fp32, cpu_env, fp64);
10939            } else {
10940                gen_helper_float_cvt_w_d(fp32, cpu_env, fp64);
10941            }
10942            tcg_temp_free_i64(fp64);
10943            gen_store_fpr32(ctx, fp32, fd);
10944            tcg_temp_free_i32(fp32);
10945        }
10946        break;
10947    case OPC_CVT_L_D:
10948        check_cp1_64bitmode(ctx);
10949        {
10950            TCGv_i64 fp0 = tcg_temp_new_i64();
10951
10952            gen_load_fpr64(ctx, fp0, fs);
10953            if (ctx->nan2008) {
10954                gen_helper_float_cvt_2008_l_d(fp0, cpu_env, fp0);
10955            } else {
10956                gen_helper_float_cvt_l_d(fp0, cpu_env, fp0);
10957            }
10958            gen_store_fpr64(ctx, fp0, fd);
10959            tcg_temp_free_i64(fp0);
10960        }
10961        break;
10962    case OPC_CVT_S_W:
10963        {
10964            TCGv_i32 fp0 = tcg_temp_new_i32();
10965
10966            gen_load_fpr32(ctx, fp0, fs);
10967            gen_helper_float_cvts_w(fp0, cpu_env, fp0);
10968            gen_store_fpr32(ctx, fp0, fd);
10969            tcg_temp_free_i32(fp0);
10970        }
10971        break;
10972    case OPC_CVT_D_W:
10973        check_cp1_registers(ctx, fd);
10974        {
10975            TCGv_i32 fp32 = tcg_temp_new_i32();
10976            TCGv_i64 fp64 = tcg_temp_new_i64();
10977
10978            gen_load_fpr32(ctx, fp32, fs);
10979            gen_helper_float_cvtd_w(fp64, cpu_env, fp32);
10980            tcg_temp_free_i32(fp32);
10981            gen_store_fpr64(ctx, fp64, fd);
10982            tcg_temp_free_i64(fp64);
10983        }
10984        break;
10985    case OPC_CVT_S_L:
10986        check_cp1_64bitmode(ctx);
10987        {
10988            TCGv_i32 fp32 = tcg_temp_new_i32();
10989            TCGv_i64 fp64 = tcg_temp_new_i64();
10990
10991            gen_load_fpr64(ctx, fp64, fs);
10992            gen_helper_float_cvts_l(fp32, cpu_env, fp64);
10993            tcg_temp_free_i64(fp64);
10994            gen_store_fpr32(ctx, fp32, fd);
10995            tcg_temp_free_i32(fp32);
10996        }
10997        break;
10998    case OPC_CVT_D_L:
10999        check_cp1_64bitmode(ctx);
11000        {
11001            TCGv_i64 fp0 = tcg_temp_new_i64();
11002
11003            gen_load_fpr64(ctx, fp0, fs);
11004            gen_helper_float_cvtd_l(fp0, cpu_env, fp0);
11005            gen_store_fpr64(ctx, fp0, fd);
11006            tcg_temp_free_i64(fp0);
11007        }
11008        break;
11009    case OPC_CVT_PS_PW:
11010        check_ps(ctx);
11011        {
11012            TCGv_i64 fp0 = tcg_temp_new_i64();
11013
11014            gen_load_fpr64(ctx, fp0, fs);
11015            gen_helper_float_cvtps_pw(fp0, cpu_env, fp0);
11016            gen_store_fpr64(ctx, fp0, fd);
11017            tcg_temp_free_i64(fp0);
11018        }
11019        break;
11020    case OPC_ADD_PS:
11021        check_ps(ctx);
11022        {
11023            TCGv_i64 fp0 = tcg_temp_new_i64();
11024            TCGv_i64 fp1 = tcg_temp_new_i64();
11025
11026            gen_load_fpr64(ctx, fp0, fs);
11027            gen_load_fpr64(ctx, fp1, ft);
11028            gen_helper_float_add_ps(fp0, cpu_env, fp0, fp1);
11029            tcg_temp_free_i64(fp1);
11030            gen_store_fpr64(ctx, fp0, fd);
11031            tcg_temp_free_i64(fp0);
11032        }
11033        break;
11034    case OPC_SUB_PS:
11035        check_ps(ctx);
11036        {
11037            TCGv_i64 fp0 = tcg_temp_new_i64();
11038            TCGv_i64 fp1 = tcg_temp_new_i64();
11039
11040            gen_load_fpr64(ctx, fp0, fs);
11041            gen_load_fpr64(ctx, fp1, ft);
11042            gen_helper_float_sub_ps(fp0, cpu_env, fp0, fp1);
11043            tcg_temp_free_i64(fp1);
11044            gen_store_fpr64(ctx, fp0, fd);
11045            tcg_temp_free_i64(fp0);
11046        }
11047        break;
11048    case OPC_MUL_PS:
11049        check_ps(ctx);
11050        {
11051            TCGv_i64 fp0 = tcg_temp_new_i64();
11052            TCGv_i64 fp1 = tcg_temp_new_i64();
11053
11054            gen_load_fpr64(ctx, fp0, fs);
11055            gen_load_fpr64(ctx, fp1, ft);
11056            gen_helper_float_mul_ps(fp0, cpu_env, fp0, fp1);
11057            tcg_temp_free_i64(fp1);
11058            gen_store_fpr64(ctx, fp0, fd);
11059            tcg_temp_free_i64(fp0);
11060        }
11061        break;
11062    case OPC_ABS_PS:
11063        check_ps(ctx);
11064        {
11065            TCGv_i64 fp0 = tcg_temp_new_i64();
11066
11067            gen_load_fpr64(ctx, fp0, fs);
11068            gen_helper_float_abs_ps(fp0, fp0);
11069            gen_store_fpr64(ctx, fp0, fd);
11070            tcg_temp_free_i64(fp0);
11071        }
11072        break;
11073    case OPC_MOV_PS:
11074        check_ps(ctx);
11075        {
11076            TCGv_i64 fp0 = tcg_temp_new_i64();
11077
11078            gen_load_fpr64(ctx, fp0, fs);
11079            gen_store_fpr64(ctx, fp0, fd);
11080            tcg_temp_free_i64(fp0);
11081        }
11082        break;
11083    case OPC_NEG_PS:
11084        check_ps(ctx);
11085        {
11086            TCGv_i64 fp0 = tcg_temp_new_i64();
11087
11088            gen_load_fpr64(ctx, fp0, fs);
11089            gen_helper_float_chs_ps(fp0, fp0);
11090            gen_store_fpr64(ctx, fp0, fd);
11091            tcg_temp_free_i64(fp0);
11092        }
11093        break;
11094    case OPC_MOVCF_PS:
11095        check_ps(ctx);
11096        gen_movcf_ps(ctx, fs, fd, (ft >> 2) & 0x7, ft & 0x1);
11097        break;
11098    case OPC_MOVZ_PS:
11099        check_ps(ctx);
11100        {
11101            TCGLabel *l1 = gen_new_label();
11102            TCGv_i64 fp0;
11103
11104            if (ft != 0) {
11105                tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[ft], 0, l1);
11106            }
11107            fp0 = tcg_temp_new_i64();
11108            gen_load_fpr64(ctx, fp0, fs);
11109            gen_store_fpr64(ctx, fp0, fd);
11110            tcg_temp_free_i64(fp0);
11111            gen_set_label(l1);
11112        }
11113        break;
11114    case OPC_MOVN_PS:
11115        check_ps(ctx);
11116        {
11117            TCGLabel *l1 = gen_new_label();
11118            TCGv_i64 fp0;
11119
11120            if (ft != 0) {
11121                tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[ft], 0, l1);
11122                fp0 = tcg_temp_new_i64();
11123                gen_load_fpr64(ctx, fp0, fs);
11124                gen_store_fpr64(ctx, fp0, fd);
11125                tcg_temp_free_i64(fp0);
11126                gen_set_label(l1);
11127            }
11128        }
11129        break;
11130    case OPC_ADDR_PS:
11131        check_ps(ctx);
11132        {
11133            TCGv_i64 fp0 = tcg_temp_new_i64();
11134            TCGv_i64 fp1 = tcg_temp_new_i64();
11135
11136            gen_load_fpr64(ctx, fp0, ft);
11137            gen_load_fpr64(ctx, fp1, fs);
11138            gen_helper_float_addr_ps(fp0, cpu_env, fp0, fp1);
11139            tcg_temp_free_i64(fp1);
11140            gen_store_fpr64(ctx, fp0, fd);
11141            tcg_temp_free_i64(fp0);
11142        }
11143        break;
11144    case OPC_MULR_PS:
11145        check_ps(ctx);
11146        {
11147            TCGv_i64 fp0 = tcg_temp_new_i64();
11148            TCGv_i64 fp1 = tcg_temp_new_i64();
11149
11150            gen_load_fpr64(ctx, fp0, ft);
11151            gen_load_fpr64(ctx, fp1, fs);
11152            gen_helper_float_mulr_ps(fp0, cpu_env, fp0, fp1);
11153            tcg_temp_free_i64(fp1);
11154            gen_store_fpr64(ctx, fp0, fd);
11155            tcg_temp_free_i64(fp0);
11156        }
11157        break;
11158    case OPC_RECIP2_PS:
11159        check_ps(ctx);
11160        {
11161            TCGv_i64 fp0 = tcg_temp_new_i64();
11162            TCGv_i64 fp1 = tcg_temp_new_i64();
11163
11164            gen_load_fpr64(ctx, fp0, fs);
11165            gen_load_fpr64(ctx, fp1, ft);
11166            gen_helper_float_recip2_ps(fp0, cpu_env, fp0, fp1);
11167            tcg_temp_free_i64(fp1);
11168            gen_store_fpr64(ctx, fp0, fd);
11169            tcg_temp_free_i64(fp0);
11170        }
11171        break;
11172    case OPC_RECIP1_PS:
11173        check_ps(ctx);
11174        {
11175            TCGv_i64 fp0 = tcg_temp_new_i64();
11176
11177            gen_load_fpr64(ctx, fp0, fs);
11178            gen_helper_float_recip1_ps(fp0, cpu_env, fp0);
11179            gen_store_fpr64(ctx, fp0, fd);
11180            tcg_temp_free_i64(fp0);
11181        }
11182        break;
11183    case OPC_RSQRT1_PS:
11184        check_ps(ctx);
11185        {
11186            TCGv_i64 fp0 = tcg_temp_new_i64();
11187
11188            gen_load_fpr64(ctx, fp0, fs);
11189            gen_helper_float_rsqrt1_ps(fp0, cpu_env, fp0);
11190            gen_store_fpr64(ctx, fp0, fd);
11191            tcg_temp_free_i64(fp0);
11192        }
11193        break;
11194    case OPC_RSQRT2_PS:
11195        check_ps(ctx);
11196        {
11197            TCGv_i64 fp0 = tcg_temp_new_i64();
11198            TCGv_i64 fp1 = tcg_temp_new_i64();
11199
11200            gen_load_fpr64(ctx, fp0, fs);
11201            gen_load_fpr64(ctx, fp1, ft);
11202            gen_helper_float_rsqrt2_ps(fp0, cpu_env, fp0, fp1);
11203            tcg_temp_free_i64(fp1);
11204            gen_store_fpr64(ctx, fp0, fd);
11205            tcg_temp_free_i64(fp0);
11206        }
11207        break;
11208    case OPC_CVT_S_PU:
11209        check_cp1_64bitmode(ctx);
11210        {
11211            TCGv_i32 fp0 = tcg_temp_new_i32();
11212
11213            gen_load_fpr32h(ctx, fp0, fs);
11214            gen_helper_float_cvts_pu(fp0, cpu_env, fp0);
11215            gen_store_fpr32(ctx, fp0, fd);
11216            tcg_temp_free_i32(fp0);
11217        }
11218        break;
11219    case OPC_CVT_PW_PS:
11220        check_ps(ctx);
11221        {
11222            TCGv_i64 fp0 = tcg_temp_new_i64();
11223
11224            gen_load_fpr64(ctx, fp0, fs);
11225            gen_helper_float_cvtpw_ps(fp0, cpu_env, fp0);
11226            gen_store_fpr64(ctx, fp0, fd);
11227            tcg_temp_free_i64(fp0);
11228        }
11229        break;
11230    case OPC_CVT_S_PL:
11231        check_cp1_64bitmode(ctx);
11232        {
11233            TCGv_i32 fp0 = tcg_temp_new_i32();
11234
11235            gen_load_fpr32(ctx, fp0, fs);
11236            gen_helper_float_cvts_pl(fp0, cpu_env, fp0);
11237            gen_store_fpr32(ctx, fp0, fd);
11238            tcg_temp_free_i32(fp0);
11239        }
11240        break;
11241    case OPC_PLL_PS:
11242        check_ps(ctx);
11243        {
11244            TCGv_i32 fp0 = tcg_temp_new_i32();
11245            TCGv_i32 fp1 = tcg_temp_new_i32();
11246
11247            gen_load_fpr32(ctx, fp0, fs);
11248            gen_load_fpr32(ctx, fp1, ft);
11249            gen_store_fpr32h(ctx, fp0, fd);
11250            gen_store_fpr32(ctx, fp1, fd);
11251            tcg_temp_free_i32(fp0);
11252            tcg_temp_free_i32(fp1);
11253        }
11254        break;
11255    case OPC_PLU_PS:
11256        check_ps(ctx);
11257        {
11258            TCGv_i32 fp0 = tcg_temp_new_i32();
11259            TCGv_i32 fp1 = tcg_temp_new_i32();
11260
11261            gen_load_fpr32(ctx, fp0, fs);
11262            gen_load_fpr32h(ctx, fp1, ft);
11263            gen_store_fpr32(ctx, fp1, fd);
11264            gen_store_fpr32h(ctx, fp0, fd);
11265            tcg_temp_free_i32(fp0);
11266            tcg_temp_free_i32(fp1);
11267        }
11268        break;
11269    case OPC_PUL_PS:
11270        check_ps(ctx);
11271        {
11272            TCGv_i32 fp0 = tcg_temp_new_i32();
11273            TCGv_i32 fp1 = tcg_temp_new_i32();
11274
11275            gen_load_fpr32h(ctx, fp0, fs);
11276            gen_load_fpr32(ctx, fp1, ft);
11277            gen_store_fpr32(ctx, fp1, fd);
11278            gen_store_fpr32h(ctx, fp0, fd);
11279            tcg_temp_free_i32(fp0);
11280            tcg_temp_free_i32(fp1);
11281        }
11282        break;
11283    case OPC_PUU_PS:
11284        check_ps(ctx);
11285        {
11286            TCGv_i32 fp0 = tcg_temp_new_i32();
11287            TCGv_i32 fp1 = tcg_temp_new_i32();
11288
11289            gen_load_fpr32h(ctx, fp0, fs);
11290            gen_load_fpr32h(ctx, fp1, ft);
11291            gen_store_fpr32(ctx, fp1, fd);
11292            gen_store_fpr32h(ctx, fp0, fd);
11293            tcg_temp_free_i32(fp0);
11294            tcg_temp_free_i32(fp1);
11295        }
11296        break;
11297    case OPC_CMP_F_PS:
11298    case OPC_CMP_UN_PS:
11299    case OPC_CMP_EQ_PS:
11300    case OPC_CMP_UEQ_PS:
11301    case OPC_CMP_OLT_PS:
11302    case OPC_CMP_ULT_PS:
11303    case OPC_CMP_OLE_PS:
11304    case OPC_CMP_ULE_PS:
11305    case OPC_CMP_SF_PS:
11306    case OPC_CMP_NGLE_PS:
11307    case OPC_CMP_SEQ_PS:
11308    case OPC_CMP_NGL_PS:
11309    case OPC_CMP_LT_PS:
11310    case OPC_CMP_NGE_PS:
11311    case OPC_CMP_LE_PS:
11312    case OPC_CMP_NGT_PS:
11313        if (ctx->opcode & (1 << 6)) {
11314            gen_cmpabs_ps(ctx, func - 48, ft, fs, cc);
11315        } else {
11316            gen_cmp_ps(ctx, func - 48, ft, fs, cc);
11317        }
11318        break;
11319    default:
11320        MIPS_INVAL("farith");
11321        gen_reserved_instruction(ctx);
11322        return;
11323    }
11324}
11325
11326/* Coprocessor 3 (FPU) */
11327static void gen_flt3_ldst(DisasContext *ctx, uint32_t opc,
11328                          int fd, int fs, int base, int index)
11329{
11330    TCGv t0 = tcg_temp_new();
11331
11332    if (base == 0) {
11333        gen_load_gpr(t0, index);
11334    } else if (index == 0) {
11335        gen_load_gpr(t0, base);
11336    } else {
11337        gen_op_addr_add(ctx, t0, cpu_gpr[base], cpu_gpr[index]);
11338    }
11339    /*
11340     * Don't do NOP if destination is zero: we must perform the actual
11341     * memory access.
11342     */
11343    switch (opc) {
11344    case OPC_LWXC1:
11345        check_cop1x(ctx);
11346        {
11347            TCGv_i32 fp0 = tcg_temp_new_i32();
11348
11349            tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TESL);
11350            tcg_gen_trunc_tl_i32(fp0, t0);
11351            gen_store_fpr32(ctx, fp0, fd);
11352            tcg_temp_free_i32(fp0);
11353        }
11354        break;
11355    case OPC_LDXC1:
11356        check_cop1x(ctx);
11357        check_cp1_registers(ctx, fd);
11358        {
11359            TCGv_i64 fp0 = tcg_temp_new_i64();
11360            tcg_gen_qemu_ld_i64(fp0, t0, ctx->mem_idx, MO_TEUQ);
11361            gen_store_fpr64(ctx, fp0, fd);
11362            tcg_temp_free_i64(fp0);
11363        }
11364        break;
11365    case OPC_LUXC1:
11366        check_cp1_64bitmode(ctx);
11367        tcg_gen_andi_tl(t0, t0, ~0x7);
11368        {
11369            TCGv_i64 fp0 = tcg_temp_new_i64();
11370
11371            tcg_gen_qemu_ld_i64(fp0, t0, ctx->mem_idx, MO_TEUQ);
11372            gen_store_fpr64(ctx, fp0, fd);
11373            tcg_temp_free_i64(fp0);
11374        }
11375        break;
11376    case OPC_SWXC1:
11377        check_cop1x(ctx);
11378        {
11379            TCGv_i32 fp0 = tcg_temp_new_i32();
11380            gen_load_fpr32(ctx, fp0, fs);
11381            tcg_gen_qemu_st_i32(fp0, t0, ctx->mem_idx, MO_TEUL);
11382            tcg_temp_free_i32(fp0);
11383        }
11384        break;
11385    case OPC_SDXC1:
11386        check_cop1x(ctx);
11387        check_cp1_registers(ctx, fs);
11388        {
11389            TCGv_i64 fp0 = tcg_temp_new_i64();
11390            gen_load_fpr64(ctx, fp0, fs);
11391            tcg_gen_qemu_st_i64(fp0, t0, ctx->mem_idx, MO_TEUQ);
11392            tcg_temp_free_i64(fp0);
11393        }
11394        break;
11395    case OPC_SUXC1:
11396        check_cp1_64bitmode(ctx);
11397        tcg_gen_andi_tl(t0, t0, ~0x7);
11398        {
11399            TCGv_i64 fp0 = tcg_temp_new_i64();
11400            gen_load_fpr64(ctx, fp0, fs);
11401            tcg_gen_qemu_st_i64(fp0, t0, ctx->mem_idx, MO_TEUQ);
11402            tcg_temp_free_i64(fp0);
11403        }
11404        break;
11405    }
11406    tcg_temp_free(t0);
11407}
11408
11409static void gen_flt3_arith(DisasContext *ctx, uint32_t opc,
11410                           int fd, int fr, int fs, int ft)
11411{
11412    switch (opc) {
11413    case OPC_ALNV_PS:
11414        check_ps(ctx);
11415        {
11416            TCGv t0 = tcg_temp_local_new();
11417            TCGv_i32 fp = tcg_temp_new_i32();
11418            TCGv_i32 fph = tcg_temp_new_i32();
11419            TCGLabel *l1 = gen_new_label();
11420            TCGLabel *l2 = gen_new_label();
11421
11422            gen_load_gpr(t0, fr);
11423            tcg_gen_andi_tl(t0, t0, 0x7);
11424
11425            tcg_gen_brcondi_tl(TCG_COND_NE, t0, 0, l1);
11426            gen_load_fpr32(ctx, fp, fs);
11427            gen_load_fpr32h(ctx, fph, fs);
11428            gen_store_fpr32(ctx, fp, fd);
11429            gen_store_fpr32h(ctx, fph, fd);
11430            tcg_gen_br(l2);
11431            gen_set_label(l1);
11432            tcg_gen_brcondi_tl(TCG_COND_NE, t0, 4, l2);
11433            tcg_temp_free(t0);
11434            if (cpu_is_bigendian(ctx)) {
11435                gen_load_fpr32(ctx, fp, fs);
11436                gen_load_fpr32h(ctx, fph, ft);
11437                gen_store_fpr32h(ctx, fp, fd);
11438                gen_store_fpr32(ctx, fph, fd);
11439            } else {
11440                gen_load_fpr32h(ctx, fph, fs);
11441                gen_load_fpr32(ctx, fp, ft);
11442                gen_store_fpr32(ctx, fph, fd);
11443                gen_store_fpr32h(ctx, fp, fd);
11444            }
11445            gen_set_label(l2);
11446            tcg_temp_free_i32(fp);
11447            tcg_temp_free_i32(fph);
11448        }
11449        break;
11450    case OPC_MADD_S:
11451        check_cop1x(ctx);
11452        {
11453            TCGv_i32 fp0 = tcg_temp_new_i32();
11454            TCGv_i32 fp1 = tcg_temp_new_i32();
11455            TCGv_i32 fp2 = tcg_temp_new_i32();
11456
11457            gen_load_fpr32(ctx, fp0, fs);
11458            gen_load_fpr32(ctx, fp1, ft);
11459            gen_load_fpr32(ctx, fp2, fr);
11460            gen_helper_float_madd_s(fp2, cpu_env, fp0, fp1, fp2);
11461            tcg_temp_free_i32(fp0);
11462            tcg_temp_free_i32(fp1);
11463            gen_store_fpr32(ctx, fp2, fd);
11464            tcg_temp_free_i32(fp2);
11465        }
11466        break;
11467    case OPC_MADD_D:
11468        check_cop1x(ctx);
11469        check_cp1_registers(ctx, fd | fs | ft | fr);
11470        {
11471            TCGv_i64 fp0 = tcg_temp_new_i64();
11472            TCGv_i64 fp1 = tcg_temp_new_i64();
11473            TCGv_i64 fp2 = tcg_temp_new_i64();
11474
11475            gen_load_fpr64(ctx, fp0, fs);
11476            gen_load_fpr64(ctx, fp1, ft);
11477            gen_load_fpr64(ctx, fp2, fr);
11478            gen_helper_float_madd_d(fp2, cpu_env, fp0, fp1, fp2);
11479            tcg_temp_free_i64(fp0);
11480            tcg_temp_free_i64(fp1);
11481            gen_store_fpr64(ctx, fp2, fd);
11482            tcg_temp_free_i64(fp2);
11483        }
11484        break;
11485    case OPC_MADD_PS:
11486        check_ps(ctx);
11487        {
11488            TCGv_i64 fp0 = tcg_temp_new_i64();
11489            TCGv_i64 fp1 = tcg_temp_new_i64();
11490            TCGv_i64 fp2 = tcg_temp_new_i64();
11491
11492            gen_load_fpr64(ctx, fp0, fs);
11493            gen_load_fpr64(ctx, fp1, ft);
11494            gen_load_fpr64(ctx, fp2, fr);
11495            gen_helper_float_madd_ps(fp2, cpu_env, fp0, fp1, fp2);
11496            tcg_temp_free_i64(fp0);
11497            tcg_temp_free_i64(fp1);
11498            gen_store_fpr64(ctx, fp2, fd);
11499            tcg_temp_free_i64(fp2);
11500        }
11501        break;
11502    case OPC_MSUB_S:
11503        check_cop1x(ctx);
11504        {
11505            TCGv_i32 fp0 = tcg_temp_new_i32();
11506            TCGv_i32 fp1 = tcg_temp_new_i32();
11507            TCGv_i32 fp2 = tcg_temp_new_i32();
11508
11509            gen_load_fpr32(ctx, fp0, fs);
11510            gen_load_fpr32(ctx, fp1, ft);
11511            gen_load_fpr32(ctx, fp2, fr);
11512            gen_helper_float_msub_s(fp2, cpu_env, fp0, fp1, fp2);
11513            tcg_temp_free_i32(fp0);
11514            tcg_temp_free_i32(fp1);
11515            gen_store_fpr32(ctx, fp2, fd);
11516            tcg_temp_free_i32(fp2);
11517        }
11518        break;
11519    case OPC_MSUB_D:
11520        check_cop1x(ctx);
11521        check_cp1_registers(ctx, fd | fs | ft | fr);
11522        {
11523            TCGv_i64 fp0 = tcg_temp_new_i64();
11524            TCGv_i64 fp1 = tcg_temp_new_i64();
11525            TCGv_i64 fp2 = tcg_temp_new_i64();
11526
11527            gen_load_fpr64(ctx, fp0, fs);
11528            gen_load_fpr64(ctx, fp1, ft);
11529            gen_load_fpr64(ctx, fp2, fr);
11530            gen_helper_float_msub_d(fp2, cpu_env, fp0, fp1, fp2);
11531            tcg_temp_free_i64(fp0);
11532            tcg_temp_free_i64(fp1);
11533            gen_store_fpr64(ctx, fp2, fd);
11534            tcg_temp_free_i64(fp2);
11535        }
11536        break;
11537    case OPC_MSUB_PS:
11538        check_ps(ctx);
11539        {
11540            TCGv_i64 fp0 = tcg_temp_new_i64();
11541            TCGv_i64 fp1 = tcg_temp_new_i64();
11542            TCGv_i64 fp2 = tcg_temp_new_i64();
11543
11544            gen_load_fpr64(ctx, fp0, fs);
11545            gen_load_fpr64(ctx, fp1, ft);
11546            gen_load_fpr64(ctx, fp2, fr);
11547            gen_helper_float_msub_ps(fp2, cpu_env, fp0, fp1, fp2);
11548            tcg_temp_free_i64(fp0);
11549            tcg_temp_free_i64(fp1);
11550            gen_store_fpr64(ctx, fp2, fd);
11551            tcg_temp_free_i64(fp2);
11552        }
11553        break;
11554    case OPC_NMADD_S:
11555        check_cop1x(ctx);
11556        {
11557            TCGv_i32 fp0 = tcg_temp_new_i32();
11558            TCGv_i32 fp1 = tcg_temp_new_i32();
11559            TCGv_i32 fp2 = tcg_temp_new_i32();
11560
11561            gen_load_fpr32(ctx, fp0, fs);
11562            gen_load_fpr32(ctx, fp1, ft);
11563            gen_load_fpr32(ctx, fp2, fr);
11564            gen_helper_float_nmadd_s(fp2, cpu_env, fp0, fp1, fp2);
11565            tcg_temp_free_i32(fp0);
11566            tcg_temp_free_i32(fp1);
11567            gen_store_fpr32(ctx, fp2, fd);
11568            tcg_temp_free_i32(fp2);
11569        }
11570        break;
11571    case OPC_NMADD_D:
11572        check_cop1x(ctx);
11573        check_cp1_registers(ctx, fd | fs | ft | fr);
11574        {
11575            TCGv_i64 fp0 = tcg_temp_new_i64();
11576            TCGv_i64 fp1 = tcg_temp_new_i64();
11577            TCGv_i64 fp2 = tcg_temp_new_i64();
11578
11579            gen_load_fpr64(ctx, fp0, fs);
11580            gen_load_fpr64(ctx, fp1, ft);
11581            gen_load_fpr64(ctx, fp2, fr);
11582            gen_helper_float_nmadd_d(fp2, cpu_env, fp0, fp1, fp2);
11583            tcg_temp_free_i64(fp0);
11584            tcg_temp_free_i64(fp1);
11585            gen_store_fpr64(ctx, fp2, fd);
11586            tcg_temp_free_i64(fp2);
11587        }
11588        break;
11589    case OPC_NMADD_PS:
11590        check_ps(ctx);
11591        {
11592            TCGv_i64 fp0 = tcg_temp_new_i64();
11593            TCGv_i64 fp1 = tcg_temp_new_i64();
11594            TCGv_i64 fp2 = tcg_temp_new_i64();
11595
11596            gen_load_fpr64(ctx, fp0, fs);
11597            gen_load_fpr64(ctx, fp1, ft);
11598            gen_load_fpr64(ctx, fp2, fr);
11599            gen_helper_float_nmadd_ps(fp2, cpu_env, fp0, fp1, fp2);
11600            tcg_temp_free_i64(fp0);
11601            tcg_temp_free_i64(fp1);
11602            gen_store_fpr64(ctx, fp2, fd);
11603            tcg_temp_free_i64(fp2);
11604        }
11605        break;
11606    case OPC_NMSUB_S:
11607        check_cop1x(ctx);
11608        {
11609            TCGv_i32 fp0 = tcg_temp_new_i32();
11610            TCGv_i32 fp1 = tcg_temp_new_i32();
11611            TCGv_i32 fp2 = tcg_temp_new_i32();
11612
11613            gen_load_fpr32(ctx, fp0, fs);
11614            gen_load_fpr32(ctx, fp1, ft);
11615            gen_load_fpr32(ctx, fp2, fr);
11616            gen_helper_float_nmsub_s(fp2, cpu_env, fp0, fp1, fp2);
11617            tcg_temp_free_i32(fp0);
11618            tcg_temp_free_i32(fp1);
11619            gen_store_fpr32(ctx, fp2, fd);
11620            tcg_temp_free_i32(fp2);
11621        }
11622        break;
11623    case OPC_NMSUB_D:
11624        check_cop1x(ctx);
11625        check_cp1_registers(ctx, fd | fs | ft | fr);
11626        {
11627            TCGv_i64 fp0 = tcg_temp_new_i64();
11628            TCGv_i64 fp1 = tcg_temp_new_i64();
11629            TCGv_i64 fp2 = tcg_temp_new_i64();
11630
11631            gen_load_fpr64(ctx, fp0, fs);
11632            gen_load_fpr64(ctx, fp1, ft);
11633            gen_load_fpr64(ctx, fp2, fr);
11634            gen_helper_float_nmsub_d(fp2, cpu_env, fp0, fp1, fp2);
11635            tcg_temp_free_i64(fp0);
11636            tcg_temp_free_i64(fp1);
11637            gen_store_fpr64(ctx, fp2, fd);
11638            tcg_temp_free_i64(fp2);
11639        }
11640        break;
11641    case OPC_NMSUB_PS:
11642        check_ps(ctx);
11643        {
11644            TCGv_i64 fp0 = tcg_temp_new_i64();
11645            TCGv_i64 fp1 = tcg_temp_new_i64();
11646            TCGv_i64 fp2 = tcg_temp_new_i64();
11647
11648            gen_load_fpr64(ctx, fp0, fs);
11649            gen_load_fpr64(ctx, fp1, ft);
11650            gen_load_fpr64(ctx, fp2, fr);
11651            gen_helper_float_nmsub_ps(fp2, cpu_env, fp0, fp1, fp2);
11652            tcg_temp_free_i64(fp0);
11653            tcg_temp_free_i64(fp1);
11654            gen_store_fpr64(ctx, fp2, fd);
11655            tcg_temp_free_i64(fp2);
11656        }
11657        break;
11658    default:
11659        MIPS_INVAL("flt3_arith");
11660        gen_reserved_instruction(ctx);
11661        return;
11662    }
11663}
11664
11665void gen_rdhwr(DisasContext *ctx, int rt, int rd, int sel)
11666{
11667    TCGv t0;
11668
11669#if !defined(CONFIG_USER_ONLY)
11670    /*
11671     * The Linux kernel will emulate rdhwr if it's not supported natively.
11672     * Therefore only check the ISA in system mode.
11673     */
11674    check_insn(ctx, ISA_MIPS_R2);
11675#endif
11676    t0 = tcg_temp_new();
11677
11678    switch (rd) {
11679    case 0:
11680        gen_helper_rdhwr_cpunum(t0, cpu_env);
11681        gen_store_gpr(t0, rt);
11682        break;
11683    case 1:
11684        gen_helper_rdhwr_synci_step(t0, cpu_env);
11685        gen_store_gpr(t0, rt);
11686        break;
11687    case 2:
11688        if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
11689            gen_io_start();
11690        }
11691        gen_helper_rdhwr_cc(t0, cpu_env);
11692        gen_store_gpr(t0, rt);
11693        /*
11694         * Break the TB to be able to take timer interrupts immediately
11695         * after reading count. DISAS_STOP isn't sufficient, we need to ensure
11696         * we break completely out of translated code.
11697         */
11698        gen_save_pc(ctx->base.pc_next + 4);
11699        ctx->base.is_jmp = DISAS_EXIT;
11700        break;
11701    case 3:
11702        gen_helper_rdhwr_ccres(t0, cpu_env);
11703        gen_store_gpr(t0, rt);
11704        break;
11705    case 4:
11706        check_insn(ctx, ISA_MIPS_R6);
11707        if (sel != 0) {
11708            /*
11709             * Performance counter registers are not implemented other than
11710             * control register 0.
11711             */
11712            generate_exception(ctx, EXCP_RI);
11713        }
11714        gen_helper_rdhwr_performance(t0, cpu_env);
11715        gen_store_gpr(t0, rt);
11716        break;
11717    case 5:
11718        check_insn(ctx, ISA_MIPS_R6);
11719        gen_helper_rdhwr_xnp(t0, cpu_env);
11720        gen_store_gpr(t0, rt);
11721        break;
11722    case 29:
11723#if defined(CONFIG_USER_ONLY)
11724        tcg_gen_ld_tl(t0, cpu_env,
11725                      offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
11726        gen_store_gpr(t0, rt);
11727        break;
11728#else
11729        if ((ctx->hflags & MIPS_HFLAG_CP0) ||
11730            (ctx->hflags & MIPS_HFLAG_HWRENA_ULR)) {
11731            tcg_gen_ld_tl(t0, cpu_env,
11732                          offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
11733            gen_store_gpr(t0, rt);
11734        } else {
11735            gen_reserved_instruction(ctx);
11736        }
11737        break;
11738#endif
11739    default:            /* Invalid */
11740        MIPS_INVAL("rdhwr");
11741        gen_reserved_instruction(ctx);
11742        break;
11743    }
11744    tcg_temp_free(t0);
11745}
11746
11747static inline void clear_branch_hflags(DisasContext *ctx)
11748{
11749    ctx->hflags &= ~MIPS_HFLAG_BMASK;
11750    if (ctx->base.is_jmp == DISAS_NEXT) {
11751        save_cpu_state(ctx, 0);
11752    } else {
11753        /*
11754         * It is not safe to save ctx->hflags as hflags may be changed
11755         * in execution time by the instruction in delay / forbidden slot.
11756         */
11757        tcg_gen_andi_i32(hflags, hflags, ~MIPS_HFLAG_BMASK);
11758    }
11759}
11760
11761static void gen_branch(DisasContext *ctx, int insn_bytes)
11762{
11763    if (ctx->hflags & MIPS_HFLAG_BMASK) {
11764        int proc_hflags = ctx->hflags & MIPS_HFLAG_BMASK;
11765        /* Branches completion */
11766        clear_branch_hflags(ctx);
11767        ctx->base.is_jmp = DISAS_NORETURN;
11768        /* FIXME: Need to clear can_do_io.  */
11769        switch (proc_hflags & MIPS_HFLAG_BMASK_BASE) {
11770        case MIPS_HFLAG_FBNSLOT:
11771            gen_goto_tb(ctx, 0, ctx->base.pc_next + insn_bytes);
11772            break;
11773        case MIPS_HFLAG_B:
11774            /* unconditional branch */
11775            if (proc_hflags & MIPS_HFLAG_BX) {
11776                tcg_gen_xori_i32(hflags, hflags, MIPS_HFLAG_M16);
11777            }
11778            gen_goto_tb(ctx, 0, ctx->btarget);
11779            break;
11780        case MIPS_HFLAG_BL:
11781            /* blikely taken case */
11782            gen_goto_tb(ctx, 0, ctx->btarget);
11783            break;
11784        case MIPS_HFLAG_BC:
11785            /* Conditional branch */
11786            {
11787                TCGLabel *l1 = gen_new_label();
11788
11789                tcg_gen_brcondi_tl(TCG_COND_NE, bcond, 0, l1);
11790                gen_goto_tb(ctx, 1, ctx->base.pc_next + insn_bytes);
11791                gen_set_label(l1);
11792                gen_goto_tb(ctx, 0, ctx->btarget);
11793            }
11794            break;
11795        case MIPS_HFLAG_BR:
11796            /* unconditional branch to register */
11797            if (ctx->insn_flags & (ASE_MIPS16 | ASE_MICROMIPS)) {
11798                TCGv t0 = tcg_temp_new();
11799                TCGv_i32 t1 = tcg_temp_new_i32();
11800
11801                tcg_gen_andi_tl(t0, btarget, 0x1);
11802                tcg_gen_trunc_tl_i32(t1, t0);
11803                tcg_temp_free(t0);
11804                tcg_gen_andi_i32(hflags, hflags, ~(uint32_t)MIPS_HFLAG_M16);
11805                tcg_gen_shli_i32(t1, t1, MIPS_HFLAG_M16_SHIFT);
11806                tcg_gen_or_i32(hflags, hflags, t1);
11807                tcg_temp_free_i32(t1);
11808
11809                tcg_gen_andi_tl(cpu_PC, btarget, ~(target_ulong)0x1);
11810            } else {
11811                tcg_gen_mov_tl(cpu_PC, btarget);
11812            }
11813            tcg_gen_lookup_and_goto_ptr();
11814            break;
11815        default:
11816            LOG_DISAS("unknown branch 0x%x\n", proc_hflags);
11817            gen_reserved_instruction(ctx);
11818        }
11819    }
11820}
11821
11822/* Compact Branches */
11823static void gen_compute_compact_branch(DisasContext *ctx, uint32_t opc,
11824                                       int rs, int rt, int32_t offset)
11825{
11826    int bcond_compute = 0;
11827    TCGv t0 = tcg_temp_new();
11828    TCGv t1 = tcg_temp_new();
11829    int m16_lowbit = (ctx->hflags & MIPS_HFLAG_M16) != 0;
11830
11831    if (ctx->hflags & MIPS_HFLAG_BMASK) {
11832#ifdef MIPS_DEBUG_DISAS
11833        LOG_DISAS("Branch in delay / forbidden slot at PC 0x" TARGET_FMT_lx
11834                  "\n", ctx->base.pc_next);
11835#endif
11836        gen_reserved_instruction(ctx);
11837        goto out;
11838    }
11839
11840    /* Load needed operands and calculate btarget */
11841    switch (opc) {
11842    /* compact branch */
11843    case OPC_BOVC: /* OPC_BEQZALC, OPC_BEQC */
11844    case OPC_BNVC: /* OPC_BNEZALC, OPC_BNEC */
11845        gen_load_gpr(t0, rs);
11846        gen_load_gpr(t1, rt);
11847        bcond_compute = 1;
11848        ctx->btarget = addr_add(ctx, ctx->base.pc_next + 4, offset);
11849        if (rs <= rt && rs == 0) {
11850            /* OPC_BEQZALC, OPC_BNEZALC */
11851            tcg_gen_movi_tl(cpu_gpr[31], ctx->base.pc_next + 4 + m16_lowbit);
11852        }
11853        break;
11854    case OPC_BLEZC: /* OPC_BGEZC, OPC_BGEC */
11855    case OPC_BGTZC: /* OPC_BLTZC, OPC_BLTC */
11856        gen_load_gpr(t0, rs);
11857        gen_load_gpr(t1, rt);
11858        bcond_compute = 1;
11859        ctx->btarget = addr_add(ctx, ctx->base.pc_next + 4, offset);
11860        break;
11861    case OPC_BLEZALC: /* OPC_BGEZALC, OPC_BGEUC */
11862    case OPC_BGTZALC: /* OPC_BLTZALC, OPC_BLTUC */
11863        if (rs == 0 || rs == rt) {
11864            /* OPC_BLEZALC, OPC_BGEZALC */
11865            /* OPC_BGTZALC, OPC_BLTZALC */
11866            tcg_gen_movi_tl(cpu_gpr[31], ctx->base.pc_next + 4 + m16_lowbit);
11867        }
11868        gen_load_gpr(t0, rs);
11869        gen_load_gpr(t1, rt);
11870        bcond_compute = 1;
11871        ctx->btarget = addr_add(ctx, ctx->base.pc_next + 4, offset);
11872        break;
11873    case OPC_BC:
11874    case OPC_BALC:
11875        ctx->btarget = addr_add(ctx, ctx->base.pc_next + 4, offset);
11876        break;
11877    case OPC_BEQZC:
11878    case OPC_BNEZC:
11879        if (rs != 0) {
11880            /* OPC_BEQZC, OPC_BNEZC */
11881            gen_load_gpr(t0, rs);
11882            bcond_compute = 1;
11883            ctx->btarget = addr_add(ctx, ctx->base.pc_next + 4, offset);
11884        } else {
11885            /* OPC_JIC, OPC_JIALC */
11886            TCGv tbase = tcg_temp_new();
11887            TCGv toffset = tcg_constant_tl(offset);
11888
11889            gen_load_gpr(tbase, rt);
11890            gen_op_addr_add(ctx, btarget, tbase, toffset);
11891            tcg_temp_free(tbase);
11892        }
11893        break;
11894    default:
11895        MIPS_INVAL("Compact branch/jump");
11896        gen_reserved_instruction(ctx);
11897        goto out;
11898    }
11899
11900    if (bcond_compute == 0) {
11901        /* Unconditional compact branch */
11902        switch (opc) {
11903        case OPC_JIALC:
11904            tcg_gen_movi_tl(cpu_gpr[31], ctx->base.pc_next + 4 + m16_lowbit);
11905            /* Fallthrough */
11906        case OPC_JIC:
11907            ctx->hflags |= MIPS_HFLAG_BR;
11908            break;
11909        case OPC_BALC:
11910            tcg_gen_movi_tl(cpu_gpr[31], ctx->base.pc_next + 4 + m16_lowbit);
11911            /* Fallthrough */
11912        case OPC_BC:
11913            ctx->hflags |= MIPS_HFLAG_B;
11914            break;
11915        default:
11916            MIPS_INVAL("Compact branch/jump");
11917            gen_reserved_instruction(ctx);
11918            goto out;
11919        }
11920
11921        /* Generating branch here as compact branches don't have delay slot */
11922        gen_branch(ctx, 4);
11923    } else {
11924        /* Conditional compact branch */
11925        TCGLabel *fs = gen_new_label();
11926        save_cpu_state(ctx, 0);
11927
11928        switch (opc) {
11929        case OPC_BLEZALC: /* OPC_BGEZALC, OPC_BGEUC */
11930            if (rs == 0 && rt != 0) {
11931                /* OPC_BLEZALC */
11932                tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LE), t1, 0, fs);
11933            } else if (rs != 0 && rt != 0 && rs == rt) {
11934                /* OPC_BGEZALC */
11935                tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GE), t1, 0, fs);
11936            } else {
11937                /* OPC_BGEUC */
11938                tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_GEU), t0, t1, fs);
11939            }
11940            break;
11941        case OPC_BGTZALC: /* OPC_BLTZALC, OPC_BLTUC */
11942            if (rs == 0 && rt != 0) {
11943                /* OPC_BGTZALC */
11944                tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GT), t1, 0, fs);
11945            } else if (rs != 0 && rt != 0 && rs == rt) {
11946                /* OPC_BLTZALC */
11947                tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LT), t1, 0, fs);
11948            } else {
11949                /* OPC_BLTUC */
11950                tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_LTU), t0, t1, fs);
11951            }
11952            break;
11953        case OPC_BLEZC: /* OPC_BGEZC, OPC_BGEC */
11954            if (rs == 0 && rt != 0) {
11955                /* OPC_BLEZC */
11956                tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LE), t1, 0, fs);
11957            } else if (rs != 0 && rt != 0 && rs == rt) {
11958                /* OPC_BGEZC */
11959                tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GE), t1, 0, fs);
11960            } else {
11961                /* OPC_BGEC */
11962                tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_GE), t0, t1, fs);
11963            }
11964            break;
11965        case OPC_BGTZC: /* OPC_BLTZC, OPC_BLTC */
11966            if (rs == 0 && rt != 0) {
11967                /* OPC_BGTZC */
11968                tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GT), t1, 0, fs);
11969            } else if (rs != 0 && rt != 0 && rs == rt) {
11970                /* OPC_BLTZC */
11971                tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LT), t1, 0, fs);
11972            } else {
11973                /* OPC_BLTC */
11974                tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_LT), t0, t1, fs);
11975            }
11976            break;
11977        case OPC_BOVC: /* OPC_BEQZALC, OPC_BEQC */
11978        case OPC_BNVC: /* OPC_BNEZALC, OPC_BNEC */
11979            if (rs >= rt) {
11980                /* OPC_BOVC, OPC_BNVC */
11981                TCGv t2 = tcg_temp_new();
11982                TCGv t3 = tcg_temp_new();
11983                TCGv t4 = tcg_temp_new();
11984                TCGv input_overflow = tcg_temp_new();
11985
11986                gen_load_gpr(t0, rs);
11987                gen_load_gpr(t1, rt);
11988                tcg_gen_ext32s_tl(t2, t0);
11989                tcg_gen_setcond_tl(TCG_COND_NE, input_overflow, t2, t0);
11990                tcg_gen_ext32s_tl(t3, t1);
11991                tcg_gen_setcond_tl(TCG_COND_NE, t4, t3, t1);
11992                tcg_gen_or_tl(input_overflow, input_overflow, t4);
11993
11994                tcg_gen_add_tl(t4, t2, t3);
11995                tcg_gen_ext32s_tl(t4, t4);
11996                tcg_gen_xor_tl(t2, t2, t3);
11997                tcg_gen_xor_tl(t3, t4, t3);
11998                tcg_gen_andc_tl(t2, t3, t2);
11999                tcg_gen_setcondi_tl(TCG_COND_LT, t4, t2, 0);
12000                tcg_gen_or_tl(t4, t4, input_overflow);
12001                if (opc == OPC_BOVC) {
12002                    /* OPC_BOVC */
12003                    tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_NE), t4, 0, fs);
12004                } else {
12005                    /* OPC_BNVC */
12006                    tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_EQ), t4, 0, fs);
12007                }
12008                tcg_temp_free(input_overflow);
12009                tcg_temp_free(t4);
12010                tcg_temp_free(t3);
12011                tcg_temp_free(t2);
12012            } else if (rs < rt && rs == 0) {
12013                /* OPC_BEQZALC, OPC_BNEZALC */
12014                if (opc == OPC_BEQZALC) {
12015                    /* OPC_BEQZALC */
12016                    tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_EQ), t1, 0, fs);
12017                } else {
12018                    /* OPC_BNEZALC */
12019                    tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_NE), t1, 0, fs);
12020                }
12021            } else {
12022                /* OPC_BEQC, OPC_BNEC */
12023                if (opc == OPC_BEQC) {
12024                    /* OPC_BEQC */
12025                    tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_EQ), t0, t1, fs);
12026                } else {
12027                    /* OPC_BNEC */
12028                    tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_NE), t0, t1, fs);
12029                }
12030            }
12031            break;
12032        case OPC_BEQZC:
12033            tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_EQ), t0, 0, fs);
12034            break;
12035        case OPC_BNEZC:
12036            tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_NE), t0, 0, fs);
12037            break;
12038        default:
12039            MIPS_INVAL("Compact conditional branch/jump");
12040            gen_reserved_instruction(ctx);
12041            goto out;
12042        }
12043
12044        /* Generating branch here as compact branches don't have delay slot */
12045        gen_goto_tb(ctx, 1, ctx->btarget);
12046        gen_set_label(fs);
12047
12048        ctx->hflags |= MIPS_HFLAG_FBNSLOT;
12049    }
12050
12051out:
12052    tcg_temp_free(t0);
12053    tcg_temp_free(t1);
12054}
12055
12056void gen_addiupc(DisasContext *ctx, int rx, int imm,
12057                 int is_64_bit, int extended)
12058{
12059    TCGv t0;
12060
12061    if (extended && (ctx->hflags & MIPS_HFLAG_BMASK)) {
12062        gen_reserved_instruction(ctx);
12063        return;
12064    }
12065
12066    t0 = tcg_temp_new();
12067
12068    tcg_gen_movi_tl(t0, pc_relative_pc(ctx));
12069    tcg_gen_addi_tl(cpu_gpr[rx], t0, imm);
12070    if (!is_64_bit) {
12071        tcg_gen_ext32s_tl(cpu_gpr[rx], cpu_gpr[rx]);
12072    }
12073
12074    tcg_temp_free(t0);
12075}
12076
12077static void gen_cache_operation(DisasContext *ctx, uint32_t op, int base,
12078                                int16_t offset)
12079{
12080    TCGv_i32 t0 = tcg_const_i32(op);
12081    TCGv t1 = tcg_temp_new();
12082    gen_base_offset_addr(ctx, t1, base, offset);
12083    gen_helper_cache(cpu_env, t1, t0);
12084    tcg_temp_free(t1);
12085    tcg_temp_free_i32(t0);
12086}
12087
12088static inline bool is_uhi(int sdbbp_code)
12089{
12090#ifdef CONFIG_USER_ONLY
12091    return false;
12092#else
12093    return semihosting_enabled() && sdbbp_code == 1;
12094#endif
12095}
12096
12097#ifdef CONFIG_USER_ONLY
12098/* The above should dead-code away any calls to this..*/
12099static inline void gen_helper_do_semihosting(void *env)
12100{
12101    g_assert_not_reached();
12102}
12103#endif
12104
12105void gen_ldxs(DisasContext *ctx, int base, int index, int rd)
12106{
12107    TCGv t0 = tcg_temp_new();
12108    TCGv t1 = tcg_temp_new();
12109
12110    gen_load_gpr(t0, base);
12111
12112    if (index != 0) {
12113        gen_load_gpr(t1, index);
12114        tcg_gen_shli_tl(t1, t1, 2);
12115        gen_op_addr_add(ctx, t0, t1, t0);
12116    }
12117
12118    tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TESL);
12119    gen_store_gpr(t1, rd);
12120
12121    tcg_temp_free(t0);
12122    tcg_temp_free(t1);
12123}
12124
12125static void gen_sync(int stype)
12126{
12127    TCGBar tcg_mo = TCG_BAR_SC;
12128
12129    switch (stype) {
12130    case 0x4: /* SYNC_WMB */
12131        tcg_mo |= TCG_MO_ST_ST;
12132        break;
12133    case 0x10: /* SYNC_MB */
12134        tcg_mo |= TCG_MO_ALL;
12135        break;
12136    case 0x11: /* SYNC_ACQUIRE */
12137        tcg_mo |= TCG_MO_LD_LD | TCG_MO_LD_ST;
12138        break;
12139    case 0x12: /* SYNC_RELEASE */
12140        tcg_mo |= TCG_MO_ST_ST | TCG_MO_LD_ST;
12141        break;
12142    case 0x13: /* SYNC_RMB */
12143        tcg_mo |= TCG_MO_LD_LD;
12144        break;
12145    default:
12146        tcg_mo |= TCG_MO_ALL;
12147        break;
12148    }
12149
12150    tcg_gen_mb(tcg_mo);
12151}
12152
12153/* ISA extensions (ASEs) */
12154
12155/* MIPS16 extension to MIPS32 */
12156#include "mips16e_translate.c.inc"
12157
12158/* microMIPS extension to MIPS32/MIPS64 */
12159
12160/*
12161 * Values for microMIPS fmt field.  Variable-width, depending on which
12162 * formats the instruction supports.
12163 */
12164enum {
12165    FMT_SD_S = 0,
12166    FMT_SD_D = 1,
12167
12168    FMT_SDPS_S = 0,
12169    FMT_SDPS_D = 1,
12170    FMT_SDPS_PS = 2,
12171
12172    FMT_SWL_S = 0,
12173    FMT_SWL_W = 1,
12174    FMT_SWL_L = 2,
12175
12176    FMT_DWL_D = 0,
12177    FMT_DWL_W = 1,
12178    FMT_DWL_L = 2
12179};
12180
12181#include "micromips_translate.c.inc"
12182
12183#include "nanomips_translate.c.inc"
12184
12185/* MIPSDSP functions. */
12186static void gen_mipsdsp_ld(DisasContext *ctx, uint32_t opc,
12187                           int rd, int base, int offset)
12188{
12189    TCGv t0;
12190
12191    check_dsp(ctx);
12192    t0 = tcg_temp_new();
12193
12194    if (base == 0) {
12195        gen_load_gpr(t0, offset);
12196    } else if (offset == 0) {
12197        gen_load_gpr(t0, base);
12198    } else {
12199        gen_op_addr_add(ctx, t0, cpu_gpr[base], cpu_gpr[offset]);
12200    }
12201
12202    switch (opc) {
12203    case OPC_LBUX:
12204        tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_UB);
12205        gen_store_gpr(t0, rd);
12206        break;
12207    case OPC_LHX:
12208        tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TESW);
12209        gen_store_gpr(t0, rd);
12210        break;
12211    case OPC_LWX:
12212        tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TESL);
12213        gen_store_gpr(t0, rd);
12214        break;
12215#if defined(TARGET_MIPS64)
12216    case OPC_LDX:
12217        tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEUQ);
12218        gen_store_gpr(t0, rd);
12219        break;
12220#endif
12221    }
12222    tcg_temp_free(t0);
12223}
12224
12225static void gen_mipsdsp_arith(DisasContext *ctx, uint32_t op1, uint32_t op2,
12226                              int ret, int v1, int v2)
12227{
12228    TCGv v1_t;
12229    TCGv v2_t;
12230
12231    if (ret == 0) {
12232        /* Treat as NOP. */
12233        return;
12234    }
12235
12236    v1_t = tcg_temp_new();
12237    v2_t = tcg_temp_new();
12238
12239    gen_load_gpr(v1_t, v1);
12240    gen_load_gpr(v2_t, v2);
12241
12242    switch (op1) {
12243    /* OPC_MULT_G_2E is equal OPC_ADDUH_QB_DSP */
12244    case OPC_MULT_G_2E:
12245        check_dsp_r2(ctx);
12246        switch (op2) {
12247        case OPC_ADDUH_QB:
12248            gen_helper_adduh_qb(cpu_gpr[ret], v1_t, v2_t);
12249            break;
12250        case OPC_ADDUH_R_QB:
12251            gen_helper_adduh_r_qb(cpu_gpr[ret], v1_t, v2_t);
12252            break;
12253        case OPC_ADDQH_PH:
12254            gen_helper_addqh_ph(cpu_gpr[ret], v1_t, v2_t);
12255            break;
12256        case OPC_ADDQH_R_PH:
12257            gen_helper_addqh_r_ph(cpu_gpr[ret], v1_t, v2_t);
12258            break;
12259        case OPC_ADDQH_W:
12260            gen_helper_addqh_w(cpu_gpr[ret], v1_t, v2_t);
12261            break;
12262        case OPC_ADDQH_R_W:
12263            gen_helper_addqh_r_w(cpu_gpr[ret], v1_t, v2_t);
12264            break;
12265        case OPC_SUBUH_QB:
12266            gen_helper_subuh_qb(cpu_gpr[ret], v1_t, v2_t);
12267            break;
12268        case OPC_SUBUH_R_QB:
12269            gen_helper_subuh_r_qb(cpu_gpr[ret], v1_t, v2_t);
12270            break;
12271        case OPC_SUBQH_PH:
12272            gen_helper_subqh_ph(cpu_gpr[ret], v1_t, v2_t);
12273            break;
12274        case OPC_SUBQH_R_PH:
12275            gen_helper_subqh_r_ph(cpu_gpr[ret], v1_t, v2_t);
12276            break;
12277        case OPC_SUBQH_W:
12278            gen_helper_subqh_w(cpu_gpr[ret], v1_t, v2_t);
12279            break;
12280        case OPC_SUBQH_R_W:
12281            gen_helper_subqh_r_w(cpu_gpr[ret], v1_t, v2_t);
12282            break;
12283        }
12284        break;
12285    case OPC_ABSQ_S_PH_DSP:
12286        switch (op2) {
12287        case OPC_ABSQ_S_QB:
12288            check_dsp_r2(ctx);
12289            gen_helper_absq_s_qb(cpu_gpr[ret], v2_t, cpu_env);
12290            break;
12291        case OPC_ABSQ_S_PH:
12292            check_dsp(ctx);
12293            gen_helper_absq_s_ph(cpu_gpr[ret], v2_t, cpu_env);
12294            break;
12295        case OPC_ABSQ_S_W:
12296            check_dsp(ctx);
12297            gen_helper_absq_s_w(cpu_gpr[ret], v2_t, cpu_env);
12298            break;
12299        case OPC_PRECEQ_W_PHL:
12300            check_dsp(ctx);
12301            tcg_gen_andi_tl(cpu_gpr[ret], v2_t, 0xFFFF0000);
12302            tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]);
12303            break;
12304        case OPC_PRECEQ_W_PHR:
12305            check_dsp(ctx);
12306            tcg_gen_andi_tl(cpu_gpr[ret], v2_t, 0x0000FFFF);
12307            tcg_gen_shli_tl(cpu_gpr[ret], cpu_gpr[ret], 16);
12308            tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]);
12309            break;
12310        case OPC_PRECEQU_PH_QBL:
12311            check_dsp(ctx);
12312            gen_helper_precequ_ph_qbl(cpu_gpr[ret], v2_t);
12313            break;
12314        case OPC_PRECEQU_PH_QBR:
12315            check_dsp(ctx);
12316            gen_helper_precequ_ph_qbr(cpu_gpr[ret], v2_t);
12317            break;
12318        case OPC_PRECEQU_PH_QBLA:
12319            check_dsp(ctx);
12320            gen_helper_precequ_ph_qbla(cpu_gpr[ret], v2_t);
12321            break;
12322        case OPC_PRECEQU_PH_QBRA:
12323            check_dsp(ctx);
12324            gen_helper_precequ_ph_qbra(cpu_gpr[ret], v2_t);
12325            break;
12326        case OPC_PRECEU_PH_QBL:
12327            check_dsp(ctx);
12328            gen_helper_preceu_ph_qbl(cpu_gpr[ret], v2_t);
12329            break;
12330        case OPC_PRECEU_PH_QBR:
12331            check_dsp(ctx);
12332            gen_helper_preceu_ph_qbr(cpu_gpr[ret], v2_t);
12333            break;
12334        case OPC_PRECEU_PH_QBLA:
12335            check_dsp(ctx);
12336            gen_helper_preceu_ph_qbla(cpu_gpr[ret], v2_t);
12337            break;
12338        case OPC_PRECEU_PH_QBRA:
12339            check_dsp(ctx);
12340            gen_helper_preceu_ph_qbra(cpu_gpr[ret], v2_t);
12341            break;
12342        }
12343        break;
12344    case OPC_ADDU_QB_DSP:
12345        switch (op2) {
12346        case OPC_ADDQ_PH:
12347            check_dsp(ctx);
12348            gen_helper_addq_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12349            break;
12350        case OPC_ADDQ_S_PH:
12351            check_dsp(ctx);
12352            gen_helper_addq_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12353            break;
12354        case OPC_ADDQ_S_W:
12355            check_dsp(ctx);
12356            gen_helper_addq_s_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12357            break;
12358        case OPC_ADDU_QB:
12359            check_dsp(ctx);
12360            gen_helper_addu_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12361            break;
12362        case OPC_ADDU_S_QB:
12363            check_dsp(ctx);
12364            gen_helper_addu_s_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12365            break;
12366        case OPC_ADDU_PH:
12367            check_dsp_r2(ctx);
12368            gen_helper_addu_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12369            break;
12370        case OPC_ADDU_S_PH:
12371            check_dsp_r2(ctx);
12372            gen_helper_addu_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12373            break;
12374        case OPC_SUBQ_PH:
12375            check_dsp(ctx);
12376            gen_helper_subq_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12377            break;
12378        case OPC_SUBQ_S_PH:
12379            check_dsp(ctx);
12380            gen_helper_subq_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12381            break;
12382        case OPC_SUBQ_S_W:
12383            check_dsp(ctx);
12384            gen_helper_subq_s_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12385            break;
12386        case OPC_SUBU_QB:
12387            check_dsp(ctx);
12388            gen_helper_subu_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12389            break;
12390        case OPC_SUBU_S_QB:
12391            check_dsp(ctx);
12392            gen_helper_subu_s_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12393            break;
12394        case OPC_SUBU_PH:
12395            check_dsp_r2(ctx);
12396            gen_helper_subu_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12397            break;
12398        case OPC_SUBU_S_PH:
12399            check_dsp_r2(ctx);
12400            gen_helper_subu_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12401            break;
12402        case OPC_ADDSC:
12403            check_dsp(ctx);
12404            gen_helper_addsc(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12405            break;
12406        case OPC_ADDWC:
12407            check_dsp(ctx);
12408            gen_helper_addwc(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12409            break;
12410        case OPC_MODSUB:
12411            check_dsp(ctx);
12412            gen_helper_modsub(cpu_gpr[ret], v1_t, v2_t);
12413            break;
12414        case OPC_RADDU_W_QB:
12415            check_dsp(ctx);
12416            gen_helper_raddu_w_qb(cpu_gpr[ret], v1_t);
12417            break;
12418        }
12419        break;
12420    case OPC_CMPU_EQ_QB_DSP:
12421        switch (op2) {
12422        case OPC_PRECR_QB_PH:
12423            check_dsp_r2(ctx);
12424            gen_helper_precr_qb_ph(cpu_gpr[ret], v1_t, v2_t);
12425            break;
12426        case OPC_PRECRQ_QB_PH:
12427            check_dsp(ctx);
12428            gen_helper_precrq_qb_ph(cpu_gpr[ret], v1_t, v2_t);
12429            break;
12430        case OPC_PRECR_SRA_PH_W:
12431            check_dsp_r2(ctx);
12432            {
12433                TCGv_i32 sa_t = tcg_const_i32(v2);
12434                gen_helper_precr_sra_ph_w(cpu_gpr[ret], sa_t, v1_t,
12435                                          cpu_gpr[ret]);
12436                tcg_temp_free_i32(sa_t);
12437                break;
12438            }
12439        case OPC_PRECR_SRA_R_PH_W:
12440            check_dsp_r2(ctx);
12441            {
12442                TCGv_i32 sa_t = tcg_const_i32(v2);
12443                gen_helper_precr_sra_r_ph_w(cpu_gpr[ret], sa_t, v1_t,
12444                                            cpu_gpr[ret]);
12445                tcg_temp_free_i32(sa_t);
12446                break;
12447            }
12448        case OPC_PRECRQ_PH_W:
12449            check_dsp(ctx);
12450            gen_helper_precrq_ph_w(cpu_gpr[ret], v1_t, v2_t);
12451            break;
12452        case OPC_PRECRQ_RS_PH_W:
12453            check_dsp(ctx);
12454            gen_helper_precrq_rs_ph_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12455            break;
12456        case OPC_PRECRQU_S_QB_PH:
12457            check_dsp(ctx);
12458            gen_helper_precrqu_s_qb_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12459            break;
12460        }
12461        break;
12462#ifdef TARGET_MIPS64
12463    case OPC_ABSQ_S_QH_DSP:
12464        switch (op2) {
12465        case OPC_PRECEQ_L_PWL:
12466            check_dsp(ctx);
12467            tcg_gen_andi_tl(cpu_gpr[ret], v2_t, 0xFFFFFFFF00000000ull);
12468            break;
12469        case OPC_PRECEQ_L_PWR:
12470            check_dsp(ctx);
12471            tcg_gen_shli_tl(cpu_gpr[ret], v2_t, 32);
12472            break;
12473        case OPC_PRECEQ_PW_QHL:
12474            check_dsp(ctx);
12475            gen_helper_preceq_pw_qhl(cpu_gpr[ret], v2_t);
12476            break;
12477        case OPC_PRECEQ_PW_QHR:
12478            check_dsp(ctx);
12479            gen_helper_preceq_pw_qhr(cpu_gpr[ret], v2_t);
12480            break;
12481        case OPC_PRECEQ_PW_QHLA:
12482            check_dsp(ctx);
12483            gen_helper_preceq_pw_qhla(cpu_gpr[ret], v2_t);
12484            break;
12485        case OPC_PRECEQ_PW_QHRA:
12486            check_dsp(ctx);
12487            gen_helper_preceq_pw_qhra(cpu_gpr[ret], v2_t);
12488            break;
12489        case OPC_PRECEQU_QH_OBL:
12490            check_dsp(ctx);
12491            gen_helper_precequ_qh_obl(cpu_gpr[ret], v2_t);
12492            break;
12493        case OPC_PRECEQU_QH_OBR:
12494            check_dsp(ctx);
12495            gen_helper_precequ_qh_obr(cpu_gpr[ret], v2_t);
12496            break;
12497        case OPC_PRECEQU_QH_OBLA:
12498            check_dsp(ctx);
12499            gen_helper_precequ_qh_obla(cpu_gpr[ret], v2_t);
12500            break;
12501        case OPC_PRECEQU_QH_OBRA:
12502            check_dsp(ctx);
12503            gen_helper_precequ_qh_obra(cpu_gpr[ret], v2_t);
12504            break;
12505        case OPC_PRECEU_QH_OBL:
12506            check_dsp(ctx);
12507            gen_helper_preceu_qh_obl(cpu_gpr[ret], v2_t);
12508            break;
12509        case OPC_PRECEU_QH_OBR:
12510            check_dsp(ctx);
12511            gen_helper_preceu_qh_obr(cpu_gpr[ret], v2_t);
12512            break;
12513        case OPC_PRECEU_QH_OBLA:
12514            check_dsp(ctx);
12515            gen_helper_preceu_qh_obla(cpu_gpr[ret], v2_t);
12516            break;
12517        case OPC_PRECEU_QH_OBRA:
12518            check_dsp(ctx);
12519            gen_helper_preceu_qh_obra(cpu_gpr[ret], v2_t);
12520            break;
12521        case OPC_ABSQ_S_OB:
12522            check_dsp_r2(ctx);
12523            gen_helper_absq_s_ob(cpu_gpr[ret], v2_t, cpu_env);
12524            break;
12525        case OPC_ABSQ_S_PW:
12526            check_dsp(ctx);
12527            gen_helper_absq_s_pw(cpu_gpr[ret], v2_t, cpu_env);
12528            break;
12529        case OPC_ABSQ_S_QH:
12530            check_dsp(ctx);
12531            gen_helper_absq_s_qh(cpu_gpr[ret], v2_t, cpu_env);
12532            break;
12533        }
12534        break;
12535    case OPC_ADDU_OB_DSP:
12536        switch (op2) {
12537        case OPC_RADDU_L_OB:
12538            check_dsp(ctx);
12539            gen_helper_raddu_l_ob(cpu_gpr[ret], v1_t);
12540            break;
12541        case OPC_SUBQ_PW:
12542            check_dsp(ctx);
12543            gen_helper_subq_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12544            break;
12545        case OPC_SUBQ_S_PW:
12546            check_dsp(ctx);
12547            gen_helper_subq_s_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12548            break;
12549        case OPC_SUBQ_QH:
12550            check_dsp(ctx);
12551            gen_helper_subq_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12552            break;
12553        case OPC_SUBQ_S_QH:
12554            check_dsp(ctx);
12555            gen_helper_subq_s_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12556            break;
12557        case OPC_SUBU_OB:
12558            check_dsp(ctx);
12559            gen_helper_subu_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12560            break;
12561        case OPC_SUBU_S_OB:
12562            check_dsp(ctx);
12563            gen_helper_subu_s_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12564            break;
12565        case OPC_SUBU_QH:
12566            check_dsp_r2(ctx);
12567            gen_helper_subu_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12568            break;
12569        case OPC_SUBU_S_QH:
12570            check_dsp_r2(ctx);
12571            gen_helper_subu_s_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12572            break;
12573        case OPC_SUBUH_OB:
12574            check_dsp_r2(ctx);
12575            gen_helper_subuh_ob(cpu_gpr[ret], v1_t, v2_t);
12576            break;
12577        case OPC_SUBUH_R_OB:
12578            check_dsp_r2(ctx);
12579            gen_helper_subuh_r_ob(cpu_gpr[ret], v1_t, v2_t);
12580            break;
12581        case OPC_ADDQ_PW:
12582            check_dsp(ctx);
12583            gen_helper_addq_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12584            break;
12585        case OPC_ADDQ_S_PW:
12586            check_dsp(ctx);
12587            gen_helper_addq_s_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12588            break;
12589        case OPC_ADDQ_QH:
12590            check_dsp(ctx);
12591            gen_helper_addq_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12592            break;
12593        case OPC_ADDQ_S_QH:
12594            check_dsp(ctx);
12595            gen_helper_addq_s_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12596            break;
12597        case OPC_ADDU_OB:
12598            check_dsp(ctx);
12599            gen_helper_addu_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12600            break;
12601        case OPC_ADDU_S_OB:
12602            check_dsp(ctx);
12603            gen_helper_addu_s_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12604            break;
12605        case OPC_ADDU_QH:
12606            check_dsp_r2(ctx);
12607            gen_helper_addu_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12608            break;
12609        case OPC_ADDU_S_QH:
12610            check_dsp_r2(ctx);
12611            gen_helper_addu_s_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12612            break;
12613        case OPC_ADDUH_OB:
12614            check_dsp_r2(ctx);
12615            gen_helper_adduh_ob(cpu_gpr[ret], v1_t, v2_t);
12616            break;
12617        case OPC_ADDUH_R_OB:
12618            check_dsp_r2(ctx);
12619            gen_helper_adduh_r_ob(cpu_gpr[ret], v1_t, v2_t);
12620            break;
12621        }
12622        break;
12623    case OPC_CMPU_EQ_OB_DSP:
12624        switch (op2) {
12625        case OPC_PRECR_OB_QH:
12626            check_dsp_r2(ctx);
12627            gen_helper_precr_ob_qh(cpu_gpr[ret], v1_t, v2_t);
12628            break;
12629        case OPC_PRECR_SRA_QH_PW:
12630            check_dsp_r2(ctx);
12631            {
12632                TCGv_i32 ret_t = tcg_const_i32(ret);
12633                gen_helper_precr_sra_qh_pw(v2_t, v1_t, v2_t, ret_t);
12634                tcg_temp_free_i32(ret_t);
12635                break;
12636            }
12637        case OPC_PRECR_SRA_R_QH_PW:
12638            check_dsp_r2(ctx);
12639            {
12640                TCGv_i32 sa_v = tcg_const_i32(ret);
12641                gen_helper_precr_sra_r_qh_pw(v2_t, v1_t, v2_t, sa_v);
12642                tcg_temp_free_i32(sa_v);
12643                break;
12644            }
12645        case OPC_PRECRQ_OB_QH:
12646            check_dsp(ctx);
12647            gen_helper_precrq_ob_qh(cpu_gpr[ret], v1_t, v2_t);
12648            break;
12649        case OPC_PRECRQ_PW_L:
12650            check_dsp(ctx);
12651            gen_helper_precrq_pw_l(cpu_gpr[ret], v1_t, v2_t);
12652            break;
12653        case OPC_PRECRQ_QH_PW:
12654            check_dsp(ctx);
12655            gen_helper_precrq_qh_pw(cpu_gpr[ret], v1_t, v2_t);
12656            break;
12657        case OPC_PRECRQ_RS_QH_PW:
12658            check_dsp(ctx);
12659            gen_helper_precrq_rs_qh_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12660            break;
12661        case OPC_PRECRQU_S_OB_QH:
12662            check_dsp(ctx);
12663            gen_helper_precrqu_s_ob_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12664            break;
12665        }
12666        break;
12667#endif
12668    }
12669
12670    tcg_temp_free(v1_t);
12671    tcg_temp_free(v2_t);
12672}
12673
12674static void gen_mipsdsp_shift(DisasContext *ctx, uint32_t opc,
12675                              int ret, int v1, int v2)
12676{
12677    uint32_t op2;
12678    TCGv t0;
12679    TCGv v1_t;
12680    TCGv v2_t;
12681
12682    if (ret == 0) {
12683        /* Treat as NOP. */
12684        return;
12685    }
12686
12687    t0 = tcg_temp_new();
12688    v1_t = tcg_temp_new();
12689    v2_t = tcg_temp_new();
12690
12691    tcg_gen_movi_tl(t0, v1);
12692    gen_load_gpr(v1_t, v1);
12693    gen_load_gpr(v2_t, v2);
12694
12695    switch (opc) {
12696    case OPC_SHLL_QB_DSP:
12697        {
12698            op2 = MASK_SHLL_QB(ctx->opcode);
12699            switch (op2) {
12700            case OPC_SHLL_QB:
12701                check_dsp(ctx);
12702                gen_helper_shll_qb(cpu_gpr[ret], t0, v2_t, cpu_env);
12703                break;
12704            case OPC_SHLLV_QB:
12705                check_dsp(ctx);
12706                gen_helper_shll_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12707                break;
12708            case OPC_SHLL_PH:
12709                check_dsp(ctx);
12710                gen_helper_shll_ph(cpu_gpr[ret], t0, v2_t, cpu_env);
12711                break;
12712            case OPC_SHLLV_PH:
12713                check_dsp(ctx);
12714                gen_helper_shll_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12715                break;
12716            case OPC_SHLL_S_PH:
12717                check_dsp(ctx);
12718                gen_helper_shll_s_ph(cpu_gpr[ret], t0, v2_t, cpu_env);
12719                break;
12720            case OPC_SHLLV_S_PH:
12721                check_dsp(ctx);
12722                gen_helper_shll_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12723                break;
12724            case OPC_SHLL_S_W:
12725                check_dsp(ctx);
12726                gen_helper_shll_s_w(cpu_gpr[ret], t0, v2_t, cpu_env);
12727                break;
12728            case OPC_SHLLV_S_W:
12729                check_dsp(ctx);
12730                gen_helper_shll_s_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12731                break;
12732            case OPC_SHRL_QB:
12733                check_dsp(ctx);
12734                gen_helper_shrl_qb(cpu_gpr[ret], t0, v2_t);
12735                break;
12736            case OPC_SHRLV_QB:
12737                check_dsp(ctx);
12738                gen_helper_shrl_qb(cpu_gpr[ret], v1_t, v2_t);
12739                break;
12740            case OPC_SHRL_PH:
12741                check_dsp_r2(ctx);
12742                gen_helper_shrl_ph(cpu_gpr[ret], t0, v2_t);
12743                break;
12744            case OPC_SHRLV_PH:
12745                check_dsp_r2(ctx);
12746                gen_helper_shrl_ph(cpu_gpr[ret], v1_t, v2_t);
12747                break;
12748            case OPC_SHRA_QB:
12749                check_dsp_r2(ctx);
12750                gen_helper_shra_qb(cpu_gpr[ret], t0, v2_t);
12751                break;
12752            case OPC_SHRA_R_QB:
12753                check_dsp_r2(ctx);
12754                gen_helper_shra_r_qb(cpu_gpr[ret], t0, v2_t);
12755                break;
12756            case OPC_SHRAV_QB:
12757                check_dsp_r2(ctx);
12758                gen_helper_shra_qb(cpu_gpr[ret], v1_t, v2_t);
12759                break;
12760            case OPC_SHRAV_R_QB:
12761                check_dsp_r2(ctx);
12762                gen_helper_shra_r_qb(cpu_gpr[ret], v1_t, v2_t);
12763                break;
12764            case OPC_SHRA_PH:
12765                check_dsp(ctx);
12766                gen_helper_shra_ph(cpu_gpr[ret], t0, v2_t);
12767                break;
12768            case OPC_SHRA_R_PH:
12769                check_dsp(ctx);
12770                gen_helper_shra_r_ph(cpu_gpr[ret], t0, v2_t);
12771                break;
12772            case OPC_SHRAV_PH:
12773                check_dsp(ctx);
12774                gen_helper_shra_ph(cpu_gpr[ret], v1_t, v2_t);
12775                break;
12776            case OPC_SHRAV_R_PH:
12777                check_dsp(ctx);
12778                gen_helper_shra_r_ph(cpu_gpr[ret], v1_t, v2_t);
12779                break;
12780            case OPC_SHRA_R_W:
12781                check_dsp(ctx);
12782                gen_helper_shra_r_w(cpu_gpr[ret], t0, v2_t);
12783                break;
12784            case OPC_SHRAV_R_W:
12785                check_dsp(ctx);
12786                gen_helper_shra_r_w(cpu_gpr[ret], v1_t, v2_t);
12787                break;
12788            default:            /* Invalid */
12789                MIPS_INVAL("MASK SHLL.QB");
12790                gen_reserved_instruction(ctx);
12791                break;
12792            }
12793            break;
12794        }
12795#ifdef TARGET_MIPS64
12796    case OPC_SHLL_OB_DSP:
12797        op2 = MASK_SHLL_OB(ctx->opcode);
12798        switch (op2) {
12799        case OPC_SHLL_PW:
12800            check_dsp(ctx);
12801            gen_helper_shll_pw(cpu_gpr[ret], v2_t, t0, cpu_env);
12802            break;
12803        case OPC_SHLLV_PW:
12804            check_dsp(ctx);
12805            gen_helper_shll_pw(cpu_gpr[ret], v2_t, v1_t, cpu_env);
12806            break;
12807        case OPC_SHLL_S_PW:
12808            check_dsp(ctx);
12809            gen_helper_shll_s_pw(cpu_gpr[ret], v2_t, t0, cpu_env);
12810            break;
12811        case OPC_SHLLV_S_PW:
12812            check_dsp(ctx);
12813            gen_helper_shll_s_pw(cpu_gpr[ret], v2_t, v1_t, cpu_env);
12814            break;
12815        case OPC_SHLL_OB:
12816            check_dsp(ctx);
12817            gen_helper_shll_ob(cpu_gpr[ret], v2_t, t0, cpu_env);
12818            break;
12819        case OPC_SHLLV_OB:
12820            check_dsp(ctx);
12821            gen_helper_shll_ob(cpu_gpr[ret], v2_t, v1_t, cpu_env);
12822            break;
12823        case OPC_SHLL_QH:
12824            check_dsp(ctx);
12825            gen_helper_shll_qh(cpu_gpr[ret], v2_t, t0, cpu_env);
12826            break;
12827        case OPC_SHLLV_QH:
12828            check_dsp(ctx);
12829            gen_helper_shll_qh(cpu_gpr[ret], v2_t, v1_t, cpu_env);
12830            break;
12831        case OPC_SHLL_S_QH:
12832            check_dsp(ctx);
12833            gen_helper_shll_s_qh(cpu_gpr[ret], v2_t, t0, cpu_env);
12834            break;
12835        case OPC_SHLLV_S_QH:
12836            check_dsp(ctx);
12837            gen_helper_shll_s_qh(cpu_gpr[ret], v2_t, v1_t, cpu_env);
12838            break;
12839        case OPC_SHRA_OB:
12840            check_dsp_r2(ctx);
12841            gen_helper_shra_ob(cpu_gpr[ret], v2_t, t0);
12842            break;
12843        case OPC_SHRAV_OB:
12844            check_dsp_r2(ctx);
12845            gen_helper_shra_ob(cpu_gpr[ret], v2_t, v1_t);
12846            break;
12847        case OPC_SHRA_R_OB:
12848            check_dsp_r2(ctx);
12849            gen_helper_shra_r_ob(cpu_gpr[ret], v2_t, t0);
12850            break;
12851        case OPC_SHRAV_R_OB:
12852            check_dsp_r2(ctx);
12853            gen_helper_shra_r_ob(cpu_gpr[ret], v2_t, v1_t);
12854            break;
12855        case OPC_SHRA_PW:
12856            check_dsp(ctx);
12857            gen_helper_shra_pw(cpu_gpr[ret], v2_t, t0);
12858            break;
12859        case OPC_SHRAV_PW:
12860            check_dsp(ctx);
12861            gen_helper_shra_pw(cpu_gpr[ret], v2_t, v1_t);
12862            break;
12863        case OPC_SHRA_R_PW:
12864            check_dsp(ctx);
12865            gen_helper_shra_r_pw(cpu_gpr[ret], v2_t, t0);
12866            break;
12867        case OPC_SHRAV_R_PW:
12868            check_dsp(ctx);
12869            gen_helper_shra_r_pw(cpu_gpr[ret], v2_t, v1_t);
12870            break;
12871        case OPC_SHRA_QH:
12872            check_dsp(ctx);
12873            gen_helper_shra_qh(cpu_gpr[ret], v2_t, t0);
12874            break;
12875        case OPC_SHRAV_QH:
12876            check_dsp(ctx);
12877            gen_helper_shra_qh(cpu_gpr[ret], v2_t, v1_t);
12878            break;
12879        case OPC_SHRA_R_QH:
12880            check_dsp(ctx);
12881            gen_helper_shra_r_qh(cpu_gpr[ret], v2_t, t0);
12882            break;
12883        case OPC_SHRAV_R_QH:
12884            check_dsp(ctx);
12885            gen_helper_shra_r_qh(cpu_gpr[ret], v2_t, v1_t);
12886            break;
12887        case OPC_SHRL_OB:
12888            check_dsp(ctx);
12889            gen_helper_shrl_ob(cpu_gpr[ret], v2_t, t0);
12890            break;
12891        case OPC_SHRLV_OB:
12892            check_dsp(ctx);
12893            gen_helper_shrl_ob(cpu_gpr[ret], v2_t, v1_t);
12894            break;
12895        case OPC_SHRL_QH:
12896            check_dsp_r2(ctx);
12897            gen_helper_shrl_qh(cpu_gpr[ret], v2_t, t0);
12898            break;
12899        case OPC_SHRLV_QH:
12900            check_dsp_r2(ctx);
12901            gen_helper_shrl_qh(cpu_gpr[ret], v2_t, v1_t);
12902            break;
12903        default:            /* Invalid */
12904            MIPS_INVAL("MASK SHLL.OB");
12905            gen_reserved_instruction(ctx);
12906            break;
12907        }
12908        break;
12909#endif
12910    }
12911
12912    tcg_temp_free(t0);
12913    tcg_temp_free(v1_t);
12914    tcg_temp_free(v2_t);
12915}
12916
12917static void gen_mipsdsp_multiply(DisasContext *ctx, uint32_t op1, uint32_t op2,
12918                                 int ret, int v1, int v2, int check_ret)
12919{
12920    TCGv_i32 t0;
12921    TCGv v1_t;
12922    TCGv v2_t;
12923
12924    if ((ret == 0) && (check_ret == 1)) {
12925        /* Treat as NOP. */
12926        return;
12927    }
12928
12929    t0 = tcg_temp_new_i32();
12930    v1_t = tcg_temp_new();
12931    v2_t = tcg_temp_new();
12932
12933    tcg_gen_movi_i32(t0, ret);
12934    gen_load_gpr(v1_t, v1);
12935    gen_load_gpr(v2_t, v2);
12936
12937    switch (op1) {
12938    /*
12939     * OPC_MULT_G_2E, OPC_ADDUH_QB_DSP, OPC_MUL_PH_DSP have
12940     * the same mask and op1.
12941     */
12942    case OPC_MULT_G_2E:
12943        check_dsp_r2(ctx);
12944        switch (op2) {
12945        case  OPC_MUL_PH:
12946            gen_helper_mul_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12947            break;
12948        case  OPC_MUL_S_PH:
12949            gen_helper_mul_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12950            break;
12951        case OPC_MULQ_S_W:
12952            gen_helper_mulq_s_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12953            break;
12954        case OPC_MULQ_RS_W:
12955            gen_helper_mulq_rs_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12956            break;
12957        }
12958        break;
12959    case OPC_DPA_W_PH_DSP:
12960        switch (op2) {
12961        case OPC_DPAU_H_QBL:
12962            check_dsp(ctx);
12963            gen_helper_dpau_h_qbl(t0, v1_t, v2_t, cpu_env);
12964            break;
12965        case OPC_DPAU_H_QBR:
12966            check_dsp(ctx);
12967            gen_helper_dpau_h_qbr(t0, v1_t, v2_t, cpu_env);
12968            break;
12969        case OPC_DPSU_H_QBL:
12970            check_dsp(ctx);
12971            gen_helper_dpsu_h_qbl(t0, v1_t, v2_t, cpu_env);
12972            break;
12973        case OPC_DPSU_H_QBR:
12974            check_dsp(ctx);
12975            gen_helper_dpsu_h_qbr(t0, v1_t, v2_t, cpu_env);
12976            break;
12977        case OPC_DPA_W_PH:
12978            check_dsp_r2(ctx);
12979            gen_helper_dpa_w_ph(t0, v1_t, v2_t, cpu_env);
12980            break;
12981        case OPC_DPAX_W_PH:
12982            check_dsp_r2(ctx);
12983            gen_helper_dpax_w_ph(t0, v1_t, v2_t, cpu_env);
12984            break;
12985        case OPC_DPAQ_S_W_PH:
12986            check_dsp(ctx);
12987            gen_helper_dpaq_s_w_ph(t0, v1_t, v2_t, cpu_env);
12988            break;
12989        case OPC_DPAQX_S_W_PH:
12990            check_dsp_r2(ctx);
12991            gen_helper_dpaqx_s_w_ph(t0, v1_t, v2_t, cpu_env);
12992            break;
12993        case OPC_DPAQX_SA_W_PH:
12994            check_dsp_r2(ctx);
12995            gen_helper_dpaqx_sa_w_ph(t0, v1_t, v2_t, cpu_env);
12996            break;
12997        case OPC_DPS_W_PH:
12998            check_dsp_r2(ctx);
12999            gen_helper_dps_w_ph(t0, v1_t, v2_t, cpu_env);
13000            break;
13001        case OPC_DPSX_W_PH:
13002            check_dsp_r2(ctx);
13003            gen_helper_dpsx_w_ph(t0, v1_t, v2_t, cpu_env);
13004            break;
13005        case OPC_DPSQ_S_W_PH:
13006            check_dsp(ctx);
13007            gen_helper_dpsq_s_w_ph(t0, v1_t, v2_t, cpu_env);
13008            break;
13009        case OPC_DPSQX_S_W_PH:
13010            check_dsp_r2(ctx);
13011            gen_helper_dpsqx_s_w_ph(t0, v1_t, v2_t, cpu_env);
13012            break;
13013        case OPC_DPSQX_SA_W_PH:
13014            check_dsp_r2(ctx);
13015            gen_helper_dpsqx_sa_w_ph(t0, v1_t, v2_t, cpu_env);
13016            break;
13017        case OPC_MULSAQ_S_W_PH:
13018            check_dsp(ctx);
13019            gen_helper_mulsaq_s_w_ph(t0, v1_t, v2_t, cpu_env);
13020            break;
13021        case OPC_DPAQ_SA_L_W:
13022            check_dsp(ctx);
13023            gen_helper_dpaq_sa_l_w(t0, v1_t, v2_t, cpu_env);
13024            break;
13025        case OPC_DPSQ_SA_L_W:
13026            check_dsp(ctx);
13027            gen_helper_dpsq_sa_l_w(t0, v1_t, v2_t, cpu_env);
13028            break;
13029        case OPC_MAQ_S_W_PHL:
13030            check_dsp(ctx);
13031            gen_helper_maq_s_w_phl(t0, v1_t, v2_t, cpu_env);
13032            break;
13033        case OPC_MAQ_S_W_PHR:
13034            check_dsp(ctx);
13035            gen_helper_maq_s_w_phr(t0, v1_t, v2_t, cpu_env);
13036            break;
13037        case OPC_MAQ_SA_W_PHL:
13038            check_dsp(ctx);
13039            gen_helper_maq_sa_w_phl(t0, v1_t, v2_t, cpu_env);
13040            break;
13041        case OPC_MAQ_SA_W_PHR:
13042            check_dsp(ctx);
13043            gen_helper_maq_sa_w_phr(t0, v1_t, v2_t, cpu_env);
13044            break;
13045        case OPC_MULSA_W_PH:
13046            check_dsp_r2(ctx);
13047            gen_helper_mulsa_w_ph(t0, v1_t, v2_t, cpu_env);
13048            break;
13049        }
13050        break;
13051#ifdef TARGET_MIPS64
13052    case OPC_DPAQ_W_QH_DSP:
13053        {
13054            int ac = ret & 0x03;
13055            tcg_gen_movi_i32(t0, ac);
13056
13057            switch (op2) {
13058            case OPC_DMADD:
13059                check_dsp(ctx);
13060                gen_helper_dmadd(v1_t, v2_t, t0, cpu_env);
13061                break;
13062            case OPC_DMADDU:
13063                check_dsp(ctx);
13064                gen_helper_dmaddu(v1_t, v2_t, t0, cpu_env);
13065                break;
13066            case OPC_DMSUB:
13067                check_dsp(ctx);
13068                gen_helper_dmsub(v1_t, v2_t, t0, cpu_env);
13069                break;
13070            case OPC_DMSUBU:
13071                check_dsp(ctx);
13072                gen_helper_dmsubu(v1_t, v2_t, t0, cpu_env);
13073                break;
13074            case OPC_DPA_W_QH:
13075                check_dsp_r2(ctx);
13076                gen_helper_dpa_w_qh(v1_t, v2_t, t0, cpu_env);
13077                break;
13078            case OPC_DPAQ_S_W_QH:
13079                check_dsp(ctx);
13080                gen_helper_dpaq_s_w_qh(v1_t, v2_t, t0, cpu_env);
13081                break;
13082            case OPC_DPAQ_SA_L_PW:
13083                check_dsp(ctx);
13084                gen_helper_dpaq_sa_l_pw(v1_t, v2_t, t0, cpu_env);
13085                break;
13086            case OPC_DPAU_H_OBL:
13087                check_dsp(ctx);
13088                gen_helper_dpau_h_obl(v1_t, v2_t, t0, cpu_env);
13089                break;
13090            case OPC_DPAU_H_OBR:
13091                check_dsp(ctx);
13092                gen_helper_dpau_h_obr(v1_t, v2_t, t0, cpu_env);
13093                break;
13094            case OPC_DPS_W_QH:
13095                check_dsp_r2(ctx);
13096                gen_helper_dps_w_qh(v1_t, v2_t, t0, cpu_env);
13097                break;
13098            case OPC_DPSQ_S_W_QH:
13099                check_dsp(ctx);
13100                gen_helper_dpsq_s_w_qh(v1_t, v2_t, t0, cpu_env);
13101                break;
13102            case OPC_DPSQ_SA_L_PW:
13103                check_dsp(ctx);
13104                gen_helper_dpsq_sa_l_pw(v1_t, v2_t, t0, cpu_env);
13105                break;
13106            case OPC_DPSU_H_OBL:
13107                check_dsp(ctx);
13108                gen_helper_dpsu_h_obl(v1_t, v2_t, t0, cpu_env);
13109                break;
13110            case OPC_DPSU_H_OBR:
13111                check_dsp(ctx);
13112                gen_helper_dpsu_h_obr(v1_t, v2_t, t0, cpu_env);
13113                break;
13114            case OPC_MAQ_S_L_PWL:
13115                check_dsp(ctx);
13116                gen_helper_maq_s_l_pwl(v1_t, v2_t, t0, cpu_env);
13117                break;
13118            case OPC_MAQ_S_L_PWR:
13119                check_dsp(ctx);
13120                gen_helper_maq_s_l_pwr(v1_t, v2_t, t0, cpu_env);
13121                break;
13122            case OPC_MAQ_S_W_QHLL:
13123                check_dsp(ctx);
13124                gen_helper_maq_s_w_qhll(v1_t, v2_t, t0, cpu_env);
13125                break;
13126            case OPC_MAQ_SA_W_QHLL:
13127                check_dsp(ctx);
13128                gen_helper_maq_sa_w_qhll(v1_t, v2_t, t0, cpu_env);
13129                break;
13130            case OPC_MAQ_S_W_QHLR:
13131                check_dsp(ctx);
13132                gen_helper_maq_s_w_qhlr(v1_t, v2_t, t0, cpu_env);
13133                break;
13134            case OPC_MAQ_SA_W_QHLR:
13135                check_dsp(ctx);
13136                gen_helper_maq_sa_w_qhlr(v1_t, v2_t, t0, cpu_env);
13137                break;
13138            case OPC_MAQ_S_W_QHRL:
13139                check_dsp(ctx);
13140                gen_helper_maq_s_w_qhrl(v1_t, v2_t, t0, cpu_env);
13141                break;
13142            case OPC_MAQ_SA_W_QHRL:
13143                check_dsp(ctx);
13144                gen_helper_maq_sa_w_qhrl(v1_t, v2_t, t0, cpu_env);
13145                break;
13146            case OPC_MAQ_S_W_QHRR:
13147                check_dsp(ctx);
13148                gen_helper_maq_s_w_qhrr(v1_t, v2_t, t0, cpu_env);
13149                break;
13150            case OPC_MAQ_SA_W_QHRR:
13151                check_dsp(ctx);
13152                gen_helper_maq_sa_w_qhrr(v1_t, v2_t, t0, cpu_env);
13153                break;
13154            case OPC_MULSAQ_S_L_PW:
13155                check_dsp(ctx);
13156                gen_helper_mulsaq_s_l_pw(v1_t, v2_t, t0, cpu_env);
13157                break;
13158            case OPC_MULSAQ_S_W_QH:
13159                check_dsp(ctx);
13160                gen_helper_mulsaq_s_w_qh(v1_t, v2_t, t0, cpu_env);
13161                break;
13162            }
13163        }
13164        break;
13165#endif
13166    case OPC_ADDU_QB_DSP:
13167        switch (op2) {
13168        case OPC_MULEU_S_PH_QBL:
13169            check_dsp(ctx);
13170            gen_helper_muleu_s_ph_qbl(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13171            break;
13172        case OPC_MULEU_S_PH_QBR:
13173            check_dsp(ctx);
13174            gen_helper_muleu_s_ph_qbr(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13175            break;
13176        case OPC_MULQ_RS_PH:
13177            check_dsp(ctx);
13178            gen_helper_mulq_rs_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13179            break;
13180        case OPC_MULEQ_S_W_PHL:
13181            check_dsp(ctx);
13182            gen_helper_muleq_s_w_phl(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13183            break;
13184        case OPC_MULEQ_S_W_PHR:
13185            check_dsp(ctx);
13186            gen_helper_muleq_s_w_phr(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13187            break;
13188        case OPC_MULQ_S_PH:
13189            check_dsp_r2(ctx);
13190            gen_helper_mulq_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13191            break;
13192        }
13193        break;
13194#ifdef TARGET_MIPS64
13195    case OPC_ADDU_OB_DSP:
13196        switch (op2) {
13197        case OPC_MULEQ_S_PW_QHL:
13198            check_dsp(ctx);
13199            gen_helper_muleq_s_pw_qhl(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13200            break;
13201        case OPC_MULEQ_S_PW_QHR:
13202            check_dsp(ctx);
13203            gen_helper_muleq_s_pw_qhr(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13204            break;
13205        case OPC_MULEU_S_QH_OBL:
13206            check_dsp(ctx);
13207            gen_helper_muleu_s_qh_obl(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13208            break;
13209        case OPC_MULEU_S_QH_OBR:
13210            check_dsp(ctx);
13211            gen_helper_muleu_s_qh_obr(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13212            break;
13213        case OPC_MULQ_RS_QH:
13214            check_dsp(ctx);
13215            gen_helper_mulq_rs_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13216            break;
13217        }
13218        break;
13219#endif
13220    }
13221
13222    tcg_temp_free_i32(t0);
13223    tcg_temp_free(v1_t);
13224    tcg_temp_free(v2_t);
13225}
13226
13227static void gen_mipsdsp_bitinsn(DisasContext *ctx, uint32_t op1, uint32_t op2,
13228                                int ret, int val)
13229{
13230    int16_t imm;
13231    TCGv t0;
13232    TCGv val_t;
13233
13234    if (ret == 0) {
13235        /* Treat as NOP. */
13236        return;
13237    }
13238
13239    t0 = tcg_temp_new();
13240    val_t = tcg_temp_new();
13241    gen_load_gpr(val_t, val);
13242
13243    switch (op1) {
13244    case OPC_ABSQ_S_PH_DSP:
13245        switch (op2) {
13246        case OPC_BITREV:
13247            check_dsp(ctx);
13248            gen_helper_bitrev(cpu_gpr[ret], val_t);
13249            break;
13250        case OPC_REPL_QB:
13251            check_dsp(ctx);
13252            {
13253                target_long result;
13254                imm = (ctx->opcode >> 16) & 0xFF;
13255                result = (uint32_t)imm << 24 |
13256                         (uint32_t)imm << 16 |
13257                         (uint32_t)imm << 8  |
13258                         (uint32_t)imm;
13259                result = (int32_t)result;
13260                tcg_gen_movi_tl(cpu_gpr[ret], result);
13261            }
13262            break;
13263        case OPC_REPLV_QB:
13264            check_dsp(ctx);
13265            tcg_gen_ext8u_tl(cpu_gpr[ret], val_t);
13266            tcg_gen_shli_tl(t0, cpu_gpr[ret], 8);
13267            tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
13268            tcg_gen_shli_tl(t0, cpu_gpr[ret], 16);
13269            tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
13270            tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]);
13271            break;
13272        case OPC_REPL_PH:
13273            check_dsp(ctx);
13274            {
13275                imm = (ctx->opcode >> 16) & 0x03FF;
13276                imm = (int16_t)(imm << 6) >> 6;
13277                tcg_gen_movi_tl(cpu_gpr[ret], \
13278                                (target_long)((int32_t)imm << 16 | \
13279                                (uint16_t)imm));
13280            }
13281            break;
13282        case OPC_REPLV_PH:
13283            check_dsp(ctx);
13284            tcg_gen_ext16u_tl(cpu_gpr[ret], val_t);
13285            tcg_gen_shli_tl(t0, cpu_gpr[ret], 16);
13286            tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
13287            tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]);
13288            break;
13289        }
13290        break;
13291#ifdef TARGET_MIPS64
13292    case OPC_ABSQ_S_QH_DSP:
13293        switch (op2) {
13294        case OPC_REPL_OB:
13295            check_dsp(ctx);
13296            {
13297                target_long temp;
13298
13299                imm = (ctx->opcode >> 16) & 0xFF;
13300                temp = ((uint64_t)imm << 8) | (uint64_t)imm;
13301                temp = (temp << 16) | temp;
13302                temp = (temp << 32) | temp;
13303                tcg_gen_movi_tl(cpu_gpr[ret], temp);
13304                break;
13305            }
13306        case OPC_REPL_PW:
13307            check_dsp(ctx);
13308            {
13309                target_long temp;
13310
13311                imm = (ctx->opcode >> 16) & 0x03FF;
13312                imm = (int16_t)(imm << 6) >> 6;
13313                temp = ((target_long)imm << 32) \
13314                       | ((target_long)imm & 0xFFFFFFFF);
13315                tcg_gen_movi_tl(cpu_gpr[ret], temp);
13316                break;
13317            }
13318        case OPC_REPL_QH:
13319            check_dsp(ctx);
13320            {
13321                target_long temp;
13322
13323                imm = (ctx->opcode >> 16) & 0x03FF;
13324                imm = (int16_t)(imm << 6) >> 6;
13325
13326                temp = ((uint64_t)(uint16_t)imm << 48) |
13327                       ((uint64_t)(uint16_t)imm << 32) |
13328                       ((uint64_t)(uint16_t)imm << 16) |
13329                       (uint64_t)(uint16_t)imm;
13330                tcg_gen_movi_tl(cpu_gpr[ret], temp);
13331                break;
13332            }
13333        case OPC_REPLV_OB:
13334            check_dsp(ctx);
13335            tcg_gen_ext8u_tl(cpu_gpr[ret], val_t);
13336            tcg_gen_shli_tl(t0, cpu_gpr[ret], 8);
13337            tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
13338            tcg_gen_shli_tl(t0, cpu_gpr[ret], 16);
13339            tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
13340            tcg_gen_shli_tl(t0, cpu_gpr[ret], 32);
13341            tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
13342            break;
13343        case OPC_REPLV_PW:
13344            check_dsp(ctx);
13345            tcg_gen_ext32u_i64(cpu_gpr[ret], val_t);
13346            tcg_gen_shli_tl(t0, cpu_gpr[ret], 32);
13347            tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
13348            break;
13349        case OPC_REPLV_QH:
13350            check_dsp(ctx);
13351            tcg_gen_ext16u_tl(cpu_gpr[ret], val_t);
13352            tcg_gen_shli_tl(t0, cpu_gpr[ret], 16);
13353            tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
13354            tcg_gen_shli_tl(t0, cpu_gpr[ret], 32);
13355            tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
13356            break;
13357        }
13358        break;
13359#endif
13360    }
13361    tcg_temp_free(t0);
13362    tcg_temp_free(val_t);
13363}
13364
13365static void gen_mipsdsp_add_cmp_pick(DisasContext *ctx,
13366                                     uint32_t op1, uint32_t op2,
13367                                     int ret, int v1, int v2, int check_ret)
13368{
13369    TCGv t1;
13370    TCGv v1_t;
13371    TCGv v2_t;
13372
13373    if ((ret == 0) && (check_ret == 1)) {
13374        /* Treat as NOP. */
13375        return;
13376    }
13377
13378    t1 = tcg_temp_new();
13379    v1_t = tcg_temp_new();
13380    v2_t = tcg_temp_new();
13381
13382    gen_load_gpr(v1_t, v1);
13383    gen_load_gpr(v2_t, v2);
13384
13385    switch (op1) {
13386    case OPC_CMPU_EQ_QB_DSP:
13387        switch (op2) {
13388        case OPC_CMPU_EQ_QB:
13389            check_dsp(ctx);
13390            gen_helper_cmpu_eq_qb(v1_t, v2_t, cpu_env);
13391            break;
13392        case OPC_CMPU_LT_QB:
13393            check_dsp(ctx);
13394            gen_helper_cmpu_lt_qb(v1_t, v2_t, cpu_env);
13395            break;
13396        case OPC_CMPU_LE_QB:
13397            check_dsp(ctx);
13398            gen_helper_cmpu_le_qb(v1_t, v2_t, cpu_env);
13399            break;
13400        case OPC_CMPGU_EQ_QB:
13401            check_dsp(ctx);
13402            gen_helper_cmpgu_eq_qb(cpu_gpr[ret], v1_t, v2_t);
13403            break;
13404        case OPC_CMPGU_LT_QB:
13405            check_dsp(ctx);
13406            gen_helper_cmpgu_lt_qb(cpu_gpr[ret], v1_t, v2_t);
13407            break;
13408        case OPC_CMPGU_LE_QB:
13409            check_dsp(ctx);
13410            gen_helper_cmpgu_le_qb(cpu_gpr[ret], v1_t, v2_t);
13411            break;
13412        case OPC_CMPGDU_EQ_QB:
13413            check_dsp_r2(ctx);
13414            gen_helper_cmpgu_eq_qb(t1, v1_t, v2_t);
13415            tcg_gen_mov_tl(cpu_gpr[ret], t1);
13416            tcg_gen_andi_tl(cpu_dspctrl, cpu_dspctrl, 0xF0FFFFFF);
13417            tcg_gen_shli_tl(t1, t1, 24);
13418            tcg_gen_or_tl(cpu_dspctrl, cpu_dspctrl, t1);
13419            break;
13420        case OPC_CMPGDU_LT_QB:
13421            check_dsp_r2(ctx);
13422            gen_helper_cmpgu_lt_qb(t1, v1_t, v2_t);
13423            tcg_gen_mov_tl(cpu_gpr[ret], t1);
13424            tcg_gen_andi_tl(cpu_dspctrl, cpu_dspctrl, 0xF0FFFFFF);
13425            tcg_gen_shli_tl(t1, t1, 24);
13426            tcg_gen_or_tl(cpu_dspctrl, cpu_dspctrl, t1);
13427            break;
13428        case OPC_CMPGDU_LE_QB:
13429            check_dsp_r2(ctx);
13430            gen_helper_cmpgu_le_qb(t1, v1_t, v2_t);
13431            tcg_gen_mov_tl(cpu_gpr[ret], t1);
13432            tcg_gen_andi_tl(cpu_dspctrl, cpu_dspctrl, 0xF0FFFFFF);
13433            tcg_gen_shli_tl(t1, t1, 24);
13434            tcg_gen_or_tl(cpu_dspctrl, cpu_dspctrl, t1);
13435            break;
13436        case OPC_CMP_EQ_PH:
13437            check_dsp(ctx);
13438            gen_helper_cmp_eq_ph(v1_t, v2_t, cpu_env);
13439            break;
13440        case OPC_CMP_LT_PH:
13441            check_dsp(ctx);
13442            gen_helper_cmp_lt_ph(v1_t, v2_t, cpu_env);
13443            break;
13444        case OPC_CMP_LE_PH:
13445            check_dsp(ctx);
13446            gen_helper_cmp_le_ph(v1_t, v2_t, cpu_env);
13447            break;
13448        case OPC_PICK_QB:
13449            check_dsp(ctx);
13450            gen_helper_pick_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13451            break;
13452        case OPC_PICK_PH:
13453            check_dsp(ctx);
13454            gen_helper_pick_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13455            break;
13456        case OPC_PACKRL_PH:
13457            check_dsp(ctx);
13458            gen_helper_packrl_ph(cpu_gpr[ret], v1_t, v2_t);
13459            break;
13460        }
13461        break;
13462#ifdef TARGET_MIPS64
13463    case OPC_CMPU_EQ_OB_DSP:
13464        switch (op2) {
13465        case OPC_CMP_EQ_PW:
13466            check_dsp(ctx);
13467            gen_helper_cmp_eq_pw(v1_t, v2_t, cpu_env);
13468            break;
13469        case OPC_CMP_LT_PW:
13470            check_dsp(ctx);
13471            gen_helper_cmp_lt_pw(v1_t, v2_t, cpu_env);
13472            break;
13473        case OPC_CMP_LE_PW:
13474            check_dsp(ctx);
13475            gen_helper_cmp_le_pw(v1_t, v2_t, cpu_env);
13476            break;
13477        case OPC_CMP_EQ_QH:
13478            check_dsp(ctx);
13479            gen_helper_cmp_eq_qh(v1_t, v2_t, cpu_env);
13480            break;
13481        case OPC_CMP_LT_QH:
13482            check_dsp(ctx);
13483            gen_helper_cmp_lt_qh(v1_t, v2_t, cpu_env);
13484            break;
13485        case OPC_CMP_LE_QH:
13486            check_dsp(ctx);
13487            gen_helper_cmp_le_qh(v1_t, v2_t, cpu_env);
13488            break;
13489        case OPC_CMPGDU_EQ_OB:
13490            check_dsp_r2(ctx);
13491            gen_helper_cmpgdu_eq_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13492            break;
13493        case OPC_CMPGDU_LT_OB:
13494            check_dsp_r2(ctx);
13495            gen_helper_cmpgdu_lt_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13496            break;
13497        case OPC_CMPGDU_LE_OB:
13498            check_dsp_r2(ctx);
13499            gen_helper_cmpgdu_le_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13500            break;
13501        case OPC_CMPGU_EQ_OB:
13502            check_dsp(ctx);
13503            gen_helper_cmpgu_eq_ob(cpu_gpr[ret], v1_t, v2_t);
13504            break;
13505        case OPC_CMPGU_LT_OB:
13506            check_dsp(ctx);
13507            gen_helper_cmpgu_lt_ob(cpu_gpr[ret], v1_t, v2_t);
13508            break;
13509        case OPC_CMPGU_LE_OB:
13510            check_dsp(ctx);
13511            gen_helper_cmpgu_le_ob(cpu_gpr[ret], v1_t, v2_t);
13512            break;
13513        case OPC_CMPU_EQ_OB:
13514            check_dsp(ctx);
13515            gen_helper_cmpu_eq_ob(v1_t, v2_t, cpu_env);
13516            break;
13517        case OPC_CMPU_LT_OB:
13518            check_dsp(ctx);
13519            gen_helper_cmpu_lt_ob(v1_t, v2_t, cpu_env);
13520            break;
13521        case OPC_CMPU_LE_OB:
13522            check_dsp(ctx);
13523            gen_helper_cmpu_le_ob(v1_t, v2_t, cpu_env);
13524            break;
13525        case OPC_PACKRL_PW:
13526            check_dsp(ctx);
13527            gen_helper_packrl_pw(cpu_gpr[ret], v1_t, v2_t);
13528            break;
13529        case OPC_PICK_OB:
13530            check_dsp(ctx);
13531            gen_helper_pick_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13532            break;
13533        case OPC_PICK_PW:
13534            check_dsp(ctx);
13535            gen_helper_pick_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13536            break;
13537        case OPC_PICK_QH:
13538            check_dsp(ctx);
13539            gen_helper_pick_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13540            break;
13541        }
13542        break;
13543#endif
13544    }
13545
13546    tcg_temp_free(t1);
13547    tcg_temp_free(v1_t);
13548    tcg_temp_free(v2_t);
13549}
13550
13551static void gen_mipsdsp_append(CPUMIPSState *env, DisasContext *ctx,
13552                               uint32_t op1, int rt, int rs, int sa)
13553{
13554    TCGv t0;
13555
13556    check_dsp_r2(ctx);
13557
13558    if (rt == 0) {
13559        /* Treat as NOP. */
13560        return;
13561    }
13562
13563    t0 = tcg_temp_new();
13564    gen_load_gpr(t0, rs);
13565
13566    switch (op1) {
13567    case OPC_APPEND_DSP:
13568        switch (MASK_APPEND(ctx->opcode)) {
13569        case OPC_APPEND:
13570            if (sa != 0) {
13571                tcg_gen_deposit_tl(cpu_gpr[rt], t0, cpu_gpr[rt], sa, 32 - sa);
13572            }
13573            tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
13574            break;
13575        case OPC_PREPEND:
13576            if (sa != 0) {
13577                tcg_gen_ext32u_tl(cpu_gpr[rt], cpu_gpr[rt]);
13578                tcg_gen_shri_tl(cpu_gpr[rt], cpu_gpr[rt], sa);
13579                tcg_gen_shli_tl(t0, t0, 32 - sa);
13580                tcg_gen_or_tl(cpu_gpr[rt], cpu_gpr[rt], t0);
13581            }
13582            tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
13583            break;
13584        case OPC_BALIGN:
13585            sa &= 3;
13586            if (sa != 0 && sa != 2) {
13587                tcg_gen_shli_tl(cpu_gpr[rt], cpu_gpr[rt], 8 * sa);
13588                tcg_gen_ext32u_tl(t0, t0);
13589                tcg_gen_shri_tl(t0, t0, 8 * (4 - sa));
13590                tcg_gen_or_tl(cpu_gpr[rt], cpu_gpr[rt], t0);
13591            }
13592            tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
13593            break;
13594        default:            /* Invalid */
13595            MIPS_INVAL("MASK APPEND");
13596            gen_reserved_instruction(ctx);
13597            break;
13598        }
13599        break;
13600#ifdef TARGET_MIPS64
13601    case OPC_DAPPEND_DSP:
13602        switch (MASK_DAPPEND(ctx->opcode)) {
13603        case OPC_DAPPEND:
13604            if (sa != 0) {
13605                tcg_gen_deposit_tl(cpu_gpr[rt], t0, cpu_gpr[rt], sa, 64 - sa);
13606            }
13607            break;
13608        case OPC_PREPENDD:
13609            tcg_gen_shri_tl(cpu_gpr[rt], cpu_gpr[rt], 0x20 | sa);
13610            tcg_gen_shli_tl(t0, t0, 64 - (0x20 | sa));
13611            tcg_gen_or_tl(cpu_gpr[rt], t0, t0);
13612            break;
13613        case OPC_PREPENDW:
13614            if (sa != 0) {
13615                tcg_gen_shri_tl(cpu_gpr[rt], cpu_gpr[rt], sa);
13616                tcg_gen_shli_tl(t0, t0, 64 - sa);
13617                tcg_gen_or_tl(cpu_gpr[rt], cpu_gpr[rt], t0);
13618            }
13619            break;
13620        case OPC_DBALIGN:
13621            sa &= 7;
13622            if (sa != 0 && sa != 2 && sa != 4) {
13623                tcg_gen_shli_tl(cpu_gpr[rt], cpu_gpr[rt], 8 * sa);
13624                tcg_gen_shri_tl(t0, t0, 8 * (8 - sa));
13625                tcg_gen_or_tl(cpu_gpr[rt], cpu_gpr[rt], t0);
13626            }
13627            break;
13628        default:            /* Invalid */
13629            MIPS_INVAL("MASK DAPPEND");
13630            gen_reserved_instruction(ctx);
13631            break;
13632        }
13633        break;
13634#endif
13635    }
13636    tcg_temp_free(t0);
13637}
13638
13639static void gen_mipsdsp_accinsn(DisasContext *ctx, uint32_t op1, uint32_t op2,
13640                                int ret, int v1, int v2, int check_ret)
13641
13642{
13643    TCGv t0;
13644    TCGv t1;
13645    TCGv v1_t;
13646    int16_t imm;
13647
13648    if ((ret == 0) && (check_ret == 1)) {
13649        /* Treat as NOP. */
13650        return;
13651    }
13652
13653    t0 = tcg_temp_new();
13654    t1 = tcg_temp_new();
13655    v1_t = tcg_temp_new();
13656
13657    gen_load_gpr(v1_t, v1);
13658
13659    switch (op1) {
13660    case OPC_EXTR_W_DSP:
13661        check_dsp(ctx);
13662        switch (op2) {
13663        case OPC_EXTR_W:
13664            tcg_gen_movi_tl(t0, v2);
13665            tcg_gen_movi_tl(t1, v1);
13666            gen_helper_extr_w(cpu_gpr[ret], t0, t1, cpu_env);
13667            break;
13668        case OPC_EXTR_R_W:
13669            tcg_gen_movi_tl(t0, v2);
13670            tcg_gen_movi_tl(t1, v1);
13671            gen_helper_extr_r_w(cpu_gpr[ret], t0, t1, cpu_env);
13672            break;
13673        case OPC_EXTR_RS_W:
13674            tcg_gen_movi_tl(t0, v2);
13675            tcg_gen_movi_tl(t1, v1);
13676            gen_helper_extr_rs_w(cpu_gpr[ret], t0, t1, cpu_env);
13677            break;
13678        case OPC_EXTR_S_H:
13679            tcg_gen_movi_tl(t0, v2);
13680            tcg_gen_movi_tl(t1, v1);
13681            gen_helper_extr_s_h(cpu_gpr[ret], t0, t1, cpu_env);
13682            break;
13683        case OPC_EXTRV_S_H:
13684            tcg_gen_movi_tl(t0, v2);
13685            gen_helper_extr_s_h(cpu_gpr[ret], t0, v1_t, cpu_env);
13686            break;
13687        case OPC_EXTRV_W:
13688            tcg_gen_movi_tl(t0, v2);
13689            gen_helper_extr_w(cpu_gpr[ret], t0, v1_t, cpu_env);
13690            break;
13691        case OPC_EXTRV_R_W:
13692            tcg_gen_movi_tl(t0, v2);
13693            gen_helper_extr_r_w(cpu_gpr[ret], t0, v1_t, cpu_env);
13694            break;
13695        case OPC_EXTRV_RS_W:
13696            tcg_gen_movi_tl(t0, v2);
13697            gen_helper_extr_rs_w(cpu_gpr[ret], t0, v1_t, cpu_env);
13698            break;
13699        case OPC_EXTP:
13700            tcg_gen_movi_tl(t0, v2);
13701            tcg_gen_movi_tl(t1, v1);
13702            gen_helper_extp(cpu_gpr[ret], t0, t1, cpu_env);
13703            break;
13704        case OPC_EXTPV:
13705            tcg_gen_movi_tl(t0, v2);
13706            gen_helper_extp(cpu_gpr[ret], t0, v1_t, cpu_env);
13707            break;
13708        case OPC_EXTPDP:
13709            tcg_gen_movi_tl(t0, v2);
13710            tcg_gen_movi_tl(t1, v1);
13711            gen_helper_extpdp(cpu_gpr[ret], t0, t1, cpu_env);
13712            break;
13713        case OPC_EXTPDPV:
13714            tcg_gen_movi_tl(t0, v2);
13715            gen_helper_extpdp(cpu_gpr[ret], t0, v1_t, cpu_env);
13716            break;
13717        case OPC_SHILO:
13718            imm = (ctx->opcode >> 20) & 0x3F;
13719            tcg_gen_movi_tl(t0, ret);
13720            tcg_gen_movi_tl(t1, imm);
13721            gen_helper_shilo(t0, t1, cpu_env);
13722            break;
13723        case OPC_SHILOV:
13724            tcg_gen_movi_tl(t0, ret);
13725            gen_helper_shilo(t0, v1_t, cpu_env);
13726            break;
13727        case OPC_MTHLIP:
13728            tcg_gen_movi_tl(t0, ret);
13729            gen_helper_mthlip(t0, v1_t, cpu_env);
13730            break;
13731        case OPC_WRDSP:
13732            imm = (ctx->opcode >> 11) & 0x3FF;
13733            tcg_gen_movi_tl(t0, imm);
13734            gen_helper_wrdsp(v1_t, t0, cpu_env);
13735            break;
13736        case OPC_RDDSP:
13737            imm = (ctx->opcode >> 16) & 0x03FF;
13738            tcg_gen_movi_tl(t0, imm);
13739            gen_helper_rddsp(cpu_gpr[ret], t0, cpu_env);
13740            break;
13741        }
13742        break;
13743#ifdef TARGET_MIPS64
13744    case OPC_DEXTR_W_DSP:
13745        check_dsp(ctx);
13746        switch (op2) {
13747        case OPC_DMTHLIP:
13748            tcg_gen_movi_tl(t0, ret);
13749            gen_helper_dmthlip(v1_t, t0, cpu_env);
13750            break;
13751        case OPC_DSHILO:
13752            {
13753                int shift = (ctx->opcode >> 19) & 0x7F;
13754                int ac = (ctx->opcode >> 11) & 0x03;
13755                tcg_gen_movi_tl(t0, shift);
13756                tcg_gen_movi_tl(t1, ac);
13757                gen_helper_dshilo(t0, t1, cpu_env);
13758                break;
13759            }
13760        case OPC_DSHILOV:
13761            {
13762                int ac = (ctx->opcode >> 11) & 0x03;
13763                tcg_gen_movi_tl(t0, ac);
13764                gen_helper_dshilo(v1_t, t0, cpu_env);
13765                break;
13766            }
13767        case OPC_DEXTP:
13768            tcg_gen_movi_tl(t0, v2);
13769            tcg_gen_movi_tl(t1, v1);
13770
13771            gen_helper_dextp(cpu_gpr[ret], t0, t1, cpu_env);
13772            break;
13773        case OPC_DEXTPV:
13774            tcg_gen_movi_tl(t0, v2);
13775            gen_helper_dextp(cpu_gpr[ret], t0, v1_t, cpu_env);
13776            break;
13777        case OPC_DEXTPDP:
13778            tcg_gen_movi_tl(t0, v2);
13779            tcg_gen_movi_tl(t1, v1);
13780            gen_helper_dextpdp(cpu_gpr[ret], t0, t1, cpu_env);
13781            break;
13782        case OPC_DEXTPDPV:
13783            tcg_gen_movi_tl(t0, v2);
13784            gen_helper_dextpdp(cpu_gpr[ret], t0, v1_t, cpu_env);
13785            break;
13786        case OPC_DEXTR_L:
13787            tcg_gen_movi_tl(t0, v2);
13788            tcg_gen_movi_tl(t1, v1);
13789            gen_helper_dextr_l(cpu_gpr[ret], t0, t1, cpu_env);
13790            break;
13791        case OPC_DEXTR_R_L:
13792            tcg_gen_movi_tl(t0, v2);
13793            tcg_gen_movi_tl(t1, v1);
13794            gen_helper_dextr_r_l(cpu_gpr[ret], t0, t1, cpu_env);
13795            break;
13796        case OPC_DEXTR_RS_L:
13797            tcg_gen_movi_tl(t0, v2);
13798            tcg_gen_movi_tl(t1, v1);
13799            gen_helper_dextr_rs_l(cpu_gpr[ret], t0, t1, cpu_env);
13800            break;
13801        case OPC_DEXTR_W:
13802            tcg_gen_movi_tl(t0, v2);
13803            tcg_gen_movi_tl(t1, v1);
13804            gen_helper_dextr_w(cpu_gpr[ret], t0, t1, cpu_env);
13805            break;
13806        case OPC_DEXTR_R_W:
13807            tcg_gen_movi_tl(t0, v2);
13808            tcg_gen_movi_tl(t1, v1);
13809            gen_helper_dextr_r_w(cpu_gpr[ret], t0, t1, cpu_env);
13810            break;
13811        case OPC_DEXTR_RS_W:
13812            tcg_gen_movi_tl(t0, v2);
13813            tcg_gen_movi_tl(t1, v1);
13814            gen_helper_dextr_rs_w(cpu_gpr[ret], t0, t1, cpu_env);
13815            break;
13816        case OPC_DEXTR_S_H:
13817            tcg_gen_movi_tl(t0, v2);
13818            tcg_gen_movi_tl(t1, v1);
13819            gen_helper_dextr_s_h(cpu_gpr[ret], t0, t1, cpu_env);
13820            break;
13821        case OPC_DEXTRV_S_H:
13822            tcg_gen_movi_tl(t0, v2);
13823            gen_helper_dextr_s_h(cpu_gpr[ret], t0, v1_t, cpu_env);
13824            break;
13825        case OPC_DEXTRV_L:
13826            tcg_gen_movi_tl(t0, v2);
13827            gen_helper_dextr_l(cpu_gpr[ret], t0, v1_t, cpu_env);
13828            break;
13829        case OPC_DEXTRV_R_L:
13830            tcg_gen_movi_tl(t0, v2);
13831            gen_helper_dextr_r_l(cpu_gpr[ret], t0, v1_t, cpu_env);
13832            break;
13833        case OPC_DEXTRV_RS_L:
13834            tcg_gen_movi_tl(t0, v2);
13835            gen_helper_dextr_rs_l(cpu_gpr[ret], t0, v1_t, cpu_env);
13836            break;
13837        case OPC_DEXTRV_W:
13838            tcg_gen_movi_tl(t0, v2);
13839            gen_helper_dextr_w(cpu_gpr[ret], t0, v1_t, cpu_env);
13840            break;
13841        case OPC_DEXTRV_R_W:
13842            tcg_gen_movi_tl(t0, v2);
13843            gen_helper_dextr_r_w(cpu_gpr[ret], t0, v1_t, cpu_env);
13844            break;
13845        case OPC_DEXTRV_RS_W:
13846            tcg_gen_movi_tl(t0, v2);
13847            gen_helper_dextr_rs_w(cpu_gpr[ret], t0, v1_t, cpu_env);
13848            break;
13849        }
13850        break;
13851#endif
13852    }
13853
13854    tcg_temp_free(t0);
13855    tcg_temp_free(t1);
13856    tcg_temp_free(v1_t);
13857}
13858
13859/* End MIPSDSP functions. */
13860
13861static void decode_opc_special_r6(CPUMIPSState *env, DisasContext *ctx)
13862{
13863    int rs, rt, rd, sa;
13864    uint32_t op1, op2;
13865
13866    rs = (ctx->opcode >> 21) & 0x1f;
13867    rt = (ctx->opcode >> 16) & 0x1f;
13868    rd = (ctx->opcode >> 11) & 0x1f;
13869    sa = (ctx->opcode >> 6) & 0x1f;
13870
13871    op1 = MASK_SPECIAL(ctx->opcode);
13872    switch (op1) {
13873    case OPC_MULT:
13874    case OPC_MULTU:
13875    case OPC_DIV:
13876    case OPC_DIVU:
13877        op2 = MASK_R6_MULDIV(ctx->opcode);
13878        switch (op2) {
13879        case R6_OPC_MUL:
13880        case R6_OPC_MUH:
13881        case R6_OPC_MULU:
13882        case R6_OPC_MUHU:
13883        case R6_OPC_DIV:
13884        case R6_OPC_MOD:
13885        case R6_OPC_DIVU:
13886        case R6_OPC_MODU:
13887            gen_r6_muldiv(ctx, op2, rd, rs, rt);
13888            break;
13889        default:
13890            MIPS_INVAL("special_r6 muldiv");
13891            gen_reserved_instruction(ctx);
13892            break;
13893        }
13894        break;
13895    case OPC_SELEQZ:
13896    case OPC_SELNEZ:
13897        gen_cond_move(ctx, op1, rd, rs, rt);
13898        break;
13899    case R6_OPC_CLO:
13900    case R6_OPC_CLZ:
13901        if (rt == 0 && sa == 1) {
13902            /*
13903             * Major opcode and function field is shared with preR6 MFHI/MTHI.
13904             * We need additionally to check other fields.
13905             */
13906            gen_cl(ctx, op1, rd, rs);
13907        } else {
13908            gen_reserved_instruction(ctx);
13909        }
13910        break;
13911    case R6_OPC_SDBBP:
13912        if (is_uhi(extract32(ctx->opcode, 6, 20))) {
13913            gen_helper_do_semihosting(cpu_env);
13914        } else {
13915            if (ctx->hflags & MIPS_HFLAG_SBRI) {
13916                gen_reserved_instruction(ctx);
13917            } else {
13918                generate_exception_end(ctx, EXCP_DBp);
13919            }
13920        }
13921        break;
13922#if defined(TARGET_MIPS64)
13923    case R6_OPC_DCLO:
13924    case R6_OPC_DCLZ:
13925        if (rt == 0 && sa == 1) {
13926            /*
13927             * Major opcode and function field is shared with preR6 MFHI/MTHI.
13928             * We need additionally to check other fields.
13929             */
13930            check_mips_64(ctx);
13931            gen_cl(ctx, op1, rd, rs);
13932        } else {
13933            gen_reserved_instruction(ctx);
13934        }
13935        break;
13936    case OPC_DMULT:
13937    case OPC_DMULTU:
13938    case OPC_DDIV:
13939    case OPC_DDIVU:
13940
13941        op2 = MASK_R6_MULDIV(ctx->opcode);
13942        switch (op2) {
13943        case R6_OPC_DMUL:
13944        case R6_OPC_DMUH:
13945        case R6_OPC_DMULU:
13946        case R6_OPC_DMUHU:
13947        case R6_OPC_DDIV:
13948        case R6_OPC_DMOD:
13949        case R6_OPC_DDIVU:
13950        case R6_OPC_DMODU:
13951            check_mips_64(ctx);
13952            gen_r6_muldiv(ctx, op2, rd, rs, rt);
13953            break;
13954        default:
13955            MIPS_INVAL("special_r6 muldiv");
13956            gen_reserved_instruction(ctx);
13957            break;
13958        }
13959        break;
13960#endif
13961    default:            /* Invalid */
13962        MIPS_INVAL("special_r6");
13963        gen_reserved_instruction(ctx);
13964        break;
13965    }
13966}
13967
13968static void decode_opc_special_tx79(CPUMIPSState *env, DisasContext *ctx)
13969{
13970    int rs = extract32(ctx->opcode, 21, 5);
13971    int rt = extract32(ctx->opcode, 16, 5);
13972    int rd = extract32(ctx->opcode, 11, 5);
13973    uint32_t op1 = MASK_SPECIAL(ctx->opcode);
13974
13975    switch (op1) {
13976    case OPC_MOVN:         /* Conditional move */
13977    case OPC_MOVZ:
13978        gen_cond_move(ctx, op1, rd, rs, rt);
13979        break;
13980    case OPC_MFHI:          /* Move from HI/LO */
13981    case OPC_MFLO:
13982        gen_HILO(ctx, op1, 0, rd);
13983        break;
13984    case OPC_MTHI:
13985    case OPC_MTLO:          /* Move to HI/LO */
13986        gen_HILO(ctx, op1, 0, rs);
13987        break;
13988    case OPC_MULT:
13989    case OPC_MULTU:
13990        gen_mul_txx9(ctx, op1, rd, rs, rt);
13991        break;
13992    case OPC_DIV:
13993    case OPC_DIVU:
13994        gen_muldiv(ctx, op1, 0, rs, rt);
13995        break;
13996#if defined(TARGET_MIPS64)
13997    case OPC_DMULT:
13998    case OPC_DMULTU:
13999    case OPC_DDIV:
14000    case OPC_DDIVU:
14001        check_insn_opc_user_only(ctx, INSN_R5900);
14002        gen_muldiv(ctx, op1, 0, rs, rt);
14003        break;
14004#endif
14005    case OPC_JR:
14006        gen_compute_branch(ctx, op1, 4, rs, 0, 0, 4);
14007        break;
14008    default:            /* Invalid */
14009        MIPS_INVAL("special_tx79");
14010        gen_reserved_instruction(ctx);
14011        break;
14012    }
14013}
14014
14015static void decode_opc_special_legacy(CPUMIPSState *env, DisasContext *ctx)
14016{
14017    int rs, rt, rd;
14018    uint32_t op1;
14019
14020    rs = (ctx->opcode >> 21) & 0x1f;
14021    rt = (ctx->opcode >> 16) & 0x1f;
14022    rd = (ctx->opcode >> 11) & 0x1f;
14023
14024    op1 = MASK_SPECIAL(ctx->opcode);
14025    switch (op1) {
14026    case OPC_MOVN:         /* Conditional move */
14027    case OPC_MOVZ:
14028        check_insn(ctx, ISA_MIPS4 | ISA_MIPS_R1 |
14029                   INSN_LOONGSON2E | INSN_LOONGSON2F);
14030        gen_cond_move(ctx, op1, rd, rs, rt);
14031        break;
14032    case OPC_MFHI:          /* Move from HI/LO */
14033    case OPC_MFLO:
14034        gen_HILO(ctx, op1, rs & 3, rd);
14035        break;
14036    case OPC_MTHI:
14037    case OPC_MTLO:          /* Move to HI/LO */
14038        gen_HILO(ctx, op1, rd & 3, rs);
14039        break;
14040    case OPC_MOVCI:
14041        check_insn(ctx, ISA_MIPS4 | ISA_MIPS_R1);
14042        if (env->CP0_Config1 & (1 << CP0C1_FP)) {
14043            check_cp1_enabled(ctx);
14044            gen_movci(ctx, rd, rs, (ctx->opcode >> 18) & 0x7,
14045                      (ctx->opcode >> 16) & 1);
14046        } else {
14047            generate_exception_err(ctx, EXCP_CpU, 1);
14048        }
14049        break;
14050    case OPC_MULT:
14051    case OPC_MULTU:
14052        gen_muldiv(ctx, op1, rd & 3, rs, rt);
14053        break;
14054    case OPC_DIV:
14055    case OPC_DIVU:
14056        gen_muldiv(ctx, op1, 0, rs, rt);
14057        break;
14058#if defined(TARGET_MIPS64)
14059    case OPC_DMULT:
14060    case OPC_DMULTU:
14061    case OPC_DDIV:
14062    case OPC_DDIVU:
14063        check_insn(ctx, ISA_MIPS3);
14064        check_mips_64(ctx);
14065        gen_muldiv(ctx, op1, 0, rs, rt);
14066        break;
14067#endif
14068    case OPC_JR:
14069        gen_compute_branch(ctx, op1, 4, rs, 0, 0, 4);
14070        break;
14071    case OPC_SPIM:
14072#ifdef MIPS_STRICT_STANDARD
14073        MIPS_INVAL("SPIM");
14074        gen_reserved_instruction(ctx);
14075#else
14076        /* Implemented as RI exception for now. */
14077        MIPS_INVAL("spim (unofficial)");
14078        gen_reserved_instruction(ctx);
14079#endif
14080        break;
14081    default:            /* Invalid */
14082        MIPS_INVAL("special_legacy");
14083        gen_reserved_instruction(ctx);
14084        break;
14085    }
14086}
14087
14088static void decode_opc_special(CPUMIPSState *env, DisasContext *ctx)
14089{
14090    int rs, rt, rd, sa;
14091    uint32_t op1;
14092
14093    rs = (ctx->opcode >> 21) & 0x1f;
14094    rt = (ctx->opcode >> 16) & 0x1f;
14095    rd = (ctx->opcode >> 11) & 0x1f;
14096    sa = (ctx->opcode >> 6) & 0x1f;
14097
14098    op1 = MASK_SPECIAL(ctx->opcode);
14099    switch (op1) {
14100    case OPC_SLL:          /* Shift with immediate */
14101        if (sa == 5 && rd == 0 &&
14102            rs == 0 && rt == 0) { /* PAUSE */
14103            if ((ctx->insn_flags & ISA_MIPS_R6) &&
14104                (ctx->hflags & MIPS_HFLAG_BMASK)) {
14105                gen_reserved_instruction(ctx);
14106                break;
14107            }
14108        }
14109        /* Fallthrough */
14110    case OPC_SRA:
14111        gen_shift_imm(ctx, op1, rd, rt, sa);
14112        break;
14113    case OPC_SRL:
14114        switch ((ctx->opcode >> 21) & 0x1f) {
14115        case 1:
14116            /* rotr is decoded as srl on non-R2 CPUs */
14117            if (ctx->insn_flags & ISA_MIPS_R2) {
14118                op1 = OPC_ROTR;
14119            }
14120            /* Fallthrough */
14121        case 0:
14122            gen_shift_imm(ctx, op1, rd, rt, sa);
14123            break;
14124        default:
14125            gen_reserved_instruction(ctx);
14126            break;
14127        }
14128        break;
14129    case OPC_ADD:
14130    case OPC_ADDU:
14131    case OPC_SUB:
14132    case OPC_SUBU:
14133        gen_arith(ctx, op1, rd, rs, rt);
14134        break;
14135    case OPC_SLLV:         /* Shifts */
14136    case OPC_SRAV:
14137        gen_shift(ctx, op1, rd, rs, rt);
14138        break;
14139    case OPC_SRLV:
14140        switch ((ctx->opcode >> 6) & 0x1f) {
14141        case 1:
14142            /* rotrv is decoded as srlv on non-R2 CPUs */
14143            if (ctx->insn_flags & ISA_MIPS_R2) {
14144                op1 = OPC_ROTRV;
14145            }
14146            /* Fallthrough */
14147        case 0:
14148            gen_shift(ctx, op1, rd, rs, rt);
14149            break;
14150        default:
14151            gen_reserved_instruction(ctx);
14152            break;
14153        }
14154        break;
14155    case OPC_SLT:          /* Set on less than */
14156    case OPC_SLTU:
14157        gen_slt(ctx, op1, rd, rs, rt);
14158        break;
14159    case OPC_AND:          /* Logic*/
14160    case OPC_OR:
14161    case OPC_NOR:
14162    case OPC_XOR:
14163        gen_logic(ctx, op1, rd, rs, rt);
14164        break;
14165    case OPC_JALR:
14166        gen_compute_branch(ctx, op1, 4, rs, rd, sa, 4);
14167        break;
14168    case OPC_TGE: /* Traps */
14169    case OPC_TGEU:
14170    case OPC_TLT:
14171    case OPC_TLTU:
14172    case OPC_TEQ:
14173    case OPC_TNE:
14174        check_insn(ctx, ISA_MIPS2);
14175        gen_trap(ctx, op1, rs, rt, -1, extract32(ctx->opcode, 6, 10));
14176        break;
14177    case OPC_PMON:
14178        /* Pmon entry point, also R4010 selsl */
14179#ifdef MIPS_STRICT_STANDARD
14180        MIPS_INVAL("PMON / selsl");
14181        gen_reserved_instruction(ctx);
14182#else
14183        gen_helper_pmon(cpu_env, tcg_constant_i32(sa));
14184#endif
14185        break;
14186    case OPC_SYSCALL:
14187        generate_exception_end(ctx, EXCP_SYSCALL);
14188        break;
14189    case OPC_BREAK:
14190        generate_exception_break(ctx, extract32(ctx->opcode, 6, 20));
14191        break;
14192    case OPC_SYNC:
14193        check_insn(ctx, ISA_MIPS2);
14194        gen_sync(extract32(ctx->opcode, 6, 5));
14195        break;
14196
14197#if defined(TARGET_MIPS64)
14198        /* MIPS64 specific opcodes */
14199    case OPC_DSLL:
14200    case OPC_DSRA:
14201    case OPC_DSLL32:
14202    case OPC_DSRA32:
14203        check_insn(ctx, ISA_MIPS3);
14204        check_mips_64(ctx);
14205        gen_shift_imm(ctx, op1, rd, rt, sa);
14206        break;
14207    case OPC_DSRL:
14208        switch ((ctx->opcode >> 21) & 0x1f) {
14209        case 1:
14210            /* drotr is decoded as dsrl on non-R2 CPUs */
14211            if (ctx->insn_flags & ISA_MIPS_R2) {
14212                op1 = OPC_DROTR;
14213            }
14214            /* Fallthrough */
14215        case 0:
14216            check_insn(ctx, ISA_MIPS3);
14217            check_mips_64(ctx);
14218            gen_shift_imm(ctx, op1, rd, rt, sa);
14219            break;
14220        default:
14221            gen_reserved_instruction(ctx);
14222            break;
14223        }
14224        break;
14225    case OPC_DSRL32:
14226        switch ((ctx->opcode >> 21) & 0x1f) {
14227        case 1:
14228            /* drotr32 is decoded as dsrl32 on non-R2 CPUs */
14229            if (ctx->insn_flags & ISA_MIPS_R2) {
14230                op1 = OPC_DROTR32;
14231            }
14232            /* Fallthrough */
14233        case 0:
14234            check_insn(ctx, ISA_MIPS3);
14235            check_mips_64(ctx);
14236            gen_shift_imm(ctx, op1, rd, rt, sa);
14237            break;
14238        default:
14239            gen_reserved_instruction(ctx);
14240            break;
14241        }
14242        break;
14243    case OPC_DADD:
14244    case OPC_DADDU:
14245    case OPC_DSUB:
14246    case OPC_DSUBU:
14247        check_insn(ctx, ISA_MIPS3);
14248        check_mips_64(ctx);
14249        gen_arith(ctx, op1, rd, rs, rt);
14250        break;
14251    case OPC_DSLLV:
14252    case OPC_DSRAV:
14253        check_insn(ctx, ISA_MIPS3);
14254        check_mips_64(ctx);
14255        gen_shift(ctx, op1, rd, rs, rt);
14256        break;
14257    case OPC_DSRLV:
14258        switch ((ctx->opcode >> 6) & 0x1f) {
14259        case 1:
14260            /* drotrv is decoded as dsrlv on non-R2 CPUs */
14261            if (ctx->insn_flags & ISA_MIPS_R2) {
14262                op1 = OPC_DROTRV;
14263            }
14264            /* Fallthrough */
14265        case 0:
14266            check_insn(ctx, ISA_MIPS3);
14267            check_mips_64(ctx);
14268            gen_shift(ctx, op1, rd, rs, rt);
14269            break;
14270        default:
14271            gen_reserved_instruction(ctx);
14272            break;
14273        }
14274        break;
14275#endif
14276    default:
14277        if (ctx->insn_flags & ISA_MIPS_R6) {
14278            decode_opc_special_r6(env, ctx);
14279        } else if (ctx->insn_flags & INSN_R5900) {
14280            decode_opc_special_tx79(env, ctx);
14281        } else {
14282            decode_opc_special_legacy(env, ctx);
14283        }
14284    }
14285}
14286
14287
14288static void decode_opc_special2_legacy(CPUMIPSState *env, DisasContext *ctx)
14289{
14290    int rs, rt, rd;
14291    uint32_t op1;
14292
14293    rs = (ctx->opcode >> 21) & 0x1f;
14294    rt = (ctx->opcode >> 16) & 0x1f;
14295    rd = (ctx->opcode >> 11) & 0x1f;
14296
14297    op1 = MASK_SPECIAL2(ctx->opcode);
14298    switch (op1) {
14299    case OPC_MADD: /* Multiply and add/sub */
14300    case OPC_MADDU:
14301    case OPC_MSUB:
14302    case OPC_MSUBU:
14303        check_insn(ctx, ISA_MIPS_R1);
14304        gen_muldiv(ctx, op1, rd & 3, rs, rt);
14305        break;
14306    case OPC_MUL:
14307        gen_arith(ctx, op1, rd, rs, rt);
14308        break;
14309    case OPC_DIV_G_2F:
14310    case OPC_DIVU_G_2F:
14311    case OPC_MULT_G_2F:
14312    case OPC_MULTU_G_2F:
14313    case OPC_MOD_G_2F:
14314    case OPC_MODU_G_2F:
14315        check_insn(ctx, INSN_LOONGSON2F | ASE_LEXT);
14316        gen_loongson_integer(ctx, op1, rd, rs, rt);
14317        break;
14318    case OPC_CLO:
14319    case OPC_CLZ:
14320        check_insn(ctx, ISA_MIPS_R1);
14321        gen_cl(ctx, op1, rd, rs);
14322        break;
14323    case OPC_SDBBP:
14324        if (is_uhi(extract32(ctx->opcode, 6, 20))) {
14325            gen_helper_do_semihosting(cpu_env);
14326        } else {
14327            /*
14328             * XXX: not clear which exception should be raised
14329             *      when in debug mode...
14330             */
14331            check_insn(ctx, ISA_MIPS_R1);
14332            generate_exception_end(ctx, EXCP_DBp);
14333        }
14334        break;
14335#if defined(TARGET_MIPS64)
14336    case OPC_DCLO:
14337    case OPC_DCLZ:
14338        check_insn(ctx, ISA_MIPS_R1);
14339        check_mips_64(ctx);
14340        gen_cl(ctx, op1, rd, rs);
14341        break;
14342    case OPC_DMULT_G_2F:
14343    case OPC_DMULTU_G_2F:
14344    case OPC_DDIV_G_2F:
14345    case OPC_DDIVU_G_2F:
14346    case OPC_DMOD_G_2F:
14347    case OPC_DMODU_G_2F:
14348        check_insn(ctx, INSN_LOONGSON2F | ASE_LEXT);
14349        gen_loongson_integer(ctx, op1, rd, rs, rt);
14350        break;
14351#endif
14352    default:            /* Invalid */
14353        MIPS_INVAL("special2_legacy");
14354        gen_reserved_instruction(ctx);
14355        break;
14356    }
14357}
14358
14359static void decode_opc_special3_r6(CPUMIPSState *env, DisasContext *ctx)
14360{
14361    int rs, rt, rd, sa;
14362    uint32_t op1, op2;
14363    int16_t imm;
14364
14365    rs = (ctx->opcode >> 21) & 0x1f;
14366    rt = (ctx->opcode >> 16) & 0x1f;
14367    rd = (ctx->opcode >> 11) & 0x1f;
14368    sa = (ctx->opcode >> 6) & 0x1f;
14369    imm = (int16_t)ctx->opcode >> 7;
14370
14371    op1 = MASK_SPECIAL3(ctx->opcode);
14372    switch (op1) {
14373    case R6_OPC_PREF:
14374        if (rt >= 24) {
14375            /* hint codes 24-31 are reserved and signal RI */
14376            gen_reserved_instruction(ctx);
14377        }
14378        /* Treat as NOP. */
14379        break;
14380    case R6_OPC_CACHE:
14381        check_cp0_enabled(ctx);
14382        if (ctx->hflags & MIPS_HFLAG_ITC_CACHE) {
14383            gen_cache_operation(ctx, rt, rs, imm);
14384        }
14385        break;
14386    case R6_OPC_SC:
14387        gen_st_cond(ctx, rt, rs, imm, MO_TESL, false);
14388        break;
14389    case R6_OPC_LL:
14390        gen_ld(ctx, op1, rt, rs, imm);
14391        break;
14392    case OPC_BSHFL:
14393        {
14394            if (rd == 0) {
14395                /* Treat as NOP. */
14396                break;
14397            }
14398            op2 = MASK_BSHFL(ctx->opcode);
14399            switch (op2) {
14400            case OPC_ALIGN:
14401            case OPC_ALIGN_1:
14402            case OPC_ALIGN_2:
14403            case OPC_ALIGN_3:
14404                gen_align(ctx, 32, rd, rs, rt, sa & 3);
14405                break;
14406            case OPC_BITSWAP:
14407                gen_bitswap(ctx, op2, rd, rt);
14408                break;
14409            }
14410        }
14411        break;
14412#ifndef CONFIG_USER_ONLY
14413    case OPC_GINV:
14414        if (unlikely(ctx->gi <= 1)) {
14415            gen_reserved_instruction(ctx);
14416        }
14417        check_cp0_enabled(ctx);
14418        switch ((ctx->opcode >> 6) & 3) {
14419        case 0:    /* GINVI */
14420            /* Treat as NOP. */
14421            break;
14422        case 2:    /* GINVT */
14423            gen_helper_0e1i(ginvt, cpu_gpr[rs], extract32(ctx->opcode, 8, 2));
14424            break;
14425        default:
14426            gen_reserved_instruction(ctx);
14427            break;
14428        }
14429        break;
14430#endif
14431#if defined(TARGET_MIPS64)
14432    case R6_OPC_SCD:
14433        gen_st_cond(ctx, rt, rs, imm, MO_TEUQ, false);
14434        break;
14435    case R6_OPC_LLD:
14436        gen_ld(ctx, op1, rt, rs, imm);
14437        break;
14438    case OPC_DBSHFL:
14439        check_mips_64(ctx);
14440        {
14441            if (rd == 0) {
14442                /* Treat as NOP. */
14443                break;
14444            }
14445            op2 = MASK_DBSHFL(ctx->opcode);
14446            switch (op2) {
14447            case OPC_DALIGN:
14448            case OPC_DALIGN_1:
14449            case OPC_DALIGN_2:
14450            case OPC_DALIGN_3:
14451            case OPC_DALIGN_4:
14452            case OPC_DALIGN_5:
14453            case OPC_DALIGN_6:
14454            case OPC_DALIGN_7:
14455                gen_align(ctx, 64, rd, rs, rt, sa & 7);
14456                break;
14457            case OPC_DBITSWAP:
14458                gen_bitswap(ctx, op2, rd, rt);
14459                break;
14460            }
14461
14462        }
14463        break;
14464#endif
14465    default:            /* Invalid */
14466        MIPS_INVAL("special3_r6");
14467        gen_reserved_instruction(ctx);
14468        break;
14469    }
14470}
14471
14472static void decode_opc_special3_legacy(CPUMIPSState *env, DisasContext *ctx)
14473{
14474    int rs, rt, rd;
14475    uint32_t op1, op2;
14476
14477    rs = (ctx->opcode >> 21) & 0x1f;
14478    rt = (ctx->opcode >> 16) & 0x1f;
14479    rd = (ctx->opcode >> 11) & 0x1f;
14480
14481    op1 = MASK_SPECIAL3(ctx->opcode);
14482    switch (op1) {
14483    case OPC_DIV_G_2E:
14484    case OPC_DIVU_G_2E:
14485    case OPC_MOD_G_2E:
14486    case OPC_MODU_G_2E:
14487    case OPC_MULT_G_2E:
14488    case OPC_MULTU_G_2E:
14489        /*
14490         * OPC_MULT_G_2E, OPC_ADDUH_QB_DSP, OPC_MUL_PH_DSP have
14491         * the same mask and op1.
14492         */
14493        if ((ctx->insn_flags & ASE_DSP_R2) && (op1 == OPC_MULT_G_2E)) {
14494            op2 = MASK_ADDUH_QB(ctx->opcode);
14495            switch (op2) {
14496            case OPC_ADDUH_QB:
14497            case OPC_ADDUH_R_QB:
14498            case OPC_ADDQH_PH:
14499            case OPC_ADDQH_R_PH:
14500            case OPC_ADDQH_W:
14501            case OPC_ADDQH_R_W:
14502            case OPC_SUBUH_QB:
14503            case OPC_SUBUH_R_QB:
14504            case OPC_SUBQH_PH:
14505            case OPC_SUBQH_R_PH:
14506            case OPC_SUBQH_W:
14507            case OPC_SUBQH_R_W:
14508                gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
14509                break;
14510            case OPC_MUL_PH:
14511            case OPC_MUL_S_PH:
14512            case OPC_MULQ_S_W:
14513            case OPC_MULQ_RS_W:
14514                gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 1);
14515                break;
14516            default:
14517                MIPS_INVAL("MASK ADDUH.QB");
14518                gen_reserved_instruction(ctx);
14519                break;
14520            }
14521        } else if (ctx->insn_flags & INSN_LOONGSON2E) {
14522            gen_loongson_integer(ctx, op1, rd, rs, rt);
14523        } else {
14524            gen_reserved_instruction(ctx);
14525        }
14526        break;
14527    case OPC_LX_DSP:
14528        op2 = MASK_LX(ctx->opcode);
14529        switch (op2) {
14530#if defined(TARGET_MIPS64)
14531        case OPC_LDX:
14532#endif
14533        case OPC_LBUX:
14534        case OPC_LHX:
14535        case OPC_LWX:
14536            gen_mipsdsp_ld(ctx, op2, rd, rs, rt);
14537            break;
14538        default:            /* Invalid */
14539            MIPS_INVAL("MASK LX");
14540            gen_reserved_instruction(ctx);
14541            break;
14542        }
14543        break;
14544    case OPC_ABSQ_S_PH_DSP:
14545        op2 = MASK_ABSQ_S_PH(ctx->opcode);
14546        switch (op2) {
14547        case OPC_ABSQ_S_QB:
14548        case OPC_ABSQ_S_PH:
14549        case OPC_ABSQ_S_W:
14550        case OPC_PRECEQ_W_PHL:
14551        case OPC_PRECEQ_W_PHR:
14552        case OPC_PRECEQU_PH_QBL:
14553        case OPC_PRECEQU_PH_QBR:
14554        case OPC_PRECEQU_PH_QBLA:
14555        case OPC_PRECEQU_PH_QBRA:
14556        case OPC_PRECEU_PH_QBL:
14557        case OPC_PRECEU_PH_QBR:
14558        case OPC_PRECEU_PH_QBLA:
14559        case OPC_PRECEU_PH_QBRA:
14560            gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
14561            break;
14562        case OPC_BITREV:
14563        case OPC_REPL_QB:
14564        case OPC_REPLV_QB:
14565        case OPC_REPL_PH:
14566        case OPC_REPLV_PH:
14567            gen_mipsdsp_bitinsn(ctx, op1, op2, rd, rt);
14568            break;
14569        default:
14570            MIPS_INVAL("MASK ABSQ_S.PH");
14571            gen_reserved_instruction(ctx);
14572            break;
14573        }
14574        break;
14575    case OPC_ADDU_QB_DSP:
14576        op2 = MASK_ADDU_QB(ctx->opcode);
14577        switch (op2) {
14578        case OPC_ADDQ_PH:
14579        case OPC_ADDQ_S_PH:
14580        case OPC_ADDQ_S_W:
14581        case OPC_ADDU_QB:
14582        case OPC_ADDU_S_QB:
14583        case OPC_ADDU_PH:
14584        case OPC_ADDU_S_PH:
14585        case OPC_SUBQ_PH:
14586        case OPC_SUBQ_S_PH:
14587        case OPC_SUBQ_S_W:
14588        case OPC_SUBU_QB:
14589        case OPC_SUBU_S_QB:
14590        case OPC_SUBU_PH:
14591        case OPC_SUBU_S_PH:
14592        case OPC_ADDSC:
14593        case OPC_ADDWC:
14594        case OPC_MODSUB:
14595        case OPC_RADDU_W_QB:
14596            gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
14597            break;
14598        case OPC_MULEU_S_PH_QBL:
14599        case OPC_MULEU_S_PH_QBR:
14600        case OPC_MULQ_RS_PH:
14601        case OPC_MULEQ_S_W_PHL:
14602        case OPC_MULEQ_S_W_PHR:
14603        case OPC_MULQ_S_PH:
14604            gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 1);
14605            break;
14606        default:            /* Invalid */
14607            MIPS_INVAL("MASK ADDU.QB");
14608            gen_reserved_instruction(ctx);
14609            break;
14610
14611        }
14612        break;
14613    case OPC_CMPU_EQ_QB_DSP:
14614        op2 = MASK_CMPU_EQ_QB(ctx->opcode);
14615        switch (op2) {
14616        case OPC_PRECR_SRA_PH_W:
14617        case OPC_PRECR_SRA_R_PH_W:
14618            gen_mipsdsp_arith(ctx, op1, op2, rt, rs, rd);
14619            break;
14620        case OPC_PRECR_QB_PH:
14621        case OPC_PRECRQ_QB_PH:
14622        case OPC_PRECRQ_PH_W:
14623        case OPC_PRECRQ_RS_PH_W:
14624        case OPC_PRECRQU_S_QB_PH:
14625            gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
14626            break;
14627        case OPC_CMPU_EQ_QB:
14628        case OPC_CMPU_LT_QB:
14629        case OPC_CMPU_LE_QB:
14630        case OPC_CMP_EQ_PH:
14631        case OPC_CMP_LT_PH:
14632        case OPC_CMP_LE_PH:
14633            gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 0);
14634            break;
14635        case OPC_CMPGU_EQ_QB:
14636        case OPC_CMPGU_LT_QB:
14637        case OPC_CMPGU_LE_QB:
14638        case OPC_CMPGDU_EQ_QB:
14639        case OPC_CMPGDU_LT_QB:
14640        case OPC_CMPGDU_LE_QB:
14641        case OPC_PICK_QB:
14642        case OPC_PICK_PH:
14643        case OPC_PACKRL_PH:
14644            gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 1);
14645            break;
14646        default:            /* Invalid */
14647            MIPS_INVAL("MASK CMPU.EQ.QB");
14648            gen_reserved_instruction(ctx);
14649            break;
14650        }
14651        break;
14652    case OPC_SHLL_QB_DSP:
14653        gen_mipsdsp_shift(ctx, op1, rd, rs, rt);
14654        break;
14655    case OPC_DPA_W_PH_DSP:
14656        op2 = MASK_DPA_W_PH(ctx->opcode);
14657        switch (op2) {
14658        case OPC_DPAU_H_QBL:
14659        case OPC_DPAU_H_QBR:
14660        case OPC_DPSU_H_QBL:
14661        case OPC_DPSU_H_QBR:
14662        case OPC_DPA_W_PH:
14663        case OPC_DPAX_W_PH:
14664        case OPC_DPAQ_S_W_PH:
14665        case OPC_DPAQX_S_W_PH:
14666        case OPC_DPAQX_SA_W_PH:
14667        case OPC_DPS_W_PH:
14668        case OPC_DPSX_W_PH:
14669        case OPC_DPSQ_S_W_PH:
14670        case OPC_DPSQX_S_W_PH:
14671        case OPC_DPSQX_SA_W_PH:
14672        case OPC_MULSAQ_S_W_PH:
14673        case OPC_DPAQ_SA_L_W:
14674        case OPC_DPSQ_SA_L_W:
14675        case OPC_MAQ_S_W_PHL:
14676        case OPC_MAQ_S_W_PHR:
14677        case OPC_MAQ_SA_W_PHL:
14678        case OPC_MAQ_SA_W_PHR:
14679        case OPC_MULSA_W_PH:
14680            gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 0);
14681            break;
14682        default:            /* Invalid */
14683            MIPS_INVAL("MASK DPAW.PH");
14684            gen_reserved_instruction(ctx);
14685            break;
14686        }
14687        break;
14688    case OPC_INSV_DSP:
14689        op2 = MASK_INSV(ctx->opcode);
14690        switch (op2) {
14691        case OPC_INSV:
14692            check_dsp(ctx);
14693            {
14694                TCGv t0, t1;
14695
14696                if (rt == 0) {
14697                    break;
14698                }
14699
14700                t0 = tcg_temp_new();
14701                t1 = tcg_temp_new();
14702
14703                gen_load_gpr(t0, rt);
14704                gen_load_gpr(t1, rs);
14705
14706                gen_helper_insv(cpu_gpr[rt], cpu_env, t1, t0);
14707
14708                tcg_temp_free(t0);
14709                tcg_temp_free(t1);
14710                break;
14711            }
14712        default:            /* Invalid */
14713            MIPS_INVAL("MASK INSV");
14714            gen_reserved_instruction(ctx);
14715            break;
14716        }
14717        break;
14718    case OPC_APPEND_DSP:
14719        gen_mipsdsp_append(env, ctx, op1, rt, rs, rd);
14720        break;
14721    case OPC_EXTR_W_DSP:
14722        op2 = MASK_EXTR_W(ctx->opcode);
14723        switch (op2) {
14724        case OPC_EXTR_W:
14725        case OPC_EXTR_R_W:
14726        case OPC_EXTR_RS_W:
14727        case OPC_EXTR_S_H:
14728        case OPC_EXTRV_S_H:
14729        case OPC_EXTRV_W:
14730        case OPC_EXTRV_R_W:
14731        case OPC_EXTRV_RS_W:
14732        case OPC_EXTP:
14733        case OPC_EXTPV:
14734        case OPC_EXTPDP:
14735        case OPC_EXTPDPV:
14736            gen_mipsdsp_accinsn(ctx, op1, op2, rt, rs, rd, 1);
14737            break;
14738        case OPC_RDDSP:
14739            gen_mipsdsp_accinsn(ctx, op1, op2, rd, rs, rt, 1);
14740            break;
14741        case OPC_SHILO:
14742        case OPC_SHILOV:
14743        case OPC_MTHLIP:
14744        case OPC_WRDSP:
14745            gen_mipsdsp_accinsn(ctx, op1, op2, rd, rs, rt, 0);
14746            break;
14747        default:            /* Invalid */
14748            MIPS_INVAL("MASK EXTR.W");
14749            gen_reserved_instruction(ctx);
14750            break;
14751        }
14752        break;
14753#if defined(TARGET_MIPS64)
14754    case OPC_DDIV_G_2E:
14755    case OPC_DDIVU_G_2E:
14756    case OPC_DMULT_G_2E:
14757    case OPC_DMULTU_G_2E:
14758    case OPC_DMOD_G_2E:
14759    case OPC_DMODU_G_2E:
14760        check_insn(ctx, INSN_LOONGSON2E);
14761        gen_loongson_integer(ctx, op1, rd, rs, rt);
14762        break;
14763    case OPC_ABSQ_S_QH_DSP:
14764        op2 = MASK_ABSQ_S_QH(ctx->opcode);
14765        switch (op2) {
14766        case OPC_PRECEQ_L_PWL:
14767        case OPC_PRECEQ_L_PWR:
14768        case OPC_PRECEQ_PW_QHL:
14769        case OPC_PRECEQ_PW_QHR:
14770        case OPC_PRECEQ_PW_QHLA:
14771        case OPC_PRECEQ_PW_QHRA:
14772        case OPC_PRECEQU_QH_OBL:
14773        case OPC_PRECEQU_QH_OBR:
14774        case OPC_PRECEQU_QH_OBLA:
14775        case OPC_PRECEQU_QH_OBRA:
14776        case OPC_PRECEU_QH_OBL:
14777        case OPC_PRECEU_QH_OBR:
14778        case OPC_PRECEU_QH_OBLA:
14779        case OPC_PRECEU_QH_OBRA:
14780        case OPC_ABSQ_S_OB:
14781        case OPC_ABSQ_S_PW:
14782        case OPC_ABSQ_S_QH:
14783            gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
14784            break;
14785        case OPC_REPL_OB:
14786        case OPC_REPL_PW:
14787        case OPC_REPL_QH:
14788        case OPC_REPLV_OB:
14789        case OPC_REPLV_PW:
14790        case OPC_REPLV_QH:
14791            gen_mipsdsp_bitinsn(ctx, op1, op2, rd, rt);
14792            break;
14793        default:            /* Invalid */
14794            MIPS_INVAL("MASK ABSQ_S.QH");
14795            gen_reserved_instruction(ctx);
14796            break;
14797        }
14798        break;
14799    case OPC_ADDU_OB_DSP:
14800        op2 = MASK_ADDU_OB(ctx->opcode);
14801        switch (op2) {
14802        case OPC_RADDU_L_OB:
14803        case OPC_SUBQ_PW:
14804        case OPC_SUBQ_S_PW:
14805        case OPC_SUBQ_QH:
14806        case OPC_SUBQ_S_QH:
14807        case OPC_SUBU_OB:
14808        case OPC_SUBU_S_OB:
14809        case OPC_SUBU_QH:
14810        case OPC_SUBU_S_QH:
14811        case OPC_SUBUH_OB:
14812        case OPC_SUBUH_R_OB:
14813        case OPC_ADDQ_PW:
14814        case OPC_ADDQ_S_PW:
14815        case OPC_ADDQ_QH:
14816        case OPC_ADDQ_S_QH:
14817        case OPC_ADDU_OB:
14818        case OPC_ADDU_S_OB:
14819        case OPC_ADDU_QH:
14820        case OPC_ADDU_S_QH:
14821        case OPC_ADDUH_OB:
14822        case OPC_ADDUH_R_OB:
14823            gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
14824            break;
14825        case OPC_MULEQ_S_PW_QHL:
14826        case OPC_MULEQ_S_PW_QHR:
14827        case OPC_MULEU_S_QH_OBL:
14828        case OPC_MULEU_S_QH_OBR:
14829        case OPC_MULQ_RS_QH:
14830            gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 1);
14831            break;
14832        default:            /* Invalid */
14833            MIPS_INVAL("MASK ADDU.OB");
14834            gen_reserved_instruction(ctx);
14835            break;
14836        }
14837        break;
14838    case OPC_CMPU_EQ_OB_DSP:
14839        op2 = MASK_CMPU_EQ_OB(ctx->opcode);
14840        switch (op2) {
14841        case OPC_PRECR_SRA_QH_PW:
14842        case OPC_PRECR_SRA_R_QH_PW:
14843            /* Return value is rt. */
14844            gen_mipsdsp_arith(ctx, op1, op2, rt, rs, rd);
14845            break;
14846        case OPC_PRECR_OB_QH:
14847        case OPC_PRECRQ_OB_QH:
14848        case OPC_PRECRQ_PW_L:
14849        case OPC_PRECRQ_QH_PW:
14850        case OPC_PRECRQ_RS_QH_PW:
14851        case OPC_PRECRQU_S_OB_QH:
14852            gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
14853            break;
14854        case OPC_CMPU_EQ_OB:
14855        case OPC_CMPU_LT_OB:
14856        case OPC_CMPU_LE_OB:
14857        case OPC_CMP_EQ_QH:
14858        case OPC_CMP_LT_QH:
14859        case OPC_CMP_LE_QH:
14860        case OPC_CMP_EQ_PW:
14861        case OPC_CMP_LT_PW:
14862        case OPC_CMP_LE_PW:
14863            gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 0);
14864            break;
14865        case OPC_CMPGDU_EQ_OB:
14866        case OPC_CMPGDU_LT_OB:
14867        case OPC_CMPGDU_LE_OB:
14868        case OPC_CMPGU_EQ_OB:
14869        case OPC_CMPGU_LT_OB:
14870        case OPC_CMPGU_LE_OB:
14871        case OPC_PACKRL_PW:
14872        case OPC_PICK_OB:
14873        case OPC_PICK_PW:
14874        case OPC_PICK_QH:
14875            gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 1);
14876            break;
14877        default:            /* Invalid */
14878            MIPS_INVAL("MASK CMPU_EQ.OB");
14879            gen_reserved_instruction(ctx);
14880            break;
14881        }
14882        break;
14883    case OPC_DAPPEND_DSP:
14884        gen_mipsdsp_append(env, ctx, op1, rt, rs, rd);
14885        break;
14886    case OPC_DEXTR_W_DSP:
14887        op2 = MASK_DEXTR_W(ctx->opcode);
14888        switch (op2) {
14889        case OPC_DEXTP:
14890        case OPC_DEXTPDP:
14891        case OPC_DEXTPDPV:
14892        case OPC_DEXTPV:
14893        case OPC_DEXTR_L:
14894        case OPC_DEXTR_R_L:
14895        case OPC_DEXTR_RS_L:
14896        case OPC_DEXTR_W:
14897        case OPC_DEXTR_R_W:
14898        case OPC_DEXTR_RS_W:
14899        case OPC_DEXTR_S_H:
14900        case OPC_DEXTRV_L:
14901        case OPC_DEXTRV_R_L:
14902        case OPC_DEXTRV_RS_L:
14903        case OPC_DEXTRV_S_H:
14904        case OPC_DEXTRV_W:
14905        case OPC_DEXTRV_R_W:
14906        case OPC_DEXTRV_RS_W:
14907            gen_mipsdsp_accinsn(ctx, op1, op2, rt, rs, rd, 1);
14908            break;
14909        case OPC_DMTHLIP:
14910        case OPC_DSHILO:
14911        case OPC_DSHILOV:
14912            gen_mipsdsp_accinsn(ctx, op1, op2, rd, rs, rt, 0);
14913            break;
14914        default:            /* Invalid */
14915            MIPS_INVAL("MASK EXTR.W");
14916            gen_reserved_instruction(ctx);
14917            break;
14918        }
14919        break;
14920    case OPC_DPAQ_W_QH_DSP:
14921        op2 = MASK_DPAQ_W_QH(ctx->opcode);
14922        switch (op2) {
14923        case OPC_DPAU_H_OBL:
14924        case OPC_DPAU_H_OBR:
14925        case OPC_DPSU_H_OBL:
14926        case OPC_DPSU_H_OBR:
14927        case OPC_DPA_W_QH:
14928        case OPC_DPAQ_S_W_QH:
14929        case OPC_DPS_W_QH:
14930        case OPC_DPSQ_S_W_QH:
14931        case OPC_MULSAQ_S_W_QH:
14932        case OPC_DPAQ_SA_L_PW:
14933        case OPC_DPSQ_SA_L_PW:
14934        case OPC_MULSAQ_S_L_PW:
14935            gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 0);
14936            break;
14937        case OPC_MAQ_S_W_QHLL:
14938        case OPC_MAQ_S_W_QHLR:
14939        case OPC_MAQ_S_W_QHRL:
14940        case OPC_MAQ_S_W_QHRR:
14941        case OPC_MAQ_SA_W_QHLL:
14942        case OPC_MAQ_SA_W_QHLR:
14943        case OPC_MAQ_SA_W_QHRL:
14944        case OPC_MAQ_SA_W_QHRR:
14945        case OPC_MAQ_S_L_PWL:
14946        case OPC_MAQ_S_L_PWR:
14947        case OPC_DMADD:
14948        case OPC_DMADDU:
14949        case OPC_DMSUB:
14950        case OPC_DMSUBU:
14951            gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 0);
14952            break;
14953        default:            /* Invalid */
14954            MIPS_INVAL("MASK DPAQ.W.QH");
14955            gen_reserved_instruction(ctx);
14956            break;
14957        }
14958        break;
14959    case OPC_DINSV_DSP:
14960        op2 = MASK_INSV(ctx->opcode);
14961        switch (op2) {
14962        case OPC_DINSV:
14963        {
14964            TCGv t0, t1;
14965
14966            check_dsp(ctx);
14967
14968            if (rt == 0) {
14969                break;
14970            }
14971
14972            t0 = tcg_temp_new();
14973            t1 = tcg_temp_new();
14974
14975            gen_load_gpr(t0, rt);
14976            gen_load_gpr(t1, rs);
14977
14978            gen_helper_dinsv(cpu_gpr[rt], cpu_env, t1, t0);
14979
14980            tcg_temp_free(t0);
14981            tcg_temp_free(t1);
14982            break;
14983        }
14984        default:            /* Invalid */
14985            MIPS_INVAL("MASK DINSV");
14986            gen_reserved_instruction(ctx);
14987            break;
14988        }
14989        break;
14990    case OPC_SHLL_OB_DSP:
14991        gen_mipsdsp_shift(ctx, op1, rd, rs, rt);
14992        break;
14993#endif
14994    default:            /* Invalid */
14995        MIPS_INVAL("special3_legacy");
14996        gen_reserved_instruction(ctx);
14997        break;
14998    }
14999}
15000
15001
15002#if defined(TARGET_MIPS64)
15003
15004static void decode_mmi(CPUMIPSState *env, DisasContext *ctx)
15005{
15006    uint32_t opc = MASK_MMI(ctx->opcode);
15007    int rs = extract32(ctx->opcode, 21, 5);
15008    int rt = extract32(ctx->opcode, 16, 5);
15009    int rd = extract32(ctx->opcode, 11, 5);
15010
15011    switch (opc) {
15012    case MMI_OPC_MULT1:
15013    case MMI_OPC_MULTU1:
15014    case MMI_OPC_MADD:
15015    case MMI_OPC_MADDU:
15016    case MMI_OPC_MADD1:
15017    case MMI_OPC_MADDU1:
15018        gen_mul_txx9(ctx, opc, rd, rs, rt);
15019        break;
15020    case MMI_OPC_DIV1:
15021    case MMI_OPC_DIVU1:
15022        gen_div1_tx79(ctx, opc, rs, rt);
15023        break;
15024    default:
15025        MIPS_INVAL("TX79 MMI class");
15026        gen_reserved_instruction(ctx);
15027        break;
15028    }
15029}
15030
15031static void gen_mmi_sq(DisasContext *ctx, int base, int rt, int offset)
15032{
15033    gen_reserved_instruction(ctx);    /* TODO: MMI_OPC_SQ */
15034}
15035
15036/*
15037 * The TX79-specific instruction Store Quadword
15038 *
15039 * +--------+-------+-------+------------------------+
15040 * | 011111 |  base |   rt  |           offset       | SQ
15041 * +--------+-------+-------+------------------------+
15042 *      6       5       5                 16
15043 *
15044 * has the same opcode as the Read Hardware Register instruction
15045 *
15046 * +--------+-------+-------+-------+-------+--------+
15047 * | 011111 | 00000 |   rt  |   rd  | 00000 | 111011 | RDHWR
15048 * +--------+-------+-------+-------+-------+--------+
15049 *      6       5       5       5       5        6
15050 *
15051 * that is required, trapped and emulated by the Linux kernel. However, all
15052 * RDHWR encodings yield address error exceptions on the TX79 since the SQ
15053 * offset is odd. Therefore all valid SQ instructions can execute normally.
15054 * In user mode, QEMU must verify the upper and lower 11 bits to distinguish
15055 * between SQ and RDHWR, as the Linux kernel does.
15056 */
15057static void decode_mmi_sq(CPUMIPSState *env, DisasContext *ctx)
15058{
15059    int base = extract32(ctx->opcode, 21, 5);
15060    int rt = extract32(ctx->opcode, 16, 5);
15061    int offset = extract32(ctx->opcode, 0, 16);
15062
15063#ifdef CONFIG_USER_ONLY
15064    uint32_t op1 = MASK_SPECIAL3(ctx->opcode);
15065    uint32_t op2 = extract32(ctx->opcode, 6, 5);
15066
15067    if (base == 0 && op2 == 0 && op1 == OPC_RDHWR) {
15068        int rd = extract32(ctx->opcode, 11, 5);
15069
15070        gen_rdhwr(ctx, rt, rd, 0);
15071        return;
15072    }
15073#endif
15074
15075    gen_mmi_sq(ctx, base, rt, offset);
15076}
15077
15078#endif
15079
15080static void decode_opc_special3(CPUMIPSState *env, DisasContext *ctx)
15081{
15082    int rs, rt, rd, sa;
15083    uint32_t op1, op2;
15084    int16_t imm;
15085
15086    rs = (ctx->opcode >> 21) & 0x1f;
15087    rt = (ctx->opcode >> 16) & 0x1f;
15088    rd = (ctx->opcode >> 11) & 0x1f;
15089    sa = (ctx->opcode >> 6) & 0x1f;
15090    imm = sextract32(ctx->opcode, 7, 9);
15091
15092    op1 = MASK_SPECIAL3(ctx->opcode);
15093
15094    /*
15095     * EVA loads and stores overlap Loongson 2E instructions decoded by
15096     * decode_opc_special3_legacy(), so be careful to allow their decoding when
15097     * EVA is absent.
15098     */
15099    if (ctx->eva) {
15100        switch (op1) {
15101        case OPC_LWLE:
15102        case OPC_LWRE:
15103        case OPC_LBUE:
15104        case OPC_LHUE:
15105        case OPC_LBE:
15106        case OPC_LHE:
15107        case OPC_LLE:
15108        case OPC_LWE:
15109            check_cp0_enabled(ctx);
15110            gen_ld(ctx, op1, rt, rs, imm);
15111            return;
15112        case OPC_SWLE:
15113        case OPC_SWRE:
15114        case OPC_SBE:
15115        case OPC_SHE:
15116        case OPC_SWE:
15117            check_cp0_enabled(ctx);
15118            gen_st(ctx, op1, rt, rs, imm);
15119            return;
15120        case OPC_SCE:
15121            check_cp0_enabled(ctx);
15122            gen_st_cond(ctx, rt, rs, imm, MO_TESL, true);
15123            return;
15124        case OPC_CACHEE:
15125            check_eva(ctx);
15126            check_cp0_enabled(ctx);
15127            if (ctx->hflags & MIPS_HFLAG_ITC_CACHE) {
15128                gen_cache_operation(ctx, rt, rs, imm);
15129            }
15130            return;
15131        case OPC_PREFE:
15132            check_cp0_enabled(ctx);
15133            /* Treat as NOP. */
15134            return;
15135        }
15136    }
15137
15138    switch (op1) {
15139    case OPC_EXT:
15140    case OPC_INS:
15141        check_insn(ctx, ISA_MIPS_R2);
15142        gen_bitops(ctx, op1, rt, rs, sa, rd);
15143        break;
15144    case OPC_BSHFL:
15145        op2 = MASK_BSHFL(ctx->opcode);
15146        switch (op2) {
15147        case OPC_ALIGN:
15148        case OPC_ALIGN_1:
15149        case OPC_ALIGN_2:
15150        case OPC_ALIGN_3:
15151        case OPC_BITSWAP:
15152            check_insn(ctx, ISA_MIPS_R6);
15153            decode_opc_special3_r6(env, ctx);
15154            break;
15155        default:
15156            check_insn(ctx, ISA_MIPS_R2);
15157            gen_bshfl(ctx, op2, rt, rd);
15158            break;
15159        }
15160        break;
15161#if defined(TARGET_MIPS64)
15162    case OPC_DEXTM:
15163    case OPC_DEXTU:
15164    case OPC_DEXT:
15165    case OPC_DINSM:
15166    case OPC_DINSU:
15167    case OPC_DINS:
15168        check_insn(ctx, ISA_MIPS_R2);
15169        check_mips_64(ctx);
15170        gen_bitops(ctx, op1, rt, rs, sa, rd);
15171        break;
15172    case OPC_DBSHFL:
15173        op2 = MASK_DBSHFL(ctx->opcode);
15174        switch (op2) {
15175        case OPC_DALIGN:
15176        case OPC_DALIGN_1:
15177        case OPC_DALIGN_2:
15178        case OPC_DALIGN_3:
15179        case OPC_DALIGN_4:
15180        case OPC_DALIGN_5:
15181        case OPC_DALIGN_6:
15182        case OPC_DALIGN_7:
15183        case OPC_DBITSWAP:
15184            check_insn(ctx, ISA_MIPS_R6);
15185            decode_opc_special3_r6(env, ctx);
15186            break;
15187        default:
15188            check_insn(ctx, ISA_MIPS_R2);
15189            check_mips_64(ctx);
15190            op2 = MASK_DBSHFL(ctx->opcode);
15191            gen_bshfl(ctx, op2, rt, rd);
15192            break;
15193        }
15194        break;
15195#endif
15196    case OPC_RDHWR:
15197        gen_rdhwr(ctx, rt, rd, extract32(ctx->opcode, 6, 3));
15198        break;
15199    case OPC_FORK:
15200        check_mt(ctx);
15201        {
15202            TCGv t0 = tcg_temp_new();
15203            TCGv t1 = tcg_temp_new();
15204
15205            gen_load_gpr(t0, rt);
15206            gen_load_gpr(t1, rs);
15207            gen_helper_fork(t0, t1);
15208            tcg_temp_free(t0);
15209            tcg_temp_free(t1);
15210        }
15211        break;
15212    case OPC_YIELD:
15213        check_mt(ctx);
15214        {
15215            TCGv t0 = tcg_temp_new();
15216
15217            gen_load_gpr(t0, rs);
15218            gen_helper_yield(t0, cpu_env, t0);
15219            gen_store_gpr(t0, rd);
15220            tcg_temp_free(t0);
15221        }
15222        break;
15223    default:
15224        if (ctx->insn_flags & ISA_MIPS_R6) {
15225            decode_opc_special3_r6(env, ctx);
15226        } else {
15227            decode_opc_special3_legacy(env, ctx);
15228        }
15229    }
15230}
15231
15232static bool decode_opc_legacy(CPUMIPSState *env, DisasContext *ctx)
15233{
15234    int32_t offset;
15235    int rs, rt, rd, sa;
15236    uint32_t op, op1;
15237    int16_t imm;
15238
15239    op = MASK_OP_MAJOR(ctx->opcode);
15240    rs = (ctx->opcode >> 21) & 0x1f;
15241    rt = (ctx->opcode >> 16) & 0x1f;
15242    rd = (ctx->opcode >> 11) & 0x1f;
15243    sa = (ctx->opcode >> 6) & 0x1f;
15244    imm = (int16_t)ctx->opcode;
15245    switch (op) {
15246    case OPC_SPECIAL:
15247        decode_opc_special(env, ctx);
15248        break;
15249    case OPC_SPECIAL2:
15250#if defined(TARGET_MIPS64)
15251        if ((ctx->insn_flags & INSN_R5900) && (ctx->insn_flags & ASE_MMI)) {
15252            decode_mmi(env, ctx);
15253            break;
15254        }
15255#endif
15256        if (TARGET_LONG_BITS == 32 && (ctx->insn_flags & ASE_MXU)) {
15257            if (MASK_SPECIAL2(ctx->opcode) == OPC_MUL) {
15258                gen_arith(ctx, OPC_MUL, rd, rs, rt);
15259            } else {
15260                decode_ase_mxu(ctx, ctx->opcode);
15261            }
15262            break;
15263        }
15264        decode_opc_special2_legacy(env, ctx);
15265        break;
15266    case OPC_SPECIAL3:
15267#if defined(TARGET_MIPS64)
15268        if (ctx->insn_flags & INSN_R5900) {
15269            decode_mmi_sq(env, ctx);    /* MMI_OPC_SQ */
15270        } else {
15271            decode_opc_special3(env, ctx);
15272        }
15273#else
15274        decode_opc_special3(env, ctx);
15275#endif
15276        break;
15277    case OPC_REGIMM:
15278        op1 = MASK_REGIMM(ctx->opcode);
15279        switch (op1) {
15280        case OPC_BLTZL: /* REGIMM branches */
15281        case OPC_BGEZL:
15282        case OPC_BLTZALL:
15283        case OPC_BGEZALL:
15284            check_insn(ctx, ISA_MIPS2);
15285            check_insn_opc_removed(ctx, ISA_MIPS_R6);
15286            /* Fallthrough */
15287        case OPC_BLTZ:
15288        case OPC_BGEZ:
15289            gen_compute_branch(ctx, op1, 4, rs, -1, imm << 2, 4);
15290            break;
15291        case OPC_BLTZAL:
15292        case OPC_BGEZAL:
15293            if (ctx->insn_flags & ISA_MIPS_R6) {
15294                if (rs == 0) {
15295                    /* OPC_NAL, OPC_BAL */
15296                    gen_compute_branch(ctx, op1, 4, 0, -1, imm << 2, 4);
15297                } else {
15298                    gen_reserved_instruction(ctx);
15299                }
15300            } else {
15301                gen_compute_branch(ctx, op1, 4, rs, -1, imm << 2, 4);
15302            }
15303            break;
15304        case OPC_TGEI: /* REGIMM traps */
15305        case OPC_TGEIU:
15306        case OPC_TLTI:
15307        case OPC_TLTIU:
15308        case OPC_TEQI:
15309        case OPC_TNEI:
15310            check_insn(ctx, ISA_MIPS2);
15311            check_insn_opc_removed(ctx, ISA_MIPS_R6);
15312            gen_trap(ctx, op1, rs, -1, imm, 0);
15313            break;
15314        case OPC_SIGRIE:
15315            check_insn(ctx, ISA_MIPS_R6);
15316            gen_reserved_instruction(ctx);
15317            break;
15318        case OPC_SYNCI:
15319            check_insn(ctx, ISA_MIPS_R2);
15320            /*
15321             * Break the TB to be able to sync copied instructions
15322             * immediately.
15323             */
15324            ctx->base.is_jmp = DISAS_STOP;
15325            break;
15326        case OPC_BPOSGE32:    /* MIPS DSP branch */
15327#if defined(TARGET_MIPS64)
15328        case OPC_BPOSGE64:
15329#endif
15330            check_dsp(ctx);
15331            gen_compute_branch(ctx, op1, 4, -1, -2, (int32_t)imm << 2, 4);
15332            break;
15333#if defined(TARGET_MIPS64)
15334        case OPC_DAHI:
15335            check_insn(ctx, ISA_MIPS_R6);
15336            check_mips_64(ctx);
15337            if (rs != 0) {
15338                tcg_gen_addi_tl(cpu_gpr[rs], cpu_gpr[rs], (int64_t)imm << 32);
15339            }
15340            break;
15341        case OPC_DATI:
15342            check_insn(ctx, ISA_MIPS_R6);
15343            check_mips_64(ctx);
15344            if (rs != 0) {
15345                tcg_gen_addi_tl(cpu_gpr[rs], cpu_gpr[rs], (int64_t)imm << 48);
15346            }
15347            break;
15348#endif
15349        default:            /* Invalid */
15350            MIPS_INVAL("regimm");
15351            gen_reserved_instruction(ctx);
15352            break;
15353        }
15354        break;
15355    case OPC_CP0:
15356        check_cp0_enabled(ctx);
15357        op1 = MASK_CP0(ctx->opcode);
15358        switch (op1) {
15359        case OPC_MFC0:
15360        case OPC_MTC0:
15361        case OPC_MFTR:
15362        case OPC_MTTR:
15363        case OPC_MFHC0:
15364        case OPC_MTHC0:
15365#if defined(TARGET_MIPS64)
15366        case OPC_DMFC0:
15367        case OPC_DMTC0:
15368#endif
15369#ifndef CONFIG_USER_ONLY
15370            gen_cp0(env, ctx, op1, rt, rd);
15371#endif /* !CONFIG_USER_ONLY */
15372            break;
15373        case OPC_C0:
15374        case OPC_C0_1:
15375        case OPC_C0_2:
15376        case OPC_C0_3:
15377        case OPC_C0_4:
15378        case OPC_C0_5:
15379        case OPC_C0_6:
15380        case OPC_C0_7:
15381        case OPC_C0_8:
15382        case OPC_C0_9:
15383        case OPC_C0_A:
15384        case OPC_C0_B:
15385        case OPC_C0_C:
15386        case OPC_C0_D:
15387        case OPC_C0_E:
15388        case OPC_C0_F:
15389#ifndef CONFIG_USER_ONLY
15390            gen_cp0(env, ctx, MASK_C0(ctx->opcode), rt, rd);
15391#endif /* !CONFIG_USER_ONLY */
15392            break;
15393        case OPC_MFMC0:
15394#ifndef CONFIG_USER_ONLY
15395            {
15396                uint32_t op2;
15397                TCGv t0 = tcg_temp_new();
15398
15399                op2 = MASK_MFMC0(ctx->opcode);
15400                switch (op2) {
15401                case OPC_DMT:
15402                    check_cp0_mt(ctx);
15403                    gen_helper_dmt(t0);
15404                    gen_store_gpr(t0, rt);
15405                    break;
15406                case OPC_EMT:
15407                    check_cp0_mt(ctx);
15408                    gen_helper_emt(t0);
15409                    gen_store_gpr(t0, rt);
15410                    break;
15411                case OPC_DVPE:
15412                    check_cp0_mt(ctx);
15413                    gen_helper_dvpe(t0, cpu_env);
15414                    gen_store_gpr(t0, rt);
15415                    break;
15416                case OPC_EVPE:
15417                    check_cp0_mt(ctx);
15418                    gen_helper_evpe(t0, cpu_env);
15419                    gen_store_gpr(t0, rt);
15420                    break;
15421                case OPC_DVP:
15422                    check_insn(ctx, ISA_MIPS_R6);
15423                    if (ctx->vp) {
15424                        gen_helper_dvp(t0, cpu_env);
15425                        gen_store_gpr(t0, rt);
15426                    }
15427                    break;
15428                case OPC_EVP:
15429                    check_insn(ctx, ISA_MIPS_R6);
15430                    if (ctx->vp) {
15431                        gen_helper_evp(t0, cpu_env);
15432                        gen_store_gpr(t0, rt);
15433                    }
15434                    break;
15435                case OPC_DI:
15436                    check_insn(ctx, ISA_MIPS_R2);
15437                    save_cpu_state(ctx, 1);
15438                    gen_helper_di(t0, cpu_env);
15439                    gen_store_gpr(t0, rt);
15440                    /*
15441                     * Stop translation as we may have switched
15442                     * the execution mode.
15443                     */
15444                    ctx->base.is_jmp = DISAS_STOP;
15445                    break;
15446                case OPC_EI:
15447                    check_insn(ctx, ISA_MIPS_R2);
15448                    save_cpu_state(ctx, 1);
15449                    gen_helper_ei(t0, cpu_env);
15450                    gen_store_gpr(t0, rt);
15451                    /*
15452                     * DISAS_STOP isn't sufficient, we need to ensure we break
15453                     * out of translated code to check for pending interrupts.
15454                     */
15455                    gen_save_pc(ctx->base.pc_next + 4);
15456                    ctx->base.is_jmp = DISAS_EXIT;
15457                    break;
15458                default:            /* Invalid */
15459                    MIPS_INVAL("mfmc0");
15460                    gen_reserved_instruction(ctx);
15461                    break;
15462                }
15463                tcg_temp_free(t0);
15464            }
15465#endif /* !CONFIG_USER_ONLY */
15466            break;
15467        case OPC_RDPGPR:
15468            check_insn(ctx, ISA_MIPS_R2);
15469            gen_load_srsgpr(rt, rd);
15470            break;
15471        case OPC_WRPGPR:
15472            check_insn(ctx, ISA_MIPS_R2);
15473            gen_store_srsgpr(rt, rd);
15474            break;
15475        default:
15476            MIPS_INVAL("cp0");
15477            gen_reserved_instruction(ctx);
15478            break;
15479        }
15480        break;
15481    case OPC_BOVC: /* OPC_BEQZALC, OPC_BEQC, OPC_ADDI */
15482        if (ctx->insn_flags & ISA_MIPS_R6) {
15483            /* OPC_BOVC, OPC_BEQZALC, OPC_BEQC */
15484            gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
15485        } else {
15486            /* OPC_ADDI */
15487            /* Arithmetic with immediate opcode */
15488            gen_arith_imm(ctx, op, rt, rs, imm);
15489        }
15490        break;
15491    case OPC_ADDIU:
15492         gen_arith_imm(ctx, op, rt, rs, imm);
15493         break;
15494    case OPC_SLTI: /* Set on less than with immediate opcode */
15495    case OPC_SLTIU:
15496         gen_slt_imm(ctx, op, rt, rs, imm);
15497         break;
15498    case OPC_ANDI: /* Arithmetic with immediate opcode */
15499    case OPC_LUI: /* OPC_AUI */
15500    case OPC_ORI:
15501    case OPC_XORI:
15502         gen_logic_imm(ctx, op, rt, rs, imm);
15503         break;
15504    case OPC_J: /* Jump */
15505    case OPC_JAL:
15506         offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 2;
15507         gen_compute_branch(ctx, op, 4, rs, rt, offset, 4);
15508         break;
15509    /* Branch */
15510    case OPC_BLEZC: /* OPC_BGEZC, OPC_BGEC, OPC_BLEZL */
15511        if (ctx->insn_flags & ISA_MIPS_R6) {
15512            if (rt == 0) {
15513                gen_reserved_instruction(ctx);
15514                break;
15515            }
15516            /* OPC_BLEZC, OPC_BGEZC, OPC_BGEC */
15517            gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
15518        } else {
15519            /* OPC_BLEZL */
15520            gen_compute_branch(ctx, op, 4, rs, rt, imm << 2, 4);
15521        }
15522        break;
15523    case OPC_BGTZC: /* OPC_BLTZC, OPC_BLTC, OPC_BGTZL */
15524        if (ctx->insn_flags & ISA_MIPS_R6) {
15525            if (rt == 0) {
15526                gen_reserved_instruction(ctx);
15527                break;
15528            }
15529            /* OPC_BGTZC, OPC_BLTZC, OPC_BLTC */
15530            gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
15531        } else {
15532            /* OPC_BGTZL */
15533            gen_compute_branch(ctx, op, 4, rs, rt, imm << 2, 4);
15534        }
15535        break;
15536    case OPC_BLEZALC: /* OPC_BGEZALC, OPC_BGEUC, OPC_BLEZ */
15537        if (rt == 0) {
15538            /* OPC_BLEZ */
15539            gen_compute_branch(ctx, op, 4, rs, rt, imm << 2, 4);
15540        } else {
15541            check_insn(ctx, ISA_MIPS_R6);
15542            /* OPC_BLEZALC, OPC_BGEZALC, OPC_BGEUC */
15543            gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
15544        }
15545        break;
15546    case OPC_BGTZALC: /* OPC_BLTZALC, OPC_BLTUC, OPC_BGTZ */
15547        if (rt == 0) {
15548            /* OPC_BGTZ */
15549            gen_compute_branch(ctx, op, 4, rs, rt, imm << 2, 4);
15550        } else {
15551            check_insn(ctx, ISA_MIPS_R6);
15552            /* OPC_BGTZALC, OPC_BLTZALC, OPC_BLTUC */
15553            gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
15554        }
15555        break;
15556    case OPC_BEQL:
15557    case OPC_BNEL:
15558        check_insn(ctx, ISA_MIPS2);
15559         check_insn_opc_removed(ctx, ISA_MIPS_R6);
15560        /* Fallthrough */
15561    case OPC_BEQ:
15562    case OPC_BNE:
15563         gen_compute_branch(ctx, op, 4, rs, rt, imm << 2, 4);
15564         break;
15565    case OPC_LL: /* Load and stores */
15566        check_insn(ctx, ISA_MIPS2);
15567        if (ctx->insn_flags & INSN_R5900) {
15568            check_insn_opc_user_only(ctx, INSN_R5900);
15569        }
15570        /* Fallthrough */
15571    case OPC_LWL:
15572    case OPC_LWR:
15573    case OPC_LB:
15574    case OPC_LH:
15575    case OPC_LW:
15576    case OPC_LWPC:
15577    case OPC_LBU:
15578    case OPC_LHU:
15579         gen_ld(ctx, op, rt, rs, imm);
15580         break;
15581    case OPC_SWL:
15582    case OPC_SWR:
15583    case OPC_SB:
15584    case OPC_SH:
15585    case OPC_SW:
15586         gen_st(ctx, op, rt, rs, imm);
15587         break;
15588    case OPC_SC:
15589        check_insn(ctx, ISA_MIPS2);
15590        if (ctx->insn_flags & INSN_R5900) {
15591            check_insn_opc_user_only(ctx, INSN_R5900);
15592        }
15593        gen_st_cond(ctx, rt, rs, imm, MO_TESL, false);
15594        break;
15595    case OPC_CACHE:
15596        check_cp0_enabled(ctx);
15597        check_insn(ctx, ISA_MIPS3 | ISA_MIPS_R1);
15598        if (ctx->hflags & MIPS_HFLAG_ITC_CACHE) {
15599            gen_cache_operation(ctx, rt, rs, imm);
15600        }
15601        /* Treat as NOP. */
15602        break;
15603    case OPC_PREF:
15604        check_insn(ctx, ISA_MIPS4 | ISA_MIPS_R1 | INSN_R5900);
15605        /* Treat as NOP. */
15606        break;
15607
15608    /* Floating point (COP1). */
15609    case OPC_LWC1:
15610    case OPC_LDC1:
15611    case OPC_SWC1:
15612    case OPC_SDC1:
15613        gen_cop1_ldst(ctx, op, rt, rs, imm);
15614        break;
15615
15616    case OPC_CP1:
15617        op1 = MASK_CP1(ctx->opcode);
15618
15619        switch (op1) {
15620        case OPC_MFHC1:
15621        case OPC_MTHC1:
15622            check_cp1_enabled(ctx);
15623            check_insn(ctx, ISA_MIPS_R2);
15624            /* fall through */
15625        case OPC_MFC1:
15626        case OPC_CFC1:
15627        case OPC_MTC1:
15628        case OPC_CTC1:
15629            check_cp1_enabled(ctx);
15630            gen_cp1(ctx, op1, rt, rd);
15631            break;
15632#if defined(TARGET_MIPS64)
15633        case OPC_DMFC1:
15634        case OPC_DMTC1:
15635            check_cp1_enabled(ctx);
15636            check_insn(ctx, ISA_MIPS3);
15637            check_mips_64(ctx);
15638            gen_cp1(ctx, op1, rt, rd);
15639            break;
15640#endif
15641        case OPC_BC1EQZ: /* OPC_BC1ANY2 */
15642            check_cp1_enabled(ctx);
15643            if (ctx->insn_flags & ISA_MIPS_R6) {
15644                /* OPC_BC1EQZ */
15645                gen_compute_branch1_r6(ctx, MASK_CP1(ctx->opcode),
15646                                       rt, imm << 2, 4);
15647            } else {
15648                /* OPC_BC1ANY2 */
15649                check_cop1x(ctx);
15650                check_insn(ctx, ASE_MIPS3D);
15651                gen_compute_branch1(ctx, MASK_BC1(ctx->opcode),
15652                                    (rt >> 2) & 0x7, imm << 2);
15653            }
15654            break;
15655        case OPC_BC1NEZ:
15656            check_cp1_enabled(ctx);
15657            check_insn(ctx, ISA_MIPS_R6);
15658            gen_compute_branch1_r6(ctx, MASK_CP1(ctx->opcode),
15659                                   rt, imm << 2, 4);
15660            break;
15661        case OPC_BC1ANY4:
15662            check_cp1_enabled(ctx);
15663            check_insn_opc_removed(ctx, ISA_MIPS_R6);
15664            check_cop1x(ctx);
15665            check_insn(ctx, ASE_MIPS3D);
15666            /* fall through */
15667        case OPC_BC1:
15668            check_cp1_enabled(ctx);
15669            check_insn_opc_removed(ctx, ISA_MIPS_R6);
15670            gen_compute_branch1(ctx, MASK_BC1(ctx->opcode),
15671                                (rt >> 2) & 0x7, imm << 2);
15672            break;
15673        case OPC_PS_FMT:
15674            check_ps(ctx);
15675            /* fall through */
15676        case OPC_S_FMT:
15677        case OPC_D_FMT:
15678            check_cp1_enabled(ctx);
15679            gen_farith(ctx, ctx->opcode & FOP(0x3f, 0x1f), rt, rd, sa,
15680                       (imm >> 8) & 0x7);
15681            break;
15682        case OPC_W_FMT:
15683        case OPC_L_FMT:
15684        {
15685            int r6_op = ctx->opcode & FOP(0x3f, 0x1f);
15686            check_cp1_enabled(ctx);
15687            if (ctx->insn_flags & ISA_MIPS_R6) {
15688                switch (r6_op) {
15689                case R6_OPC_CMP_AF_S:
15690                case R6_OPC_CMP_UN_S:
15691                case R6_OPC_CMP_EQ_S:
15692                case R6_OPC_CMP_UEQ_S:
15693                case R6_OPC_CMP_LT_S:
15694                case R6_OPC_CMP_ULT_S:
15695                case R6_OPC_CMP_LE_S:
15696                case R6_OPC_CMP_ULE_S:
15697                case R6_OPC_CMP_SAF_S:
15698                case R6_OPC_CMP_SUN_S:
15699                case R6_OPC_CMP_SEQ_S:
15700                case R6_OPC_CMP_SEUQ_S:
15701                case R6_OPC_CMP_SLT_S:
15702                case R6_OPC_CMP_SULT_S:
15703                case R6_OPC_CMP_SLE_S:
15704                case R6_OPC_CMP_SULE_S:
15705                case R6_OPC_CMP_OR_S:
15706                case R6_OPC_CMP_UNE_S:
15707                case R6_OPC_CMP_NE_S:
15708                case R6_OPC_CMP_SOR_S:
15709                case R6_OPC_CMP_SUNE_S:
15710                case R6_OPC_CMP_SNE_S:
15711                    gen_r6_cmp_s(ctx, ctx->opcode & 0x1f, rt, rd, sa);
15712                    break;
15713                case R6_OPC_CMP_AF_D:
15714                case R6_OPC_CMP_UN_D:
15715                case R6_OPC_CMP_EQ_D:
15716                case R6_OPC_CMP_UEQ_D:
15717                case R6_OPC_CMP_LT_D:
15718                case R6_OPC_CMP_ULT_D:
15719                case R6_OPC_CMP_LE_D:
15720                case R6_OPC_CMP_ULE_D:
15721                case R6_OPC_CMP_SAF_D:
15722                case R6_OPC_CMP_SUN_D:
15723                case R6_OPC_CMP_SEQ_D:
15724                case R6_OPC_CMP_SEUQ_D:
15725                case R6_OPC_CMP_SLT_D:
15726                case R6_OPC_CMP_SULT_D:
15727                case R6_OPC_CMP_SLE_D:
15728                case R6_OPC_CMP_SULE_D:
15729                case R6_OPC_CMP_OR_D:
15730                case R6_OPC_CMP_UNE_D:
15731                case R6_OPC_CMP_NE_D:
15732                case R6_OPC_CMP_SOR_D:
15733                case R6_OPC_CMP_SUNE_D:
15734                case R6_OPC_CMP_SNE_D:
15735                    gen_r6_cmp_d(ctx, ctx->opcode & 0x1f, rt, rd, sa);
15736                    break;
15737                default:
15738                    gen_farith(ctx, ctx->opcode & FOP(0x3f, 0x1f),
15739                               rt, rd, sa, (imm >> 8) & 0x7);
15740
15741                    break;
15742                }
15743            } else {
15744                gen_farith(ctx, ctx->opcode & FOP(0x3f, 0x1f), rt, rd, sa,
15745                           (imm >> 8) & 0x7);
15746            }
15747            break;
15748        }
15749        default:
15750            MIPS_INVAL("cp1");
15751            gen_reserved_instruction(ctx);
15752            break;
15753        }
15754        break;
15755
15756    /* Compact branches [R6] and COP2 [non-R6] */
15757    case OPC_BC: /* OPC_LWC2 */
15758    case OPC_BALC: /* OPC_SWC2 */
15759        if (ctx->insn_flags & ISA_MIPS_R6) {
15760            /* OPC_BC, OPC_BALC */
15761            gen_compute_compact_branch(ctx, op, 0, 0,
15762                                       sextract32(ctx->opcode << 2, 0, 28));
15763        } else if (ctx->insn_flags & ASE_LEXT) {
15764            gen_loongson_lswc2(ctx, rt, rs, rd);
15765        } else {
15766            /* OPC_LWC2, OPC_SWC2 */
15767            /* COP2: Not implemented. */
15768            generate_exception_err(ctx, EXCP_CpU, 2);
15769        }
15770        break;
15771    case OPC_BEQZC: /* OPC_JIC, OPC_LDC2 */
15772    case OPC_BNEZC: /* OPC_JIALC, OPC_SDC2 */
15773        if (ctx->insn_flags & ISA_MIPS_R6) {
15774            if (rs != 0) {
15775                /* OPC_BEQZC, OPC_BNEZC */
15776                gen_compute_compact_branch(ctx, op, rs, 0,
15777                                           sextract32(ctx->opcode << 2, 0, 23));
15778            } else {
15779                /* OPC_JIC, OPC_JIALC */
15780                gen_compute_compact_branch(ctx, op, 0, rt, imm);
15781            }
15782        } else if (ctx->insn_flags & ASE_LEXT) {
15783            gen_loongson_lsdc2(ctx, rt, rs, rd);
15784        } else {
15785            /* OPC_LWC2, OPC_SWC2 */
15786            /* COP2: Not implemented. */
15787            generate_exception_err(ctx, EXCP_CpU, 2);
15788        }
15789        break;
15790    case OPC_CP2:
15791        check_insn(ctx, ASE_LMMI);
15792        /* Note that these instructions use different fields.  */
15793        gen_loongson_multimedia(ctx, sa, rd, rt);
15794        break;
15795
15796    case OPC_CP3:
15797        if (ctx->CP0_Config1 & (1 << CP0C1_FP)) {
15798            check_cp1_enabled(ctx);
15799            op1 = MASK_CP3(ctx->opcode);
15800            switch (op1) {
15801            case OPC_LUXC1:
15802            case OPC_SUXC1:
15803                check_insn(ctx, ISA_MIPS5 | ISA_MIPS_R2);
15804                /* Fallthrough */
15805            case OPC_LWXC1:
15806            case OPC_LDXC1:
15807            case OPC_SWXC1:
15808            case OPC_SDXC1:
15809                check_insn(ctx, ISA_MIPS4 | ISA_MIPS_R2);
15810                gen_flt3_ldst(ctx, op1, sa, rd, rs, rt);
15811                break;
15812            case OPC_PREFX:
15813                check_insn(ctx, ISA_MIPS4 | ISA_MIPS_R2);
15814                /* Treat as NOP. */
15815                break;
15816            case OPC_ALNV_PS:
15817                check_insn(ctx, ISA_MIPS5 | ISA_MIPS_R2);
15818                /* Fallthrough */
15819            case OPC_MADD_S:
15820            case OPC_MADD_D:
15821            case OPC_MADD_PS:
15822            case OPC_MSUB_S:
15823            case OPC_MSUB_D:
15824            case OPC_MSUB_PS:
15825            case OPC_NMADD_S:
15826            case OPC_NMADD_D:
15827            case OPC_NMADD_PS:
15828            case OPC_NMSUB_S:
15829            case OPC_NMSUB_D:
15830            case OPC_NMSUB_PS:
15831                check_insn(ctx, ISA_MIPS4 | ISA_MIPS_R2);
15832                gen_flt3_arith(ctx, op1, sa, rs, rd, rt);
15833                break;
15834            default:
15835                MIPS_INVAL("cp3");
15836                gen_reserved_instruction(ctx);
15837                break;
15838            }
15839        } else {
15840            generate_exception_err(ctx, EXCP_CpU, 1);
15841        }
15842        break;
15843
15844#if defined(TARGET_MIPS64)
15845    /* MIPS64 opcodes */
15846    case OPC_LLD:
15847        if (ctx->insn_flags & INSN_R5900) {
15848            check_insn_opc_user_only(ctx, INSN_R5900);
15849        }
15850        /* fall through */
15851    case OPC_LDL:
15852    case OPC_LDR:
15853    case OPC_LWU:
15854    case OPC_LD:
15855        check_insn(ctx, ISA_MIPS3);
15856        check_mips_64(ctx);
15857        gen_ld(ctx, op, rt, rs, imm);
15858        break;
15859    case OPC_SDL:
15860    case OPC_SDR:
15861    case OPC_SD:
15862        check_insn(ctx, ISA_MIPS3);
15863        check_mips_64(ctx);
15864        gen_st(ctx, op, rt, rs, imm);
15865        break;
15866    case OPC_SCD:
15867        check_insn(ctx, ISA_MIPS3);
15868        if (ctx->insn_flags & INSN_R5900) {
15869            check_insn_opc_user_only(ctx, INSN_R5900);
15870        }
15871        check_mips_64(ctx);
15872        gen_st_cond(ctx, rt, rs, imm, MO_TEUQ, false);
15873        break;
15874    case OPC_BNVC: /* OPC_BNEZALC, OPC_BNEC, OPC_DADDI */
15875        if (ctx->insn_flags & ISA_MIPS_R6) {
15876            /* OPC_BNVC, OPC_BNEZALC, OPC_BNEC */
15877            gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
15878        } else {
15879            /* OPC_DADDI */
15880            check_insn(ctx, ISA_MIPS3);
15881            check_mips_64(ctx);
15882            gen_arith_imm(ctx, op, rt, rs, imm);
15883        }
15884        break;
15885    case OPC_DADDIU:
15886        check_insn(ctx, ISA_MIPS3);
15887        check_mips_64(ctx);
15888        gen_arith_imm(ctx, op, rt, rs, imm);
15889        break;
15890#else
15891    case OPC_BNVC: /* OPC_BNEZALC, OPC_BNEC */
15892        if (ctx->insn_flags & ISA_MIPS_R6) {
15893            gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
15894        } else {
15895            MIPS_INVAL("major opcode");
15896            gen_reserved_instruction(ctx);
15897        }
15898        break;
15899#endif
15900    case OPC_DAUI: /* OPC_JALX */
15901        if (ctx->insn_flags & ISA_MIPS_R6) {
15902#if defined(TARGET_MIPS64)
15903            /* OPC_DAUI */
15904            check_mips_64(ctx);
15905            if (rs == 0) {
15906                generate_exception(ctx, EXCP_RI);
15907            } else if (rt != 0) {
15908                TCGv t0 = tcg_temp_new();
15909                gen_load_gpr(t0, rs);
15910                tcg_gen_addi_tl(cpu_gpr[rt], t0, imm << 16);
15911                tcg_temp_free(t0);
15912            }
15913#else
15914            gen_reserved_instruction(ctx);
15915            MIPS_INVAL("major opcode");
15916#endif
15917        } else {
15918            /* OPC_JALX */
15919            check_insn(ctx, ASE_MIPS16 | ASE_MICROMIPS);
15920            offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 2;
15921            gen_compute_branch(ctx, op, 4, rs, rt, offset, 4);
15922        }
15923        break;
15924    case OPC_MDMX:
15925        /* MDMX: Not implemented. */
15926        break;
15927    case OPC_PCREL:
15928        check_insn(ctx, ISA_MIPS_R6);
15929        gen_pcrel(ctx, ctx->opcode, ctx->base.pc_next, rs);
15930        break;
15931    default:            /* Invalid */
15932        MIPS_INVAL("major opcode");
15933        return false;
15934    }
15935    return true;
15936}
15937
15938static void decode_opc(CPUMIPSState *env, DisasContext *ctx)
15939{
15940    /* make sure instructions are on a word boundary */
15941    if (ctx->base.pc_next & 0x3) {
15942        env->CP0_BadVAddr = ctx->base.pc_next;
15943        generate_exception_err(ctx, EXCP_AdEL, EXCP_INST_NOTAVAIL);
15944        return;
15945    }
15946
15947    /* Handle blikely not taken case */
15948    if ((ctx->hflags & MIPS_HFLAG_BMASK_BASE) == MIPS_HFLAG_BL) {
15949        TCGLabel *l1 = gen_new_label();
15950
15951        tcg_gen_brcondi_tl(TCG_COND_NE, bcond, 0, l1);
15952        tcg_gen_movi_i32(hflags, ctx->hflags & ~MIPS_HFLAG_BMASK);
15953        gen_goto_tb(ctx, 1, ctx->base.pc_next + 4);
15954        gen_set_label(l1);
15955    }
15956
15957    /* Transition to the auto-generated decoder.  */
15958
15959    /* Vendor specific extensions */
15960    if (cpu_supports_isa(env, INSN_R5900) && decode_ext_txx9(ctx, ctx->opcode)) {
15961        return;
15962    }
15963    if (cpu_supports_isa(env, INSN_VR54XX) && decode_ext_vr54xx(ctx, ctx->opcode)) {
15964        return;
15965    }
15966
15967    /* ISA extensions */
15968    if (ase_msa_available(env) && decode_ase_msa(ctx, ctx->opcode)) {
15969        return;
15970    }
15971
15972    /* ISA (from latest to oldest) */
15973    if (cpu_supports_isa(env, ISA_MIPS_R6) && decode_isa_rel6(ctx, ctx->opcode)) {
15974        return;
15975    }
15976
15977    if (decode_opc_legacy(env, ctx)) {
15978        return;
15979    }
15980
15981    gen_reserved_instruction(ctx);
15982}
15983
15984static void mips_tr_init_disas_context(DisasContextBase *dcbase, CPUState *cs)
15985{
15986    DisasContext *ctx = container_of(dcbase, DisasContext, base);
15987    CPUMIPSState *env = cs->env_ptr;
15988
15989    ctx->page_start = ctx->base.pc_first & TARGET_PAGE_MASK;
15990    ctx->saved_pc = -1;
15991    ctx->insn_flags = env->insn_flags;
15992    ctx->CP0_Config0 = env->CP0_Config0;
15993    ctx->CP0_Config1 = env->CP0_Config1;
15994    ctx->CP0_Config2 = env->CP0_Config2;
15995    ctx->CP0_Config3 = env->CP0_Config3;
15996    ctx->CP0_Config5 = env->CP0_Config5;
15997    ctx->btarget = 0;
15998    ctx->kscrexist = (env->CP0_Config4 >> CP0C4_KScrExist) & 0xff;
15999    ctx->rxi = (env->CP0_Config3 >> CP0C3_RXI) & 1;
16000    ctx->ie = (env->CP0_Config4 >> CP0C4_IE) & 3;
16001    ctx->bi = (env->CP0_Config3 >> CP0C3_BI) & 1;
16002    ctx->bp = (env->CP0_Config3 >> CP0C3_BP) & 1;
16003    ctx->PAMask = env->PAMask;
16004    ctx->mvh = (env->CP0_Config5 >> CP0C5_MVH) & 1;
16005    ctx->eva = (env->CP0_Config5 >> CP0C5_EVA) & 1;
16006    ctx->sc = (env->CP0_Config3 >> CP0C3_SC) & 1;
16007    ctx->CP0_LLAddr_shift = env->CP0_LLAddr_shift;
16008    ctx->cmgcr = (env->CP0_Config3 >> CP0C3_CMGCR) & 1;
16009    /* Restore delay slot state from the tb context.  */
16010    ctx->hflags = (uint32_t)ctx->base.tb->flags; /* FIXME: maybe use 64 bits? */
16011    ctx->ulri = (env->CP0_Config3 >> CP0C3_ULRI) & 1;
16012    ctx->ps = ((env->active_fpu.fcr0 >> FCR0_PS) & 1) ||
16013             (env->insn_flags & (INSN_LOONGSON2E | INSN_LOONGSON2F));
16014    ctx->vp = (env->CP0_Config5 >> CP0C5_VP) & 1;
16015    ctx->mrp = (env->CP0_Config5 >> CP0C5_MRP) & 1;
16016    ctx->nan2008 = (env->active_fpu.fcr31 >> FCR31_NAN2008) & 1;
16017    ctx->abs2008 = (env->active_fpu.fcr31 >> FCR31_ABS2008) & 1;
16018    ctx->mi = (env->CP0_Config5 >> CP0C5_MI) & 1;
16019    ctx->gi = (env->CP0_Config5 >> CP0C5_GI) & 3;
16020    restore_cpu_state(env, ctx);
16021#ifdef CONFIG_USER_ONLY
16022        ctx->mem_idx = MIPS_HFLAG_UM;
16023#else
16024        ctx->mem_idx = hflags_mmu_index(ctx->hflags);
16025#endif
16026    ctx->default_tcg_memop_mask = (ctx->insn_flags & (ISA_MIPS_R6 |
16027                                  INSN_LOONGSON3A)) ? MO_UNALN : MO_ALIGN;
16028
16029    /*
16030     * Execute a branch and its delay slot as a single instruction.
16031     * This is what GDB expects and is consistent with what the
16032     * hardware does (e.g. if a delay slot instruction faults, the
16033     * reported PC is the PC of the branch).
16034     */
16035    if (ctx->base.singlestep_enabled && (ctx->hflags & MIPS_HFLAG_BMASK)) {
16036        ctx->base.max_insns = 2;
16037    }
16038
16039    LOG_DISAS("\ntb %p idx %d hflags %04x\n", ctx->base.tb, ctx->mem_idx,
16040              ctx->hflags);
16041}
16042
16043static void mips_tr_tb_start(DisasContextBase *dcbase, CPUState *cs)
16044{
16045}
16046
16047static void mips_tr_insn_start(DisasContextBase *dcbase, CPUState *cs)
16048{
16049    DisasContext *ctx = container_of(dcbase, DisasContext, base);
16050
16051    tcg_gen_insn_start(ctx->base.pc_next, ctx->hflags & MIPS_HFLAG_BMASK,
16052                       ctx->btarget);
16053}
16054
16055static void mips_tr_translate_insn(DisasContextBase *dcbase, CPUState *cs)
16056{
16057    CPUMIPSState *env = cs->env_ptr;
16058    DisasContext *ctx = container_of(dcbase, DisasContext, base);
16059    int insn_bytes;
16060    int is_slot;
16061
16062    is_slot = ctx->hflags & MIPS_HFLAG_BMASK;
16063    if (ctx->insn_flags & ISA_NANOMIPS32) {
16064        ctx->opcode = translator_lduw(env, &ctx->base, ctx->base.pc_next);
16065        insn_bytes = decode_isa_nanomips(env, ctx);
16066    } else if (!(ctx->hflags & MIPS_HFLAG_M16)) {
16067        ctx->opcode = translator_ldl(env, &ctx->base, ctx->base.pc_next);
16068        insn_bytes = 4;
16069        decode_opc(env, ctx);
16070    } else if (ctx->insn_flags & ASE_MICROMIPS) {
16071        ctx->opcode = translator_lduw(env, &ctx->base, ctx->base.pc_next);
16072        insn_bytes = decode_isa_micromips(env, ctx);
16073    } else if (ctx->insn_flags & ASE_MIPS16) {
16074        ctx->opcode = translator_lduw(env, &ctx->base, ctx->base.pc_next);
16075        insn_bytes = decode_ase_mips16e(env, ctx);
16076    } else {
16077        gen_reserved_instruction(ctx);
16078        g_assert(ctx->base.is_jmp == DISAS_NORETURN);
16079        return;
16080    }
16081
16082    if (ctx->hflags & MIPS_HFLAG_BMASK) {
16083        if (!(ctx->hflags & (MIPS_HFLAG_BDS16 | MIPS_HFLAG_BDS32 |
16084                             MIPS_HFLAG_FBNSLOT))) {
16085            /*
16086             * Force to generate branch as there is neither delay nor
16087             * forbidden slot.
16088             */
16089            is_slot = 1;
16090        }
16091        if ((ctx->hflags & MIPS_HFLAG_M16) &&
16092            (ctx->hflags & MIPS_HFLAG_FBNSLOT)) {
16093            /*
16094             * Force to generate branch as microMIPS R6 doesn't restrict
16095             * branches in the forbidden slot.
16096             */
16097            is_slot = 1;
16098        }
16099    }
16100    if (is_slot) {
16101        gen_branch(ctx, insn_bytes);
16102    }
16103    ctx->base.pc_next += insn_bytes;
16104
16105    if (ctx->base.is_jmp != DISAS_NEXT) {
16106        return;
16107    }
16108
16109    /*
16110     * End the TB on (most) page crossings.
16111     * See mips_tr_init_disas_context about single-stepping a branch
16112     * together with its delay slot.
16113     */
16114    if (ctx->base.pc_next - ctx->page_start >= TARGET_PAGE_SIZE
16115        && !ctx->base.singlestep_enabled) {
16116        ctx->base.is_jmp = DISAS_TOO_MANY;
16117    }
16118}
16119
16120static void mips_tr_tb_stop(DisasContextBase *dcbase, CPUState *cs)
16121{
16122    DisasContext *ctx = container_of(dcbase, DisasContext, base);
16123
16124    switch (ctx->base.is_jmp) {
16125    case DISAS_STOP:
16126        gen_save_pc(ctx->base.pc_next);
16127        tcg_gen_lookup_and_goto_ptr();
16128        break;
16129    case DISAS_NEXT:
16130    case DISAS_TOO_MANY:
16131        save_cpu_state(ctx, 0);
16132        gen_goto_tb(ctx, 0, ctx->base.pc_next);
16133        break;
16134    case DISAS_EXIT:
16135        tcg_gen_exit_tb(NULL, 0);
16136        break;
16137    case DISAS_NORETURN:
16138        break;
16139    default:
16140        g_assert_not_reached();
16141    }
16142}
16143
16144static void mips_tr_disas_log(const DisasContextBase *dcbase, CPUState *cs)
16145{
16146    qemu_log("IN: %s\n", lookup_symbol(dcbase->pc_first));
16147    log_target_disas(cs, dcbase->pc_first, dcbase->tb->size);
16148}
16149
16150static const TranslatorOps mips_tr_ops = {
16151    .init_disas_context = mips_tr_init_disas_context,
16152    .tb_start           = mips_tr_tb_start,
16153    .insn_start         = mips_tr_insn_start,
16154    .translate_insn     = mips_tr_translate_insn,
16155    .tb_stop            = mips_tr_tb_stop,
16156    .disas_log          = mips_tr_disas_log,
16157};
16158
16159void gen_intermediate_code(CPUState *cs, TranslationBlock *tb, int max_insns)
16160{
16161    DisasContext ctx;
16162
16163    translator_loop(&mips_tr_ops, &ctx.base, cs, tb, max_insns);
16164}
16165
16166void mips_tcg_init(void)
16167{
16168    int i;
16169
16170    cpu_gpr[0] = NULL;
16171    for (i = 1; i < 32; i++)
16172        cpu_gpr[i] = tcg_global_mem_new(cpu_env,
16173                                        offsetof(CPUMIPSState,
16174                                                 active_tc.gpr[i]),
16175                                        regnames[i]);
16176#if defined(TARGET_MIPS64)
16177    cpu_gpr_hi[0] = NULL;
16178
16179    for (unsigned i = 1; i < 32; i++) {
16180        g_autofree char *rname = g_strdup_printf("%s[hi]", regnames[i]);
16181
16182        cpu_gpr_hi[i] = tcg_global_mem_new_i64(cpu_env,
16183                                               offsetof(CPUMIPSState,
16184                                                        active_tc.gpr_hi[i]),
16185                                               rname);
16186    }
16187#endif /* !TARGET_MIPS64 */
16188    for (i = 0; i < 32; i++) {
16189        int off = offsetof(CPUMIPSState, active_fpu.fpr[i].wr.d[0]);
16190
16191        fpu_f64[i] = tcg_global_mem_new_i64(cpu_env, off, fregnames[i]);
16192    }
16193    msa_translate_init();
16194    cpu_PC = tcg_global_mem_new(cpu_env,
16195                                offsetof(CPUMIPSState, active_tc.PC), "PC");
16196    for (i = 0; i < MIPS_DSP_ACC; i++) {
16197        cpu_HI[i] = tcg_global_mem_new(cpu_env,
16198                                       offsetof(CPUMIPSState, active_tc.HI[i]),
16199                                       regnames_HI[i]);
16200        cpu_LO[i] = tcg_global_mem_new(cpu_env,
16201                                       offsetof(CPUMIPSState, active_tc.LO[i]),
16202                                       regnames_LO[i]);
16203    }
16204    cpu_dspctrl = tcg_global_mem_new(cpu_env,
16205                                     offsetof(CPUMIPSState,
16206                                              active_tc.DSPControl),
16207                                     "DSPControl");
16208    bcond = tcg_global_mem_new(cpu_env,
16209                               offsetof(CPUMIPSState, bcond), "bcond");
16210    btarget = tcg_global_mem_new(cpu_env,
16211                                 offsetof(CPUMIPSState, btarget), "btarget");
16212    hflags = tcg_global_mem_new_i32(cpu_env,
16213                                    offsetof(CPUMIPSState, hflags), "hflags");
16214
16215    fpu_fcr0 = tcg_global_mem_new_i32(cpu_env,
16216                                      offsetof(CPUMIPSState, active_fpu.fcr0),
16217                                      "fcr0");
16218    fpu_fcr31 = tcg_global_mem_new_i32(cpu_env,
16219                                       offsetof(CPUMIPSState, active_fpu.fcr31),
16220                                       "fcr31");
16221    cpu_lladdr = tcg_global_mem_new(cpu_env, offsetof(CPUMIPSState, lladdr),
16222                                    "lladdr");
16223    cpu_llval = tcg_global_mem_new(cpu_env, offsetof(CPUMIPSState, llval),
16224                                   "llval");
16225
16226    if (TARGET_LONG_BITS == 32) {
16227        mxu_translate_init();
16228    }
16229}
16230
16231void restore_state_to_opc(CPUMIPSState *env, TranslationBlock *tb,
16232                          target_ulong *data)
16233{
16234    env->active_tc.PC = data[0];
16235    env->hflags &= ~MIPS_HFLAG_BMASK;
16236    env->hflags |= data[1];
16237    switch (env->hflags & MIPS_HFLAG_BMASK_BASE) {
16238    case MIPS_HFLAG_BR:
16239        break;
16240    case MIPS_HFLAG_BC:
16241    case MIPS_HFLAG_BL:
16242    case MIPS_HFLAG_B:
16243        env->btarget = data[2];
16244        break;
16245    }
16246}
16247