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
1216static const char regnames_HI[][4] = {
1217    "HI0", "HI1", "HI2", "HI3",
1218};
1219
1220static const char regnames_LO[][4] = {
1221    "LO0", "LO1", "LO2", "LO3",
1222};
1223
1224/* General purpose registers moves. */
1225void gen_load_gpr(TCGv t, int reg)
1226{
1227    if (reg == 0) {
1228        tcg_gen_movi_tl(t, 0);
1229    } else {
1230        tcg_gen_mov_tl(t, cpu_gpr[reg]);
1231    }
1232}
1233
1234void gen_store_gpr(TCGv t, int reg)
1235{
1236    if (reg != 0) {
1237        tcg_gen_mov_tl(cpu_gpr[reg], t);
1238    }
1239}
1240
1241#if defined(TARGET_MIPS64)
1242void gen_load_gpr_hi(TCGv_i64 t, int reg)
1243{
1244    if (reg == 0) {
1245        tcg_gen_movi_i64(t, 0);
1246    } else {
1247        tcg_gen_mov_i64(t, cpu_gpr_hi[reg]);
1248    }
1249}
1250
1251void gen_store_gpr_hi(TCGv_i64 t, int reg)
1252{
1253    if (reg != 0) {
1254        tcg_gen_mov_i64(cpu_gpr_hi[reg], t);
1255    }
1256}
1257#endif /* TARGET_MIPS64 */
1258
1259/* Moves to/from shadow registers. */
1260static inline void gen_load_srsgpr(int from, int to)
1261{
1262    TCGv t0 = tcg_temp_new();
1263
1264    if (from == 0) {
1265        tcg_gen_movi_tl(t0, 0);
1266    } else {
1267        TCGv_i32 t2 = tcg_temp_new_i32();
1268        TCGv_ptr addr = tcg_temp_new_ptr();
1269
1270        tcg_gen_ld_i32(t2, cpu_env, offsetof(CPUMIPSState, CP0_SRSCtl));
1271        tcg_gen_shri_i32(t2, t2, CP0SRSCtl_PSS);
1272        tcg_gen_andi_i32(t2, t2, 0xf);
1273        tcg_gen_muli_i32(t2, t2, sizeof(target_ulong) * 32);
1274        tcg_gen_ext_i32_ptr(addr, t2);
1275        tcg_gen_add_ptr(addr, cpu_env, addr);
1276
1277        tcg_gen_ld_tl(t0, addr, sizeof(target_ulong) * from);
1278        tcg_temp_free_ptr(addr);
1279        tcg_temp_free_i32(t2);
1280    }
1281    gen_store_gpr(t0, to);
1282    tcg_temp_free(t0);
1283}
1284
1285static inline void gen_store_srsgpr(int from, int to)
1286{
1287    if (to != 0) {
1288        TCGv t0 = tcg_temp_new();
1289        TCGv_i32 t2 = tcg_temp_new_i32();
1290        TCGv_ptr addr = tcg_temp_new_ptr();
1291
1292        gen_load_gpr(t0, from);
1293        tcg_gen_ld_i32(t2, cpu_env, offsetof(CPUMIPSState, CP0_SRSCtl));
1294        tcg_gen_shri_i32(t2, t2, CP0SRSCtl_PSS);
1295        tcg_gen_andi_i32(t2, t2, 0xf);
1296        tcg_gen_muli_i32(t2, t2, sizeof(target_ulong) * 32);
1297        tcg_gen_ext_i32_ptr(addr, t2);
1298        tcg_gen_add_ptr(addr, cpu_env, addr);
1299
1300        tcg_gen_st_tl(t0, addr, sizeof(target_ulong) * to);
1301        tcg_temp_free_ptr(addr);
1302        tcg_temp_free_i32(t2);
1303        tcg_temp_free(t0);
1304    }
1305}
1306
1307/* Tests */
1308static inline void gen_save_pc(target_ulong pc)
1309{
1310    tcg_gen_movi_tl(cpu_PC, pc);
1311}
1312
1313static inline void save_cpu_state(DisasContext *ctx, int do_save_pc)
1314{
1315    LOG_DISAS("hflags %08x saved %08x\n", ctx->hflags, ctx->saved_hflags);
1316    if (do_save_pc && ctx->base.pc_next != ctx->saved_pc) {
1317        gen_save_pc(ctx->base.pc_next);
1318        ctx->saved_pc = ctx->base.pc_next;
1319    }
1320    if (ctx->hflags != ctx->saved_hflags) {
1321        tcg_gen_movi_i32(hflags, ctx->hflags);
1322        ctx->saved_hflags = ctx->hflags;
1323        switch (ctx->hflags & MIPS_HFLAG_BMASK_BASE) {
1324        case MIPS_HFLAG_BR:
1325            break;
1326        case MIPS_HFLAG_BC:
1327        case MIPS_HFLAG_BL:
1328        case MIPS_HFLAG_B:
1329            tcg_gen_movi_tl(btarget, ctx->btarget);
1330            break;
1331        }
1332    }
1333}
1334
1335static inline void restore_cpu_state(CPUMIPSState *env, DisasContext *ctx)
1336{
1337    ctx->saved_hflags = ctx->hflags;
1338    switch (ctx->hflags & MIPS_HFLAG_BMASK_BASE) {
1339    case MIPS_HFLAG_BR:
1340        break;
1341    case MIPS_HFLAG_BC:
1342    case MIPS_HFLAG_BL:
1343    case MIPS_HFLAG_B:
1344        ctx->btarget = env->btarget;
1345        break;
1346    }
1347}
1348
1349void generate_exception_err(DisasContext *ctx, int excp, int err)
1350{
1351    save_cpu_state(ctx, 1);
1352    gen_helper_raise_exception_err(cpu_env, tcg_constant_i32(excp),
1353                                   tcg_constant_i32(err));
1354    ctx->base.is_jmp = DISAS_NORETURN;
1355}
1356
1357void generate_exception(DisasContext *ctx, int excp)
1358{
1359    gen_helper_raise_exception(cpu_env, tcg_constant_i32(excp));
1360}
1361
1362void generate_exception_end(DisasContext *ctx, int excp)
1363{
1364    generate_exception_err(ctx, excp, 0);
1365}
1366
1367void generate_exception_break(DisasContext *ctx, int code)
1368{
1369#ifdef CONFIG_USER_ONLY
1370    /* Pass the break code along to cpu_loop. */
1371    tcg_gen_st_i32(tcg_constant_i32(code), cpu_env,
1372                   offsetof(CPUMIPSState, error_code));
1373#endif
1374    generate_exception_end(ctx, EXCP_BREAK);
1375}
1376
1377void gen_reserved_instruction(DisasContext *ctx)
1378{
1379    generate_exception_end(ctx, EXCP_RI);
1380}
1381
1382/* Floating point register moves. */
1383void gen_load_fpr32(DisasContext *ctx, TCGv_i32 t, int reg)
1384{
1385    if (ctx->hflags & MIPS_HFLAG_FRE) {
1386        generate_exception(ctx, EXCP_RI);
1387    }
1388    tcg_gen_extrl_i64_i32(t, fpu_f64[reg]);
1389}
1390
1391void gen_store_fpr32(DisasContext *ctx, TCGv_i32 t, int reg)
1392{
1393    TCGv_i64 t64;
1394    if (ctx->hflags & MIPS_HFLAG_FRE) {
1395        generate_exception(ctx, EXCP_RI);
1396    }
1397    t64 = tcg_temp_new_i64();
1398    tcg_gen_extu_i32_i64(t64, t);
1399    tcg_gen_deposit_i64(fpu_f64[reg], fpu_f64[reg], t64, 0, 32);
1400    tcg_temp_free_i64(t64);
1401}
1402
1403static void gen_load_fpr32h(DisasContext *ctx, TCGv_i32 t, int reg)
1404{
1405    if (ctx->hflags & MIPS_HFLAG_F64) {
1406        tcg_gen_extrh_i64_i32(t, fpu_f64[reg]);
1407    } else {
1408        gen_load_fpr32(ctx, t, reg | 1);
1409    }
1410}
1411
1412static void gen_store_fpr32h(DisasContext *ctx, TCGv_i32 t, int reg)
1413{
1414    if (ctx->hflags & MIPS_HFLAG_F64) {
1415        TCGv_i64 t64 = tcg_temp_new_i64();
1416        tcg_gen_extu_i32_i64(t64, t);
1417        tcg_gen_deposit_i64(fpu_f64[reg], fpu_f64[reg], t64, 32, 32);
1418        tcg_temp_free_i64(t64);
1419    } else {
1420        gen_store_fpr32(ctx, t, reg | 1);
1421    }
1422}
1423
1424void gen_load_fpr64(DisasContext *ctx, TCGv_i64 t, int reg)
1425{
1426    if (ctx->hflags & MIPS_HFLAG_F64) {
1427        tcg_gen_mov_i64(t, fpu_f64[reg]);
1428    } else {
1429        tcg_gen_concat32_i64(t, fpu_f64[reg & ~1], fpu_f64[reg | 1]);
1430    }
1431}
1432
1433void gen_store_fpr64(DisasContext *ctx, TCGv_i64 t, int reg)
1434{
1435    if (ctx->hflags & MIPS_HFLAG_F64) {
1436        tcg_gen_mov_i64(fpu_f64[reg], t);
1437    } else {
1438        TCGv_i64 t0;
1439        tcg_gen_deposit_i64(fpu_f64[reg & ~1], fpu_f64[reg & ~1], t, 0, 32);
1440        t0 = tcg_temp_new_i64();
1441        tcg_gen_shri_i64(t0, t, 32);
1442        tcg_gen_deposit_i64(fpu_f64[reg | 1], fpu_f64[reg | 1], t0, 0, 32);
1443        tcg_temp_free_i64(t0);
1444    }
1445}
1446
1447int get_fp_bit(int cc)
1448{
1449    if (cc) {
1450        return 24 + cc;
1451    } else {
1452        return 23;
1453    }
1454}
1455
1456/* Addresses computation */
1457void gen_op_addr_add(DisasContext *ctx, TCGv ret, TCGv arg0, TCGv arg1)
1458{
1459    tcg_gen_add_tl(ret, arg0, arg1);
1460
1461#if defined(TARGET_MIPS64)
1462    if (ctx->hflags & MIPS_HFLAG_AWRAP) {
1463        tcg_gen_ext32s_i64(ret, ret);
1464    }
1465#endif
1466}
1467
1468static inline void gen_op_addr_addi(DisasContext *ctx, TCGv ret, TCGv base,
1469                                    target_long ofs)
1470{
1471    tcg_gen_addi_tl(ret, base, ofs);
1472
1473#if defined(TARGET_MIPS64)
1474    if (ctx->hflags & MIPS_HFLAG_AWRAP) {
1475        tcg_gen_ext32s_i64(ret, ret);
1476    }
1477#endif
1478}
1479
1480/* Addresses computation (translation time) */
1481static target_long addr_add(DisasContext *ctx, target_long base,
1482                            target_long offset)
1483{
1484    target_long sum = base + offset;
1485
1486#if defined(TARGET_MIPS64)
1487    if (ctx->hflags & MIPS_HFLAG_AWRAP) {
1488        sum = (int32_t)sum;
1489    }
1490#endif
1491    return sum;
1492}
1493
1494/* Sign-extract the low 32-bits to a target_long.  */
1495void gen_move_low32(TCGv ret, TCGv_i64 arg)
1496{
1497#if defined(TARGET_MIPS64)
1498    tcg_gen_ext32s_i64(ret, arg);
1499#else
1500    tcg_gen_extrl_i64_i32(ret, arg);
1501#endif
1502}
1503
1504/* Sign-extract the high 32-bits to a target_long.  */
1505void gen_move_high32(TCGv ret, TCGv_i64 arg)
1506{
1507#if defined(TARGET_MIPS64)
1508    tcg_gen_sari_i64(ret, arg, 32);
1509#else
1510    tcg_gen_extrh_i64_i32(ret, arg);
1511#endif
1512}
1513
1514bool check_cp0_enabled(DisasContext *ctx)
1515{
1516    if (unlikely(!(ctx->hflags & MIPS_HFLAG_CP0))) {
1517        generate_exception_end(ctx, EXCP_CpU);
1518        return false;
1519    }
1520    return true;
1521}
1522
1523void check_cp1_enabled(DisasContext *ctx)
1524{
1525    if (unlikely(!(ctx->hflags & MIPS_HFLAG_FPU))) {
1526        generate_exception_err(ctx, EXCP_CpU, 1);
1527    }
1528}
1529
1530/*
1531 * Verify that the processor is running with COP1X instructions enabled.
1532 * This is associated with the nabla symbol in the MIPS32 and MIPS64
1533 * opcode tables.
1534 */
1535void check_cop1x(DisasContext *ctx)
1536{
1537    if (unlikely(!(ctx->hflags & MIPS_HFLAG_COP1X))) {
1538        gen_reserved_instruction(ctx);
1539    }
1540}
1541
1542/*
1543 * Verify that the processor is running with 64-bit floating-point
1544 * operations enabled.
1545 */
1546void check_cp1_64bitmode(DisasContext *ctx)
1547{
1548    if (unlikely(~ctx->hflags & (MIPS_HFLAG_F64 | MIPS_HFLAG_COP1X))) {
1549        gen_reserved_instruction(ctx);
1550    }
1551}
1552
1553/*
1554 * Verify if floating point register is valid; an operation is not defined
1555 * if bit 0 of any register specification is set and the FR bit in the
1556 * Status register equals zero, since the register numbers specify an
1557 * even-odd pair of adjacent coprocessor general registers. When the FR bit
1558 * in the Status register equals one, both even and odd register numbers
1559 * are valid. This limitation exists only for 64 bit wide (d,l,ps) registers.
1560 *
1561 * Multiple 64 bit wide registers can be checked by calling
1562 * gen_op_cp1_registers(freg1 | freg2 | ... | fregN);
1563 */
1564void check_cp1_registers(DisasContext *ctx, int regs)
1565{
1566    if (unlikely(!(ctx->hflags & MIPS_HFLAG_F64) && (regs & 1))) {
1567        gen_reserved_instruction(ctx);
1568    }
1569}
1570
1571/*
1572 * Verify that the processor is running with DSP instructions enabled.
1573 * This is enabled by CP0 Status register MX(24) bit.
1574 */
1575static inline void check_dsp(DisasContext *ctx)
1576{
1577    if (unlikely(!(ctx->hflags & MIPS_HFLAG_DSP))) {
1578        if (ctx->insn_flags & ASE_DSP) {
1579            generate_exception_end(ctx, EXCP_DSPDIS);
1580        } else {
1581            gen_reserved_instruction(ctx);
1582        }
1583    }
1584}
1585
1586static inline void check_dsp_r2(DisasContext *ctx)
1587{
1588    if (unlikely(!(ctx->hflags & MIPS_HFLAG_DSP_R2))) {
1589        if (ctx->insn_flags & ASE_DSP) {
1590            generate_exception_end(ctx, EXCP_DSPDIS);
1591        } else {
1592            gen_reserved_instruction(ctx);
1593        }
1594    }
1595}
1596
1597static inline void check_dsp_r3(DisasContext *ctx)
1598{
1599    if (unlikely(!(ctx->hflags & MIPS_HFLAG_DSP_R3))) {
1600        if (ctx->insn_flags & ASE_DSP) {
1601            generate_exception_end(ctx, EXCP_DSPDIS);
1602        } else {
1603            gen_reserved_instruction(ctx);
1604        }
1605    }
1606}
1607
1608/*
1609 * This code generates a "reserved instruction" exception if the
1610 * CPU does not support the instruction set corresponding to flags.
1611 */
1612void check_insn(DisasContext *ctx, uint64_t flags)
1613{
1614    if (unlikely(!(ctx->insn_flags & flags))) {
1615        gen_reserved_instruction(ctx);
1616    }
1617}
1618
1619/*
1620 * This code generates a "reserved instruction" exception if the
1621 * CPU has corresponding flag set which indicates that the instruction
1622 * has been removed.
1623 */
1624static inline void check_insn_opc_removed(DisasContext *ctx, uint64_t flags)
1625{
1626    if (unlikely(ctx->insn_flags & flags)) {
1627        gen_reserved_instruction(ctx);
1628    }
1629}
1630
1631/*
1632 * The Linux kernel traps certain reserved instruction exceptions to
1633 * emulate the corresponding instructions. QEMU is the kernel in user
1634 * mode, so those traps are emulated by accepting the instructions.
1635 *
1636 * A reserved instruction exception is generated for flagged CPUs if
1637 * QEMU runs in system mode.
1638 */
1639static inline void check_insn_opc_user_only(DisasContext *ctx, uint64_t flags)
1640{
1641#ifndef CONFIG_USER_ONLY
1642    check_insn_opc_removed(ctx, flags);
1643#endif
1644}
1645
1646/*
1647 * This code generates a "reserved instruction" exception if the
1648 * CPU does not support 64-bit paired-single (PS) floating point data type.
1649 */
1650static inline void check_ps(DisasContext *ctx)
1651{
1652    if (unlikely(!ctx->ps)) {
1653        generate_exception(ctx, EXCP_RI);
1654    }
1655    check_cp1_64bitmode(ctx);
1656}
1657
1658/*
1659 * This code generates a "reserved instruction" exception if cpu is not
1660 * 64-bit or 64-bit instructions are not enabled.
1661 */
1662void check_mips_64(DisasContext *ctx)
1663{
1664    if (unlikely((TARGET_LONG_BITS != 64) || !(ctx->hflags & MIPS_HFLAG_64))) {
1665        gen_reserved_instruction(ctx);
1666    }
1667}
1668
1669#ifndef CONFIG_USER_ONLY
1670static inline void check_mvh(DisasContext *ctx)
1671{
1672    if (unlikely(!ctx->mvh)) {
1673        generate_exception(ctx, EXCP_RI);
1674    }
1675}
1676#endif
1677
1678/*
1679 * This code generates a "reserved instruction" exception if the
1680 * Config5 XNP bit is set.
1681 */
1682static inline void check_xnp(DisasContext *ctx)
1683{
1684    if (unlikely(ctx->CP0_Config5 & (1 << CP0C5_XNP))) {
1685        gen_reserved_instruction(ctx);
1686    }
1687}
1688
1689#ifndef CONFIG_USER_ONLY
1690/*
1691 * This code generates a "reserved instruction" exception if the
1692 * Config3 PW bit is NOT set.
1693 */
1694static inline void check_pw(DisasContext *ctx)
1695{
1696    if (unlikely(!(ctx->CP0_Config3 & (1 << CP0C3_PW)))) {
1697        gen_reserved_instruction(ctx);
1698    }
1699}
1700#endif
1701
1702/*
1703 * This code generates a "reserved instruction" exception if the
1704 * Config3 MT bit is NOT set.
1705 */
1706static inline void check_mt(DisasContext *ctx)
1707{
1708    if (unlikely(!(ctx->CP0_Config3 & (1 << CP0C3_MT)))) {
1709        gen_reserved_instruction(ctx);
1710    }
1711}
1712
1713#ifndef CONFIG_USER_ONLY
1714/*
1715 * This code generates a "coprocessor unusable" exception if CP0 is not
1716 * available, and, if that is not the case, generates a "reserved instruction"
1717 * exception if the Config5 MT bit is NOT set. This is needed for availability
1718 * control of some of MT ASE instructions.
1719 */
1720static inline void check_cp0_mt(DisasContext *ctx)
1721{
1722    if (unlikely(!(ctx->hflags & MIPS_HFLAG_CP0))) {
1723        generate_exception_end(ctx, EXCP_CpU);
1724    } else {
1725        if (unlikely(!(ctx->CP0_Config3 & (1 << CP0C3_MT)))) {
1726            gen_reserved_instruction(ctx);
1727        }
1728    }
1729}
1730#endif
1731
1732/*
1733 * This code generates a "reserved instruction" exception if the
1734 * Config5 NMS bit is set.
1735 */
1736static inline void check_nms(DisasContext *ctx)
1737{
1738    if (unlikely(ctx->CP0_Config5 & (1 << CP0C5_NMS))) {
1739        gen_reserved_instruction(ctx);
1740    }
1741}
1742
1743/*
1744 * This code generates a "reserved instruction" exception if the
1745 * Config5 NMS bit is set, and Config1 DL, Config1 IL, Config2 SL,
1746 * Config2 TL, and Config5 L2C are unset.
1747 */
1748static inline void check_nms_dl_il_sl_tl_l2c(DisasContext *ctx)
1749{
1750    if (unlikely((ctx->CP0_Config5 & (1 << CP0C5_NMS)) &&
1751                 !(ctx->CP0_Config1 & (1 << CP0C1_DL)) &&
1752                 !(ctx->CP0_Config1 & (1 << CP0C1_IL)) &&
1753                 !(ctx->CP0_Config2 & (1 << CP0C2_SL)) &&
1754                 !(ctx->CP0_Config2 & (1 << CP0C2_TL)) &&
1755                 !(ctx->CP0_Config5 & (1 << CP0C5_L2C)))) {
1756        gen_reserved_instruction(ctx);
1757    }
1758}
1759
1760/*
1761 * This code generates a "reserved instruction" exception if the
1762 * Config5 EVA bit is NOT set.
1763 */
1764static inline void check_eva(DisasContext *ctx)
1765{
1766    if (unlikely(!(ctx->CP0_Config5 & (1 << CP0C5_EVA)))) {
1767        gen_reserved_instruction(ctx);
1768    }
1769}
1770
1771
1772/*
1773 * Define small wrappers for gen_load_fpr* so that we have a uniform
1774 * calling interface for 32 and 64-bit FPRs.  No sense in changing
1775 * all callers for gen_load_fpr32 when we need the CTX parameter for
1776 * this one use.
1777 */
1778#define gen_ldcmp_fpr32(ctx, x, y) gen_load_fpr32(ctx, x, y)
1779#define gen_ldcmp_fpr64(ctx, x, y) gen_load_fpr64(ctx, x, y)
1780#define FOP_CONDS(type, abs, fmt, ifmt, bits)                                 \
1781static inline void gen_cmp ## type ## _ ## fmt(DisasContext *ctx, int n,      \
1782                                               int ft, int fs, int cc)        \
1783{                                                                             \
1784    TCGv_i##bits fp0 = tcg_temp_new_i##bits();                                \
1785    TCGv_i##bits fp1 = tcg_temp_new_i##bits();                                \
1786    switch (ifmt) {                                                           \
1787    case FMT_PS:                                                              \
1788        check_ps(ctx);                                                        \
1789        break;                                                                \
1790    case FMT_D:                                                               \
1791        if (abs) {                                                            \
1792            check_cop1x(ctx);                                                 \
1793        }                                                                     \
1794        check_cp1_registers(ctx, fs | ft);                                    \
1795        break;                                                                \
1796    case FMT_S:                                                               \
1797        if (abs) {                                                            \
1798            check_cop1x(ctx);                                                 \
1799        }                                                                     \
1800        break;                                                                \
1801    }                                                                         \
1802    gen_ldcmp_fpr##bits(ctx, fp0, fs);                                        \
1803    gen_ldcmp_fpr##bits(ctx, fp1, ft);                                        \
1804    switch (n) {                                                              \
1805    case  0:                                                                  \
1806        gen_helper_0e2i(cmp ## type ## _ ## fmt ## _f, fp0, fp1, cc);         \
1807    break;                                                                    \
1808    case  1:                                                                  \
1809        gen_helper_0e2i(cmp ## type ## _ ## fmt ## _un, fp0, fp1, cc);        \
1810    break;                                                                    \
1811    case  2:                                                                  \
1812        gen_helper_0e2i(cmp ## type ## _ ## fmt ## _eq, fp0, fp1, cc);        \
1813    break;                                                                    \
1814    case  3:                                                                  \
1815        gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ueq, fp0, fp1, cc);       \
1816    break;                                                                    \
1817    case  4:                                                                  \
1818        gen_helper_0e2i(cmp ## type ## _ ## fmt ## _olt, fp0, fp1, cc);       \
1819    break;                                                                    \
1820    case  5:                                                                  \
1821        gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ult, fp0, fp1, cc);       \
1822    break;                                                                    \
1823    case  6:                                                                  \
1824        gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ole, fp0, fp1, cc);       \
1825    break;                                                                    \
1826    case  7:                                                                  \
1827        gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ule, fp0, fp1, cc);       \
1828    break;                                                                    \
1829    case  8:                                                                  \
1830        gen_helper_0e2i(cmp ## type ## _ ## fmt ## _sf, fp0, fp1, cc);        \
1831    break;                                                                    \
1832    case  9:                                                                  \
1833        gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ngle, fp0, fp1, cc);      \
1834    break;                                                                    \
1835    case 10:                                                                  \
1836        gen_helper_0e2i(cmp ## type ## _ ## fmt ## _seq, fp0, fp1, cc);       \
1837    break;                                                                    \
1838    case 11:                                                                  \
1839        gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ngl, fp0, fp1, cc);       \
1840    break;                                                                    \
1841    case 12:                                                                  \
1842        gen_helper_0e2i(cmp ## type ## _ ## fmt ## _lt, fp0, fp1, cc);        \
1843    break;                                                                    \
1844    case 13:                                                                  \
1845        gen_helper_0e2i(cmp ## type ## _ ## fmt ## _nge, fp0, fp1, cc);       \
1846    break;                                                                    \
1847    case 14:                                                                  \
1848        gen_helper_0e2i(cmp ## type ## _ ## fmt ## _le, fp0, fp1, cc);        \
1849    break;                                                                    \
1850    case 15:                                                                  \
1851        gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ngt, fp0, fp1, cc);       \
1852    break;                                                                    \
1853    default:                                                                  \
1854        abort();                                                              \
1855    }                                                                         \
1856    tcg_temp_free_i##bits(fp0);                                               \
1857    tcg_temp_free_i##bits(fp1);                                               \
1858}
1859
1860FOP_CONDS(, 0, d, FMT_D, 64)
1861FOP_CONDS(abs, 1, d, FMT_D, 64)
1862FOP_CONDS(, 0, s, FMT_S, 32)
1863FOP_CONDS(abs, 1, s, FMT_S, 32)
1864FOP_CONDS(, 0, ps, FMT_PS, 64)
1865FOP_CONDS(abs, 1, ps, FMT_PS, 64)
1866#undef FOP_CONDS
1867
1868#define FOP_CONDNS(fmt, ifmt, bits, STORE)                              \
1869static inline void gen_r6_cmp_ ## fmt(DisasContext *ctx, int n,         \
1870                                      int ft, int fs, int fd)           \
1871{                                                                       \
1872    TCGv_i ## bits fp0 = tcg_temp_new_i ## bits();                      \
1873    TCGv_i ## bits fp1 = tcg_temp_new_i ## bits();                      \
1874    if (ifmt == FMT_D) {                                                \
1875        check_cp1_registers(ctx, fs | ft | fd);                         \
1876    }                                                                   \
1877    gen_ldcmp_fpr ## bits(ctx, fp0, fs);                                \
1878    gen_ldcmp_fpr ## bits(ctx, fp1, ft);                                \
1879    switch (n) {                                                        \
1880    case  0:                                                            \
1881        gen_helper_r6_cmp_ ## fmt ## _af(fp0, cpu_env, fp0, fp1);       \
1882        break;                                                          \
1883    case  1:                                                            \
1884        gen_helper_r6_cmp_ ## fmt ## _un(fp0, cpu_env, fp0, fp1);       \
1885        break;                                                          \
1886    case  2:                                                            \
1887        gen_helper_r6_cmp_ ## fmt ## _eq(fp0, cpu_env, fp0, fp1);       \
1888        break;                                                          \
1889    case  3:                                                            \
1890        gen_helper_r6_cmp_ ## fmt ## _ueq(fp0, cpu_env, fp0, fp1);      \
1891        break;                                                          \
1892    case  4:                                                            \
1893        gen_helper_r6_cmp_ ## fmt ## _lt(fp0, cpu_env, fp0, fp1);       \
1894        break;                                                          \
1895    case  5:                                                            \
1896        gen_helper_r6_cmp_ ## fmt ## _ult(fp0, cpu_env, fp0, fp1);      \
1897        break;                                                          \
1898    case  6:                                                            \
1899        gen_helper_r6_cmp_ ## fmt ## _le(fp0, cpu_env, fp0, fp1);       \
1900        break;                                                          \
1901    case  7:                                                            \
1902        gen_helper_r6_cmp_ ## fmt ## _ule(fp0, cpu_env, fp0, fp1);      \
1903        break;                                                          \
1904    case  8:                                                            \
1905        gen_helper_r6_cmp_ ## fmt ## _saf(fp0, cpu_env, fp0, fp1);      \
1906        break;                                                          \
1907    case  9:                                                            \
1908        gen_helper_r6_cmp_ ## fmt ## _sun(fp0, cpu_env, fp0, fp1);      \
1909        break;                                                          \
1910    case 10:                                                            \
1911        gen_helper_r6_cmp_ ## fmt ## _seq(fp0, cpu_env, fp0, fp1);      \
1912        break;                                                          \
1913    case 11:                                                            \
1914        gen_helper_r6_cmp_ ## fmt ## _sueq(fp0, cpu_env, fp0, fp1);     \
1915        break;                                                          \
1916    case 12:                                                            \
1917        gen_helper_r6_cmp_ ## fmt ## _slt(fp0, cpu_env, fp0, fp1);      \
1918        break;                                                          \
1919    case 13:                                                            \
1920        gen_helper_r6_cmp_ ## fmt ## _sult(fp0, cpu_env, fp0, fp1);     \
1921        break;                                                          \
1922    case 14:                                                            \
1923        gen_helper_r6_cmp_ ## fmt ## _sle(fp0, cpu_env, fp0, fp1);      \
1924        break;                                                          \
1925    case 15:                                                            \
1926        gen_helper_r6_cmp_ ## fmt ## _sule(fp0, cpu_env, fp0, fp1);     \
1927        break;                                                          \
1928    case 17:                                                            \
1929        gen_helper_r6_cmp_ ## fmt ## _or(fp0, cpu_env, fp0, fp1);       \
1930        break;                                                          \
1931    case 18:                                                            \
1932        gen_helper_r6_cmp_ ## fmt ## _une(fp0, cpu_env, fp0, fp1);      \
1933        break;                                                          \
1934    case 19:                                                            \
1935        gen_helper_r6_cmp_ ## fmt ## _ne(fp0, cpu_env, fp0, fp1);       \
1936        break;                                                          \
1937    case 25:                                                            \
1938        gen_helper_r6_cmp_ ## fmt ## _sor(fp0, cpu_env, fp0, fp1);      \
1939        break;                                                          \
1940    case 26:                                                            \
1941        gen_helper_r6_cmp_ ## fmt ## _sune(fp0, cpu_env, fp0, fp1);     \
1942        break;                                                          \
1943    case 27:                                                            \
1944        gen_helper_r6_cmp_ ## fmt ## _sne(fp0, cpu_env, fp0, fp1);      \
1945        break;                                                          \
1946    default:                                                            \
1947        abort();                                                        \
1948    }                                                                   \
1949    STORE;                                                              \
1950    tcg_temp_free_i ## bits(fp0);                                       \
1951    tcg_temp_free_i ## bits(fp1);                                       \
1952}
1953
1954FOP_CONDNS(d, FMT_D, 64, gen_store_fpr64(ctx, fp0, fd))
1955FOP_CONDNS(s, FMT_S, 32, gen_store_fpr32(ctx, fp0, fd))
1956#undef FOP_CONDNS
1957#undef gen_ldcmp_fpr32
1958#undef gen_ldcmp_fpr64
1959
1960/* load/store instructions. */
1961#ifdef CONFIG_USER_ONLY
1962#define OP_LD_ATOMIC(insn, fname)                                          \
1963static inline void op_ld_##insn(TCGv ret, TCGv arg1, int mem_idx,          \
1964                                DisasContext *ctx)                         \
1965{                                                                          \
1966    TCGv t0 = tcg_temp_new();                                              \
1967    tcg_gen_mov_tl(t0, arg1);                                              \
1968    tcg_gen_qemu_##fname(ret, arg1, ctx->mem_idx);                         \
1969    tcg_gen_st_tl(t0, cpu_env, offsetof(CPUMIPSState, lladdr));            \
1970    tcg_gen_st_tl(ret, cpu_env, offsetof(CPUMIPSState, llval));            \
1971    tcg_temp_free(t0);                                                     \
1972}
1973#else
1974#define OP_LD_ATOMIC(insn, fname)                                          \
1975static inline void op_ld_##insn(TCGv ret, TCGv arg1, int mem_idx,          \
1976                                DisasContext *ctx)                         \
1977{                                                                          \
1978    gen_helper_##insn(ret, cpu_env, arg1, tcg_constant_i32(mem_idx));      \
1979}
1980#endif
1981OP_LD_ATOMIC(ll, ld32s);
1982#if defined(TARGET_MIPS64)
1983OP_LD_ATOMIC(lld, ld64);
1984#endif
1985#undef OP_LD_ATOMIC
1986
1987void gen_base_offset_addr(DisasContext *ctx, TCGv addr, int base, int offset)
1988{
1989    if (base == 0) {
1990        tcg_gen_movi_tl(addr, offset);
1991    } else if (offset == 0) {
1992        gen_load_gpr(addr, base);
1993    } else {
1994        tcg_gen_movi_tl(addr, offset);
1995        gen_op_addr_add(ctx, addr, cpu_gpr[base], addr);
1996    }
1997}
1998
1999static target_ulong pc_relative_pc(DisasContext *ctx)
2000{
2001    target_ulong pc = ctx->base.pc_next;
2002
2003    if (ctx->hflags & MIPS_HFLAG_BMASK) {
2004        int branch_bytes = ctx->hflags & MIPS_HFLAG_BDS16 ? 2 : 4;
2005
2006        pc -= branch_bytes;
2007    }
2008
2009    pc &= ~(target_ulong)3;
2010    return pc;
2011}
2012
2013/* Load */
2014static void gen_ld(DisasContext *ctx, uint32_t opc,
2015                   int rt, int base, int offset)
2016{
2017    TCGv t0, t1, t2;
2018    int mem_idx = ctx->mem_idx;
2019
2020    if (rt == 0 && ctx->insn_flags & (INSN_LOONGSON2E | INSN_LOONGSON2F |
2021                                      INSN_LOONGSON3A)) {
2022        /*
2023         * Loongson CPU uses a load to zero register for prefetch.
2024         * We emulate it as a NOP. On other CPU we must perform the
2025         * actual memory access.
2026         */
2027        return;
2028    }
2029
2030    t0 = tcg_temp_new();
2031    gen_base_offset_addr(ctx, t0, base, offset);
2032
2033    switch (opc) {
2034#if defined(TARGET_MIPS64)
2035    case OPC_LWU:
2036        tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TEUL |
2037                           ctx->default_tcg_memop_mask);
2038        gen_store_gpr(t0, rt);
2039        break;
2040    case OPC_LD:
2041        tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TEUQ |
2042                           ctx->default_tcg_memop_mask);
2043        gen_store_gpr(t0, rt);
2044        break;
2045    case OPC_LLD:
2046    case R6_OPC_LLD:
2047        op_ld_lld(t0, t0, mem_idx, ctx);
2048        gen_store_gpr(t0, rt);
2049        break;
2050    case OPC_LDL:
2051        t1 = tcg_temp_new();
2052        /*
2053         * Do a byte access to possibly trigger a page
2054         * fault with the unaligned address.
2055         */
2056        tcg_gen_qemu_ld_tl(t1, t0, mem_idx, MO_UB);
2057        tcg_gen_andi_tl(t1, t0, 7);
2058        if (!cpu_is_bigendian(ctx)) {
2059            tcg_gen_xori_tl(t1, t1, 7);
2060        }
2061        tcg_gen_shli_tl(t1, t1, 3);
2062        tcg_gen_andi_tl(t0, t0, ~7);
2063        tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TEUQ);
2064        tcg_gen_shl_tl(t0, t0, t1);
2065        t2 = tcg_const_tl(-1);
2066        tcg_gen_shl_tl(t2, t2, t1);
2067        gen_load_gpr(t1, rt);
2068        tcg_gen_andc_tl(t1, t1, t2);
2069        tcg_temp_free(t2);
2070        tcg_gen_or_tl(t0, t0, t1);
2071        tcg_temp_free(t1);
2072        gen_store_gpr(t0, rt);
2073        break;
2074    case OPC_LDR:
2075        t1 = tcg_temp_new();
2076        /*
2077         * Do a byte access to possibly trigger a page
2078         * fault with the unaligned address.
2079         */
2080        tcg_gen_qemu_ld_tl(t1, t0, mem_idx, MO_UB);
2081        tcg_gen_andi_tl(t1, t0, 7);
2082        if (cpu_is_bigendian(ctx)) {
2083            tcg_gen_xori_tl(t1, t1, 7);
2084        }
2085        tcg_gen_shli_tl(t1, t1, 3);
2086        tcg_gen_andi_tl(t0, t0, ~7);
2087        tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TEUQ);
2088        tcg_gen_shr_tl(t0, t0, t1);
2089        tcg_gen_xori_tl(t1, t1, 63);
2090        t2 = tcg_const_tl(0xfffffffffffffffeull);
2091        tcg_gen_shl_tl(t2, t2, t1);
2092        gen_load_gpr(t1, rt);
2093        tcg_gen_and_tl(t1, t1, t2);
2094        tcg_temp_free(t2);
2095        tcg_gen_or_tl(t0, t0, t1);
2096        tcg_temp_free(t1);
2097        gen_store_gpr(t0, rt);
2098        break;
2099    case OPC_LDPC:
2100        t1 = tcg_const_tl(pc_relative_pc(ctx));
2101        gen_op_addr_add(ctx, t0, t0, t1);
2102        tcg_temp_free(t1);
2103        tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TEUQ);
2104        gen_store_gpr(t0, rt);
2105        break;
2106#endif
2107    case OPC_LWPC:
2108        t1 = tcg_const_tl(pc_relative_pc(ctx));
2109        gen_op_addr_add(ctx, t0, t0, t1);
2110        tcg_temp_free(t1);
2111        tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TESL);
2112        gen_store_gpr(t0, rt);
2113        break;
2114    case OPC_LWE:
2115        mem_idx = MIPS_HFLAG_UM;
2116        /* fall through */
2117    case OPC_LW:
2118        tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TESL |
2119                           ctx->default_tcg_memop_mask);
2120        gen_store_gpr(t0, rt);
2121        break;
2122    case OPC_LHE:
2123        mem_idx = MIPS_HFLAG_UM;
2124        /* fall through */
2125    case OPC_LH:
2126        tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TESW |
2127                           ctx->default_tcg_memop_mask);
2128        gen_store_gpr(t0, rt);
2129        break;
2130    case OPC_LHUE:
2131        mem_idx = MIPS_HFLAG_UM;
2132        /* fall through */
2133    case OPC_LHU:
2134        tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TEUW |
2135                           ctx->default_tcg_memop_mask);
2136        gen_store_gpr(t0, rt);
2137        break;
2138    case OPC_LBE:
2139        mem_idx = MIPS_HFLAG_UM;
2140        /* fall through */
2141    case OPC_LB:
2142        tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_SB);
2143        gen_store_gpr(t0, rt);
2144        break;
2145    case OPC_LBUE:
2146        mem_idx = MIPS_HFLAG_UM;
2147        /* fall through */
2148    case OPC_LBU:
2149        tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_UB);
2150        gen_store_gpr(t0, rt);
2151        break;
2152    case OPC_LWLE:
2153        mem_idx = MIPS_HFLAG_UM;
2154        /* fall through */
2155    case OPC_LWL:
2156        t1 = tcg_temp_new();
2157        /*
2158         * Do a byte access to possibly trigger a page
2159         * fault with the unaligned address.
2160         */
2161        tcg_gen_qemu_ld_tl(t1, t0, mem_idx, MO_UB);
2162        tcg_gen_andi_tl(t1, t0, 3);
2163        if (!cpu_is_bigendian(ctx)) {
2164            tcg_gen_xori_tl(t1, t1, 3);
2165        }
2166        tcg_gen_shli_tl(t1, t1, 3);
2167        tcg_gen_andi_tl(t0, t0, ~3);
2168        tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TEUL);
2169        tcg_gen_shl_tl(t0, t0, t1);
2170        t2 = tcg_const_tl(-1);
2171        tcg_gen_shl_tl(t2, t2, t1);
2172        gen_load_gpr(t1, rt);
2173        tcg_gen_andc_tl(t1, t1, t2);
2174        tcg_temp_free(t2);
2175        tcg_gen_or_tl(t0, t0, t1);
2176        tcg_temp_free(t1);
2177        tcg_gen_ext32s_tl(t0, t0);
2178        gen_store_gpr(t0, rt);
2179        break;
2180    case OPC_LWRE:
2181        mem_idx = MIPS_HFLAG_UM;
2182        /* fall through */
2183    case OPC_LWR:
2184        t1 = tcg_temp_new();
2185        /*
2186         * Do a byte access to possibly trigger a page
2187         * fault with the unaligned address.
2188         */
2189        tcg_gen_qemu_ld_tl(t1, t0, mem_idx, MO_UB);
2190        tcg_gen_andi_tl(t1, t0, 3);
2191        if (cpu_is_bigendian(ctx)) {
2192            tcg_gen_xori_tl(t1, t1, 3);
2193        }
2194        tcg_gen_shli_tl(t1, t1, 3);
2195        tcg_gen_andi_tl(t0, t0, ~3);
2196        tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TEUL);
2197        tcg_gen_shr_tl(t0, t0, t1);
2198        tcg_gen_xori_tl(t1, t1, 31);
2199        t2 = tcg_const_tl(0xfffffffeull);
2200        tcg_gen_shl_tl(t2, t2, t1);
2201        gen_load_gpr(t1, rt);
2202        tcg_gen_and_tl(t1, t1, t2);
2203        tcg_temp_free(t2);
2204        tcg_gen_or_tl(t0, t0, t1);
2205        tcg_temp_free(t1);
2206        tcg_gen_ext32s_tl(t0, t0);
2207        gen_store_gpr(t0, rt);
2208        break;
2209    case OPC_LLE:
2210        mem_idx = MIPS_HFLAG_UM;
2211        /* fall through */
2212    case OPC_LL:
2213    case R6_OPC_LL:
2214        op_ld_ll(t0, t0, mem_idx, ctx);
2215        gen_store_gpr(t0, rt);
2216        break;
2217    }
2218    tcg_temp_free(t0);
2219}
2220
2221/* Store */
2222static void gen_st(DisasContext *ctx, uint32_t opc, int rt,
2223                   int base, int offset)
2224{
2225    TCGv t0 = tcg_temp_new();
2226    TCGv t1 = tcg_temp_new();
2227    int mem_idx = ctx->mem_idx;
2228
2229    gen_base_offset_addr(ctx, t0, base, offset);
2230    gen_load_gpr(t1, rt);
2231    switch (opc) {
2232#if defined(TARGET_MIPS64)
2233    case OPC_SD:
2234        tcg_gen_qemu_st_tl(t1, t0, mem_idx, MO_TEUQ |
2235                           ctx->default_tcg_memop_mask);
2236        break;
2237    case OPC_SDL:
2238        gen_helper_0e2i(sdl, t1, t0, mem_idx);
2239        break;
2240    case OPC_SDR:
2241        gen_helper_0e2i(sdr, t1, t0, mem_idx);
2242        break;
2243#endif
2244    case OPC_SWE:
2245        mem_idx = MIPS_HFLAG_UM;
2246        /* fall through */
2247    case OPC_SW:
2248        tcg_gen_qemu_st_tl(t1, t0, mem_idx, MO_TEUL |
2249                           ctx->default_tcg_memop_mask);
2250        break;
2251    case OPC_SHE:
2252        mem_idx = MIPS_HFLAG_UM;
2253        /* fall through */
2254    case OPC_SH:
2255        tcg_gen_qemu_st_tl(t1, t0, mem_idx, MO_TEUW |
2256                           ctx->default_tcg_memop_mask);
2257        break;
2258    case OPC_SBE:
2259        mem_idx = MIPS_HFLAG_UM;
2260        /* fall through */
2261    case OPC_SB:
2262        tcg_gen_qemu_st_tl(t1, t0, mem_idx, MO_8);
2263        break;
2264    case OPC_SWLE:
2265        mem_idx = MIPS_HFLAG_UM;
2266        /* fall through */
2267    case OPC_SWL:
2268        gen_helper_0e2i(swl, t1, t0, mem_idx);
2269        break;
2270    case OPC_SWRE:
2271        mem_idx = MIPS_HFLAG_UM;
2272        /* fall through */
2273    case OPC_SWR:
2274        gen_helper_0e2i(swr, t1, t0, mem_idx);
2275        break;
2276    }
2277    tcg_temp_free(t0);
2278    tcg_temp_free(t1);
2279}
2280
2281
2282/* Store conditional */
2283static void gen_st_cond(DisasContext *ctx, int rt, int base, int offset,
2284                        MemOp tcg_mo, bool eva)
2285{
2286    TCGv addr, t0, val;
2287    TCGLabel *l1 = gen_new_label();
2288    TCGLabel *done = gen_new_label();
2289
2290    t0 = tcg_temp_new();
2291    addr = tcg_temp_new();
2292    /* compare the address against that of the preceding LL */
2293    gen_base_offset_addr(ctx, addr, base, offset);
2294    tcg_gen_brcond_tl(TCG_COND_EQ, addr, cpu_lladdr, l1);
2295    tcg_temp_free(addr);
2296    tcg_gen_movi_tl(t0, 0);
2297    gen_store_gpr(t0, rt);
2298    tcg_gen_br(done);
2299
2300    gen_set_label(l1);
2301    /* generate cmpxchg */
2302    val = tcg_temp_new();
2303    gen_load_gpr(val, rt);
2304    tcg_gen_atomic_cmpxchg_tl(t0, cpu_lladdr, cpu_llval, val,
2305                              eva ? MIPS_HFLAG_UM : ctx->mem_idx, tcg_mo);
2306    tcg_gen_setcond_tl(TCG_COND_EQ, t0, t0, cpu_llval);
2307    gen_store_gpr(t0, rt);
2308    tcg_temp_free(val);
2309
2310    gen_set_label(done);
2311    tcg_temp_free(t0);
2312}
2313
2314/* Load and store */
2315static void gen_flt_ldst(DisasContext *ctx, uint32_t opc, int ft,
2316                         TCGv t0)
2317{
2318    /*
2319     * Don't do NOP if destination is zero: we must perform the actual
2320     * memory access.
2321     */
2322    switch (opc) {
2323    case OPC_LWC1:
2324        {
2325            TCGv_i32 fp0 = tcg_temp_new_i32();
2326            tcg_gen_qemu_ld_i32(fp0, t0, ctx->mem_idx, MO_TESL |
2327                                ctx->default_tcg_memop_mask);
2328            gen_store_fpr32(ctx, fp0, ft);
2329            tcg_temp_free_i32(fp0);
2330        }
2331        break;
2332    case OPC_SWC1:
2333        {
2334            TCGv_i32 fp0 = tcg_temp_new_i32();
2335            gen_load_fpr32(ctx, fp0, ft);
2336            tcg_gen_qemu_st_i32(fp0, t0, ctx->mem_idx, MO_TEUL |
2337                                ctx->default_tcg_memop_mask);
2338            tcg_temp_free_i32(fp0);
2339        }
2340        break;
2341    case OPC_LDC1:
2342        {
2343            TCGv_i64 fp0 = tcg_temp_new_i64();
2344            tcg_gen_qemu_ld_i64(fp0, t0, ctx->mem_idx, MO_TEUQ |
2345                                ctx->default_tcg_memop_mask);
2346            gen_store_fpr64(ctx, fp0, ft);
2347            tcg_temp_free_i64(fp0);
2348        }
2349        break;
2350    case OPC_SDC1:
2351        {
2352            TCGv_i64 fp0 = tcg_temp_new_i64();
2353            gen_load_fpr64(ctx, fp0, ft);
2354            tcg_gen_qemu_st_i64(fp0, t0, ctx->mem_idx, MO_TEUQ |
2355                                ctx->default_tcg_memop_mask);
2356            tcg_temp_free_i64(fp0);
2357        }
2358        break;
2359    default:
2360        MIPS_INVAL("flt_ldst");
2361        gen_reserved_instruction(ctx);
2362        break;
2363    }
2364}
2365
2366static void gen_cop1_ldst(DisasContext *ctx, uint32_t op, int rt,
2367                          int rs, int16_t imm)
2368{
2369    TCGv t0 = tcg_temp_new();
2370
2371    if (ctx->CP0_Config1 & (1 << CP0C1_FP)) {
2372        check_cp1_enabled(ctx);
2373        switch (op) {
2374        case OPC_LDC1:
2375        case OPC_SDC1:
2376            check_insn(ctx, ISA_MIPS2);
2377            /* Fallthrough */
2378        default:
2379            gen_base_offset_addr(ctx, t0, rs, imm);
2380            gen_flt_ldst(ctx, op, rt, t0);
2381        }
2382    } else {
2383        generate_exception_err(ctx, EXCP_CpU, 1);
2384    }
2385    tcg_temp_free(t0);
2386}
2387
2388/* Arithmetic with immediate operand */
2389static void gen_arith_imm(DisasContext *ctx, uint32_t opc,
2390                          int rt, int rs, int imm)
2391{
2392    target_ulong uimm = (target_long)imm; /* Sign extend to 32/64 bits */
2393
2394    if (rt == 0 && opc != OPC_ADDI && opc != OPC_DADDI) {
2395        /*
2396         * If no destination, treat it as a NOP.
2397         * For addi, we must generate the overflow exception when needed.
2398         */
2399        return;
2400    }
2401    switch (opc) {
2402    case OPC_ADDI:
2403        {
2404            TCGv t0 = tcg_temp_local_new();
2405            TCGv t1 = tcg_temp_new();
2406            TCGv t2 = tcg_temp_new();
2407            TCGLabel *l1 = gen_new_label();
2408
2409            gen_load_gpr(t1, rs);
2410            tcg_gen_addi_tl(t0, t1, uimm);
2411            tcg_gen_ext32s_tl(t0, t0);
2412
2413            tcg_gen_xori_tl(t1, t1, ~uimm);
2414            tcg_gen_xori_tl(t2, t0, uimm);
2415            tcg_gen_and_tl(t1, t1, t2);
2416            tcg_temp_free(t2);
2417            tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
2418            tcg_temp_free(t1);
2419            /* operands of same sign, result different sign */
2420            generate_exception(ctx, EXCP_OVERFLOW);
2421            gen_set_label(l1);
2422            tcg_gen_ext32s_tl(t0, t0);
2423            gen_store_gpr(t0, rt);
2424            tcg_temp_free(t0);
2425        }
2426        break;
2427    case OPC_ADDIU:
2428        if (rs != 0) {
2429            tcg_gen_addi_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
2430            tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
2431        } else {
2432            tcg_gen_movi_tl(cpu_gpr[rt], uimm);
2433        }
2434        break;
2435#if defined(TARGET_MIPS64)
2436    case OPC_DADDI:
2437        {
2438            TCGv t0 = tcg_temp_local_new();
2439            TCGv t1 = tcg_temp_new();
2440            TCGv t2 = tcg_temp_new();
2441            TCGLabel *l1 = gen_new_label();
2442
2443            gen_load_gpr(t1, rs);
2444            tcg_gen_addi_tl(t0, t1, uimm);
2445
2446            tcg_gen_xori_tl(t1, t1, ~uimm);
2447            tcg_gen_xori_tl(t2, t0, uimm);
2448            tcg_gen_and_tl(t1, t1, t2);
2449            tcg_temp_free(t2);
2450            tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
2451            tcg_temp_free(t1);
2452            /* operands of same sign, result different sign */
2453            generate_exception(ctx, EXCP_OVERFLOW);
2454            gen_set_label(l1);
2455            gen_store_gpr(t0, rt);
2456            tcg_temp_free(t0);
2457        }
2458        break;
2459    case OPC_DADDIU:
2460        if (rs != 0) {
2461            tcg_gen_addi_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
2462        } else {
2463            tcg_gen_movi_tl(cpu_gpr[rt], uimm);
2464        }
2465        break;
2466#endif
2467    }
2468}
2469
2470/* Logic with immediate operand */
2471static void gen_logic_imm(DisasContext *ctx, uint32_t opc,
2472                          int rt, int rs, int16_t imm)
2473{
2474    target_ulong uimm;
2475
2476    if (rt == 0) {
2477        /* If no destination, treat it as a NOP. */
2478        return;
2479    }
2480    uimm = (uint16_t)imm;
2481    switch (opc) {
2482    case OPC_ANDI:
2483        if (likely(rs != 0)) {
2484            tcg_gen_andi_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
2485        } else {
2486            tcg_gen_movi_tl(cpu_gpr[rt], 0);
2487        }
2488        break;
2489    case OPC_ORI:
2490        if (rs != 0) {
2491            tcg_gen_ori_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
2492        } else {
2493            tcg_gen_movi_tl(cpu_gpr[rt], uimm);
2494        }
2495        break;
2496    case OPC_XORI:
2497        if (likely(rs != 0)) {
2498            tcg_gen_xori_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
2499        } else {
2500            tcg_gen_movi_tl(cpu_gpr[rt], uimm);
2501        }
2502        break;
2503    case OPC_LUI:
2504        if (rs != 0 && (ctx->insn_flags & ISA_MIPS_R6)) {
2505            /* OPC_AUI */
2506            tcg_gen_addi_tl(cpu_gpr[rt], cpu_gpr[rs], imm << 16);
2507            tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
2508        } else {
2509            tcg_gen_movi_tl(cpu_gpr[rt], imm << 16);
2510        }
2511        break;
2512
2513    default:
2514        break;
2515    }
2516}
2517
2518/* Set on less than with immediate operand */
2519static void gen_slt_imm(DisasContext *ctx, uint32_t opc,
2520                        int rt, int rs, int16_t imm)
2521{
2522    target_ulong uimm = (target_long)imm; /* Sign extend to 32/64 bits */
2523    TCGv t0;
2524
2525    if (rt == 0) {
2526        /* If no destination, treat it as a NOP. */
2527        return;
2528    }
2529    t0 = tcg_temp_new();
2530    gen_load_gpr(t0, rs);
2531    switch (opc) {
2532    case OPC_SLTI:
2533        tcg_gen_setcondi_tl(TCG_COND_LT, cpu_gpr[rt], t0, uimm);
2534        break;
2535    case OPC_SLTIU:
2536        tcg_gen_setcondi_tl(TCG_COND_LTU, cpu_gpr[rt], t0, uimm);
2537        break;
2538    }
2539    tcg_temp_free(t0);
2540}
2541
2542/* Shifts with immediate operand */
2543static void gen_shift_imm(DisasContext *ctx, uint32_t opc,
2544                          int rt, int rs, int16_t imm)
2545{
2546    target_ulong uimm = ((uint16_t)imm) & 0x1f;
2547    TCGv t0;
2548
2549    if (rt == 0) {
2550        /* If no destination, treat it as a NOP. */
2551        return;
2552    }
2553
2554    t0 = tcg_temp_new();
2555    gen_load_gpr(t0, rs);
2556    switch (opc) {
2557    case OPC_SLL:
2558        tcg_gen_shli_tl(t0, t0, uimm);
2559        tcg_gen_ext32s_tl(cpu_gpr[rt], t0);
2560        break;
2561    case OPC_SRA:
2562        tcg_gen_sari_tl(cpu_gpr[rt], t0, uimm);
2563        break;
2564    case OPC_SRL:
2565        if (uimm != 0) {
2566            tcg_gen_ext32u_tl(t0, t0);
2567            tcg_gen_shri_tl(cpu_gpr[rt], t0, uimm);
2568        } else {
2569            tcg_gen_ext32s_tl(cpu_gpr[rt], t0);
2570        }
2571        break;
2572    case OPC_ROTR:
2573        if (uimm != 0) {
2574            TCGv_i32 t1 = tcg_temp_new_i32();
2575
2576            tcg_gen_trunc_tl_i32(t1, t0);
2577            tcg_gen_rotri_i32(t1, t1, uimm);
2578            tcg_gen_ext_i32_tl(cpu_gpr[rt], t1);
2579            tcg_temp_free_i32(t1);
2580        } else {
2581            tcg_gen_ext32s_tl(cpu_gpr[rt], t0);
2582        }
2583        break;
2584#if defined(TARGET_MIPS64)
2585    case OPC_DSLL:
2586        tcg_gen_shli_tl(cpu_gpr[rt], t0, uimm);
2587        break;
2588    case OPC_DSRA:
2589        tcg_gen_sari_tl(cpu_gpr[rt], t0, uimm);
2590        break;
2591    case OPC_DSRL:
2592        tcg_gen_shri_tl(cpu_gpr[rt], t0, uimm);
2593        break;
2594    case OPC_DROTR:
2595        if (uimm != 0) {
2596            tcg_gen_rotri_tl(cpu_gpr[rt], t0, uimm);
2597        } else {
2598            tcg_gen_mov_tl(cpu_gpr[rt], t0);
2599        }
2600        break;
2601    case OPC_DSLL32:
2602        tcg_gen_shli_tl(cpu_gpr[rt], t0, uimm + 32);
2603        break;
2604    case OPC_DSRA32:
2605        tcg_gen_sari_tl(cpu_gpr[rt], t0, uimm + 32);
2606        break;
2607    case OPC_DSRL32:
2608        tcg_gen_shri_tl(cpu_gpr[rt], t0, uimm + 32);
2609        break;
2610    case OPC_DROTR32:
2611        tcg_gen_rotri_tl(cpu_gpr[rt], t0, uimm + 32);
2612        break;
2613#endif
2614    }
2615    tcg_temp_free(t0);
2616}
2617
2618/* Arithmetic */
2619static void gen_arith(DisasContext *ctx, uint32_t opc,
2620                      int rd, int rs, int rt)
2621{
2622    if (rd == 0 && opc != OPC_ADD && opc != OPC_SUB
2623       && opc != OPC_DADD && opc != OPC_DSUB) {
2624        /*
2625         * If no destination, treat it as a NOP.
2626         * For add & sub, we must generate the overflow exception when needed.
2627         */
2628        return;
2629    }
2630
2631    switch (opc) {
2632    case OPC_ADD:
2633        {
2634            TCGv t0 = tcg_temp_local_new();
2635            TCGv t1 = tcg_temp_new();
2636            TCGv t2 = tcg_temp_new();
2637            TCGLabel *l1 = gen_new_label();
2638
2639            gen_load_gpr(t1, rs);
2640            gen_load_gpr(t2, rt);
2641            tcg_gen_add_tl(t0, t1, t2);
2642            tcg_gen_ext32s_tl(t0, t0);
2643            tcg_gen_xor_tl(t1, t1, t2);
2644            tcg_gen_xor_tl(t2, t0, t2);
2645            tcg_gen_andc_tl(t1, t2, t1);
2646            tcg_temp_free(t2);
2647            tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
2648            tcg_temp_free(t1);
2649            /* operands of same sign, result different sign */
2650            generate_exception(ctx, EXCP_OVERFLOW);
2651            gen_set_label(l1);
2652            gen_store_gpr(t0, rd);
2653            tcg_temp_free(t0);
2654        }
2655        break;
2656    case OPC_ADDU:
2657        if (rs != 0 && rt != 0) {
2658            tcg_gen_add_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2659            tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
2660        } else if (rs == 0 && rt != 0) {
2661            tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
2662        } else if (rs != 0 && rt == 0) {
2663            tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
2664        } else {
2665            tcg_gen_movi_tl(cpu_gpr[rd], 0);
2666        }
2667        break;
2668    case OPC_SUB:
2669        {
2670            TCGv t0 = tcg_temp_local_new();
2671            TCGv t1 = tcg_temp_new();
2672            TCGv t2 = tcg_temp_new();
2673            TCGLabel *l1 = gen_new_label();
2674
2675            gen_load_gpr(t1, rs);
2676            gen_load_gpr(t2, rt);
2677            tcg_gen_sub_tl(t0, t1, t2);
2678            tcg_gen_ext32s_tl(t0, t0);
2679            tcg_gen_xor_tl(t2, t1, t2);
2680            tcg_gen_xor_tl(t1, t0, t1);
2681            tcg_gen_and_tl(t1, t1, t2);
2682            tcg_temp_free(t2);
2683            tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
2684            tcg_temp_free(t1);
2685            /*
2686             * operands of different sign, first operand and the result
2687             * of different sign
2688             */
2689            generate_exception(ctx, EXCP_OVERFLOW);
2690            gen_set_label(l1);
2691            gen_store_gpr(t0, rd);
2692            tcg_temp_free(t0);
2693        }
2694        break;
2695    case OPC_SUBU:
2696        if (rs != 0 && rt != 0) {
2697            tcg_gen_sub_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2698            tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
2699        } else if (rs == 0 && rt != 0) {
2700            tcg_gen_neg_tl(cpu_gpr[rd], cpu_gpr[rt]);
2701            tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
2702        } else if (rs != 0 && rt == 0) {
2703            tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
2704        } else {
2705            tcg_gen_movi_tl(cpu_gpr[rd], 0);
2706        }
2707        break;
2708#if defined(TARGET_MIPS64)
2709    case OPC_DADD:
2710        {
2711            TCGv t0 = tcg_temp_local_new();
2712            TCGv t1 = tcg_temp_new();
2713            TCGv t2 = tcg_temp_new();
2714            TCGLabel *l1 = gen_new_label();
2715
2716            gen_load_gpr(t1, rs);
2717            gen_load_gpr(t2, rt);
2718            tcg_gen_add_tl(t0, t1, t2);
2719            tcg_gen_xor_tl(t1, t1, t2);
2720            tcg_gen_xor_tl(t2, t0, t2);
2721            tcg_gen_andc_tl(t1, t2, t1);
2722            tcg_temp_free(t2);
2723            tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
2724            tcg_temp_free(t1);
2725            /* operands of same sign, result different sign */
2726            generate_exception(ctx, EXCP_OVERFLOW);
2727            gen_set_label(l1);
2728            gen_store_gpr(t0, rd);
2729            tcg_temp_free(t0);
2730        }
2731        break;
2732    case OPC_DADDU:
2733        if (rs != 0 && rt != 0) {
2734            tcg_gen_add_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2735        } else if (rs == 0 && rt != 0) {
2736            tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
2737        } else if (rs != 0 && rt == 0) {
2738            tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
2739        } else {
2740            tcg_gen_movi_tl(cpu_gpr[rd], 0);
2741        }
2742        break;
2743    case OPC_DSUB:
2744        {
2745            TCGv t0 = tcg_temp_local_new();
2746            TCGv t1 = tcg_temp_new();
2747            TCGv t2 = tcg_temp_new();
2748            TCGLabel *l1 = gen_new_label();
2749
2750            gen_load_gpr(t1, rs);
2751            gen_load_gpr(t2, rt);
2752            tcg_gen_sub_tl(t0, t1, t2);
2753            tcg_gen_xor_tl(t2, t1, t2);
2754            tcg_gen_xor_tl(t1, t0, t1);
2755            tcg_gen_and_tl(t1, t1, t2);
2756            tcg_temp_free(t2);
2757            tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
2758            tcg_temp_free(t1);
2759            /*
2760             * Operands of different sign, first operand and result different
2761             * sign.
2762             */
2763            generate_exception(ctx, EXCP_OVERFLOW);
2764            gen_set_label(l1);
2765            gen_store_gpr(t0, rd);
2766            tcg_temp_free(t0);
2767        }
2768        break;
2769    case OPC_DSUBU:
2770        if (rs != 0 && rt != 0) {
2771            tcg_gen_sub_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2772        } else if (rs == 0 && rt != 0) {
2773            tcg_gen_neg_tl(cpu_gpr[rd], cpu_gpr[rt]);
2774        } else if (rs != 0 && rt == 0) {
2775            tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
2776        } else {
2777            tcg_gen_movi_tl(cpu_gpr[rd], 0);
2778        }
2779        break;
2780#endif
2781    case OPC_MUL:
2782        if (likely(rs != 0 && rt != 0)) {
2783            tcg_gen_mul_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2784            tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
2785        } else {
2786            tcg_gen_movi_tl(cpu_gpr[rd], 0);
2787        }
2788        break;
2789    }
2790}
2791
2792/* Conditional move */
2793static void gen_cond_move(DisasContext *ctx, uint32_t opc,
2794                          int rd, int rs, int rt)
2795{
2796    TCGv t0, t1, t2;
2797
2798    if (rd == 0) {
2799        /* If no destination, treat it as a NOP. */
2800        return;
2801    }
2802
2803    t0 = tcg_temp_new();
2804    gen_load_gpr(t0, rt);
2805    t1 = tcg_const_tl(0);
2806    t2 = tcg_temp_new();
2807    gen_load_gpr(t2, rs);
2808    switch (opc) {
2809    case OPC_MOVN:
2810        tcg_gen_movcond_tl(TCG_COND_NE, cpu_gpr[rd], t0, t1, t2, cpu_gpr[rd]);
2811        break;
2812    case OPC_MOVZ:
2813        tcg_gen_movcond_tl(TCG_COND_EQ, cpu_gpr[rd], t0, t1, t2, cpu_gpr[rd]);
2814        break;
2815    case OPC_SELNEZ:
2816        tcg_gen_movcond_tl(TCG_COND_NE, cpu_gpr[rd], t0, t1, t2, t1);
2817        break;
2818    case OPC_SELEQZ:
2819        tcg_gen_movcond_tl(TCG_COND_EQ, cpu_gpr[rd], t0, t1, t2, t1);
2820        break;
2821    }
2822    tcg_temp_free(t2);
2823    tcg_temp_free(t1);
2824    tcg_temp_free(t0);
2825}
2826
2827/* Logic */
2828static void gen_logic(DisasContext *ctx, uint32_t opc,
2829                      int rd, int rs, int rt)
2830{
2831    if (rd == 0) {
2832        /* If no destination, treat it as a NOP. */
2833        return;
2834    }
2835
2836    switch (opc) {
2837    case OPC_AND:
2838        if (likely(rs != 0 && rt != 0)) {
2839            tcg_gen_and_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2840        } else {
2841            tcg_gen_movi_tl(cpu_gpr[rd], 0);
2842        }
2843        break;
2844    case OPC_NOR:
2845        if (rs != 0 && rt != 0) {
2846            tcg_gen_nor_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2847        } else if (rs == 0 && rt != 0) {
2848            tcg_gen_not_tl(cpu_gpr[rd], cpu_gpr[rt]);
2849        } else if (rs != 0 && rt == 0) {
2850            tcg_gen_not_tl(cpu_gpr[rd], cpu_gpr[rs]);
2851        } else {
2852            tcg_gen_movi_tl(cpu_gpr[rd], ~((target_ulong)0));
2853        }
2854        break;
2855    case OPC_OR:
2856        if (likely(rs != 0 && rt != 0)) {
2857            tcg_gen_or_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2858        } else if (rs == 0 && rt != 0) {
2859            tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
2860        } else if (rs != 0 && rt == 0) {
2861            tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
2862        } else {
2863            tcg_gen_movi_tl(cpu_gpr[rd], 0);
2864        }
2865        break;
2866    case OPC_XOR:
2867        if (likely(rs != 0 && rt != 0)) {
2868            tcg_gen_xor_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2869        } else if (rs == 0 && rt != 0) {
2870            tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
2871        } else if (rs != 0 && rt == 0) {
2872            tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
2873        } else {
2874            tcg_gen_movi_tl(cpu_gpr[rd], 0);
2875        }
2876        break;
2877    }
2878}
2879
2880/* Set on lower than */
2881static void gen_slt(DisasContext *ctx, uint32_t opc,
2882                    int rd, int rs, int rt)
2883{
2884    TCGv t0, t1;
2885
2886    if (rd == 0) {
2887        /* If no destination, treat it as a NOP. */
2888        return;
2889    }
2890
2891    t0 = tcg_temp_new();
2892    t1 = tcg_temp_new();
2893    gen_load_gpr(t0, rs);
2894    gen_load_gpr(t1, rt);
2895    switch (opc) {
2896    case OPC_SLT:
2897        tcg_gen_setcond_tl(TCG_COND_LT, cpu_gpr[rd], t0, t1);
2898        break;
2899    case OPC_SLTU:
2900        tcg_gen_setcond_tl(TCG_COND_LTU, cpu_gpr[rd], t0, t1);
2901        break;
2902    }
2903    tcg_temp_free(t0);
2904    tcg_temp_free(t1);
2905}
2906
2907/* Shifts */
2908static void gen_shift(DisasContext *ctx, uint32_t opc,
2909                      int rd, int rs, int rt)
2910{
2911    TCGv t0, t1;
2912
2913    if (rd == 0) {
2914        /*
2915         * If no destination, treat it as a NOP.
2916         * For add & sub, we must generate the overflow exception when needed.
2917         */
2918        return;
2919    }
2920
2921    t0 = tcg_temp_new();
2922    t1 = tcg_temp_new();
2923    gen_load_gpr(t0, rs);
2924    gen_load_gpr(t1, rt);
2925    switch (opc) {
2926    case OPC_SLLV:
2927        tcg_gen_andi_tl(t0, t0, 0x1f);
2928        tcg_gen_shl_tl(t0, t1, t0);
2929        tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
2930        break;
2931    case OPC_SRAV:
2932        tcg_gen_andi_tl(t0, t0, 0x1f);
2933        tcg_gen_sar_tl(cpu_gpr[rd], t1, t0);
2934        break;
2935    case OPC_SRLV:
2936        tcg_gen_ext32u_tl(t1, t1);
2937        tcg_gen_andi_tl(t0, t0, 0x1f);
2938        tcg_gen_shr_tl(t0, t1, t0);
2939        tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
2940        break;
2941    case OPC_ROTRV:
2942        {
2943            TCGv_i32 t2 = tcg_temp_new_i32();
2944            TCGv_i32 t3 = tcg_temp_new_i32();
2945
2946            tcg_gen_trunc_tl_i32(t2, t0);
2947            tcg_gen_trunc_tl_i32(t3, t1);
2948            tcg_gen_andi_i32(t2, t2, 0x1f);
2949            tcg_gen_rotr_i32(t2, t3, t2);
2950            tcg_gen_ext_i32_tl(cpu_gpr[rd], t2);
2951            tcg_temp_free_i32(t2);
2952            tcg_temp_free_i32(t3);
2953        }
2954        break;
2955#if defined(TARGET_MIPS64)
2956    case OPC_DSLLV:
2957        tcg_gen_andi_tl(t0, t0, 0x3f);
2958        tcg_gen_shl_tl(cpu_gpr[rd], t1, t0);
2959        break;
2960    case OPC_DSRAV:
2961        tcg_gen_andi_tl(t0, t0, 0x3f);
2962        tcg_gen_sar_tl(cpu_gpr[rd], t1, t0);
2963        break;
2964    case OPC_DSRLV:
2965        tcg_gen_andi_tl(t0, t0, 0x3f);
2966        tcg_gen_shr_tl(cpu_gpr[rd], t1, t0);
2967        break;
2968    case OPC_DROTRV:
2969        tcg_gen_andi_tl(t0, t0, 0x3f);
2970        tcg_gen_rotr_tl(cpu_gpr[rd], t1, t0);
2971        break;
2972#endif
2973    }
2974    tcg_temp_free(t0);
2975    tcg_temp_free(t1);
2976}
2977
2978/* Arithmetic on HI/LO registers */
2979static void gen_HILO(DisasContext *ctx, uint32_t opc, int acc, int reg)
2980{
2981    if (reg == 0 && (opc == OPC_MFHI || opc == OPC_MFLO)) {
2982        /* Treat as NOP. */
2983        return;
2984    }
2985
2986    if (acc != 0) {
2987        check_dsp(ctx);
2988    }
2989
2990    switch (opc) {
2991    case OPC_MFHI:
2992#if defined(TARGET_MIPS64)
2993        if (acc != 0) {
2994            tcg_gen_ext32s_tl(cpu_gpr[reg], cpu_HI[acc]);
2995        } else
2996#endif
2997        {
2998            tcg_gen_mov_tl(cpu_gpr[reg], cpu_HI[acc]);
2999        }
3000        break;
3001    case OPC_MFLO:
3002#if defined(TARGET_MIPS64)
3003        if (acc != 0) {
3004            tcg_gen_ext32s_tl(cpu_gpr[reg], cpu_LO[acc]);
3005        } else
3006#endif
3007        {
3008            tcg_gen_mov_tl(cpu_gpr[reg], cpu_LO[acc]);
3009        }
3010        break;
3011    case OPC_MTHI:
3012        if (reg != 0) {
3013#if defined(TARGET_MIPS64)
3014            if (acc != 0) {
3015                tcg_gen_ext32s_tl(cpu_HI[acc], cpu_gpr[reg]);
3016            } else
3017#endif
3018            {
3019                tcg_gen_mov_tl(cpu_HI[acc], cpu_gpr[reg]);
3020            }
3021        } else {
3022            tcg_gen_movi_tl(cpu_HI[acc], 0);
3023        }
3024        break;
3025    case OPC_MTLO:
3026        if (reg != 0) {
3027#if defined(TARGET_MIPS64)
3028            if (acc != 0) {
3029                tcg_gen_ext32s_tl(cpu_LO[acc], cpu_gpr[reg]);
3030            } else
3031#endif
3032            {
3033                tcg_gen_mov_tl(cpu_LO[acc], cpu_gpr[reg]);
3034            }
3035        } else {
3036            tcg_gen_movi_tl(cpu_LO[acc], 0);
3037        }
3038        break;
3039    }
3040}
3041
3042static inline void gen_r6_ld(target_long addr, int reg, int memidx,
3043                             MemOp memop)
3044{
3045    TCGv t0 = tcg_const_tl(addr);
3046    tcg_gen_qemu_ld_tl(t0, t0, memidx, memop);
3047    gen_store_gpr(t0, reg);
3048    tcg_temp_free(t0);
3049}
3050
3051static inline void gen_pcrel(DisasContext *ctx, int opc, target_ulong pc,
3052                             int rs)
3053{
3054    target_long offset;
3055    target_long addr;
3056
3057    switch (MASK_OPC_PCREL_TOP2BITS(opc)) {
3058    case OPC_ADDIUPC:
3059        if (rs != 0) {
3060            offset = sextract32(ctx->opcode << 2, 0, 21);
3061            addr = addr_add(ctx, pc, offset);
3062            tcg_gen_movi_tl(cpu_gpr[rs], addr);
3063        }
3064        break;
3065    case R6_OPC_LWPC:
3066        offset = sextract32(ctx->opcode << 2, 0, 21);
3067        addr = addr_add(ctx, pc, offset);
3068        gen_r6_ld(addr, rs, ctx->mem_idx, MO_TESL);
3069        break;
3070#if defined(TARGET_MIPS64)
3071    case OPC_LWUPC:
3072        check_mips_64(ctx);
3073        offset = sextract32(ctx->opcode << 2, 0, 21);
3074        addr = addr_add(ctx, pc, offset);
3075        gen_r6_ld(addr, rs, ctx->mem_idx, MO_TEUL);
3076        break;
3077#endif
3078    default:
3079        switch (MASK_OPC_PCREL_TOP5BITS(opc)) {
3080        case OPC_AUIPC:
3081            if (rs != 0) {
3082                offset = sextract32(ctx->opcode, 0, 16) << 16;
3083                addr = addr_add(ctx, pc, offset);
3084                tcg_gen_movi_tl(cpu_gpr[rs], addr);
3085            }
3086            break;
3087        case OPC_ALUIPC:
3088            if (rs != 0) {
3089                offset = sextract32(ctx->opcode, 0, 16) << 16;
3090                addr = ~0xFFFF & addr_add(ctx, pc, offset);
3091                tcg_gen_movi_tl(cpu_gpr[rs], addr);
3092            }
3093            break;
3094#if defined(TARGET_MIPS64)
3095        case R6_OPC_LDPC: /* bits 16 and 17 are part of immediate */
3096        case R6_OPC_LDPC + (1 << 16):
3097        case R6_OPC_LDPC + (2 << 16):
3098        case R6_OPC_LDPC + (3 << 16):
3099            check_mips_64(ctx);
3100            offset = sextract32(ctx->opcode << 3, 0, 21);
3101            addr = addr_add(ctx, (pc & ~0x7), offset);
3102            gen_r6_ld(addr, rs, ctx->mem_idx, MO_TEUQ);
3103            break;
3104#endif
3105        default:
3106            MIPS_INVAL("OPC_PCREL");
3107            gen_reserved_instruction(ctx);
3108            break;
3109        }
3110        break;
3111    }
3112}
3113
3114static void gen_r6_muldiv(DisasContext *ctx, int opc, int rd, int rs, int rt)
3115{
3116    TCGv t0, t1;
3117
3118    if (rd == 0) {
3119        /* Treat as NOP. */
3120        return;
3121    }
3122
3123    t0 = tcg_temp_new();
3124    t1 = tcg_temp_new();
3125
3126    gen_load_gpr(t0, rs);
3127    gen_load_gpr(t1, rt);
3128
3129    switch (opc) {
3130    case R6_OPC_DIV:
3131        {
3132            TCGv t2 = tcg_temp_new();
3133            TCGv t3 = tcg_temp_new();
3134            tcg_gen_ext32s_tl(t0, t0);
3135            tcg_gen_ext32s_tl(t1, t1);
3136            tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, INT_MIN);
3137            tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1);
3138            tcg_gen_and_tl(t2, t2, t3);
3139            tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
3140            tcg_gen_or_tl(t2, t2, t3);
3141            tcg_gen_movi_tl(t3, 0);
3142            tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
3143            tcg_gen_div_tl(cpu_gpr[rd], t0, t1);
3144            tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3145            tcg_temp_free(t3);
3146            tcg_temp_free(t2);
3147        }
3148        break;
3149    case R6_OPC_MOD:
3150        {
3151            TCGv t2 = tcg_temp_new();
3152            TCGv t3 = tcg_temp_new();
3153            tcg_gen_ext32s_tl(t0, t0);
3154            tcg_gen_ext32s_tl(t1, t1);
3155            tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, INT_MIN);
3156            tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1);
3157            tcg_gen_and_tl(t2, t2, t3);
3158            tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
3159            tcg_gen_or_tl(t2, t2, t3);
3160            tcg_gen_movi_tl(t3, 0);
3161            tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
3162            tcg_gen_rem_tl(cpu_gpr[rd], t0, t1);
3163            tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3164            tcg_temp_free(t3);
3165            tcg_temp_free(t2);
3166        }
3167        break;
3168    case R6_OPC_DIVU:
3169        {
3170            TCGv t2 = tcg_const_tl(0);
3171            TCGv t3 = tcg_const_tl(1);
3172            tcg_gen_ext32u_tl(t0, t0);
3173            tcg_gen_ext32u_tl(t1, t1);
3174            tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
3175            tcg_gen_divu_tl(cpu_gpr[rd], t0, t1);
3176            tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3177            tcg_temp_free(t3);
3178            tcg_temp_free(t2);
3179        }
3180        break;
3181    case R6_OPC_MODU:
3182        {
3183            TCGv t2 = tcg_const_tl(0);
3184            TCGv t3 = tcg_const_tl(1);
3185            tcg_gen_ext32u_tl(t0, t0);
3186            tcg_gen_ext32u_tl(t1, t1);
3187            tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
3188            tcg_gen_remu_tl(cpu_gpr[rd], t0, t1);
3189            tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3190            tcg_temp_free(t3);
3191            tcg_temp_free(t2);
3192        }
3193        break;
3194    case R6_OPC_MUL:
3195        {
3196            TCGv_i32 t2 = tcg_temp_new_i32();
3197            TCGv_i32 t3 = tcg_temp_new_i32();
3198            tcg_gen_trunc_tl_i32(t2, t0);
3199            tcg_gen_trunc_tl_i32(t3, t1);
3200            tcg_gen_mul_i32(t2, t2, t3);
3201            tcg_gen_ext_i32_tl(cpu_gpr[rd], t2);
3202            tcg_temp_free_i32(t2);
3203            tcg_temp_free_i32(t3);
3204        }
3205        break;
3206    case R6_OPC_MUH:
3207        {
3208            TCGv_i32 t2 = tcg_temp_new_i32();
3209            TCGv_i32 t3 = tcg_temp_new_i32();
3210            tcg_gen_trunc_tl_i32(t2, t0);
3211            tcg_gen_trunc_tl_i32(t3, t1);
3212            tcg_gen_muls2_i32(t2, t3, t2, t3);
3213            tcg_gen_ext_i32_tl(cpu_gpr[rd], t3);
3214            tcg_temp_free_i32(t2);
3215            tcg_temp_free_i32(t3);
3216        }
3217        break;
3218    case R6_OPC_MULU:
3219        {
3220            TCGv_i32 t2 = tcg_temp_new_i32();
3221            TCGv_i32 t3 = tcg_temp_new_i32();
3222            tcg_gen_trunc_tl_i32(t2, t0);
3223            tcg_gen_trunc_tl_i32(t3, t1);
3224            tcg_gen_mul_i32(t2, t2, t3);
3225            tcg_gen_ext_i32_tl(cpu_gpr[rd], t2);
3226            tcg_temp_free_i32(t2);
3227            tcg_temp_free_i32(t3);
3228        }
3229        break;
3230    case R6_OPC_MUHU:
3231        {
3232            TCGv_i32 t2 = tcg_temp_new_i32();
3233            TCGv_i32 t3 = tcg_temp_new_i32();
3234            tcg_gen_trunc_tl_i32(t2, t0);
3235            tcg_gen_trunc_tl_i32(t3, t1);
3236            tcg_gen_mulu2_i32(t2, t3, t2, t3);
3237            tcg_gen_ext_i32_tl(cpu_gpr[rd], t3);
3238            tcg_temp_free_i32(t2);
3239            tcg_temp_free_i32(t3);
3240        }
3241        break;
3242#if defined(TARGET_MIPS64)
3243    case R6_OPC_DDIV:
3244        {
3245            TCGv t2 = tcg_temp_new();
3246            TCGv t3 = tcg_temp_new();
3247            tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, -1LL << 63);
3248            tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1LL);
3249            tcg_gen_and_tl(t2, t2, t3);
3250            tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
3251            tcg_gen_or_tl(t2, t2, t3);
3252            tcg_gen_movi_tl(t3, 0);
3253            tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
3254            tcg_gen_div_tl(cpu_gpr[rd], t0, t1);
3255            tcg_temp_free(t3);
3256            tcg_temp_free(t2);
3257        }
3258        break;
3259    case R6_OPC_DMOD:
3260        {
3261            TCGv t2 = tcg_temp_new();
3262            TCGv t3 = tcg_temp_new();
3263            tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, -1LL << 63);
3264            tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1LL);
3265            tcg_gen_and_tl(t2, t2, t3);
3266            tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
3267            tcg_gen_or_tl(t2, t2, t3);
3268            tcg_gen_movi_tl(t3, 0);
3269            tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
3270            tcg_gen_rem_tl(cpu_gpr[rd], t0, t1);
3271            tcg_temp_free(t3);
3272            tcg_temp_free(t2);
3273        }
3274        break;
3275    case R6_OPC_DDIVU:
3276        {
3277            TCGv t2 = tcg_const_tl(0);
3278            TCGv t3 = tcg_const_tl(1);
3279            tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
3280            tcg_gen_divu_i64(cpu_gpr[rd], t0, t1);
3281            tcg_temp_free(t3);
3282            tcg_temp_free(t2);
3283        }
3284        break;
3285    case R6_OPC_DMODU:
3286        {
3287            TCGv t2 = tcg_const_tl(0);
3288            TCGv t3 = tcg_const_tl(1);
3289            tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
3290            tcg_gen_remu_i64(cpu_gpr[rd], t0, t1);
3291            tcg_temp_free(t3);
3292            tcg_temp_free(t2);
3293        }
3294        break;
3295    case R6_OPC_DMUL:
3296        tcg_gen_mul_i64(cpu_gpr[rd], t0, t1);
3297        break;
3298    case R6_OPC_DMUH:
3299        {
3300            TCGv t2 = tcg_temp_new();
3301            tcg_gen_muls2_i64(t2, cpu_gpr[rd], t0, t1);
3302            tcg_temp_free(t2);
3303        }
3304        break;
3305    case R6_OPC_DMULU:
3306        tcg_gen_mul_i64(cpu_gpr[rd], t0, t1);
3307        break;
3308    case R6_OPC_DMUHU:
3309        {
3310            TCGv t2 = tcg_temp_new();
3311            tcg_gen_mulu2_i64(t2, cpu_gpr[rd], t0, t1);
3312            tcg_temp_free(t2);
3313        }
3314        break;
3315#endif
3316    default:
3317        MIPS_INVAL("r6 mul/div");
3318        gen_reserved_instruction(ctx);
3319        goto out;
3320    }
3321 out:
3322    tcg_temp_free(t0);
3323    tcg_temp_free(t1);
3324}
3325
3326#if defined(TARGET_MIPS64)
3327static void gen_div1_tx79(DisasContext *ctx, uint32_t opc, int rs, int rt)
3328{
3329    TCGv t0, t1;
3330
3331    t0 = tcg_temp_new();
3332    t1 = tcg_temp_new();
3333
3334    gen_load_gpr(t0, rs);
3335    gen_load_gpr(t1, rt);
3336
3337    switch (opc) {
3338    case MMI_OPC_DIV1:
3339        {
3340            TCGv t2 = tcg_temp_new();
3341            TCGv t3 = tcg_temp_new();
3342            tcg_gen_ext32s_tl(t0, t0);
3343            tcg_gen_ext32s_tl(t1, t1);
3344            tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, INT_MIN);
3345            tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1);
3346            tcg_gen_and_tl(t2, t2, t3);
3347            tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
3348            tcg_gen_or_tl(t2, t2, t3);
3349            tcg_gen_movi_tl(t3, 0);
3350            tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
3351            tcg_gen_div_tl(cpu_LO[1], t0, t1);
3352            tcg_gen_rem_tl(cpu_HI[1], t0, t1);
3353            tcg_gen_ext32s_tl(cpu_LO[1], cpu_LO[1]);
3354            tcg_gen_ext32s_tl(cpu_HI[1], cpu_HI[1]);
3355            tcg_temp_free(t3);
3356            tcg_temp_free(t2);
3357        }
3358        break;
3359    case MMI_OPC_DIVU1:
3360        {
3361            TCGv t2 = tcg_const_tl(0);
3362            TCGv t3 = tcg_const_tl(1);
3363            tcg_gen_ext32u_tl(t0, t0);
3364            tcg_gen_ext32u_tl(t1, t1);
3365            tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
3366            tcg_gen_divu_tl(cpu_LO[1], t0, t1);
3367            tcg_gen_remu_tl(cpu_HI[1], t0, t1);
3368            tcg_gen_ext32s_tl(cpu_LO[1], cpu_LO[1]);
3369            tcg_gen_ext32s_tl(cpu_HI[1], cpu_HI[1]);
3370            tcg_temp_free(t3);
3371            tcg_temp_free(t2);
3372        }
3373        break;
3374    default:
3375        MIPS_INVAL("div1 TX79");
3376        gen_reserved_instruction(ctx);
3377        goto out;
3378    }
3379 out:
3380    tcg_temp_free(t0);
3381    tcg_temp_free(t1);
3382}
3383#endif
3384
3385static void gen_muldiv(DisasContext *ctx, uint32_t opc,
3386                       int acc, int rs, int rt)
3387{
3388    TCGv t0, t1;
3389
3390    t0 = tcg_temp_new();
3391    t1 = tcg_temp_new();
3392
3393    gen_load_gpr(t0, rs);
3394    gen_load_gpr(t1, rt);
3395
3396    if (acc != 0) {
3397        check_dsp(ctx);
3398    }
3399
3400    switch (opc) {
3401    case OPC_DIV:
3402        {
3403            TCGv t2 = tcg_temp_new();
3404            TCGv t3 = tcg_temp_new();
3405            tcg_gen_ext32s_tl(t0, t0);
3406            tcg_gen_ext32s_tl(t1, t1);
3407            tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, INT_MIN);
3408            tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1);
3409            tcg_gen_and_tl(t2, t2, t3);
3410            tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
3411            tcg_gen_or_tl(t2, t2, t3);
3412            tcg_gen_movi_tl(t3, 0);
3413            tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
3414            tcg_gen_div_tl(cpu_LO[acc], t0, t1);
3415            tcg_gen_rem_tl(cpu_HI[acc], t0, t1);
3416            tcg_gen_ext32s_tl(cpu_LO[acc], cpu_LO[acc]);
3417            tcg_gen_ext32s_tl(cpu_HI[acc], cpu_HI[acc]);
3418            tcg_temp_free(t3);
3419            tcg_temp_free(t2);
3420        }
3421        break;
3422    case OPC_DIVU:
3423        {
3424            TCGv t2 = tcg_const_tl(0);
3425            TCGv t3 = tcg_const_tl(1);
3426            tcg_gen_ext32u_tl(t0, t0);
3427            tcg_gen_ext32u_tl(t1, t1);
3428            tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
3429            tcg_gen_divu_tl(cpu_LO[acc], t0, t1);
3430            tcg_gen_remu_tl(cpu_HI[acc], t0, t1);
3431            tcg_gen_ext32s_tl(cpu_LO[acc], cpu_LO[acc]);
3432            tcg_gen_ext32s_tl(cpu_HI[acc], cpu_HI[acc]);
3433            tcg_temp_free(t3);
3434            tcg_temp_free(t2);
3435        }
3436        break;
3437    case OPC_MULT:
3438        {
3439            TCGv_i32 t2 = tcg_temp_new_i32();
3440            TCGv_i32 t3 = tcg_temp_new_i32();
3441            tcg_gen_trunc_tl_i32(t2, t0);
3442            tcg_gen_trunc_tl_i32(t3, t1);
3443            tcg_gen_muls2_i32(t2, t3, t2, t3);
3444            tcg_gen_ext_i32_tl(cpu_LO[acc], t2);
3445            tcg_gen_ext_i32_tl(cpu_HI[acc], t3);
3446            tcg_temp_free_i32(t2);
3447            tcg_temp_free_i32(t3);
3448        }
3449        break;
3450    case OPC_MULTU:
3451        {
3452            TCGv_i32 t2 = tcg_temp_new_i32();
3453            TCGv_i32 t3 = tcg_temp_new_i32();
3454            tcg_gen_trunc_tl_i32(t2, t0);
3455            tcg_gen_trunc_tl_i32(t3, t1);
3456            tcg_gen_mulu2_i32(t2, t3, t2, t3);
3457            tcg_gen_ext_i32_tl(cpu_LO[acc], t2);
3458            tcg_gen_ext_i32_tl(cpu_HI[acc], t3);
3459            tcg_temp_free_i32(t2);
3460            tcg_temp_free_i32(t3);
3461        }
3462        break;
3463#if defined(TARGET_MIPS64)
3464    case OPC_DDIV:
3465        {
3466            TCGv t2 = tcg_temp_new();
3467            TCGv t3 = tcg_temp_new();
3468            tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, -1LL << 63);
3469            tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1LL);
3470            tcg_gen_and_tl(t2, t2, t3);
3471            tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
3472            tcg_gen_or_tl(t2, t2, t3);
3473            tcg_gen_movi_tl(t3, 0);
3474            tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
3475            tcg_gen_div_tl(cpu_LO[acc], t0, t1);
3476            tcg_gen_rem_tl(cpu_HI[acc], t0, t1);
3477            tcg_temp_free(t3);
3478            tcg_temp_free(t2);
3479        }
3480        break;
3481    case OPC_DDIVU:
3482        {
3483            TCGv t2 = tcg_const_tl(0);
3484            TCGv t3 = tcg_const_tl(1);
3485            tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
3486            tcg_gen_divu_i64(cpu_LO[acc], t0, t1);
3487            tcg_gen_remu_i64(cpu_HI[acc], t0, t1);
3488            tcg_temp_free(t3);
3489            tcg_temp_free(t2);
3490        }
3491        break;
3492    case OPC_DMULT:
3493        tcg_gen_muls2_i64(cpu_LO[acc], cpu_HI[acc], t0, t1);
3494        break;
3495    case OPC_DMULTU:
3496        tcg_gen_mulu2_i64(cpu_LO[acc], cpu_HI[acc], t0, t1);
3497        break;
3498#endif
3499    case OPC_MADD:
3500        {
3501            TCGv_i64 t2 = tcg_temp_new_i64();
3502            TCGv_i64 t3 = tcg_temp_new_i64();
3503
3504            tcg_gen_ext_tl_i64(t2, t0);
3505            tcg_gen_ext_tl_i64(t3, t1);
3506            tcg_gen_mul_i64(t2, t2, t3);
3507            tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
3508            tcg_gen_add_i64(t2, t2, t3);
3509            tcg_temp_free_i64(t3);
3510            gen_move_low32(cpu_LO[acc], t2);
3511            gen_move_high32(cpu_HI[acc], t2);
3512            tcg_temp_free_i64(t2);
3513        }
3514        break;
3515    case OPC_MADDU:
3516        {
3517            TCGv_i64 t2 = tcg_temp_new_i64();
3518            TCGv_i64 t3 = tcg_temp_new_i64();
3519
3520            tcg_gen_ext32u_tl(t0, t0);
3521            tcg_gen_ext32u_tl(t1, t1);
3522            tcg_gen_extu_tl_i64(t2, t0);
3523            tcg_gen_extu_tl_i64(t3, t1);
3524            tcg_gen_mul_i64(t2, t2, t3);
3525            tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
3526            tcg_gen_add_i64(t2, t2, t3);
3527            tcg_temp_free_i64(t3);
3528            gen_move_low32(cpu_LO[acc], t2);
3529            gen_move_high32(cpu_HI[acc], t2);
3530            tcg_temp_free_i64(t2);
3531        }
3532        break;
3533    case OPC_MSUB:
3534        {
3535            TCGv_i64 t2 = tcg_temp_new_i64();
3536            TCGv_i64 t3 = tcg_temp_new_i64();
3537
3538            tcg_gen_ext_tl_i64(t2, t0);
3539            tcg_gen_ext_tl_i64(t3, t1);
3540            tcg_gen_mul_i64(t2, t2, t3);
3541            tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
3542            tcg_gen_sub_i64(t2, t3, t2);
3543            tcg_temp_free_i64(t3);
3544            gen_move_low32(cpu_LO[acc], t2);
3545            gen_move_high32(cpu_HI[acc], t2);
3546            tcg_temp_free_i64(t2);
3547        }
3548        break;
3549    case OPC_MSUBU:
3550        {
3551            TCGv_i64 t2 = tcg_temp_new_i64();
3552            TCGv_i64 t3 = tcg_temp_new_i64();
3553
3554            tcg_gen_ext32u_tl(t0, t0);
3555            tcg_gen_ext32u_tl(t1, t1);
3556            tcg_gen_extu_tl_i64(t2, t0);
3557            tcg_gen_extu_tl_i64(t3, t1);
3558            tcg_gen_mul_i64(t2, t2, t3);
3559            tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
3560            tcg_gen_sub_i64(t2, t3, t2);
3561            tcg_temp_free_i64(t3);
3562            gen_move_low32(cpu_LO[acc], t2);
3563            gen_move_high32(cpu_HI[acc], t2);
3564            tcg_temp_free_i64(t2);
3565        }
3566        break;
3567    default:
3568        MIPS_INVAL("mul/div");
3569        gen_reserved_instruction(ctx);
3570        goto out;
3571    }
3572 out:
3573    tcg_temp_free(t0);
3574    tcg_temp_free(t1);
3575}
3576
3577/*
3578 * These MULT[U] and MADD[U] instructions implemented in for example
3579 * the Toshiba/Sony R5900 and the Toshiba TX19, TX39 and TX79 core
3580 * architectures are special three-operand variants with the syntax
3581 *
3582 *     MULT[U][1] rd, rs, rt
3583 *
3584 * such that
3585 *
3586 *     (rd, LO, HI) <- rs * rt
3587 *
3588 * and
3589 *
3590 *     MADD[U][1] rd, rs, rt
3591 *
3592 * such that
3593 *
3594 *     (rd, LO, HI) <- (LO, HI) + rs * rt
3595 *
3596 * where the low-order 32-bits of the result is placed into both the
3597 * GPR rd and the special register LO. The high-order 32-bits of the
3598 * result is placed into the special register HI.
3599 *
3600 * If the GPR rd is omitted in assembly language, it is taken to be 0,
3601 * which is the zero register that always reads as 0.
3602 */
3603static void gen_mul_txx9(DisasContext *ctx, uint32_t opc,
3604                         int rd, int rs, int rt)
3605{
3606    TCGv t0 = tcg_temp_new();
3607    TCGv t1 = tcg_temp_new();
3608    int acc = 0;
3609
3610    gen_load_gpr(t0, rs);
3611    gen_load_gpr(t1, rt);
3612
3613    switch (opc) {
3614    case MMI_OPC_MULT1:
3615        acc = 1;
3616        /* Fall through */
3617    case OPC_MULT:
3618        {
3619            TCGv_i32 t2 = tcg_temp_new_i32();
3620            TCGv_i32 t3 = tcg_temp_new_i32();
3621            tcg_gen_trunc_tl_i32(t2, t0);
3622            tcg_gen_trunc_tl_i32(t3, t1);
3623            tcg_gen_muls2_i32(t2, t3, t2, t3);
3624            if (rd) {
3625                tcg_gen_ext_i32_tl(cpu_gpr[rd], t2);
3626            }
3627            tcg_gen_ext_i32_tl(cpu_LO[acc], t2);
3628            tcg_gen_ext_i32_tl(cpu_HI[acc], t3);
3629            tcg_temp_free_i32(t2);
3630            tcg_temp_free_i32(t3);
3631        }
3632        break;
3633    case MMI_OPC_MULTU1:
3634        acc = 1;
3635        /* Fall through */
3636    case OPC_MULTU:
3637        {
3638            TCGv_i32 t2 = tcg_temp_new_i32();
3639            TCGv_i32 t3 = tcg_temp_new_i32();
3640            tcg_gen_trunc_tl_i32(t2, t0);
3641            tcg_gen_trunc_tl_i32(t3, t1);
3642            tcg_gen_mulu2_i32(t2, t3, t2, t3);
3643            if (rd) {
3644                tcg_gen_ext_i32_tl(cpu_gpr[rd], t2);
3645            }
3646            tcg_gen_ext_i32_tl(cpu_LO[acc], t2);
3647            tcg_gen_ext_i32_tl(cpu_HI[acc], t3);
3648            tcg_temp_free_i32(t2);
3649            tcg_temp_free_i32(t3);
3650        }
3651        break;
3652    case MMI_OPC_MADD1:
3653        acc = 1;
3654        /* Fall through */
3655    case MMI_OPC_MADD:
3656        {
3657            TCGv_i64 t2 = tcg_temp_new_i64();
3658            TCGv_i64 t3 = tcg_temp_new_i64();
3659
3660            tcg_gen_ext_tl_i64(t2, t0);
3661            tcg_gen_ext_tl_i64(t3, t1);
3662            tcg_gen_mul_i64(t2, t2, t3);
3663            tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
3664            tcg_gen_add_i64(t2, t2, t3);
3665            tcg_temp_free_i64(t3);
3666            gen_move_low32(cpu_LO[acc], t2);
3667            gen_move_high32(cpu_HI[acc], t2);
3668            if (rd) {
3669                gen_move_low32(cpu_gpr[rd], t2);
3670            }
3671            tcg_temp_free_i64(t2);
3672        }
3673        break;
3674    case MMI_OPC_MADDU1:
3675        acc = 1;
3676        /* Fall through */
3677    case MMI_OPC_MADDU:
3678        {
3679            TCGv_i64 t2 = tcg_temp_new_i64();
3680            TCGv_i64 t3 = tcg_temp_new_i64();
3681
3682            tcg_gen_ext32u_tl(t0, t0);
3683            tcg_gen_ext32u_tl(t1, t1);
3684            tcg_gen_extu_tl_i64(t2, t0);
3685            tcg_gen_extu_tl_i64(t3, t1);
3686            tcg_gen_mul_i64(t2, t2, t3);
3687            tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
3688            tcg_gen_add_i64(t2, t2, t3);
3689            tcg_temp_free_i64(t3);
3690            gen_move_low32(cpu_LO[acc], t2);
3691            gen_move_high32(cpu_HI[acc], t2);
3692            if (rd) {
3693                gen_move_low32(cpu_gpr[rd], t2);
3694            }
3695            tcg_temp_free_i64(t2);
3696        }
3697        break;
3698    default:
3699        MIPS_INVAL("mul/madd TXx9");
3700        gen_reserved_instruction(ctx);
3701        goto out;
3702    }
3703
3704 out:
3705    tcg_temp_free(t0);
3706    tcg_temp_free(t1);
3707}
3708
3709static void gen_cl(DisasContext *ctx, uint32_t opc,
3710                   int rd, int rs)
3711{
3712    TCGv t0;
3713
3714    if (rd == 0) {
3715        /* Treat as NOP. */
3716        return;
3717    }
3718    t0 = cpu_gpr[rd];
3719    gen_load_gpr(t0, rs);
3720
3721    switch (opc) {
3722    case OPC_CLO:
3723    case R6_OPC_CLO:
3724#if defined(TARGET_MIPS64)
3725    case OPC_DCLO:
3726    case R6_OPC_DCLO:
3727#endif
3728        tcg_gen_not_tl(t0, t0);
3729        break;
3730    }
3731
3732    switch (opc) {
3733    case OPC_CLO:
3734    case R6_OPC_CLO:
3735    case OPC_CLZ:
3736    case R6_OPC_CLZ:
3737        tcg_gen_ext32u_tl(t0, t0);
3738        tcg_gen_clzi_tl(t0, t0, TARGET_LONG_BITS);
3739        tcg_gen_subi_tl(t0, t0, TARGET_LONG_BITS - 32);
3740        break;
3741#if defined(TARGET_MIPS64)
3742    case OPC_DCLO:
3743    case R6_OPC_DCLO:
3744    case OPC_DCLZ:
3745    case R6_OPC_DCLZ:
3746        tcg_gen_clzi_i64(t0, t0, 64);
3747        break;
3748#endif
3749    }
3750}
3751
3752/* Godson integer instructions */
3753static void gen_loongson_integer(DisasContext *ctx, uint32_t opc,
3754                                 int rd, int rs, int rt)
3755{
3756    TCGv t0, t1;
3757
3758    if (rd == 0) {
3759        /* Treat as NOP. */
3760        return;
3761    }
3762
3763    switch (opc) {
3764    case OPC_MULT_G_2E:
3765    case OPC_MULT_G_2F:
3766    case OPC_MULTU_G_2E:
3767    case OPC_MULTU_G_2F:
3768#if defined(TARGET_MIPS64)
3769    case OPC_DMULT_G_2E:
3770    case OPC_DMULT_G_2F:
3771    case OPC_DMULTU_G_2E:
3772    case OPC_DMULTU_G_2F:
3773#endif
3774        t0 = tcg_temp_new();
3775        t1 = tcg_temp_new();
3776        break;
3777    default:
3778        t0 = tcg_temp_local_new();
3779        t1 = tcg_temp_local_new();
3780        break;
3781    }
3782
3783    gen_load_gpr(t0, rs);
3784    gen_load_gpr(t1, rt);
3785
3786    switch (opc) {
3787    case OPC_MULT_G_2E:
3788    case OPC_MULT_G_2F:
3789        tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
3790        tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3791        break;
3792    case OPC_MULTU_G_2E:
3793    case OPC_MULTU_G_2F:
3794        tcg_gen_ext32u_tl(t0, t0);
3795        tcg_gen_ext32u_tl(t1, t1);
3796        tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
3797        tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3798        break;
3799    case OPC_DIV_G_2E:
3800    case OPC_DIV_G_2F:
3801        {
3802            TCGLabel *l1 = gen_new_label();
3803            TCGLabel *l2 = gen_new_label();
3804            TCGLabel *l3 = gen_new_label();
3805            tcg_gen_ext32s_tl(t0, t0);
3806            tcg_gen_ext32s_tl(t1, t1);
3807            tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
3808            tcg_gen_movi_tl(cpu_gpr[rd], 0);
3809            tcg_gen_br(l3);
3810            gen_set_label(l1);
3811            tcg_gen_brcondi_tl(TCG_COND_NE, t0, INT_MIN, l2);
3812            tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1, l2);
3813            tcg_gen_mov_tl(cpu_gpr[rd], t0);
3814            tcg_gen_br(l3);
3815            gen_set_label(l2);
3816            tcg_gen_div_tl(cpu_gpr[rd], t0, t1);
3817            tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3818            gen_set_label(l3);
3819        }
3820        break;
3821    case OPC_DIVU_G_2E:
3822    case OPC_DIVU_G_2F:
3823        {
3824            TCGLabel *l1 = gen_new_label();
3825            TCGLabel *l2 = gen_new_label();
3826            tcg_gen_ext32u_tl(t0, t0);
3827            tcg_gen_ext32u_tl(t1, t1);
3828            tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
3829            tcg_gen_movi_tl(cpu_gpr[rd], 0);
3830            tcg_gen_br(l2);
3831            gen_set_label(l1);
3832            tcg_gen_divu_tl(cpu_gpr[rd], t0, t1);
3833            tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3834            gen_set_label(l2);
3835        }
3836        break;
3837    case OPC_MOD_G_2E:
3838    case OPC_MOD_G_2F:
3839        {
3840            TCGLabel *l1 = gen_new_label();
3841            TCGLabel *l2 = gen_new_label();
3842            TCGLabel *l3 = gen_new_label();
3843            tcg_gen_ext32u_tl(t0, t0);
3844            tcg_gen_ext32u_tl(t1, t1);
3845            tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
3846            tcg_gen_brcondi_tl(TCG_COND_NE, t0, INT_MIN, l2);
3847            tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1, l2);
3848            gen_set_label(l1);
3849            tcg_gen_movi_tl(cpu_gpr[rd], 0);
3850            tcg_gen_br(l3);
3851            gen_set_label(l2);
3852            tcg_gen_rem_tl(cpu_gpr[rd], t0, t1);
3853            tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3854            gen_set_label(l3);
3855        }
3856        break;
3857    case OPC_MODU_G_2E:
3858    case OPC_MODU_G_2F:
3859        {
3860            TCGLabel *l1 = gen_new_label();
3861            TCGLabel *l2 = gen_new_label();
3862            tcg_gen_ext32u_tl(t0, t0);
3863            tcg_gen_ext32u_tl(t1, t1);
3864            tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
3865            tcg_gen_movi_tl(cpu_gpr[rd], 0);
3866            tcg_gen_br(l2);
3867            gen_set_label(l1);
3868            tcg_gen_remu_tl(cpu_gpr[rd], t0, t1);
3869            tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3870            gen_set_label(l2);
3871        }
3872        break;
3873#if defined(TARGET_MIPS64)
3874    case OPC_DMULT_G_2E:
3875    case OPC_DMULT_G_2F:
3876        tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
3877        break;
3878    case OPC_DMULTU_G_2E:
3879    case OPC_DMULTU_G_2F:
3880        tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
3881        break;
3882    case OPC_DDIV_G_2E:
3883    case OPC_DDIV_G_2F:
3884        {
3885            TCGLabel *l1 = gen_new_label();
3886            TCGLabel *l2 = gen_new_label();
3887            TCGLabel *l3 = gen_new_label();
3888            tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
3889            tcg_gen_movi_tl(cpu_gpr[rd], 0);
3890            tcg_gen_br(l3);
3891            gen_set_label(l1);
3892            tcg_gen_brcondi_tl(TCG_COND_NE, t0, -1LL << 63, l2);
3893            tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1LL, l2);
3894            tcg_gen_mov_tl(cpu_gpr[rd], t0);
3895            tcg_gen_br(l3);
3896            gen_set_label(l2);
3897            tcg_gen_div_tl(cpu_gpr[rd], t0, t1);
3898            gen_set_label(l3);
3899        }
3900        break;
3901    case OPC_DDIVU_G_2E:
3902    case OPC_DDIVU_G_2F:
3903        {
3904            TCGLabel *l1 = gen_new_label();
3905            TCGLabel *l2 = gen_new_label();
3906            tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
3907            tcg_gen_movi_tl(cpu_gpr[rd], 0);
3908            tcg_gen_br(l2);
3909            gen_set_label(l1);
3910            tcg_gen_divu_tl(cpu_gpr[rd], t0, t1);
3911            gen_set_label(l2);
3912        }
3913        break;
3914    case OPC_DMOD_G_2E:
3915    case OPC_DMOD_G_2F:
3916        {
3917            TCGLabel *l1 = gen_new_label();
3918            TCGLabel *l2 = gen_new_label();
3919            TCGLabel *l3 = gen_new_label();
3920            tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
3921            tcg_gen_brcondi_tl(TCG_COND_NE, t0, -1LL << 63, l2);
3922            tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1LL, l2);
3923            gen_set_label(l1);
3924            tcg_gen_movi_tl(cpu_gpr[rd], 0);
3925            tcg_gen_br(l3);
3926            gen_set_label(l2);
3927            tcg_gen_rem_tl(cpu_gpr[rd], t0, t1);
3928            gen_set_label(l3);
3929        }
3930        break;
3931    case OPC_DMODU_G_2E:
3932    case OPC_DMODU_G_2F:
3933        {
3934            TCGLabel *l1 = gen_new_label();
3935            TCGLabel *l2 = gen_new_label();
3936            tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
3937            tcg_gen_movi_tl(cpu_gpr[rd], 0);
3938            tcg_gen_br(l2);
3939            gen_set_label(l1);
3940            tcg_gen_remu_tl(cpu_gpr[rd], t0, t1);
3941            gen_set_label(l2);
3942        }
3943        break;
3944#endif
3945    }
3946
3947    tcg_temp_free(t0);
3948    tcg_temp_free(t1);
3949}
3950
3951/* Loongson multimedia instructions */
3952static void gen_loongson_multimedia(DisasContext *ctx, int rd, int rs, int rt)
3953{
3954    uint32_t opc, shift_max;
3955    TCGv_i64 t0, t1;
3956    TCGCond cond;
3957
3958    opc = MASK_LMMI(ctx->opcode);
3959    switch (opc) {
3960    case OPC_ADD_CP2:
3961    case OPC_SUB_CP2:
3962    case OPC_DADD_CP2:
3963    case OPC_DSUB_CP2:
3964        t0 = tcg_temp_local_new_i64();
3965        t1 = tcg_temp_local_new_i64();
3966        break;
3967    default:
3968        t0 = tcg_temp_new_i64();
3969        t1 = tcg_temp_new_i64();
3970        break;
3971    }
3972
3973    check_cp1_enabled(ctx);
3974    gen_load_fpr64(ctx, t0, rs);
3975    gen_load_fpr64(ctx, t1, rt);
3976
3977    switch (opc) {
3978    case OPC_PADDSH:
3979        gen_helper_paddsh(t0, t0, t1);
3980        break;
3981    case OPC_PADDUSH:
3982        gen_helper_paddush(t0, t0, t1);
3983        break;
3984    case OPC_PADDH:
3985        gen_helper_paddh(t0, t0, t1);
3986        break;
3987    case OPC_PADDW:
3988        gen_helper_paddw(t0, t0, t1);
3989        break;
3990    case OPC_PADDSB:
3991        gen_helper_paddsb(t0, t0, t1);
3992        break;
3993    case OPC_PADDUSB:
3994        gen_helper_paddusb(t0, t0, t1);
3995        break;
3996    case OPC_PADDB:
3997        gen_helper_paddb(t0, t0, t1);
3998        break;
3999
4000    case OPC_PSUBSH:
4001        gen_helper_psubsh(t0, t0, t1);
4002        break;
4003    case OPC_PSUBUSH:
4004        gen_helper_psubush(t0, t0, t1);
4005        break;
4006    case OPC_PSUBH:
4007        gen_helper_psubh(t0, t0, t1);
4008        break;
4009    case OPC_PSUBW:
4010        gen_helper_psubw(t0, t0, t1);
4011        break;
4012    case OPC_PSUBSB:
4013        gen_helper_psubsb(t0, t0, t1);
4014        break;
4015    case OPC_PSUBUSB:
4016        gen_helper_psubusb(t0, t0, t1);
4017        break;
4018    case OPC_PSUBB:
4019        gen_helper_psubb(t0, t0, t1);
4020        break;
4021
4022    case OPC_PSHUFH:
4023        gen_helper_pshufh(t0, t0, t1);
4024        break;
4025    case OPC_PACKSSWH:
4026        gen_helper_packsswh(t0, t0, t1);
4027        break;
4028    case OPC_PACKSSHB:
4029        gen_helper_packsshb(t0, t0, t1);
4030        break;
4031    case OPC_PACKUSHB:
4032        gen_helper_packushb(t0, t0, t1);
4033        break;
4034
4035    case OPC_PUNPCKLHW:
4036        gen_helper_punpcklhw(t0, t0, t1);
4037        break;
4038    case OPC_PUNPCKHHW:
4039        gen_helper_punpckhhw(t0, t0, t1);
4040        break;
4041    case OPC_PUNPCKLBH:
4042        gen_helper_punpcklbh(t0, t0, t1);
4043        break;
4044    case OPC_PUNPCKHBH:
4045        gen_helper_punpckhbh(t0, t0, t1);
4046        break;
4047    case OPC_PUNPCKLWD:
4048        gen_helper_punpcklwd(t0, t0, t1);
4049        break;
4050    case OPC_PUNPCKHWD:
4051        gen_helper_punpckhwd(t0, t0, t1);
4052        break;
4053
4054    case OPC_PAVGH:
4055        gen_helper_pavgh(t0, t0, t1);
4056        break;
4057    case OPC_PAVGB:
4058        gen_helper_pavgb(t0, t0, t1);
4059        break;
4060    case OPC_PMAXSH:
4061        gen_helper_pmaxsh(t0, t0, t1);
4062        break;
4063    case OPC_PMINSH:
4064        gen_helper_pminsh(t0, t0, t1);
4065        break;
4066    case OPC_PMAXUB:
4067        gen_helper_pmaxub(t0, t0, t1);
4068        break;
4069    case OPC_PMINUB:
4070        gen_helper_pminub(t0, t0, t1);
4071        break;
4072
4073    case OPC_PCMPEQW:
4074        gen_helper_pcmpeqw(t0, t0, t1);
4075        break;
4076    case OPC_PCMPGTW:
4077        gen_helper_pcmpgtw(t0, t0, t1);
4078        break;
4079    case OPC_PCMPEQH:
4080        gen_helper_pcmpeqh(t0, t0, t1);
4081        break;
4082    case OPC_PCMPGTH:
4083        gen_helper_pcmpgth(t0, t0, t1);
4084        break;
4085    case OPC_PCMPEQB:
4086        gen_helper_pcmpeqb(t0, t0, t1);
4087        break;
4088    case OPC_PCMPGTB:
4089        gen_helper_pcmpgtb(t0, t0, t1);
4090        break;
4091
4092    case OPC_PSLLW:
4093        gen_helper_psllw(t0, t0, t1);
4094        break;
4095    case OPC_PSLLH:
4096        gen_helper_psllh(t0, t0, t1);
4097        break;
4098    case OPC_PSRLW:
4099        gen_helper_psrlw(t0, t0, t1);
4100        break;
4101    case OPC_PSRLH:
4102        gen_helper_psrlh(t0, t0, t1);
4103        break;
4104    case OPC_PSRAW:
4105        gen_helper_psraw(t0, t0, t1);
4106        break;
4107    case OPC_PSRAH:
4108        gen_helper_psrah(t0, t0, t1);
4109        break;
4110
4111    case OPC_PMULLH:
4112        gen_helper_pmullh(t0, t0, t1);
4113        break;
4114    case OPC_PMULHH:
4115        gen_helper_pmulhh(t0, t0, t1);
4116        break;
4117    case OPC_PMULHUH:
4118        gen_helper_pmulhuh(t0, t0, t1);
4119        break;
4120    case OPC_PMADDHW:
4121        gen_helper_pmaddhw(t0, t0, t1);
4122        break;
4123
4124    case OPC_PASUBUB:
4125        gen_helper_pasubub(t0, t0, t1);
4126        break;
4127    case OPC_BIADD:
4128        gen_helper_biadd(t0, t0);
4129        break;
4130    case OPC_PMOVMSKB:
4131        gen_helper_pmovmskb(t0, t0);
4132        break;
4133
4134    case OPC_PADDD:
4135        tcg_gen_add_i64(t0, t0, t1);
4136        break;
4137    case OPC_PSUBD:
4138        tcg_gen_sub_i64(t0, t0, t1);
4139        break;
4140    case OPC_XOR_CP2:
4141        tcg_gen_xor_i64(t0, t0, t1);
4142        break;
4143    case OPC_NOR_CP2:
4144        tcg_gen_nor_i64(t0, t0, t1);
4145        break;
4146    case OPC_AND_CP2:
4147        tcg_gen_and_i64(t0, t0, t1);
4148        break;
4149    case OPC_OR_CP2:
4150        tcg_gen_or_i64(t0, t0, t1);
4151        break;
4152
4153    case OPC_PANDN:
4154        tcg_gen_andc_i64(t0, t1, t0);
4155        break;
4156
4157    case OPC_PINSRH_0:
4158        tcg_gen_deposit_i64(t0, t0, t1, 0, 16);
4159        break;
4160    case OPC_PINSRH_1:
4161        tcg_gen_deposit_i64(t0, t0, t1, 16, 16);
4162        break;
4163    case OPC_PINSRH_2:
4164        tcg_gen_deposit_i64(t0, t0, t1, 32, 16);
4165        break;
4166    case OPC_PINSRH_3:
4167        tcg_gen_deposit_i64(t0, t0, t1, 48, 16);
4168        break;
4169
4170    case OPC_PEXTRH:
4171        tcg_gen_andi_i64(t1, t1, 3);
4172        tcg_gen_shli_i64(t1, t1, 4);
4173        tcg_gen_shr_i64(t0, t0, t1);
4174        tcg_gen_ext16u_i64(t0, t0);
4175        break;
4176
4177    case OPC_ADDU_CP2:
4178        tcg_gen_add_i64(t0, t0, t1);
4179        tcg_gen_ext32s_i64(t0, t0);
4180        break;
4181    case OPC_SUBU_CP2:
4182        tcg_gen_sub_i64(t0, t0, t1);
4183        tcg_gen_ext32s_i64(t0, t0);
4184        break;
4185
4186    case OPC_SLL_CP2:
4187        shift_max = 32;
4188        goto do_shift;
4189    case OPC_SRL_CP2:
4190        shift_max = 32;
4191        goto do_shift;
4192    case OPC_SRA_CP2:
4193        shift_max = 32;
4194        goto do_shift;
4195    case OPC_DSLL_CP2:
4196        shift_max = 64;
4197        goto do_shift;
4198    case OPC_DSRL_CP2:
4199        shift_max = 64;
4200        goto do_shift;
4201    case OPC_DSRA_CP2:
4202        shift_max = 64;
4203        goto do_shift;
4204    do_shift:
4205        /* Make sure shift count isn't TCG undefined behaviour.  */
4206        tcg_gen_andi_i64(t1, t1, shift_max - 1);
4207
4208        switch (opc) {
4209        case OPC_SLL_CP2:
4210        case OPC_DSLL_CP2:
4211            tcg_gen_shl_i64(t0, t0, t1);
4212            break;
4213        case OPC_SRA_CP2:
4214        case OPC_DSRA_CP2:
4215            /*
4216             * Since SRA is UndefinedResult without sign-extended inputs,
4217             * we can treat SRA and DSRA the same.
4218             */
4219            tcg_gen_sar_i64(t0, t0, t1);
4220            break;
4221        case OPC_SRL_CP2:
4222            /* We want to shift in zeros for SRL; zero-extend first.  */
4223            tcg_gen_ext32u_i64(t0, t0);
4224            /* FALLTHRU */
4225        case OPC_DSRL_CP2:
4226            tcg_gen_shr_i64(t0, t0, t1);
4227            break;
4228        }
4229
4230        if (shift_max == 32) {
4231            tcg_gen_ext32s_i64(t0, t0);
4232        }
4233
4234        /* Shifts larger than MAX produce zero.  */
4235        tcg_gen_setcondi_i64(TCG_COND_LTU, t1, t1, shift_max);
4236        tcg_gen_neg_i64(t1, t1);
4237        tcg_gen_and_i64(t0, t0, t1);
4238        break;
4239
4240    case OPC_ADD_CP2:
4241    case OPC_DADD_CP2:
4242        {
4243            TCGv_i64 t2 = tcg_temp_new_i64();
4244            TCGLabel *lab = gen_new_label();
4245
4246            tcg_gen_mov_i64(t2, t0);
4247            tcg_gen_add_i64(t0, t1, t2);
4248            if (opc == OPC_ADD_CP2) {
4249                tcg_gen_ext32s_i64(t0, t0);
4250            }
4251            tcg_gen_xor_i64(t1, t1, t2);
4252            tcg_gen_xor_i64(t2, t2, t0);
4253            tcg_gen_andc_i64(t1, t2, t1);
4254            tcg_temp_free_i64(t2);
4255            tcg_gen_brcondi_i64(TCG_COND_GE, t1, 0, lab);
4256            generate_exception(ctx, EXCP_OVERFLOW);
4257            gen_set_label(lab);
4258            break;
4259        }
4260
4261    case OPC_SUB_CP2:
4262    case OPC_DSUB_CP2:
4263        {
4264            TCGv_i64 t2 = tcg_temp_new_i64();
4265            TCGLabel *lab = gen_new_label();
4266
4267            tcg_gen_mov_i64(t2, t0);
4268            tcg_gen_sub_i64(t0, t1, t2);
4269            if (opc == OPC_SUB_CP2) {
4270                tcg_gen_ext32s_i64(t0, t0);
4271            }
4272            tcg_gen_xor_i64(t1, t1, t2);
4273            tcg_gen_xor_i64(t2, t2, t0);
4274            tcg_gen_and_i64(t1, t1, t2);
4275            tcg_temp_free_i64(t2);
4276            tcg_gen_brcondi_i64(TCG_COND_GE, t1, 0, lab);
4277            generate_exception(ctx, EXCP_OVERFLOW);
4278            gen_set_label(lab);
4279            break;
4280        }
4281
4282    case OPC_PMULUW:
4283        tcg_gen_ext32u_i64(t0, t0);
4284        tcg_gen_ext32u_i64(t1, t1);
4285        tcg_gen_mul_i64(t0, t0, t1);
4286        break;
4287
4288    case OPC_SEQU_CP2:
4289    case OPC_SEQ_CP2:
4290        cond = TCG_COND_EQ;
4291        goto do_cc_cond;
4292        break;
4293    case OPC_SLTU_CP2:
4294        cond = TCG_COND_LTU;
4295        goto do_cc_cond;
4296        break;
4297    case OPC_SLT_CP2:
4298        cond = TCG_COND_LT;
4299        goto do_cc_cond;
4300        break;
4301    case OPC_SLEU_CP2:
4302        cond = TCG_COND_LEU;
4303        goto do_cc_cond;
4304        break;
4305    case OPC_SLE_CP2:
4306        cond = TCG_COND_LE;
4307    do_cc_cond:
4308        {
4309            int cc = (ctx->opcode >> 8) & 0x7;
4310            TCGv_i64 t64 = tcg_temp_new_i64();
4311            TCGv_i32 t32 = tcg_temp_new_i32();
4312
4313            tcg_gen_setcond_i64(cond, t64, t0, t1);
4314            tcg_gen_extrl_i64_i32(t32, t64);
4315            tcg_gen_deposit_i32(fpu_fcr31, fpu_fcr31, t32,
4316                                get_fp_bit(cc), 1);
4317
4318            tcg_temp_free_i32(t32);
4319            tcg_temp_free_i64(t64);
4320        }
4321        goto no_rd;
4322        break;
4323    default:
4324        MIPS_INVAL("loongson_cp2");
4325        gen_reserved_instruction(ctx);
4326        return;
4327    }
4328
4329    gen_store_fpr64(ctx, t0, rd);
4330
4331no_rd:
4332    tcg_temp_free_i64(t0);
4333    tcg_temp_free_i64(t1);
4334}
4335
4336static void gen_loongson_lswc2(DisasContext *ctx, int rt,
4337                               int rs, int rd)
4338{
4339    TCGv t0, t1, t2;
4340    TCGv_i32 fp0;
4341#if defined(TARGET_MIPS64)
4342    int lsq_rt1 = ctx->opcode & 0x1f;
4343    int lsq_offset = sextract32(ctx->opcode, 6, 9) << 4;
4344#endif
4345    int shf_offset = sextract32(ctx->opcode, 6, 8);
4346
4347    t0 = tcg_temp_new();
4348
4349    switch (MASK_LOONGSON_GSLSQ(ctx->opcode)) {
4350#if defined(TARGET_MIPS64)
4351    case OPC_GSLQ:
4352        t1 = tcg_temp_new();
4353        gen_base_offset_addr(ctx, t0, rs, lsq_offset);
4354        tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TEUQ |
4355                           ctx->default_tcg_memop_mask);
4356        gen_base_offset_addr(ctx, t0, rs, lsq_offset + 8);
4357        tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEUQ |
4358                           ctx->default_tcg_memop_mask);
4359        gen_store_gpr(t1, rt);
4360        gen_store_gpr(t0, lsq_rt1);
4361        tcg_temp_free(t1);
4362        break;
4363    case OPC_GSLQC1:
4364        check_cp1_enabled(ctx);
4365        t1 = tcg_temp_new();
4366        gen_base_offset_addr(ctx, t0, rs, lsq_offset);
4367        tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TEUQ |
4368                           ctx->default_tcg_memop_mask);
4369        gen_base_offset_addr(ctx, t0, rs, lsq_offset + 8);
4370        tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEUQ |
4371                           ctx->default_tcg_memop_mask);
4372        gen_store_fpr64(ctx, t1, rt);
4373        gen_store_fpr64(ctx, t0, lsq_rt1);
4374        tcg_temp_free(t1);
4375        break;
4376    case OPC_GSSQ:
4377        t1 = tcg_temp_new();
4378        gen_base_offset_addr(ctx, t0, rs, lsq_offset);
4379        gen_load_gpr(t1, rt);
4380        tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUQ |
4381                           ctx->default_tcg_memop_mask);
4382        gen_base_offset_addr(ctx, t0, rs, lsq_offset + 8);
4383        gen_load_gpr(t1, lsq_rt1);
4384        tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUQ |
4385                           ctx->default_tcg_memop_mask);
4386        tcg_temp_free(t1);
4387        break;
4388    case OPC_GSSQC1:
4389        check_cp1_enabled(ctx);
4390        t1 = tcg_temp_new();
4391        gen_base_offset_addr(ctx, t0, rs, lsq_offset);
4392        gen_load_fpr64(ctx, t1, rt);
4393        tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUQ |
4394                           ctx->default_tcg_memop_mask);
4395        gen_base_offset_addr(ctx, t0, rs, lsq_offset + 8);
4396        gen_load_fpr64(ctx, t1, lsq_rt1);
4397        tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUQ |
4398                           ctx->default_tcg_memop_mask);
4399        tcg_temp_free(t1);
4400        break;
4401#endif
4402    case OPC_GSSHFL:
4403        switch (MASK_LOONGSON_GSSHFLS(ctx->opcode)) {
4404        case OPC_GSLWLC1:
4405            check_cp1_enabled(ctx);
4406            gen_base_offset_addr(ctx, t0, rs, shf_offset);
4407            t1 = tcg_temp_new();
4408            tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_UB);
4409            tcg_gen_andi_tl(t1, t0, 3);
4410            if (!cpu_is_bigendian(ctx)) {
4411                tcg_gen_xori_tl(t1, t1, 3);
4412            }
4413            tcg_gen_shli_tl(t1, t1, 3);
4414            tcg_gen_andi_tl(t0, t0, ~3);
4415            tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEUL);
4416            tcg_gen_shl_tl(t0, t0, t1);
4417            t2 = tcg_const_tl(-1);
4418            tcg_gen_shl_tl(t2, t2, t1);
4419            fp0 = tcg_temp_new_i32();
4420            gen_load_fpr32(ctx, fp0, rt);
4421            tcg_gen_ext_i32_tl(t1, fp0);
4422            tcg_gen_andc_tl(t1, t1, t2);
4423            tcg_temp_free(t2);
4424            tcg_gen_or_tl(t0, t0, t1);
4425            tcg_temp_free(t1);
4426#if defined(TARGET_MIPS64)
4427            tcg_gen_extrl_i64_i32(fp0, t0);
4428#else
4429            tcg_gen_ext32s_tl(fp0, t0);
4430#endif
4431            gen_store_fpr32(ctx, fp0, rt);
4432            tcg_temp_free_i32(fp0);
4433            break;
4434        case OPC_GSLWRC1:
4435            check_cp1_enabled(ctx);
4436            gen_base_offset_addr(ctx, t0, rs, shf_offset);
4437            t1 = tcg_temp_new();
4438            tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_UB);
4439            tcg_gen_andi_tl(t1, t0, 3);
4440            if (cpu_is_bigendian(ctx)) {
4441                tcg_gen_xori_tl(t1, t1, 3);
4442            }
4443            tcg_gen_shli_tl(t1, t1, 3);
4444            tcg_gen_andi_tl(t0, t0, ~3);
4445            tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEUL);
4446            tcg_gen_shr_tl(t0, t0, t1);
4447            tcg_gen_xori_tl(t1, t1, 31);
4448            t2 = tcg_const_tl(0xfffffffeull);
4449            tcg_gen_shl_tl(t2, t2, t1);
4450            fp0 = tcg_temp_new_i32();
4451            gen_load_fpr32(ctx, fp0, rt);
4452            tcg_gen_ext_i32_tl(t1, fp0);
4453            tcg_gen_and_tl(t1, t1, t2);
4454            tcg_temp_free(t2);
4455            tcg_gen_or_tl(t0, t0, t1);
4456            tcg_temp_free(t1);
4457#if defined(TARGET_MIPS64)
4458            tcg_gen_extrl_i64_i32(fp0, t0);
4459#else
4460            tcg_gen_ext32s_tl(fp0, t0);
4461#endif
4462            gen_store_fpr32(ctx, fp0, rt);
4463            tcg_temp_free_i32(fp0);
4464            break;
4465#if defined(TARGET_MIPS64)
4466        case OPC_GSLDLC1:
4467            check_cp1_enabled(ctx);
4468            gen_base_offset_addr(ctx, t0, rs, shf_offset);
4469            t1 = tcg_temp_new();
4470            tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_UB);
4471            tcg_gen_andi_tl(t1, t0, 7);
4472            if (!cpu_is_bigendian(ctx)) {
4473                tcg_gen_xori_tl(t1, t1, 7);
4474            }
4475            tcg_gen_shli_tl(t1, t1, 3);
4476            tcg_gen_andi_tl(t0, t0, ~7);
4477            tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEUQ);
4478            tcg_gen_shl_tl(t0, t0, t1);
4479            t2 = tcg_const_tl(-1);
4480            tcg_gen_shl_tl(t2, t2, t1);
4481            gen_load_fpr64(ctx, t1, rt);
4482            tcg_gen_andc_tl(t1, t1, t2);
4483            tcg_temp_free(t2);
4484            tcg_gen_or_tl(t0, t0, t1);
4485            tcg_temp_free(t1);
4486            gen_store_fpr64(ctx, t0, rt);
4487            break;
4488        case OPC_GSLDRC1:
4489            check_cp1_enabled(ctx);
4490            gen_base_offset_addr(ctx, t0, rs, shf_offset);
4491            t1 = tcg_temp_new();
4492            tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_UB);
4493            tcg_gen_andi_tl(t1, t0, 7);
4494            if (cpu_is_bigendian(ctx)) {
4495                tcg_gen_xori_tl(t1, t1, 7);
4496            }
4497            tcg_gen_shli_tl(t1, t1, 3);
4498            tcg_gen_andi_tl(t0, t0, ~7);
4499            tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEUQ);
4500            tcg_gen_shr_tl(t0, t0, t1);
4501            tcg_gen_xori_tl(t1, t1, 63);
4502            t2 = tcg_const_tl(0xfffffffffffffffeull);
4503            tcg_gen_shl_tl(t2, t2, t1);
4504            gen_load_fpr64(ctx, t1, rt);
4505            tcg_gen_and_tl(t1, t1, t2);
4506            tcg_temp_free(t2);
4507            tcg_gen_or_tl(t0, t0, t1);
4508            tcg_temp_free(t1);
4509            gen_store_fpr64(ctx, t0, rt);
4510            break;
4511#endif
4512        default:
4513            MIPS_INVAL("loongson_gsshfl");
4514            gen_reserved_instruction(ctx);
4515            break;
4516        }
4517        break;
4518    case OPC_GSSHFS:
4519        switch (MASK_LOONGSON_GSSHFLS(ctx->opcode)) {
4520        case OPC_GSSWLC1:
4521            check_cp1_enabled(ctx);
4522            t1 = tcg_temp_new();
4523            gen_base_offset_addr(ctx, t0, rs, shf_offset);
4524            fp0 = tcg_temp_new_i32();
4525            gen_load_fpr32(ctx, fp0, rt);
4526            tcg_gen_ext_i32_tl(t1, fp0);
4527            gen_helper_0e2i(swl, t1, t0, ctx->mem_idx);
4528            tcg_temp_free_i32(fp0);
4529            tcg_temp_free(t1);
4530            break;
4531        case OPC_GSSWRC1:
4532            check_cp1_enabled(ctx);
4533            t1 = tcg_temp_new();
4534            gen_base_offset_addr(ctx, t0, rs, shf_offset);
4535            fp0 = tcg_temp_new_i32();
4536            gen_load_fpr32(ctx, fp0, rt);
4537            tcg_gen_ext_i32_tl(t1, fp0);
4538            gen_helper_0e2i(swr, t1, t0, ctx->mem_idx);
4539            tcg_temp_free_i32(fp0);
4540            tcg_temp_free(t1);
4541            break;
4542#if defined(TARGET_MIPS64)
4543        case OPC_GSSDLC1:
4544            check_cp1_enabled(ctx);
4545            t1 = tcg_temp_new();
4546            gen_base_offset_addr(ctx, t0, rs, shf_offset);
4547            gen_load_fpr64(ctx, t1, rt);
4548            gen_helper_0e2i(sdl, t1, t0, ctx->mem_idx);
4549            tcg_temp_free(t1);
4550            break;
4551        case OPC_GSSDRC1:
4552            check_cp1_enabled(ctx);
4553            t1 = tcg_temp_new();
4554            gen_base_offset_addr(ctx, t0, rs, shf_offset);
4555            gen_load_fpr64(ctx, t1, rt);
4556            gen_helper_0e2i(sdr, t1, t0, ctx->mem_idx);
4557            tcg_temp_free(t1);
4558            break;
4559#endif
4560        default:
4561            MIPS_INVAL("loongson_gsshfs");
4562            gen_reserved_instruction(ctx);
4563            break;
4564        }
4565        break;
4566    default:
4567        MIPS_INVAL("loongson_gslsq");
4568        gen_reserved_instruction(ctx);
4569        break;
4570    }
4571    tcg_temp_free(t0);
4572}
4573
4574/* Loongson EXT LDC2/SDC2 */
4575static void gen_loongson_lsdc2(DisasContext *ctx, int rt,
4576                               int rs, int rd)
4577{
4578    int offset = sextract32(ctx->opcode, 3, 8);
4579    uint32_t opc = MASK_LOONGSON_LSDC2(ctx->opcode);
4580    TCGv t0, t1;
4581    TCGv_i32 fp0;
4582
4583    /* Pre-conditions */
4584    switch (opc) {
4585    case OPC_GSLBX:
4586    case OPC_GSLHX:
4587    case OPC_GSLWX:
4588    case OPC_GSLDX:
4589        /* prefetch, implement as NOP */
4590        if (rt == 0) {
4591            return;
4592        }
4593        break;
4594    case OPC_GSSBX:
4595    case OPC_GSSHX:
4596    case OPC_GSSWX:
4597    case OPC_GSSDX:
4598        break;
4599    case OPC_GSLWXC1:
4600#if defined(TARGET_MIPS64)
4601    case OPC_GSLDXC1:
4602#endif
4603        check_cp1_enabled(ctx);
4604        /* prefetch, implement as NOP */
4605        if (rt == 0) {
4606            return;
4607        }
4608        break;
4609    case OPC_GSSWXC1:
4610#if defined(TARGET_MIPS64)
4611    case OPC_GSSDXC1:
4612#endif
4613        check_cp1_enabled(ctx);
4614        break;
4615    default:
4616        MIPS_INVAL("loongson_lsdc2");
4617        gen_reserved_instruction(ctx);
4618        return;
4619        break;
4620    }
4621
4622    t0 = tcg_temp_new();
4623
4624    gen_base_offset_addr(ctx, t0, rs, offset);
4625    gen_op_addr_add(ctx, t0, cpu_gpr[rd], t0);
4626
4627    switch (opc) {
4628    case OPC_GSLBX:
4629        tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_SB);
4630        gen_store_gpr(t0, rt);
4631        break;
4632    case OPC_GSLHX:
4633        tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TESW |
4634                           ctx->default_tcg_memop_mask);
4635        gen_store_gpr(t0, rt);
4636        break;
4637    case OPC_GSLWX:
4638        gen_base_offset_addr(ctx, t0, rs, offset);
4639        if (rd) {
4640            gen_op_addr_add(ctx, t0, cpu_gpr[rd], t0);
4641        }
4642        tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TESL |
4643                           ctx->default_tcg_memop_mask);
4644        gen_store_gpr(t0, rt);
4645        break;
4646#if defined(TARGET_MIPS64)
4647    case OPC_GSLDX:
4648        gen_base_offset_addr(ctx, t0, rs, offset);
4649        if (rd) {
4650            gen_op_addr_add(ctx, t0, cpu_gpr[rd], t0);
4651        }
4652        tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEUQ |
4653                           ctx->default_tcg_memop_mask);
4654        gen_store_gpr(t0, rt);
4655        break;
4656#endif
4657    case OPC_GSLWXC1:
4658        gen_base_offset_addr(ctx, t0, rs, offset);
4659        if (rd) {
4660            gen_op_addr_add(ctx, t0, cpu_gpr[rd], t0);
4661        }
4662        fp0 = tcg_temp_new_i32();
4663        tcg_gen_qemu_ld_i32(fp0, t0, ctx->mem_idx, MO_TESL |
4664                            ctx->default_tcg_memop_mask);
4665        gen_store_fpr32(ctx, fp0, rt);
4666        tcg_temp_free_i32(fp0);
4667        break;
4668#if defined(TARGET_MIPS64)
4669    case OPC_GSLDXC1:
4670        gen_base_offset_addr(ctx, t0, rs, offset);
4671        if (rd) {
4672            gen_op_addr_add(ctx, t0, cpu_gpr[rd], t0);
4673        }
4674        tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEUQ |
4675                           ctx->default_tcg_memop_mask);
4676        gen_store_fpr64(ctx, t0, rt);
4677        break;
4678#endif
4679    case OPC_GSSBX:
4680        t1 = tcg_temp_new();
4681        gen_load_gpr(t1, rt);
4682        tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_SB);
4683        tcg_temp_free(t1);
4684        break;
4685    case OPC_GSSHX:
4686        t1 = tcg_temp_new();
4687        gen_load_gpr(t1, rt);
4688        tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUW |
4689                           ctx->default_tcg_memop_mask);
4690        tcg_temp_free(t1);
4691        break;
4692    case OPC_GSSWX:
4693        t1 = tcg_temp_new();
4694        gen_load_gpr(t1, rt);
4695        tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL |
4696                           ctx->default_tcg_memop_mask);
4697        tcg_temp_free(t1);
4698        break;
4699#if defined(TARGET_MIPS64)
4700    case OPC_GSSDX:
4701        t1 = tcg_temp_new();
4702        gen_load_gpr(t1, rt);
4703        tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUQ |
4704                           ctx->default_tcg_memop_mask);
4705        tcg_temp_free(t1);
4706        break;
4707#endif
4708    case OPC_GSSWXC1:
4709        fp0 = tcg_temp_new_i32();
4710        gen_load_fpr32(ctx, fp0, rt);
4711        tcg_gen_qemu_st_i32(fp0, t0, ctx->mem_idx, MO_TEUL |
4712                            ctx->default_tcg_memop_mask);
4713        tcg_temp_free_i32(fp0);
4714        break;
4715#if defined(TARGET_MIPS64)
4716    case OPC_GSSDXC1:
4717        t1 = tcg_temp_new();
4718        gen_load_fpr64(ctx, t1, rt);
4719        tcg_gen_qemu_st_i64(t1, t0, ctx->mem_idx, MO_TEUQ |
4720                            ctx->default_tcg_memop_mask);
4721        tcg_temp_free(t1);
4722        break;
4723#endif
4724    default:
4725        break;
4726    }
4727
4728    tcg_temp_free(t0);
4729}
4730
4731/* Traps */
4732static void gen_trap(DisasContext *ctx, uint32_t opc,
4733                     int rs, int rt, int16_t imm, int code)
4734{
4735    int cond;
4736    TCGv t0 = tcg_temp_new();
4737    TCGv t1 = tcg_temp_new();
4738
4739    cond = 0;
4740    /* Load needed operands */
4741    switch (opc) {
4742    case OPC_TEQ:
4743    case OPC_TGE:
4744    case OPC_TGEU:
4745    case OPC_TLT:
4746    case OPC_TLTU:
4747    case OPC_TNE:
4748        /* Compare two registers */
4749        if (rs != rt) {
4750            gen_load_gpr(t0, rs);
4751            gen_load_gpr(t1, rt);
4752            cond = 1;
4753        }
4754        break;
4755    case OPC_TEQI:
4756    case OPC_TGEI:
4757    case OPC_TGEIU:
4758    case OPC_TLTI:
4759    case OPC_TLTIU:
4760    case OPC_TNEI:
4761        /* Compare register to immediate */
4762        if (rs != 0 || imm != 0) {
4763            gen_load_gpr(t0, rs);
4764            tcg_gen_movi_tl(t1, (int32_t)imm);
4765            cond = 1;
4766        }
4767        break;
4768    }
4769    if (cond == 0) {
4770        switch (opc) {
4771        case OPC_TEQ:   /* rs == rs */
4772        case OPC_TEQI:  /* r0 == 0  */
4773        case OPC_TGE:   /* rs >= rs */
4774        case OPC_TGEI:  /* r0 >= 0  */
4775        case OPC_TGEU:  /* rs >= rs unsigned */
4776        case OPC_TGEIU: /* r0 >= 0  unsigned */
4777            /* Always trap */
4778#ifdef CONFIG_USER_ONLY
4779            /* Pass the break code along to cpu_loop. */
4780            tcg_gen_st_i32(tcg_constant_i32(code), cpu_env,
4781                           offsetof(CPUMIPSState, error_code));
4782#endif
4783            generate_exception_end(ctx, EXCP_TRAP);
4784            break;
4785        case OPC_TLT:   /* rs < rs           */
4786        case OPC_TLTI:  /* r0 < 0            */
4787        case OPC_TLTU:  /* rs < rs unsigned  */
4788        case OPC_TLTIU: /* r0 < 0  unsigned  */
4789        case OPC_TNE:   /* rs != rs          */
4790        case OPC_TNEI:  /* r0 != 0           */
4791            /* Never trap: treat as NOP. */
4792            break;
4793        }
4794    } else {
4795        TCGLabel *l1 = gen_new_label();
4796
4797        switch (opc) {
4798        case OPC_TEQ:
4799        case OPC_TEQI:
4800            tcg_gen_brcond_tl(TCG_COND_NE, t0, t1, l1);
4801            break;
4802        case OPC_TGE:
4803        case OPC_TGEI:
4804            tcg_gen_brcond_tl(TCG_COND_LT, t0, t1, l1);
4805            break;
4806        case OPC_TGEU:
4807        case OPC_TGEIU:
4808            tcg_gen_brcond_tl(TCG_COND_LTU, t0, t1, l1);
4809            break;
4810        case OPC_TLT:
4811        case OPC_TLTI:
4812            tcg_gen_brcond_tl(TCG_COND_GE, t0, t1, l1);
4813            break;
4814        case OPC_TLTU:
4815        case OPC_TLTIU:
4816            tcg_gen_brcond_tl(TCG_COND_GEU, t0, t1, l1);
4817            break;
4818        case OPC_TNE:
4819        case OPC_TNEI:
4820            tcg_gen_brcond_tl(TCG_COND_EQ, t0, t1, l1);
4821            break;
4822        }
4823#ifdef CONFIG_USER_ONLY
4824        /* Pass the break code along to cpu_loop. */
4825        tcg_gen_st_i32(tcg_constant_i32(code), cpu_env,
4826                       offsetof(CPUMIPSState, error_code));
4827#endif
4828        /* Like save_cpu_state, only don't update saved values. */
4829        if (ctx->base.pc_next != ctx->saved_pc) {
4830            gen_save_pc(ctx->base.pc_next);
4831        }
4832        if (ctx->hflags != ctx->saved_hflags) {
4833            tcg_gen_movi_i32(hflags, ctx->hflags);
4834        }
4835        generate_exception(ctx, EXCP_TRAP);
4836        gen_set_label(l1);
4837    }
4838    tcg_temp_free(t0);
4839    tcg_temp_free(t1);
4840}
4841
4842static void gen_goto_tb(DisasContext *ctx, int n, target_ulong dest)
4843{
4844    if (translator_use_goto_tb(&ctx->base, dest)) {
4845        tcg_gen_goto_tb(n);
4846        gen_save_pc(dest);
4847        tcg_gen_exit_tb(ctx->base.tb, n);
4848    } else {
4849        gen_save_pc(dest);
4850        tcg_gen_lookup_and_goto_ptr();
4851    }
4852}
4853
4854/* Branches (before delay slot) */
4855static void gen_compute_branch(DisasContext *ctx, uint32_t opc,
4856                               int insn_bytes,
4857                               int rs, int rt, int32_t offset,
4858                               int delayslot_size)
4859{
4860    target_ulong btgt = -1;
4861    int blink = 0;
4862    int bcond_compute = 0;
4863    TCGv t0 = tcg_temp_new();
4864    TCGv t1 = tcg_temp_new();
4865
4866    if (ctx->hflags & MIPS_HFLAG_BMASK) {
4867#ifdef MIPS_DEBUG_DISAS
4868        LOG_DISAS("Branch in delay / forbidden slot at PC 0x"
4869                  TARGET_FMT_lx "\n", ctx->base.pc_next);
4870#endif
4871        gen_reserved_instruction(ctx);
4872        goto out;
4873    }
4874
4875    /* Load needed operands */
4876    switch (opc) {
4877    case OPC_BEQ:
4878    case OPC_BEQL:
4879    case OPC_BNE:
4880    case OPC_BNEL:
4881        /* Compare two registers */
4882        if (rs != rt) {
4883            gen_load_gpr(t0, rs);
4884            gen_load_gpr(t1, rt);
4885            bcond_compute = 1;
4886        }
4887        btgt = ctx->base.pc_next + insn_bytes + offset;
4888        break;
4889    case OPC_BGEZ:
4890    case OPC_BGEZAL:
4891    case OPC_BGEZALL:
4892    case OPC_BGEZL:
4893    case OPC_BGTZ:
4894    case OPC_BGTZL:
4895    case OPC_BLEZ:
4896    case OPC_BLEZL:
4897    case OPC_BLTZ:
4898    case OPC_BLTZAL:
4899    case OPC_BLTZALL:
4900    case OPC_BLTZL:
4901        /* Compare to zero */
4902        if (rs != 0) {
4903            gen_load_gpr(t0, rs);
4904            bcond_compute = 1;
4905        }
4906        btgt = ctx->base.pc_next + insn_bytes + offset;
4907        break;
4908    case OPC_BPOSGE32:
4909#if defined(TARGET_MIPS64)
4910    case OPC_BPOSGE64:
4911        tcg_gen_andi_tl(t0, cpu_dspctrl, 0x7F);
4912#else
4913        tcg_gen_andi_tl(t0, cpu_dspctrl, 0x3F);
4914#endif
4915        bcond_compute = 1;
4916        btgt = ctx->base.pc_next + insn_bytes + offset;
4917        break;
4918    case OPC_J:
4919    case OPC_JAL:
4920    case OPC_JALX:
4921        /* Jump to immediate */
4922        btgt = ((ctx->base.pc_next + insn_bytes) & (int32_t)0xF0000000) |
4923            (uint32_t)offset;
4924        break;
4925    case OPC_JR:
4926    case OPC_JALR:
4927        /* Jump to register */
4928        if (offset != 0 && offset != 16) {
4929            /*
4930             * Hint = 0 is JR/JALR, hint 16 is JR.HB/JALR.HB, the
4931             * others are reserved.
4932             */
4933            MIPS_INVAL("jump hint");
4934            gen_reserved_instruction(ctx);
4935            goto out;
4936        }
4937        gen_load_gpr(btarget, rs);
4938        break;
4939    default:
4940        MIPS_INVAL("branch/jump");
4941        gen_reserved_instruction(ctx);
4942        goto out;
4943    }
4944    if (bcond_compute == 0) {
4945        /* No condition to be computed */
4946        switch (opc) {
4947        case OPC_BEQ:     /* rx == rx        */
4948        case OPC_BEQL:    /* rx == rx likely */
4949        case OPC_BGEZ:    /* 0 >= 0          */
4950        case OPC_BGEZL:   /* 0 >= 0 likely   */
4951        case OPC_BLEZ:    /* 0 <= 0          */
4952        case OPC_BLEZL:   /* 0 <= 0 likely   */
4953            /* Always take */
4954            ctx->hflags |= MIPS_HFLAG_B;
4955            break;
4956        case OPC_BGEZAL:  /* 0 >= 0          */
4957        case OPC_BGEZALL: /* 0 >= 0 likely   */
4958            /* Always take and link */
4959            blink = 31;
4960            ctx->hflags |= MIPS_HFLAG_B;
4961            break;
4962        case OPC_BNE:     /* rx != rx        */
4963        case OPC_BGTZ:    /* 0 > 0           */
4964        case OPC_BLTZ:    /* 0 < 0           */
4965            /* Treat as NOP. */
4966            goto out;
4967        case OPC_BLTZAL:  /* 0 < 0           */
4968            /*
4969             * Handle as an unconditional branch to get correct delay
4970             * slot checking.
4971             */
4972            blink = 31;
4973            btgt = ctx->base.pc_next + insn_bytes + delayslot_size;
4974            ctx->hflags |= MIPS_HFLAG_B;
4975            break;
4976        case OPC_BLTZALL: /* 0 < 0 likely */
4977            tcg_gen_movi_tl(cpu_gpr[31], ctx->base.pc_next + 8);
4978            /* Skip the instruction in the delay slot */
4979            ctx->base.pc_next += 4;
4980            goto out;
4981        case OPC_BNEL:    /* rx != rx likely */
4982        case OPC_BGTZL:   /* 0 > 0 likely */
4983        case OPC_BLTZL:   /* 0 < 0 likely */
4984            /* Skip the instruction in the delay slot */
4985            ctx->base.pc_next += 4;
4986            goto out;
4987        case OPC_J:
4988            ctx->hflags |= MIPS_HFLAG_B;
4989            break;
4990        case OPC_JALX:
4991            ctx->hflags |= MIPS_HFLAG_BX;
4992            /* Fallthrough */
4993        case OPC_JAL:
4994            blink = 31;
4995            ctx->hflags |= MIPS_HFLAG_B;
4996            break;
4997        case OPC_JR:
4998            ctx->hflags |= MIPS_HFLAG_BR;
4999            break;
5000        case OPC_JALR:
5001            blink = rt;
5002            ctx->hflags |= MIPS_HFLAG_BR;
5003            break;
5004        default:
5005            MIPS_INVAL("branch/jump");
5006            gen_reserved_instruction(ctx);
5007            goto out;
5008        }
5009    } else {
5010        switch (opc) {
5011        case OPC_BEQ:
5012            tcg_gen_setcond_tl(TCG_COND_EQ, bcond, t0, t1);
5013            goto not_likely;
5014        case OPC_BEQL:
5015            tcg_gen_setcond_tl(TCG_COND_EQ, bcond, t0, t1);
5016            goto likely;
5017        case OPC_BNE:
5018            tcg_gen_setcond_tl(TCG_COND_NE, bcond, t0, t1);
5019            goto not_likely;
5020        case OPC_BNEL:
5021            tcg_gen_setcond_tl(TCG_COND_NE, bcond, t0, t1);
5022            goto likely;
5023        case OPC_BGEZ:
5024            tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
5025            goto not_likely;
5026        case OPC_BGEZL:
5027            tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
5028            goto likely;
5029        case OPC_BGEZAL:
5030            tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
5031            blink = 31;
5032            goto not_likely;
5033        case OPC_BGEZALL:
5034            tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
5035            blink = 31;
5036            goto likely;
5037        case OPC_BGTZ:
5038            tcg_gen_setcondi_tl(TCG_COND_GT, bcond, t0, 0);
5039            goto not_likely;
5040        case OPC_BGTZL:
5041            tcg_gen_setcondi_tl(TCG_COND_GT, bcond, t0, 0);
5042            goto likely;
5043        case OPC_BLEZ:
5044            tcg_gen_setcondi_tl(TCG_COND_LE, bcond, t0, 0);
5045            goto not_likely;
5046        case OPC_BLEZL:
5047            tcg_gen_setcondi_tl(TCG_COND_LE, bcond, t0, 0);
5048            goto likely;
5049        case OPC_BLTZ:
5050            tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
5051            goto not_likely;
5052        case OPC_BLTZL:
5053            tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
5054            goto likely;
5055        case OPC_BPOSGE32:
5056            tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 32);
5057            goto not_likely;
5058#if defined(TARGET_MIPS64)
5059        case OPC_BPOSGE64:
5060            tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 64);
5061            goto not_likely;
5062#endif
5063        case OPC_BLTZAL:
5064            tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
5065            blink = 31;
5066        not_likely:
5067            ctx->hflags |= MIPS_HFLAG_BC;
5068            break;
5069        case OPC_BLTZALL:
5070            tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
5071            blink = 31;
5072        likely:
5073            ctx->hflags |= MIPS_HFLAG_BL;
5074            break;
5075        default:
5076            MIPS_INVAL("conditional branch/jump");
5077            gen_reserved_instruction(ctx);
5078            goto out;
5079        }
5080    }
5081
5082    ctx->btarget = btgt;
5083
5084    switch (delayslot_size) {
5085    case 2:
5086        ctx->hflags |= MIPS_HFLAG_BDS16;
5087        break;
5088    case 4:
5089        ctx->hflags |= MIPS_HFLAG_BDS32;
5090        break;
5091    }
5092
5093    if (blink > 0) {
5094        int post_delay = insn_bytes + delayslot_size;
5095        int lowbit = !!(ctx->hflags & MIPS_HFLAG_M16);
5096
5097        tcg_gen_movi_tl(cpu_gpr[blink],
5098                        ctx->base.pc_next + post_delay + lowbit);
5099    }
5100
5101 out:
5102    if (insn_bytes == 2) {
5103        ctx->hflags |= MIPS_HFLAG_B16;
5104    }
5105    tcg_temp_free(t0);
5106    tcg_temp_free(t1);
5107}
5108
5109
5110/* special3 bitfield operations */
5111static void gen_bitops(DisasContext *ctx, uint32_t opc, int rt,
5112                       int rs, int lsb, int msb)
5113{
5114    TCGv t0 = tcg_temp_new();
5115    TCGv t1 = tcg_temp_new();
5116
5117    gen_load_gpr(t1, rs);
5118    switch (opc) {
5119    case OPC_EXT:
5120        if (lsb + msb > 31) {
5121            goto fail;
5122        }
5123        if (msb != 31) {
5124            tcg_gen_extract_tl(t0, t1, lsb, msb + 1);
5125        } else {
5126            /*
5127             * The two checks together imply that lsb == 0,
5128             * so this is a simple sign-extension.
5129             */
5130            tcg_gen_ext32s_tl(t0, t1);
5131        }
5132        break;
5133#if defined(TARGET_MIPS64)
5134    case OPC_DEXTU:
5135        lsb += 32;
5136        goto do_dext;
5137    case OPC_DEXTM:
5138        msb += 32;
5139        goto do_dext;
5140    case OPC_DEXT:
5141    do_dext:
5142        if (lsb + msb > 63) {
5143            goto fail;
5144        }
5145        tcg_gen_extract_tl(t0, t1, lsb, msb + 1);
5146        break;
5147#endif
5148    case OPC_INS:
5149        if (lsb > msb) {
5150            goto fail;
5151        }
5152        gen_load_gpr(t0, rt);
5153        tcg_gen_deposit_tl(t0, t0, t1, lsb, msb - lsb + 1);
5154        tcg_gen_ext32s_tl(t0, t0);
5155        break;
5156#if defined(TARGET_MIPS64)
5157    case OPC_DINSU:
5158        lsb += 32;
5159        /* FALLTHRU */
5160    case OPC_DINSM:
5161        msb += 32;
5162        /* FALLTHRU */
5163    case OPC_DINS:
5164        if (lsb > msb) {
5165            goto fail;
5166        }
5167        gen_load_gpr(t0, rt);
5168        tcg_gen_deposit_tl(t0, t0, t1, lsb, msb - lsb + 1);
5169        break;
5170#endif
5171    default:
5172fail:
5173        MIPS_INVAL("bitops");
5174        gen_reserved_instruction(ctx);
5175        tcg_temp_free(t0);
5176        tcg_temp_free(t1);
5177        return;
5178    }
5179    gen_store_gpr(t0, rt);
5180    tcg_temp_free(t0);
5181    tcg_temp_free(t1);
5182}
5183
5184static void gen_bshfl(DisasContext *ctx, uint32_t op2, int rt, int rd)
5185{
5186    TCGv t0;
5187
5188    if (rd == 0) {
5189        /* If no destination, treat it as a NOP. */
5190        return;
5191    }
5192
5193    t0 = tcg_temp_new();
5194    gen_load_gpr(t0, rt);
5195    switch (op2) {
5196    case OPC_WSBH:
5197        {
5198            TCGv t1 = tcg_temp_new();
5199            TCGv t2 = tcg_const_tl(0x00FF00FF);
5200
5201            tcg_gen_shri_tl(t1, t0, 8);
5202            tcg_gen_and_tl(t1, t1, t2);
5203            tcg_gen_and_tl(t0, t0, t2);
5204            tcg_gen_shli_tl(t0, t0, 8);
5205            tcg_gen_or_tl(t0, t0, t1);
5206            tcg_temp_free(t2);
5207            tcg_temp_free(t1);
5208            tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
5209        }
5210        break;
5211    case OPC_SEB:
5212        tcg_gen_ext8s_tl(cpu_gpr[rd], t0);
5213        break;
5214    case OPC_SEH:
5215        tcg_gen_ext16s_tl(cpu_gpr[rd], t0);
5216        break;
5217#if defined(TARGET_MIPS64)
5218    case OPC_DSBH:
5219        {
5220            TCGv t1 = tcg_temp_new();
5221            TCGv t2 = tcg_const_tl(0x00FF00FF00FF00FFULL);
5222
5223            tcg_gen_shri_tl(t1, t0, 8);
5224            tcg_gen_and_tl(t1, t1, t2);
5225            tcg_gen_and_tl(t0, t0, t2);
5226            tcg_gen_shli_tl(t0, t0, 8);
5227            tcg_gen_or_tl(cpu_gpr[rd], t0, t1);
5228            tcg_temp_free(t2);
5229            tcg_temp_free(t1);
5230        }
5231        break;
5232    case OPC_DSHD:
5233        {
5234            TCGv t1 = tcg_temp_new();
5235            TCGv t2 = tcg_const_tl(0x0000FFFF0000FFFFULL);
5236
5237            tcg_gen_shri_tl(t1, t0, 16);
5238            tcg_gen_and_tl(t1, t1, t2);
5239            tcg_gen_and_tl(t0, t0, t2);
5240            tcg_gen_shli_tl(t0, t0, 16);
5241            tcg_gen_or_tl(t0, t0, t1);
5242            tcg_gen_shri_tl(t1, t0, 32);
5243            tcg_gen_shli_tl(t0, t0, 32);
5244            tcg_gen_or_tl(cpu_gpr[rd], t0, t1);
5245            tcg_temp_free(t2);
5246            tcg_temp_free(t1);
5247        }
5248        break;
5249#endif
5250    default:
5251        MIPS_INVAL("bsfhl");
5252        gen_reserved_instruction(ctx);
5253        tcg_temp_free(t0);
5254        return;
5255    }
5256    tcg_temp_free(t0);
5257}
5258
5259static void gen_align_bits(DisasContext *ctx, int wordsz, int rd, int rs,
5260                           int rt, int bits)
5261{
5262    TCGv t0;
5263    if (rd == 0) {
5264        /* Treat as NOP. */
5265        return;
5266    }
5267    t0 = tcg_temp_new();
5268    if (bits == 0 || bits == wordsz) {
5269        if (bits == 0) {
5270            gen_load_gpr(t0, rt);
5271        } else {
5272            gen_load_gpr(t0, rs);
5273        }
5274        switch (wordsz) {
5275        case 32:
5276            tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
5277            break;
5278#if defined(TARGET_MIPS64)
5279        case 64:
5280            tcg_gen_mov_tl(cpu_gpr[rd], t0);
5281            break;
5282#endif
5283        }
5284    } else {
5285        TCGv t1 = tcg_temp_new();
5286        gen_load_gpr(t0, rt);
5287        gen_load_gpr(t1, rs);
5288        switch (wordsz) {
5289        case 32:
5290            {
5291                TCGv_i64 t2 = tcg_temp_new_i64();
5292                tcg_gen_concat_tl_i64(t2, t1, t0);
5293                tcg_gen_shri_i64(t2, t2, 32 - bits);
5294                gen_move_low32(cpu_gpr[rd], t2);
5295                tcg_temp_free_i64(t2);
5296            }
5297            break;
5298#if defined(TARGET_MIPS64)
5299        case 64:
5300            tcg_gen_shli_tl(t0, t0, bits);
5301            tcg_gen_shri_tl(t1, t1, 64 - bits);
5302            tcg_gen_or_tl(cpu_gpr[rd], t1, t0);
5303            break;
5304#endif
5305        }
5306        tcg_temp_free(t1);
5307    }
5308
5309    tcg_temp_free(t0);
5310}
5311
5312void gen_align(DisasContext *ctx, int wordsz, int rd, int rs, int rt, int bp)
5313{
5314    gen_align_bits(ctx, wordsz, rd, rs, rt, bp * 8);
5315}
5316
5317static void gen_bitswap(DisasContext *ctx, int opc, int rd, int rt)
5318{
5319    TCGv t0;
5320    if (rd == 0) {
5321        /* Treat as NOP. */
5322        return;
5323    }
5324    t0 = tcg_temp_new();
5325    gen_load_gpr(t0, rt);
5326    switch (opc) {
5327    case OPC_BITSWAP:
5328        gen_helper_bitswap(cpu_gpr[rd], t0);
5329        break;
5330#if defined(TARGET_MIPS64)
5331    case OPC_DBITSWAP:
5332        gen_helper_dbitswap(cpu_gpr[rd], t0);
5333        break;
5334#endif
5335    }
5336    tcg_temp_free(t0);
5337}
5338
5339#ifndef CONFIG_USER_ONLY
5340/* CP0 (MMU and control) */
5341static inline void gen_mthc0_entrylo(TCGv arg, target_ulong off)
5342{
5343    TCGv_i64 t0 = tcg_temp_new_i64();
5344    TCGv_i64 t1 = tcg_temp_new_i64();
5345
5346    tcg_gen_ext_tl_i64(t0, arg);
5347    tcg_gen_ld_i64(t1, cpu_env, off);
5348#if defined(TARGET_MIPS64)
5349    tcg_gen_deposit_i64(t1, t1, t0, 30, 32);
5350#else
5351    tcg_gen_concat32_i64(t1, t1, t0);
5352#endif
5353    tcg_gen_st_i64(t1, cpu_env, off);
5354    tcg_temp_free_i64(t1);
5355    tcg_temp_free_i64(t0);
5356}
5357
5358static inline void gen_mthc0_store64(TCGv arg, target_ulong off)
5359{
5360    TCGv_i64 t0 = tcg_temp_new_i64();
5361    TCGv_i64 t1 = tcg_temp_new_i64();
5362
5363    tcg_gen_ext_tl_i64(t0, arg);
5364    tcg_gen_ld_i64(t1, cpu_env, off);
5365    tcg_gen_concat32_i64(t1, t1, t0);
5366    tcg_gen_st_i64(t1, cpu_env, off);
5367    tcg_temp_free_i64(t1);
5368    tcg_temp_free_i64(t0);
5369}
5370
5371static inline void gen_mfhc0_entrylo(TCGv arg, target_ulong off)
5372{
5373    TCGv_i64 t0 = tcg_temp_new_i64();
5374
5375    tcg_gen_ld_i64(t0, cpu_env, off);
5376#if defined(TARGET_MIPS64)
5377    tcg_gen_shri_i64(t0, t0, 30);
5378#else
5379    tcg_gen_shri_i64(t0, t0, 32);
5380#endif
5381    gen_move_low32(arg, t0);
5382    tcg_temp_free_i64(t0);
5383}
5384
5385static inline void gen_mfhc0_load64(TCGv arg, target_ulong off, int shift)
5386{
5387    TCGv_i64 t0 = tcg_temp_new_i64();
5388
5389    tcg_gen_ld_i64(t0, cpu_env, off);
5390    tcg_gen_shri_i64(t0, t0, 32 + shift);
5391    gen_move_low32(arg, t0);
5392    tcg_temp_free_i64(t0);
5393}
5394
5395static inline void gen_mfc0_load32(TCGv arg, target_ulong off)
5396{
5397    TCGv_i32 t0 = tcg_temp_new_i32();
5398
5399    tcg_gen_ld_i32(t0, cpu_env, off);
5400    tcg_gen_ext_i32_tl(arg, t0);
5401    tcg_temp_free_i32(t0);
5402}
5403
5404static inline void gen_mfc0_load64(TCGv arg, target_ulong off)
5405{
5406    tcg_gen_ld_tl(arg, cpu_env, off);
5407    tcg_gen_ext32s_tl(arg, arg);
5408}
5409
5410static inline void gen_mtc0_store32(TCGv arg, target_ulong off)
5411{
5412    TCGv_i32 t0 = tcg_temp_new_i32();
5413
5414    tcg_gen_trunc_tl_i32(t0, arg);
5415    tcg_gen_st_i32(t0, cpu_env, off);
5416    tcg_temp_free_i32(t0);
5417}
5418
5419#define CP0_CHECK(c)                            \
5420    do {                                        \
5421        if (!(c)) {                             \
5422            goto cp0_unimplemented;             \
5423        }                                       \
5424    } while (0)
5425
5426static void gen_mfhc0(DisasContext *ctx, TCGv arg, int reg, int sel)
5427{
5428    const char *register_name = "invalid";
5429
5430    switch (reg) {
5431    case CP0_REGISTER_02:
5432        switch (sel) {
5433        case 0:
5434            CP0_CHECK(ctx->hflags & MIPS_HFLAG_ELPA);
5435            gen_mfhc0_entrylo(arg, offsetof(CPUMIPSState, CP0_EntryLo0));
5436            register_name = "EntryLo0";
5437            break;
5438        default:
5439            goto cp0_unimplemented;
5440        }
5441        break;
5442    case CP0_REGISTER_03:
5443        switch (sel) {
5444        case CP0_REG03__ENTRYLO1:
5445            CP0_CHECK(ctx->hflags & MIPS_HFLAG_ELPA);
5446            gen_mfhc0_entrylo(arg, offsetof(CPUMIPSState, CP0_EntryLo1));
5447            register_name = "EntryLo1";
5448            break;
5449        default:
5450            goto cp0_unimplemented;
5451        }
5452        break;
5453    case CP0_REGISTER_09:
5454        switch (sel) {
5455        case CP0_REG09__SAAR:
5456            CP0_CHECK(ctx->saar);
5457            gen_helper_mfhc0_saar(arg, cpu_env);
5458            register_name = "SAAR";
5459            break;
5460        default:
5461            goto cp0_unimplemented;
5462        }
5463        break;
5464    case CP0_REGISTER_17:
5465        switch (sel) {
5466        case CP0_REG17__LLADDR:
5467            gen_mfhc0_load64(arg, offsetof(CPUMIPSState, CP0_LLAddr),
5468                             ctx->CP0_LLAddr_shift);
5469            register_name = "LLAddr";
5470            break;
5471        case CP0_REG17__MAAR:
5472            CP0_CHECK(ctx->mrp);
5473            gen_helper_mfhc0_maar(arg, cpu_env);
5474            register_name = "MAAR";
5475            break;
5476        default:
5477            goto cp0_unimplemented;
5478        }
5479        break;
5480    case CP0_REGISTER_19:
5481        switch (sel) {
5482        case CP0_REG19__WATCHHI0:
5483        case CP0_REG19__WATCHHI1:
5484        case CP0_REG19__WATCHHI2:
5485        case CP0_REG19__WATCHHI3:
5486        case CP0_REG19__WATCHHI4:
5487        case CP0_REG19__WATCHHI5:
5488        case CP0_REG19__WATCHHI6:
5489        case CP0_REG19__WATCHHI7:
5490            /* upper 32 bits are only available when Config5MI != 0 */
5491            CP0_CHECK(ctx->mi);
5492            gen_mfhc0_load64(arg, offsetof(CPUMIPSState, CP0_WatchHi[sel]), 0);
5493            register_name = "WatchHi";
5494            break;
5495        default:
5496            goto cp0_unimplemented;
5497        }
5498        break;
5499    case CP0_REGISTER_28:
5500        switch (sel) {
5501        case 0:
5502        case 2:
5503        case 4:
5504        case 6:
5505            gen_mfhc0_load64(arg, offsetof(CPUMIPSState, CP0_TagLo), 0);
5506            register_name = "TagLo";
5507            break;
5508        default:
5509            goto cp0_unimplemented;
5510        }
5511        break;
5512    default:
5513        goto cp0_unimplemented;
5514    }
5515    trace_mips_translate_c0("mfhc0", register_name, reg, sel);
5516    return;
5517
5518cp0_unimplemented:
5519    qemu_log_mask(LOG_UNIMP, "mfhc0 %s (reg %d sel %d)\n",
5520                  register_name, reg, sel);
5521    tcg_gen_movi_tl(arg, 0);
5522}
5523
5524static void gen_mthc0(DisasContext *ctx, TCGv arg, int reg, int sel)
5525{
5526    const char *register_name = "invalid";
5527    uint64_t mask = ctx->PAMask >> 36;
5528
5529    switch (reg) {
5530    case CP0_REGISTER_02:
5531        switch (sel) {
5532        case 0:
5533            CP0_CHECK(ctx->hflags & MIPS_HFLAG_ELPA);
5534            tcg_gen_andi_tl(arg, arg, mask);
5535            gen_mthc0_entrylo(arg, offsetof(CPUMIPSState, CP0_EntryLo0));
5536            register_name = "EntryLo0";
5537            break;
5538        default:
5539            goto cp0_unimplemented;
5540        }
5541        break;
5542    case CP0_REGISTER_03:
5543        switch (sel) {
5544        case CP0_REG03__ENTRYLO1:
5545            CP0_CHECK(ctx->hflags & MIPS_HFLAG_ELPA);
5546            tcg_gen_andi_tl(arg, arg, mask);
5547            gen_mthc0_entrylo(arg, offsetof(CPUMIPSState, CP0_EntryLo1));
5548            register_name = "EntryLo1";
5549            break;
5550        default:
5551            goto cp0_unimplemented;
5552        }
5553        break;
5554    case CP0_REGISTER_09:
5555        switch (sel) {
5556        case CP0_REG09__SAAR:
5557            CP0_CHECK(ctx->saar);
5558            gen_helper_mthc0_saar(cpu_env, arg);
5559            register_name = "SAAR";
5560            break;
5561        default:
5562            goto cp0_unimplemented;
5563        }
5564        break;
5565    case CP0_REGISTER_17:
5566        switch (sel) {
5567        case CP0_REG17__LLADDR:
5568            /*
5569             * LLAddr is read-only (the only exception is bit 0 if LLB is
5570             * supported); the CP0_LLAddr_rw_bitmask does not seem to be
5571             * relevant for modern MIPS cores supporting MTHC0, therefore
5572             * treating MTHC0 to LLAddr as NOP.
5573             */
5574            register_name = "LLAddr";
5575            break;
5576        case CP0_REG17__MAAR:
5577            CP0_CHECK(ctx->mrp);
5578            gen_helper_mthc0_maar(cpu_env, arg);
5579            register_name = "MAAR";
5580            break;
5581        default:
5582            goto cp0_unimplemented;
5583        }
5584        break;
5585    case CP0_REGISTER_19:
5586        switch (sel) {
5587        case CP0_REG19__WATCHHI0:
5588        case CP0_REG19__WATCHHI1:
5589        case CP0_REG19__WATCHHI2:
5590        case CP0_REG19__WATCHHI3:
5591        case CP0_REG19__WATCHHI4:
5592        case CP0_REG19__WATCHHI5:
5593        case CP0_REG19__WATCHHI6:
5594        case CP0_REG19__WATCHHI7:
5595            /* upper 32 bits are only available when Config5MI != 0 */
5596            CP0_CHECK(ctx->mi);
5597            gen_helper_0e1i(mthc0_watchhi, arg, sel);
5598            register_name = "WatchHi";
5599            break;
5600        default:
5601            goto cp0_unimplemented;
5602        }
5603        break;
5604    case CP0_REGISTER_28:
5605        switch (sel) {
5606        case 0:
5607        case 2:
5608        case 4:
5609        case 6:
5610            tcg_gen_andi_tl(arg, arg, mask);
5611            gen_mthc0_store64(arg, offsetof(CPUMIPSState, CP0_TagLo));
5612            register_name = "TagLo";
5613            break;
5614        default:
5615            goto cp0_unimplemented;
5616        }
5617        break;
5618    default:
5619        goto cp0_unimplemented;
5620    }
5621    trace_mips_translate_c0("mthc0", register_name, reg, sel);
5622    return;
5623
5624cp0_unimplemented:
5625    qemu_log_mask(LOG_UNIMP, "mthc0 %s (reg %d sel %d)\n",
5626                  register_name, reg, sel);
5627}
5628
5629static inline void gen_mfc0_unimplemented(DisasContext *ctx, TCGv arg)
5630{
5631    if (ctx->insn_flags & ISA_MIPS_R6) {
5632        tcg_gen_movi_tl(arg, 0);
5633    } else {
5634        tcg_gen_movi_tl(arg, ~0);
5635    }
5636}
5637
5638static void gen_mfc0(DisasContext *ctx, TCGv arg, int reg, int sel)
5639{
5640    const char *register_name = "invalid";
5641
5642    if (sel != 0) {
5643        check_insn(ctx, ISA_MIPS_R1);
5644    }
5645
5646    switch (reg) {
5647    case CP0_REGISTER_00:
5648        switch (sel) {
5649        case CP0_REG00__INDEX:
5650            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Index));
5651            register_name = "Index";
5652            break;
5653        case CP0_REG00__MVPCONTROL:
5654            CP0_CHECK(ctx->insn_flags & ASE_MT);
5655            gen_helper_mfc0_mvpcontrol(arg, cpu_env);
5656            register_name = "MVPControl";
5657            break;
5658        case CP0_REG00__MVPCONF0:
5659            CP0_CHECK(ctx->insn_flags & ASE_MT);
5660            gen_helper_mfc0_mvpconf0(arg, cpu_env);
5661            register_name = "MVPConf0";
5662            break;
5663        case CP0_REG00__MVPCONF1:
5664            CP0_CHECK(ctx->insn_flags & ASE_MT);
5665            gen_helper_mfc0_mvpconf1(arg, cpu_env);
5666            register_name = "MVPConf1";
5667            break;
5668        case CP0_REG00__VPCONTROL:
5669            CP0_CHECK(ctx->vp);
5670            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPControl));
5671            register_name = "VPControl";
5672            break;
5673        default:
5674            goto cp0_unimplemented;
5675        }
5676        break;
5677    case CP0_REGISTER_01:
5678        switch (sel) {
5679        case CP0_REG01__RANDOM:
5680            CP0_CHECK(!(ctx->insn_flags & ISA_MIPS_R6));
5681            gen_helper_mfc0_random(arg, cpu_env);
5682            register_name = "Random";
5683            break;
5684        case CP0_REG01__VPECONTROL:
5685            CP0_CHECK(ctx->insn_flags & ASE_MT);
5686            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEControl));
5687            register_name = "VPEControl";
5688            break;
5689        case CP0_REG01__VPECONF0:
5690            CP0_CHECK(ctx->insn_flags & ASE_MT);
5691            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf0));
5692            register_name = "VPEConf0";
5693            break;
5694        case CP0_REG01__VPECONF1:
5695            CP0_CHECK(ctx->insn_flags & ASE_MT);
5696            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf1));
5697            register_name = "VPEConf1";
5698            break;
5699        case CP0_REG01__YQMASK:
5700            CP0_CHECK(ctx->insn_flags & ASE_MT);
5701            gen_mfc0_load64(arg, offsetof(CPUMIPSState, CP0_YQMask));
5702            register_name = "YQMask";
5703            break;
5704        case CP0_REG01__VPESCHEDULE:
5705            CP0_CHECK(ctx->insn_flags & ASE_MT);
5706            gen_mfc0_load64(arg, offsetof(CPUMIPSState, CP0_VPESchedule));
5707            register_name = "VPESchedule";
5708            break;
5709        case CP0_REG01__VPESCHEFBACK:
5710            CP0_CHECK(ctx->insn_flags & ASE_MT);
5711            gen_mfc0_load64(arg, offsetof(CPUMIPSState, CP0_VPEScheFBack));
5712            register_name = "VPEScheFBack";
5713            break;
5714        case CP0_REG01__VPEOPT:
5715            CP0_CHECK(ctx->insn_flags & ASE_MT);
5716            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEOpt));
5717            register_name = "VPEOpt";
5718            break;
5719        default:
5720            goto cp0_unimplemented;
5721        }
5722        break;
5723    case CP0_REGISTER_02:
5724        switch (sel) {
5725        case CP0_REG02__ENTRYLO0:
5726            {
5727                TCGv_i64 tmp = tcg_temp_new_i64();
5728                tcg_gen_ld_i64(tmp, cpu_env,
5729                               offsetof(CPUMIPSState, CP0_EntryLo0));
5730#if defined(TARGET_MIPS64)
5731                if (ctx->rxi) {
5732                    /* Move RI/XI fields to bits 31:30 */
5733                    tcg_gen_shri_tl(arg, tmp, CP0EnLo_XI);
5734                    tcg_gen_deposit_tl(tmp, tmp, arg, 30, 2);
5735                }
5736#endif
5737                gen_move_low32(arg, tmp);
5738                tcg_temp_free_i64(tmp);
5739            }
5740            register_name = "EntryLo0";
5741            break;
5742        case CP0_REG02__TCSTATUS:
5743            CP0_CHECK(ctx->insn_flags & ASE_MT);
5744            gen_helper_mfc0_tcstatus(arg, cpu_env);
5745            register_name = "TCStatus";
5746            break;
5747        case CP0_REG02__TCBIND:
5748            CP0_CHECK(ctx->insn_flags & ASE_MT);
5749            gen_helper_mfc0_tcbind(arg, cpu_env);
5750            register_name = "TCBind";
5751            break;
5752        case CP0_REG02__TCRESTART:
5753            CP0_CHECK(ctx->insn_flags & ASE_MT);
5754            gen_helper_mfc0_tcrestart(arg, cpu_env);
5755            register_name = "TCRestart";
5756            break;
5757        case CP0_REG02__TCHALT:
5758            CP0_CHECK(ctx->insn_flags & ASE_MT);
5759            gen_helper_mfc0_tchalt(arg, cpu_env);
5760            register_name = "TCHalt";
5761            break;
5762        case CP0_REG02__TCCONTEXT:
5763            CP0_CHECK(ctx->insn_flags & ASE_MT);
5764            gen_helper_mfc0_tccontext(arg, cpu_env);
5765            register_name = "TCContext";
5766            break;
5767        case CP0_REG02__TCSCHEDULE:
5768            CP0_CHECK(ctx->insn_flags & ASE_MT);
5769            gen_helper_mfc0_tcschedule(arg, cpu_env);
5770            register_name = "TCSchedule";
5771            break;
5772        case CP0_REG02__TCSCHEFBACK:
5773            CP0_CHECK(ctx->insn_flags & ASE_MT);
5774            gen_helper_mfc0_tcschefback(arg, cpu_env);
5775            register_name = "TCScheFBack";
5776            break;
5777        default:
5778            goto cp0_unimplemented;
5779        }
5780        break;
5781    case CP0_REGISTER_03:
5782        switch (sel) {
5783        case CP0_REG03__ENTRYLO1:
5784            {
5785                TCGv_i64 tmp = tcg_temp_new_i64();
5786                tcg_gen_ld_i64(tmp, cpu_env,
5787                               offsetof(CPUMIPSState, CP0_EntryLo1));
5788#if defined(TARGET_MIPS64)
5789                if (ctx->rxi) {
5790                    /* Move RI/XI fields to bits 31:30 */
5791                    tcg_gen_shri_tl(arg, tmp, CP0EnLo_XI);
5792                    tcg_gen_deposit_tl(tmp, tmp, arg, 30, 2);
5793                }
5794#endif
5795                gen_move_low32(arg, tmp);
5796                tcg_temp_free_i64(tmp);
5797            }
5798            register_name = "EntryLo1";
5799            break;
5800        case CP0_REG03__GLOBALNUM:
5801            CP0_CHECK(ctx->vp);
5802            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_GlobalNumber));
5803            register_name = "GlobalNumber";
5804            break;
5805        default:
5806            goto cp0_unimplemented;
5807        }
5808        break;
5809    case CP0_REGISTER_04:
5810        switch (sel) {
5811        case CP0_REG04__CONTEXT:
5812            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_Context));
5813            tcg_gen_ext32s_tl(arg, arg);
5814            register_name = "Context";
5815            break;
5816        case CP0_REG04__CONTEXTCONFIG:
5817            /* SmartMIPS ASE */
5818            /* gen_helper_mfc0_contextconfig(arg); */
5819            register_name = "ContextConfig";
5820            goto cp0_unimplemented;
5821        case CP0_REG04__USERLOCAL:
5822            CP0_CHECK(ctx->ulri);
5823            tcg_gen_ld_tl(arg, cpu_env,
5824                          offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
5825            tcg_gen_ext32s_tl(arg, arg);
5826            register_name = "UserLocal";
5827            break;
5828        case CP0_REG04__MMID:
5829            CP0_CHECK(ctx->mi);
5830            gen_helper_mtc0_memorymapid(cpu_env, arg);
5831            register_name = "MMID";
5832            break;
5833        default:
5834            goto cp0_unimplemented;
5835        }
5836        break;
5837    case CP0_REGISTER_05:
5838        switch (sel) {
5839        case CP0_REG05__PAGEMASK:
5840            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageMask));
5841            register_name = "PageMask";
5842            break;
5843        case CP0_REG05__PAGEGRAIN:
5844            check_insn(ctx, ISA_MIPS_R2);
5845            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageGrain));
5846            register_name = "PageGrain";
5847            break;
5848        case CP0_REG05__SEGCTL0:
5849            CP0_CHECK(ctx->sc);
5850            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_SegCtl0));
5851            tcg_gen_ext32s_tl(arg, arg);
5852            register_name = "SegCtl0";
5853            break;
5854        case CP0_REG05__SEGCTL1:
5855            CP0_CHECK(ctx->sc);
5856            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_SegCtl1));
5857            tcg_gen_ext32s_tl(arg, arg);
5858            register_name = "SegCtl1";
5859            break;
5860        case CP0_REG05__SEGCTL2:
5861            CP0_CHECK(ctx->sc);
5862            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_SegCtl2));
5863            tcg_gen_ext32s_tl(arg, arg);
5864            register_name = "SegCtl2";
5865            break;
5866        case CP0_REG05__PWBASE:
5867            check_pw(ctx);
5868            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PWBase));
5869            register_name = "PWBase";
5870            break;
5871        case CP0_REG05__PWFIELD:
5872            check_pw(ctx);
5873            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PWField));
5874            register_name = "PWField";
5875            break;
5876        case CP0_REG05__PWSIZE:
5877            check_pw(ctx);
5878            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PWSize));
5879            register_name = "PWSize";
5880            break;
5881        default:
5882            goto cp0_unimplemented;
5883        }
5884        break;
5885    case CP0_REGISTER_06:
5886        switch (sel) {
5887        case CP0_REG06__WIRED:
5888            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Wired));
5889            register_name = "Wired";
5890            break;
5891        case CP0_REG06__SRSCONF0:
5892            check_insn(ctx, ISA_MIPS_R2);
5893            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf0));
5894            register_name = "SRSConf0";
5895            break;
5896        case CP0_REG06__SRSCONF1:
5897            check_insn(ctx, ISA_MIPS_R2);
5898            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf1));
5899            register_name = "SRSConf1";
5900            break;
5901        case CP0_REG06__SRSCONF2:
5902            check_insn(ctx, ISA_MIPS_R2);
5903            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf2));
5904            register_name = "SRSConf2";
5905            break;
5906        case CP0_REG06__SRSCONF3:
5907            check_insn(ctx, ISA_MIPS_R2);
5908            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf3));
5909            register_name = "SRSConf3";
5910            break;
5911        case CP0_REG06__SRSCONF4:
5912            check_insn(ctx, ISA_MIPS_R2);
5913            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf4));
5914            register_name = "SRSConf4";
5915            break;
5916        case CP0_REG06__PWCTL:
5917            check_pw(ctx);
5918            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PWCtl));
5919            register_name = "PWCtl";
5920            break;
5921        default:
5922            goto cp0_unimplemented;
5923        }
5924        break;
5925    case CP0_REGISTER_07:
5926        switch (sel) {
5927        case CP0_REG07__HWRENA:
5928            check_insn(ctx, ISA_MIPS_R2);
5929            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_HWREna));
5930            register_name = "HWREna";
5931            break;
5932        default:
5933            goto cp0_unimplemented;
5934        }
5935        break;
5936    case CP0_REGISTER_08:
5937        switch (sel) {
5938        case CP0_REG08__BADVADDR:
5939            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_BadVAddr));
5940            tcg_gen_ext32s_tl(arg, arg);
5941            register_name = "BadVAddr";
5942            break;
5943        case CP0_REG08__BADINSTR:
5944            CP0_CHECK(ctx->bi);
5945            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_BadInstr));
5946            register_name = "BadInstr";
5947            break;
5948        case CP0_REG08__BADINSTRP:
5949            CP0_CHECK(ctx->bp);
5950            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_BadInstrP));
5951            register_name = "BadInstrP";
5952            break;
5953        case CP0_REG08__BADINSTRX:
5954            CP0_CHECK(ctx->bi);
5955            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_BadInstrX));
5956            tcg_gen_andi_tl(arg, arg, ~0xffff);
5957            register_name = "BadInstrX";
5958            break;
5959        default:
5960            goto cp0_unimplemented;
5961        }
5962        break;
5963    case CP0_REGISTER_09:
5964        switch (sel) {
5965        case CP0_REG09__COUNT:
5966            /* Mark as an IO operation because we read the time.  */
5967            if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
5968                gen_io_start();
5969            }
5970            gen_helper_mfc0_count(arg, cpu_env);
5971            /*
5972             * Break the TB to be able to take timer interrupts immediately
5973             * after reading count. DISAS_STOP isn't sufficient, we need to
5974             * ensure we break completely out of translated code.
5975             */
5976            gen_save_pc(ctx->base.pc_next + 4);
5977            ctx->base.is_jmp = DISAS_EXIT;
5978            register_name = "Count";
5979            break;
5980        case CP0_REG09__SAARI:
5981            CP0_CHECK(ctx->saar);
5982            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SAARI));
5983            register_name = "SAARI";
5984            break;
5985        case CP0_REG09__SAAR:
5986            CP0_CHECK(ctx->saar);
5987            gen_helper_mfc0_saar(arg, cpu_env);
5988            register_name = "SAAR";
5989            break;
5990        default:
5991            goto cp0_unimplemented;
5992        }
5993        break;
5994    case CP0_REGISTER_10:
5995        switch (sel) {
5996        case CP0_REG10__ENTRYHI:
5997            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryHi));
5998            tcg_gen_ext32s_tl(arg, arg);
5999            register_name = "EntryHi";
6000            break;
6001        default:
6002            goto cp0_unimplemented;
6003        }
6004        break;
6005    case CP0_REGISTER_11:
6006        switch (sel) {
6007        case CP0_REG11__COMPARE:
6008            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Compare));
6009            register_name = "Compare";
6010            break;
6011        /* 6,7 are implementation dependent */
6012        default:
6013            goto cp0_unimplemented;
6014        }
6015        break;
6016    case CP0_REGISTER_12:
6017        switch (sel) {
6018        case CP0_REG12__STATUS:
6019            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Status));
6020            register_name = "Status";
6021            break;
6022        case CP0_REG12__INTCTL:
6023            check_insn(ctx, ISA_MIPS_R2);
6024            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_IntCtl));
6025            register_name = "IntCtl";
6026            break;
6027        case CP0_REG12__SRSCTL:
6028            check_insn(ctx, ISA_MIPS_R2);
6029            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSCtl));
6030            register_name = "SRSCtl";
6031            break;
6032        case CP0_REG12__SRSMAP:
6033            check_insn(ctx, ISA_MIPS_R2);
6034            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSMap));
6035            register_name = "SRSMap";
6036            break;
6037        default:
6038            goto cp0_unimplemented;
6039       }
6040        break;
6041    case CP0_REGISTER_13:
6042        switch (sel) {
6043        case CP0_REG13__CAUSE:
6044            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Cause));
6045            register_name = "Cause";
6046            break;
6047        default:
6048            goto cp0_unimplemented;
6049       }
6050        break;
6051    case CP0_REGISTER_14:
6052        switch (sel) {
6053        case CP0_REG14__EPC:
6054            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EPC));
6055            tcg_gen_ext32s_tl(arg, arg);
6056            register_name = "EPC";
6057            break;
6058        default:
6059            goto cp0_unimplemented;
6060        }
6061        break;
6062    case CP0_REGISTER_15:
6063        switch (sel) {
6064        case CP0_REG15__PRID:
6065            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PRid));
6066            register_name = "PRid";
6067            break;
6068        case CP0_REG15__EBASE:
6069            check_insn(ctx, ISA_MIPS_R2);
6070            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EBase));
6071            tcg_gen_ext32s_tl(arg, arg);
6072            register_name = "EBase";
6073            break;
6074        case CP0_REG15__CMGCRBASE:
6075            check_insn(ctx, ISA_MIPS_R2);
6076            CP0_CHECK(ctx->cmgcr);
6077            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_CMGCRBase));
6078            tcg_gen_ext32s_tl(arg, arg);
6079            register_name = "CMGCRBase";
6080            break;
6081        default:
6082            goto cp0_unimplemented;
6083       }
6084        break;
6085    case CP0_REGISTER_16:
6086        switch (sel) {
6087        case CP0_REG16__CONFIG:
6088            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config0));
6089            register_name = "Config";
6090            break;
6091        case CP0_REG16__CONFIG1:
6092            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config1));
6093            register_name = "Config1";
6094            break;
6095        case CP0_REG16__CONFIG2:
6096            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config2));
6097            register_name = "Config2";
6098            break;
6099        case CP0_REG16__CONFIG3:
6100            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config3));
6101            register_name = "Config3";
6102            break;
6103        case CP0_REG16__CONFIG4:
6104            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config4));
6105            register_name = "Config4";
6106            break;
6107        case CP0_REG16__CONFIG5:
6108            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config5));
6109            register_name = "Config5";
6110            break;
6111        /* 6,7 are implementation dependent */
6112        case CP0_REG16__CONFIG6:
6113            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config6));
6114            register_name = "Config6";
6115            break;
6116        case CP0_REG16__CONFIG7:
6117            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config7));
6118            register_name = "Config7";
6119            break;
6120        default:
6121            goto cp0_unimplemented;
6122        }
6123        break;
6124    case CP0_REGISTER_17:
6125        switch (sel) {
6126        case CP0_REG17__LLADDR:
6127            gen_helper_mfc0_lladdr(arg, cpu_env);
6128            register_name = "LLAddr";
6129            break;
6130        case CP0_REG17__MAAR:
6131            CP0_CHECK(ctx->mrp);
6132            gen_helper_mfc0_maar(arg, cpu_env);
6133            register_name = "MAAR";
6134            break;
6135        case CP0_REG17__MAARI:
6136            CP0_CHECK(ctx->mrp);
6137            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_MAARI));
6138            register_name = "MAARI";
6139            break;
6140        default:
6141            goto cp0_unimplemented;
6142        }
6143        break;
6144    case CP0_REGISTER_18:
6145        switch (sel) {
6146        case CP0_REG18__WATCHLO0:
6147        case CP0_REG18__WATCHLO1:
6148        case CP0_REG18__WATCHLO2:
6149        case CP0_REG18__WATCHLO3:
6150        case CP0_REG18__WATCHLO4:
6151        case CP0_REG18__WATCHLO5:
6152        case CP0_REG18__WATCHLO6:
6153        case CP0_REG18__WATCHLO7:
6154            CP0_CHECK(ctx->CP0_Config1 & (1 << CP0C1_WR));
6155            gen_helper_1e0i(mfc0_watchlo, arg, sel);
6156            register_name = "WatchLo";
6157            break;
6158        default:
6159            goto cp0_unimplemented;
6160        }
6161        break;
6162    case CP0_REGISTER_19:
6163        switch (sel) {
6164        case CP0_REG19__WATCHHI0:
6165        case CP0_REG19__WATCHHI1:
6166        case CP0_REG19__WATCHHI2:
6167        case CP0_REG19__WATCHHI3:
6168        case CP0_REG19__WATCHHI4:
6169        case CP0_REG19__WATCHHI5:
6170        case CP0_REG19__WATCHHI6:
6171        case CP0_REG19__WATCHHI7:
6172            CP0_CHECK(ctx->CP0_Config1 & (1 << CP0C1_WR));
6173            gen_helper_1e0i(mfc0_watchhi, arg, sel);
6174            register_name = "WatchHi";
6175            break;
6176        default:
6177            goto cp0_unimplemented;
6178        }
6179        break;
6180    case CP0_REGISTER_20:
6181        switch (sel) {
6182        case CP0_REG20__XCONTEXT:
6183#if defined(TARGET_MIPS64)
6184            check_insn(ctx, ISA_MIPS3);
6185            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_XContext));
6186            tcg_gen_ext32s_tl(arg, arg);
6187            register_name = "XContext";
6188            break;
6189#endif
6190        default:
6191            goto cp0_unimplemented;
6192        }
6193        break;
6194    case CP0_REGISTER_21:
6195       /* Officially reserved, but sel 0 is used for R1x000 framemask */
6196        CP0_CHECK(!(ctx->insn_flags & ISA_MIPS_R6));
6197        switch (sel) {
6198        case 0:
6199            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Framemask));
6200            register_name = "Framemask";
6201            break;
6202        default:
6203            goto cp0_unimplemented;
6204        }
6205        break;
6206    case CP0_REGISTER_22:
6207        tcg_gen_movi_tl(arg, 0); /* unimplemented */
6208        register_name = "'Diagnostic"; /* implementation dependent */
6209        break;
6210    case CP0_REGISTER_23:
6211        switch (sel) {
6212        case CP0_REG23__DEBUG:
6213            gen_helper_mfc0_debug(arg, cpu_env); /* EJTAG support */
6214            register_name = "Debug";
6215            break;
6216        case CP0_REG23__TRACECONTROL:
6217            /* PDtrace support */
6218            /* gen_helper_mfc0_tracecontrol(arg);  */
6219            register_name = "TraceControl";
6220            goto cp0_unimplemented;
6221        case CP0_REG23__TRACECONTROL2:
6222            /* PDtrace support */
6223            /* gen_helper_mfc0_tracecontrol2(arg); */
6224            register_name = "TraceControl2";
6225            goto cp0_unimplemented;
6226        case CP0_REG23__USERTRACEDATA1:
6227            /* PDtrace support */
6228            /* gen_helper_mfc0_usertracedata1(arg);*/
6229            register_name = "UserTraceData1";
6230            goto cp0_unimplemented;
6231        case CP0_REG23__TRACEIBPC:
6232            /* PDtrace support */
6233            /* gen_helper_mfc0_traceibpc(arg);     */
6234            register_name = "TraceIBPC";
6235            goto cp0_unimplemented;
6236        case CP0_REG23__TRACEDBPC:
6237            /* PDtrace support */
6238            /* gen_helper_mfc0_tracedbpc(arg);     */
6239            register_name = "TraceDBPC";
6240            goto cp0_unimplemented;
6241        default:
6242            goto cp0_unimplemented;
6243        }
6244        break;
6245    case CP0_REGISTER_24:
6246        switch (sel) {
6247        case CP0_REG24__DEPC:
6248            /* EJTAG support */
6249            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_DEPC));
6250            tcg_gen_ext32s_tl(arg, arg);
6251            register_name = "DEPC";
6252            break;
6253        default:
6254            goto cp0_unimplemented;
6255        }
6256        break;
6257    case CP0_REGISTER_25:
6258        switch (sel) {
6259        case CP0_REG25__PERFCTL0:
6260            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Performance0));
6261            register_name = "Performance0";
6262            break;
6263        case CP0_REG25__PERFCNT0:
6264            /* gen_helper_mfc0_performance1(arg); */
6265            register_name = "Performance1";
6266            goto cp0_unimplemented;
6267        case CP0_REG25__PERFCTL1:
6268            /* gen_helper_mfc0_performance2(arg); */
6269            register_name = "Performance2";
6270            goto cp0_unimplemented;
6271        case CP0_REG25__PERFCNT1:
6272            /* gen_helper_mfc0_performance3(arg); */
6273            register_name = "Performance3";
6274            goto cp0_unimplemented;
6275        case CP0_REG25__PERFCTL2:
6276            /* gen_helper_mfc0_performance4(arg); */
6277            register_name = "Performance4";
6278            goto cp0_unimplemented;
6279        case CP0_REG25__PERFCNT2:
6280            /* gen_helper_mfc0_performance5(arg); */
6281            register_name = "Performance5";
6282            goto cp0_unimplemented;
6283        case CP0_REG25__PERFCTL3:
6284            /* gen_helper_mfc0_performance6(arg); */
6285            register_name = "Performance6";
6286            goto cp0_unimplemented;
6287        case CP0_REG25__PERFCNT3:
6288            /* gen_helper_mfc0_performance7(arg); */
6289            register_name = "Performance7";
6290            goto cp0_unimplemented;
6291        default:
6292            goto cp0_unimplemented;
6293        }
6294        break;
6295    case CP0_REGISTER_26:
6296        switch (sel) {
6297        case CP0_REG26__ERRCTL:
6298            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_ErrCtl));
6299            register_name = "ErrCtl";
6300            break;
6301        default:
6302            goto cp0_unimplemented;
6303        }
6304        break;
6305    case CP0_REGISTER_27:
6306        switch (sel) {
6307        case CP0_REG27__CACHERR:
6308            tcg_gen_movi_tl(arg, 0); /* unimplemented */
6309            register_name = "CacheErr";
6310            break;
6311        default:
6312            goto cp0_unimplemented;
6313        }
6314        break;
6315    case CP0_REGISTER_28:
6316        switch (sel) {
6317        case CP0_REG28__TAGLO:
6318        case CP0_REG28__TAGLO1:
6319        case CP0_REG28__TAGLO2:
6320        case CP0_REG28__TAGLO3:
6321            {
6322                TCGv_i64 tmp = tcg_temp_new_i64();
6323                tcg_gen_ld_i64(tmp, cpu_env, offsetof(CPUMIPSState, CP0_TagLo));
6324                gen_move_low32(arg, tmp);
6325                tcg_temp_free_i64(tmp);
6326            }
6327            register_name = "TagLo";
6328            break;
6329        case CP0_REG28__DATALO:
6330        case CP0_REG28__DATALO1:
6331        case CP0_REG28__DATALO2:
6332        case CP0_REG28__DATALO3:
6333            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataLo));
6334            register_name = "DataLo";
6335            break;
6336        default:
6337            goto cp0_unimplemented;
6338        }
6339        break;
6340    case CP0_REGISTER_29:
6341        switch (sel) {
6342        case CP0_REG29__TAGHI:
6343        case CP0_REG29__TAGHI1:
6344        case CP0_REG29__TAGHI2:
6345        case CP0_REG29__TAGHI3:
6346            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_TagHi));
6347            register_name = "TagHi";
6348            break;
6349        case CP0_REG29__DATAHI:
6350        case CP0_REG29__DATAHI1:
6351        case CP0_REG29__DATAHI2:
6352        case CP0_REG29__DATAHI3:
6353            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataHi));
6354            register_name = "DataHi";
6355            break;
6356        default:
6357            goto cp0_unimplemented;
6358        }
6359        break;
6360    case CP0_REGISTER_30:
6361        switch (sel) {
6362        case CP0_REG30__ERROREPC:
6363            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_ErrorEPC));
6364            tcg_gen_ext32s_tl(arg, arg);
6365            register_name = "ErrorEPC";
6366            break;
6367        default:
6368            goto cp0_unimplemented;
6369        }
6370        break;
6371    case CP0_REGISTER_31:
6372        switch (sel) {
6373        case CP0_REG31__DESAVE:
6374            /* EJTAG support */
6375            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DESAVE));
6376            register_name = "DESAVE";
6377            break;
6378        case CP0_REG31__KSCRATCH1:
6379        case CP0_REG31__KSCRATCH2:
6380        case CP0_REG31__KSCRATCH3:
6381        case CP0_REG31__KSCRATCH4:
6382        case CP0_REG31__KSCRATCH5:
6383        case CP0_REG31__KSCRATCH6:
6384            CP0_CHECK(ctx->kscrexist & (1 << sel));
6385            tcg_gen_ld_tl(arg, cpu_env,
6386                          offsetof(CPUMIPSState, CP0_KScratch[sel - 2]));
6387            tcg_gen_ext32s_tl(arg, arg);
6388            register_name = "KScratch";
6389            break;
6390        default:
6391            goto cp0_unimplemented;
6392        }
6393        break;
6394    default:
6395       goto cp0_unimplemented;
6396    }
6397    trace_mips_translate_c0("mfc0", register_name, reg, sel);
6398    return;
6399
6400cp0_unimplemented:
6401    qemu_log_mask(LOG_UNIMP, "mfc0 %s (reg %d sel %d)\n",
6402                  register_name, reg, sel);
6403    gen_mfc0_unimplemented(ctx, arg);
6404}
6405
6406static void gen_mtc0(DisasContext *ctx, TCGv arg, int reg, int sel)
6407{
6408    const char *register_name = "invalid";
6409
6410    if (sel != 0) {
6411        check_insn(ctx, ISA_MIPS_R1);
6412    }
6413
6414    if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
6415        gen_io_start();
6416    }
6417
6418    switch (reg) {
6419    case CP0_REGISTER_00:
6420        switch (sel) {
6421        case CP0_REG00__INDEX:
6422            gen_helper_mtc0_index(cpu_env, arg);
6423            register_name = "Index";
6424            break;
6425        case CP0_REG00__MVPCONTROL:
6426            CP0_CHECK(ctx->insn_flags & ASE_MT);
6427            gen_helper_mtc0_mvpcontrol(cpu_env, arg);
6428            register_name = "MVPControl";
6429            break;
6430        case CP0_REG00__MVPCONF0:
6431            CP0_CHECK(ctx->insn_flags & ASE_MT);
6432            /* ignored */
6433            register_name = "MVPConf0";
6434            break;
6435        case CP0_REG00__MVPCONF1:
6436            CP0_CHECK(ctx->insn_flags & ASE_MT);
6437            /* ignored */
6438            register_name = "MVPConf1";
6439            break;
6440        case CP0_REG00__VPCONTROL:
6441            CP0_CHECK(ctx->vp);
6442            /* ignored */
6443            register_name = "VPControl";
6444            break;
6445        default:
6446            goto cp0_unimplemented;
6447        }
6448        break;
6449    case CP0_REGISTER_01:
6450        switch (sel) {
6451        case CP0_REG01__RANDOM:
6452            /* ignored */
6453            register_name = "Random";
6454            break;
6455        case CP0_REG01__VPECONTROL:
6456            CP0_CHECK(ctx->insn_flags & ASE_MT);
6457            gen_helper_mtc0_vpecontrol(cpu_env, arg);
6458            register_name = "VPEControl";
6459            break;
6460        case CP0_REG01__VPECONF0:
6461            CP0_CHECK(ctx->insn_flags & ASE_MT);
6462            gen_helper_mtc0_vpeconf0(cpu_env, arg);
6463            register_name = "VPEConf0";
6464            break;
6465        case CP0_REG01__VPECONF1:
6466            CP0_CHECK(ctx->insn_flags & ASE_MT);
6467            gen_helper_mtc0_vpeconf1(cpu_env, arg);
6468            register_name = "VPEConf1";
6469            break;
6470        case CP0_REG01__YQMASK:
6471            CP0_CHECK(ctx->insn_flags & ASE_MT);
6472            gen_helper_mtc0_yqmask(cpu_env, arg);
6473            register_name = "YQMask";
6474            break;
6475        case CP0_REG01__VPESCHEDULE:
6476            CP0_CHECK(ctx->insn_flags & ASE_MT);
6477            tcg_gen_st_tl(arg, cpu_env,
6478                          offsetof(CPUMIPSState, CP0_VPESchedule));
6479            register_name = "VPESchedule";
6480            break;
6481        case CP0_REG01__VPESCHEFBACK:
6482            CP0_CHECK(ctx->insn_flags & ASE_MT);
6483            tcg_gen_st_tl(arg, cpu_env,
6484                          offsetof(CPUMIPSState, CP0_VPEScheFBack));
6485            register_name = "VPEScheFBack";
6486            break;
6487        case CP0_REG01__VPEOPT:
6488            CP0_CHECK(ctx->insn_flags & ASE_MT);
6489            gen_helper_mtc0_vpeopt(cpu_env, arg);
6490            register_name = "VPEOpt";
6491            break;
6492        default:
6493            goto cp0_unimplemented;
6494        }
6495        break;
6496    case CP0_REGISTER_02:
6497        switch (sel) {
6498        case CP0_REG02__ENTRYLO0:
6499            gen_helper_mtc0_entrylo0(cpu_env, arg);
6500            register_name = "EntryLo0";
6501            break;
6502        case CP0_REG02__TCSTATUS:
6503            CP0_CHECK(ctx->insn_flags & ASE_MT);
6504            gen_helper_mtc0_tcstatus(cpu_env, arg);
6505            register_name = "TCStatus";
6506            break;
6507        case CP0_REG02__TCBIND:
6508            CP0_CHECK(ctx->insn_flags & ASE_MT);
6509            gen_helper_mtc0_tcbind(cpu_env, arg);
6510            register_name = "TCBind";
6511            break;
6512        case CP0_REG02__TCRESTART:
6513            CP0_CHECK(ctx->insn_flags & ASE_MT);
6514            gen_helper_mtc0_tcrestart(cpu_env, arg);
6515            register_name = "TCRestart";
6516            break;
6517        case CP0_REG02__TCHALT:
6518            CP0_CHECK(ctx->insn_flags & ASE_MT);
6519            gen_helper_mtc0_tchalt(cpu_env, arg);
6520            register_name = "TCHalt";
6521            break;
6522        case CP0_REG02__TCCONTEXT:
6523            CP0_CHECK(ctx->insn_flags & ASE_MT);
6524            gen_helper_mtc0_tccontext(cpu_env, arg);
6525            register_name = "TCContext";
6526            break;
6527        case CP0_REG02__TCSCHEDULE:
6528            CP0_CHECK(ctx->insn_flags & ASE_MT);
6529            gen_helper_mtc0_tcschedule(cpu_env, arg);
6530            register_name = "TCSchedule";
6531            break;
6532        case CP0_REG02__TCSCHEFBACK:
6533            CP0_CHECK(ctx->insn_flags & ASE_MT);
6534            gen_helper_mtc0_tcschefback(cpu_env, arg);
6535            register_name = "TCScheFBack";
6536            break;
6537        default:
6538            goto cp0_unimplemented;
6539        }
6540        break;
6541    case CP0_REGISTER_03:
6542        switch (sel) {
6543        case CP0_REG03__ENTRYLO1:
6544            gen_helper_mtc0_entrylo1(cpu_env, arg);
6545            register_name = "EntryLo1";
6546            break;
6547        case CP0_REG03__GLOBALNUM:
6548            CP0_CHECK(ctx->vp);
6549            /* ignored */
6550            register_name = "GlobalNumber";
6551            break;
6552        default:
6553            goto cp0_unimplemented;
6554        }
6555        break;
6556    case CP0_REGISTER_04:
6557        switch (sel) {
6558        case CP0_REG04__CONTEXT:
6559            gen_helper_mtc0_context(cpu_env, arg);
6560            register_name = "Context";
6561            break;
6562        case CP0_REG04__CONTEXTCONFIG:
6563            /* SmartMIPS ASE */
6564            /* gen_helper_mtc0_contextconfig(arg); */
6565            register_name = "ContextConfig";
6566            goto cp0_unimplemented;
6567        case CP0_REG04__USERLOCAL:
6568            CP0_CHECK(ctx->ulri);
6569            tcg_gen_st_tl(arg, cpu_env,
6570                          offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
6571            register_name = "UserLocal";
6572            break;
6573        case CP0_REG04__MMID:
6574            CP0_CHECK(ctx->mi);
6575            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_MemoryMapID));
6576            register_name = "MMID";
6577            break;
6578        default:
6579            goto cp0_unimplemented;
6580        }
6581        break;
6582    case CP0_REGISTER_05:
6583        switch (sel) {
6584        case CP0_REG05__PAGEMASK:
6585            gen_helper_mtc0_pagemask(cpu_env, arg);
6586            register_name = "PageMask";
6587            break;
6588        case CP0_REG05__PAGEGRAIN:
6589            check_insn(ctx, ISA_MIPS_R2);
6590            gen_helper_mtc0_pagegrain(cpu_env, arg);
6591            register_name = "PageGrain";
6592            ctx->base.is_jmp = DISAS_STOP;
6593            break;
6594        case CP0_REG05__SEGCTL0:
6595            CP0_CHECK(ctx->sc);
6596            gen_helper_mtc0_segctl0(cpu_env, arg);
6597            register_name = "SegCtl0";
6598            break;
6599        case CP0_REG05__SEGCTL1:
6600            CP0_CHECK(ctx->sc);
6601            gen_helper_mtc0_segctl1(cpu_env, arg);
6602            register_name = "SegCtl1";
6603            break;
6604        case CP0_REG05__SEGCTL2:
6605            CP0_CHECK(ctx->sc);
6606            gen_helper_mtc0_segctl2(cpu_env, arg);
6607            register_name = "SegCtl2";
6608            break;
6609        case CP0_REG05__PWBASE:
6610            check_pw(ctx);
6611            gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_PWBase));
6612            register_name = "PWBase";
6613            break;
6614        case CP0_REG05__PWFIELD:
6615            check_pw(ctx);
6616            gen_helper_mtc0_pwfield(cpu_env, arg);
6617            register_name = "PWField";
6618            break;
6619        case CP0_REG05__PWSIZE:
6620            check_pw(ctx);
6621            gen_helper_mtc0_pwsize(cpu_env, arg);
6622            register_name = "PWSize";
6623            break;
6624        default:
6625            goto cp0_unimplemented;
6626        }
6627        break;
6628    case CP0_REGISTER_06:
6629        switch (sel) {
6630        case CP0_REG06__WIRED:
6631            gen_helper_mtc0_wired(cpu_env, arg);
6632            register_name = "Wired";
6633            break;
6634        case CP0_REG06__SRSCONF0:
6635            check_insn(ctx, ISA_MIPS_R2);
6636            gen_helper_mtc0_srsconf0(cpu_env, arg);
6637            register_name = "SRSConf0";
6638            break;
6639        case CP0_REG06__SRSCONF1:
6640            check_insn(ctx, ISA_MIPS_R2);
6641            gen_helper_mtc0_srsconf1(cpu_env, arg);
6642            register_name = "SRSConf1";
6643            break;
6644        case CP0_REG06__SRSCONF2:
6645            check_insn(ctx, ISA_MIPS_R2);
6646            gen_helper_mtc0_srsconf2(cpu_env, arg);
6647            register_name = "SRSConf2";
6648            break;
6649        case CP0_REG06__SRSCONF3:
6650            check_insn(ctx, ISA_MIPS_R2);
6651            gen_helper_mtc0_srsconf3(cpu_env, arg);
6652            register_name = "SRSConf3";
6653            break;
6654        case CP0_REG06__SRSCONF4:
6655            check_insn(ctx, ISA_MIPS_R2);
6656            gen_helper_mtc0_srsconf4(cpu_env, arg);
6657            register_name = "SRSConf4";
6658            break;
6659        case CP0_REG06__PWCTL:
6660            check_pw(ctx);
6661            gen_helper_mtc0_pwctl(cpu_env, arg);
6662            register_name = "PWCtl";
6663            break;
6664        default:
6665            goto cp0_unimplemented;
6666        }
6667        break;
6668    case CP0_REGISTER_07:
6669        switch (sel) {
6670        case CP0_REG07__HWRENA:
6671            check_insn(ctx, ISA_MIPS_R2);
6672            gen_helper_mtc0_hwrena(cpu_env, arg);
6673            ctx->base.is_jmp = DISAS_STOP;
6674            register_name = "HWREna";
6675            break;
6676        default:
6677            goto cp0_unimplemented;
6678        }
6679        break;
6680    case CP0_REGISTER_08:
6681        switch (sel) {
6682        case CP0_REG08__BADVADDR:
6683            /* ignored */
6684            register_name = "BadVAddr";
6685            break;
6686        case CP0_REG08__BADINSTR:
6687            /* ignored */
6688            register_name = "BadInstr";
6689            break;
6690        case CP0_REG08__BADINSTRP:
6691            /* ignored */
6692            register_name = "BadInstrP";
6693            break;
6694        case CP0_REG08__BADINSTRX:
6695            /* ignored */
6696            register_name = "BadInstrX";
6697            break;
6698        default:
6699            goto cp0_unimplemented;
6700        }
6701        break;
6702    case CP0_REGISTER_09:
6703        switch (sel) {
6704        case CP0_REG09__COUNT:
6705            gen_helper_mtc0_count(cpu_env, arg);
6706            register_name = "Count";
6707            break;
6708        case CP0_REG09__SAARI:
6709            CP0_CHECK(ctx->saar);
6710            gen_helper_mtc0_saari(cpu_env, arg);
6711            register_name = "SAARI";
6712            break;
6713        case CP0_REG09__SAAR:
6714            CP0_CHECK(ctx->saar);
6715            gen_helper_mtc0_saar(cpu_env, arg);
6716            register_name = "SAAR";
6717            break;
6718        default:
6719            goto cp0_unimplemented;
6720        }
6721        break;
6722    case CP0_REGISTER_10:
6723        switch (sel) {
6724        case CP0_REG10__ENTRYHI:
6725            gen_helper_mtc0_entryhi(cpu_env, arg);
6726            register_name = "EntryHi";
6727            break;
6728        default:
6729            goto cp0_unimplemented;
6730        }
6731        break;
6732    case CP0_REGISTER_11:
6733        switch (sel) {
6734        case CP0_REG11__COMPARE:
6735            gen_helper_mtc0_compare(cpu_env, arg);
6736            register_name = "Compare";
6737            break;
6738        /* 6,7 are implementation dependent */
6739        default:
6740            goto cp0_unimplemented;
6741        }
6742        break;
6743    case CP0_REGISTER_12:
6744        switch (sel) {
6745        case CP0_REG12__STATUS:
6746            save_cpu_state(ctx, 1);
6747            gen_helper_mtc0_status(cpu_env, arg);
6748            /* DISAS_STOP isn't good enough here, hflags may have changed. */
6749            gen_save_pc(ctx->base.pc_next + 4);
6750            ctx->base.is_jmp = DISAS_EXIT;
6751            register_name = "Status";
6752            break;
6753        case CP0_REG12__INTCTL:
6754            check_insn(ctx, ISA_MIPS_R2);
6755            gen_helper_mtc0_intctl(cpu_env, arg);
6756            /* Stop translation as we may have switched the execution mode */
6757            ctx->base.is_jmp = DISAS_STOP;
6758            register_name = "IntCtl";
6759            break;
6760        case CP0_REG12__SRSCTL:
6761            check_insn(ctx, ISA_MIPS_R2);
6762            gen_helper_mtc0_srsctl(cpu_env, arg);
6763            /* Stop translation as we may have switched the execution mode */
6764            ctx->base.is_jmp = DISAS_STOP;
6765            register_name = "SRSCtl";
6766            break;
6767        case CP0_REG12__SRSMAP:
6768            check_insn(ctx, ISA_MIPS_R2);
6769            gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_SRSMap));
6770            /* Stop translation as we may have switched the execution mode */
6771            ctx->base.is_jmp = DISAS_STOP;
6772            register_name = "SRSMap";
6773            break;
6774        default:
6775            goto cp0_unimplemented;
6776        }
6777        break;
6778    case CP0_REGISTER_13:
6779        switch (sel) {
6780        case CP0_REG13__CAUSE:
6781            save_cpu_state(ctx, 1);
6782            gen_helper_mtc0_cause(cpu_env, arg);
6783            /*
6784             * Stop translation as we may have triggered an interrupt.
6785             * DISAS_STOP isn't sufficient, we need to ensure we break out of
6786             * translated code to check for pending interrupts.
6787             */
6788            gen_save_pc(ctx->base.pc_next + 4);
6789            ctx->base.is_jmp = DISAS_EXIT;
6790            register_name = "Cause";
6791            break;
6792        default:
6793            goto cp0_unimplemented;
6794        }
6795        break;
6796    case CP0_REGISTER_14:
6797        switch (sel) {
6798        case CP0_REG14__EPC:
6799            tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EPC));
6800            register_name = "EPC";
6801            break;
6802        default:
6803            goto cp0_unimplemented;
6804        }
6805        break;
6806    case CP0_REGISTER_15:
6807        switch (sel) {
6808        case CP0_REG15__PRID:
6809            /* ignored */
6810            register_name = "PRid";
6811            break;
6812        case CP0_REG15__EBASE:
6813            check_insn(ctx, ISA_MIPS_R2);
6814            gen_helper_mtc0_ebase(cpu_env, arg);
6815            register_name = "EBase";
6816            break;
6817        default:
6818            goto cp0_unimplemented;
6819        }
6820        break;
6821    case CP0_REGISTER_16:
6822        switch (sel) {
6823        case CP0_REG16__CONFIG:
6824            gen_helper_mtc0_config0(cpu_env, arg);
6825            register_name = "Config";
6826            /* Stop translation as we may have switched the execution mode */
6827            ctx->base.is_jmp = DISAS_STOP;
6828            break;
6829        case CP0_REG16__CONFIG1:
6830            /* ignored, read only */
6831            register_name = "Config1";
6832            break;
6833        case CP0_REG16__CONFIG2:
6834            gen_helper_mtc0_config2(cpu_env, arg);
6835            register_name = "Config2";
6836            /* Stop translation as we may have switched the execution mode */
6837            ctx->base.is_jmp = DISAS_STOP;
6838            break;
6839        case CP0_REG16__CONFIG3:
6840            gen_helper_mtc0_config3(cpu_env, arg);
6841            register_name = "Config3";
6842            /* Stop translation as we may have switched the execution mode */
6843            ctx->base.is_jmp = DISAS_STOP;
6844            break;
6845        case CP0_REG16__CONFIG4:
6846            gen_helper_mtc0_config4(cpu_env, arg);
6847            register_name = "Config4";
6848            ctx->base.is_jmp = DISAS_STOP;
6849            break;
6850        case CP0_REG16__CONFIG5:
6851            gen_helper_mtc0_config5(cpu_env, arg);
6852            register_name = "Config5";
6853            /* Stop translation as we may have switched the execution mode */
6854            ctx->base.is_jmp = DISAS_STOP;
6855            break;
6856        /* 6,7 are implementation dependent */
6857        case CP0_REG16__CONFIG6:
6858            /* ignored */
6859            register_name = "Config6";
6860            break;
6861        case CP0_REG16__CONFIG7:
6862            /* ignored */
6863            register_name = "Config7";
6864            break;
6865        default:
6866            register_name = "Invalid config selector";
6867            goto cp0_unimplemented;
6868        }
6869        break;
6870    case CP0_REGISTER_17:
6871        switch (sel) {
6872        case CP0_REG17__LLADDR:
6873            gen_helper_mtc0_lladdr(cpu_env, arg);
6874            register_name = "LLAddr";
6875            break;
6876        case CP0_REG17__MAAR:
6877            CP0_CHECK(ctx->mrp);
6878            gen_helper_mtc0_maar(cpu_env, arg);
6879            register_name = "MAAR";
6880            break;
6881        case CP0_REG17__MAARI:
6882            CP0_CHECK(ctx->mrp);
6883            gen_helper_mtc0_maari(cpu_env, arg);
6884            register_name = "MAARI";
6885            break;
6886        default:
6887            goto cp0_unimplemented;
6888        }
6889        break;
6890    case CP0_REGISTER_18:
6891        switch (sel) {
6892        case CP0_REG18__WATCHLO0:
6893        case CP0_REG18__WATCHLO1:
6894        case CP0_REG18__WATCHLO2:
6895        case CP0_REG18__WATCHLO3:
6896        case CP0_REG18__WATCHLO4:
6897        case CP0_REG18__WATCHLO5:
6898        case CP0_REG18__WATCHLO6:
6899        case CP0_REG18__WATCHLO7:
6900            CP0_CHECK(ctx->CP0_Config1 & (1 << CP0C1_WR));
6901            gen_helper_0e1i(mtc0_watchlo, arg, sel);
6902            register_name = "WatchLo";
6903            break;
6904        default:
6905            goto cp0_unimplemented;
6906        }
6907        break;
6908    case CP0_REGISTER_19:
6909        switch (sel) {
6910        case CP0_REG19__WATCHHI0:
6911        case CP0_REG19__WATCHHI1:
6912        case CP0_REG19__WATCHHI2:
6913        case CP0_REG19__WATCHHI3:
6914        case CP0_REG19__WATCHHI4:
6915        case CP0_REG19__WATCHHI5:
6916        case CP0_REG19__WATCHHI6:
6917        case CP0_REG19__WATCHHI7:
6918            CP0_CHECK(ctx->CP0_Config1 & (1 << CP0C1_WR));
6919            gen_helper_0e1i(mtc0_watchhi, arg, sel);
6920            register_name = "WatchHi";
6921            break;
6922        default:
6923            goto cp0_unimplemented;
6924        }
6925        break;
6926    case CP0_REGISTER_20:
6927        switch (sel) {
6928        case CP0_REG20__XCONTEXT:
6929#if defined(TARGET_MIPS64)
6930            check_insn(ctx, ISA_MIPS3);
6931            gen_helper_mtc0_xcontext(cpu_env, arg);
6932            register_name = "XContext";
6933            break;
6934#endif
6935        default:
6936            goto cp0_unimplemented;
6937        }
6938        break;
6939    case CP0_REGISTER_21:
6940       /* Officially reserved, but sel 0 is used for R1x000 framemask */
6941        CP0_CHECK(!(ctx->insn_flags & ISA_MIPS_R6));
6942        switch (sel) {
6943        case 0:
6944            gen_helper_mtc0_framemask(cpu_env, arg);
6945            register_name = "Framemask";
6946            break;
6947        default:
6948            goto cp0_unimplemented;
6949        }
6950        break;
6951    case CP0_REGISTER_22:
6952        /* ignored */
6953        register_name = "Diagnostic"; /* implementation dependent */
6954        break;
6955    case CP0_REGISTER_23:
6956        switch (sel) {
6957        case CP0_REG23__DEBUG:
6958            gen_helper_mtc0_debug(cpu_env, arg); /* EJTAG support */
6959            /* DISAS_STOP isn't good enough here, hflags may have changed. */
6960            gen_save_pc(ctx->base.pc_next + 4);
6961            ctx->base.is_jmp = DISAS_EXIT;
6962            register_name = "Debug";
6963            break;
6964        case CP0_REG23__TRACECONTROL:
6965            /* PDtrace support */
6966            /* gen_helper_mtc0_tracecontrol(cpu_env, arg);  */
6967            register_name = "TraceControl";
6968            /* Stop translation as we may have switched the execution mode */
6969            ctx->base.is_jmp = DISAS_STOP;
6970            goto cp0_unimplemented;
6971        case CP0_REG23__TRACECONTROL2:
6972            /* PDtrace support */
6973            /* gen_helper_mtc0_tracecontrol2(cpu_env, arg); */
6974            register_name = "TraceControl2";
6975            /* Stop translation as we may have switched the execution mode */
6976            ctx->base.is_jmp = DISAS_STOP;
6977            goto cp0_unimplemented;
6978        case CP0_REG23__USERTRACEDATA1:
6979            /* Stop translation as we may have switched the execution mode */
6980            ctx->base.is_jmp = DISAS_STOP;
6981            /* PDtrace support */
6982            /* gen_helper_mtc0_usertracedata1(cpu_env, arg);*/
6983            register_name = "UserTraceData";
6984            /* Stop translation as we may have switched the execution mode */
6985            ctx->base.is_jmp = DISAS_STOP;
6986            goto cp0_unimplemented;
6987        case CP0_REG23__TRACEIBPC:
6988            /* PDtrace support */
6989            /* gen_helper_mtc0_traceibpc(cpu_env, arg);     */
6990            /* Stop translation as we may have switched the execution mode */
6991            ctx->base.is_jmp = DISAS_STOP;
6992            register_name = "TraceIBPC";
6993            goto cp0_unimplemented;
6994        case CP0_REG23__TRACEDBPC:
6995            /* PDtrace support */
6996            /* gen_helper_mtc0_tracedbpc(cpu_env, arg);     */
6997            /* Stop translation as we may have switched the execution mode */
6998            ctx->base.is_jmp = DISAS_STOP;
6999            register_name = "TraceDBPC";
7000            goto cp0_unimplemented;
7001        default:
7002            goto cp0_unimplemented;
7003        }
7004        break;
7005    case CP0_REGISTER_24:
7006        switch (sel) {
7007        case CP0_REG24__DEPC:
7008            /* EJTAG support */
7009            tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_DEPC));
7010            register_name = "DEPC";
7011            break;
7012        default:
7013            goto cp0_unimplemented;
7014        }
7015        break;
7016    case CP0_REGISTER_25:
7017        switch (sel) {
7018        case CP0_REG25__PERFCTL0:
7019            gen_helper_mtc0_performance0(cpu_env, arg);
7020            register_name = "Performance0";
7021            break;
7022        case CP0_REG25__PERFCNT0:
7023            /* gen_helper_mtc0_performance1(arg); */
7024            register_name = "Performance1";
7025            goto cp0_unimplemented;
7026        case CP0_REG25__PERFCTL1:
7027            /* gen_helper_mtc0_performance2(arg); */
7028            register_name = "Performance2";
7029            goto cp0_unimplemented;
7030        case CP0_REG25__PERFCNT1:
7031            /* gen_helper_mtc0_performance3(arg); */
7032            register_name = "Performance3";
7033            goto cp0_unimplemented;
7034        case CP0_REG25__PERFCTL2:
7035            /* gen_helper_mtc0_performance4(arg); */
7036            register_name = "Performance4";
7037            goto cp0_unimplemented;
7038        case CP0_REG25__PERFCNT2:
7039            /* gen_helper_mtc0_performance5(arg); */
7040            register_name = "Performance5";
7041            goto cp0_unimplemented;
7042        case CP0_REG25__PERFCTL3:
7043            /* gen_helper_mtc0_performance6(arg); */
7044            register_name = "Performance6";
7045            goto cp0_unimplemented;
7046        case CP0_REG25__PERFCNT3:
7047            /* gen_helper_mtc0_performance7(arg); */
7048            register_name = "Performance7";
7049            goto cp0_unimplemented;
7050        default:
7051            goto cp0_unimplemented;
7052        }
7053       break;
7054    case CP0_REGISTER_26:
7055        switch (sel) {
7056        case CP0_REG26__ERRCTL:
7057            gen_helper_mtc0_errctl(cpu_env, arg);
7058            ctx->base.is_jmp = DISAS_STOP;
7059            register_name = "ErrCtl";
7060            break;
7061        default:
7062            goto cp0_unimplemented;
7063        }
7064        break;
7065    case CP0_REGISTER_27:
7066        switch (sel) {
7067        case CP0_REG27__CACHERR:
7068            /* ignored */
7069            register_name = "CacheErr";
7070            break;
7071        default:
7072            goto cp0_unimplemented;
7073        }
7074       break;
7075    case CP0_REGISTER_28:
7076        switch (sel) {
7077        case CP0_REG28__TAGLO:
7078        case CP0_REG28__TAGLO1:
7079        case CP0_REG28__TAGLO2:
7080        case CP0_REG28__TAGLO3:
7081            gen_helper_mtc0_taglo(cpu_env, arg);
7082            register_name = "TagLo";
7083            break;
7084        case CP0_REG28__DATALO:
7085        case CP0_REG28__DATALO1:
7086        case CP0_REG28__DATALO2:
7087        case CP0_REG28__DATALO3:
7088            gen_helper_mtc0_datalo(cpu_env, arg);
7089            register_name = "DataLo";
7090            break;
7091        default:
7092            goto cp0_unimplemented;
7093        }
7094        break;
7095    case CP0_REGISTER_29:
7096        switch (sel) {
7097        case CP0_REG29__TAGHI:
7098        case CP0_REG29__TAGHI1:
7099        case CP0_REG29__TAGHI2:
7100        case CP0_REG29__TAGHI3:
7101            gen_helper_mtc0_taghi(cpu_env, arg);
7102            register_name = "TagHi";
7103            break;
7104        case CP0_REG29__DATAHI:
7105        case CP0_REG29__DATAHI1:
7106        case CP0_REG29__DATAHI2:
7107        case CP0_REG29__DATAHI3:
7108            gen_helper_mtc0_datahi(cpu_env, arg);
7109            register_name = "DataHi";
7110            break;
7111        default:
7112            register_name = "invalid sel";
7113            goto cp0_unimplemented;
7114        }
7115       break;
7116    case CP0_REGISTER_30:
7117        switch (sel) {
7118        case CP0_REG30__ERROREPC:
7119            tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_ErrorEPC));
7120            register_name = "ErrorEPC";
7121            break;
7122        default:
7123            goto cp0_unimplemented;
7124        }
7125        break;
7126    case CP0_REGISTER_31:
7127        switch (sel) {
7128        case CP0_REG31__DESAVE:
7129            /* EJTAG support */
7130            gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_DESAVE));
7131            register_name = "DESAVE";
7132            break;
7133        case CP0_REG31__KSCRATCH1:
7134        case CP0_REG31__KSCRATCH2:
7135        case CP0_REG31__KSCRATCH3:
7136        case CP0_REG31__KSCRATCH4:
7137        case CP0_REG31__KSCRATCH5:
7138        case CP0_REG31__KSCRATCH6:
7139            CP0_CHECK(ctx->kscrexist & (1 << sel));
7140            tcg_gen_st_tl(arg, cpu_env,
7141                          offsetof(CPUMIPSState, CP0_KScratch[sel - 2]));
7142            register_name = "KScratch";
7143            break;
7144        default:
7145            goto cp0_unimplemented;
7146        }
7147        break;
7148    default:
7149       goto cp0_unimplemented;
7150    }
7151    trace_mips_translate_c0("mtc0", register_name, reg, sel);
7152
7153    /* For simplicity assume that all writes can cause interrupts.  */
7154    if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
7155        /*
7156         * DISAS_STOP isn't sufficient, we need to ensure we break out of
7157         * translated code to check for pending interrupts.
7158         */
7159        gen_save_pc(ctx->base.pc_next + 4);
7160        ctx->base.is_jmp = DISAS_EXIT;
7161    }
7162    return;
7163
7164cp0_unimplemented:
7165    qemu_log_mask(LOG_UNIMP, "mtc0 %s (reg %d sel %d)\n",
7166                  register_name, reg, sel);
7167}
7168
7169#if defined(TARGET_MIPS64)
7170static void gen_dmfc0(DisasContext *ctx, TCGv arg, int reg, int sel)
7171{
7172    const char *register_name = "invalid";
7173
7174    if (sel != 0) {
7175        check_insn(ctx, ISA_MIPS_R1);
7176    }
7177
7178    switch (reg) {
7179    case CP0_REGISTER_00:
7180        switch (sel) {
7181        case CP0_REG00__INDEX:
7182            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Index));
7183            register_name = "Index";
7184            break;
7185        case CP0_REG00__MVPCONTROL:
7186            CP0_CHECK(ctx->insn_flags & ASE_MT);
7187            gen_helper_mfc0_mvpcontrol(arg, cpu_env);
7188            register_name = "MVPControl";
7189            break;
7190        case CP0_REG00__MVPCONF0:
7191            CP0_CHECK(ctx->insn_flags & ASE_MT);
7192            gen_helper_mfc0_mvpconf0(arg, cpu_env);
7193            register_name = "MVPConf0";
7194            break;
7195        case CP0_REG00__MVPCONF1:
7196            CP0_CHECK(ctx->insn_flags & ASE_MT);
7197            gen_helper_mfc0_mvpconf1(arg, cpu_env);
7198            register_name = "MVPConf1";
7199            break;
7200        case CP0_REG00__VPCONTROL:
7201            CP0_CHECK(ctx->vp);
7202            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPControl));
7203            register_name = "VPControl";
7204            break;
7205        default:
7206            goto cp0_unimplemented;
7207        }
7208        break;
7209    case CP0_REGISTER_01:
7210        switch (sel) {
7211        case CP0_REG01__RANDOM:
7212            CP0_CHECK(!(ctx->insn_flags & ISA_MIPS_R6));
7213            gen_helper_mfc0_random(arg, cpu_env);
7214            register_name = "Random";
7215            break;
7216        case CP0_REG01__VPECONTROL:
7217            CP0_CHECK(ctx->insn_flags & ASE_MT);
7218            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEControl));
7219            register_name = "VPEControl";
7220            break;
7221        case CP0_REG01__VPECONF0:
7222            CP0_CHECK(ctx->insn_flags & ASE_MT);
7223            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf0));
7224            register_name = "VPEConf0";
7225            break;
7226        case CP0_REG01__VPECONF1:
7227            CP0_CHECK(ctx->insn_flags & ASE_MT);
7228            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf1));
7229            register_name = "VPEConf1";
7230            break;
7231        case CP0_REG01__YQMASK:
7232            CP0_CHECK(ctx->insn_flags & ASE_MT);
7233            tcg_gen_ld_tl(arg, cpu_env,
7234                          offsetof(CPUMIPSState, CP0_YQMask));
7235            register_name = "YQMask";
7236            break;
7237        case CP0_REG01__VPESCHEDULE:
7238            CP0_CHECK(ctx->insn_flags & ASE_MT);
7239            tcg_gen_ld_tl(arg, cpu_env,
7240                          offsetof(CPUMIPSState, CP0_VPESchedule));
7241            register_name = "VPESchedule";
7242            break;
7243        case CP0_REG01__VPESCHEFBACK:
7244            CP0_CHECK(ctx->insn_flags & ASE_MT);
7245            tcg_gen_ld_tl(arg, cpu_env,
7246                          offsetof(CPUMIPSState, CP0_VPEScheFBack));
7247            register_name = "VPEScheFBack";
7248            break;
7249        case CP0_REG01__VPEOPT:
7250            CP0_CHECK(ctx->insn_flags & ASE_MT);
7251            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEOpt));
7252            register_name = "VPEOpt";
7253            break;
7254        default:
7255            goto cp0_unimplemented;
7256        }
7257        break;
7258    case CP0_REGISTER_02:
7259        switch (sel) {
7260        case CP0_REG02__ENTRYLO0:
7261            tcg_gen_ld_tl(arg, cpu_env,
7262                          offsetof(CPUMIPSState, CP0_EntryLo0));
7263            register_name = "EntryLo0";
7264            break;
7265        case CP0_REG02__TCSTATUS:
7266            CP0_CHECK(ctx->insn_flags & ASE_MT);
7267            gen_helper_mfc0_tcstatus(arg, cpu_env);
7268            register_name = "TCStatus";
7269            break;
7270        case CP0_REG02__TCBIND:
7271            CP0_CHECK(ctx->insn_flags & ASE_MT);
7272            gen_helper_mfc0_tcbind(arg, cpu_env);
7273            register_name = "TCBind";
7274            break;
7275        case CP0_REG02__TCRESTART:
7276            CP0_CHECK(ctx->insn_flags & ASE_MT);
7277            gen_helper_dmfc0_tcrestart(arg, cpu_env);
7278            register_name = "TCRestart";
7279            break;
7280        case CP0_REG02__TCHALT:
7281            CP0_CHECK(ctx->insn_flags & ASE_MT);
7282            gen_helper_dmfc0_tchalt(arg, cpu_env);
7283            register_name = "TCHalt";
7284            break;
7285        case CP0_REG02__TCCONTEXT:
7286            CP0_CHECK(ctx->insn_flags & ASE_MT);
7287            gen_helper_dmfc0_tccontext(arg, cpu_env);
7288            register_name = "TCContext";
7289            break;
7290        case CP0_REG02__TCSCHEDULE:
7291            CP0_CHECK(ctx->insn_flags & ASE_MT);
7292            gen_helper_dmfc0_tcschedule(arg, cpu_env);
7293            register_name = "TCSchedule";
7294            break;
7295        case CP0_REG02__TCSCHEFBACK:
7296            CP0_CHECK(ctx->insn_flags & ASE_MT);
7297            gen_helper_dmfc0_tcschefback(arg, cpu_env);
7298            register_name = "TCScheFBack";
7299            break;
7300        default:
7301            goto cp0_unimplemented;
7302        }
7303        break;
7304    case CP0_REGISTER_03:
7305        switch (sel) {
7306        case CP0_REG03__ENTRYLO1:
7307            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryLo1));
7308            register_name = "EntryLo1";
7309            break;
7310        case CP0_REG03__GLOBALNUM:
7311            CP0_CHECK(ctx->vp);
7312            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_GlobalNumber));
7313            register_name = "GlobalNumber";
7314            break;
7315        default:
7316            goto cp0_unimplemented;
7317        }
7318        break;
7319    case CP0_REGISTER_04:
7320        switch (sel) {
7321        case CP0_REG04__CONTEXT:
7322            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_Context));
7323            register_name = "Context";
7324            break;
7325        case CP0_REG04__CONTEXTCONFIG:
7326            /* SmartMIPS ASE */
7327            /* gen_helper_dmfc0_contextconfig(arg); */
7328            register_name = "ContextConfig";
7329            goto cp0_unimplemented;
7330        case CP0_REG04__USERLOCAL:
7331            CP0_CHECK(ctx->ulri);
7332            tcg_gen_ld_tl(arg, cpu_env,
7333                          offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
7334            register_name = "UserLocal";
7335            break;
7336        case CP0_REG04__MMID:
7337            CP0_CHECK(ctx->mi);
7338            gen_helper_mtc0_memorymapid(cpu_env, arg);
7339            register_name = "MMID";
7340            break;
7341        default:
7342            goto cp0_unimplemented;
7343        }
7344        break;
7345    case CP0_REGISTER_05:
7346        switch (sel) {
7347        case CP0_REG05__PAGEMASK:
7348            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageMask));
7349            register_name = "PageMask";
7350            break;
7351        case CP0_REG05__PAGEGRAIN:
7352            check_insn(ctx, ISA_MIPS_R2);
7353            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageGrain));
7354            register_name = "PageGrain";
7355            break;
7356        case CP0_REG05__SEGCTL0:
7357            CP0_CHECK(ctx->sc);
7358            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_SegCtl0));
7359            register_name = "SegCtl0";
7360            break;
7361        case CP0_REG05__SEGCTL1:
7362            CP0_CHECK(ctx->sc);
7363            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_SegCtl1));
7364            register_name = "SegCtl1";
7365            break;
7366        case CP0_REG05__SEGCTL2:
7367            CP0_CHECK(ctx->sc);
7368            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_SegCtl2));
7369            register_name = "SegCtl2";
7370            break;
7371        case CP0_REG05__PWBASE:
7372            check_pw(ctx);
7373            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_PWBase));
7374            register_name = "PWBase";
7375            break;
7376        case CP0_REG05__PWFIELD:
7377            check_pw(ctx);
7378            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_PWField));
7379            register_name = "PWField";
7380            break;
7381        case CP0_REG05__PWSIZE:
7382            check_pw(ctx);
7383            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_PWSize));
7384            register_name = "PWSize";
7385            break;
7386        default:
7387            goto cp0_unimplemented;
7388        }
7389        break;
7390    case CP0_REGISTER_06:
7391        switch (sel) {
7392        case CP0_REG06__WIRED:
7393            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Wired));
7394            register_name = "Wired";
7395            break;
7396        case CP0_REG06__SRSCONF0:
7397            check_insn(ctx, ISA_MIPS_R2);
7398            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf0));
7399            register_name = "SRSConf0";
7400            break;
7401        case CP0_REG06__SRSCONF1:
7402            check_insn(ctx, ISA_MIPS_R2);
7403            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf1));
7404            register_name = "SRSConf1";
7405            break;
7406        case CP0_REG06__SRSCONF2:
7407            check_insn(ctx, ISA_MIPS_R2);
7408            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf2));
7409            register_name = "SRSConf2";
7410            break;
7411        case CP0_REG06__SRSCONF3:
7412            check_insn(ctx, ISA_MIPS_R2);
7413            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf3));
7414            register_name = "SRSConf3";
7415            break;
7416        case CP0_REG06__SRSCONF4:
7417            check_insn(ctx, ISA_MIPS_R2);
7418            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf4));
7419            register_name = "SRSConf4";
7420            break;
7421        case CP0_REG06__PWCTL:
7422            check_pw(ctx);
7423            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PWCtl));
7424            register_name = "PWCtl";
7425            break;
7426        default:
7427            goto cp0_unimplemented;
7428        }
7429        break;
7430    case CP0_REGISTER_07:
7431        switch (sel) {
7432        case CP0_REG07__HWRENA:
7433            check_insn(ctx, ISA_MIPS_R2);
7434            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_HWREna));
7435            register_name = "HWREna";
7436            break;
7437        default:
7438            goto cp0_unimplemented;
7439        }
7440        break;
7441    case CP0_REGISTER_08:
7442        switch (sel) {
7443        case CP0_REG08__BADVADDR:
7444            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_BadVAddr));
7445            register_name = "BadVAddr";
7446            break;
7447        case CP0_REG08__BADINSTR:
7448            CP0_CHECK(ctx->bi);
7449            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_BadInstr));
7450            register_name = "BadInstr";
7451            break;
7452        case CP0_REG08__BADINSTRP:
7453            CP0_CHECK(ctx->bp);
7454            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_BadInstrP));
7455            register_name = "BadInstrP";
7456            break;
7457        case CP0_REG08__BADINSTRX:
7458            CP0_CHECK(ctx->bi);
7459            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_BadInstrX));
7460            tcg_gen_andi_tl(arg, arg, ~0xffff);
7461            register_name = "BadInstrX";
7462            break;
7463        default:
7464            goto cp0_unimplemented;
7465        }
7466        break;
7467    case CP0_REGISTER_09:
7468        switch (sel) {
7469        case CP0_REG09__COUNT:
7470            /* Mark as an IO operation because we read the time.  */
7471            if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
7472                gen_io_start();
7473            }
7474            gen_helper_mfc0_count(arg, cpu_env);
7475            /*
7476             * Break the TB to be able to take timer interrupts immediately
7477             * after reading count. DISAS_STOP isn't sufficient, we need to
7478             * ensure we break completely out of translated code.
7479             */
7480            gen_save_pc(ctx->base.pc_next + 4);
7481            ctx->base.is_jmp = DISAS_EXIT;
7482            register_name = "Count";
7483            break;
7484        case CP0_REG09__SAARI:
7485            CP0_CHECK(ctx->saar);
7486            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SAARI));
7487            register_name = "SAARI";
7488            break;
7489        case CP0_REG09__SAAR:
7490            CP0_CHECK(ctx->saar);
7491            gen_helper_dmfc0_saar(arg, cpu_env);
7492            register_name = "SAAR";
7493            break;
7494        default:
7495            goto cp0_unimplemented;
7496        }
7497        break;
7498    case CP0_REGISTER_10:
7499        switch (sel) {
7500        case CP0_REG10__ENTRYHI:
7501            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryHi));
7502            register_name = "EntryHi";
7503            break;
7504        default:
7505            goto cp0_unimplemented;
7506        }
7507        break;
7508    case CP0_REGISTER_11:
7509        switch (sel) {
7510        case CP0_REG11__COMPARE:
7511            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Compare));
7512            register_name = "Compare";
7513            break;
7514        /* 6,7 are implementation dependent */
7515        default:
7516            goto cp0_unimplemented;
7517        }
7518        break;
7519    case CP0_REGISTER_12:
7520        switch (sel) {
7521        case CP0_REG12__STATUS:
7522            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Status));
7523            register_name = "Status";
7524            break;
7525        case CP0_REG12__INTCTL:
7526            check_insn(ctx, ISA_MIPS_R2);
7527            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_IntCtl));
7528            register_name = "IntCtl";
7529            break;
7530        case CP0_REG12__SRSCTL:
7531            check_insn(ctx, ISA_MIPS_R2);
7532            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSCtl));
7533            register_name = "SRSCtl";
7534            break;
7535        case CP0_REG12__SRSMAP:
7536            check_insn(ctx, ISA_MIPS_R2);
7537            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSMap));
7538            register_name = "SRSMap";
7539            break;
7540        default:
7541            goto cp0_unimplemented;
7542        }
7543        break;
7544    case CP0_REGISTER_13:
7545        switch (sel) {
7546        case CP0_REG13__CAUSE:
7547            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Cause));
7548            register_name = "Cause";
7549            break;
7550        default:
7551            goto cp0_unimplemented;
7552        }
7553        break;
7554    case CP0_REGISTER_14:
7555        switch (sel) {
7556        case CP0_REG14__EPC:
7557            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EPC));
7558            register_name = "EPC";
7559            break;
7560        default:
7561            goto cp0_unimplemented;
7562        }
7563        break;
7564    case CP0_REGISTER_15:
7565        switch (sel) {
7566        case CP0_REG15__PRID:
7567            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PRid));
7568            register_name = "PRid";
7569            break;
7570        case CP0_REG15__EBASE:
7571            check_insn(ctx, ISA_MIPS_R2);
7572            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EBase));
7573            register_name = "EBase";
7574            break;
7575        case CP0_REG15__CMGCRBASE:
7576            check_insn(ctx, ISA_MIPS_R2);
7577            CP0_CHECK(ctx->cmgcr);
7578            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_CMGCRBase));
7579            register_name = "CMGCRBase";
7580            break;
7581        default:
7582            goto cp0_unimplemented;
7583        }
7584        break;
7585    case CP0_REGISTER_16:
7586        switch (sel) {
7587        case CP0_REG16__CONFIG:
7588            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config0));
7589            register_name = "Config";
7590            break;
7591        case CP0_REG16__CONFIG1:
7592            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config1));
7593            register_name = "Config1";
7594            break;
7595        case CP0_REG16__CONFIG2:
7596            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config2));
7597            register_name = "Config2";
7598            break;
7599        case CP0_REG16__CONFIG3:
7600            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config3));
7601            register_name = "Config3";
7602            break;
7603        case CP0_REG16__CONFIG4:
7604            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config4));
7605            register_name = "Config4";
7606            break;
7607        case CP0_REG16__CONFIG5:
7608            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config5));
7609            register_name = "Config5";
7610            break;
7611        /* 6,7 are implementation dependent */
7612        case CP0_REG16__CONFIG6:
7613            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config6));
7614            register_name = "Config6";
7615            break;
7616        case CP0_REG16__CONFIG7:
7617            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config7));
7618            register_name = "Config7";
7619            break;
7620        default:
7621            goto cp0_unimplemented;
7622        }
7623        break;
7624    case CP0_REGISTER_17:
7625        switch (sel) {
7626        case CP0_REG17__LLADDR:
7627            gen_helper_dmfc0_lladdr(arg, cpu_env);
7628            register_name = "LLAddr";
7629            break;
7630        case CP0_REG17__MAAR:
7631            CP0_CHECK(ctx->mrp);
7632            gen_helper_dmfc0_maar(arg, cpu_env);
7633            register_name = "MAAR";
7634            break;
7635        case CP0_REG17__MAARI:
7636            CP0_CHECK(ctx->mrp);
7637            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_MAARI));
7638            register_name = "MAARI";
7639            break;
7640        default:
7641            goto cp0_unimplemented;
7642        }
7643        break;
7644    case CP0_REGISTER_18:
7645        switch (sel) {
7646        case CP0_REG18__WATCHLO0:
7647        case CP0_REG18__WATCHLO1:
7648        case CP0_REG18__WATCHLO2:
7649        case CP0_REG18__WATCHLO3:
7650        case CP0_REG18__WATCHLO4:
7651        case CP0_REG18__WATCHLO5:
7652        case CP0_REG18__WATCHLO6:
7653        case CP0_REG18__WATCHLO7:
7654            CP0_CHECK(ctx->CP0_Config1 & (1 << CP0C1_WR));
7655            gen_helper_1e0i(dmfc0_watchlo, arg, sel);
7656            register_name = "WatchLo";
7657            break;
7658        default:
7659            goto cp0_unimplemented;
7660        }
7661        break;
7662    case CP0_REGISTER_19:
7663        switch (sel) {
7664        case CP0_REG19__WATCHHI0:
7665        case CP0_REG19__WATCHHI1:
7666        case CP0_REG19__WATCHHI2:
7667        case CP0_REG19__WATCHHI3:
7668        case CP0_REG19__WATCHHI4:
7669        case CP0_REG19__WATCHHI5:
7670        case CP0_REG19__WATCHHI6:
7671        case CP0_REG19__WATCHHI7:
7672            CP0_CHECK(ctx->CP0_Config1 & (1 << CP0C1_WR));
7673            gen_helper_1e0i(dmfc0_watchhi, arg, sel);
7674            register_name = "WatchHi";
7675            break;
7676        default:
7677            goto cp0_unimplemented;
7678        }
7679        break;
7680    case CP0_REGISTER_20:
7681        switch (sel) {
7682        case CP0_REG20__XCONTEXT:
7683            check_insn(ctx, ISA_MIPS3);
7684            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_XContext));
7685            register_name = "XContext";
7686            break;
7687        default:
7688            goto cp0_unimplemented;
7689        }
7690        break;
7691    case CP0_REGISTER_21:
7692        /* Officially reserved, but sel 0 is used for R1x000 framemask */
7693        CP0_CHECK(!(ctx->insn_flags & ISA_MIPS_R6));
7694        switch (sel) {
7695        case 0:
7696            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Framemask));
7697            register_name = "Framemask";
7698            break;
7699        default:
7700            goto cp0_unimplemented;
7701        }
7702        break;
7703    case CP0_REGISTER_22:
7704        tcg_gen_movi_tl(arg, 0); /* unimplemented */
7705        register_name = "'Diagnostic"; /* implementation dependent */
7706        break;
7707    case CP0_REGISTER_23:
7708        switch (sel) {
7709        case CP0_REG23__DEBUG:
7710            gen_helper_mfc0_debug(arg, cpu_env); /* EJTAG support */
7711            register_name = "Debug";
7712            break;
7713        case CP0_REG23__TRACECONTROL:
7714            /* PDtrace support */
7715            /* gen_helper_dmfc0_tracecontrol(arg, cpu_env);  */
7716            register_name = "TraceControl";
7717            goto cp0_unimplemented;
7718        case CP0_REG23__TRACECONTROL2:
7719            /* PDtrace support */
7720            /* gen_helper_dmfc0_tracecontrol2(arg, cpu_env); */
7721            register_name = "TraceControl2";
7722            goto cp0_unimplemented;
7723        case CP0_REG23__USERTRACEDATA1:
7724            /* PDtrace support */
7725            /* gen_helper_dmfc0_usertracedata1(arg, cpu_env);*/
7726            register_name = "UserTraceData1";
7727            goto cp0_unimplemented;
7728        case CP0_REG23__TRACEIBPC:
7729            /* PDtrace support */
7730            /* gen_helper_dmfc0_traceibpc(arg, cpu_env);     */
7731            register_name = "TraceIBPC";
7732            goto cp0_unimplemented;
7733        case CP0_REG23__TRACEDBPC:
7734            /* PDtrace support */
7735            /* gen_helper_dmfc0_tracedbpc(arg, cpu_env);     */
7736            register_name = "TraceDBPC";
7737            goto cp0_unimplemented;
7738        default:
7739            goto cp0_unimplemented;
7740        }
7741        break;
7742    case CP0_REGISTER_24:
7743        switch (sel) {
7744        case CP0_REG24__DEPC:
7745            /* EJTAG support */
7746            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_DEPC));
7747            register_name = "DEPC";
7748            break;
7749        default:
7750            goto cp0_unimplemented;
7751        }
7752        break;
7753    case CP0_REGISTER_25:
7754        switch (sel) {
7755        case CP0_REG25__PERFCTL0:
7756            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Performance0));
7757            register_name = "Performance0";
7758            break;
7759        case CP0_REG25__PERFCNT0:
7760            /* gen_helper_dmfc0_performance1(arg); */
7761            register_name = "Performance1";
7762            goto cp0_unimplemented;
7763        case CP0_REG25__PERFCTL1:
7764            /* gen_helper_dmfc0_performance2(arg); */
7765            register_name = "Performance2";
7766            goto cp0_unimplemented;
7767        case CP0_REG25__PERFCNT1:
7768            /* gen_helper_dmfc0_performance3(arg); */
7769            register_name = "Performance3";
7770            goto cp0_unimplemented;
7771        case CP0_REG25__PERFCTL2:
7772            /* gen_helper_dmfc0_performance4(arg); */
7773            register_name = "Performance4";
7774            goto cp0_unimplemented;
7775        case CP0_REG25__PERFCNT2:
7776            /* gen_helper_dmfc0_performance5(arg); */
7777            register_name = "Performance5";
7778            goto cp0_unimplemented;
7779        case CP0_REG25__PERFCTL3:
7780            /* gen_helper_dmfc0_performance6(arg); */
7781            register_name = "Performance6";
7782            goto cp0_unimplemented;
7783        case CP0_REG25__PERFCNT3:
7784            /* gen_helper_dmfc0_performance7(arg); */
7785            register_name = "Performance7";
7786            goto cp0_unimplemented;
7787        default:
7788            goto cp0_unimplemented;
7789        }
7790        break;
7791    case CP0_REGISTER_26:
7792        switch (sel) {
7793        case CP0_REG26__ERRCTL:
7794            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_ErrCtl));
7795            register_name = "ErrCtl";
7796            break;
7797        default:
7798            goto cp0_unimplemented;
7799        }
7800        break;
7801    case CP0_REGISTER_27:
7802        switch (sel) {
7803        /* ignored */
7804        case CP0_REG27__CACHERR:
7805            tcg_gen_movi_tl(arg, 0); /* unimplemented */
7806            register_name = "CacheErr";
7807            break;
7808        default:
7809            goto cp0_unimplemented;
7810        }
7811        break;
7812    case CP0_REGISTER_28:
7813        switch (sel) {
7814        case CP0_REG28__TAGLO:
7815        case CP0_REG28__TAGLO1:
7816        case CP0_REG28__TAGLO2:
7817        case CP0_REG28__TAGLO3:
7818            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_TagLo));
7819            register_name = "TagLo";
7820            break;
7821        case CP0_REG28__DATALO:
7822        case CP0_REG28__DATALO1:
7823        case CP0_REG28__DATALO2:
7824        case CP0_REG28__DATALO3:
7825            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataLo));
7826            register_name = "DataLo";
7827            break;
7828        default:
7829            goto cp0_unimplemented;
7830        }
7831        break;
7832    case CP0_REGISTER_29:
7833        switch (sel) {
7834        case CP0_REG29__TAGHI:
7835        case CP0_REG29__TAGHI1:
7836        case CP0_REG29__TAGHI2:
7837        case CP0_REG29__TAGHI3:
7838            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_TagHi));
7839            register_name = "TagHi";
7840            break;
7841        case CP0_REG29__DATAHI:
7842        case CP0_REG29__DATAHI1:
7843        case CP0_REG29__DATAHI2:
7844        case CP0_REG29__DATAHI3:
7845            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataHi));
7846            register_name = "DataHi";
7847            break;
7848        default:
7849            goto cp0_unimplemented;
7850        }
7851        break;
7852    case CP0_REGISTER_30:
7853        switch (sel) {
7854        case CP0_REG30__ERROREPC:
7855            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_ErrorEPC));
7856            register_name = "ErrorEPC";
7857            break;
7858        default:
7859            goto cp0_unimplemented;
7860        }
7861        break;
7862    case CP0_REGISTER_31:
7863        switch (sel) {
7864        case CP0_REG31__DESAVE:
7865            /* EJTAG support */
7866            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DESAVE));
7867            register_name = "DESAVE";
7868            break;
7869        case CP0_REG31__KSCRATCH1:
7870        case CP0_REG31__KSCRATCH2:
7871        case CP0_REG31__KSCRATCH3:
7872        case CP0_REG31__KSCRATCH4:
7873        case CP0_REG31__KSCRATCH5:
7874        case CP0_REG31__KSCRATCH6:
7875            CP0_CHECK(ctx->kscrexist & (1 << sel));
7876            tcg_gen_ld_tl(arg, cpu_env,
7877                          offsetof(CPUMIPSState, CP0_KScratch[sel - 2]));
7878            register_name = "KScratch";
7879            break;
7880        default:
7881            goto cp0_unimplemented;
7882        }
7883        break;
7884    default:
7885        goto cp0_unimplemented;
7886    }
7887    trace_mips_translate_c0("dmfc0", register_name, reg, sel);
7888    return;
7889
7890cp0_unimplemented:
7891    qemu_log_mask(LOG_UNIMP, "dmfc0 %s (reg %d sel %d)\n",
7892                  register_name, reg, sel);
7893    gen_mfc0_unimplemented(ctx, arg);
7894}
7895
7896static void gen_dmtc0(DisasContext *ctx, TCGv arg, int reg, int sel)
7897{
7898    const char *register_name = "invalid";
7899
7900    if (sel != 0) {
7901        check_insn(ctx, ISA_MIPS_R1);
7902    }
7903
7904    if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
7905        gen_io_start();
7906    }
7907
7908    switch (reg) {
7909    case CP0_REGISTER_00:
7910        switch (sel) {
7911        case CP0_REG00__INDEX:
7912            gen_helper_mtc0_index(cpu_env, arg);
7913            register_name = "Index";
7914            break;
7915        case CP0_REG00__MVPCONTROL:
7916            CP0_CHECK(ctx->insn_flags & ASE_MT);
7917            gen_helper_mtc0_mvpcontrol(cpu_env, arg);
7918            register_name = "MVPControl";
7919            break;
7920        case CP0_REG00__MVPCONF0:
7921            CP0_CHECK(ctx->insn_flags & ASE_MT);
7922            /* ignored */
7923            register_name = "MVPConf0";
7924            break;
7925        case CP0_REG00__MVPCONF1:
7926            CP0_CHECK(ctx->insn_flags & ASE_MT);
7927            /* ignored */
7928            register_name = "MVPConf1";
7929            break;
7930        case CP0_REG00__VPCONTROL:
7931            CP0_CHECK(ctx->vp);
7932            /* ignored */
7933            register_name = "VPControl";
7934            break;
7935        default:
7936            goto cp0_unimplemented;
7937        }
7938        break;
7939    case CP0_REGISTER_01:
7940        switch (sel) {
7941        case CP0_REG01__RANDOM:
7942            /* ignored */
7943            register_name = "Random";
7944            break;
7945        case CP0_REG01__VPECONTROL:
7946            CP0_CHECK(ctx->insn_flags & ASE_MT);
7947            gen_helper_mtc0_vpecontrol(cpu_env, arg);
7948            register_name = "VPEControl";
7949            break;
7950        case CP0_REG01__VPECONF0:
7951            CP0_CHECK(ctx->insn_flags & ASE_MT);
7952            gen_helper_mtc0_vpeconf0(cpu_env, arg);
7953            register_name = "VPEConf0";
7954            break;
7955        case CP0_REG01__VPECONF1:
7956            CP0_CHECK(ctx->insn_flags & ASE_MT);
7957            gen_helper_mtc0_vpeconf1(cpu_env, arg);
7958            register_name = "VPEConf1";
7959            break;
7960        case CP0_REG01__YQMASK:
7961            CP0_CHECK(ctx->insn_flags & ASE_MT);
7962            gen_helper_mtc0_yqmask(cpu_env, arg);
7963            register_name = "YQMask";
7964            break;
7965        case CP0_REG01__VPESCHEDULE:
7966            CP0_CHECK(ctx->insn_flags & ASE_MT);
7967            tcg_gen_st_tl(arg, cpu_env,
7968                          offsetof(CPUMIPSState, CP0_VPESchedule));
7969            register_name = "VPESchedule";
7970            break;
7971        case CP0_REG01__VPESCHEFBACK:
7972            CP0_CHECK(ctx->insn_flags & ASE_MT);
7973            tcg_gen_st_tl(arg, cpu_env,
7974                          offsetof(CPUMIPSState, CP0_VPEScheFBack));
7975            register_name = "VPEScheFBack";
7976            break;
7977        case CP0_REG01__VPEOPT:
7978            CP0_CHECK(ctx->insn_flags & ASE_MT);
7979            gen_helper_mtc0_vpeopt(cpu_env, arg);
7980            register_name = "VPEOpt";
7981            break;
7982        default:
7983            goto cp0_unimplemented;
7984        }
7985        break;
7986    case CP0_REGISTER_02:
7987        switch (sel) {
7988        case CP0_REG02__ENTRYLO0:
7989            gen_helper_dmtc0_entrylo0(cpu_env, arg);
7990            register_name = "EntryLo0";
7991            break;
7992        case CP0_REG02__TCSTATUS:
7993            CP0_CHECK(ctx->insn_flags & ASE_MT);
7994            gen_helper_mtc0_tcstatus(cpu_env, arg);
7995            register_name = "TCStatus";
7996            break;
7997        case CP0_REG02__TCBIND:
7998            CP0_CHECK(ctx->insn_flags & ASE_MT);
7999            gen_helper_mtc0_tcbind(cpu_env, arg);
8000            register_name = "TCBind";
8001            break;
8002        case CP0_REG02__TCRESTART:
8003            CP0_CHECK(ctx->insn_flags & ASE_MT);
8004            gen_helper_mtc0_tcrestart(cpu_env, arg);
8005            register_name = "TCRestart";
8006            break;
8007        case CP0_REG02__TCHALT:
8008            CP0_CHECK(ctx->insn_flags & ASE_MT);
8009            gen_helper_mtc0_tchalt(cpu_env, arg);
8010            register_name = "TCHalt";
8011            break;
8012        case CP0_REG02__TCCONTEXT:
8013            CP0_CHECK(ctx->insn_flags & ASE_MT);
8014            gen_helper_mtc0_tccontext(cpu_env, arg);
8015            register_name = "TCContext";
8016            break;
8017        case CP0_REG02__TCSCHEDULE:
8018            CP0_CHECK(ctx->insn_flags & ASE_MT);
8019            gen_helper_mtc0_tcschedule(cpu_env, arg);
8020            register_name = "TCSchedule";
8021            break;
8022        case CP0_REG02__TCSCHEFBACK:
8023            CP0_CHECK(ctx->insn_flags & ASE_MT);
8024            gen_helper_mtc0_tcschefback(cpu_env, arg);
8025            register_name = "TCScheFBack";
8026            break;
8027        default:
8028            goto cp0_unimplemented;
8029        }
8030        break;
8031    case CP0_REGISTER_03:
8032        switch (sel) {
8033        case CP0_REG03__ENTRYLO1:
8034            gen_helper_dmtc0_entrylo1(cpu_env, arg);
8035            register_name = "EntryLo1";
8036            break;
8037        case CP0_REG03__GLOBALNUM:
8038            CP0_CHECK(ctx->vp);
8039            /* ignored */
8040            register_name = "GlobalNumber";
8041            break;
8042        default:
8043            goto cp0_unimplemented;
8044        }
8045        break;
8046    case CP0_REGISTER_04:
8047        switch (sel) {
8048        case CP0_REG04__CONTEXT:
8049            gen_helper_mtc0_context(cpu_env, arg);
8050            register_name = "Context";
8051            break;
8052        case CP0_REG04__CONTEXTCONFIG:
8053            /* SmartMIPS ASE */
8054            /* gen_helper_dmtc0_contextconfig(arg); */
8055            register_name = "ContextConfig";
8056            goto cp0_unimplemented;
8057        case CP0_REG04__USERLOCAL:
8058            CP0_CHECK(ctx->ulri);
8059            tcg_gen_st_tl(arg, cpu_env,
8060                          offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
8061            register_name = "UserLocal";
8062            break;
8063        case CP0_REG04__MMID:
8064            CP0_CHECK(ctx->mi);
8065            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_MemoryMapID));
8066            register_name = "MMID";
8067            break;
8068        default:
8069            goto cp0_unimplemented;
8070        }
8071        break;
8072    case CP0_REGISTER_05:
8073        switch (sel) {
8074        case CP0_REG05__PAGEMASK:
8075            gen_helper_mtc0_pagemask(cpu_env, arg);
8076            register_name = "PageMask";
8077            break;
8078        case CP0_REG05__PAGEGRAIN:
8079            check_insn(ctx, ISA_MIPS_R2);
8080            gen_helper_mtc0_pagegrain(cpu_env, arg);
8081            register_name = "PageGrain";
8082            break;
8083        case CP0_REG05__SEGCTL0:
8084            CP0_CHECK(ctx->sc);
8085            gen_helper_mtc0_segctl0(cpu_env, arg);
8086            register_name = "SegCtl0";
8087            break;
8088        case CP0_REG05__SEGCTL1:
8089            CP0_CHECK(ctx->sc);
8090            gen_helper_mtc0_segctl1(cpu_env, arg);
8091            register_name = "SegCtl1";
8092            break;
8093        case CP0_REG05__SEGCTL2:
8094            CP0_CHECK(ctx->sc);
8095            gen_helper_mtc0_segctl2(cpu_env, arg);
8096            register_name = "SegCtl2";
8097            break;
8098        case CP0_REG05__PWBASE:
8099            check_pw(ctx);
8100            tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_PWBase));
8101            register_name = "PWBase";
8102            break;
8103        case CP0_REG05__PWFIELD:
8104            check_pw(ctx);
8105            gen_helper_mtc0_pwfield(cpu_env, arg);
8106            register_name = "PWField";
8107            break;
8108        case CP0_REG05__PWSIZE:
8109            check_pw(ctx);
8110            gen_helper_mtc0_pwsize(cpu_env, arg);
8111            register_name = "PWSize";
8112            break;
8113        default:
8114            goto cp0_unimplemented;
8115        }
8116        break;
8117    case CP0_REGISTER_06:
8118        switch (sel) {
8119        case CP0_REG06__WIRED:
8120            gen_helper_mtc0_wired(cpu_env, arg);
8121            register_name = "Wired";
8122            break;
8123        case CP0_REG06__SRSCONF0:
8124            check_insn(ctx, ISA_MIPS_R2);
8125            gen_helper_mtc0_srsconf0(cpu_env, arg);
8126            register_name = "SRSConf0";
8127            break;
8128        case CP0_REG06__SRSCONF1:
8129            check_insn(ctx, ISA_MIPS_R2);
8130            gen_helper_mtc0_srsconf1(cpu_env, arg);
8131            register_name = "SRSConf1";
8132            break;
8133        case CP0_REG06__SRSCONF2:
8134            check_insn(ctx, ISA_MIPS_R2);
8135            gen_helper_mtc0_srsconf2(cpu_env, arg);
8136            register_name = "SRSConf2";
8137            break;
8138        case CP0_REG06__SRSCONF3:
8139            check_insn(ctx, ISA_MIPS_R2);
8140            gen_helper_mtc0_srsconf3(cpu_env, arg);
8141            register_name = "SRSConf3";
8142            break;
8143        case CP0_REG06__SRSCONF4:
8144            check_insn(ctx, ISA_MIPS_R2);
8145            gen_helper_mtc0_srsconf4(cpu_env, arg);
8146            register_name = "SRSConf4";
8147            break;
8148        case CP0_REG06__PWCTL:
8149            check_pw(ctx);
8150            gen_helper_mtc0_pwctl(cpu_env, arg);
8151            register_name = "PWCtl";
8152            break;
8153        default:
8154            goto cp0_unimplemented;
8155        }
8156        break;
8157    case CP0_REGISTER_07:
8158        switch (sel) {
8159        case CP0_REG07__HWRENA:
8160            check_insn(ctx, ISA_MIPS_R2);
8161            gen_helper_mtc0_hwrena(cpu_env, arg);
8162            ctx->base.is_jmp = DISAS_STOP;
8163            register_name = "HWREna";
8164            break;
8165        default:
8166            goto cp0_unimplemented;
8167        }
8168        break;
8169    case CP0_REGISTER_08:
8170        switch (sel) {
8171        case CP0_REG08__BADVADDR:
8172            /* ignored */
8173            register_name = "BadVAddr";
8174            break;
8175        case CP0_REG08__BADINSTR:
8176            /* ignored */
8177            register_name = "BadInstr";
8178            break;
8179        case CP0_REG08__BADINSTRP:
8180            /* ignored */
8181            register_name = "BadInstrP";
8182            break;
8183        case CP0_REG08__BADINSTRX:
8184            /* ignored */
8185            register_name = "BadInstrX";
8186            break;
8187        default:
8188            goto cp0_unimplemented;
8189        }
8190        break;
8191    case CP0_REGISTER_09:
8192        switch (sel) {
8193        case CP0_REG09__COUNT:
8194            gen_helper_mtc0_count(cpu_env, arg);
8195            register_name = "Count";
8196            break;
8197        case CP0_REG09__SAARI:
8198            CP0_CHECK(ctx->saar);
8199            gen_helper_mtc0_saari(cpu_env, arg);
8200            register_name = "SAARI";
8201            break;
8202        case CP0_REG09__SAAR:
8203            CP0_CHECK(ctx->saar);
8204            gen_helper_mtc0_saar(cpu_env, arg);
8205            register_name = "SAAR";
8206            break;
8207        default:
8208            goto cp0_unimplemented;
8209        }
8210        /* Stop translation as we may have switched the execution mode */
8211        ctx->base.is_jmp = DISAS_STOP;
8212        break;
8213    case CP0_REGISTER_10:
8214        switch (sel) {
8215        case CP0_REG10__ENTRYHI:
8216            gen_helper_mtc0_entryhi(cpu_env, arg);
8217            register_name = "EntryHi";
8218            break;
8219        default:
8220            goto cp0_unimplemented;
8221        }
8222        break;
8223    case CP0_REGISTER_11:
8224        switch (sel) {
8225        case CP0_REG11__COMPARE:
8226            gen_helper_mtc0_compare(cpu_env, arg);
8227            register_name = "Compare";
8228            break;
8229        /* 6,7 are implementation dependent */
8230        default:
8231            goto cp0_unimplemented;
8232        }
8233        /* Stop translation as we may have switched the execution mode */
8234        ctx->base.is_jmp = DISAS_STOP;
8235        break;
8236    case CP0_REGISTER_12:
8237        switch (sel) {
8238        case CP0_REG12__STATUS:
8239            save_cpu_state(ctx, 1);
8240            gen_helper_mtc0_status(cpu_env, arg);
8241            /* DISAS_STOP isn't good enough here, hflags may have changed. */
8242            gen_save_pc(ctx->base.pc_next + 4);
8243            ctx->base.is_jmp = DISAS_EXIT;
8244            register_name = "Status";
8245            break;
8246        case CP0_REG12__INTCTL:
8247            check_insn(ctx, ISA_MIPS_R2);
8248            gen_helper_mtc0_intctl(cpu_env, arg);
8249            /* Stop translation as we may have switched the execution mode */
8250            ctx->base.is_jmp = DISAS_STOP;
8251            register_name = "IntCtl";
8252            break;
8253        case CP0_REG12__SRSCTL:
8254            check_insn(ctx, ISA_MIPS_R2);
8255            gen_helper_mtc0_srsctl(cpu_env, arg);
8256            /* Stop translation as we may have switched the execution mode */
8257            ctx->base.is_jmp = DISAS_STOP;
8258            register_name = "SRSCtl";
8259            break;
8260        case CP0_REG12__SRSMAP:
8261            check_insn(ctx, ISA_MIPS_R2);
8262            gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_SRSMap));
8263            /* Stop translation as we may have switched the execution mode */
8264            ctx->base.is_jmp = DISAS_STOP;
8265            register_name = "SRSMap";
8266            break;
8267        default:
8268            goto cp0_unimplemented;
8269        }
8270        break;
8271    case CP0_REGISTER_13:
8272        switch (sel) {
8273        case CP0_REG13__CAUSE:
8274            save_cpu_state(ctx, 1);
8275            gen_helper_mtc0_cause(cpu_env, arg);
8276            /*
8277             * Stop translation as we may have triggered an interrupt.
8278             * DISAS_STOP isn't sufficient, we need to ensure we break out of
8279             * translated code to check for pending interrupts.
8280             */
8281            gen_save_pc(ctx->base.pc_next + 4);
8282            ctx->base.is_jmp = DISAS_EXIT;
8283            register_name = "Cause";
8284            break;
8285        default:
8286            goto cp0_unimplemented;
8287        }
8288        break;
8289    case CP0_REGISTER_14:
8290        switch (sel) {
8291        case CP0_REG14__EPC:
8292            tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EPC));
8293            register_name = "EPC";
8294            break;
8295        default:
8296            goto cp0_unimplemented;
8297        }
8298        break;
8299    case CP0_REGISTER_15:
8300        switch (sel) {
8301        case CP0_REG15__PRID:
8302            /* ignored */
8303            register_name = "PRid";
8304            break;
8305        case CP0_REG15__EBASE:
8306            check_insn(ctx, ISA_MIPS_R2);
8307            gen_helper_mtc0_ebase(cpu_env, arg);
8308            register_name = "EBase";
8309            break;
8310        default:
8311            goto cp0_unimplemented;
8312        }
8313        break;
8314    case CP0_REGISTER_16:
8315        switch (sel) {
8316        case CP0_REG16__CONFIG:
8317            gen_helper_mtc0_config0(cpu_env, arg);
8318            register_name = "Config";
8319            /* Stop translation as we may have switched the execution mode */
8320            ctx->base.is_jmp = DISAS_STOP;
8321            break;
8322        case CP0_REG16__CONFIG1:
8323            /* ignored, read only */
8324            register_name = "Config1";
8325            break;
8326        case CP0_REG16__CONFIG2:
8327            gen_helper_mtc0_config2(cpu_env, arg);
8328            register_name = "Config2";
8329            /* Stop translation as we may have switched the execution mode */
8330            ctx->base.is_jmp = DISAS_STOP;
8331            break;
8332        case CP0_REG16__CONFIG3:
8333            gen_helper_mtc0_config3(cpu_env, arg);
8334            register_name = "Config3";
8335            /* Stop translation as we may have switched the execution mode */
8336            ctx->base.is_jmp = DISAS_STOP;
8337            break;
8338        case CP0_REG16__CONFIG4:
8339            /* currently ignored */
8340            register_name = "Config4";
8341            break;
8342        case CP0_REG16__CONFIG5:
8343            gen_helper_mtc0_config5(cpu_env, arg);
8344            register_name = "Config5";
8345            /* Stop translation as we may have switched the execution mode */
8346            ctx->base.is_jmp = DISAS_STOP;
8347            break;
8348        /* 6,7 are implementation dependent */
8349        default:
8350            register_name = "Invalid config selector";
8351            goto cp0_unimplemented;
8352        }
8353        break;
8354    case CP0_REGISTER_17:
8355        switch (sel) {
8356        case CP0_REG17__LLADDR:
8357            gen_helper_mtc0_lladdr(cpu_env, arg);
8358            register_name = "LLAddr";
8359            break;
8360        case CP0_REG17__MAAR:
8361            CP0_CHECK(ctx->mrp);
8362            gen_helper_mtc0_maar(cpu_env, arg);
8363            register_name = "MAAR";
8364            break;
8365        case CP0_REG17__MAARI:
8366            CP0_CHECK(ctx->mrp);
8367            gen_helper_mtc0_maari(cpu_env, arg);
8368            register_name = "MAARI";
8369            break;
8370        default:
8371            goto cp0_unimplemented;
8372        }
8373        break;
8374    case CP0_REGISTER_18:
8375        switch (sel) {
8376        case CP0_REG18__WATCHLO0:
8377        case CP0_REG18__WATCHLO1:
8378        case CP0_REG18__WATCHLO2:
8379        case CP0_REG18__WATCHLO3:
8380        case CP0_REG18__WATCHLO4:
8381        case CP0_REG18__WATCHLO5:
8382        case CP0_REG18__WATCHLO6:
8383        case CP0_REG18__WATCHLO7:
8384            CP0_CHECK(ctx->CP0_Config1 & (1 << CP0C1_WR));
8385            gen_helper_0e1i(mtc0_watchlo, arg, sel);
8386            register_name = "WatchLo";
8387            break;
8388        default:
8389            goto cp0_unimplemented;
8390        }
8391        break;
8392    case CP0_REGISTER_19:
8393        switch (sel) {
8394        case CP0_REG19__WATCHHI0:
8395        case CP0_REG19__WATCHHI1:
8396        case CP0_REG19__WATCHHI2:
8397        case CP0_REG19__WATCHHI3:
8398        case CP0_REG19__WATCHHI4:
8399        case CP0_REG19__WATCHHI5:
8400        case CP0_REG19__WATCHHI6:
8401        case CP0_REG19__WATCHHI7:
8402            CP0_CHECK(ctx->CP0_Config1 & (1 << CP0C1_WR));
8403            gen_helper_0e1i(mtc0_watchhi, arg, sel);
8404            register_name = "WatchHi";
8405            break;
8406        default:
8407            goto cp0_unimplemented;
8408        }
8409        break;
8410    case CP0_REGISTER_20:
8411        switch (sel) {
8412        case CP0_REG20__XCONTEXT:
8413            check_insn(ctx, ISA_MIPS3);
8414            gen_helper_mtc0_xcontext(cpu_env, arg);
8415            register_name = "XContext";
8416            break;
8417        default:
8418            goto cp0_unimplemented;
8419        }
8420        break;
8421    case CP0_REGISTER_21:
8422       /* Officially reserved, but sel 0 is used for R1x000 framemask */
8423        CP0_CHECK(!(ctx->insn_flags & ISA_MIPS_R6));
8424        switch (sel) {
8425        case 0:
8426            gen_helper_mtc0_framemask(cpu_env, arg);
8427            register_name = "Framemask";
8428            break;
8429        default:
8430            goto cp0_unimplemented;
8431        }
8432        break;
8433    case CP0_REGISTER_22:
8434        /* ignored */
8435        register_name = "Diagnostic"; /* implementation dependent */
8436        break;
8437    case CP0_REGISTER_23:
8438        switch (sel) {
8439        case CP0_REG23__DEBUG:
8440            gen_helper_mtc0_debug(cpu_env, arg); /* EJTAG support */
8441            /* DISAS_STOP isn't good enough here, hflags may have changed. */
8442            gen_save_pc(ctx->base.pc_next + 4);
8443            ctx->base.is_jmp = DISAS_EXIT;
8444            register_name = "Debug";
8445            break;
8446        case CP0_REG23__TRACECONTROL:
8447            /* PDtrace support */
8448            /* gen_helper_mtc0_tracecontrol(cpu_env, arg);  */
8449            /* Stop translation as we may have switched the execution mode */
8450            ctx->base.is_jmp = DISAS_STOP;
8451            register_name = "TraceControl";
8452            goto cp0_unimplemented;
8453        case CP0_REG23__TRACECONTROL2:
8454            /* PDtrace support */
8455            /* gen_helper_mtc0_tracecontrol2(cpu_env, arg); */
8456            /* Stop translation as we may have switched the execution mode */
8457            ctx->base.is_jmp = DISAS_STOP;
8458            register_name = "TraceControl2";
8459            goto cp0_unimplemented;
8460        case CP0_REG23__USERTRACEDATA1:
8461            /* PDtrace support */
8462            /* gen_helper_mtc0_usertracedata1(cpu_env, arg);*/
8463            /* Stop translation as we may have switched the execution mode */
8464            ctx->base.is_jmp = DISAS_STOP;
8465            register_name = "UserTraceData1";
8466            goto cp0_unimplemented;
8467        case CP0_REG23__TRACEIBPC:
8468            /* PDtrace support */
8469            /* gen_helper_mtc0_traceibpc(cpu_env, arg);     */
8470            /* Stop translation as we may have switched the execution mode */
8471            ctx->base.is_jmp = DISAS_STOP;
8472            register_name = "TraceIBPC";
8473            goto cp0_unimplemented;
8474        case CP0_REG23__TRACEDBPC:
8475            /* PDtrace support */
8476            /* gen_helper_mtc0_tracedbpc(cpu_env, arg);     */
8477            /* Stop translation as we may have switched the execution mode */
8478            ctx->base.is_jmp = DISAS_STOP;
8479            register_name = "TraceDBPC";
8480            goto cp0_unimplemented;
8481        default:
8482            goto cp0_unimplemented;
8483        }
8484        break;
8485    case CP0_REGISTER_24:
8486        switch (sel) {
8487        case CP0_REG24__DEPC:
8488            /* EJTAG support */
8489            tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_DEPC));
8490            register_name = "DEPC";
8491            break;
8492        default:
8493            goto cp0_unimplemented;
8494        }
8495        break;
8496    case CP0_REGISTER_25:
8497        switch (sel) {
8498        case CP0_REG25__PERFCTL0:
8499            gen_helper_mtc0_performance0(cpu_env, arg);
8500            register_name = "Performance0";
8501            break;
8502        case CP0_REG25__PERFCNT0:
8503            /* gen_helper_mtc0_performance1(cpu_env, arg); */
8504            register_name = "Performance1";
8505            goto cp0_unimplemented;
8506        case CP0_REG25__PERFCTL1:
8507            /* gen_helper_mtc0_performance2(cpu_env, arg); */
8508            register_name = "Performance2";
8509            goto cp0_unimplemented;
8510        case CP0_REG25__PERFCNT1:
8511            /* gen_helper_mtc0_performance3(cpu_env, arg); */
8512            register_name = "Performance3";
8513            goto cp0_unimplemented;
8514        case CP0_REG25__PERFCTL2:
8515            /* gen_helper_mtc0_performance4(cpu_env, arg); */
8516            register_name = "Performance4";
8517            goto cp0_unimplemented;
8518        case CP0_REG25__PERFCNT2:
8519            /* gen_helper_mtc0_performance5(cpu_env, arg); */
8520            register_name = "Performance5";
8521            goto cp0_unimplemented;
8522        case CP0_REG25__PERFCTL3:
8523            /* gen_helper_mtc0_performance6(cpu_env, arg); */
8524            register_name = "Performance6";
8525            goto cp0_unimplemented;
8526        case CP0_REG25__PERFCNT3:
8527            /* gen_helper_mtc0_performance7(cpu_env, arg); */
8528            register_name = "Performance7";
8529            goto cp0_unimplemented;
8530        default:
8531            goto cp0_unimplemented;
8532        }
8533        break;
8534    case CP0_REGISTER_26:
8535        switch (sel) {
8536        case CP0_REG26__ERRCTL:
8537            gen_helper_mtc0_errctl(cpu_env, arg);
8538            ctx->base.is_jmp = DISAS_STOP;
8539            register_name = "ErrCtl";
8540            break;
8541        default:
8542            goto cp0_unimplemented;
8543        }
8544        break;
8545    case CP0_REGISTER_27:
8546        switch (sel) {
8547        case CP0_REG27__CACHERR:
8548            /* ignored */
8549            register_name = "CacheErr";
8550            break;
8551        default:
8552            goto cp0_unimplemented;
8553        }
8554        break;
8555    case CP0_REGISTER_28:
8556        switch (sel) {
8557        case CP0_REG28__TAGLO:
8558        case CP0_REG28__TAGLO1:
8559        case CP0_REG28__TAGLO2:
8560        case CP0_REG28__TAGLO3:
8561            gen_helper_mtc0_taglo(cpu_env, arg);
8562            register_name = "TagLo";
8563            break;
8564        case CP0_REG28__DATALO:
8565        case CP0_REG28__DATALO1:
8566        case CP0_REG28__DATALO2:
8567        case CP0_REG28__DATALO3:
8568            gen_helper_mtc0_datalo(cpu_env, arg);
8569            register_name = "DataLo";
8570            break;
8571        default:
8572            goto cp0_unimplemented;
8573        }
8574        break;
8575    case CP0_REGISTER_29:
8576        switch (sel) {
8577        case CP0_REG29__TAGHI:
8578        case CP0_REG29__TAGHI1:
8579        case CP0_REG29__TAGHI2:
8580        case CP0_REG29__TAGHI3:
8581            gen_helper_mtc0_taghi(cpu_env, arg);
8582            register_name = "TagHi";
8583            break;
8584        case CP0_REG29__DATAHI:
8585        case CP0_REG29__DATAHI1:
8586        case CP0_REG29__DATAHI2:
8587        case CP0_REG29__DATAHI3:
8588            gen_helper_mtc0_datahi(cpu_env, arg);
8589            register_name = "DataHi";
8590            break;
8591        default:
8592            register_name = "invalid sel";
8593            goto cp0_unimplemented;
8594        }
8595        break;
8596    case CP0_REGISTER_30:
8597        switch (sel) {
8598        case CP0_REG30__ERROREPC:
8599            tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_ErrorEPC));
8600            register_name = "ErrorEPC";
8601            break;
8602        default:
8603            goto cp0_unimplemented;
8604        }
8605        break;
8606    case CP0_REGISTER_31:
8607        switch (sel) {
8608        case CP0_REG31__DESAVE:
8609            /* EJTAG support */
8610            gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_DESAVE));
8611            register_name = "DESAVE";
8612            break;
8613        case CP0_REG31__KSCRATCH1:
8614        case CP0_REG31__KSCRATCH2:
8615        case CP0_REG31__KSCRATCH3:
8616        case CP0_REG31__KSCRATCH4:
8617        case CP0_REG31__KSCRATCH5:
8618        case CP0_REG31__KSCRATCH6:
8619            CP0_CHECK(ctx->kscrexist & (1 << sel));
8620            tcg_gen_st_tl(arg, cpu_env,
8621                          offsetof(CPUMIPSState, CP0_KScratch[sel - 2]));
8622            register_name = "KScratch";
8623            break;
8624        default:
8625            goto cp0_unimplemented;
8626        }
8627        break;
8628    default:
8629        goto cp0_unimplemented;
8630    }
8631    trace_mips_translate_c0("dmtc0", register_name, reg, sel);
8632
8633    /* For simplicity assume that all writes can cause interrupts.  */
8634    if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
8635        /*
8636         * DISAS_STOP isn't sufficient, we need to ensure we break out of
8637         * translated code to check for pending interrupts.
8638         */
8639        gen_save_pc(ctx->base.pc_next + 4);
8640        ctx->base.is_jmp = DISAS_EXIT;
8641    }
8642    return;
8643
8644cp0_unimplemented:
8645    qemu_log_mask(LOG_UNIMP, "dmtc0 %s (reg %d sel %d)\n",
8646                  register_name, reg, sel);
8647}
8648#endif /* TARGET_MIPS64 */
8649
8650static void gen_mftr(CPUMIPSState *env, DisasContext *ctx, int rt, int rd,
8651                     int u, int sel, int h)
8652{
8653    int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
8654    TCGv t0 = tcg_temp_local_new();
8655
8656    if ((env->CP0_VPEConf0 & (1 << CP0VPEC0_MVP)) == 0 &&
8657        ((env->tcs[other_tc].CP0_TCBind & (0xf << CP0TCBd_CurVPE)) !=
8658         (env->active_tc.CP0_TCBind & (0xf << CP0TCBd_CurVPE)))) {
8659        tcg_gen_movi_tl(t0, -1);
8660    } else if ((env->CP0_VPEControl & (0xff << CP0VPECo_TargTC)) >
8661               (env->mvp->CP0_MVPConf0 & (0xff << CP0MVPC0_PTC))) {
8662        tcg_gen_movi_tl(t0, -1);
8663    } else if (u == 0) {
8664        switch (rt) {
8665        case 1:
8666            switch (sel) {
8667            case 1:
8668                gen_helper_mftc0_vpecontrol(t0, cpu_env);
8669                break;
8670            case 2:
8671                gen_helper_mftc0_vpeconf0(t0, cpu_env);
8672                break;
8673            default:
8674                goto die;
8675                break;
8676            }
8677            break;
8678        case 2:
8679            switch (sel) {
8680            case 1:
8681                gen_helper_mftc0_tcstatus(t0, cpu_env);
8682                break;
8683            case 2:
8684                gen_helper_mftc0_tcbind(t0, cpu_env);
8685                break;
8686            case 3:
8687                gen_helper_mftc0_tcrestart(t0, cpu_env);
8688                break;
8689            case 4:
8690                gen_helper_mftc0_tchalt(t0, cpu_env);
8691                break;
8692            case 5:
8693                gen_helper_mftc0_tccontext(t0, cpu_env);
8694                break;
8695            case 6:
8696                gen_helper_mftc0_tcschedule(t0, cpu_env);
8697                break;
8698            case 7:
8699                gen_helper_mftc0_tcschefback(t0, cpu_env);
8700                break;
8701            default:
8702                gen_mfc0(ctx, t0, rt, sel);
8703                break;
8704            }
8705            break;
8706        case 10:
8707            switch (sel) {
8708            case 0:
8709                gen_helper_mftc0_entryhi(t0, cpu_env);
8710                break;
8711            default:
8712                gen_mfc0(ctx, t0, rt, sel);
8713                break;
8714            }
8715            break;
8716        case 12:
8717            switch (sel) {
8718            case 0:
8719                gen_helper_mftc0_status(t0, cpu_env);
8720                break;
8721            default:
8722                gen_mfc0(ctx, t0, rt, sel);
8723                break;
8724            }
8725            break;
8726        case 13:
8727            switch (sel) {
8728            case 0:
8729                gen_helper_mftc0_cause(t0, cpu_env);
8730                break;
8731            default:
8732                goto die;
8733                break;
8734            }
8735            break;
8736        case 14:
8737            switch (sel) {
8738            case 0:
8739                gen_helper_mftc0_epc(t0, cpu_env);
8740                break;
8741            default:
8742                goto die;
8743                break;
8744            }
8745            break;
8746        case 15:
8747            switch (sel) {
8748            case 1:
8749                gen_helper_mftc0_ebase(t0, cpu_env);
8750                break;
8751            default:
8752                goto die;
8753                break;
8754            }
8755            break;
8756        case 16:
8757            switch (sel) {
8758            case 0:
8759            case 1:
8760            case 2:
8761            case 3:
8762            case 4:
8763            case 5:
8764            case 6:
8765            case 7:
8766                gen_helper_mftc0_configx(t0, cpu_env, tcg_const_tl(sel));
8767                break;
8768            default:
8769                goto die;
8770                break;
8771            }
8772            break;
8773        case 23:
8774            switch (sel) {
8775            case 0:
8776                gen_helper_mftc0_debug(t0, cpu_env);
8777                break;
8778            default:
8779                gen_mfc0(ctx, t0, rt, sel);
8780                break;
8781            }
8782            break;
8783        default:
8784            gen_mfc0(ctx, t0, rt, sel);
8785        }
8786    } else {
8787        switch (sel) {
8788        /* GPR registers. */
8789        case 0:
8790            gen_helper_1e0i(mftgpr, t0, rt);
8791            break;
8792        /* Auxiliary CPU registers */
8793        case 1:
8794            switch (rt) {
8795            case 0:
8796                gen_helper_1e0i(mftlo, t0, 0);
8797                break;
8798            case 1:
8799                gen_helper_1e0i(mfthi, t0, 0);
8800                break;
8801            case 2:
8802                gen_helper_1e0i(mftacx, t0, 0);
8803                break;
8804            case 4:
8805                gen_helper_1e0i(mftlo, t0, 1);
8806                break;
8807            case 5:
8808                gen_helper_1e0i(mfthi, t0, 1);
8809                break;
8810            case 6:
8811                gen_helper_1e0i(mftacx, t0, 1);
8812                break;
8813            case 8:
8814                gen_helper_1e0i(mftlo, t0, 2);
8815                break;
8816            case 9:
8817                gen_helper_1e0i(mfthi, t0, 2);
8818                break;
8819            case 10:
8820                gen_helper_1e0i(mftacx, t0, 2);
8821                break;
8822            case 12:
8823                gen_helper_1e0i(mftlo, t0, 3);
8824                break;
8825            case 13:
8826                gen_helper_1e0i(mfthi, t0, 3);
8827                break;
8828            case 14:
8829                gen_helper_1e0i(mftacx, t0, 3);
8830                break;
8831            case 16:
8832                gen_helper_mftdsp(t0, cpu_env);
8833                break;
8834            default:
8835                goto die;
8836            }
8837            break;
8838        /* Floating point (COP1). */
8839        case 2:
8840            /* XXX: For now we support only a single FPU context. */
8841            if (h == 0) {
8842                TCGv_i32 fp0 = tcg_temp_new_i32();
8843
8844                gen_load_fpr32(ctx, fp0, rt);
8845                tcg_gen_ext_i32_tl(t0, fp0);
8846                tcg_temp_free_i32(fp0);
8847            } else {
8848                TCGv_i32 fp0 = tcg_temp_new_i32();
8849
8850                gen_load_fpr32h(ctx, fp0, rt);
8851                tcg_gen_ext_i32_tl(t0, fp0);
8852                tcg_temp_free_i32(fp0);
8853            }
8854            break;
8855        case 3:
8856            /* XXX: For now we support only a single FPU context. */
8857            gen_helper_1e0i(cfc1, t0, rt);
8858            break;
8859        /* COP2: Not implemented. */
8860        case 4:
8861        case 5:
8862            /* fall through */
8863        default:
8864            goto die;
8865        }
8866    }
8867    trace_mips_translate_tr("mftr", rt, u, sel, h);
8868    gen_store_gpr(t0, rd);
8869    tcg_temp_free(t0);
8870    return;
8871
8872die:
8873    tcg_temp_free(t0);
8874    LOG_DISAS("mftr (reg %d u %d sel %d h %d)\n", rt, u, sel, h);
8875    gen_reserved_instruction(ctx);
8876}
8877
8878static void gen_mttr(CPUMIPSState *env, DisasContext *ctx, int rd, int rt,
8879                     int u, int sel, int h)
8880{
8881    int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
8882    TCGv t0 = tcg_temp_local_new();
8883
8884    gen_load_gpr(t0, rt);
8885    if ((env->CP0_VPEConf0 & (1 << CP0VPEC0_MVP)) == 0 &&
8886        ((env->tcs[other_tc].CP0_TCBind & (0xf << CP0TCBd_CurVPE)) !=
8887         (env->active_tc.CP0_TCBind & (0xf << CP0TCBd_CurVPE)))) {
8888        /* NOP */
8889        ;
8890    } else if ((env->CP0_VPEControl & (0xff << CP0VPECo_TargTC)) >
8891             (env->mvp->CP0_MVPConf0 & (0xff << CP0MVPC0_PTC))) {
8892        /* NOP */
8893        ;
8894    } else if (u == 0) {
8895        switch (rd) {
8896        case 1:
8897            switch (sel) {
8898            case 1:
8899                gen_helper_mttc0_vpecontrol(cpu_env, t0);
8900                break;
8901            case 2:
8902                gen_helper_mttc0_vpeconf0(cpu_env, t0);
8903                break;
8904            default:
8905                goto die;
8906                break;
8907            }
8908            break;
8909        case 2:
8910            switch (sel) {
8911            case 1:
8912                gen_helper_mttc0_tcstatus(cpu_env, t0);
8913                break;
8914            case 2:
8915                gen_helper_mttc0_tcbind(cpu_env, t0);
8916                break;
8917            case 3:
8918                gen_helper_mttc0_tcrestart(cpu_env, t0);
8919                break;
8920            case 4:
8921                gen_helper_mttc0_tchalt(cpu_env, t0);
8922                break;
8923            case 5:
8924                gen_helper_mttc0_tccontext(cpu_env, t0);
8925                break;
8926            case 6:
8927                gen_helper_mttc0_tcschedule(cpu_env, t0);
8928                break;
8929            case 7:
8930                gen_helper_mttc0_tcschefback(cpu_env, t0);
8931                break;
8932            default:
8933                gen_mtc0(ctx, t0, rd, sel);
8934                break;
8935            }
8936            break;
8937        case 10:
8938            switch (sel) {
8939            case 0:
8940                gen_helper_mttc0_entryhi(cpu_env, t0);
8941                break;
8942            default:
8943                gen_mtc0(ctx, t0, rd, sel);
8944                break;
8945            }
8946            break;
8947        case 12:
8948            switch (sel) {
8949            case 0:
8950                gen_helper_mttc0_status(cpu_env, t0);
8951                break;
8952            default:
8953                gen_mtc0(ctx, t0, rd, sel);
8954                break;
8955            }
8956            break;
8957        case 13:
8958            switch (sel) {
8959            case 0:
8960                gen_helper_mttc0_cause(cpu_env, t0);
8961                break;
8962            default:
8963                goto die;
8964                break;
8965            }
8966            break;
8967        case 15:
8968            switch (sel) {
8969            case 1:
8970                gen_helper_mttc0_ebase(cpu_env, t0);
8971                break;
8972            default:
8973                goto die;
8974                break;
8975            }
8976            break;
8977        case 23:
8978            switch (sel) {
8979            case 0:
8980                gen_helper_mttc0_debug(cpu_env, t0);
8981                break;
8982            default:
8983                gen_mtc0(ctx, t0, rd, sel);
8984                break;
8985            }
8986            break;
8987        default:
8988            gen_mtc0(ctx, t0, rd, sel);
8989        }
8990    } else {
8991        switch (sel) {
8992        /* GPR registers. */
8993        case 0:
8994            gen_helper_0e1i(mttgpr, t0, rd);
8995            break;
8996        /* Auxiliary CPU registers */
8997        case 1:
8998            switch (rd) {
8999            case 0:
9000                gen_helper_0e1i(mttlo, t0, 0);
9001                break;
9002            case 1:
9003                gen_helper_0e1i(mtthi, t0, 0);
9004                break;
9005            case 2:
9006                gen_helper_0e1i(mttacx, t0, 0);
9007                break;
9008            case 4:
9009                gen_helper_0e1i(mttlo, t0, 1);
9010                break;
9011            case 5:
9012                gen_helper_0e1i(mtthi, t0, 1);
9013                break;
9014            case 6:
9015                gen_helper_0e1i(mttacx, t0, 1);
9016                break;
9017            case 8:
9018                gen_helper_0e1i(mttlo, t0, 2);
9019                break;
9020            case 9:
9021                gen_helper_0e1i(mtthi, t0, 2);
9022                break;
9023            case 10:
9024                gen_helper_0e1i(mttacx, t0, 2);
9025                break;
9026            case 12:
9027                gen_helper_0e1i(mttlo, t0, 3);
9028                break;
9029            case 13:
9030                gen_helper_0e1i(mtthi, t0, 3);
9031                break;
9032            case 14:
9033                gen_helper_0e1i(mttacx, t0, 3);
9034                break;
9035            case 16:
9036                gen_helper_mttdsp(cpu_env, t0);
9037                break;
9038            default:
9039                goto die;
9040            }
9041            break;
9042        /* Floating point (COP1). */
9043        case 2:
9044            /* XXX: For now we support only a single FPU context. */
9045            if (h == 0) {
9046                TCGv_i32 fp0 = tcg_temp_new_i32();
9047
9048                tcg_gen_trunc_tl_i32(fp0, t0);
9049                gen_store_fpr32(ctx, fp0, rd);
9050                tcg_temp_free_i32(fp0);
9051            } else {
9052                TCGv_i32 fp0 = tcg_temp_new_i32();
9053
9054                tcg_gen_trunc_tl_i32(fp0, t0);
9055                gen_store_fpr32h(ctx, fp0, rd);
9056                tcg_temp_free_i32(fp0);
9057            }
9058            break;
9059        case 3:
9060            /* XXX: For now we support only a single FPU context. */
9061            gen_helper_0e2i(ctc1, t0, tcg_constant_i32(rd), rt);
9062            /* Stop translation as we may have changed hflags */
9063            ctx->base.is_jmp = DISAS_STOP;
9064            break;
9065        /* COP2: Not implemented. */
9066        case 4:
9067        case 5:
9068            /* fall through */
9069        default:
9070            goto die;
9071        }
9072    }
9073    trace_mips_translate_tr("mttr", rd, u, sel, h);
9074    tcg_temp_free(t0);
9075    return;
9076
9077die:
9078    tcg_temp_free(t0);
9079    LOG_DISAS("mttr (reg %d u %d sel %d h %d)\n", rd, u, sel, h);
9080    gen_reserved_instruction(ctx);
9081}
9082
9083static void gen_cp0(CPUMIPSState *env, DisasContext *ctx, uint32_t opc,
9084                    int rt, int rd)
9085{
9086    const char *opn = "ldst";
9087
9088    check_cp0_enabled(ctx);
9089    switch (opc) {
9090    case OPC_MFC0:
9091        if (rt == 0) {
9092            /* Treat as NOP. */
9093            return;
9094        }
9095        gen_mfc0(ctx, cpu_gpr[rt], rd, ctx->opcode & 0x7);
9096        opn = "mfc0";
9097        break;
9098    case OPC_MTC0:
9099        {
9100            TCGv t0 = tcg_temp_new();
9101
9102            gen_load_gpr(t0, rt);
9103            gen_mtc0(ctx, t0, rd, ctx->opcode & 0x7);
9104            tcg_temp_free(t0);
9105        }
9106        opn = "mtc0";
9107        break;
9108#if defined(TARGET_MIPS64)
9109    case OPC_DMFC0:
9110        check_insn(ctx, ISA_MIPS3);
9111        if (rt == 0) {
9112            /* Treat as NOP. */
9113            return;
9114        }
9115        gen_dmfc0(ctx, cpu_gpr[rt], rd, ctx->opcode & 0x7);
9116        opn = "dmfc0";
9117        break;
9118    case OPC_DMTC0:
9119        check_insn(ctx, ISA_MIPS3);
9120        {
9121            TCGv t0 = tcg_temp_new();
9122
9123            gen_load_gpr(t0, rt);
9124            gen_dmtc0(ctx, t0, rd, ctx->opcode & 0x7);
9125            tcg_temp_free(t0);
9126        }
9127        opn = "dmtc0";
9128        break;
9129#endif
9130    case OPC_MFHC0:
9131        check_mvh(ctx);
9132        if (rt == 0) {
9133            /* Treat as NOP. */
9134            return;
9135        }
9136        gen_mfhc0(ctx, cpu_gpr[rt], rd, ctx->opcode & 0x7);
9137        opn = "mfhc0";
9138        break;
9139    case OPC_MTHC0:
9140        check_mvh(ctx);
9141        {
9142            TCGv t0 = tcg_temp_new();
9143            gen_load_gpr(t0, rt);
9144            gen_mthc0(ctx, t0, rd, ctx->opcode & 0x7);
9145            tcg_temp_free(t0);
9146        }
9147        opn = "mthc0";
9148        break;
9149    case OPC_MFTR:
9150        check_cp0_enabled(ctx);
9151        if (rd == 0) {
9152            /* Treat as NOP. */
9153            return;
9154        }
9155        gen_mftr(env, ctx, rt, rd, (ctx->opcode >> 5) & 1,
9156                 ctx->opcode & 0x7, (ctx->opcode >> 4) & 1);
9157        opn = "mftr";
9158        break;
9159    case OPC_MTTR:
9160        check_cp0_enabled(ctx);
9161        gen_mttr(env, ctx, rd, rt, (ctx->opcode >> 5) & 1,
9162                 ctx->opcode & 0x7, (ctx->opcode >> 4) & 1);
9163        opn = "mttr";
9164        break;
9165    case OPC_TLBWI:
9166        opn = "tlbwi";
9167        if (!env->tlb->helper_tlbwi) {
9168            goto die;
9169        }
9170        gen_helper_tlbwi(cpu_env);
9171        break;
9172    case OPC_TLBINV:
9173        opn = "tlbinv";
9174        if (ctx->ie >= 2) {
9175            if (!env->tlb->helper_tlbinv) {
9176                goto die;
9177            }
9178            gen_helper_tlbinv(cpu_env);
9179        } /* treat as nop if TLBINV not supported */
9180        break;
9181    case OPC_TLBINVF:
9182        opn = "tlbinvf";
9183        if (ctx->ie >= 2) {
9184            if (!env->tlb->helper_tlbinvf) {
9185                goto die;
9186            }
9187            gen_helper_tlbinvf(cpu_env);
9188        } /* treat as nop if TLBINV not supported */
9189        break;
9190    case OPC_TLBWR:
9191        opn = "tlbwr";
9192        if (!env->tlb->helper_tlbwr) {
9193            goto die;
9194        }
9195        gen_helper_tlbwr(cpu_env);
9196        break;
9197    case OPC_TLBP:
9198        opn = "tlbp";
9199        if (!env->tlb->helper_tlbp) {
9200            goto die;
9201        }
9202        gen_helper_tlbp(cpu_env);
9203        break;
9204    case OPC_TLBR:
9205        opn = "tlbr";
9206        if (!env->tlb->helper_tlbr) {
9207            goto die;
9208        }
9209        gen_helper_tlbr(cpu_env);
9210        break;
9211    case OPC_ERET: /* OPC_ERETNC */
9212        if ((ctx->insn_flags & ISA_MIPS_R6) &&
9213            (ctx->hflags & MIPS_HFLAG_BMASK)) {
9214            goto die;
9215        } else {
9216            int bit_shift = (ctx->hflags & MIPS_HFLAG_M16) ? 16 : 6;
9217            if (ctx->opcode & (1 << bit_shift)) {
9218                /* OPC_ERETNC */
9219                opn = "eretnc";
9220                check_insn(ctx, ISA_MIPS_R5);
9221                gen_helper_eretnc(cpu_env);
9222            } else {
9223                /* OPC_ERET */
9224                opn = "eret";
9225                check_insn(ctx, ISA_MIPS2);
9226                gen_helper_eret(cpu_env);
9227            }
9228            ctx->base.is_jmp = DISAS_EXIT;
9229        }
9230        break;
9231    case OPC_DERET:
9232        opn = "deret";
9233        check_insn(ctx, ISA_MIPS_R1);
9234        if ((ctx->insn_flags & ISA_MIPS_R6) &&
9235            (ctx->hflags & MIPS_HFLAG_BMASK)) {
9236            goto die;
9237        }
9238        if (!(ctx->hflags & MIPS_HFLAG_DM)) {
9239            MIPS_INVAL(opn);
9240            gen_reserved_instruction(ctx);
9241        } else {
9242            gen_helper_deret(cpu_env);
9243            ctx->base.is_jmp = DISAS_EXIT;
9244        }
9245        break;
9246    case OPC_WAIT:
9247        opn = "wait";
9248        check_insn(ctx, ISA_MIPS3 | ISA_MIPS_R1);
9249        if ((ctx->insn_flags & ISA_MIPS_R6) &&
9250            (ctx->hflags & MIPS_HFLAG_BMASK)) {
9251            goto die;
9252        }
9253        /* If we get an exception, we want to restart at next instruction */
9254        ctx->base.pc_next += 4;
9255        save_cpu_state(ctx, 1);
9256        ctx->base.pc_next -= 4;
9257        gen_helper_wait(cpu_env);
9258        ctx->base.is_jmp = DISAS_NORETURN;
9259        break;
9260    default:
9261 die:
9262        MIPS_INVAL(opn);
9263        gen_reserved_instruction(ctx);
9264        return;
9265    }
9266    (void)opn; /* avoid a compiler warning */
9267}
9268#endif /* !CONFIG_USER_ONLY */
9269
9270/* CP1 Branches (before delay slot) */
9271static void gen_compute_branch1(DisasContext *ctx, uint32_t op,
9272                                int32_t cc, int32_t offset)
9273{
9274    target_ulong btarget;
9275    TCGv_i32 t0 = tcg_temp_new_i32();
9276
9277    if ((ctx->insn_flags & ISA_MIPS_R6) && (ctx->hflags & MIPS_HFLAG_BMASK)) {
9278        gen_reserved_instruction(ctx);
9279        goto out;
9280    }
9281
9282    if (cc != 0) {
9283        check_insn(ctx, ISA_MIPS4 | ISA_MIPS_R1);
9284    }
9285
9286    btarget = ctx->base.pc_next + 4 + offset;
9287
9288    switch (op) {
9289    case OPC_BC1F:
9290        tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
9291        tcg_gen_not_i32(t0, t0);
9292        tcg_gen_andi_i32(t0, t0, 1);
9293        tcg_gen_extu_i32_tl(bcond, t0);
9294        goto not_likely;
9295    case OPC_BC1FL:
9296        tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
9297        tcg_gen_not_i32(t0, t0);
9298        tcg_gen_andi_i32(t0, t0, 1);
9299        tcg_gen_extu_i32_tl(bcond, t0);
9300        goto likely;
9301    case OPC_BC1T:
9302        tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
9303        tcg_gen_andi_i32(t0, t0, 1);
9304        tcg_gen_extu_i32_tl(bcond, t0);
9305        goto not_likely;
9306    case OPC_BC1TL:
9307        tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
9308        tcg_gen_andi_i32(t0, t0, 1);
9309        tcg_gen_extu_i32_tl(bcond, t0);
9310    likely:
9311        ctx->hflags |= MIPS_HFLAG_BL;
9312        break;
9313    case OPC_BC1FANY2:
9314        {
9315            TCGv_i32 t1 = tcg_temp_new_i32();
9316            tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
9317            tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc + 1));
9318            tcg_gen_nand_i32(t0, t0, t1);
9319            tcg_temp_free_i32(t1);
9320            tcg_gen_andi_i32(t0, t0, 1);
9321            tcg_gen_extu_i32_tl(bcond, t0);
9322        }
9323        goto not_likely;
9324    case OPC_BC1TANY2:
9325        {
9326            TCGv_i32 t1 = tcg_temp_new_i32();
9327            tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
9328            tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc + 1));
9329            tcg_gen_or_i32(t0, t0, t1);
9330            tcg_temp_free_i32(t1);
9331            tcg_gen_andi_i32(t0, t0, 1);
9332            tcg_gen_extu_i32_tl(bcond, t0);
9333        }
9334        goto not_likely;
9335    case OPC_BC1FANY4:
9336        {
9337            TCGv_i32 t1 = tcg_temp_new_i32();
9338            tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
9339            tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc + 1));
9340            tcg_gen_and_i32(t0, t0, t1);
9341            tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc + 2));
9342            tcg_gen_and_i32(t0, t0, t1);
9343            tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc + 3));
9344            tcg_gen_nand_i32(t0, t0, t1);
9345            tcg_temp_free_i32(t1);
9346            tcg_gen_andi_i32(t0, t0, 1);
9347            tcg_gen_extu_i32_tl(bcond, t0);
9348        }
9349        goto not_likely;
9350    case OPC_BC1TANY4:
9351        {
9352            TCGv_i32 t1 = tcg_temp_new_i32();
9353            tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
9354            tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc + 1));
9355            tcg_gen_or_i32(t0, t0, t1);
9356            tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc + 2));
9357            tcg_gen_or_i32(t0, t0, t1);
9358            tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc + 3));
9359            tcg_gen_or_i32(t0, t0, t1);
9360            tcg_temp_free_i32(t1);
9361            tcg_gen_andi_i32(t0, t0, 1);
9362            tcg_gen_extu_i32_tl(bcond, t0);
9363        }
9364    not_likely:
9365        ctx->hflags |= MIPS_HFLAG_BC;
9366        break;
9367    default:
9368        MIPS_INVAL("cp1 cond branch");
9369        gen_reserved_instruction(ctx);
9370        goto out;
9371    }
9372    ctx->btarget = btarget;
9373    ctx->hflags |= MIPS_HFLAG_BDS32;
9374 out:
9375    tcg_temp_free_i32(t0);
9376}
9377
9378/* R6 CP1 Branches */
9379static void gen_compute_branch1_r6(DisasContext *ctx, uint32_t op,
9380                                   int32_t ft, int32_t offset,
9381                                   int delayslot_size)
9382{
9383    target_ulong btarget;
9384    TCGv_i64 t0 = tcg_temp_new_i64();
9385
9386    if (ctx->hflags & MIPS_HFLAG_BMASK) {
9387#ifdef MIPS_DEBUG_DISAS
9388        LOG_DISAS("Branch in delay / forbidden slot at PC 0x" TARGET_FMT_lx
9389                  "\n", ctx->base.pc_next);
9390#endif
9391        gen_reserved_instruction(ctx);
9392        goto out;
9393    }
9394
9395    gen_load_fpr64(ctx, t0, ft);
9396    tcg_gen_andi_i64(t0, t0, 1);
9397
9398    btarget = addr_add(ctx, ctx->base.pc_next + 4, offset);
9399
9400    switch (op) {
9401    case OPC_BC1EQZ:
9402        tcg_gen_xori_i64(t0, t0, 1);
9403        ctx->hflags |= MIPS_HFLAG_BC;
9404        break;
9405    case OPC_BC1NEZ:
9406        /* t0 already set */
9407        ctx->hflags |= MIPS_HFLAG_BC;
9408        break;
9409    default:
9410        MIPS_INVAL("cp1 cond branch");
9411        gen_reserved_instruction(ctx);
9412        goto out;
9413    }
9414
9415    tcg_gen_trunc_i64_tl(bcond, t0);
9416
9417    ctx->btarget = btarget;
9418
9419    switch (delayslot_size) {
9420    case 2:
9421        ctx->hflags |= MIPS_HFLAG_BDS16;
9422        break;
9423    case 4:
9424        ctx->hflags |= MIPS_HFLAG_BDS32;
9425        break;
9426    }
9427
9428out:
9429    tcg_temp_free_i64(t0);
9430}
9431
9432/* Coprocessor 1 (FPU) */
9433
9434#define FOP(func, fmt) (((fmt) << 21) | (func))
9435
9436enum fopcode {
9437    OPC_ADD_S = FOP(0, FMT_S),
9438    OPC_SUB_S = FOP(1, FMT_S),
9439    OPC_MUL_S = FOP(2, FMT_S),
9440    OPC_DIV_S = FOP(3, FMT_S),
9441    OPC_SQRT_S = FOP(4, FMT_S),
9442    OPC_ABS_S = FOP(5, FMT_S),
9443    OPC_MOV_S = FOP(6, FMT_S),
9444    OPC_NEG_S = FOP(7, FMT_S),
9445    OPC_ROUND_L_S = FOP(8, FMT_S),
9446    OPC_TRUNC_L_S = FOP(9, FMT_S),
9447    OPC_CEIL_L_S = FOP(10, FMT_S),
9448    OPC_FLOOR_L_S = FOP(11, FMT_S),
9449    OPC_ROUND_W_S = FOP(12, FMT_S),
9450    OPC_TRUNC_W_S = FOP(13, FMT_S),
9451    OPC_CEIL_W_S = FOP(14, FMT_S),
9452    OPC_FLOOR_W_S = FOP(15, FMT_S),
9453    OPC_SEL_S = FOP(16, FMT_S),
9454    OPC_MOVCF_S = FOP(17, FMT_S),
9455    OPC_MOVZ_S = FOP(18, FMT_S),
9456    OPC_MOVN_S = FOP(19, FMT_S),
9457    OPC_SELEQZ_S = FOP(20, FMT_S),
9458    OPC_RECIP_S = FOP(21, FMT_S),
9459    OPC_RSQRT_S = FOP(22, FMT_S),
9460    OPC_SELNEZ_S = FOP(23, FMT_S),
9461    OPC_MADDF_S = FOP(24, FMT_S),
9462    OPC_MSUBF_S = FOP(25, FMT_S),
9463    OPC_RINT_S = FOP(26, FMT_S),
9464    OPC_CLASS_S = FOP(27, FMT_S),
9465    OPC_MIN_S = FOP(28, FMT_S),
9466    OPC_RECIP2_S = FOP(28, FMT_S),
9467    OPC_MINA_S = FOP(29, FMT_S),
9468    OPC_RECIP1_S = FOP(29, FMT_S),
9469    OPC_MAX_S = FOP(30, FMT_S),
9470    OPC_RSQRT1_S = FOP(30, FMT_S),
9471    OPC_MAXA_S = FOP(31, FMT_S),
9472    OPC_RSQRT2_S = FOP(31, FMT_S),
9473    OPC_CVT_D_S = FOP(33, FMT_S),
9474    OPC_CVT_W_S = FOP(36, FMT_S),
9475    OPC_CVT_L_S = FOP(37, FMT_S),
9476    OPC_CVT_PS_S = FOP(38, FMT_S),
9477    OPC_CMP_F_S = FOP(48, FMT_S),
9478    OPC_CMP_UN_S = FOP(49, FMT_S),
9479    OPC_CMP_EQ_S = FOP(50, FMT_S),
9480    OPC_CMP_UEQ_S = FOP(51, FMT_S),
9481    OPC_CMP_OLT_S = FOP(52, FMT_S),
9482    OPC_CMP_ULT_S = FOP(53, FMT_S),
9483    OPC_CMP_OLE_S = FOP(54, FMT_S),
9484    OPC_CMP_ULE_S = FOP(55, FMT_S),
9485    OPC_CMP_SF_S = FOP(56, FMT_S),
9486    OPC_CMP_NGLE_S = FOP(57, FMT_S),
9487    OPC_CMP_SEQ_S = FOP(58, FMT_S),
9488    OPC_CMP_NGL_S = FOP(59, FMT_S),
9489    OPC_CMP_LT_S = FOP(60, FMT_S),
9490    OPC_CMP_NGE_S = FOP(61, FMT_S),
9491    OPC_CMP_LE_S = FOP(62, FMT_S),
9492    OPC_CMP_NGT_S = FOP(63, FMT_S),
9493
9494    OPC_ADD_D = FOP(0, FMT_D),
9495    OPC_SUB_D = FOP(1, FMT_D),
9496    OPC_MUL_D = FOP(2, FMT_D),
9497    OPC_DIV_D = FOP(3, FMT_D),
9498    OPC_SQRT_D = FOP(4, FMT_D),
9499    OPC_ABS_D = FOP(5, FMT_D),
9500    OPC_MOV_D = FOP(6, FMT_D),
9501    OPC_NEG_D = FOP(7, FMT_D),
9502    OPC_ROUND_L_D = FOP(8, FMT_D),
9503    OPC_TRUNC_L_D = FOP(9, FMT_D),
9504    OPC_CEIL_L_D = FOP(10, FMT_D),
9505    OPC_FLOOR_L_D = FOP(11, FMT_D),
9506    OPC_ROUND_W_D = FOP(12, FMT_D),
9507    OPC_TRUNC_W_D = FOP(13, FMT_D),
9508    OPC_CEIL_W_D = FOP(14, FMT_D),
9509    OPC_FLOOR_W_D = FOP(15, FMT_D),
9510    OPC_SEL_D = FOP(16, FMT_D),
9511    OPC_MOVCF_D = FOP(17, FMT_D),
9512    OPC_MOVZ_D = FOP(18, FMT_D),
9513    OPC_MOVN_D = FOP(19, FMT_D),
9514    OPC_SELEQZ_D = FOP(20, FMT_D),
9515    OPC_RECIP_D = FOP(21, FMT_D),
9516    OPC_RSQRT_D = FOP(22, FMT_D),
9517    OPC_SELNEZ_D = FOP(23, FMT_D),
9518    OPC_MADDF_D = FOP(24, FMT_D),
9519    OPC_MSUBF_D = FOP(25, FMT_D),
9520    OPC_RINT_D = FOP(26, FMT_D),
9521    OPC_CLASS_D = FOP(27, FMT_D),
9522    OPC_MIN_D = FOP(28, FMT_D),
9523    OPC_RECIP2_D = FOP(28, FMT_D),
9524    OPC_MINA_D = FOP(29, FMT_D),
9525    OPC_RECIP1_D = FOP(29, FMT_D),
9526    OPC_MAX_D = FOP(30, FMT_D),
9527    OPC_RSQRT1_D = FOP(30, FMT_D),
9528    OPC_MAXA_D = FOP(31, FMT_D),
9529    OPC_RSQRT2_D = FOP(31, FMT_D),
9530    OPC_CVT_S_D = FOP(32, FMT_D),
9531    OPC_CVT_W_D = FOP(36, FMT_D),
9532    OPC_CVT_L_D = FOP(37, FMT_D),
9533    OPC_CMP_F_D = FOP(48, FMT_D),
9534    OPC_CMP_UN_D = FOP(49, FMT_D),
9535    OPC_CMP_EQ_D = FOP(50, FMT_D),
9536    OPC_CMP_UEQ_D = FOP(51, FMT_D),
9537    OPC_CMP_OLT_D = FOP(52, FMT_D),
9538    OPC_CMP_ULT_D = FOP(53, FMT_D),
9539    OPC_CMP_OLE_D = FOP(54, FMT_D),
9540    OPC_CMP_ULE_D = FOP(55, FMT_D),
9541    OPC_CMP_SF_D = FOP(56, FMT_D),
9542    OPC_CMP_NGLE_D = FOP(57, FMT_D),
9543    OPC_CMP_SEQ_D = FOP(58, FMT_D),
9544    OPC_CMP_NGL_D = FOP(59, FMT_D),
9545    OPC_CMP_LT_D = FOP(60, FMT_D),
9546    OPC_CMP_NGE_D = FOP(61, FMT_D),
9547    OPC_CMP_LE_D = FOP(62, FMT_D),
9548    OPC_CMP_NGT_D = FOP(63, FMT_D),
9549
9550    OPC_CVT_S_W = FOP(32, FMT_W),
9551    OPC_CVT_D_W = FOP(33, FMT_W),
9552    OPC_CVT_S_L = FOP(32, FMT_L),
9553    OPC_CVT_D_L = FOP(33, FMT_L),
9554    OPC_CVT_PS_PW = FOP(38, FMT_W),
9555
9556    OPC_ADD_PS = FOP(0, FMT_PS),
9557    OPC_SUB_PS = FOP(1, FMT_PS),
9558    OPC_MUL_PS = FOP(2, FMT_PS),
9559    OPC_DIV_PS = FOP(3, FMT_PS),
9560    OPC_ABS_PS = FOP(5, FMT_PS),
9561    OPC_MOV_PS = FOP(6, FMT_PS),
9562    OPC_NEG_PS = FOP(7, FMT_PS),
9563    OPC_MOVCF_PS = FOP(17, FMT_PS),
9564    OPC_MOVZ_PS = FOP(18, FMT_PS),
9565    OPC_MOVN_PS = FOP(19, FMT_PS),
9566    OPC_ADDR_PS = FOP(24, FMT_PS),
9567    OPC_MULR_PS = FOP(26, FMT_PS),
9568    OPC_RECIP2_PS = FOP(28, FMT_PS),
9569    OPC_RECIP1_PS = FOP(29, FMT_PS),
9570    OPC_RSQRT1_PS = FOP(30, FMT_PS),
9571    OPC_RSQRT2_PS = FOP(31, FMT_PS),
9572
9573    OPC_CVT_S_PU = FOP(32, FMT_PS),
9574    OPC_CVT_PW_PS = FOP(36, FMT_PS),
9575    OPC_CVT_S_PL = FOP(40, FMT_PS),
9576    OPC_PLL_PS = FOP(44, FMT_PS),
9577    OPC_PLU_PS = FOP(45, FMT_PS),
9578    OPC_PUL_PS = FOP(46, FMT_PS),
9579    OPC_PUU_PS = FOP(47, FMT_PS),
9580    OPC_CMP_F_PS = FOP(48, FMT_PS),
9581    OPC_CMP_UN_PS = FOP(49, FMT_PS),
9582    OPC_CMP_EQ_PS = FOP(50, FMT_PS),
9583    OPC_CMP_UEQ_PS = FOP(51, FMT_PS),
9584    OPC_CMP_OLT_PS = FOP(52, FMT_PS),
9585    OPC_CMP_ULT_PS = FOP(53, FMT_PS),
9586    OPC_CMP_OLE_PS = FOP(54, FMT_PS),
9587    OPC_CMP_ULE_PS = FOP(55, FMT_PS),
9588    OPC_CMP_SF_PS = FOP(56, FMT_PS),
9589    OPC_CMP_NGLE_PS = FOP(57, FMT_PS),
9590    OPC_CMP_SEQ_PS = FOP(58, FMT_PS),
9591    OPC_CMP_NGL_PS = FOP(59, FMT_PS),
9592    OPC_CMP_LT_PS = FOP(60, FMT_PS),
9593    OPC_CMP_NGE_PS = FOP(61, FMT_PS),
9594    OPC_CMP_LE_PS = FOP(62, FMT_PS),
9595    OPC_CMP_NGT_PS = FOP(63, FMT_PS),
9596};
9597
9598enum r6_f_cmp_op {
9599    R6_OPC_CMP_AF_S   = FOP(0, FMT_W),
9600    R6_OPC_CMP_UN_S   = FOP(1, FMT_W),
9601    R6_OPC_CMP_EQ_S   = FOP(2, FMT_W),
9602    R6_OPC_CMP_UEQ_S  = FOP(3, FMT_W),
9603    R6_OPC_CMP_LT_S   = FOP(4, FMT_W),
9604    R6_OPC_CMP_ULT_S  = FOP(5, FMT_W),
9605    R6_OPC_CMP_LE_S   = FOP(6, FMT_W),
9606    R6_OPC_CMP_ULE_S  = FOP(7, FMT_W),
9607    R6_OPC_CMP_SAF_S  = FOP(8, FMT_W),
9608    R6_OPC_CMP_SUN_S  = FOP(9, FMT_W),
9609    R6_OPC_CMP_SEQ_S  = FOP(10, FMT_W),
9610    R6_OPC_CMP_SEUQ_S = FOP(11, FMT_W),
9611    R6_OPC_CMP_SLT_S  = FOP(12, FMT_W),
9612    R6_OPC_CMP_SULT_S = FOP(13, FMT_W),
9613    R6_OPC_CMP_SLE_S  = FOP(14, FMT_W),
9614    R6_OPC_CMP_SULE_S = FOP(15, FMT_W),
9615    R6_OPC_CMP_OR_S   = FOP(17, FMT_W),
9616    R6_OPC_CMP_UNE_S  = FOP(18, FMT_W),
9617    R6_OPC_CMP_NE_S   = FOP(19, FMT_W),
9618    R6_OPC_CMP_SOR_S  = FOP(25, FMT_W),
9619    R6_OPC_CMP_SUNE_S = FOP(26, FMT_W),
9620    R6_OPC_CMP_SNE_S  = FOP(27, FMT_W),
9621
9622    R6_OPC_CMP_AF_D   = FOP(0, FMT_L),
9623    R6_OPC_CMP_UN_D   = FOP(1, FMT_L),
9624    R6_OPC_CMP_EQ_D   = FOP(2, FMT_L),
9625    R6_OPC_CMP_UEQ_D  = FOP(3, FMT_L),
9626    R6_OPC_CMP_LT_D   = FOP(4, FMT_L),
9627    R6_OPC_CMP_ULT_D  = FOP(5, FMT_L),
9628    R6_OPC_CMP_LE_D   = FOP(6, FMT_L),
9629    R6_OPC_CMP_ULE_D  = FOP(7, FMT_L),
9630    R6_OPC_CMP_SAF_D  = FOP(8, FMT_L),
9631    R6_OPC_CMP_SUN_D  = FOP(9, FMT_L),
9632    R6_OPC_CMP_SEQ_D  = FOP(10, FMT_L),
9633    R6_OPC_CMP_SEUQ_D = FOP(11, FMT_L),
9634    R6_OPC_CMP_SLT_D  = FOP(12, FMT_L),
9635    R6_OPC_CMP_SULT_D = FOP(13, FMT_L),
9636    R6_OPC_CMP_SLE_D  = FOP(14, FMT_L),
9637    R6_OPC_CMP_SULE_D = FOP(15, FMT_L),
9638    R6_OPC_CMP_OR_D   = FOP(17, FMT_L),
9639    R6_OPC_CMP_UNE_D  = FOP(18, FMT_L),
9640    R6_OPC_CMP_NE_D   = FOP(19, FMT_L),
9641    R6_OPC_CMP_SOR_D  = FOP(25, FMT_L),
9642    R6_OPC_CMP_SUNE_D = FOP(26, FMT_L),
9643    R6_OPC_CMP_SNE_D  = FOP(27, FMT_L),
9644};
9645
9646static void gen_cp1(DisasContext *ctx, uint32_t opc, int rt, int fs)
9647{
9648    TCGv t0 = tcg_temp_new();
9649
9650    switch (opc) {
9651    case OPC_MFC1:
9652        {
9653            TCGv_i32 fp0 = tcg_temp_new_i32();
9654
9655            gen_load_fpr32(ctx, fp0, fs);
9656            tcg_gen_ext_i32_tl(t0, fp0);
9657            tcg_temp_free_i32(fp0);
9658        }
9659        gen_store_gpr(t0, rt);
9660        break;
9661    case OPC_MTC1:
9662        gen_load_gpr(t0, rt);
9663        {
9664            TCGv_i32 fp0 = tcg_temp_new_i32();
9665
9666            tcg_gen_trunc_tl_i32(fp0, t0);
9667            gen_store_fpr32(ctx, fp0, fs);
9668            tcg_temp_free_i32(fp0);
9669        }
9670        break;
9671    case OPC_CFC1:
9672        gen_helper_1e0i(cfc1, t0, fs);
9673        gen_store_gpr(t0, rt);
9674        break;
9675    case OPC_CTC1:
9676        gen_load_gpr(t0, rt);
9677        save_cpu_state(ctx, 0);
9678        gen_helper_0e2i(ctc1, t0, tcg_constant_i32(fs), rt);
9679        /* Stop translation as we may have changed hflags */
9680        ctx->base.is_jmp = DISAS_STOP;
9681        break;
9682#if defined(TARGET_MIPS64)
9683    case OPC_DMFC1:
9684        gen_load_fpr64(ctx, t0, fs);
9685        gen_store_gpr(t0, rt);
9686        break;
9687    case OPC_DMTC1:
9688        gen_load_gpr(t0, rt);
9689        gen_store_fpr64(ctx, t0, fs);
9690        break;
9691#endif
9692    case OPC_MFHC1:
9693        {
9694            TCGv_i32 fp0 = tcg_temp_new_i32();
9695
9696            gen_load_fpr32h(ctx, fp0, fs);
9697            tcg_gen_ext_i32_tl(t0, fp0);
9698            tcg_temp_free_i32(fp0);
9699        }
9700        gen_store_gpr(t0, rt);
9701        break;
9702    case OPC_MTHC1:
9703        gen_load_gpr(t0, rt);
9704        {
9705            TCGv_i32 fp0 = tcg_temp_new_i32();
9706
9707            tcg_gen_trunc_tl_i32(fp0, t0);
9708            gen_store_fpr32h(ctx, fp0, fs);
9709            tcg_temp_free_i32(fp0);
9710        }
9711        break;
9712    default:
9713        MIPS_INVAL("cp1 move");
9714        gen_reserved_instruction(ctx);
9715        goto out;
9716    }
9717
9718 out:
9719    tcg_temp_free(t0);
9720}
9721
9722static void gen_movci(DisasContext *ctx, int rd, int rs, int cc, int tf)
9723{
9724    TCGLabel *l1;
9725    TCGCond cond;
9726    TCGv_i32 t0;
9727
9728    if (rd == 0) {
9729        /* Treat as NOP. */
9730        return;
9731    }
9732
9733    if (tf) {
9734        cond = TCG_COND_EQ;
9735    } else {
9736        cond = TCG_COND_NE;
9737    }
9738
9739    l1 = gen_new_label();
9740    t0 = tcg_temp_new_i32();
9741    tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
9742    tcg_gen_brcondi_i32(cond, t0, 0, l1);
9743    tcg_temp_free_i32(t0);
9744    gen_load_gpr(cpu_gpr[rd], rs);
9745    gen_set_label(l1);
9746}
9747
9748static inline void gen_movcf_s(DisasContext *ctx, int fs, int fd, int cc,
9749                               int tf)
9750{
9751    int cond;
9752    TCGv_i32 t0 = tcg_temp_new_i32();
9753    TCGLabel *l1 = gen_new_label();
9754
9755    if (tf) {
9756        cond = TCG_COND_EQ;
9757    } else {
9758        cond = TCG_COND_NE;
9759    }
9760
9761    tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
9762    tcg_gen_brcondi_i32(cond, t0, 0, l1);
9763    gen_load_fpr32(ctx, t0, fs);
9764    gen_store_fpr32(ctx, t0, fd);
9765    gen_set_label(l1);
9766    tcg_temp_free_i32(t0);
9767}
9768
9769static inline void gen_movcf_d(DisasContext *ctx, int fs, int fd, int cc,
9770                               int tf)
9771{
9772    int cond;
9773    TCGv_i32 t0 = tcg_temp_new_i32();
9774    TCGv_i64 fp0;
9775    TCGLabel *l1 = gen_new_label();
9776
9777    if (tf) {
9778        cond = TCG_COND_EQ;
9779    } else {
9780        cond = TCG_COND_NE;
9781    }
9782
9783    tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
9784    tcg_gen_brcondi_i32(cond, t0, 0, l1);
9785    tcg_temp_free_i32(t0);
9786    fp0 = tcg_temp_new_i64();
9787    gen_load_fpr64(ctx, fp0, fs);
9788    gen_store_fpr64(ctx, fp0, fd);
9789    tcg_temp_free_i64(fp0);
9790    gen_set_label(l1);
9791}
9792
9793static inline void gen_movcf_ps(DisasContext *ctx, int fs, int fd,
9794                                int cc, int tf)
9795{
9796    int cond;
9797    TCGv_i32 t0 = tcg_temp_new_i32();
9798    TCGLabel *l1 = gen_new_label();
9799    TCGLabel *l2 = gen_new_label();
9800
9801    if (tf) {
9802        cond = TCG_COND_EQ;
9803    } else {
9804        cond = TCG_COND_NE;
9805    }
9806
9807    tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
9808    tcg_gen_brcondi_i32(cond, t0, 0, l1);
9809    gen_load_fpr32(ctx, t0, fs);
9810    gen_store_fpr32(ctx, t0, fd);
9811    gen_set_label(l1);
9812
9813    tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc + 1));
9814    tcg_gen_brcondi_i32(cond, t0, 0, l2);
9815    gen_load_fpr32h(ctx, t0, fs);
9816    gen_store_fpr32h(ctx, t0, fd);
9817    tcg_temp_free_i32(t0);
9818    gen_set_label(l2);
9819}
9820
9821static void gen_sel_s(DisasContext *ctx, enum fopcode op1, int fd, int ft,
9822                      int fs)
9823{
9824    TCGv_i32 t1 = tcg_const_i32(0);
9825    TCGv_i32 fp0 = tcg_temp_new_i32();
9826    TCGv_i32 fp1 = tcg_temp_new_i32();
9827    TCGv_i32 fp2 = tcg_temp_new_i32();
9828    gen_load_fpr32(ctx, fp0, fd);
9829    gen_load_fpr32(ctx, fp1, ft);
9830    gen_load_fpr32(ctx, fp2, fs);
9831
9832    switch (op1) {
9833    case OPC_SEL_S:
9834        tcg_gen_andi_i32(fp0, fp0, 1);
9835        tcg_gen_movcond_i32(TCG_COND_NE, fp0, fp0, t1, fp1, fp2);
9836        break;
9837    case OPC_SELEQZ_S:
9838        tcg_gen_andi_i32(fp1, fp1, 1);
9839        tcg_gen_movcond_i32(TCG_COND_EQ, fp0, fp1, t1, fp2, t1);
9840        break;
9841    case OPC_SELNEZ_S:
9842        tcg_gen_andi_i32(fp1, fp1, 1);
9843        tcg_gen_movcond_i32(TCG_COND_NE, fp0, fp1, t1, fp2, t1);
9844        break;
9845    default:
9846        MIPS_INVAL("gen_sel_s");
9847        gen_reserved_instruction(ctx);
9848        break;
9849    }
9850
9851    gen_store_fpr32(ctx, fp0, fd);
9852    tcg_temp_free_i32(fp2);
9853    tcg_temp_free_i32(fp1);
9854    tcg_temp_free_i32(fp0);
9855    tcg_temp_free_i32(t1);
9856}
9857
9858static void gen_sel_d(DisasContext *ctx, enum fopcode op1, int fd, int ft,
9859                      int fs)
9860{
9861    TCGv_i64 t1 = tcg_const_i64(0);
9862    TCGv_i64 fp0 = tcg_temp_new_i64();
9863    TCGv_i64 fp1 = tcg_temp_new_i64();
9864    TCGv_i64 fp2 = tcg_temp_new_i64();
9865    gen_load_fpr64(ctx, fp0, fd);
9866    gen_load_fpr64(ctx, fp1, ft);
9867    gen_load_fpr64(ctx, fp2, fs);
9868
9869    switch (op1) {
9870    case OPC_SEL_D:
9871        tcg_gen_andi_i64(fp0, fp0, 1);
9872        tcg_gen_movcond_i64(TCG_COND_NE, fp0, fp0, t1, fp1, fp2);
9873        break;
9874    case OPC_SELEQZ_D:
9875        tcg_gen_andi_i64(fp1, fp1, 1);
9876        tcg_gen_movcond_i64(TCG_COND_EQ, fp0, fp1, t1, fp2, t1);
9877        break;
9878    case OPC_SELNEZ_D:
9879        tcg_gen_andi_i64(fp1, fp1, 1);
9880        tcg_gen_movcond_i64(TCG_COND_NE, fp0, fp1, t1, fp2, t1);
9881        break;
9882    default:
9883        MIPS_INVAL("gen_sel_d");
9884        gen_reserved_instruction(ctx);
9885        break;
9886    }
9887
9888    gen_store_fpr64(ctx, fp0, fd);
9889    tcg_temp_free_i64(fp2);
9890    tcg_temp_free_i64(fp1);
9891    tcg_temp_free_i64(fp0);
9892    tcg_temp_free_i64(t1);
9893}
9894
9895static void gen_farith(DisasContext *ctx, enum fopcode op1,
9896                       int ft, int fs, int fd, int cc)
9897{
9898    uint32_t func = ctx->opcode & 0x3f;
9899    switch (op1) {
9900    case OPC_ADD_S:
9901        {
9902            TCGv_i32 fp0 = tcg_temp_new_i32();
9903            TCGv_i32 fp1 = tcg_temp_new_i32();
9904
9905            gen_load_fpr32(ctx, fp0, fs);
9906            gen_load_fpr32(ctx, fp1, ft);
9907            gen_helper_float_add_s(fp0, cpu_env, fp0, fp1);
9908            tcg_temp_free_i32(fp1);
9909            gen_store_fpr32(ctx, fp0, fd);
9910            tcg_temp_free_i32(fp0);
9911        }
9912        break;
9913    case OPC_SUB_S:
9914        {
9915            TCGv_i32 fp0 = tcg_temp_new_i32();
9916            TCGv_i32 fp1 = tcg_temp_new_i32();
9917
9918            gen_load_fpr32(ctx, fp0, fs);
9919            gen_load_fpr32(ctx, fp1, ft);
9920            gen_helper_float_sub_s(fp0, cpu_env, fp0, fp1);
9921            tcg_temp_free_i32(fp1);
9922            gen_store_fpr32(ctx, fp0, fd);
9923            tcg_temp_free_i32(fp0);
9924        }
9925        break;
9926    case OPC_MUL_S:
9927        {
9928            TCGv_i32 fp0 = tcg_temp_new_i32();
9929            TCGv_i32 fp1 = tcg_temp_new_i32();
9930
9931            gen_load_fpr32(ctx, fp0, fs);
9932            gen_load_fpr32(ctx, fp1, ft);
9933            gen_helper_float_mul_s(fp0, cpu_env, fp0, fp1);
9934            tcg_temp_free_i32(fp1);
9935            gen_store_fpr32(ctx, fp0, fd);
9936            tcg_temp_free_i32(fp0);
9937        }
9938        break;
9939    case OPC_DIV_S:
9940        {
9941            TCGv_i32 fp0 = tcg_temp_new_i32();
9942            TCGv_i32 fp1 = tcg_temp_new_i32();
9943
9944            gen_load_fpr32(ctx, fp0, fs);
9945            gen_load_fpr32(ctx, fp1, ft);
9946            gen_helper_float_div_s(fp0, cpu_env, fp0, fp1);
9947            tcg_temp_free_i32(fp1);
9948            gen_store_fpr32(ctx, fp0, fd);
9949            tcg_temp_free_i32(fp0);
9950        }
9951        break;
9952    case OPC_SQRT_S:
9953        {
9954            TCGv_i32 fp0 = tcg_temp_new_i32();
9955
9956            gen_load_fpr32(ctx, fp0, fs);
9957            gen_helper_float_sqrt_s(fp0, cpu_env, fp0);
9958            gen_store_fpr32(ctx, fp0, fd);
9959            tcg_temp_free_i32(fp0);
9960        }
9961        break;
9962    case OPC_ABS_S:
9963        {
9964            TCGv_i32 fp0 = tcg_temp_new_i32();
9965
9966            gen_load_fpr32(ctx, fp0, fs);
9967            if (ctx->abs2008) {
9968                tcg_gen_andi_i32(fp0, fp0, 0x7fffffffUL);
9969            } else {
9970                gen_helper_float_abs_s(fp0, fp0);
9971            }
9972            gen_store_fpr32(ctx, fp0, fd);
9973            tcg_temp_free_i32(fp0);
9974        }
9975        break;
9976    case OPC_MOV_S:
9977        {
9978            TCGv_i32 fp0 = tcg_temp_new_i32();
9979
9980            gen_load_fpr32(ctx, fp0, fs);
9981            gen_store_fpr32(ctx, fp0, fd);
9982            tcg_temp_free_i32(fp0);
9983        }
9984        break;
9985    case OPC_NEG_S:
9986        {
9987            TCGv_i32 fp0 = tcg_temp_new_i32();
9988
9989            gen_load_fpr32(ctx, fp0, fs);
9990            if (ctx->abs2008) {
9991                tcg_gen_xori_i32(fp0, fp0, 1UL << 31);
9992            } else {
9993                gen_helper_float_chs_s(fp0, fp0);
9994            }
9995            gen_store_fpr32(ctx, fp0, fd);
9996            tcg_temp_free_i32(fp0);
9997        }
9998        break;
9999    case OPC_ROUND_L_S:
10000        check_cp1_64bitmode(ctx);
10001        {
10002            TCGv_i32 fp32 = tcg_temp_new_i32();
10003            TCGv_i64 fp64 = tcg_temp_new_i64();
10004
10005            gen_load_fpr32(ctx, fp32, fs);
10006            if (ctx->nan2008) {
10007                gen_helper_float_round_2008_l_s(fp64, cpu_env, fp32);
10008            } else {
10009                gen_helper_float_round_l_s(fp64, cpu_env, fp32);
10010            }
10011            tcg_temp_free_i32(fp32);
10012            gen_store_fpr64(ctx, fp64, fd);
10013            tcg_temp_free_i64(fp64);
10014        }
10015        break;
10016    case OPC_TRUNC_L_S:
10017        check_cp1_64bitmode(ctx);
10018        {
10019            TCGv_i32 fp32 = tcg_temp_new_i32();
10020            TCGv_i64 fp64 = tcg_temp_new_i64();
10021
10022            gen_load_fpr32(ctx, fp32, fs);
10023            if (ctx->nan2008) {
10024                gen_helper_float_trunc_2008_l_s(fp64, cpu_env, fp32);
10025            } else {
10026                gen_helper_float_trunc_l_s(fp64, cpu_env, fp32);
10027            }
10028            tcg_temp_free_i32(fp32);
10029            gen_store_fpr64(ctx, fp64, fd);
10030            tcg_temp_free_i64(fp64);
10031        }
10032        break;
10033    case OPC_CEIL_L_S:
10034        check_cp1_64bitmode(ctx);
10035        {
10036            TCGv_i32 fp32 = tcg_temp_new_i32();
10037            TCGv_i64 fp64 = tcg_temp_new_i64();
10038
10039            gen_load_fpr32(ctx, fp32, fs);
10040            if (ctx->nan2008) {
10041                gen_helper_float_ceil_2008_l_s(fp64, cpu_env, fp32);
10042            } else {
10043                gen_helper_float_ceil_l_s(fp64, cpu_env, fp32);
10044            }
10045            tcg_temp_free_i32(fp32);
10046            gen_store_fpr64(ctx, fp64, fd);
10047            tcg_temp_free_i64(fp64);
10048        }
10049        break;
10050    case OPC_FLOOR_L_S:
10051        check_cp1_64bitmode(ctx);
10052        {
10053            TCGv_i32 fp32 = tcg_temp_new_i32();
10054            TCGv_i64 fp64 = tcg_temp_new_i64();
10055
10056            gen_load_fpr32(ctx, fp32, fs);
10057            if (ctx->nan2008) {
10058                gen_helper_float_floor_2008_l_s(fp64, cpu_env, fp32);
10059            } else {
10060                gen_helper_float_floor_l_s(fp64, cpu_env, fp32);
10061            }
10062            tcg_temp_free_i32(fp32);
10063            gen_store_fpr64(ctx, fp64, fd);
10064            tcg_temp_free_i64(fp64);
10065        }
10066        break;
10067    case OPC_ROUND_W_S:
10068        {
10069            TCGv_i32 fp0 = tcg_temp_new_i32();
10070
10071            gen_load_fpr32(ctx, fp0, fs);
10072            if (ctx->nan2008) {
10073                gen_helper_float_round_2008_w_s(fp0, cpu_env, fp0);
10074            } else {
10075                gen_helper_float_round_w_s(fp0, cpu_env, fp0);
10076            }
10077            gen_store_fpr32(ctx, fp0, fd);
10078            tcg_temp_free_i32(fp0);
10079        }
10080        break;
10081    case OPC_TRUNC_W_S:
10082        {
10083            TCGv_i32 fp0 = tcg_temp_new_i32();
10084
10085            gen_load_fpr32(ctx, fp0, fs);
10086            if (ctx->nan2008) {
10087                gen_helper_float_trunc_2008_w_s(fp0, cpu_env, fp0);
10088            } else {
10089                gen_helper_float_trunc_w_s(fp0, cpu_env, fp0);
10090            }
10091            gen_store_fpr32(ctx, fp0, fd);
10092            tcg_temp_free_i32(fp0);
10093        }
10094        break;
10095    case OPC_CEIL_W_S:
10096        {
10097            TCGv_i32 fp0 = tcg_temp_new_i32();
10098
10099            gen_load_fpr32(ctx, fp0, fs);
10100            if (ctx->nan2008) {
10101                gen_helper_float_ceil_2008_w_s(fp0, cpu_env, fp0);
10102            } else {
10103                gen_helper_float_ceil_w_s(fp0, cpu_env, fp0);
10104            }
10105            gen_store_fpr32(ctx, fp0, fd);
10106            tcg_temp_free_i32(fp0);
10107        }
10108        break;
10109    case OPC_FLOOR_W_S:
10110        {
10111            TCGv_i32 fp0 = tcg_temp_new_i32();
10112
10113            gen_load_fpr32(ctx, fp0, fs);
10114            if (ctx->nan2008) {
10115                gen_helper_float_floor_2008_w_s(fp0, cpu_env, fp0);
10116            } else {
10117                gen_helper_float_floor_w_s(fp0, cpu_env, fp0);
10118            }
10119            gen_store_fpr32(ctx, fp0, fd);
10120            tcg_temp_free_i32(fp0);
10121        }
10122        break;
10123    case OPC_SEL_S:
10124        check_insn(ctx, ISA_MIPS_R6);
10125        gen_sel_s(ctx, op1, fd, ft, fs);
10126        break;
10127    case OPC_SELEQZ_S:
10128        check_insn(ctx, ISA_MIPS_R6);
10129        gen_sel_s(ctx, op1, fd, ft, fs);
10130        break;
10131    case OPC_SELNEZ_S:
10132        check_insn(ctx, ISA_MIPS_R6);
10133        gen_sel_s(ctx, op1, fd, ft, fs);
10134        break;
10135    case OPC_MOVCF_S:
10136        check_insn_opc_removed(ctx, ISA_MIPS_R6);
10137        gen_movcf_s(ctx, fs, fd, (ft >> 2) & 0x7, ft & 0x1);
10138        break;
10139    case OPC_MOVZ_S:
10140        check_insn_opc_removed(ctx, ISA_MIPS_R6);
10141        {
10142            TCGLabel *l1 = gen_new_label();
10143            TCGv_i32 fp0;
10144
10145            if (ft != 0) {
10146                tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[ft], 0, l1);
10147            }
10148            fp0 = tcg_temp_new_i32();
10149            gen_load_fpr32(ctx, fp0, fs);
10150            gen_store_fpr32(ctx, fp0, fd);
10151            tcg_temp_free_i32(fp0);
10152            gen_set_label(l1);
10153        }
10154        break;
10155    case OPC_MOVN_S:
10156        check_insn_opc_removed(ctx, ISA_MIPS_R6);
10157        {
10158            TCGLabel *l1 = gen_new_label();
10159            TCGv_i32 fp0;
10160
10161            if (ft != 0) {
10162                tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[ft], 0, l1);
10163                fp0 = tcg_temp_new_i32();
10164                gen_load_fpr32(ctx, fp0, fs);
10165                gen_store_fpr32(ctx, fp0, fd);
10166                tcg_temp_free_i32(fp0);
10167                gen_set_label(l1);
10168            }
10169        }
10170        break;
10171    case OPC_RECIP_S:
10172        {
10173            TCGv_i32 fp0 = tcg_temp_new_i32();
10174
10175            gen_load_fpr32(ctx, fp0, fs);
10176            gen_helper_float_recip_s(fp0, cpu_env, fp0);
10177            gen_store_fpr32(ctx, fp0, fd);
10178            tcg_temp_free_i32(fp0);
10179        }
10180        break;
10181    case OPC_RSQRT_S:
10182        {
10183            TCGv_i32 fp0 = tcg_temp_new_i32();
10184
10185            gen_load_fpr32(ctx, fp0, fs);
10186            gen_helper_float_rsqrt_s(fp0, cpu_env, fp0);
10187            gen_store_fpr32(ctx, fp0, fd);
10188            tcg_temp_free_i32(fp0);
10189        }
10190        break;
10191    case OPC_MADDF_S:
10192        check_insn(ctx, ISA_MIPS_R6);
10193        {
10194            TCGv_i32 fp0 = tcg_temp_new_i32();
10195            TCGv_i32 fp1 = tcg_temp_new_i32();
10196            TCGv_i32 fp2 = tcg_temp_new_i32();
10197            gen_load_fpr32(ctx, fp0, fs);
10198            gen_load_fpr32(ctx, fp1, ft);
10199            gen_load_fpr32(ctx, fp2, fd);
10200            gen_helper_float_maddf_s(fp2, cpu_env, fp0, fp1, fp2);
10201            gen_store_fpr32(ctx, fp2, fd);
10202            tcg_temp_free_i32(fp2);
10203            tcg_temp_free_i32(fp1);
10204            tcg_temp_free_i32(fp0);
10205        }
10206        break;
10207    case OPC_MSUBF_S:
10208        check_insn(ctx, ISA_MIPS_R6);
10209        {
10210            TCGv_i32 fp0 = tcg_temp_new_i32();
10211            TCGv_i32 fp1 = tcg_temp_new_i32();
10212            TCGv_i32 fp2 = tcg_temp_new_i32();
10213            gen_load_fpr32(ctx, fp0, fs);
10214            gen_load_fpr32(ctx, fp1, ft);
10215            gen_load_fpr32(ctx, fp2, fd);
10216            gen_helper_float_msubf_s(fp2, cpu_env, fp0, fp1, fp2);
10217            gen_store_fpr32(ctx, fp2, fd);
10218            tcg_temp_free_i32(fp2);
10219            tcg_temp_free_i32(fp1);
10220            tcg_temp_free_i32(fp0);
10221        }
10222        break;
10223    case OPC_RINT_S:
10224        check_insn(ctx, ISA_MIPS_R6);
10225        {
10226            TCGv_i32 fp0 = tcg_temp_new_i32();
10227            gen_load_fpr32(ctx, fp0, fs);
10228            gen_helper_float_rint_s(fp0, cpu_env, fp0);
10229            gen_store_fpr32(ctx, fp0, fd);
10230            tcg_temp_free_i32(fp0);
10231        }
10232        break;
10233    case OPC_CLASS_S:
10234        check_insn(ctx, ISA_MIPS_R6);
10235        {
10236            TCGv_i32 fp0 = tcg_temp_new_i32();
10237            gen_load_fpr32(ctx, fp0, fs);
10238            gen_helper_float_class_s(fp0, cpu_env, fp0);
10239            gen_store_fpr32(ctx, fp0, fd);
10240            tcg_temp_free_i32(fp0);
10241        }
10242        break;
10243    case OPC_MIN_S: /* OPC_RECIP2_S */
10244        if (ctx->insn_flags & ISA_MIPS_R6) {
10245            /* OPC_MIN_S */
10246            TCGv_i32 fp0 = tcg_temp_new_i32();
10247            TCGv_i32 fp1 = tcg_temp_new_i32();
10248            TCGv_i32 fp2 = tcg_temp_new_i32();
10249            gen_load_fpr32(ctx, fp0, fs);
10250            gen_load_fpr32(ctx, fp1, ft);
10251            gen_helper_float_min_s(fp2, cpu_env, fp0, fp1);
10252            gen_store_fpr32(ctx, fp2, fd);
10253            tcg_temp_free_i32(fp2);
10254            tcg_temp_free_i32(fp1);
10255            tcg_temp_free_i32(fp0);
10256        } else {
10257            /* OPC_RECIP2_S */
10258            check_cp1_64bitmode(ctx);
10259            {
10260                TCGv_i32 fp0 = tcg_temp_new_i32();
10261                TCGv_i32 fp1 = tcg_temp_new_i32();
10262
10263                gen_load_fpr32(ctx, fp0, fs);
10264                gen_load_fpr32(ctx, fp1, ft);
10265                gen_helper_float_recip2_s(fp0, cpu_env, fp0, fp1);
10266                tcg_temp_free_i32(fp1);
10267                gen_store_fpr32(ctx, fp0, fd);
10268                tcg_temp_free_i32(fp0);
10269            }
10270        }
10271        break;
10272    case OPC_MINA_S: /* OPC_RECIP1_S */
10273        if (ctx->insn_flags & ISA_MIPS_R6) {
10274            /* OPC_MINA_S */
10275            TCGv_i32 fp0 = tcg_temp_new_i32();
10276            TCGv_i32 fp1 = tcg_temp_new_i32();
10277            TCGv_i32 fp2 = tcg_temp_new_i32();
10278            gen_load_fpr32(ctx, fp0, fs);
10279            gen_load_fpr32(ctx, fp1, ft);
10280            gen_helper_float_mina_s(fp2, cpu_env, fp0, fp1);
10281            gen_store_fpr32(ctx, fp2, fd);
10282            tcg_temp_free_i32(fp2);
10283            tcg_temp_free_i32(fp1);
10284            tcg_temp_free_i32(fp0);
10285        } else {
10286            /* OPC_RECIP1_S */
10287            check_cp1_64bitmode(ctx);
10288            {
10289                TCGv_i32 fp0 = tcg_temp_new_i32();
10290
10291                gen_load_fpr32(ctx, fp0, fs);
10292                gen_helper_float_recip1_s(fp0, cpu_env, fp0);
10293                gen_store_fpr32(ctx, fp0, fd);
10294                tcg_temp_free_i32(fp0);
10295            }
10296        }
10297        break;
10298    case OPC_MAX_S: /* OPC_RSQRT1_S */
10299        if (ctx->insn_flags & ISA_MIPS_R6) {
10300            /* OPC_MAX_S */
10301            TCGv_i32 fp0 = tcg_temp_new_i32();
10302            TCGv_i32 fp1 = tcg_temp_new_i32();
10303            gen_load_fpr32(ctx, fp0, fs);
10304            gen_load_fpr32(ctx, fp1, ft);
10305            gen_helper_float_max_s(fp1, cpu_env, fp0, fp1);
10306            gen_store_fpr32(ctx, fp1, fd);
10307            tcg_temp_free_i32(fp1);
10308            tcg_temp_free_i32(fp0);
10309        } else {
10310            /* OPC_RSQRT1_S */
10311            check_cp1_64bitmode(ctx);
10312            {
10313                TCGv_i32 fp0 = tcg_temp_new_i32();
10314
10315                gen_load_fpr32(ctx, fp0, fs);
10316                gen_helper_float_rsqrt1_s(fp0, cpu_env, fp0);
10317                gen_store_fpr32(ctx, fp0, fd);
10318                tcg_temp_free_i32(fp0);
10319            }
10320        }
10321        break;
10322    case OPC_MAXA_S: /* OPC_RSQRT2_S */
10323        if (ctx->insn_flags & ISA_MIPS_R6) {
10324            /* OPC_MAXA_S */
10325            TCGv_i32 fp0 = tcg_temp_new_i32();
10326            TCGv_i32 fp1 = tcg_temp_new_i32();
10327            gen_load_fpr32(ctx, fp0, fs);
10328            gen_load_fpr32(ctx, fp1, ft);
10329            gen_helper_float_maxa_s(fp1, cpu_env, fp0, fp1);
10330            gen_store_fpr32(ctx, fp1, fd);
10331            tcg_temp_free_i32(fp1);
10332            tcg_temp_free_i32(fp0);
10333        } else {
10334            /* OPC_RSQRT2_S */
10335            check_cp1_64bitmode(ctx);
10336            {
10337                TCGv_i32 fp0 = tcg_temp_new_i32();
10338                TCGv_i32 fp1 = tcg_temp_new_i32();
10339
10340                gen_load_fpr32(ctx, fp0, fs);
10341                gen_load_fpr32(ctx, fp1, ft);
10342                gen_helper_float_rsqrt2_s(fp0, cpu_env, fp0, fp1);
10343                tcg_temp_free_i32(fp1);
10344                gen_store_fpr32(ctx, fp0, fd);
10345                tcg_temp_free_i32(fp0);
10346            }
10347        }
10348        break;
10349    case OPC_CVT_D_S:
10350        check_cp1_registers(ctx, fd);
10351        {
10352            TCGv_i32 fp32 = tcg_temp_new_i32();
10353            TCGv_i64 fp64 = tcg_temp_new_i64();
10354
10355            gen_load_fpr32(ctx, fp32, fs);
10356            gen_helper_float_cvtd_s(fp64, cpu_env, fp32);
10357            tcg_temp_free_i32(fp32);
10358            gen_store_fpr64(ctx, fp64, fd);
10359            tcg_temp_free_i64(fp64);
10360        }
10361        break;
10362    case OPC_CVT_W_S:
10363        {
10364            TCGv_i32 fp0 = tcg_temp_new_i32();
10365
10366            gen_load_fpr32(ctx, fp0, fs);
10367            if (ctx->nan2008) {
10368                gen_helper_float_cvt_2008_w_s(fp0, cpu_env, fp0);
10369            } else {
10370                gen_helper_float_cvt_w_s(fp0, cpu_env, fp0);
10371            }
10372            gen_store_fpr32(ctx, fp0, fd);
10373            tcg_temp_free_i32(fp0);
10374        }
10375        break;
10376    case OPC_CVT_L_S:
10377        check_cp1_64bitmode(ctx);
10378        {
10379            TCGv_i32 fp32 = tcg_temp_new_i32();
10380            TCGv_i64 fp64 = tcg_temp_new_i64();
10381
10382            gen_load_fpr32(ctx, fp32, fs);
10383            if (ctx->nan2008) {
10384                gen_helper_float_cvt_2008_l_s(fp64, cpu_env, fp32);
10385            } else {
10386                gen_helper_float_cvt_l_s(fp64, cpu_env, fp32);
10387            }
10388            tcg_temp_free_i32(fp32);
10389            gen_store_fpr64(ctx, fp64, fd);
10390            tcg_temp_free_i64(fp64);
10391        }
10392        break;
10393    case OPC_CVT_PS_S:
10394        check_ps(ctx);
10395        {
10396            TCGv_i64 fp64 = tcg_temp_new_i64();
10397            TCGv_i32 fp32_0 = tcg_temp_new_i32();
10398            TCGv_i32 fp32_1 = tcg_temp_new_i32();
10399
10400            gen_load_fpr32(ctx, fp32_0, fs);
10401            gen_load_fpr32(ctx, fp32_1, ft);
10402            tcg_gen_concat_i32_i64(fp64, fp32_1, fp32_0);
10403            tcg_temp_free_i32(fp32_1);
10404            tcg_temp_free_i32(fp32_0);
10405            gen_store_fpr64(ctx, fp64, fd);
10406            tcg_temp_free_i64(fp64);
10407        }
10408        break;
10409    case OPC_CMP_F_S:
10410    case OPC_CMP_UN_S:
10411    case OPC_CMP_EQ_S:
10412    case OPC_CMP_UEQ_S:
10413    case OPC_CMP_OLT_S:
10414    case OPC_CMP_ULT_S:
10415    case OPC_CMP_OLE_S:
10416    case OPC_CMP_ULE_S:
10417    case OPC_CMP_SF_S:
10418    case OPC_CMP_NGLE_S:
10419    case OPC_CMP_SEQ_S:
10420    case OPC_CMP_NGL_S:
10421    case OPC_CMP_LT_S:
10422    case OPC_CMP_NGE_S:
10423    case OPC_CMP_LE_S:
10424    case OPC_CMP_NGT_S:
10425        check_insn_opc_removed(ctx, ISA_MIPS_R6);
10426        if (ctx->opcode & (1 << 6)) {
10427            gen_cmpabs_s(ctx, func - 48, ft, fs, cc);
10428        } else {
10429            gen_cmp_s(ctx, func - 48, ft, fs, cc);
10430        }
10431        break;
10432    case OPC_ADD_D:
10433        check_cp1_registers(ctx, fs | ft | fd);
10434        {
10435            TCGv_i64 fp0 = tcg_temp_new_i64();
10436            TCGv_i64 fp1 = tcg_temp_new_i64();
10437
10438            gen_load_fpr64(ctx, fp0, fs);
10439            gen_load_fpr64(ctx, fp1, ft);
10440            gen_helper_float_add_d(fp0, cpu_env, fp0, fp1);
10441            tcg_temp_free_i64(fp1);
10442            gen_store_fpr64(ctx, fp0, fd);
10443            tcg_temp_free_i64(fp0);
10444        }
10445        break;
10446    case OPC_SUB_D:
10447        check_cp1_registers(ctx, fs | ft | fd);
10448        {
10449            TCGv_i64 fp0 = tcg_temp_new_i64();
10450            TCGv_i64 fp1 = tcg_temp_new_i64();
10451
10452            gen_load_fpr64(ctx, fp0, fs);
10453            gen_load_fpr64(ctx, fp1, ft);
10454            gen_helper_float_sub_d(fp0, cpu_env, fp0, fp1);
10455            tcg_temp_free_i64(fp1);
10456            gen_store_fpr64(ctx, fp0, fd);
10457            tcg_temp_free_i64(fp0);
10458        }
10459        break;
10460    case OPC_MUL_D:
10461        check_cp1_registers(ctx, fs | ft | fd);
10462        {
10463            TCGv_i64 fp0 = tcg_temp_new_i64();
10464            TCGv_i64 fp1 = tcg_temp_new_i64();
10465
10466            gen_load_fpr64(ctx, fp0, fs);
10467            gen_load_fpr64(ctx, fp1, ft);
10468            gen_helper_float_mul_d(fp0, cpu_env, fp0, fp1);
10469            tcg_temp_free_i64(fp1);
10470            gen_store_fpr64(ctx, fp0, fd);
10471            tcg_temp_free_i64(fp0);
10472        }
10473        break;
10474    case OPC_DIV_D:
10475        check_cp1_registers(ctx, fs | ft | fd);
10476        {
10477            TCGv_i64 fp0 = tcg_temp_new_i64();
10478            TCGv_i64 fp1 = tcg_temp_new_i64();
10479
10480            gen_load_fpr64(ctx, fp0, fs);
10481            gen_load_fpr64(ctx, fp1, ft);
10482            gen_helper_float_div_d(fp0, cpu_env, fp0, fp1);
10483            tcg_temp_free_i64(fp1);
10484            gen_store_fpr64(ctx, fp0, fd);
10485            tcg_temp_free_i64(fp0);
10486        }
10487        break;
10488    case OPC_SQRT_D:
10489        check_cp1_registers(ctx, fs | fd);
10490        {
10491            TCGv_i64 fp0 = tcg_temp_new_i64();
10492
10493            gen_load_fpr64(ctx, fp0, fs);
10494            gen_helper_float_sqrt_d(fp0, cpu_env, fp0);
10495            gen_store_fpr64(ctx, fp0, fd);
10496            tcg_temp_free_i64(fp0);
10497        }
10498        break;
10499    case OPC_ABS_D:
10500        check_cp1_registers(ctx, fs | fd);
10501        {
10502            TCGv_i64 fp0 = tcg_temp_new_i64();
10503
10504            gen_load_fpr64(ctx, fp0, fs);
10505            if (ctx->abs2008) {
10506                tcg_gen_andi_i64(fp0, fp0, 0x7fffffffffffffffULL);
10507            } else {
10508                gen_helper_float_abs_d(fp0, fp0);
10509            }
10510            gen_store_fpr64(ctx, fp0, fd);
10511            tcg_temp_free_i64(fp0);
10512        }
10513        break;
10514    case OPC_MOV_D:
10515        check_cp1_registers(ctx, fs | fd);
10516        {
10517            TCGv_i64 fp0 = tcg_temp_new_i64();
10518
10519            gen_load_fpr64(ctx, fp0, fs);
10520            gen_store_fpr64(ctx, fp0, fd);
10521            tcg_temp_free_i64(fp0);
10522        }
10523        break;
10524    case OPC_NEG_D:
10525        check_cp1_registers(ctx, fs | fd);
10526        {
10527            TCGv_i64 fp0 = tcg_temp_new_i64();
10528
10529            gen_load_fpr64(ctx, fp0, fs);
10530            if (ctx->abs2008) {
10531                tcg_gen_xori_i64(fp0, fp0, 1ULL << 63);
10532            } else {
10533                gen_helper_float_chs_d(fp0, fp0);
10534            }
10535            gen_store_fpr64(ctx, fp0, fd);
10536            tcg_temp_free_i64(fp0);
10537        }
10538        break;
10539    case OPC_ROUND_L_D:
10540        check_cp1_64bitmode(ctx);
10541        {
10542            TCGv_i64 fp0 = tcg_temp_new_i64();
10543
10544            gen_load_fpr64(ctx, fp0, fs);
10545            if (ctx->nan2008) {
10546                gen_helper_float_round_2008_l_d(fp0, cpu_env, fp0);
10547            } else {
10548                gen_helper_float_round_l_d(fp0, cpu_env, fp0);
10549            }
10550            gen_store_fpr64(ctx, fp0, fd);
10551            tcg_temp_free_i64(fp0);
10552        }
10553        break;
10554    case OPC_TRUNC_L_D:
10555        check_cp1_64bitmode(ctx);
10556        {
10557            TCGv_i64 fp0 = tcg_temp_new_i64();
10558
10559            gen_load_fpr64(ctx, fp0, fs);
10560            if (ctx->nan2008) {
10561                gen_helper_float_trunc_2008_l_d(fp0, cpu_env, fp0);
10562            } else {
10563                gen_helper_float_trunc_l_d(fp0, cpu_env, fp0);
10564            }
10565            gen_store_fpr64(ctx, fp0, fd);
10566            tcg_temp_free_i64(fp0);
10567        }
10568        break;
10569    case OPC_CEIL_L_D:
10570        check_cp1_64bitmode(ctx);
10571        {
10572            TCGv_i64 fp0 = tcg_temp_new_i64();
10573
10574            gen_load_fpr64(ctx, fp0, fs);
10575            if (ctx->nan2008) {
10576                gen_helper_float_ceil_2008_l_d(fp0, cpu_env, fp0);
10577            } else {
10578                gen_helper_float_ceil_l_d(fp0, cpu_env, fp0);
10579            }
10580            gen_store_fpr64(ctx, fp0, fd);
10581            tcg_temp_free_i64(fp0);
10582        }
10583        break;
10584    case OPC_FLOOR_L_D:
10585        check_cp1_64bitmode(ctx);
10586        {
10587            TCGv_i64 fp0 = tcg_temp_new_i64();
10588
10589            gen_load_fpr64(ctx, fp0, fs);
10590            if (ctx->nan2008) {
10591                gen_helper_float_floor_2008_l_d(fp0, cpu_env, fp0);
10592            } else {
10593                gen_helper_float_floor_l_d(fp0, cpu_env, fp0);
10594            }
10595            gen_store_fpr64(ctx, fp0, fd);
10596            tcg_temp_free_i64(fp0);
10597        }
10598        break;
10599    case OPC_ROUND_W_D:
10600        check_cp1_registers(ctx, fs);
10601        {
10602            TCGv_i32 fp32 = tcg_temp_new_i32();
10603            TCGv_i64 fp64 = tcg_temp_new_i64();
10604
10605            gen_load_fpr64(ctx, fp64, fs);
10606            if (ctx->nan2008) {
10607                gen_helper_float_round_2008_w_d(fp32, cpu_env, fp64);
10608            } else {
10609                gen_helper_float_round_w_d(fp32, cpu_env, fp64);
10610            }
10611            tcg_temp_free_i64(fp64);
10612            gen_store_fpr32(ctx, fp32, fd);
10613            tcg_temp_free_i32(fp32);
10614        }
10615        break;
10616    case OPC_TRUNC_W_D:
10617        check_cp1_registers(ctx, fs);
10618        {
10619            TCGv_i32 fp32 = tcg_temp_new_i32();
10620            TCGv_i64 fp64 = tcg_temp_new_i64();
10621
10622            gen_load_fpr64(ctx, fp64, fs);
10623            if (ctx->nan2008) {
10624                gen_helper_float_trunc_2008_w_d(fp32, cpu_env, fp64);
10625            } else {
10626                gen_helper_float_trunc_w_d(fp32, cpu_env, fp64);
10627            }
10628            tcg_temp_free_i64(fp64);
10629            gen_store_fpr32(ctx, fp32, fd);
10630            tcg_temp_free_i32(fp32);
10631        }
10632        break;
10633    case OPC_CEIL_W_D:
10634        check_cp1_registers(ctx, fs);
10635        {
10636            TCGv_i32 fp32 = tcg_temp_new_i32();
10637            TCGv_i64 fp64 = tcg_temp_new_i64();
10638
10639            gen_load_fpr64(ctx, fp64, fs);
10640            if (ctx->nan2008) {
10641                gen_helper_float_ceil_2008_w_d(fp32, cpu_env, fp64);
10642            } else {
10643                gen_helper_float_ceil_w_d(fp32, cpu_env, fp64);
10644            }
10645            tcg_temp_free_i64(fp64);
10646            gen_store_fpr32(ctx, fp32, fd);
10647            tcg_temp_free_i32(fp32);
10648        }
10649        break;
10650    case OPC_FLOOR_W_D:
10651        check_cp1_registers(ctx, fs);
10652        {
10653            TCGv_i32 fp32 = tcg_temp_new_i32();
10654            TCGv_i64 fp64 = tcg_temp_new_i64();
10655
10656            gen_load_fpr64(ctx, fp64, fs);
10657            if (ctx->nan2008) {
10658                gen_helper_float_floor_2008_w_d(fp32, cpu_env, fp64);
10659            } else {
10660                gen_helper_float_floor_w_d(fp32, cpu_env, fp64);
10661            }
10662            tcg_temp_free_i64(fp64);
10663            gen_store_fpr32(ctx, fp32, fd);
10664            tcg_temp_free_i32(fp32);
10665        }
10666        break;
10667    case OPC_SEL_D:
10668        check_insn(ctx, ISA_MIPS_R6);
10669        gen_sel_d(ctx, op1, fd, ft, fs);
10670        break;
10671    case OPC_SELEQZ_D:
10672        check_insn(ctx, ISA_MIPS_R6);
10673        gen_sel_d(ctx, op1, fd, ft, fs);
10674        break;
10675    case OPC_SELNEZ_D:
10676        check_insn(ctx, ISA_MIPS_R6);
10677        gen_sel_d(ctx, op1, fd, ft, fs);
10678        break;
10679    case OPC_MOVCF_D:
10680        check_insn_opc_removed(ctx, ISA_MIPS_R6);
10681        gen_movcf_d(ctx, fs, fd, (ft >> 2) & 0x7, ft & 0x1);
10682        break;
10683    case OPC_MOVZ_D:
10684        check_insn_opc_removed(ctx, ISA_MIPS_R6);
10685        {
10686            TCGLabel *l1 = gen_new_label();
10687            TCGv_i64 fp0;
10688
10689            if (ft != 0) {
10690                tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[ft], 0, l1);
10691            }
10692            fp0 = tcg_temp_new_i64();
10693            gen_load_fpr64(ctx, fp0, fs);
10694            gen_store_fpr64(ctx, fp0, fd);
10695            tcg_temp_free_i64(fp0);
10696            gen_set_label(l1);
10697        }
10698        break;
10699    case OPC_MOVN_D:
10700        check_insn_opc_removed(ctx, ISA_MIPS_R6);
10701        {
10702            TCGLabel *l1 = gen_new_label();
10703            TCGv_i64 fp0;
10704
10705            if (ft != 0) {
10706                tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[ft], 0, l1);
10707                fp0 = tcg_temp_new_i64();
10708                gen_load_fpr64(ctx, fp0, fs);
10709                gen_store_fpr64(ctx, fp0, fd);
10710                tcg_temp_free_i64(fp0);
10711                gen_set_label(l1);
10712            }
10713        }
10714        break;
10715    case OPC_RECIP_D:
10716        check_cp1_registers(ctx, fs | fd);
10717        {
10718            TCGv_i64 fp0 = tcg_temp_new_i64();
10719
10720            gen_load_fpr64(ctx, fp0, fs);
10721            gen_helper_float_recip_d(fp0, cpu_env, fp0);
10722            gen_store_fpr64(ctx, fp0, fd);
10723            tcg_temp_free_i64(fp0);
10724        }
10725        break;
10726    case OPC_RSQRT_D:
10727        check_cp1_registers(ctx, fs | fd);
10728        {
10729            TCGv_i64 fp0 = tcg_temp_new_i64();
10730
10731            gen_load_fpr64(ctx, fp0, fs);
10732            gen_helper_float_rsqrt_d(fp0, cpu_env, fp0);
10733            gen_store_fpr64(ctx, fp0, fd);
10734            tcg_temp_free_i64(fp0);
10735        }
10736        break;
10737    case OPC_MADDF_D:
10738        check_insn(ctx, ISA_MIPS_R6);
10739        {
10740            TCGv_i64 fp0 = tcg_temp_new_i64();
10741            TCGv_i64 fp1 = tcg_temp_new_i64();
10742            TCGv_i64 fp2 = tcg_temp_new_i64();
10743            gen_load_fpr64(ctx, fp0, fs);
10744            gen_load_fpr64(ctx, fp1, ft);
10745            gen_load_fpr64(ctx, fp2, fd);
10746            gen_helper_float_maddf_d(fp2, cpu_env, fp0, fp1, fp2);
10747            gen_store_fpr64(ctx, fp2, fd);
10748            tcg_temp_free_i64(fp2);
10749            tcg_temp_free_i64(fp1);
10750            tcg_temp_free_i64(fp0);
10751        }
10752        break;
10753    case OPC_MSUBF_D:
10754        check_insn(ctx, ISA_MIPS_R6);
10755        {
10756            TCGv_i64 fp0 = tcg_temp_new_i64();
10757            TCGv_i64 fp1 = tcg_temp_new_i64();
10758            TCGv_i64 fp2 = tcg_temp_new_i64();
10759            gen_load_fpr64(ctx, fp0, fs);
10760            gen_load_fpr64(ctx, fp1, ft);
10761            gen_load_fpr64(ctx, fp2, fd);
10762            gen_helper_float_msubf_d(fp2, cpu_env, fp0, fp1, fp2);
10763            gen_store_fpr64(ctx, fp2, fd);
10764            tcg_temp_free_i64(fp2);
10765            tcg_temp_free_i64(fp1);
10766            tcg_temp_free_i64(fp0);
10767        }
10768        break;
10769    case OPC_RINT_D:
10770        check_insn(ctx, ISA_MIPS_R6);
10771        {
10772            TCGv_i64 fp0 = tcg_temp_new_i64();
10773            gen_load_fpr64(ctx, fp0, fs);
10774            gen_helper_float_rint_d(fp0, cpu_env, fp0);
10775            gen_store_fpr64(ctx, fp0, fd);
10776            tcg_temp_free_i64(fp0);
10777        }
10778        break;
10779    case OPC_CLASS_D:
10780        check_insn(ctx, ISA_MIPS_R6);
10781        {
10782            TCGv_i64 fp0 = tcg_temp_new_i64();
10783            gen_load_fpr64(ctx, fp0, fs);
10784            gen_helper_float_class_d(fp0, cpu_env, fp0);
10785            gen_store_fpr64(ctx, fp0, fd);
10786            tcg_temp_free_i64(fp0);
10787        }
10788        break;
10789    case OPC_MIN_D: /* OPC_RECIP2_D */
10790        if (ctx->insn_flags & ISA_MIPS_R6) {
10791            /* OPC_MIN_D */
10792            TCGv_i64 fp0 = tcg_temp_new_i64();
10793            TCGv_i64 fp1 = tcg_temp_new_i64();
10794            gen_load_fpr64(ctx, fp0, fs);
10795            gen_load_fpr64(ctx, fp1, ft);
10796            gen_helper_float_min_d(fp1, cpu_env, fp0, fp1);
10797            gen_store_fpr64(ctx, fp1, fd);
10798            tcg_temp_free_i64(fp1);
10799            tcg_temp_free_i64(fp0);
10800        } else {
10801            /* OPC_RECIP2_D */
10802            check_cp1_64bitmode(ctx);
10803            {
10804                TCGv_i64 fp0 = tcg_temp_new_i64();
10805                TCGv_i64 fp1 = tcg_temp_new_i64();
10806
10807                gen_load_fpr64(ctx, fp0, fs);
10808                gen_load_fpr64(ctx, fp1, ft);
10809                gen_helper_float_recip2_d(fp0, cpu_env, fp0, fp1);
10810                tcg_temp_free_i64(fp1);
10811                gen_store_fpr64(ctx, fp0, fd);
10812                tcg_temp_free_i64(fp0);
10813            }
10814        }
10815        break;
10816    case OPC_MINA_D: /* OPC_RECIP1_D */
10817        if (ctx->insn_flags & ISA_MIPS_R6) {
10818            /* OPC_MINA_D */
10819            TCGv_i64 fp0 = tcg_temp_new_i64();
10820            TCGv_i64 fp1 = tcg_temp_new_i64();
10821            gen_load_fpr64(ctx, fp0, fs);
10822            gen_load_fpr64(ctx, fp1, ft);
10823            gen_helper_float_mina_d(fp1, cpu_env, fp0, fp1);
10824            gen_store_fpr64(ctx, fp1, fd);
10825            tcg_temp_free_i64(fp1);
10826            tcg_temp_free_i64(fp0);
10827        } else {
10828            /* OPC_RECIP1_D */
10829            check_cp1_64bitmode(ctx);
10830            {
10831                TCGv_i64 fp0 = tcg_temp_new_i64();
10832
10833                gen_load_fpr64(ctx, fp0, fs);
10834                gen_helper_float_recip1_d(fp0, cpu_env, fp0);
10835                gen_store_fpr64(ctx, fp0, fd);
10836                tcg_temp_free_i64(fp0);
10837            }
10838        }
10839        break;
10840    case OPC_MAX_D: /*  OPC_RSQRT1_D */
10841        if (ctx->insn_flags & ISA_MIPS_R6) {
10842            /* OPC_MAX_D */
10843            TCGv_i64 fp0 = tcg_temp_new_i64();
10844            TCGv_i64 fp1 = tcg_temp_new_i64();
10845            gen_load_fpr64(ctx, fp0, fs);
10846            gen_load_fpr64(ctx, fp1, ft);
10847            gen_helper_float_max_d(fp1, cpu_env, fp0, fp1);
10848            gen_store_fpr64(ctx, fp1, fd);
10849            tcg_temp_free_i64(fp1);
10850            tcg_temp_free_i64(fp0);
10851        } else {
10852            /* OPC_RSQRT1_D */
10853            check_cp1_64bitmode(ctx);
10854            {
10855                TCGv_i64 fp0 = tcg_temp_new_i64();
10856
10857                gen_load_fpr64(ctx, fp0, fs);
10858                gen_helper_float_rsqrt1_d(fp0, cpu_env, fp0);
10859                gen_store_fpr64(ctx, fp0, fd);
10860                tcg_temp_free_i64(fp0);
10861            }
10862        }
10863        break;
10864    case OPC_MAXA_D: /* OPC_RSQRT2_D */
10865        if (ctx->insn_flags & ISA_MIPS_R6) {
10866            /* OPC_MAXA_D */
10867            TCGv_i64 fp0 = tcg_temp_new_i64();
10868            TCGv_i64 fp1 = tcg_temp_new_i64();
10869            gen_load_fpr64(ctx, fp0, fs);
10870            gen_load_fpr64(ctx, fp1, ft);
10871            gen_helper_float_maxa_d(fp1, cpu_env, fp0, fp1);
10872            gen_store_fpr64(ctx, fp1, fd);
10873            tcg_temp_free_i64(fp1);
10874            tcg_temp_free_i64(fp0);
10875        } else {
10876            /* OPC_RSQRT2_D */
10877            check_cp1_64bitmode(ctx);
10878            {
10879                TCGv_i64 fp0 = tcg_temp_new_i64();
10880                TCGv_i64 fp1 = tcg_temp_new_i64();
10881
10882                gen_load_fpr64(ctx, fp0, fs);
10883                gen_load_fpr64(ctx, fp1, ft);
10884                gen_helper_float_rsqrt2_d(fp0, cpu_env, fp0, fp1);
10885                tcg_temp_free_i64(fp1);
10886                gen_store_fpr64(ctx, fp0, fd);
10887                tcg_temp_free_i64(fp0);
10888            }
10889        }
10890        break;
10891    case OPC_CMP_F_D:
10892    case OPC_CMP_UN_D:
10893    case OPC_CMP_EQ_D:
10894    case OPC_CMP_UEQ_D:
10895    case OPC_CMP_OLT_D:
10896    case OPC_CMP_ULT_D:
10897    case OPC_CMP_OLE_D:
10898    case OPC_CMP_ULE_D:
10899    case OPC_CMP_SF_D:
10900    case OPC_CMP_NGLE_D:
10901    case OPC_CMP_SEQ_D:
10902    case OPC_CMP_NGL_D:
10903    case OPC_CMP_LT_D:
10904    case OPC_CMP_NGE_D:
10905    case OPC_CMP_LE_D:
10906    case OPC_CMP_NGT_D:
10907        check_insn_opc_removed(ctx, ISA_MIPS_R6);
10908        if (ctx->opcode & (1 << 6)) {
10909            gen_cmpabs_d(ctx, func - 48, ft, fs, cc);
10910        } else {
10911            gen_cmp_d(ctx, func - 48, ft, fs, cc);
10912        }
10913        break;
10914    case OPC_CVT_S_D:
10915        check_cp1_registers(ctx, fs);
10916        {
10917            TCGv_i32 fp32 = tcg_temp_new_i32();
10918            TCGv_i64 fp64 = tcg_temp_new_i64();
10919
10920            gen_load_fpr64(ctx, fp64, fs);
10921            gen_helper_float_cvts_d(fp32, cpu_env, fp64);
10922            tcg_temp_free_i64(fp64);
10923            gen_store_fpr32(ctx, fp32, fd);
10924            tcg_temp_free_i32(fp32);
10925        }
10926        break;
10927    case OPC_CVT_W_D:
10928        check_cp1_registers(ctx, fs);
10929        {
10930            TCGv_i32 fp32 = tcg_temp_new_i32();
10931            TCGv_i64 fp64 = tcg_temp_new_i64();
10932
10933            gen_load_fpr64(ctx, fp64, fs);
10934            if (ctx->nan2008) {
10935                gen_helper_float_cvt_2008_w_d(fp32, cpu_env, fp64);
10936            } else {
10937                gen_helper_float_cvt_w_d(fp32, cpu_env, fp64);
10938            }
10939            tcg_temp_free_i64(fp64);
10940            gen_store_fpr32(ctx, fp32, fd);
10941            tcg_temp_free_i32(fp32);
10942        }
10943        break;
10944    case OPC_CVT_L_D:
10945        check_cp1_64bitmode(ctx);
10946        {
10947            TCGv_i64 fp0 = tcg_temp_new_i64();
10948
10949            gen_load_fpr64(ctx, fp0, fs);
10950            if (ctx->nan2008) {
10951                gen_helper_float_cvt_2008_l_d(fp0, cpu_env, fp0);
10952            } else {
10953                gen_helper_float_cvt_l_d(fp0, cpu_env, fp0);
10954            }
10955            gen_store_fpr64(ctx, fp0, fd);
10956            tcg_temp_free_i64(fp0);
10957        }
10958        break;
10959    case OPC_CVT_S_W:
10960        {
10961            TCGv_i32 fp0 = tcg_temp_new_i32();
10962
10963            gen_load_fpr32(ctx, fp0, fs);
10964            gen_helper_float_cvts_w(fp0, cpu_env, fp0);
10965            gen_store_fpr32(ctx, fp0, fd);
10966            tcg_temp_free_i32(fp0);
10967        }
10968        break;
10969    case OPC_CVT_D_W:
10970        check_cp1_registers(ctx, fd);
10971        {
10972            TCGv_i32 fp32 = tcg_temp_new_i32();
10973            TCGv_i64 fp64 = tcg_temp_new_i64();
10974
10975            gen_load_fpr32(ctx, fp32, fs);
10976            gen_helper_float_cvtd_w(fp64, cpu_env, fp32);
10977            tcg_temp_free_i32(fp32);
10978            gen_store_fpr64(ctx, fp64, fd);
10979            tcg_temp_free_i64(fp64);
10980        }
10981        break;
10982    case OPC_CVT_S_L:
10983        check_cp1_64bitmode(ctx);
10984        {
10985            TCGv_i32 fp32 = tcg_temp_new_i32();
10986            TCGv_i64 fp64 = tcg_temp_new_i64();
10987
10988            gen_load_fpr64(ctx, fp64, fs);
10989            gen_helper_float_cvts_l(fp32, cpu_env, fp64);
10990            tcg_temp_free_i64(fp64);
10991            gen_store_fpr32(ctx, fp32, fd);
10992            tcg_temp_free_i32(fp32);
10993        }
10994        break;
10995    case OPC_CVT_D_L:
10996        check_cp1_64bitmode(ctx);
10997        {
10998            TCGv_i64 fp0 = tcg_temp_new_i64();
10999
11000            gen_load_fpr64(ctx, fp0, fs);
11001            gen_helper_float_cvtd_l(fp0, cpu_env, fp0);
11002            gen_store_fpr64(ctx, fp0, fd);
11003            tcg_temp_free_i64(fp0);
11004        }
11005        break;
11006    case OPC_CVT_PS_PW:
11007        check_ps(ctx);
11008        {
11009            TCGv_i64 fp0 = tcg_temp_new_i64();
11010
11011            gen_load_fpr64(ctx, fp0, fs);
11012            gen_helper_float_cvtps_pw(fp0, cpu_env, fp0);
11013            gen_store_fpr64(ctx, fp0, fd);
11014            tcg_temp_free_i64(fp0);
11015        }
11016        break;
11017    case OPC_ADD_PS:
11018        check_ps(ctx);
11019        {
11020            TCGv_i64 fp0 = tcg_temp_new_i64();
11021            TCGv_i64 fp1 = tcg_temp_new_i64();
11022
11023            gen_load_fpr64(ctx, fp0, fs);
11024            gen_load_fpr64(ctx, fp1, ft);
11025            gen_helper_float_add_ps(fp0, cpu_env, fp0, fp1);
11026            tcg_temp_free_i64(fp1);
11027            gen_store_fpr64(ctx, fp0, fd);
11028            tcg_temp_free_i64(fp0);
11029        }
11030        break;
11031    case OPC_SUB_PS:
11032        check_ps(ctx);
11033        {
11034            TCGv_i64 fp0 = tcg_temp_new_i64();
11035            TCGv_i64 fp1 = tcg_temp_new_i64();
11036
11037            gen_load_fpr64(ctx, fp0, fs);
11038            gen_load_fpr64(ctx, fp1, ft);
11039            gen_helper_float_sub_ps(fp0, cpu_env, fp0, fp1);
11040            tcg_temp_free_i64(fp1);
11041            gen_store_fpr64(ctx, fp0, fd);
11042            tcg_temp_free_i64(fp0);
11043        }
11044        break;
11045    case OPC_MUL_PS:
11046        check_ps(ctx);
11047        {
11048            TCGv_i64 fp0 = tcg_temp_new_i64();
11049            TCGv_i64 fp1 = tcg_temp_new_i64();
11050
11051            gen_load_fpr64(ctx, fp0, fs);
11052            gen_load_fpr64(ctx, fp1, ft);
11053            gen_helper_float_mul_ps(fp0, cpu_env, fp0, fp1);
11054            tcg_temp_free_i64(fp1);
11055            gen_store_fpr64(ctx, fp0, fd);
11056            tcg_temp_free_i64(fp0);
11057        }
11058        break;
11059    case OPC_ABS_PS:
11060        check_ps(ctx);
11061        {
11062            TCGv_i64 fp0 = tcg_temp_new_i64();
11063
11064            gen_load_fpr64(ctx, fp0, fs);
11065            gen_helper_float_abs_ps(fp0, fp0);
11066            gen_store_fpr64(ctx, fp0, fd);
11067            tcg_temp_free_i64(fp0);
11068        }
11069        break;
11070    case OPC_MOV_PS:
11071        check_ps(ctx);
11072        {
11073            TCGv_i64 fp0 = tcg_temp_new_i64();
11074
11075            gen_load_fpr64(ctx, fp0, fs);
11076            gen_store_fpr64(ctx, fp0, fd);
11077            tcg_temp_free_i64(fp0);
11078        }
11079        break;
11080    case OPC_NEG_PS:
11081        check_ps(ctx);
11082        {
11083            TCGv_i64 fp0 = tcg_temp_new_i64();
11084
11085            gen_load_fpr64(ctx, fp0, fs);
11086            gen_helper_float_chs_ps(fp0, fp0);
11087            gen_store_fpr64(ctx, fp0, fd);
11088            tcg_temp_free_i64(fp0);
11089        }
11090        break;
11091    case OPC_MOVCF_PS:
11092        check_ps(ctx);
11093        gen_movcf_ps(ctx, fs, fd, (ft >> 2) & 0x7, ft & 0x1);
11094        break;
11095    case OPC_MOVZ_PS:
11096        check_ps(ctx);
11097        {
11098            TCGLabel *l1 = gen_new_label();
11099            TCGv_i64 fp0;
11100
11101            if (ft != 0) {
11102                tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[ft], 0, l1);
11103            }
11104            fp0 = tcg_temp_new_i64();
11105            gen_load_fpr64(ctx, fp0, fs);
11106            gen_store_fpr64(ctx, fp0, fd);
11107            tcg_temp_free_i64(fp0);
11108            gen_set_label(l1);
11109        }
11110        break;
11111    case OPC_MOVN_PS:
11112        check_ps(ctx);
11113        {
11114            TCGLabel *l1 = gen_new_label();
11115            TCGv_i64 fp0;
11116
11117            if (ft != 0) {
11118                tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[ft], 0, l1);
11119                fp0 = tcg_temp_new_i64();
11120                gen_load_fpr64(ctx, fp0, fs);
11121                gen_store_fpr64(ctx, fp0, fd);
11122                tcg_temp_free_i64(fp0);
11123                gen_set_label(l1);
11124            }
11125        }
11126        break;
11127    case OPC_ADDR_PS:
11128        check_ps(ctx);
11129        {
11130            TCGv_i64 fp0 = tcg_temp_new_i64();
11131            TCGv_i64 fp1 = tcg_temp_new_i64();
11132
11133            gen_load_fpr64(ctx, fp0, ft);
11134            gen_load_fpr64(ctx, fp1, fs);
11135            gen_helper_float_addr_ps(fp0, cpu_env, fp0, fp1);
11136            tcg_temp_free_i64(fp1);
11137            gen_store_fpr64(ctx, fp0, fd);
11138            tcg_temp_free_i64(fp0);
11139        }
11140        break;
11141    case OPC_MULR_PS:
11142        check_ps(ctx);
11143        {
11144            TCGv_i64 fp0 = tcg_temp_new_i64();
11145            TCGv_i64 fp1 = tcg_temp_new_i64();
11146
11147            gen_load_fpr64(ctx, fp0, ft);
11148            gen_load_fpr64(ctx, fp1, fs);
11149            gen_helper_float_mulr_ps(fp0, cpu_env, fp0, fp1);
11150            tcg_temp_free_i64(fp1);
11151            gen_store_fpr64(ctx, fp0, fd);
11152            tcg_temp_free_i64(fp0);
11153        }
11154        break;
11155    case OPC_RECIP2_PS:
11156        check_ps(ctx);
11157        {
11158            TCGv_i64 fp0 = tcg_temp_new_i64();
11159            TCGv_i64 fp1 = tcg_temp_new_i64();
11160
11161            gen_load_fpr64(ctx, fp0, fs);
11162            gen_load_fpr64(ctx, fp1, ft);
11163            gen_helper_float_recip2_ps(fp0, cpu_env, fp0, fp1);
11164            tcg_temp_free_i64(fp1);
11165            gen_store_fpr64(ctx, fp0, fd);
11166            tcg_temp_free_i64(fp0);
11167        }
11168        break;
11169    case OPC_RECIP1_PS:
11170        check_ps(ctx);
11171        {
11172            TCGv_i64 fp0 = tcg_temp_new_i64();
11173
11174            gen_load_fpr64(ctx, fp0, fs);
11175            gen_helper_float_recip1_ps(fp0, cpu_env, fp0);
11176            gen_store_fpr64(ctx, fp0, fd);
11177            tcg_temp_free_i64(fp0);
11178        }
11179        break;
11180    case OPC_RSQRT1_PS:
11181        check_ps(ctx);
11182        {
11183            TCGv_i64 fp0 = tcg_temp_new_i64();
11184
11185            gen_load_fpr64(ctx, fp0, fs);
11186            gen_helper_float_rsqrt1_ps(fp0, cpu_env, fp0);
11187            gen_store_fpr64(ctx, fp0, fd);
11188            tcg_temp_free_i64(fp0);
11189        }
11190        break;
11191    case OPC_RSQRT2_PS:
11192        check_ps(ctx);
11193        {
11194            TCGv_i64 fp0 = tcg_temp_new_i64();
11195            TCGv_i64 fp1 = tcg_temp_new_i64();
11196
11197            gen_load_fpr64(ctx, fp0, fs);
11198            gen_load_fpr64(ctx, fp1, ft);
11199            gen_helper_float_rsqrt2_ps(fp0, cpu_env, fp0, fp1);
11200            tcg_temp_free_i64(fp1);
11201            gen_store_fpr64(ctx, fp0, fd);
11202            tcg_temp_free_i64(fp0);
11203        }
11204        break;
11205    case OPC_CVT_S_PU:
11206        check_cp1_64bitmode(ctx);
11207        {
11208            TCGv_i32 fp0 = tcg_temp_new_i32();
11209
11210            gen_load_fpr32h(ctx, fp0, fs);
11211            gen_helper_float_cvts_pu(fp0, cpu_env, fp0);
11212            gen_store_fpr32(ctx, fp0, fd);
11213            tcg_temp_free_i32(fp0);
11214        }
11215        break;
11216    case OPC_CVT_PW_PS:
11217        check_ps(ctx);
11218        {
11219            TCGv_i64 fp0 = tcg_temp_new_i64();
11220
11221            gen_load_fpr64(ctx, fp0, fs);
11222            gen_helper_float_cvtpw_ps(fp0, cpu_env, fp0);
11223            gen_store_fpr64(ctx, fp0, fd);
11224            tcg_temp_free_i64(fp0);
11225        }
11226        break;
11227    case OPC_CVT_S_PL:
11228        check_cp1_64bitmode(ctx);
11229        {
11230            TCGv_i32 fp0 = tcg_temp_new_i32();
11231
11232            gen_load_fpr32(ctx, fp0, fs);
11233            gen_helper_float_cvts_pl(fp0, cpu_env, fp0);
11234            gen_store_fpr32(ctx, fp0, fd);
11235            tcg_temp_free_i32(fp0);
11236        }
11237        break;
11238    case OPC_PLL_PS:
11239        check_ps(ctx);
11240        {
11241            TCGv_i32 fp0 = tcg_temp_new_i32();
11242            TCGv_i32 fp1 = tcg_temp_new_i32();
11243
11244            gen_load_fpr32(ctx, fp0, fs);
11245            gen_load_fpr32(ctx, fp1, ft);
11246            gen_store_fpr32h(ctx, fp0, fd);
11247            gen_store_fpr32(ctx, fp1, fd);
11248            tcg_temp_free_i32(fp0);
11249            tcg_temp_free_i32(fp1);
11250        }
11251        break;
11252    case OPC_PLU_PS:
11253        check_ps(ctx);
11254        {
11255            TCGv_i32 fp0 = tcg_temp_new_i32();
11256            TCGv_i32 fp1 = tcg_temp_new_i32();
11257
11258            gen_load_fpr32(ctx, fp0, fs);
11259            gen_load_fpr32h(ctx, fp1, ft);
11260            gen_store_fpr32(ctx, fp1, fd);
11261            gen_store_fpr32h(ctx, fp0, fd);
11262            tcg_temp_free_i32(fp0);
11263            tcg_temp_free_i32(fp1);
11264        }
11265        break;
11266    case OPC_PUL_PS:
11267        check_ps(ctx);
11268        {
11269            TCGv_i32 fp0 = tcg_temp_new_i32();
11270            TCGv_i32 fp1 = tcg_temp_new_i32();
11271
11272            gen_load_fpr32h(ctx, fp0, fs);
11273            gen_load_fpr32(ctx, fp1, ft);
11274            gen_store_fpr32(ctx, fp1, fd);
11275            gen_store_fpr32h(ctx, fp0, fd);
11276            tcg_temp_free_i32(fp0);
11277            tcg_temp_free_i32(fp1);
11278        }
11279        break;
11280    case OPC_PUU_PS:
11281        check_ps(ctx);
11282        {
11283            TCGv_i32 fp0 = tcg_temp_new_i32();
11284            TCGv_i32 fp1 = tcg_temp_new_i32();
11285
11286            gen_load_fpr32h(ctx, fp0, fs);
11287            gen_load_fpr32h(ctx, fp1, ft);
11288            gen_store_fpr32(ctx, fp1, fd);
11289            gen_store_fpr32h(ctx, fp0, fd);
11290            tcg_temp_free_i32(fp0);
11291            tcg_temp_free_i32(fp1);
11292        }
11293        break;
11294    case OPC_CMP_F_PS:
11295    case OPC_CMP_UN_PS:
11296    case OPC_CMP_EQ_PS:
11297    case OPC_CMP_UEQ_PS:
11298    case OPC_CMP_OLT_PS:
11299    case OPC_CMP_ULT_PS:
11300    case OPC_CMP_OLE_PS:
11301    case OPC_CMP_ULE_PS:
11302    case OPC_CMP_SF_PS:
11303    case OPC_CMP_NGLE_PS:
11304    case OPC_CMP_SEQ_PS:
11305    case OPC_CMP_NGL_PS:
11306    case OPC_CMP_LT_PS:
11307    case OPC_CMP_NGE_PS:
11308    case OPC_CMP_LE_PS:
11309    case OPC_CMP_NGT_PS:
11310        if (ctx->opcode & (1 << 6)) {
11311            gen_cmpabs_ps(ctx, func - 48, ft, fs, cc);
11312        } else {
11313            gen_cmp_ps(ctx, func - 48, ft, fs, cc);
11314        }
11315        break;
11316    default:
11317        MIPS_INVAL("farith");
11318        gen_reserved_instruction(ctx);
11319        return;
11320    }
11321}
11322
11323/* Coprocessor 3 (FPU) */
11324static void gen_flt3_ldst(DisasContext *ctx, uint32_t opc,
11325                          int fd, int fs, int base, int index)
11326{
11327    TCGv t0 = tcg_temp_new();
11328
11329    if (base == 0) {
11330        gen_load_gpr(t0, index);
11331    } else if (index == 0) {
11332        gen_load_gpr(t0, base);
11333    } else {
11334        gen_op_addr_add(ctx, t0, cpu_gpr[base], cpu_gpr[index]);
11335    }
11336    /*
11337     * Don't do NOP if destination is zero: we must perform the actual
11338     * memory access.
11339     */
11340    switch (opc) {
11341    case OPC_LWXC1:
11342        check_cop1x(ctx);
11343        {
11344            TCGv_i32 fp0 = tcg_temp_new_i32();
11345
11346            tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TESL);
11347            tcg_gen_trunc_tl_i32(fp0, t0);
11348            gen_store_fpr32(ctx, fp0, fd);
11349            tcg_temp_free_i32(fp0);
11350        }
11351        break;
11352    case OPC_LDXC1:
11353        check_cop1x(ctx);
11354        check_cp1_registers(ctx, fd);
11355        {
11356            TCGv_i64 fp0 = tcg_temp_new_i64();
11357            tcg_gen_qemu_ld_i64(fp0, t0, ctx->mem_idx, MO_TEUQ);
11358            gen_store_fpr64(ctx, fp0, fd);
11359            tcg_temp_free_i64(fp0);
11360        }
11361        break;
11362    case OPC_LUXC1:
11363        check_cp1_64bitmode(ctx);
11364        tcg_gen_andi_tl(t0, t0, ~0x7);
11365        {
11366            TCGv_i64 fp0 = tcg_temp_new_i64();
11367
11368            tcg_gen_qemu_ld_i64(fp0, t0, ctx->mem_idx, MO_TEUQ);
11369            gen_store_fpr64(ctx, fp0, fd);
11370            tcg_temp_free_i64(fp0);
11371        }
11372        break;
11373    case OPC_SWXC1:
11374        check_cop1x(ctx);
11375        {
11376            TCGv_i32 fp0 = tcg_temp_new_i32();
11377            gen_load_fpr32(ctx, fp0, fs);
11378            tcg_gen_qemu_st_i32(fp0, t0, ctx->mem_idx, MO_TEUL);
11379            tcg_temp_free_i32(fp0);
11380        }
11381        break;
11382    case OPC_SDXC1:
11383        check_cop1x(ctx);
11384        check_cp1_registers(ctx, fs);
11385        {
11386            TCGv_i64 fp0 = tcg_temp_new_i64();
11387            gen_load_fpr64(ctx, fp0, fs);
11388            tcg_gen_qemu_st_i64(fp0, t0, ctx->mem_idx, MO_TEUQ);
11389            tcg_temp_free_i64(fp0);
11390        }
11391        break;
11392    case OPC_SUXC1:
11393        check_cp1_64bitmode(ctx);
11394        tcg_gen_andi_tl(t0, t0, ~0x7);
11395        {
11396            TCGv_i64 fp0 = tcg_temp_new_i64();
11397            gen_load_fpr64(ctx, fp0, fs);
11398            tcg_gen_qemu_st_i64(fp0, t0, ctx->mem_idx, MO_TEUQ);
11399            tcg_temp_free_i64(fp0);
11400        }
11401        break;
11402    }
11403    tcg_temp_free(t0);
11404}
11405
11406static void gen_flt3_arith(DisasContext *ctx, uint32_t opc,
11407                           int fd, int fr, int fs, int ft)
11408{
11409    switch (opc) {
11410    case OPC_ALNV_PS:
11411        check_ps(ctx);
11412        {
11413            TCGv t0 = tcg_temp_local_new();
11414            TCGv_i32 fp = tcg_temp_new_i32();
11415            TCGv_i32 fph = tcg_temp_new_i32();
11416            TCGLabel *l1 = gen_new_label();
11417            TCGLabel *l2 = gen_new_label();
11418
11419            gen_load_gpr(t0, fr);
11420            tcg_gen_andi_tl(t0, t0, 0x7);
11421
11422            tcg_gen_brcondi_tl(TCG_COND_NE, t0, 0, l1);
11423            gen_load_fpr32(ctx, fp, fs);
11424            gen_load_fpr32h(ctx, fph, fs);
11425            gen_store_fpr32(ctx, fp, fd);
11426            gen_store_fpr32h(ctx, fph, fd);
11427            tcg_gen_br(l2);
11428            gen_set_label(l1);
11429            tcg_gen_brcondi_tl(TCG_COND_NE, t0, 4, l2);
11430            tcg_temp_free(t0);
11431            if (cpu_is_bigendian(ctx)) {
11432                gen_load_fpr32(ctx, fp, fs);
11433                gen_load_fpr32h(ctx, fph, ft);
11434                gen_store_fpr32h(ctx, fp, fd);
11435                gen_store_fpr32(ctx, fph, fd);
11436            } else {
11437                gen_load_fpr32h(ctx, fph, fs);
11438                gen_load_fpr32(ctx, fp, ft);
11439                gen_store_fpr32(ctx, fph, fd);
11440                gen_store_fpr32h(ctx, fp, fd);
11441            }
11442            gen_set_label(l2);
11443            tcg_temp_free_i32(fp);
11444            tcg_temp_free_i32(fph);
11445        }
11446        break;
11447    case OPC_MADD_S:
11448        check_cop1x(ctx);
11449        {
11450            TCGv_i32 fp0 = tcg_temp_new_i32();
11451            TCGv_i32 fp1 = tcg_temp_new_i32();
11452            TCGv_i32 fp2 = tcg_temp_new_i32();
11453
11454            gen_load_fpr32(ctx, fp0, fs);
11455            gen_load_fpr32(ctx, fp1, ft);
11456            gen_load_fpr32(ctx, fp2, fr);
11457            gen_helper_float_madd_s(fp2, cpu_env, fp0, fp1, fp2);
11458            tcg_temp_free_i32(fp0);
11459            tcg_temp_free_i32(fp1);
11460            gen_store_fpr32(ctx, fp2, fd);
11461            tcg_temp_free_i32(fp2);
11462        }
11463        break;
11464    case OPC_MADD_D:
11465        check_cop1x(ctx);
11466        check_cp1_registers(ctx, fd | fs | ft | fr);
11467        {
11468            TCGv_i64 fp0 = tcg_temp_new_i64();
11469            TCGv_i64 fp1 = tcg_temp_new_i64();
11470            TCGv_i64 fp2 = tcg_temp_new_i64();
11471
11472            gen_load_fpr64(ctx, fp0, fs);
11473            gen_load_fpr64(ctx, fp1, ft);
11474            gen_load_fpr64(ctx, fp2, fr);
11475            gen_helper_float_madd_d(fp2, cpu_env, fp0, fp1, fp2);
11476            tcg_temp_free_i64(fp0);
11477            tcg_temp_free_i64(fp1);
11478            gen_store_fpr64(ctx, fp2, fd);
11479            tcg_temp_free_i64(fp2);
11480        }
11481        break;
11482    case OPC_MADD_PS:
11483        check_ps(ctx);
11484        {
11485            TCGv_i64 fp0 = tcg_temp_new_i64();
11486            TCGv_i64 fp1 = tcg_temp_new_i64();
11487            TCGv_i64 fp2 = tcg_temp_new_i64();
11488
11489            gen_load_fpr64(ctx, fp0, fs);
11490            gen_load_fpr64(ctx, fp1, ft);
11491            gen_load_fpr64(ctx, fp2, fr);
11492            gen_helper_float_madd_ps(fp2, cpu_env, fp0, fp1, fp2);
11493            tcg_temp_free_i64(fp0);
11494            tcg_temp_free_i64(fp1);
11495            gen_store_fpr64(ctx, fp2, fd);
11496            tcg_temp_free_i64(fp2);
11497        }
11498        break;
11499    case OPC_MSUB_S:
11500        check_cop1x(ctx);
11501        {
11502            TCGv_i32 fp0 = tcg_temp_new_i32();
11503            TCGv_i32 fp1 = tcg_temp_new_i32();
11504            TCGv_i32 fp2 = tcg_temp_new_i32();
11505
11506            gen_load_fpr32(ctx, fp0, fs);
11507            gen_load_fpr32(ctx, fp1, ft);
11508            gen_load_fpr32(ctx, fp2, fr);
11509            gen_helper_float_msub_s(fp2, cpu_env, fp0, fp1, fp2);
11510            tcg_temp_free_i32(fp0);
11511            tcg_temp_free_i32(fp1);
11512            gen_store_fpr32(ctx, fp2, fd);
11513            tcg_temp_free_i32(fp2);
11514        }
11515        break;
11516    case OPC_MSUB_D:
11517        check_cop1x(ctx);
11518        check_cp1_registers(ctx, fd | fs | ft | fr);
11519        {
11520            TCGv_i64 fp0 = tcg_temp_new_i64();
11521            TCGv_i64 fp1 = tcg_temp_new_i64();
11522            TCGv_i64 fp2 = tcg_temp_new_i64();
11523
11524            gen_load_fpr64(ctx, fp0, fs);
11525            gen_load_fpr64(ctx, fp1, ft);
11526            gen_load_fpr64(ctx, fp2, fr);
11527            gen_helper_float_msub_d(fp2, cpu_env, fp0, fp1, fp2);
11528            tcg_temp_free_i64(fp0);
11529            tcg_temp_free_i64(fp1);
11530            gen_store_fpr64(ctx, fp2, fd);
11531            tcg_temp_free_i64(fp2);
11532        }
11533        break;
11534    case OPC_MSUB_PS:
11535        check_ps(ctx);
11536        {
11537            TCGv_i64 fp0 = tcg_temp_new_i64();
11538            TCGv_i64 fp1 = tcg_temp_new_i64();
11539            TCGv_i64 fp2 = tcg_temp_new_i64();
11540
11541            gen_load_fpr64(ctx, fp0, fs);
11542            gen_load_fpr64(ctx, fp1, ft);
11543            gen_load_fpr64(ctx, fp2, fr);
11544            gen_helper_float_msub_ps(fp2, cpu_env, fp0, fp1, fp2);
11545            tcg_temp_free_i64(fp0);
11546            tcg_temp_free_i64(fp1);
11547            gen_store_fpr64(ctx, fp2, fd);
11548            tcg_temp_free_i64(fp2);
11549        }
11550        break;
11551    case OPC_NMADD_S:
11552        check_cop1x(ctx);
11553        {
11554            TCGv_i32 fp0 = tcg_temp_new_i32();
11555            TCGv_i32 fp1 = tcg_temp_new_i32();
11556            TCGv_i32 fp2 = tcg_temp_new_i32();
11557
11558            gen_load_fpr32(ctx, fp0, fs);
11559            gen_load_fpr32(ctx, fp1, ft);
11560            gen_load_fpr32(ctx, fp2, fr);
11561            gen_helper_float_nmadd_s(fp2, cpu_env, fp0, fp1, fp2);
11562            tcg_temp_free_i32(fp0);
11563            tcg_temp_free_i32(fp1);
11564            gen_store_fpr32(ctx, fp2, fd);
11565            tcg_temp_free_i32(fp2);
11566        }
11567        break;
11568    case OPC_NMADD_D:
11569        check_cop1x(ctx);
11570        check_cp1_registers(ctx, fd | fs | ft | fr);
11571        {
11572            TCGv_i64 fp0 = tcg_temp_new_i64();
11573            TCGv_i64 fp1 = tcg_temp_new_i64();
11574            TCGv_i64 fp2 = tcg_temp_new_i64();
11575
11576            gen_load_fpr64(ctx, fp0, fs);
11577            gen_load_fpr64(ctx, fp1, ft);
11578            gen_load_fpr64(ctx, fp2, fr);
11579            gen_helper_float_nmadd_d(fp2, cpu_env, fp0, fp1, fp2);
11580            tcg_temp_free_i64(fp0);
11581            tcg_temp_free_i64(fp1);
11582            gen_store_fpr64(ctx, fp2, fd);
11583            tcg_temp_free_i64(fp2);
11584        }
11585        break;
11586    case OPC_NMADD_PS:
11587        check_ps(ctx);
11588        {
11589            TCGv_i64 fp0 = tcg_temp_new_i64();
11590            TCGv_i64 fp1 = tcg_temp_new_i64();
11591            TCGv_i64 fp2 = tcg_temp_new_i64();
11592
11593            gen_load_fpr64(ctx, fp0, fs);
11594            gen_load_fpr64(ctx, fp1, ft);
11595            gen_load_fpr64(ctx, fp2, fr);
11596            gen_helper_float_nmadd_ps(fp2, cpu_env, fp0, fp1, fp2);
11597            tcg_temp_free_i64(fp0);
11598            tcg_temp_free_i64(fp1);
11599            gen_store_fpr64(ctx, fp2, fd);
11600            tcg_temp_free_i64(fp2);
11601        }
11602        break;
11603    case OPC_NMSUB_S:
11604        check_cop1x(ctx);
11605        {
11606            TCGv_i32 fp0 = tcg_temp_new_i32();
11607            TCGv_i32 fp1 = tcg_temp_new_i32();
11608            TCGv_i32 fp2 = tcg_temp_new_i32();
11609
11610            gen_load_fpr32(ctx, fp0, fs);
11611            gen_load_fpr32(ctx, fp1, ft);
11612            gen_load_fpr32(ctx, fp2, fr);
11613            gen_helper_float_nmsub_s(fp2, cpu_env, fp0, fp1, fp2);
11614            tcg_temp_free_i32(fp0);
11615            tcg_temp_free_i32(fp1);
11616            gen_store_fpr32(ctx, fp2, fd);
11617            tcg_temp_free_i32(fp2);
11618        }
11619        break;
11620    case OPC_NMSUB_D:
11621        check_cop1x(ctx);
11622        check_cp1_registers(ctx, fd | fs | ft | fr);
11623        {
11624            TCGv_i64 fp0 = tcg_temp_new_i64();
11625            TCGv_i64 fp1 = tcg_temp_new_i64();
11626            TCGv_i64 fp2 = tcg_temp_new_i64();
11627
11628            gen_load_fpr64(ctx, fp0, fs);
11629            gen_load_fpr64(ctx, fp1, ft);
11630            gen_load_fpr64(ctx, fp2, fr);
11631            gen_helper_float_nmsub_d(fp2, cpu_env, fp0, fp1, fp2);
11632            tcg_temp_free_i64(fp0);
11633            tcg_temp_free_i64(fp1);
11634            gen_store_fpr64(ctx, fp2, fd);
11635            tcg_temp_free_i64(fp2);
11636        }
11637        break;
11638    case OPC_NMSUB_PS:
11639        check_ps(ctx);
11640        {
11641            TCGv_i64 fp0 = tcg_temp_new_i64();
11642            TCGv_i64 fp1 = tcg_temp_new_i64();
11643            TCGv_i64 fp2 = tcg_temp_new_i64();
11644
11645            gen_load_fpr64(ctx, fp0, fs);
11646            gen_load_fpr64(ctx, fp1, ft);
11647            gen_load_fpr64(ctx, fp2, fr);
11648            gen_helper_float_nmsub_ps(fp2, cpu_env, fp0, fp1, fp2);
11649            tcg_temp_free_i64(fp0);
11650            tcg_temp_free_i64(fp1);
11651            gen_store_fpr64(ctx, fp2, fd);
11652            tcg_temp_free_i64(fp2);
11653        }
11654        break;
11655    default:
11656        MIPS_INVAL("flt3_arith");
11657        gen_reserved_instruction(ctx);
11658        return;
11659    }
11660}
11661
11662void gen_rdhwr(DisasContext *ctx, int rt, int rd, int sel)
11663{
11664    TCGv t0;
11665
11666#if !defined(CONFIG_USER_ONLY)
11667    /*
11668     * The Linux kernel will emulate rdhwr if it's not supported natively.
11669     * Therefore only check the ISA in system mode.
11670     */
11671    check_insn(ctx, ISA_MIPS_R2);
11672#endif
11673    t0 = tcg_temp_new();
11674
11675    switch (rd) {
11676    case 0:
11677        gen_helper_rdhwr_cpunum(t0, cpu_env);
11678        gen_store_gpr(t0, rt);
11679        break;
11680    case 1:
11681        gen_helper_rdhwr_synci_step(t0, cpu_env);
11682        gen_store_gpr(t0, rt);
11683        break;
11684    case 2:
11685        if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
11686            gen_io_start();
11687        }
11688        gen_helper_rdhwr_cc(t0, cpu_env);
11689        gen_store_gpr(t0, rt);
11690        /*
11691         * Break the TB to be able to take timer interrupts immediately
11692         * after reading count. DISAS_STOP isn't sufficient, we need to ensure
11693         * we break completely out of translated code.
11694         */
11695        gen_save_pc(ctx->base.pc_next + 4);
11696        ctx->base.is_jmp = DISAS_EXIT;
11697        break;
11698    case 3:
11699        gen_helper_rdhwr_ccres(t0, cpu_env);
11700        gen_store_gpr(t0, rt);
11701        break;
11702    case 4:
11703        check_insn(ctx, ISA_MIPS_R6);
11704        if (sel != 0) {
11705            /*
11706             * Performance counter registers are not implemented other than
11707             * control register 0.
11708             */
11709            generate_exception(ctx, EXCP_RI);
11710        }
11711        gen_helper_rdhwr_performance(t0, cpu_env);
11712        gen_store_gpr(t0, rt);
11713        break;
11714    case 5:
11715        check_insn(ctx, ISA_MIPS_R6);
11716        gen_helper_rdhwr_xnp(t0, cpu_env);
11717        gen_store_gpr(t0, rt);
11718        break;
11719    case 29:
11720#if defined(CONFIG_USER_ONLY)
11721        tcg_gen_ld_tl(t0, cpu_env,
11722                      offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
11723        gen_store_gpr(t0, rt);
11724        break;
11725#else
11726        if ((ctx->hflags & MIPS_HFLAG_CP0) ||
11727            (ctx->hflags & MIPS_HFLAG_HWRENA_ULR)) {
11728            tcg_gen_ld_tl(t0, cpu_env,
11729                          offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
11730            gen_store_gpr(t0, rt);
11731        } else {
11732            gen_reserved_instruction(ctx);
11733        }
11734        break;
11735#endif
11736    default:            /* Invalid */
11737        MIPS_INVAL("rdhwr");
11738        gen_reserved_instruction(ctx);
11739        break;
11740    }
11741    tcg_temp_free(t0);
11742}
11743
11744static inline void clear_branch_hflags(DisasContext *ctx)
11745{
11746    ctx->hflags &= ~MIPS_HFLAG_BMASK;
11747    if (ctx->base.is_jmp == DISAS_NEXT) {
11748        save_cpu_state(ctx, 0);
11749    } else {
11750        /*
11751         * It is not safe to save ctx->hflags as hflags may be changed
11752         * in execution time by the instruction in delay / forbidden slot.
11753         */
11754        tcg_gen_andi_i32(hflags, hflags, ~MIPS_HFLAG_BMASK);
11755    }
11756}
11757
11758static void gen_branch(DisasContext *ctx, int insn_bytes)
11759{
11760    if (ctx->hflags & MIPS_HFLAG_BMASK) {
11761        int proc_hflags = ctx->hflags & MIPS_HFLAG_BMASK;
11762        /* Branches completion */
11763        clear_branch_hflags(ctx);
11764        ctx->base.is_jmp = DISAS_NORETURN;
11765        /* FIXME: Need to clear can_do_io.  */
11766        switch (proc_hflags & MIPS_HFLAG_BMASK_BASE) {
11767        case MIPS_HFLAG_FBNSLOT:
11768            gen_goto_tb(ctx, 0, ctx->base.pc_next + insn_bytes);
11769            break;
11770        case MIPS_HFLAG_B:
11771            /* unconditional branch */
11772            if (proc_hflags & MIPS_HFLAG_BX) {
11773                tcg_gen_xori_i32(hflags, hflags, MIPS_HFLAG_M16);
11774            }
11775            gen_goto_tb(ctx, 0, ctx->btarget);
11776            break;
11777        case MIPS_HFLAG_BL:
11778            /* blikely taken case */
11779            gen_goto_tb(ctx, 0, ctx->btarget);
11780            break;
11781        case MIPS_HFLAG_BC:
11782            /* Conditional branch */
11783            {
11784                TCGLabel *l1 = gen_new_label();
11785
11786                tcg_gen_brcondi_tl(TCG_COND_NE, bcond, 0, l1);
11787                gen_goto_tb(ctx, 1, ctx->base.pc_next + insn_bytes);
11788                gen_set_label(l1);
11789                gen_goto_tb(ctx, 0, ctx->btarget);
11790            }
11791            break;
11792        case MIPS_HFLAG_BR:
11793            /* unconditional branch to register */
11794            if (ctx->insn_flags & (ASE_MIPS16 | ASE_MICROMIPS)) {
11795                TCGv t0 = tcg_temp_new();
11796                TCGv_i32 t1 = tcg_temp_new_i32();
11797
11798                tcg_gen_andi_tl(t0, btarget, 0x1);
11799                tcg_gen_trunc_tl_i32(t1, t0);
11800                tcg_temp_free(t0);
11801                tcg_gen_andi_i32(hflags, hflags, ~(uint32_t)MIPS_HFLAG_M16);
11802                tcg_gen_shli_i32(t1, t1, MIPS_HFLAG_M16_SHIFT);
11803                tcg_gen_or_i32(hflags, hflags, t1);
11804                tcg_temp_free_i32(t1);
11805
11806                tcg_gen_andi_tl(cpu_PC, btarget, ~(target_ulong)0x1);
11807            } else {
11808                tcg_gen_mov_tl(cpu_PC, btarget);
11809            }
11810            tcg_gen_lookup_and_goto_ptr();
11811            break;
11812        default:
11813            LOG_DISAS("unknown branch 0x%x\n", proc_hflags);
11814            gen_reserved_instruction(ctx);
11815        }
11816    }
11817}
11818
11819/* Compact Branches */
11820static void gen_compute_compact_branch(DisasContext *ctx, uint32_t opc,
11821                                       int rs, int rt, int32_t offset)
11822{
11823    int bcond_compute = 0;
11824    TCGv t0 = tcg_temp_new();
11825    TCGv t1 = tcg_temp_new();
11826    int m16_lowbit = (ctx->hflags & MIPS_HFLAG_M16) != 0;
11827
11828    if (ctx->hflags & MIPS_HFLAG_BMASK) {
11829#ifdef MIPS_DEBUG_DISAS
11830        LOG_DISAS("Branch in delay / forbidden slot at PC 0x" TARGET_FMT_lx
11831                  "\n", ctx->base.pc_next);
11832#endif
11833        gen_reserved_instruction(ctx);
11834        goto out;
11835    }
11836
11837    /* Load needed operands and calculate btarget */
11838    switch (opc) {
11839    /* compact branch */
11840    case OPC_BOVC: /* OPC_BEQZALC, OPC_BEQC */
11841    case OPC_BNVC: /* OPC_BNEZALC, OPC_BNEC */
11842        gen_load_gpr(t0, rs);
11843        gen_load_gpr(t1, rt);
11844        bcond_compute = 1;
11845        ctx->btarget = addr_add(ctx, ctx->base.pc_next + 4, offset);
11846        if (rs <= rt && rs == 0) {
11847            /* OPC_BEQZALC, OPC_BNEZALC */
11848            tcg_gen_movi_tl(cpu_gpr[31], ctx->base.pc_next + 4 + m16_lowbit);
11849        }
11850        break;
11851    case OPC_BLEZC: /* OPC_BGEZC, OPC_BGEC */
11852    case OPC_BGTZC: /* OPC_BLTZC, OPC_BLTC */
11853        gen_load_gpr(t0, rs);
11854        gen_load_gpr(t1, rt);
11855        bcond_compute = 1;
11856        ctx->btarget = addr_add(ctx, ctx->base.pc_next + 4, offset);
11857        break;
11858    case OPC_BLEZALC: /* OPC_BGEZALC, OPC_BGEUC */
11859    case OPC_BGTZALC: /* OPC_BLTZALC, OPC_BLTUC */
11860        if (rs == 0 || rs == rt) {
11861            /* OPC_BLEZALC, OPC_BGEZALC */
11862            /* OPC_BGTZALC, OPC_BLTZALC */
11863            tcg_gen_movi_tl(cpu_gpr[31], ctx->base.pc_next + 4 + m16_lowbit);
11864        }
11865        gen_load_gpr(t0, rs);
11866        gen_load_gpr(t1, rt);
11867        bcond_compute = 1;
11868        ctx->btarget = addr_add(ctx, ctx->base.pc_next + 4, offset);
11869        break;
11870    case OPC_BC:
11871    case OPC_BALC:
11872        ctx->btarget = addr_add(ctx, ctx->base.pc_next + 4, offset);
11873        break;
11874    case OPC_BEQZC:
11875    case OPC_BNEZC:
11876        if (rs != 0) {
11877            /* OPC_BEQZC, OPC_BNEZC */
11878            gen_load_gpr(t0, rs);
11879            bcond_compute = 1;
11880            ctx->btarget = addr_add(ctx, ctx->base.pc_next + 4, offset);
11881        } else {
11882            /* OPC_JIC, OPC_JIALC */
11883            TCGv tbase = tcg_temp_new();
11884            TCGv toffset = tcg_constant_tl(offset);
11885
11886            gen_load_gpr(tbase, rt);
11887            gen_op_addr_add(ctx, btarget, tbase, toffset);
11888            tcg_temp_free(tbase);
11889        }
11890        break;
11891    default:
11892        MIPS_INVAL("Compact branch/jump");
11893        gen_reserved_instruction(ctx);
11894        goto out;
11895    }
11896
11897    if (bcond_compute == 0) {
11898        /* Unconditional compact branch */
11899        switch (opc) {
11900        case OPC_JIALC:
11901            tcg_gen_movi_tl(cpu_gpr[31], ctx->base.pc_next + 4 + m16_lowbit);
11902            /* Fallthrough */
11903        case OPC_JIC:
11904            ctx->hflags |= MIPS_HFLAG_BR;
11905            break;
11906        case OPC_BALC:
11907            tcg_gen_movi_tl(cpu_gpr[31], ctx->base.pc_next + 4 + m16_lowbit);
11908            /* Fallthrough */
11909        case OPC_BC:
11910            ctx->hflags |= MIPS_HFLAG_B;
11911            break;
11912        default:
11913            MIPS_INVAL("Compact branch/jump");
11914            gen_reserved_instruction(ctx);
11915            goto out;
11916        }
11917
11918        /* Generating branch here as compact branches don't have delay slot */
11919        gen_branch(ctx, 4);
11920    } else {
11921        /* Conditional compact branch */
11922        TCGLabel *fs = gen_new_label();
11923        save_cpu_state(ctx, 0);
11924
11925        switch (opc) {
11926        case OPC_BLEZALC: /* OPC_BGEZALC, OPC_BGEUC */
11927            if (rs == 0 && rt != 0) {
11928                /* OPC_BLEZALC */
11929                tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LE), t1, 0, fs);
11930            } else if (rs != 0 && rt != 0 && rs == rt) {
11931                /* OPC_BGEZALC */
11932                tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GE), t1, 0, fs);
11933            } else {
11934                /* OPC_BGEUC */
11935                tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_GEU), t0, t1, fs);
11936            }
11937            break;
11938        case OPC_BGTZALC: /* OPC_BLTZALC, OPC_BLTUC */
11939            if (rs == 0 && rt != 0) {
11940                /* OPC_BGTZALC */
11941                tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GT), t1, 0, fs);
11942            } else if (rs != 0 && rt != 0 && rs == rt) {
11943                /* OPC_BLTZALC */
11944                tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LT), t1, 0, fs);
11945            } else {
11946                /* OPC_BLTUC */
11947                tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_LTU), t0, t1, fs);
11948            }
11949            break;
11950        case OPC_BLEZC: /* OPC_BGEZC, OPC_BGEC */
11951            if (rs == 0 && rt != 0) {
11952                /* OPC_BLEZC */
11953                tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LE), t1, 0, fs);
11954            } else if (rs != 0 && rt != 0 && rs == rt) {
11955                /* OPC_BGEZC */
11956                tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GE), t1, 0, fs);
11957            } else {
11958                /* OPC_BGEC */
11959                tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_GE), t0, t1, fs);
11960            }
11961            break;
11962        case OPC_BGTZC: /* OPC_BLTZC, OPC_BLTC */
11963            if (rs == 0 && rt != 0) {
11964                /* OPC_BGTZC */
11965                tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GT), t1, 0, fs);
11966            } else if (rs != 0 && rt != 0 && rs == rt) {
11967                /* OPC_BLTZC */
11968                tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LT), t1, 0, fs);
11969            } else {
11970                /* OPC_BLTC */
11971                tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_LT), t0, t1, fs);
11972            }
11973            break;
11974        case OPC_BOVC: /* OPC_BEQZALC, OPC_BEQC */
11975        case OPC_BNVC: /* OPC_BNEZALC, OPC_BNEC */
11976            if (rs >= rt) {
11977                /* OPC_BOVC, OPC_BNVC */
11978                TCGv t2 = tcg_temp_new();
11979                TCGv t3 = tcg_temp_new();
11980                TCGv t4 = tcg_temp_new();
11981                TCGv input_overflow = tcg_temp_new();
11982
11983                gen_load_gpr(t0, rs);
11984                gen_load_gpr(t1, rt);
11985                tcg_gen_ext32s_tl(t2, t0);
11986                tcg_gen_setcond_tl(TCG_COND_NE, input_overflow, t2, t0);
11987                tcg_gen_ext32s_tl(t3, t1);
11988                tcg_gen_setcond_tl(TCG_COND_NE, t4, t3, t1);
11989                tcg_gen_or_tl(input_overflow, input_overflow, t4);
11990
11991                tcg_gen_add_tl(t4, t2, t3);
11992                tcg_gen_ext32s_tl(t4, t4);
11993                tcg_gen_xor_tl(t2, t2, t3);
11994                tcg_gen_xor_tl(t3, t4, t3);
11995                tcg_gen_andc_tl(t2, t3, t2);
11996                tcg_gen_setcondi_tl(TCG_COND_LT, t4, t2, 0);
11997                tcg_gen_or_tl(t4, t4, input_overflow);
11998                if (opc == OPC_BOVC) {
11999                    /* OPC_BOVC */
12000                    tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_NE), t4, 0, fs);
12001                } else {
12002                    /* OPC_BNVC */
12003                    tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_EQ), t4, 0, fs);
12004                }
12005                tcg_temp_free(input_overflow);
12006                tcg_temp_free(t4);
12007                tcg_temp_free(t3);
12008                tcg_temp_free(t2);
12009            } else if (rs < rt && rs == 0) {
12010                /* OPC_BEQZALC, OPC_BNEZALC */
12011                if (opc == OPC_BEQZALC) {
12012                    /* OPC_BEQZALC */
12013                    tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_EQ), t1, 0, fs);
12014                } else {
12015                    /* OPC_BNEZALC */
12016                    tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_NE), t1, 0, fs);
12017                }
12018            } else {
12019                /* OPC_BEQC, OPC_BNEC */
12020                if (opc == OPC_BEQC) {
12021                    /* OPC_BEQC */
12022                    tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_EQ), t0, t1, fs);
12023                } else {
12024                    /* OPC_BNEC */
12025                    tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_NE), t0, t1, fs);
12026                }
12027            }
12028            break;
12029        case OPC_BEQZC:
12030            tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_EQ), t0, 0, fs);
12031            break;
12032        case OPC_BNEZC:
12033            tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_NE), t0, 0, fs);
12034            break;
12035        default:
12036            MIPS_INVAL("Compact conditional branch/jump");
12037            gen_reserved_instruction(ctx);
12038            goto out;
12039        }
12040
12041        /* Generating branch here as compact branches don't have delay slot */
12042        gen_goto_tb(ctx, 1, ctx->btarget);
12043        gen_set_label(fs);
12044
12045        ctx->hflags |= MIPS_HFLAG_FBNSLOT;
12046    }
12047
12048out:
12049    tcg_temp_free(t0);
12050    tcg_temp_free(t1);
12051}
12052
12053void gen_addiupc(DisasContext *ctx, int rx, int imm,
12054                 int is_64_bit, int extended)
12055{
12056    TCGv t0;
12057
12058    if (extended && (ctx->hflags & MIPS_HFLAG_BMASK)) {
12059        gen_reserved_instruction(ctx);
12060        return;
12061    }
12062
12063    t0 = tcg_temp_new();
12064
12065    tcg_gen_movi_tl(t0, pc_relative_pc(ctx));
12066    tcg_gen_addi_tl(cpu_gpr[rx], t0, imm);
12067    if (!is_64_bit) {
12068        tcg_gen_ext32s_tl(cpu_gpr[rx], cpu_gpr[rx]);
12069    }
12070
12071    tcg_temp_free(t0);
12072}
12073
12074static void gen_cache_operation(DisasContext *ctx, uint32_t op, int base,
12075                                int16_t offset)
12076{
12077    TCGv_i32 t0 = tcg_const_i32(op);
12078    TCGv t1 = tcg_temp_new();
12079    gen_base_offset_addr(ctx, t1, base, offset);
12080    gen_helper_cache(cpu_env, t1, t0);
12081    tcg_temp_free(t1);
12082    tcg_temp_free_i32(t0);
12083}
12084
12085static inline bool is_uhi(int sdbbp_code)
12086{
12087#ifdef CONFIG_USER_ONLY
12088    return false;
12089#else
12090    return semihosting_enabled() && sdbbp_code == 1;
12091#endif
12092}
12093
12094void gen_ldxs(DisasContext *ctx, int base, int index, int rd)
12095{
12096    TCGv t0 = tcg_temp_new();
12097    TCGv t1 = tcg_temp_new();
12098
12099    gen_load_gpr(t0, base);
12100
12101    if (index != 0) {
12102        gen_load_gpr(t1, index);
12103        tcg_gen_shli_tl(t1, t1, 2);
12104        gen_op_addr_add(ctx, t0, t1, t0);
12105    }
12106
12107    tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TESL);
12108    gen_store_gpr(t1, rd);
12109
12110    tcg_temp_free(t0);
12111    tcg_temp_free(t1);
12112}
12113
12114static void gen_sync(int stype)
12115{
12116    TCGBar tcg_mo = TCG_BAR_SC;
12117
12118    switch (stype) {
12119    case 0x4: /* SYNC_WMB */
12120        tcg_mo |= TCG_MO_ST_ST;
12121        break;
12122    case 0x10: /* SYNC_MB */
12123        tcg_mo |= TCG_MO_ALL;
12124        break;
12125    case 0x11: /* SYNC_ACQUIRE */
12126        tcg_mo |= TCG_MO_LD_LD | TCG_MO_LD_ST;
12127        break;
12128    case 0x12: /* SYNC_RELEASE */
12129        tcg_mo |= TCG_MO_ST_ST | TCG_MO_LD_ST;
12130        break;
12131    case 0x13: /* SYNC_RMB */
12132        tcg_mo |= TCG_MO_LD_LD;
12133        break;
12134    default:
12135        tcg_mo |= TCG_MO_ALL;
12136        break;
12137    }
12138
12139    tcg_gen_mb(tcg_mo);
12140}
12141
12142/* ISA extensions (ASEs) */
12143
12144/* MIPS16 extension to MIPS32 */
12145#include "mips16e_translate.c.inc"
12146
12147/* microMIPS extension to MIPS32/MIPS64 */
12148
12149/*
12150 * Values for microMIPS fmt field.  Variable-width, depending on which
12151 * formats the instruction supports.
12152 */
12153enum {
12154    FMT_SD_S = 0,
12155    FMT_SD_D = 1,
12156
12157    FMT_SDPS_S = 0,
12158    FMT_SDPS_D = 1,
12159    FMT_SDPS_PS = 2,
12160
12161    FMT_SWL_S = 0,
12162    FMT_SWL_W = 1,
12163    FMT_SWL_L = 2,
12164
12165    FMT_DWL_D = 0,
12166    FMT_DWL_W = 1,
12167    FMT_DWL_L = 2
12168};
12169
12170#include "micromips_translate.c.inc"
12171
12172#include "nanomips_translate.c.inc"
12173
12174/* MIPSDSP functions. */
12175static void gen_mipsdsp_ld(DisasContext *ctx, uint32_t opc,
12176                           int rd, int base, int offset)
12177{
12178    TCGv t0;
12179
12180    check_dsp(ctx);
12181    t0 = tcg_temp_new();
12182
12183    if (base == 0) {
12184        gen_load_gpr(t0, offset);
12185    } else if (offset == 0) {
12186        gen_load_gpr(t0, base);
12187    } else {
12188        gen_op_addr_add(ctx, t0, cpu_gpr[base], cpu_gpr[offset]);
12189    }
12190
12191    switch (opc) {
12192    case OPC_LBUX:
12193        tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_UB);
12194        gen_store_gpr(t0, rd);
12195        break;
12196    case OPC_LHX:
12197        tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TESW);
12198        gen_store_gpr(t0, rd);
12199        break;
12200    case OPC_LWX:
12201        tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TESL);
12202        gen_store_gpr(t0, rd);
12203        break;
12204#if defined(TARGET_MIPS64)
12205    case OPC_LDX:
12206        tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEUQ);
12207        gen_store_gpr(t0, rd);
12208        break;
12209#endif
12210    }
12211    tcg_temp_free(t0);
12212}
12213
12214static void gen_mipsdsp_arith(DisasContext *ctx, uint32_t op1, uint32_t op2,
12215                              int ret, int v1, int v2)
12216{
12217    TCGv v1_t;
12218    TCGv v2_t;
12219
12220    if (ret == 0) {
12221        /* Treat as NOP. */
12222        return;
12223    }
12224
12225    v1_t = tcg_temp_new();
12226    v2_t = tcg_temp_new();
12227
12228    gen_load_gpr(v1_t, v1);
12229    gen_load_gpr(v2_t, v2);
12230
12231    switch (op1) {
12232    /* OPC_MULT_G_2E is equal OPC_ADDUH_QB_DSP */
12233    case OPC_MULT_G_2E:
12234        check_dsp_r2(ctx);
12235        switch (op2) {
12236        case OPC_ADDUH_QB:
12237            gen_helper_adduh_qb(cpu_gpr[ret], v1_t, v2_t);
12238            break;
12239        case OPC_ADDUH_R_QB:
12240            gen_helper_adduh_r_qb(cpu_gpr[ret], v1_t, v2_t);
12241            break;
12242        case OPC_ADDQH_PH:
12243            gen_helper_addqh_ph(cpu_gpr[ret], v1_t, v2_t);
12244            break;
12245        case OPC_ADDQH_R_PH:
12246            gen_helper_addqh_r_ph(cpu_gpr[ret], v1_t, v2_t);
12247            break;
12248        case OPC_ADDQH_W:
12249            gen_helper_addqh_w(cpu_gpr[ret], v1_t, v2_t);
12250            break;
12251        case OPC_ADDQH_R_W:
12252            gen_helper_addqh_r_w(cpu_gpr[ret], v1_t, v2_t);
12253            break;
12254        case OPC_SUBUH_QB:
12255            gen_helper_subuh_qb(cpu_gpr[ret], v1_t, v2_t);
12256            break;
12257        case OPC_SUBUH_R_QB:
12258            gen_helper_subuh_r_qb(cpu_gpr[ret], v1_t, v2_t);
12259            break;
12260        case OPC_SUBQH_PH:
12261            gen_helper_subqh_ph(cpu_gpr[ret], v1_t, v2_t);
12262            break;
12263        case OPC_SUBQH_R_PH:
12264            gen_helper_subqh_r_ph(cpu_gpr[ret], v1_t, v2_t);
12265            break;
12266        case OPC_SUBQH_W:
12267            gen_helper_subqh_w(cpu_gpr[ret], v1_t, v2_t);
12268            break;
12269        case OPC_SUBQH_R_W:
12270            gen_helper_subqh_r_w(cpu_gpr[ret], v1_t, v2_t);
12271            break;
12272        }
12273        break;
12274    case OPC_ABSQ_S_PH_DSP:
12275        switch (op2) {
12276        case OPC_ABSQ_S_QB:
12277            check_dsp_r2(ctx);
12278            gen_helper_absq_s_qb(cpu_gpr[ret], v2_t, cpu_env);
12279            break;
12280        case OPC_ABSQ_S_PH:
12281            check_dsp(ctx);
12282            gen_helper_absq_s_ph(cpu_gpr[ret], v2_t, cpu_env);
12283            break;
12284        case OPC_ABSQ_S_W:
12285            check_dsp(ctx);
12286            gen_helper_absq_s_w(cpu_gpr[ret], v2_t, cpu_env);
12287            break;
12288        case OPC_PRECEQ_W_PHL:
12289            check_dsp(ctx);
12290            tcg_gen_andi_tl(cpu_gpr[ret], v2_t, 0xFFFF0000);
12291            tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]);
12292            break;
12293        case OPC_PRECEQ_W_PHR:
12294            check_dsp(ctx);
12295            tcg_gen_andi_tl(cpu_gpr[ret], v2_t, 0x0000FFFF);
12296            tcg_gen_shli_tl(cpu_gpr[ret], cpu_gpr[ret], 16);
12297            tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]);
12298            break;
12299        case OPC_PRECEQU_PH_QBL:
12300            check_dsp(ctx);
12301            gen_helper_precequ_ph_qbl(cpu_gpr[ret], v2_t);
12302            break;
12303        case OPC_PRECEQU_PH_QBR:
12304            check_dsp(ctx);
12305            gen_helper_precequ_ph_qbr(cpu_gpr[ret], v2_t);
12306            break;
12307        case OPC_PRECEQU_PH_QBLA:
12308            check_dsp(ctx);
12309            gen_helper_precequ_ph_qbla(cpu_gpr[ret], v2_t);
12310            break;
12311        case OPC_PRECEQU_PH_QBRA:
12312            check_dsp(ctx);
12313            gen_helper_precequ_ph_qbra(cpu_gpr[ret], v2_t);
12314            break;
12315        case OPC_PRECEU_PH_QBL:
12316            check_dsp(ctx);
12317            gen_helper_preceu_ph_qbl(cpu_gpr[ret], v2_t);
12318            break;
12319        case OPC_PRECEU_PH_QBR:
12320            check_dsp(ctx);
12321            gen_helper_preceu_ph_qbr(cpu_gpr[ret], v2_t);
12322            break;
12323        case OPC_PRECEU_PH_QBLA:
12324            check_dsp(ctx);
12325            gen_helper_preceu_ph_qbla(cpu_gpr[ret], v2_t);
12326            break;
12327        case OPC_PRECEU_PH_QBRA:
12328            check_dsp(ctx);
12329            gen_helper_preceu_ph_qbra(cpu_gpr[ret], v2_t);
12330            break;
12331        }
12332        break;
12333    case OPC_ADDU_QB_DSP:
12334        switch (op2) {
12335        case OPC_ADDQ_PH:
12336            check_dsp(ctx);
12337            gen_helper_addq_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12338            break;
12339        case OPC_ADDQ_S_PH:
12340            check_dsp(ctx);
12341            gen_helper_addq_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12342            break;
12343        case OPC_ADDQ_S_W:
12344            check_dsp(ctx);
12345            gen_helper_addq_s_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12346            break;
12347        case OPC_ADDU_QB:
12348            check_dsp(ctx);
12349            gen_helper_addu_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12350            break;
12351        case OPC_ADDU_S_QB:
12352            check_dsp(ctx);
12353            gen_helper_addu_s_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12354            break;
12355        case OPC_ADDU_PH:
12356            check_dsp_r2(ctx);
12357            gen_helper_addu_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12358            break;
12359        case OPC_ADDU_S_PH:
12360            check_dsp_r2(ctx);
12361            gen_helper_addu_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12362            break;
12363        case OPC_SUBQ_PH:
12364            check_dsp(ctx);
12365            gen_helper_subq_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12366            break;
12367        case OPC_SUBQ_S_PH:
12368            check_dsp(ctx);
12369            gen_helper_subq_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12370            break;
12371        case OPC_SUBQ_S_W:
12372            check_dsp(ctx);
12373            gen_helper_subq_s_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12374            break;
12375        case OPC_SUBU_QB:
12376            check_dsp(ctx);
12377            gen_helper_subu_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12378            break;
12379        case OPC_SUBU_S_QB:
12380            check_dsp(ctx);
12381            gen_helper_subu_s_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12382            break;
12383        case OPC_SUBU_PH:
12384            check_dsp_r2(ctx);
12385            gen_helper_subu_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12386            break;
12387        case OPC_SUBU_S_PH:
12388            check_dsp_r2(ctx);
12389            gen_helper_subu_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12390            break;
12391        case OPC_ADDSC:
12392            check_dsp(ctx);
12393            gen_helper_addsc(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12394            break;
12395        case OPC_ADDWC:
12396            check_dsp(ctx);
12397            gen_helper_addwc(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12398            break;
12399        case OPC_MODSUB:
12400            check_dsp(ctx);
12401            gen_helper_modsub(cpu_gpr[ret], v1_t, v2_t);
12402            break;
12403        case OPC_RADDU_W_QB:
12404            check_dsp(ctx);
12405            gen_helper_raddu_w_qb(cpu_gpr[ret], v1_t);
12406            break;
12407        }
12408        break;
12409    case OPC_CMPU_EQ_QB_DSP:
12410        switch (op2) {
12411        case OPC_PRECR_QB_PH:
12412            check_dsp_r2(ctx);
12413            gen_helper_precr_qb_ph(cpu_gpr[ret], v1_t, v2_t);
12414            break;
12415        case OPC_PRECRQ_QB_PH:
12416            check_dsp(ctx);
12417            gen_helper_precrq_qb_ph(cpu_gpr[ret], v1_t, v2_t);
12418            break;
12419        case OPC_PRECR_SRA_PH_W:
12420            check_dsp_r2(ctx);
12421            {
12422                TCGv_i32 sa_t = tcg_const_i32(v2);
12423                gen_helper_precr_sra_ph_w(cpu_gpr[ret], sa_t, v1_t,
12424                                          cpu_gpr[ret]);
12425                tcg_temp_free_i32(sa_t);
12426                break;
12427            }
12428        case OPC_PRECR_SRA_R_PH_W:
12429            check_dsp_r2(ctx);
12430            {
12431                TCGv_i32 sa_t = tcg_const_i32(v2);
12432                gen_helper_precr_sra_r_ph_w(cpu_gpr[ret], sa_t, v1_t,
12433                                            cpu_gpr[ret]);
12434                tcg_temp_free_i32(sa_t);
12435                break;
12436            }
12437        case OPC_PRECRQ_PH_W:
12438            check_dsp(ctx);
12439            gen_helper_precrq_ph_w(cpu_gpr[ret], v1_t, v2_t);
12440            break;
12441        case OPC_PRECRQ_RS_PH_W:
12442            check_dsp(ctx);
12443            gen_helper_precrq_rs_ph_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12444            break;
12445        case OPC_PRECRQU_S_QB_PH:
12446            check_dsp(ctx);
12447            gen_helper_precrqu_s_qb_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12448            break;
12449        }
12450        break;
12451#ifdef TARGET_MIPS64
12452    case OPC_ABSQ_S_QH_DSP:
12453        switch (op2) {
12454        case OPC_PRECEQ_L_PWL:
12455            check_dsp(ctx);
12456            tcg_gen_andi_tl(cpu_gpr[ret], v2_t, 0xFFFFFFFF00000000ull);
12457            break;
12458        case OPC_PRECEQ_L_PWR:
12459            check_dsp(ctx);
12460            tcg_gen_shli_tl(cpu_gpr[ret], v2_t, 32);
12461            break;
12462        case OPC_PRECEQ_PW_QHL:
12463            check_dsp(ctx);
12464            gen_helper_preceq_pw_qhl(cpu_gpr[ret], v2_t);
12465            break;
12466        case OPC_PRECEQ_PW_QHR:
12467            check_dsp(ctx);
12468            gen_helper_preceq_pw_qhr(cpu_gpr[ret], v2_t);
12469            break;
12470        case OPC_PRECEQ_PW_QHLA:
12471            check_dsp(ctx);
12472            gen_helper_preceq_pw_qhla(cpu_gpr[ret], v2_t);
12473            break;
12474        case OPC_PRECEQ_PW_QHRA:
12475            check_dsp(ctx);
12476            gen_helper_preceq_pw_qhra(cpu_gpr[ret], v2_t);
12477            break;
12478        case OPC_PRECEQU_QH_OBL:
12479            check_dsp(ctx);
12480            gen_helper_precequ_qh_obl(cpu_gpr[ret], v2_t);
12481            break;
12482        case OPC_PRECEQU_QH_OBR:
12483            check_dsp(ctx);
12484            gen_helper_precequ_qh_obr(cpu_gpr[ret], v2_t);
12485            break;
12486        case OPC_PRECEQU_QH_OBLA:
12487            check_dsp(ctx);
12488            gen_helper_precequ_qh_obla(cpu_gpr[ret], v2_t);
12489            break;
12490        case OPC_PRECEQU_QH_OBRA:
12491            check_dsp(ctx);
12492            gen_helper_precequ_qh_obra(cpu_gpr[ret], v2_t);
12493            break;
12494        case OPC_PRECEU_QH_OBL:
12495            check_dsp(ctx);
12496            gen_helper_preceu_qh_obl(cpu_gpr[ret], v2_t);
12497            break;
12498        case OPC_PRECEU_QH_OBR:
12499            check_dsp(ctx);
12500            gen_helper_preceu_qh_obr(cpu_gpr[ret], v2_t);
12501            break;
12502        case OPC_PRECEU_QH_OBLA:
12503            check_dsp(ctx);
12504            gen_helper_preceu_qh_obla(cpu_gpr[ret], v2_t);
12505            break;
12506        case OPC_PRECEU_QH_OBRA:
12507            check_dsp(ctx);
12508            gen_helper_preceu_qh_obra(cpu_gpr[ret], v2_t);
12509            break;
12510        case OPC_ABSQ_S_OB:
12511            check_dsp_r2(ctx);
12512            gen_helper_absq_s_ob(cpu_gpr[ret], v2_t, cpu_env);
12513            break;
12514        case OPC_ABSQ_S_PW:
12515            check_dsp(ctx);
12516            gen_helper_absq_s_pw(cpu_gpr[ret], v2_t, cpu_env);
12517            break;
12518        case OPC_ABSQ_S_QH:
12519            check_dsp(ctx);
12520            gen_helper_absq_s_qh(cpu_gpr[ret], v2_t, cpu_env);
12521            break;
12522        }
12523        break;
12524    case OPC_ADDU_OB_DSP:
12525        switch (op2) {
12526        case OPC_RADDU_L_OB:
12527            check_dsp(ctx);
12528            gen_helper_raddu_l_ob(cpu_gpr[ret], v1_t);
12529            break;
12530        case OPC_SUBQ_PW:
12531            check_dsp(ctx);
12532            gen_helper_subq_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12533            break;
12534        case OPC_SUBQ_S_PW:
12535            check_dsp(ctx);
12536            gen_helper_subq_s_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12537            break;
12538        case OPC_SUBQ_QH:
12539            check_dsp(ctx);
12540            gen_helper_subq_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12541            break;
12542        case OPC_SUBQ_S_QH:
12543            check_dsp(ctx);
12544            gen_helper_subq_s_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12545            break;
12546        case OPC_SUBU_OB:
12547            check_dsp(ctx);
12548            gen_helper_subu_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12549            break;
12550        case OPC_SUBU_S_OB:
12551            check_dsp(ctx);
12552            gen_helper_subu_s_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12553            break;
12554        case OPC_SUBU_QH:
12555            check_dsp_r2(ctx);
12556            gen_helper_subu_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12557            break;
12558        case OPC_SUBU_S_QH:
12559            check_dsp_r2(ctx);
12560            gen_helper_subu_s_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12561            break;
12562        case OPC_SUBUH_OB:
12563            check_dsp_r2(ctx);
12564            gen_helper_subuh_ob(cpu_gpr[ret], v1_t, v2_t);
12565            break;
12566        case OPC_SUBUH_R_OB:
12567            check_dsp_r2(ctx);
12568            gen_helper_subuh_r_ob(cpu_gpr[ret], v1_t, v2_t);
12569            break;
12570        case OPC_ADDQ_PW:
12571            check_dsp(ctx);
12572            gen_helper_addq_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12573            break;
12574        case OPC_ADDQ_S_PW:
12575            check_dsp(ctx);
12576            gen_helper_addq_s_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12577            break;
12578        case OPC_ADDQ_QH:
12579            check_dsp(ctx);
12580            gen_helper_addq_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12581            break;
12582        case OPC_ADDQ_S_QH:
12583            check_dsp(ctx);
12584            gen_helper_addq_s_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12585            break;
12586        case OPC_ADDU_OB:
12587            check_dsp(ctx);
12588            gen_helper_addu_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12589            break;
12590        case OPC_ADDU_S_OB:
12591            check_dsp(ctx);
12592            gen_helper_addu_s_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12593            break;
12594        case OPC_ADDU_QH:
12595            check_dsp_r2(ctx);
12596            gen_helper_addu_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12597            break;
12598        case OPC_ADDU_S_QH:
12599            check_dsp_r2(ctx);
12600            gen_helper_addu_s_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12601            break;
12602        case OPC_ADDUH_OB:
12603            check_dsp_r2(ctx);
12604            gen_helper_adduh_ob(cpu_gpr[ret], v1_t, v2_t);
12605            break;
12606        case OPC_ADDUH_R_OB:
12607            check_dsp_r2(ctx);
12608            gen_helper_adduh_r_ob(cpu_gpr[ret], v1_t, v2_t);
12609            break;
12610        }
12611        break;
12612    case OPC_CMPU_EQ_OB_DSP:
12613        switch (op2) {
12614        case OPC_PRECR_OB_QH:
12615            check_dsp_r2(ctx);
12616            gen_helper_precr_ob_qh(cpu_gpr[ret], v1_t, v2_t);
12617            break;
12618        case OPC_PRECR_SRA_QH_PW:
12619            check_dsp_r2(ctx);
12620            {
12621                TCGv_i32 ret_t = tcg_const_i32(ret);
12622                gen_helper_precr_sra_qh_pw(v2_t, v1_t, v2_t, ret_t);
12623                tcg_temp_free_i32(ret_t);
12624                break;
12625            }
12626        case OPC_PRECR_SRA_R_QH_PW:
12627            check_dsp_r2(ctx);
12628            {
12629                TCGv_i32 sa_v = tcg_const_i32(ret);
12630                gen_helper_precr_sra_r_qh_pw(v2_t, v1_t, v2_t, sa_v);
12631                tcg_temp_free_i32(sa_v);
12632                break;
12633            }
12634        case OPC_PRECRQ_OB_QH:
12635            check_dsp(ctx);
12636            gen_helper_precrq_ob_qh(cpu_gpr[ret], v1_t, v2_t);
12637            break;
12638        case OPC_PRECRQ_PW_L:
12639            check_dsp(ctx);
12640            gen_helper_precrq_pw_l(cpu_gpr[ret], v1_t, v2_t);
12641            break;
12642        case OPC_PRECRQ_QH_PW:
12643            check_dsp(ctx);
12644            gen_helper_precrq_qh_pw(cpu_gpr[ret], v1_t, v2_t);
12645            break;
12646        case OPC_PRECRQ_RS_QH_PW:
12647            check_dsp(ctx);
12648            gen_helper_precrq_rs_qh_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12649            break;
12650        case OPC_PRECRQU_S_OB_QH:
12651            check_dsp(ctx);
12652            gen_helper_precrqu_s_ob_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12653            break;
12654        }
12655        break;
12656#endif
12657    }
12658
12659    tcg_temp_free(v1_t);
12660    tcg_temp_free(v2_t);
12661}
12662
12663static void gen_mipsdsp_shift(DisasContext *ctx, uint32_t opc,
12664                              int ret, int v1, int v2)
12665{
12666    uint32_t op2;
12667    TCGv t0;
12668    TCGv v1_t;
12669    TCGv v2_t;
12670
12671    if (ret == 0) {
12672        /* Treat as NOP. */
12673        return;
12674    }
12675
12676    t0 = tcg_temp_new();
12677    v1_t = tcg_temp_new();
12678    v2_t = tcg_temp_new();
12679
12680    tcg_gen_movi_tl(t0, v1);
12681    gen_load_gpr(v1_t, v1);
12682    gen_load_gpr(v2_t, v2);
12683
12684    switch (opc) {
12685    case OPC_SHLL_QB_DSP:
12686        {
12687            op2 = MASK_SHLL_QB(ctx->opcode);
12688            switch (op2) {
12689            case OPC_SHLL_QB:
12690                check_dsp(ctx);
12691                gen_helper_shll_qb(cpu_gpr[ret], t0, v2_t, cpu_env);
12692                break;
12693            case OPC_SHLLV_QB:
12694                check_dsp(ctx);
12695                gen_helper_shll_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12696                break;
12697            case OPC_SHLL_PH:
12698                check_dsp(ctx);
12699                gen_helper_shll_ph(cpu_gpr[ret], t0, v2_t, cpu_env);
12700                break;
12701            case OPC_SHLLV_PH:
12702                check_dsp(ctx);
12703                gen_helper_shll_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12704                break;
12705            case OPC_SHLL_S_PH:
12706                check_dsp(ctx);
12707                gen_helper_shll_s_ph(cpu_gpr[ret], t0, v2_t, cpu_env);
12708                break;
12709            case OPC_SHLLV_S_PH:
12710                check_dsp(ctx);
12711                gen_helper_shll_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12712                break;
12713            case OPC_SHLL_S_W:
12714                check_dsp(ctx);
12715                gen_helper_shll_s_w(cpu_gpr[ret], t0, v2_t, cpu_env);
12716                break;
12717            case OPC_SHLLV_S_W:
12718                check_dsp(ctx);
12719                gen_helper_shll_s_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12720                break;
12721            case OPC_SHRL_QB:
12722                check_dsp(ctx);
12723                gen_helper_shrl_qb(cpu_gpr[ret], t0, v2_t);
12724                break;
12725            case OPC_SHRLV_QB:
12726                check_dsp(ctx);
12727                gen_helper_shrl_qb(cpu_gpr[ret], v1_t, v2_t);
12728                break;
12729            case OPC_SHRL_PH:
12730                check_dsp_r2(ctx);
12731                gen_helper_shrl_ph(cpu_gpr[ret], t0, v2_t);
12732                break;
12733            case OPC_SHRLV_PH:
12734                check_dsp_r2(ctx);
12735                gen_helper_shrl_ph(cpu_gpr[ret], v1_t, v2_t);
12736                break;
12737            case OPC_SHRA_QB:
12738                check_dsp_r2(ctx);
12739                gen_helper_shra_qb(cpu_gpr[ret], t0, v2_t);
12740                break;
12741            case OPC_SHRA_R_QB:
12742                check_dsp_r2(ctx);
12743                gen_helper_shra_r_qb(cpu_gpr[ret], t0, v2_t);
12744                break;
12745            case OPC_SHRAV_QB:
12746                check_dsp_r2(ctx);
12747                gen_helper_shra_qb(cpu_gpr[ret], v1_t, v2_t);
12748                break;
12749            case OPC_SHRAV_R_QB:
12750                check_dsp_r2(ctx);
12751                gen_helper_shra_r_qb(cpu_gpr[ret], v1_t, v2_t);
12752                break;
12753            case OPC_SHRA_PH:
12754                check_dsp(ctx);
12755                gen_helper_shra_ph(cpu_gpr[ret], t0, v2_t);
12756                break;
12757            case OPC_SHRA_R_PH:
12758                check_dsp(ctx);
12759                gen_helper_shra_r_ph(cpu_gpr[ret], t0, v2_t);
12760                break;
12761            case OPC_SHRAV_PH:
12762                check_dsp(ctx);
12763                gen_helper_shra_ph(cpu_gpr[ret], v1_t, v2_t);
12764                break;
12765            case OPC_SHRAV_R_PH:
12766                check_dsp(ctx);
12767                gen_helper_shra_r_ph(cpu_gpr[ret], v1_t, v2_t);
12768                break;
12769            case OPC_SHRA_R_W:
12770                check_dsp(ctx);
12771                gen_helper_shra_r_w(cpu_gpr[ret], t0, v2_t);
12772                break;
12773            case OPC_SHRAV_R_W:
12774                check_dsp(ctx);
12775                gen_helper_shra_r_w(cpu_gpr[ret], v1_t, v2_t);
12776                break;
12777            default:            /* Invalid */
12778                MIPS_INVAL("MASK SHLL.QB");
12779                gen_reserved_instruction(ctx);
12780                break;
12781            }
12782            break;
12783        }
12784#ifdef TARGET_MIPS64
12785    case OPC_SHLL_OB_DSP:
12786        op2 = MASK_SHLL_OB(ctx->opcode);
12787        switch (op2) {
12788        case OPC_SHLL_PW:
12789            check_dsp(ctx);
12790            gen_helper_shll_pw(cpu_gpr[ret], v2_t, t0, cpu_env);
12791            break;
12792        case OPC_SHLLV_PW:
12793            check_dsp(ctx);
12794            gen_helper_shll_pw(cpu_gpr[ret], v2_t, v1_t, cpu_env);
12795            break;
12796        case OPC_SHLL_S_PW:
12797            check_dsp(ctx);
12798            gen_helper_shll_s_pw(cpu_gpr[ret], v2_t, t0, cpu_env);
12799            break;
12800        case OPC_SHLLV_S_PW:
12801            check_dsp(ctx);
12802            gen_helper_shll_s_pw(cpu_gpr[ret], v2_t, v1_t, cpu_env);
12803            break;
12804        case OPC_SHLL_OB:
12805            check_dsp(ctx);
12806            gen_helper_shll_ob(cpu_gpr[ret], v2_t, t0, cpu_env);
12807            break;
12808        case OPC_SHLLV_OB:
12809            check_dsp(ctx);
12810            gen_helper_shll_ob(cpu_gpr[ret], v2_t, v1_t, cpu_env);
12811            break;
12812        case OPC_SHLL_QH:
12813            check_dsp(ctx);
12814            gen_helper_shll_qh(cpu_gpr[ret], v2_t, t0, cpu_env);
12815            break;
12816        case OPC_SHLLV_QH:
12817            check_dsp(ctx);
12818            gen_helper_shll_qh(cpu_gpr[ret], v2_t, v1_t, cpu_env);
12819            break;
12820        case OPC_SHLL_S_QH:
12821            check_dsp(ctx);
12822            gen_helper_shll_s_qh(cpu_gpr[ret], v2_t, t0, cpu_env);
12823            break;
12824        case OPC_SHLLV_S_QH:
12825            check_dsp(ctx);
12826            gen_helper_shll_s_qh(cpu_gpr[ret], v2_t, v1_t, cpu_env);
12827            break;
12828        case OPC_SHRA_OB:
12829            check_dsp_r2(ctx);
12830            gen_helper_shra_ob(cpu_gpr[ret], v2_t, t0);
12831            break;
12832        case OPC_SHRAV_OB:
12833            check_dsp_r2(ctx);
12834            gen_helper_shra_ob(cpu_gpr[ret], v2_t, v1_t);
12835            break;
12836        case OPC_SHRA_R_OB:
12837            check_dsp_r2(ctx);
12838            gen_helper_shra_r_ob(cpu_gpr[ret], v2_t, t0);
12839            break;
12840        case OPC_SHRAV_R_OB:
12841            check_dsp_r2(ctx);
12842            gen_helper_shra_r_ob(cpu_gpr[ret], v2_t, v1_t);
12843            break;
12844        case OPC_SHRA_PW:
12845            check_dsp(ctx);
12846            gen_helper_shra_pw(cpu_gpr[ret], v2_t, t0);
12847            break;
12848        case OPC_SHRAV_PW:
12849            check_dsp(ctx);
12850            gen_helper_shra_pw(cpu_gpr[ret], v2_t, v1_t);
12851            break;
12852        case OPC_SHRA_R_PW:
12853            check_dsp(ctx);
12854            gen_helper_shra_r_pw(cpu_gpr[ret], v2_t, t0);
12855            break;
12856        case OPC_SHRAV_R_PW:
12857            check_dsp(ctx);
12858            gen_helper_shra_r_pw(cpu_gpr[ret], v2_t, v1_t);
12859            break;
12860        case OPC_SHRA_QH:
12861            check_dsp(ctx);
12862            gen_helper_shra_qh(cpu_gpr[ret], v2_t, t0);
12863            break;
12864        case OPC_SHRAV_QH:
12865            check_dsp(ctx);
12866            gen_helper_shra_qh(cpu_gpr[ret], v2_t, v1_t);
12867            break;
12868        case OPC_SHRA_R_QH:
12869            check_dsp(ctx);
12870            gen_helper_shra_r_qh(cpu_gpr[ret], v2_t, t0);
12871            break;
12872        case OPC_SHRAV_R_QH:
12873            check_dsp(ctx);
12874            gen_helper_shra_r_qh(cpu_gpr[ret], v2_t, v1_t);
12875            break;
12876        case OPC_SHRL_OB:
12877            check_dsp(ctx);
12878            gen_helper_shrl_ob(cpu_gpr[ret], v2_t, t0);
12879            break;
12880        case OPC_SHRLV_OB:
12881            check_dsp(ctx);
12882            gen_helper_shrl_ob(cpu_gpr[ret], v2_t, v1_t);
12883            break;
12884        case OPC_SHRL_QH:
12885            check_dsp_r2(ctx);
12886            gen_helper_shrl_qh(cpu_gpr[ret], v2_t, t0);
12887            break;
12888        case OPC_SHRLV_QH:
12889            check_dsp_r2(ctx);
12890            gen_helper_shrl_qh(cpu_gpr[ret], v2_t, v1_t);
12891            break;
12892        default:            /* Invalid */
12893            MIPS_INVAL("MASK SHLL.OB");
12894            gen_reserved_instruction(ctx);
12895            break;
12896        }
12897        break;
12898#endif
12899    }
12900
12901    tcg_temp_free(t0);
12902    tcg_temp_free(v1_t);
12903    tcg_temp_free(v2_t);
12904}
12905
12906static void gen_mipsdsp_multiply(DisasContext *ctx, uint32_t op1, uint32_t op2,
12907                                 int ret, int v1, int v2, int check_ret)
12908{
12909    TCGv_i32 t0;
12910    TCGv v1_t;
12911    TCGv v2_t;
12912
12913    if ((ret == 0) && (check_ret == 1)) {
12914        /* Treat as NOP. */
12915        return;
12916    }
12917
12918    t0 = tcg_temp_new_i32();
12919    v1_t = tcg_temp_new();
12920    v2_t = tcg_temp_new();
12921
12922    tcg_gen_movi_i32(t0, ret);
12923    gen_load_gpr(v1_t, v1);
12924    gen_load_gpr(v2_t, v2);
12925
12926    switch (op1) {
12927    /*
12928     * OPC_MULT_G_2E, OPC_ADDUH_QB_DSP, OPC_MUL_PH_DSP have
12929     * the same mask and op1.
12930     */
12931    case OPC_MULT_G_2E:
12932        check_dsp_r2(ctx);
12933        switch (op2) {
12934        case  OPC_MUL_PH:
12935            gen_helper_mul_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12936            break;
12937        case  OPC_MUL_S_PH:
12938            gen_helper_mul_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12939            break;
12940        case OPC_MULQ_S_W:
12941            gen_helper_mulq_s_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12942            break;
12943        case OPC_MULQ_RS_W:
12944            gen_helper_mulq_rs_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12945            break;
12946        }
12947        break;
12948    case OPC_DPA_W_PH_DSP:
12949        switch (op2) {
12950        case OPC_DPAU_H_QBL:
12951            check_dsp(ctx);
12952            gen_helper_dpau_h_qbl(t0, v1_t, v2_t, cpu_env);
12953            break;
12954        case OPC_DPAU_H_QBR:
12955            check_dsp(ctx);
12956            gen_helper_dpau_h_qbr(t0, v1_t, v2_t, cpu_env);
12957            break;
12958        case OPC_DPSU_H_QBL:
12959            check_dsp(ctx);
12960            gen_helper_dpsu_h_qbl(t0, v1_t, v2_t, cpu_env);
12961            break;
12962        case OPC_DPSU_H_QBR:
12963            check_dsp(ctx);
12964            gen_helper_dpsu_h_qbr(t0, v1_t, v2_t, cpu_env);
12965            break;
12966        case OPC_DPA_W_PH:
12967            check_dsp_r2(ctx);
12968            gen_helper_dpa_w_ph(t0, v1_t, v2_t, cpu_env);
12969            break;
12970        case OPC_DPAX_W_PH:
12971            check_dsp_r2(ctx);
12972            gen_helper_dpax_w_ph(t0, v1_t, v2_t, cpu_env);
12973            break;
12974        case OPC_DPAQ_S_W_PH:
12975            check_dsp(ctx);
12976            gen_helper_dpaq_s_w_ph(t0, v1_t, v2_t, cpu_env);
12977            break;
12978        case OPC_DPAQX_S_W_PH:
12979            check_dsp_r2(ctx);
12980            gen_helper_dpaqx_s_w_ph(t0, v1_t, v2_t, cpu_env);
12981            break;
12982        case OPC_DPAQX_SA_W_PH:
12983            check_dsp_r2(ctx);
12984            gen_helper_dpaqx_sa_w_ph(t0, v1_t, v2_t, cpu_env);
12985            break;
12986        case OPC_DPS_W_PH:
12987            check_dsp_r2(ctx);
12988            gen_helper_dps_w_ph(t0, v1_t, v2_t, cpu_env);
12989            break;
12990        case OPC_DPSX_W_PH:
12991            check_dsp_r2(ctx);
12992            gen_helper_dpsx_w_ph(t0, v1_t, v2_t, cpu_env);
12993            break;
12994        case OPC_DPSQ_S_W_PH:
12995            check_dsp(ctx);
12996            gen_helper_dpsq_s_w_ph(t0, v1_t, v2_t, cpu_env);
12997            break;
12998        case OPC_DPSQX_S_W_PH:
12999            check_dsp_r2(ctx);
13000            gen_helper_dpsqx_s_w_ph(t0, v1_t, v2_t, cpu_env);
13001            break;
13002        case OPC_DPSQX_SA_W_PH:
13003            check_dsp_r2(ctx);
13004            gen_helper_dpsqx_sa_w_ph(t0, v1_t, v2_t, cpu_env);
13005            break;
13006        case OPC_MULSAQ_S_W_PH:
13007            check_dsp(ctx);
13008            gen_helper_mulsaq_s_w_ph(t0, v1_t, v2_t, cpu_env);
13009            break;
13010        case OPC_DPAQ_SA_L_W:
13011            check_dsp(ctx);
13012            gen_helper_dpaq_sa_l_w(t0, v1_t, v2_t, cpu_env);
13013            break;
13014        case OPC_DPSQ_SA_L_W:
13015            check_dsp(ctx);
13016            gen_helper_dpsq_sa_l_w(t0, v1_t, v2_t, cpu_env);
13017            break;
13018        case OPC_MAQ_S_W_PHL:
13019            check_dsp(ctx);
13020            gen_helper_maq_s_w_phl(t0, v1_t, v2_t, cpu_env);
13021            break;
13022        case OPC_MAQ_S_W_PHR:
13023            check_dsp(ctx);
13024            gen_helper_maq_s_w_phr(t0, v1_t, v2_t, cpu_env);
13025            break;
13026        case OPC_MAQ_SA_W_PHL:
13027            check_dsp(ctx);
13028            gen_helper_maq_sa_w_phl(t0, v1_t, v2_t, cpu_env);
13029            break;
13030        case OPC_MAQ_SA_W_PHR:
13031            check_dsp(ctx);
13032            gen_helper_maq_sa_w_phr(t0, v1_t, v2_t, cpu_env);
13033            break;
13034        case OPC_MULSA_W_PH:
13035            check_dsp_r2(ctx);
13036            gen_helper_mulsa_w_ph(t0, v1_t, v2_t, cpu_env);
13037            break;
13038        }
13039        break;
13040#ifdef TARGET_MIPS64
13041    case OPC_DPAQ_W_QH_DSP:
13042        {
13043            int ac = ret & 0x03;
13044            tcg_gen_movi_i32(t0, ac);
13045
13046            switch (op2) {
13047            case OPC_DMADD:
13048                check_dsp(ctx);
13049                gen_helper_dmadd(v1_t, v2_t, t0, cpu_env);
13050                break;
13051            case OPC_DMADDU:
13052                check_dsp(ctx);
13053                gen_helper_dmaddu(v1_t, v2_t, t0, cpu_env);
13054                break;
13055            case OPC_DMSUB:
13056                check_dsp(ctx);
13057                gen_helper_dmsub(v1_t, v2_t, t0, cpu_env);
13058                break;
13059            case OPC_DMSUBU:
13060                check_dsp(ctx);
13061                gen_helper_dmsubu(v1_t, v2_t, t0, cpu_env);
13062                break;
13063            case OPC_DPA_W_QH:
13064                check_dsp_r2(ctx);
13065                gen_helper_dpa_w_qh(v1_t, v2_t, t0, cpu_env);
13066                break;
13067            case OPC_DPAQ_S_W_QH:
13068                check_dsp(ctx);
13069                gen_helper_dpaq_s_w_qh(v1_t, v2_t, t0, cpu_env);
13070                break;
13071            case OPC_DPAQ_SA_L_PW:
13072                check_dsp(ctx);
13073                gen_helper_dpaq_sa_l_pw(v1_t, v2_t, t0, cpu_env);
13074                break;
13075            case OPC_DPAU_H_OBL:
13076                check_dsp(ctx);
13077                gen_helper_dpau_h_obl(v1_t, v2_t, t0, cpu_env);
13078                break;
13079            case OPC_DPAU_H_OBR:
13080                check_dsp(ctx);
13081                gen_helper_dpau_h_obr(v1_t, v2_t, t0, cpu_env);
13082                break;
13083            case OPC_DPS_W_QH:
13084                check_dsp_r2(ctx);
13085                gen_helper_dps_w_qh(v1_t, v2_t, t0, cpu_env);
13086                break;
13087            case OPC_DPSQ_S_W_QH:
13088                check_dsp(ctx);
13089                gen_helper_dpsq_s_w_qh(v1_t, v2_t, t0, cpu_env);
13090                break;
13091            case OPC_DPSQ_SA_L_PW:
13092                check_dsp(ctx);
13093                gen_helper_dpsq_sa_l_pw(v1_t, v2_t, t0, cpu_env);
13094                break;
13095            case OPC_DPSU_H_OBL:
13096                check_dsp(ctx);
13097                gen_helper_dpsu_h_obl(v1_t, v2_t, t0, cpu_env);
13098                break;
13099            case OPC_DPSU_H_OBR:
13100                check_dsp(ctx);
13101                gen_helper_dpsu_h_obr(v1_t, v2_t, t0, cpu_env);
13102                break;
13103            case OPC_MAQ_S_L_PWL:
13104                check_dsp(ctx);
13105                gen_helper_maq_s_l_pwl(v1_t, v2_t, t0, cpu_env);
13106                break;
13107            case OPC_MAQ_S_L_PWR:
13108                check_dsp(ctx);
13109                gen_helper_maq_s_l_pwr(v1_t, v2_t, t0, cpu_env);
13110                break;
13111            case OPC_MAQ_S_W_QHLL:
13112                check_dsp(ctx);
13113                gen_helper_maq_s_w_qhll(v1_t, v2_t, t0, cpu_env);
13114                break;
13115            case OPC_MAQ_SA_W_QHLL:
13116                check_dsp(ctx);
13117                gen_helper_maq_sa_w_qhll(v1_t, v2_t, t0, cpu_env);
13118                break;
13119            case OPC_MAQ_S_W_QHLR:
13120                check_dsp(ctx);
13121                gen_helper_maq_s_w_qhlr(v1_t, v2_t, t0, cpu_env);
13122                break;
13123            case OPC_MAQ_SA_W_QHLR:
13124                check_dsp(ctx);
13125                gen_helper_maq_sa_w_qhlr(v1_t, v2_t, t0, cpu_env);
13126                break;
13127            case OPC_MAQ_S_W_QHRL:
13128                check_dsp(ctx);
13129                gen_helper_maq_s_w_qhrl(v1_t, v2_t, t0, cpu_env);
13130                break;
13131            case OPC_MAQ_SA_W_QHRL:
13132                check_dsp(ctx);
13133                gen_helper_maq_sa_w_qhrl(v1_t, v2_t, t0, cpu_env);
13134                break;
13135            case OPC_MAQ_S_W_QHRR:
13136                check_dsp(ctx);
13137                gen_helper_maq_s_w_qhrr(v1_t, v2_t, t0, cpu_env);
13138                break;
13139            case OPC_MAQ_SA_W_QHRR:
13140                check_dsp(ctx);
13141                gen_helper_maq_sa_w_qhrr(v1_t, v2_t, t0, cpu_env);
13142                break;
13143            case OPC_MULSAQ_S_L_PW:
13144                check_dsp(ctx);
13145                gen_helper_mulsaq_s_l_pw(v1_t, v2_t, t0, cpu_env);
13146                break;
13147            case OPC_MULSAQ_S_W_QH:
13148                check_dsp(ctx);
13149                gen_helper_mulsaq_s_w_qh(v1_t, v2_t, t0, cpu_env);
13150                break;
13151            }
13152        }
13153        break;
13154#endif
13155    case OPC_ADDU_QB_DSP:
13156        switch (op2) {
13157        case OPC_MULEU_S_PH_QBL:
13158            check_dsp(ctx);
13159            gen_helper_muleu_s_ph_qbl(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13160            break;
13161        case OPC_MULEU_S_PH_QBR:
13162            check_dsp(ctx);
13163            gen_helper_muleu_s_ph_qbr(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13164            break;
13165        case OPC_MULQ_RS_PH:
13166            check_dsp(ctx);
13167            gen_helper_mulq_rs_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13168            break;
13169        case OPC_MULEQ_S_W_PHL:
13170            check_dsp(ctx);
13171            gen_helper_muleq_s_w_phl(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13172            break;
13173        case OPC_MULEQ_S_W_PHR:
13174            check_dsp(ctx);
13175            gen_helper_muleq_s_w_phr(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13176            break;
13177        case OPC_MULQ_S_PH:
13178            check_dsp_r2(ctx);
13179            gen_helper_mulq_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13180            break;
13181        }
13182        break;
13183#ifdef TARGET_MIPS64
13184    case OPC_ADDU_OB_DSP:
13185        switch (op2) {
13186        case OPC_MULEQ_S_PW_QHL:
13187            check_dsp(ctx);
13188            gen_helper_muleq_s_pw_qhl(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13189            break;
13190        case OPC_MULEQ_S_PW_QHR:
13191            check_dsp(ctx);
13192            gen_helper_muleq_s_pw_qhr(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13193            break;
13194        case OPC_MULEU_S_QH_OBL:
13195            check_dsp(ctx);
13196            gen_helper_muleu_s_qh_obl(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13197            break;
13198        case OPC_MULEU_S_QH_OBR:
13199            check_dsp(ctx);
13200            gen_helper_muleu_s_qh_obr(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13201            break;
13202        case OPC_MULQ_RS_QH:
13203            check_dsp(ctx);
13204            gen_helper_mulq_rs_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13205            break;
13206        }
13207        break;
13208#endif
13209    }
13210
13211    tcg_temp_free_i32(t0);
13212    tcg_temp_free(v1_t);
13213    tcg_temp_free(v2_t);
13214}
13215
13216static void gen_mipsdsp_bitinsn(DisasContext *ctx, uint32_t op1, uint32_t op2,
13217                                int ret, int val)
13218{
13219    int16_t imm;
13220    TCGv t0;
13221    TCGv val_t;
13222
13223    if (ret == 0) {
13224        /* Treat as NOP. */
13225        return;
13226    }
13227
13228    t0 = tcg_temp_new();
13229    val_t = tcg_temp_new();
13230    gen_load_gpr(val_t, val);
13231
13232    switch (op1) {
13233    case OPC_ABSQ_S_PH_DSP:
13234        switch (op2) {
13235        case OPC_BITREV:
13236            check_dsp(ctx);
13237            gen_helper_bitrev(cpu_gpr[ret], val_t);
13238            break;
13239        case OPC_REPL_QB:
13240            check_dsp(ctx);
13241            {
13242                target_long result;
13243                imm = (ctx->opcode >> 16) & 0xFF;
13244                result = (uint32_t)imm << 24 |
13245                         (uint32_t)imm << 16 |
13246                         (uint32_t)imm << 8  |
13247                         (uint32_t)imm;
13248                result = (int32_t)result;
13249                tcg_gen_movi_tl(cpu_gpr[ret], result);
13250            }
13251            break;
13252        case OPC_REPLV_QB:
13253            check_dsp(ctx);
13254            tcg_gen_ext8u_tl(cpu_gpr[ret], val_t);
13255            tcg_gen_shli_tl(t0, cpu_gpr[ret], 8);
13256            tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
13257            tcg_gen_shli_tl(t0, cpu_gpr[ret], 16);
13258            tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
13259            tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]);
13260            break;
13261        case OPC_REPL_PH:
13262            check_dsp(ctx);
13263            {
13264                imm = (ctx->opcode >> 16) & 0x03FF;
13265                imm = (int16_t)(imm << 6) >> 6;
13266                tcg_gen_movi_tl(cpu_gpr[ret], \
13267                                (target_long)((int32_t)imm << 16 | \
13268                                (uint16_t)imm));
13269            }
13270            break;
13271        case OPC_REPLV_PH:
13272            check_dsp(ctx);
13273            tcg_gen_ext16u_tl(cpu_gpr[ret], val_t);
13274            tcg_gen_shli_tl(t0, cpu_gpr[ret], 16);
13275            tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
13276            tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]);
13277            break;
13278        }
13279        break;
13280#ifdef TARGET_MIPS64
13281    case OPC_ABSQ_S_QH_DSP:
13282        switch (op2) {
13283        case OPC_REPL_OB:
13284            check_dsp(ctx);
13285            {
13286                target_long temp;
13287
13288                imm = (ctx->opcode >> 16) & 0xFF;
13289                temp = ((uint64_t)imm << 8) | (uint64_t)imm;
13290                temp = (temp << 16) | temp;
13291                temp = (temp << 32) | temp;
13292                tcg_gen_movi_tl(cpu_gpr[ret], temp);
13293                break;
13294            }
13295        case OPC_REPL_PW:
13296            check_dsp(ctx);
13297            {
13298                target_long temp;
13299
13300                imm = (ctx->opcode >> 16) & 0x03FF;
13301                imm = (int16_t)(imm << 6) >> 6;
13302                temp = ((target_long)imm << 32) \
13303                       | ((target_long)imm & 0xFFFFFFFF);
13304                tcg_gen_movi_tl(cpu_gpr[ret], temp);
13305                break;
13306            }
13307        case OPC_REPL_QH:
13308            check_dsp(ctx);
13309            {
13310                target_long temp;
13311
13312                imm = (ctx->opcode >> 16) & 0x03FF;
13313                imm = (int16_t)(imm << 6) >> 6;
13314
13315                temp = ((uint64_t)(uint16_t)imm << 48) |
13316                       ((uint64_t)(uint16_t)imm << 32) |
13317                       ((uint64_t)(uint16_t)imm << 16) |
13318                       (uint64_t)(uint16_t)imm;
13319                tcg_gen_movi_tl(cpu_gpr[ret], temp);
13320                break;
13321            }
13322        case OPC_REPLV_OB:
13323            check_dsp(ctx);
13324            tcg_gen_ext8u_tl(cpu_gpr[ret], val_t);
13325            tcg_gen_shli_tl(t0, cpu_gpr[ret], 8);
13326            tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
13327            tcg_gen_shli_tl(t0, cpu_gpr[ret], 16);
13328            tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
13329            tcg_gen_shli_tl(t0, cpu_gpr[ret], 32);
13330            tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
13331            break;
13332        case OPC_REPLV_PW:
13333            check_dsp(ctx);
13334            tcg_gen_ext32u_i64(cpu_gpr[ret], val_t);
13335            tcg_gen_shli_tl(t0, cpu_gpr[ret], 32);
13336            tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
13337            break;
13338        case OPC_REPLV_QH:
13339            check_dsp(ctx);
13340            tcg_gen_ext16u_tl(cpu_gpr[ret], val_t);
13341            tcg_gen_shli_tl(t0, cpu_gpr[ret], 16);
13342            tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
13343            tcg_gen_shli_tl(t0, cpu_gpr[ret], 32);
13344            tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
13345            break;
13346        }
13347        break;
13348#endif
13349    }
13350    tcg_temp_free(t0);
13351    tcg_temp_free(val_t);
13352}
13353
13354static void gen_mipsdsp_add_cmp_pick(DisasContext *ctx,
13355                                     uint32_t op1, uint32_t op2,
13356                                     int ret, int v1, int v2, int check_ret)
13357{
13358    TCGv t1;
13359    TCGv v1_t;
13360    TCGv v2_t;
13361
13362    if ((ret == 0) && (check_ret == 1)) {
13363        /* Treat as NOP. */
13364        return;
13365    }
13366
13367    t1 = tcg_temp_new();
13368    v1_t = tcg_temp_new();
13369    v2_t = tcg_temp_new();
13370
13371    gen_load_gpr(v1_t, v1);
13372    gen_load_gpr(v2_t, v2);
13373
13374    switch (op1) {
13375    case OPC_CMPU_EQ_QB_DSP:
13376        switch (op2) {
13377        case OPC_CMPU_EQ_QB:
13378            check_dsp(ctx);
13379            gen_helper_cmpu_eq_qb(v1_t, v2_t, cpu_env);
13380            break;
13381        case OPC_CMPU_LT_QB:
13382            check_dsp(ctx);
13383            gen_helper_cmpu_lt_qb(v1_t, v2_t, cpu_env);
13384            break;
13385        case OPC_CMPU_LE_QB:
13386            check_dsp(ctx);
13387            gen_helper_cmpu_le_qb(v1_t, v2_t, cpu_env);
13388            break;
13389        case OPC_CMPGU_EQ_QB:
13390            check_dsp(ctx);
13391            gen_helper_cmpgu_eq_qb(cpu_gpr[ret], v1_t, v2_t);
13392            break;
13393        case OPC_CMPGU_LT_QB:
13394            check_dsp(ctx);
13395            gen_helper_cmpgu_lt_qb(cpu_gpr[ret], v1_t, v2_t);
13396            break;
13397        case OPC_CMPGU_LE_QB:
13398            check_dsp(ctx);
13399            gen_helper_cmpgu_le_qb(cpu_gpr[ret], v1_t, v2_t);
13400            break;
13401        case OPC_CMPGDU_EQ_QB:
13402            check_dsp_r2(ctx);
13403            gen_helper_cmpgu_eq_qb(t1, v1_t, v2_t);
13404            tcg_gen_mov_tl(cpu_gpr[ret], t1);
13405            tcg_gen_andi_tl(cpu_dspctrl, cpu_dspctrl, 0xF0FFFFFF);
13406            tcg_gen_shli_tl(t1, t1, 24);
13407            tcg_gen_or_tl(cpu_dspctrl, cpu_dspctrl, t1);
13408            break;
13409        case OPC_CMPGDU_LT_QB:
13410            check_dsp_r2(ctx);
13411            gen_helper_cmpgu_lt_qb(t1, v1_t, v2_t);
13412            tcg_gen_mov_tl(cpu_gpr[ret], t1);
13413            tcg_gen_andi_tl(cpu_dspctrl, cpu_dspctrl, 0xF0FFFFFF);
13414            tcg_gen_shli_tl(t1, t1, 24);
13415            tcg_gen_or_tl(cpu_dspctrl, cpu_dspctrl, t1);
13416            break;
13417        case OPC_CMPGDU_LE_QB:
13418            check_dsp_r2(ctx);
13419            gen_helper_cmpgu_le_qb(t1, v1_t, v2_t);
13420            tcg_gen_mov_tl(cpu_gpr[ret], t1);
13421            tcg_gen_andi_tl(cpu_dspctrl, cpu_dspctrl, 0xF0FFFFFF);
13422            tcg_gen_shli_tl(t1, t1, 24);
13423            tcg_gen_or_tl(cpu_dspctrl, cpu_dspctrl, t1);
13424            break;
13425        case OPC_CMP_EQ_PH:
13426            check_dsp(ctx);
13427            gen_helper_cmp_eq_ph(v1_t, v2_t, cpu_env);
13428            break;
13429        case OPC_CMP_LT_PH:
13430            check_dsp(ctx);
13431            gen_helper_cmp_lt_ph(v1_t, v2_t, cpu_env);
13432            break;
13433        case OPC_CMP_LE_PH:
13434            check_dsp(ctx);
13435            gen_helper_cmp_le_ph(v1_t, v2_t, cpu_env);
13436            break;
13437        case OPC_PICK_QB:
13438            check_dsp(ctx);
13439            gen_helper_pick_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13440            break;
13441        case OPC_PICK_PH:
13442            check_dsp(ctx);
13443            gen_helper_pick_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13444            break;
13445        case OPC_PACKRL_PH:
13446            check_dsp(ctx);
13447            gen_helper_packrl_ph(cpu_gpr[ret], v1_t, v2_t);
13448            break;
13449        }
13450        break;
13451#ifdef TARGET_MIPS64
13452    case OPC_CMPU_EQ_OB_DSP:
13453        switch (op2) {
13454        case OPC_CMP_EQ_PW:
13455            check_dsp(ctx);
13456            gen_helper_cmp_eq_pw(v1_t, v2_t, cpu_env);
13457            break;
13458        case OPC_CMP_LT_PW:
13459            check_dsp(ctx);
13460            gen_helper_cmp_lt_pw(v1_t, v2_t, cpu_env);
13461            break;
13462        case OPC_CMP_LE_PW:
13463            check_dsp(ctx);
13464            gen_helper_cmp_le_pw(v1_t, v2_t, cpu_env);
13465            break;
13466        case OPC_CMP_EQ_QH:
13467            check_dsp(ctx);
13468            gen_helper_cmp_eq_qh(v1_t, v2_t, cpu_env);
13469            break;
13470        case OPC_CMP_LT_QH:
13471            check_dsp(ctx);
13472            gen_helper_cmp_lt_qh(v1_t, v2_t, cpu_env);
13473            break;
13474        case OPC_CMP_LE_QH:
13475            check_dsp(ctx);
13476            gen_helper_cmp_le_qh(v1_t, v2_t, cpu_env);
13477            break;
13478        case OPC_CMPGDU_EQ_OB:
13479            check_dsp_r2(ctx);
13480            gen_helper_cmpgdu_eq_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13481            break;
13482        case OPC_CMPGDU_LT_OB:
13483            check_dsp_r2(ctx);
13484            gen_helper_cmpgdu_lt_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13485            break;
13486        case OPC_CMPGDU_LE_OB:
13487            check_dsp_r2(ctx);
13488            gen_helper_cmpgdu_le_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13489            break;
13490        case OPC_CMPGU_EQ_OB:
13491            check_dsp(ctx);
13492            gen_helper_cmpgu_eq_ob(cpu_gpr[ret], v1_t, v2_t);
13493            break;
13494        case OPC_CMPGU_LT_OB:
13495            check_dsp(ctx);
13496            gen_helper_cmpgu_lt_ob(cpu_gpr[ret], v1_t, v2_t);
13497            break;
13498        case OPC_CMPGU_LE_OB:
13499            check_dsp(ctx);
13500            gen_helper_cmpgu_le_ob(cpu_gpr[ret], v1_t, v2_t);
13501            break;
13502        case OPC_CMPU_EQ_OB:
13503            check_dsp(ctx);
13504            gen_helper_cmpu_eq_ob(v1_t, v2_t, cpu_env);
13505            break;
13506        case OPC_CMPU_LT_OB:
13507            check_dsp(ctx);
13508            gen_helper_cmpu_lt_ob(v1_t, v2_t, cpu_env);
13509            break;
13510        case OPC_CMPU_LE_OB:
13511            check_dsp(ctx);
13512            gen_helper_cmpu_le_ob(v1_t, v2_t, cpu_env);
13513            break;
13514        case OPC_PACKRL_PW:
13515            check_dsp(ctx);
13516            gen_helper_packrl_pw(cpu_gpr[ret], v1_t, v2_t);
13517            break;
13518        case OPC_PICK_OB:
13519            check_dsp(ctx);
13520            gen_helper_pick_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13521            break;
13522        case OPC_PICK_PW:
13523            check_dsp(ctx);
13524            gen_helper_pick_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13525            break;
13526        case OPC_PICK_QH:
13527            check_dsp(ctx);
13528            gen_helper_pick_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13529            break;
13530        }
13531        break;
13532#endif
13533    }
13534
13535    tcg_temp_free(t1);
13536    tcg_temp_free(v1_t);
13537    tcg_temp_free(v2_t);
13538}
13539
13540static void gen_mipsdsp_append(CPUMIPSState *env, DisasContext *ctx,
13541                               uint32_t op1, int rt, int rs, int sa)
13542{
13543    TCGv t0;
13544
13545    check_dsp_r2(ctx);
13546
13547    if (rt == 0) {
13548        /* Treat as NOP. */
13549        return;
13550    }
13551
13552    t0 = tcg_temp_new();
13553    gen_load_gpr(t0, rs);
13554
13555    switch (op1) {
13556    case OPC_APPEND_DSP:
13557        switch (MASK_APPEND(ctx->opcode)) {
13558        case OPC_APPEND:
13559            if (sa != 0) {
13560                tcg_gen_deposit_tl(cpu_gpr[rt], t0, cpu_gpr[rt], sa, 32 - sa);
13561            }
13562            tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
13563            break;
13564        case OPC_PREPEND:
13565            if (sa != 0) {
13566                tcg_gen_ext32u_tl(cpu_gpr[rt], cpu_gpr[rt]);
13567                tcg_gen_shri_tl(cpu_gpr[rt], cpu_gpr[rt], sa);
13568                tcg_gen_shli_tl(t0, t0, 32 - sa);
13569                tcg_gen_or_tl(cpu_gpr[rt], cpu_gpr[rt], t0);
13570            }
13571            tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
13572            break;
13573        case OPC_BALIGN:
13574            sa &= 3;
13575            if (sa != 0 && sa != 2) {
13576                tcg_gen_shli_tl(cpu_gpr[rt], cpu_gpr[rt], 8 * sa);
13577                tcg_gen_ext32u_tl(t0, t0);
13578                tcg_gen_shri_tl(t0, t0, 8 * (4 - sa));
13579                tcg_gen_or_tl(cpu_gpr[rt], cpu_gpr[rt], t0);
13580            }
13581            tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
13582            break;
13583        default:            /* Invalid */
13584            MIPS_INVAL("MASK APPEND");
13585            gen_reserved_instruction(ctx);
13586            break;
13587        }
13588        break;
13589#ifdef TARGET_MIPS64
13590    case OPC_DAPPEND_DSP:
13591        switch (MASK_DAPPEND(ctx->opcode)) {
13592        case OPC_DAPPEND:
13593            if (sa != 0) {
13594                tcg_gen_deposit_tl(cpu_gpr[rt], t0, cpu_gpr[rt], sa, 64 - sa);
13595            }
13596            break;
13597        case OPC_PREPENDD:
13598            tcg_gen_shri_tl(cpu_gpr[rt], cpu_gpr[rt], 0x20 | sa);
13599            tcg_gen_shli_tl(t0, t0, 64 - (0x20 | sa));
13600            tcg_gen_or_tl(cpu_gpr[rt], t0, t0);
13601            break;
13602        case OPC_PREPENDW:
13603            if (sa != 0) {
13604                tcg_gen_shri_tl(cpu_gpr[rt], cpu_gpr[rt], sa);
13605                tcg_gen_shli_tl(t0, t0, 64 - sa);
13606                tcg_gen_or_tl(cpu_gpr[rt], cpu_gpr[rt], t0);
13607            }
13608            break;
13609        case OPC_DBALIGN:
13610            sa &= 7;
13611            if (sa != 0 && sa != 2 && sa != 4) {
13612                tcg_gen_shli_tl(cpu_gpr[rt], cpu_gpr[rt], 8 * sa);
13613                tcg_gen_shri_tl(t0, t0, 8 * (8 - sa));
13614                tcg_gen_or_tl(cpu_gpr[rt], cpu_gpr[rt], t0);
13615            }
13616            break;
13617        default:            /* Invalid */
13618            MIPS_INVAL("MASK DAPPEND");
13619            gen_reserved_instruction(ctx);
13620            break;
13621        }
13622        break;
13623#endif
13624    }
13625    tcg_temp_free(t0);
13626}
13627
13628static void gen_mipsdsp_accinsn(DisasContext *ctx, uint32_t op1, uint32_t op2,
13629                                int ret, int v1, int v2, int check_ret)
13630
13631{
13632    TCGv t0;
13633    TCGv t1;
13634    TCGv v1_t;
13635    int16_t imm;
13636
13637    if ((ret == 0) && (check_ret == 1)) {
13638        /* Treat as NOP. */
13639        return;
13640    }
13641
13642    t0 = tcg_temp_new();
13643    t1 = tcg_temp_new();
13644    v1_t = tcg_temp_new();
13645
13646    gen_load_gpr(v1_t, v1);
13647
13648    switch (op1) {
13649    case OPC_EXTR_W_DSP:
13650        check_dsp(ctx);
13651        switch (op2) {
13652        case OPC_EXTR_W:
13653            tcg_gen_movi_tl(t0, v2);
13654            tcg_gen_movi_tl(t1, v1);
13655            gen_helper_extr_w(cpu_gpr[ret], t0, t1, cpu_env);
13656            break;
13657        case OPC_EXTR_R_W:
13658            tcg_gen_movi_tl(t0, v2);
13659            tcg_gen_movi_tl(t1, v1);
13660            gen_helper_extr_r_w(cpu_gpr[ret], t0, t1, cpu_env);
13661            break;
13662        case OPC_EXTR_RS_W:
13663            tcg_gen_movi_tl(t0, v2);
13664            tcg_gen_movi_tl(t1, v1);
13665            gen_helper_extr_rs_w(cpu_gpr[ret], t0, t1, cpu_env);
13666            break;
13667        case OPC_EXTR_S_H:
13668            tcg_gen_movi_tl(t0, v2);
13669            tcg_gen_movi_tl(t1, v1);
13670            gen_helper_extr_s_h(cpu_gpr[ret], t0, t1, cpu_env);
13671            break;
13672        case OPC_EXTRV_S_H:
13673            tcg_gen_movi_tl(t0, v2);
13674            gen_helper_extr_s_h(cpu_gpr[ret], t0, v1_t, cpu_env);
13675            break;
13676        case OPC_EXTRV_W:
13677            tcg_gen_movi_tl(t0, v2);
13678            gen_helper_extr_w(cpu_gpr[ret], t0, v1_t, cpu_env);
13679            break;
13680        case OPC_EXTRV_R_W:
13681            tcg_gen_movi_tl(t0, v2);
13682            gen_helper_extr_r_w(cpu_gpr[ret], t0, v1_t, cpu_env);
13683            break;
13684        case OPC_EXTRV_RS_W:
13685            tcg_gen_movi_tl(t0, v2);
13686            gen_helper_extr_rs_w(cpu_gpr[ret], t0, v1_t, cpu_env);
13687            break;
13688        case OPC_EXTP:
13689            tcg_gen_movi_tl(t0, v2);
13690            tcg_gen_movi_tl(t1, v1);
13691            gen_helper_extp(cpu_gpr[ret], t0, t1, cpu_env);
13692            break;
13693        case OPC_EXTPV:
13694            tcg_gen_movi_tl(t0, v2);
13695            gen_helper_extp(cpu_gpr[ret], t0, v1_t, cpu_env);
13696            break;
13697        case OPC_EXTPDP:
13698            tcg_gen_movi_tl(t0, v2);
13699            tcg_gen_movi_tl(t1, v1);
13700            gen_helper_extpdp(cpu_gpr[ret], t0, t1, cpu_env);
13701            break;
13702        case OPC_EXTPDPV:
13703            tcg_gen_movi_tl(t0, v2);
13704            gen_helper_extpdp(cpu_gpr[ret], t0, v1_t, cpu_env);
13705            break;
13706        case OPC_SHILO:
13707            imm = (ctx->opcode >> 20) & 0x3F;
13708            tcg_gen_movi_tl(t0, ret);
13709            tcg_gen_movi_tl(t1, imm);
13710            gen_helper_shilo(t0, t1, cpu_env);
13711            break;
13712        case OPC_SHILOV:
13713            tcg_gen_movi_tl(t0, ret);
13714            gen_helper_shilo(t0, v1_t, cpu_env);
13715            break;
13716        case OPC_MTHLIP:
13717            tcg_gen_movi_tl(t0, ret);
13718            gen_helper_mthlip(t0, v1_t, cpu_env);
13719            break;
13720        case OPC_WRDSP:
13721            imm = (ctx->opcode >> 11) & 0x3FF;
13722            tcg_gen_movi_tl(t0, imm);
13723            gen_helper_wrdsp(v1_t, t0, cpu_env);
13724            break;
13725        case OPC_RDDSP:
13726            imm = (ctx->opcode >> 16) & 0x03FF;
13727            tcg_gen_movi_tl(t0, imm);
13728            gen_helper_rddsp(cpu_gpr[ret], t0, cpu_env);
13729            break;
13730        }
13731        break;
13732#ifdef TARGET_MIPS64
13733    case OPC_DEXTR_W_DSP:
13734        check_dsp(ctx);
13735        switch (op2) {
13736        case OPC_DMTHLIP:
13737            tcg_gen_movi_tl(t0, ret);
13738            gen_helper_dmthlip(v1_t, t0, cpu_env);
13739            break;
13740        case OPC_DSHILO:
13741            {
13742                int shift = (ctx->opcode >> 19) & 0x7F;
13743                int ac = (ctx->opcode >> 11) & 0x03;
13744                tcg_gen_movi_tl(t0, shift);
13745                tcg_gen_movi_tl(t1, ac);
13746                gen_helper_dshilo(t0, t1, cpu_env);
13747                break;
13748            }
13749        case OPC_DSHILOV:
13750            {
13751                int ac = (ctx->opcode >> 11) & 0x03;
13752                tcg_gen_movi_tl(t0, ac);
13753                gen_helper_dshilo(v1_t, t0, cpu_env);
13754                break;
13755            }
13756        case OPC_DEXTP:
13757            tcg_gen_movi_tl(t0, v2);
13758            tcg_gen_movi_tl(t1, v1);
13759
13760            gen_helper_dextp(cpu_gpr[ret], t0, t1, cpu_env);
13761            break;
13762        case OPC_DEXTPV:
13763            tcg_gen_movi_tl(t0, v2);
13764            gen_helper_dextp(cpu_gpr[ret], t0, v1_t, cpu_env);
13765            break;
13766        case OPC_DEXTPDP:
13767            tcg_gen_movi_tl(t0, v2);
13768            tcg_gen_movi_tl(t1, v1);
13769            gen_helper_dextpdp(cpu_gpr[ret], t0, t1, cpu_env);
13770            break;
13771        case OPC_DEXTPDPV:
13772            tcg_gen_movi_tl(t0, v2);
13773            gen_helper_dextpdp(cpu_gpr[ret], t0, v1_t, cpu_env);
13774            break;
13775        case OPC_DEXTR_L:
13776            tcg_gen_movi_tl(t0, v2);
13777            tcg_gen_movi_tl(t1, v1);
13778            gen_helper_dextr_l(cpu_gpr[ret], t0, t1, cpu_env);
13779            break;
13780        case OPC_DEXTR_R_L:
13781            tcg_gen_movi_tl(t0, v2);
13782            tcg_gen_movi_tl(t1, v1);
13783            gen_helper_dextr_r_l(cpu_gpr[ret], t0, t1, cpu_env);
13784            break;
13785        case OPC_DEXTR_RS_L:
13786            tcg_gen_movi_tl(t0, v2);
13787            tcg_gen_movi_tl(t1, v1);
13788            gen_helper_dextr_rs_l(cpu_gpr[ret], t0, t1, cpu_env);
13789            break;
13790        case OPC_DEXTR_W:
13791            tcg_gen_movi_tl(t0, v2);
13792            tcg_gen_movi_tl(t1, v1);
13793            gen_helper_dextr_w(cpu_gpr[ret], t0, t1, cpu_env);
13794            break;
13795        case OPC_DEXTR_R_W:
13796            tcg_gen_movi_tl(t0, v2);
13797            tcg_gen_movi_tl(t1, v1);
13798            gen_helper_dextr_r_w(cpu_gpr[ret], t0, t1, cpu_env);
13799            break;
13800        case OPC_DEXTR_RS_W:
13801            tcg_gen_movi_tl(t0, v2);
13802            tcg_gen_movi_tl(t1, v1);
13803            gen_helper_dextr_rs_w(cpu_gpr[ret], t0, t1, cpu_env);
13804            break;
13805        case OPC_DEXTR_S_H:
13806            tcg_gen_movi_tl(t0, v2);
13807            tcg_gen_movi_tl(t1, v1);
13808            gen_helper_dextr_s_h(cpu_gpr[ret], t0, t1, cpu_env);
13809            break;
13810        case OPC_DEXTRV_S_H:
13811            tcg_gen_movi_tl(t0, v2);
13812            gen_helper_dextr_s_h(cpu_gpr[ret], t0, v1_t, cpu_env);
13813            break;
13814        case OPC_DEXTRV_L:
13815            tcg_gen_movi_tl(t0, v2);
13816            gen_helper_dextr_l(cpu_gpr[ret], t0, v1_t, cpu_env);
13817            break;
13818        case OPC_DEXTRV_R_L:
13819            tcg_gen_movi_tl(t0, v2);
13820            gen_helper_dextr_r_l(cpu_gpr[ret], t0, v1_t, cpu_env);
13821            break;
13822        case OPC_DEXTRV_RS_L:
13823            tcg_gen_movi_tl(t0, v2);
13824            gen_helper_dextr_rs_l(cpu_gpr[ret], t0, v1_t, cpu_env);
13825            break;
13826        case OPC_DEXTRV_W:
13827            tcg_gen_movi_tl(t0, v2);
13828            gen_helper_dextr_w(cpu_gpr[ret], t0, v1_t, cpu_env);
13829            break;
13830        case OPC_DEXTRV_R_W:
13831            tcg_gen_movi_tl(t0, v2);
13832            gen_helper_dextr_r_w(cpu_gpr[ret], t0, v1_t, cpu_env);
13833            break;
13834        case OPC_DEXTRV_RS_W:
13835            tcg_gen_movi_tl(t0, v2);
13836            gen_helper_dextr_rs_w(cpu_gpr[ret], t0, v1_t, cpu_env);
13837            break;
13838        }
13839        break;
13840#endif
13841    }
13842
13843    tcg_temp_free(t0);
13844    tcg_temp_free(t1);
13845    tcg_temp_free(v1_t);
13846}
13847
13848/* End MIPSDSP functions. */
13849
13850static void decode_opc_special_r6(CPUMIPSState *env, DisasContext *ctx)
13851{
13852    int rs, rt, rd, sa;
13853    uint32_t op1, op2;
13854
13855    rs = (ctx->opcode >> 21) & 0x1f;
13856    rt = (ctx->opcode >> 16) & 0x1f;
13857    rd = (ctx->opcode >> 11) & 0x1f;
13858    sa = (ctx->opcode >> 6) & 0x1f;
13859
13860    op1 = MASK_SPECIAL(ctx->opcode);
13861    switch (op1) {
13862    case OPC_MULT:
13863    case OPC_MULTU:
13864    case OPC_DIV:
13865    case OPC_DIVU:
13866        op2 = MASK_R6_MULDIV(ctx->opcode);
13867        switch (op2) {
13868        case R6_OPC_MUL:
13869        case R6_OPC_MUH:
13870        case R6_OPC_MULU:
13871        case R6_OPC_MUHU:
13872        case R6_OPC_DIV:
13873        case R6_OPC_MOD:
13874        case R6_OPC_DIVU:
13875        case R6_OPC_MODU:
13876            gen_r6_muldiv(ctx, op2, rd, rs, rt);
13877            break;
13878        default:
13879            MIPS_INVAL("special_r6 muldiv");
13880            gen_reserved_instruction(ctx);
13881            break;
13882        }
13883        break;
13884    case OPC_SELEQZ:
13885    case OPC_SELNEZ:
13886        gen_cond_move(ctx, op1, rd, rs, rt);
13887        break;
13888    case R6_OPC_CLO:
13889    case R6_OPC_CLZ:
13890        if (rt == 0 && sa == 1) {
13891            /*
13892             * Major opcode and function field is shared with preR6 MFHI/MTHI.
13893             * We need additionally to check other fields.
13894             */
13895            gen_cl(ctx, op1, rd, rs);
13896        } else {
13897            gen_reserved_instruction(ctx);
13898        }
13899        break;
13900    case R6_OPC_SDBBP:
13901        if (is_uhi(extract32(ctx->opcode, 6, 20))) {
13902            ctx->base.is_jmp = DISAS_SEMIHOST;
13903        } else {
13904            if (ctx->hflags & MIPS_HFLAG_SBRI) {
13905                gen_reserved_instruction(ctx);
13906            } else {
13907                generate_exception_end(ctx, EXCP_DBp);
13908            }
13909        }
13910        break;
13911#if defined(TARGET_MIPS64)
13912    case R6_OPC_DCLO:
13913    case R6_OPC_DCLZ:
13914        if (rt == 0 && sa == 1) {
13915            /*
13916             * Major opcode and function field is shared with preR6 MFHI/MTHI.
13917             * We need additionally to check other fields.
13918             */
13919            check_mips_64(ctx);
13920            gen_cl(ctx, op1, rd, rs);
13921        } else {
13922            gen_reserved_instruction(ctx);
13923        }
13924        break;
13925    case OPC_DMULT:
13926    case OPC_DMULTU:
13927    case OPC_DDIV:
13928    case OPC_DDIVU:
13929
13930        op2 = MASK_R6_MULDIV(ctx->opcode);
13931        switch (op2) {
13932        case R6_OPC_DMUL:
13933        case R6_OPC_DMUH:
13934        case R6_OPC_DMULU:
13935        case R6_OPC_DMUHU:
13936        case R6_OPC_DDIV:
13937        case R6_OPC_DMOD:
13938        case R6_OPC_DDIVU:
13939        case R6_OPC_DMODU:
13940            check_mips_64(ctx);
13941            gen_r6_muldiv(ctx, op2, rd, rs, rt);
13942            break;
13943        default:
13944            MIPS_INVAL("special_r6 muldiv");
13945            gen_reserved_instruction(ctx);
13946            break;
13947        }
13948        break;
13949#endif
13950    default:            /* Invalid */
13951        MIPS_INVAL("special_r6");
13952        gen_reserved_instruction(ctx);
13953        break;
13954    }
13955}
13956
13957static void decode_opc_special_tx79(CPUMIPSState *env, DisasContext *ctx)
13958{
13959    int rs = extract32(ctx->opcode, 21, 5);
13960    int rt = extract32(ctx->opcode, 16, 5);
13961    int rd = extract32(ctx->opcode, 11, 5);
13962    uint32_t op1 = MASK_SPECIAL(ctx->opcode);
13963
13964    switch (op1) {
13965    case OPC_MOVN:         /* Conditional move */
13966    case OPC_MOVZ:
13967        gen_cond_move(ctx, op1, rd, rs, rt);
13968        break;
13969    case OPC_MFHI:          /* Move from HI/LO */
13970    case OPC_MFLO:
13971        gen_HILO(ctx, op1, 0, rd);
13972        break;
13973    case OPC_MTHI:
13974    case OPC_MTLO:          /* Move to HI/LO */
13975        gen_HILO(ctx, op1, 0, rs);
13976        break;
13977    case OPC_MULT:
13978    case OPC_MULTU:
13979        gen_mul_txx9(ctx, op1, rd, rs, rt);
13980        break;
13981    case OPC_DIV:
13982    case OPC_DIVU:
13983        gen_muldiv(ctx, op1, 0, rs, rt);
13984        break;
13985#if defined(TARGET_MIPS64)
13986    case OPC_DMULT:
13987    case OPC_DMULTU:
13988    case OPC_DDIV:
13989    case OPC_DDIVU:
13990        check_insn_opc_user_only(ctx, INSN_R5900);
13991        gen_muldiv(ctx, op1, 0, rs, rt);
13992        break;
13993#endif
13994    case OPC_JR:
13995        gen_compute_branch(ctx, op1, 4, rs, 0, 0, 4);
13996        break;
13997    default:            /* Invalid */
13998        MIPS_INVAL("special_tx79");
13999        gen_reserved_instruction(ctx);
14000        break;
14001    }
14002}
14003
14004static void decode_opc_special_legacy(CPUMIPSState *env, DisasContext *ctx)
14005{
14006    int rs, rt, rd;
14007    uint32_t op1;
14008
14009    rs = (ctx->opcode >> 21) & 0x1f;
14010    rt = (ctx->opcode >> 16) & 0x1f;
14011    rd = (ctx->opcode >> 11) & 0x1f;
14012
14013    op1 = MASK_SPECIAL(ctx->opcode);
14014    switch (op1) {
14015    case OPC_MOVN:         /* Conditional move */
14016    case OPC_MOVZ:
14017        check_insn(ctx, ISA_MIPS4 | ISA_MIPS_R1 |
14018                   INSN_LOONGSON2E | INSN_LOONGSON2F);
14019        gen_cond_move(ctx, op1, rd, rs, rt);
14020        break;
14021    case OPC_MFHI:          /* Move from HI/LO */
14022    case OPC_MFLO:
14023        gen_HILO(ctx, op1, rs & 3, rd);
14024        break;
14025    case OPC_MTHI:
14026    case OPC_MTLO:          /* Move to HI/LO */
14027        gen_HILO(ctx, op1, rd & 3, rs);
14028        break;
14029    case OPC_MOVCI:
14030        check_insn(ctx, ISA_MIPS4 | ISA_MIPS_R1);
14031        if (env->CP0_Config1 & (1 << CP0C1_FP)) {
14032            check_cp1_enabled(ctx);
14033            gen_movci(ctx, rd, rs, (ctx->opcode >> 18) & 0x7,
14034                      (ctx->opcode >> 16) & 1);
14035        } else {
14036            generate_exception_err(ctx, EXCP_CpU, 1);
14037        }
14038        break;
14039    case OPC_MULT:
14040    case OPC_MULTU:
14041        gen_muldiv(ctx, op1, rd & 3, rs, rt);
14042        break;
14043    case OPC_DIV:
14044    case OPC_DIVU:
14045        gen_muldiv(ctx, op1, 0, rs, rt);
14046        break;
14047#if defined(TARGET_MIPS64)
14048    case OPC_DMULT:
14049    case OPC_DMULTU:
14050    case OPC_DDIV:
14051    case OPC_DDIVU:
14052        check_insn(ctx, ISA_MIPS3);
14053        check_mips_64(ctx);
14054        gen_muldiv(ctx, op1, 0, rs, rt);
14055        break;
14056#endif
14057    case OPC_JR:
14058        gen_compute_branch(ctx, op1, 4, rs, 0, 0, 4);
14059        break;
14060    case OPC_SPIM:
14061#ifdef MIPS_STRICT_STANDARD
14062        MIPS_INVAL("SPIM");
14063        gen_reserved_instruction(ctx);
14064#else
14065        /* Implemented as RI exception for now. */
14066        MIPS_INVAL("spim (unofficial)");
14067        gen_reserved_instruction(ctx);
14068#endif
14069        break;
14070    default:            /* Invalid */
14071        MIPS_INVAL("special_legacy");
14072        gen_reserved_instruction(ctx);
14073        break;
14074    }
14075}
14076
14077static void decode_opc_special(CPUMIPSState *env, DisasContext *ctx)
14078{
14079    int rs, rt, rd, sa;
14080    uint32_t op1;
14081
14082    rs = (ctx->opcode >> 21) & 0x1f;
14083    rt = (ctx->opcode >> 16) & 0x1f;
14084    rd = (ctx->opcode >> 11) & 0x1f;
14085    sa = (ctx->opcode >> 6) & 0x1f;
14086
14087    op1 = MASK_SPECIAL(ctx->opcode);
14088    switch (op1) {
14089    case OPC_SLL:          /* Shift with immediate */
14090        if (sa == 5 && rd == 0 &&
14091            rs == 0 && rt == 0) { /* PAUSE */
14092            if ((ctx->insn_flags & ISA_MIPS_R6) &&
14093                (ctx->hflags & MIPS_HFLAG_BMASK)) {
14094                gen_reserved_instruction(ctx);
14095                break;
14096            }
14097        }
14098        /* Fallthrough */
14099    case OPC_SRA:
14100        gen_shift_imm(ctx, op1, rd, rt, sa);
14101        break;
14102    case OPC_SRL:
14103        switch ((ctx->opcode >> 21) & 0x1f) {
14104        case 1:
14105            /* rotr is decoded as srl on non-R2 CPUs */
14106            if (ctx->insn_flags & ISA_MIPS_R2) {
14107                op1 = OPC_ROTR;
14108            }
14109            /* Fallthrough */
14110        case 0:
14111            gen_shift_imm(ctx, op1, rd, rt, sa);
14112            break;
14113        default:
14114            gen_reserved_instruction(ctx);
14115            break;
14116        }
14117        break;
14118    case OPC_ADD:
14119    case OPC_ADDU:
14120    case OPC_SUB:
14121    case OPC_SUBU:
14122        gen_arith(ctx, op1, rd, rs, rt);
14123        break;
14124    case OPC_SLLV:         /* Shifts */
14125    case OPC_SRAV:
14126        gen_shift(ctx, op1, rd, rs, rt);
14127        break;
14128    case OPC_SRLV:
14129        switch ((ctx->opcode >> 6) & 0x1f) {
14130        case 1:
14131            /* rotrv is decoded as srlv on non-R2 CPUs */
14132            if (ctx->insn_flags & ISA_MIPS_R2) {
14133                op1 = OPC_ROTRV;
14134            }
14135            /* Fallthrough */
14136        case 0:
14137            gen_shift(ctx, op1, rd, rs, rt);
14138            break;
14139        default:
14140            gen_reserved_instruction(ctx);
14141            break;
14142        }
14143        break;
14144    case OPC_SLT:          /* Set on less than */
14145    case OPC_SLTU:
14146        gen_slt(ctx, op1, rd, rs, rt);
14147        break;
14148    case OPC_AND:          /* Logic*/
14149    case OPC_OR:
14150    case OPC_NOR:
14151    case OPC_XOR:
14152        gen_logic(ctx, op1, rd, rs, rt);
14153        break;
14154    case OPC_JALR:
14155        gen_compute_branch(ctx, op1, 4, rs, rd, sa, 4);
14156        break;
14157    case OPC_TGE: /* Traps */
14158    case OPC_TGEU:
14159    case OPC_TLT:
14160    case OPC_TLTU:
14161    case OPC_TEQ:
14162    case OPC_TNE:
14163        check_insn(ctx, ISA_MIPS2);
14164        gen_trap(ctx, op1, rs, rt, -1, extract32(ctx->opcode, 6, 10));
14165        break;
14166    case OPC_PMON:
14167        /* Pmon entry point, also R4010 selsl */
14168#ifdef MIPS_STRICT_STANDARD
14169        MIPS_INVAL("PMON / selsl");
14170        gen_reserved_instruction(ctx);
14171#else
14172        gen_helper_pmon(cpu_env, tcg_constant_i32(sa));
14173#endif
14174        break;
14175    case OPC_SYSCALL:
14176        generate_exception_end(ctx, EXCP_SYSCALL);
14177        break;
14178    case OPC_BREAK:
14179        generate_exception_break(ctx, extract32(ctx->opcode, 6, 20));
14180        break;
14181    case OPC_SYNC:
14182        check_insn(ctx, ISA_MIPS2);
14183        gen_sync(extract32(ctx->opcode, 6, 5));
14184        break;
14185
14186#if defined(TARGET_MIPS64)
14187        /* MIPS64 specific opcodes */
14188    case OPC_DSLL:
14189    case OPC_DSRA:
14190    case OPC_DSLL32:
14191    case OPC_DSRA32:
14192        check_insn(ctx, ISA_MIPS3);
14193        check_mips_64(ctx);
14194        gen_shift_imm(ctx, op1, rd, rt, sa);
14195        break;
14196    case OPC_DSRL:
14197        switch ((ctx->opcode >> 21) & 0x1f) {
14198        case 1:
14199            /* drotr is decoded as dsrl on non-R2 CPUs */
14200            if (ctx->insn_flags & ISA_MIPS_R2) {
14201                op1 = OPC_DROTR;
14202            }
14203            /* Fallthrough */
14204        case 0:
14205            check_insn(ctx, ISA_MIPS3);
14206            check_mips_64(ctx);
14207            gen_shift_imm(ctx, op1, rd, rt, sa);
14208            break;
14209        default:
14210            gen_reserved_instruction(ctx);
14211            break;
14212        }
14213        break;
14214    case OPC_DSRL32:
14215        switch ((ctx->opcode >> 21) & 0x1f) {
14216        case 1:
14217            /* drotr32 is decoded as dsrl32 on non-R2 CPUs */
14218            if (ctx->insn_flags & ISA_MIPS_R2) {
14219                op1 = OPC_DROTR32;
14220            }
14221            /* Fallthrough */
14222        case 0:
14223            check_insn(ctx, ISA_MIPS3);
14224            check_mips_64(ctx);
14225            gen_shift_imm(ctx, op1, rd, rt, sa);
14226            break;
14227        default:
14228            gen_reserved_instruction(ctx);
14229            break;
14230        }
14231        break;
14232    case OPC_DADD:
14233    case OPC_DADDU:
14234    case OPC_DSUB:
14235    case OPC_DSUBU:
14236        check_insn(ctx, ISA_MIPS3);
14237        check_mips_64(ctx);
14238        gen_arith(ctx, op1, rd, rs, rt);
14239        break;
14240    case OPC_DSLLV:
14241    case OPC_DSRAV:
14242        check_insn(ctx, ISA_MIPS3);
14243        check_mips_64(ctx);
14244        gen_shift(ctx, op1, rd, rs, rt);
14245        break;
14246    case OPC_DSRLV:
14247        switch ((ctx->opcode >> 6) & 0x1f) {
14248        case 1:
14249            /* drotrv is decoded as dsrlv on non-R2 CPUs */
14250            if (ctx->insn_flags & ISA_MIPS_R2) {
14251                op1 = OPC_DROTRV;
14252            }
14253            /* Fallthrough */
14254        case 0:
14255            check_insn(ctx, ISA_MIPS3);
14256            check_mips_64(ctx);
14257            gen_shift(ctx, op1, rd, rs, rt);
14258            break;
14259        default:
14260            gen_reserved_instruction(ctx);
14261            break;
14262        }
14263        break;
14264#endif
14265    default:
14266        if (ctx->insn_flags & ISA_MIPS_R6) {
14267            decode_opc_special_r6(env, ctx);
14268        } else if (ctx->insn_flags & INSN_R5900) {
14269            decode_opc_special_tx79(env, ctx);
14270        } else {
14271            decode_opc_special_legacy(env, ctx);
14272        }
14273    }
14274}
14275
14276
14277static void decode_opc_special2_legacy(CPUMIPSState *env, DisasContext *ctx)
14278{
14279    int rs, rt, rd;
14280    uint32_t op1;
14281
14282    rs = (ctx->opcode >> 21) & 0x1f;
14283    rt = (ctx->opcode >> 16) & 0x1f;
14284    rd = (ctx->opcode >> 11) & 0x1f;
14285
14286    op1 = MASK_SPECIAL2(ctx->opcode);
14287    switch (op1) {
14288    case OPC_MADD: /* Multiply and add/sub */
14289    case OPC_MADDU:
14290    case OPC_MSUB:
14291    case OPC_MSUBU:
14292        check_insn(ctx, ISA_MIPS_R1);
14293        gen_muldiv(ctx, op1, rd & 3, rs, rt);
14294        break;
14295    case OPC_MUL:
14296        gen_arith(ctx, op1, rd, rs, rt);
14297        break;
14298    case OPC_DIV_G_2F:
14299    case OPC_DIVU_G_2F:
14300    case OPC_MULT_G_2F:
14301    case OPC_MULTU_G_2F:
14302    case OPC_MOD_G_2F:
14303    case OPC_MODU_G_2F:
14304        check_insn(ctx, INSN_LOONGSON2F | ASE_LEXT);
14305        gen_loongson_integer(ctx, op1, rd, rs, rt);
14306        break;
14307    case OPC_CLO:
14308    case OPC_CLZ:
14309        check_insn(ctx, ISA_MIPS_R1);
14310        gen_cl(ctx, op1, rd, rs);
14311        break;
14312    case OPC_SDBBP:
14313        if (is_uhi(extract32(ctx->opcode, 6, 20))) {
14314            ctx->base.is_jmp = DISAS_SEMIHOST;
14315        } else {
14316            /*
14317             * XXX: not clear which exception should be raised
14318             *      when in debug mode...
14319             */
14320            check_insn(ctx, ISA_MIPS_R1);
14321            generate_exception_end(ctx, EXCP_DBp);
14322        }
14323        break;
14324#if defined(TARGET_MIPS64)
14325    case OPC_DCLO:
14326    case OPC_DCLZ:
14327        check_insn(ctx, ISA_MIPS_R1);
14328        check_mips_64(ctx);
14329        gen_cl(ctx, op1, rd, rs);
14330        break;
14331    case OPC_DMULT_G_2F:
14332    case OPC_DMULTU_G_2F:
14333    case OPC_DDIV_G_2F:
14334    case OPC_DDIVU_G_2F:
14335    case OPC_DMOD_G_2F:
14336    case OPC_DMODU_G_2F:
14337        check_insn(ctx, INSN_LOONGSON2F | ASE_LEXT);
14338        gen_loongson_integer(ctx, op1, rd, rs, rt);
14339        break;
14340#endif
14341    default:            /* Invalid */
14342        MIPS_INVAL("special2_legacy");
14343        gen_reserved_instruction(ctx);
14344        break;
14345    }
14346}
14347
14348static void decode_opc_special3_r6(CPUMIPSState *env, DisasContext *ctx)
14349{
14350    int rs, rt, rd, sa;
14351    uint32_t op1, op2;
14352    int16_t imm;
14353
14354    rs = (ctx->opcode >> 21) & 0x1f;
14355    rt = (ctx->opcode >> 16) & 0x1f;
14356    rd = (ctx->opcode >> 11) & 0x1f;
14357    sa = (ctx->opcode >> 6) & 0x1f;
14358    imm = (int16_t)ctx->opcode >> 7;
14359
14360    op1 = MASK_SPECIAL3(ctx->opcode);
14361    switch (op1) {
14362    case R6_OPC_PREF:
14363        if (rt >= 24) {
14364            /* hint codes 24-31 are reserved and signal RI */
14365            gen_reserved_instruction(ctx);
14366        }
14367        /* Treat as NOP. */
14368        break;
14369    case R6_OPC_CACHE:
14370        check_cp0_enabled(ctx);
14371        if (ctx->hflags & MIPS_HFLAG_ITC_CACHE) {
14372            gen_cache_operation(ctx, rt, rs, imm);
14373        }
14374        break;
14375    case R6_OPC_SC:
14376        gen_st_cond(ctx, rt, rs, imm, MO_TESL, false);
14377        break;
14378    case R6_OPC_LL:
14379        gen_ld(ctx, op1, rt, rs, imm);
14380        break;
14381    case OPC_BSHFL:
14382        {
14383            if (rd == 0) {
14384                /* Treat as NOP. */
14385                break;
14386            }
14387            op2 = MASK_BSHFL(ctx->opcode);
14388            switch (op2) {
14389            case OPC_ALIGN:
14390            case OPC_ALIGN_1:
14391            case OPC_ALIGN_2:
14392            case OPC_ALIGN_3:
14393                gen_align(ctx, 32, rd, rs, rt, sa & 3);
14394                break;
14395            case OPC_BITSWAP:
14396                gen_bitswap(ctx, op2, rd, rt);
14397                break;
14398            }
14399        }
14400        break;
14401#ifndef CONFIG_USER_ONLY
14402    case OPC_GINV:
14403        if (unlikely(ctx->gi <= 1)) {
14404            gen_reserved_instruction(ctx);
14405        }
14406        check_cp0_enabled(ctx);
14407        switch ((ctx->opcode >> 6) & 3) {
14408        case 0:    /* GINVI */
14409            /* Treat as NOP. */
14410            break;
14411        case 2:    /* GINVT */
14412            gen_helper_0e1i(ginvt, cpu_gpr[rs], extract32(ctx->opcode, 8, 2));
14413            break;
14414        default:
14415            gen_reserved_instruction(ctx);
14416            break;
14417        }
14418        break;
14419#endif
14420#if defined(TARGET_MIPS64)
14421    case R6_OPC_SCD:
14422        gen_st_cond(ctx, rt, rs, imm, MO_TEUQ, false);
14423        break;
14424    case R6_OPC_LLD:
14425        gen_ld(ctx, op1, rt, rs, imm);
14426        break;
14427    case OPC_DBSHFL:
14428        check_mips_64(ctx);
14429        {
14430            if (rd == 0) {
14431                /* Treat as NOP. */
14432                break;
14433            }
14434            op2 = MASK_DBSHFL(ctx->opcode);
14435            switch (op2) {
14436            case OPC_DALIGN:
14437            case OPC_DALIGN_1:
14438            case OPC_DALIGN_2:
14439            case OPC_DALIGN_3:
14440            case OPC_DALIGN_4:
14441            case OPC_DALIGN_5:
14442            case OPC_DALIGN_6:
14443            case OPC_DALIGN_7:
14444                gen_align(ctx, 64, rd, rs, rt, sa & 7);
14445                break;
14446            case OPC_DBITSWAP:
14447                gen_bitswap(ctx, op2, rd, rt);
14448                break;
14449            }
14450
14451        }
14452        break;
14453#endif
14454    default:            /* Invalid */
14455        MIPS_INVAL("special3_r6");
14456        gen_reserved_instruction(ctx);
14457        break;
14458    }
14459}
14460
14461static void decode_opc_special3_legacy(CPUMIPSState *env, DisasContext *ctx)
14462{
14463    int rs, rt, rd;
14464    uint32_t op1, op2;
14465
14466    rs = (ctx->opcode >> 21) & 0x1f;
14467    rt = (ctx->opcode >> 16) & 0x1f;
14468    rd = (ctx->opcode >> 11) & 0x1f;
14469
14470    op1 = MASK_SPECIAL3(ctx->opcode);
14471    switch (op1) {
14472    case OPC_DIV_G_2E:
14473    case OPC_DIVU_G_2E:
14474    case OPC_MOD_G_2E:
14475    case OPC_MODU_G_2E:
14476    case OPC_MULT_G_2E:
14477    case OPC_MULTU_G_2E:
14478        /*
14479         * OPC_MULT_G_2E, OPC_ADDUH_QB_DSP, OPC_MUL_PH_DSP have
14480         * the same mask and op1.
14481         */
14482        if ((ctx->insn_flags & ASE_DSP_R2) && (op1 == OPC_MULT_G_2E)) {
14483            op2 = MASK_ADDUH_QB(ctx->opcode);
14484            switch (op2) {
14485            case OPC_ADDUH_QB:
14486            case OPC_ADDUH_R_QB:
14487            case OPC_ADDQH_PH:
14488            case OPC_ADDQH_R_PH:
14489            case OPC_ADDQH_W:
14490            case OPC_ADDQH_R_W:
14491            case OPC_SUBUH_QB:
14492            case OPC_SUBUH_R_QB:
14493            case OPC_SUBQH_PH:
14494            case OPC_SUBQH_R_PH:
14495            case OPC_SUBQH_W:
14496            case OPC_SUBQH_R_W:
14497                gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
14498                break;
14499            case OPC_MUL_PH:
14500            case OPC_MUL_S_PH:
14501            case OPC_MULQ_S_W:
14502            case OPC_MULQ_RS_W:
14503                gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 1);
14504                break;
14505            default:
14506                MIPS_INVAL("MASK ADDUH.QB");
14507                gen_reserved_instruction(ctx);
14508                break;
14509            }
14510        } else if (ctx->insn_flags & INSN_LOONGSON2E) {
14511            gen_loongson_integer(ctx, op1, rd, rs, rt);
14512        } else {
14513            gen_reserved_instruction(ctx);
14514        }
14515        break;
14516    case OPC_LX_DSP:
14517        op2 = MASK_LX(ctx->opcode);
14518        switch (op2) {
14519#if defined(TARGET_MIPS64)
14520        case OPC_LDX:
14521#endif
14522        case OPC_LBUX:
14523        case OPC_LHX:
14524        case OPC_LWX:
14525            gen_mipsdsp_ld(ctx, op2, rd, rs, rt);
14526            break;
14527        default:            /* Invalid */
14528            MIPS_INVAL("MASK LX");
14529            gen_reserved_instruction(ctx);
14530            break;
14531        }
14532        break;
14533    case OPC_ABSQ_S_PH_DSP:
14534        op2 = MASK_ABSQ_S_PH(ctx->opcode);
14535        switch (op2) {
14536        case OPC_ABSQ_S_QB:
14537        case OPC_ABSQ_S_PH:
14538        case OPC_ABSQ_S_W:
14539        case OPC_PRECEQ_W_PHL:
14540        case OPC_PRECEQ_W_PHR:
14541        case OPC_PRECEQU_PH_QBL:
14542        case OPC_PRECEQU_PH_QBR:
14543        case OPC_PRECEQU_PH_QBLA:
14544        case OPC_PRECEQU_PH_QBRA:
14545        case OPC_PRECEU_PH_QBL:
14546        case OPC_PRECEU_PH_QBR:
14547        case OPC_PRECEU_PH_QBLA:
14548        case OPC_PRECEU_PH_QBRA:
14549            gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
14550            break;
14551        case OPC_BITREV:
14552        case OPC_REPL_QB:
14553        case OPC_REPLV_QB:
14554        case OPC_REPL_PH:
14555        case OPC_REPLV_PH:
14556            gen_mipsdsp_bitinsn(ctx, op1, op2, rd, rt);
14557            break;
14558        default:
14559            MIPS_INVAL("MASK ABSQ_S.PH");
14560            gen_reserved_instruction(ctx);
14561            break;
14562        }
14563        break;
14564    case OPC_ADDU_QB_DSP:
14565        op2 = MASK_ADDU_QB(ctx->opcode);
14566        switch (op2) {
14567        case OPC_ADDQ_PH:
14568        case OPC_ADDQ_S_PH:
14569        case OPC_ADDQ_S_W:
14570        case OPC_ADDU_QB:
14571        case OPC_ADDU_S_QB:
14572        case OPC_ADDU_PH:
14573        case OPC_ADDU_S_PH:
14574        case OPC_SUBQ_PH:
14575        case OPC_SUBQ_S_PH:
14576        case OPC_SUBQ_S_W:
14577        case OPC_SUBU_QB:
14578        case OPC_SUBU_S_QB:
14579        case OPC_SUBU_PH:
14580        case OPC_SUBU_S_PH:
14581        case OPC_ADDSC:
14582        case OPC_ADDWC:
14583        case OPC_MODSUB:
14584        case OPC_RADDU_W_QB:
14585            gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
14586            break;
14587        case OPC_MULEU_S_PH_QBL:
14588        case OPC_MULEU_S_PH_QBR:
14589        case OPC_MULQ_RS_PH:
14590        case OPC_MULEQ_S_W_PHL:
14591        case OPC_MULEQ_S_W_PHR:
14592        case OPC_MULQ_S_PH:
14593            gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 1);
14594            break;
14595        default:            /* Invalid */
14596            MIPS_INVAL("MASK ADDU.QB");
14597            gen_reserved_instruction(ctx);
14598            break;
14599
14600        }
14601        break;
14602    case OPC_CMPU_EQ_QB_DSP:
14603        op2 = MASK_CMPU_EQ_QB(ctx->opcode);
14604        switch (op2) {
14605        case OPC_PRECR_SRA_PH_W:
14606        case OPC_PRECR_SRA_R_PH_W:
14607            gen_mipsdsp_arith(ctx, op1, op2, rt, rs, rd);
14608            break;
14609        case OPC_PRECR_QB_PH:
14610        case OPC_PRECRQ_QB_PH:
14611        case OPC_PRECRQ_PH_W:
14612        case OPC_PRECRQ_RS_PH_W:
14613        case OPC_PRECRQU_S_QB_PH:
14614            gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
14615            break;
14616        case OPC_CMPU_EQ_QB:
14617        case OPC_CMPU_LT_QB:
14618        case OPC_CMPU_LE_QB:
14619        case OPC_CMP_EQ_PH:
14620        case OPC_CMP_LT_PH:
14621        case OPC_CMP_LE_PH:
14622            gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 0);
14623            break;
14624        case OPC_CMPGU_EQ_QB:
14625        case OPC_CMPGU_LT_QB:
14626        case OPC_CMPGU_LE_QB:
14627        case OPC_CMPGDU_EQ_QB:
14628        case OPC_CMPGDU_LT_QB:
14629        case OPC_CMPGDU_LE_QB:
14630        case OPC_PICK_QB:
14631        case OPC_PICK_PH:
14632        case OPC_PACKRL_PH:
14633            gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 1);
14634            break;
14635        default:            /* Invalid */
14636            MIPS_INVAL("MASK CMPU.EQ.QB");
14637            gen_reserved_instruction(ctx);
14638            break;
14639        }
14640        break;
14641    case OPC_SHLL_QB_DSP:
14642        gen_mipsdsp_shift(ctx, op1, rd, rs, rt);
14643        break;
14644    case OPC_DPA_W_PH_DSP:
14645        op2 = MASK_DPA_W_PH(ctx->opcode);
14646        switch (op2) {
14647        case OPC_DPAU_H_QBL:
14648        case OPC_DPAU_H_QBR:
14649        case OPC_DPSU_H_QBL:
14650        case OPC_DPSU_H_QBR:
14651        case OPC_DPA_W_PH:
14652        case OPC_DPAX_W_PH:
14653        case OPC_DPAQ_S_W_PH:
14654        case OPC_DPAQX_S_W_PH:
14655        case OPC_DPAQX_SA_W_PH:
14656        case OPC_DPS_W_PH:
14657        case OPC_DPSX_W_PH:
14658        case OPC_DPSQ_S_W_PH:
14659        case OPC_DPSQX_S_W_PH:
14660        case OPC_DPSQX_SA_W_PH:
14661        case OPC_MULSAQ_S_W_PH:
14662        case OPC_DPAQ_SA_L_W:
14663        case OPC_DPSQ_SA_L_W:
14664        case OPC_MAQ_S_W_PHL:
14665        case OPC_MAQ_S_W_PHR:
14666        case OPC_MAQ_SA_W_PHL:
14667        case OPC_MAQ_SA_W_PHR:
14668        case OPC_MULSA_W_PH:
14669            gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 0);
14670            break;
14671        default:            /* Invalid */
14672            MIPS_INVAL("MASK DPAW.PH");
14673            gen_reserved_instruction(ctx);
14674            break;
14675        }
14676        break;
14677    case OPC_INSV_DSP:
14678        op2 = MASK_INSV(ctx->opcode);
14679        switch (op2) {
14680        case OPC_INSV:
14681            check_dsp(ctx);
14682            {
14683                TCGv t0, t1;
14684
14685                if (rt == 0) {
14686                    break;
14687                }
14688
14689                t0 = tcg_temp_new();
14690                t1 = tcg_temp_new();
14691
14692                gen_load_gpr(t0, rt);
14693                gen_load_gpr(t1, rs);
14694
14695                gen_helper_insv(cpu_gpr[rt], cpu_env, t1, t0);
14696
14697                tcg_temp_free(t0);
14698                tcg_temp_free(t1);
14699                break;
14700            }
14701        default:            /* Invalid */
14702            MIPS_INVAL("MASK INSV");
14703            gen_reserved_instruction(ctx);
14704            break;
14705        }
14706        break;
14707    case OPC_APPEND_DSP:
14708        gen_mipsdsp_append(env, ctx, op1, rt, rs, rd);
14709        break;
14710    case OPC_EXTR_W_DSP:
14711        op2 = MASK_EXTR_W(ctx->opcode);
14712        switch (op2) {
14713        case OPC_EXTR_W:
14714        case OPC_EXTR_R_W:
14715        case OPC_EXTR_RS_W:
14716        case OPC_EXTR_S_H:
14717        case OPC_EXTRV_S_H:
14718        case OPC_EXTRV_W:
14719        case OPC_EXTRV_R_W:
14720        case OPC_EXTRV_RS_W:
14721        case OPC_EXTP:
14722        case OPC_EXTPV:
14723        case OPC_EXTPDP:
14724        case OPC_EXTPDPV:
14725            gen_mipsdsp_accinsn(ctx, op1, op2, rt, rs, rd, 1);
14726            break;
14727        case OPC_RDDSP:
14728            gen_mipsdsp_accinsn(ctx, op1, op2, rd, rs, rt, 1);
14729            break;
14730        case OPC_SHILO:
14731        case OPC_SHILOV:
14732        case OPC_MTHLIP:
14733        case OPC_WRDSP:
14734            gen_mipsdsp_accinsn(ctx, op1, op2, rd, rs, rt, 0);
14735            break;
14736        default:            /* Invalid */
14737            MIPS_INVAL("MASK EXTR.W");
14738            gen_reserved_instruction(ctx);
14739            break;
14740        }
14741        break;
14742#if defined(TARGET_MIPS64)
14743    case OPC_DDIV_G_2E:
14744    case OPC_DDIVU_G_2E:
14745    case OPC_DMULT_G_2E:
14746    case OPC_DMULTU_G_2E:
14747    case OPC_DMOD_G_2E:
14748    case OPC_DMODU_G_2E:
14749        check_insn(ctx, INSN_LOONGSON2E);
14750        gen_loongson_integer(ctx, op1, rd, rs, rt);
14751        break;
14752    case OPC_ABSQ_S_QH_DSP:
14753        op2 = MASK_ABSQ_S_QH(ctx->opcode);
14754        switch (op2) {
14755        case OPC_PRECEQ_L_PWL:
14756        case OPC_PRECEQ_L_PWR:
14757        case OPC_PRECEQ_PW_QHL:
14758        case OPC_PRECEQ_PW_QHR:
14759        case OPC_PRECEQ_PW_QHLA:
14760        case OPC_PRECEQ_PW_QHRA:
14761        case OPC_PRECEQU_QH_OBL:
14762        case OPC_PRECEQU_QH_OBR:
14763        case OPC_PRECEQU_QH_OBLA:
14764        case OPC_PRECEQU_QH_OBRA:
14765        case OPC_PRECEU_QH_OBL:
14766        case OPC_PRECEU_QH_OBR:
14767        case OPC_PRECEU_QH_OBLA:
14768        case OPC_PRECEU_QH_OBRA:
14769        case OPC_ABSQ_S_OB:
14770        case OPC_ABSQ_S_PW:
14771        case OPC_ABSQ_S_QH:
14772            gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
14773            break;
14774        case OPC_REPL_OB:
14775        case OPC_REPL_PW:
14776        case OPC_REPL_QH:
14777        case OPC_REPLV_OB:
14778        case OPC_REPLV_PW:
14779        case OPC_REPLV_QH:
14780            gen_mipsdsp_bitinsn(ctx, op1, op2, rd, rt);
14781            break;
14782        default:            /* Invalid */
14783            MIPS_INVAL("MASK ABSQ_S.QH");
14784            gen_reserved_instruction(ctx);
14785            break;
14786        }
14787        break;
14788    case OPC_ADDU_OB_DSP:
14789        op2 = MASK_ADDU_OB(ctx->opcode);
14790        switch (op2) {
14791        case OPC_RADDU_L_OB:
14792        case OPC_SUBQ_PW:
14793        case OPC_SUBQ_S_PW:
14794        case OPC_SUBQ_QH:
14795        case OPC_SUBQ_S_QH:
14796        case OPC_SUBU_OB:
14797        case OPC_SUBU_S_OB:
14798        case OPC_SUBU_QH:
14799        case OPC_SUBU_S_QH:
14800        case OPC_SUBUH_OB:
14801        case OPC_SUBUH_R_OB:
14802        case OPC_ADDQ_PW:
14803        case OPC_ADDQ_S_PW:
14804        case OPC_ADDQ_QH:
14805        case OPC_ADDQ_S_QH:
14806        case OPC_ADDU_OB:
14807        case OPC_ADDU_S_OB:
14808        case OPC_ADDU_QH:
14809        case OPC_ADDU_S_QH:
14810        case OPC_ADDUH_OB:
14811        case OPC_ADDUH_R_OB:
14812            gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
14813            break;
14814        case OPC_MULEQ_S_PW_QHL:
14815        case OPC_MULEQ_S_PW_QHR:
14816        case OPC_MULEU_S_QH_OBL:
14817        case OPC_MULEU_S_QH_OBR:
14818        case OPC_MULQ_RS_QH:
14819            gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 1);
14820            break;
14821        default:            /* Invalid */
14822            MIPS_INVAL("MASK ADDU.OB");
14823            gen_reserved_instruction(ctx);
14824            break;
14825        }
14826        break;
14827    case OPC_CMPU_EQ_OB_DSP:
14828        op2 = MASK_CMPU_EQ_OB(ctx->opcode);
14829        switch (op2) {
14830        case OPC_PRECR_SRA_QH_PW:
14831        case OPC_PRECR_SRA_R_QH_PW:
14832            /* Return value is rt. */
14833            gen_mipsdsp_arith(ctx, op1, op2, rt, rs, rd);
14834            break;
14835        case OPC_PRECR_OB_QH:
14836        case OPC_PRECRQ_OB_QH:
14837        case OPC_PRECRQ_PW_L:
14838        case OPC_PRECRQ_QH_PW:
14839        case OPC_PRECRQ_RS_QH_PW:
14840        case OPC_PRECRQU_S_OB_QH:
14841            gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
14842            break;
14843        case OPC_CMPU_EQ_OB:
14844        case OPC_CMPU_LT_OB:
14845        case OPC_CMPU_LE_OB:
14846        case OPC_CMP_EQ_QH:
14847        case OPC_CMP_LT_QH:
14848        case OPC_CMP_LE_QH:
14849        case OPC_CMP_EQ_PW:
14850        case OPC_CMP_LT_PW:
14851        case OPC_CMP_LE_PW:
14852            gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 0);
14853            break;
14854        case OPC_CMPGDU_EQ_OB:
14855        case OPC_CMPGDU_LT_OB:
14856        case OPC_CMPGDU_LE_OB:
14857        case OPC_CMPGU_EQ_OB:
14858        case OPC_CMPGU_LT_OB:
14859        case OPC_CMPGU_LE_OB:
14860        case OPC_PACKRL_PW:
14861        case OPC_PICK_OB:
14862        case OPC_PICK_PW:
14863        case OPC_PICK_QH:
14864            gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 1);
14865            break;
14866        default:            /* Invalid */
14867            MIPS_INVAL("MASK CMPU_EQ.OB");
14868            gen_reserved_instruction(ctx);
14869            break;
14870        }
14871        break;
14872    case OPC_DAPPEND_DSP:
14873        gen_mipsdsp_append(env, ctx, op1, rt, rs, rd);
14874        break;
14875    case OPC_DEXTR_W_DSP:
14876        op2 = MASK_DEXTR_W(ctx->opcode);
14877        switch (op2) {
14878        case OPC_DEXTP:
14879        case OPC_DEXTPDP:
14880        case OPC_DEXTPDPV:
14881        case OPC_DEXTPV:
14882        case OPC_DEXTR_L:
14883        case OPC_DEXTR_R_L:
14884        case OPC_DEXTR_RS_L:
14885        case OPC_DEXTR_W:
14886        case OPC_DEXTR_R_W:
14887        case OPC_DEXTR_RS_W:
14888        case OPC_DEXTR_S_H:
14889        case OPC_DEXTRV_L:
14890        case OPC_DEXTRV_R_L:
14891        case OPC_DEXTRV_RS_L:
14892        case OPC_DEXTRV_S_H:
14893        case OPC_DEXTRV_W:
14894        case OPC_DEXTRV_R_W:
14895        case OPC_DEXTRV_RS_W:
14896            gen_mipsdsp_accinsn(ctx, op1, op2, rt, rs, rd, 1);
14897            break;
14898        case OPC_DMTHLIP:
14899        case OPC_DSHILO:
14900        case OPC_DSHILOV:
14901            gen_mipsdsp_accinsn(ctx, op1, op2, rd, rs, rt, 0);
14902            break;
14903        default:            /* Invalid */
14904            MIPS_INVAL("MASK EXTR.W");
14905            gen_reserved_instruction(ctx);
14906            break;
14907        }
14908        break;
14909    case OPC_DPAQ_W_QH_DSP:
14910        op2 = MASK_DPAQ_W_QH(ctx->opcode);
14911        switch (op2) {
14912        case OPC_DPAU_H_OBL:
14913        case OPC_DPAU_H_OBR:
14914        case OPC_DPSU_H_OBL:
14915        case OPC_DPSU_H_OBR:
14916        case OPC_DPA_W_QH:
14917        case OPC_DPAQ_S_W_QH:
14918        case OPC_DPS_W_QH:
14919        case OPC_DPSQ_S_W_QH:
14920        case OPC_MULSAQ_S_W_QH:
14921        case OPC_DPAQ_SA_L_PW:
14922        case OPC_DPSQ_SA_L_PW:
14923        case OPC_MULSAQ_S_L_PW:
14924            gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 0);
14925            break;
14926        case OPC_MAQ_S_W_QHLL:
14927        case OPC_MAQ_S_W_QHLR:
14928        case OPC_MAQ_S_W_QHRL:
14929        case OPC_MAQ_S_W_QHRR:
14930        case OPC_MAQ_SA_W_QHLL:
14931        case OPC_MAQ_SA_W_QHLR:
14932        case OPC_MAQ_SA_W_QHRL:
14933        case OPC_MAQ_SA_W_QHRR:
14934        case OPC_MAQ_S_L_PWL:
14935        case OPC_MAQ_S_L_PWR:
14936        case OPC_DMADD:
14937        case OPC_DMADDU:
14938        case OPC_DMSUB:
14939        case OPC_DMSUBU:
14940            gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 0);
14941            break;
14942        default:            /* Invalid */
14943            MIPS_INVAL("MASK DPAQ.W.QH");
14944            gen_reserved_instruction(ctx);
14945            break;
14946        }
14947        break;
14948    case OPC_DINSV_DSP:
14949        op2 = MASK_INSV(ctx->opcode);
14950        switch (op2) {
14951        case OPC_DINSV:
14952        {
14953            TCGv t0, t1;
14954
14955            check_dsp(ctx);
14956
14957            if (rt == 0) {
14958                break;
14959            }
14960
14961            t0 = tcg_temp_new();
14962            t1 = tcg_temp_new();
14963
14964            gen_load_gpr(t0, rt);
14965            gen_load_gpr(t1, rs);
14966
14967            gen_helper_dinsv(cpu_gpr[rt], cpu_env, t1, t0);
14968
14969            tcg_temp_free(t0);
14970            tcg_temp_free(t1);
14971            break;
14972        }
14973        default:            /* Invalid */
14974            MIPS_INVAL("MASK DINSV");
14975            gen_reserved_instruction(ctx);
14976            break;
14977        }
14978        break;
14979    case OPC_SHLL_OB_DSP:
14980        gen_mipsdsp_shift(ctx, op1, rd, rs, rt);
14981        break;
14982#endif
14983    default:            /* Invalid */
14984        MIPS_INVAL("special3_legacy");
14985        gen_reserved_instruction(ctx);
14986        break;
14987    }
14988}
14989
14990
14991#if defined(TARGET_MIPS64)
14992
14993static void decode_mmi(CPUMIPSState *env, DisasContext *ctx)
14994{
14995    uint32_t opc = MASK_MMI(ctx->opcode);
14996    int rs = extract32(ctx->opcode, 21, 5);
14997    int rt = extract32(ctx->opcode, 16, 5);
14998    int rd = extract32(ctx->opcode, 11, 5);
14999
15000    switch (opc) {
15001    case MMI_OPC_MULT1:
15002    case MMI_OPC_MULTU1:
15003    case MMI_OPC_MADD:
15004    case MMI_OPC_MADDU:
15005    case MMI_OPC_MADD1:
15006    case MMI_OPC_MADDU1:
15007        gen_mul_txx9(ctx, opc, rd, rs, rt);
15008        break;
15009    case MMI_OPC_DIV1:
15010    case MMI_OPC_DIVU1:
15011        gen_div1_tx79(ctx, opc, rs, rt);
15012        break;
15013    default:
15014        MIPS_INVAL("TX79 MMI class");
15015        gen_reserved_instruction(ctx);
15016        break;
15017    }
15018}
15019
15020static void gen_mmi_sq(DisasContext *ctx, int base, int rt, int offset)
15021{
15022    gen_reserved_instruction(ctx);    /* TODO: MMI_OPC_SQ */
15023}
15024
15025/*
15026 * The TX79-specific instruction Store Quadword
15027 *
15028 * +--------+-------+-------+------------------------+
15029 * | 011111 |  base |   rt  |           offset       | SQ
15030 * +--------+-------+-------+------------------------+
15031 *      6       5       5                 16
15032 *
15033 * has the same opcode as the Read Hardware Register instruction
15034 *
15035 * +--------+-------+-------+-------+-------+--------+
15036 * | 011111 | 00000 |   rt  |   rd  | 00000 | 111011 | RDHWR
15037 * +--------+-------+-------+-------+-------+--------+
15038 *      6       5       5       5       5        6
15039 *
15040 * that is required, trapped and emulated by the Linux kernel. However, all
15041 * RDHWR encodings yield address error exceptions on the TX79 since the SQ
15042 * offset is odd. Therefore all valid SQ instructions can execute normally.
15043 * In user mode, QEMU must verify the upper and lower 11 bits to distinguish
15044 * between SQ and RDHWR, as the Linux kernel does.
15045 */
15046static void decode_mmi_sq(CPUMIPSState *env, DisasContext *ctx)
15047{
15048    int base = extract32(ctx->opcode, 21, 5);
15049    int rt = extract32(ctx->opcode, 16, 5);
15050    int offset = extract32(ctx->opcode, 0, 16);
15051
15052#ifdef CONFIG_USER_ONLY
15053    uint32_t op1 = MASK_SPECIAL3(ctx->opcode);
15054    uint32_t op2 = extract32(ctx->opcode, 6, 5);
15055
15056    if (base == 0 && op2 == 0 && op1 == OPC_RDHWR) {
15057        int rd = extract32(ctx->opcode, 11, 5);
15058
15059        gen_rdhwr(ctx, rt, rd, 0);
15060        return;
15061    }
15062#endif
15063
15064    gen_mmi_sq(ctx, base, rt, offset);
15065}
15066
15067#endif
15068
15069static void decode_opc_special3(CPUMIPSState *env, DisasContext *ctx)
15070{
15071    int rs, rt, rd, sa;
15072    uint32_t op1, op2;
15073    int16_t imm;
15074
15075    rs = (ctx->opcode >> 21) & 0x1f;
15076    rt = (ctx->opcode >> 16) & 0x1f;
15077    rd = (ctx->opcode >> 11) & 0x1f;
15078    sa = (ctx->opcode >> 6) & 0x1f;
15079    imm = sextract32(ctx->opcode, 7, 9);
15080
15081    op1 = MASK_SPECIAL3(ctx->opcode);
15082
15083    /*
15084     * EVA loads and stores overlap Loongson 2E instructions decoded by
15085     * decode_opc_special3_legacy(), so be careful to allow their decoding when
15086     * EVA is absent.
15087     */
15088    if (ctx->eva) {
15089        switch (op1) {
15090        case OPC_LWLE:
15091        case OPC_LWRE:
15092        case OPC_LBUE:
15093        case OPC_LHUE:
15094        case OPC_LBE:
15095        case OPC_LHE:
15096        case OPC_LLE:
15097        case OPC_LWE:
15098            check_cp0_enabled(ctx);
15099            gen_ld(ctx, op1, rt, rs, imm);
15100            return;
15101        case OPC_SWLE:
15102        case OPC_SWRE:
15103        case OPC_SBE:
15104        case OPC_SHE:
15105        case OPC_SWE:
15106            check_cp0_enabled(ctx);
15107            gen_st(ctx, op1, rt, rs, imm);
15108            return;
15109        case OPC_SCE:
15110            check_cp0_enabled(ctx);
15111            gen_st_cond(ctx, rt, rs, imm, MO_TESL, true);
15112            return;
15113        case OPC_CACHEE:
15114            check_eva(ctx);
15115            check_cp0_enabled(ctx);
15116            if (ctx->hflags & MIPS_HFLAG_ITC_CACHE) {
15117                gen_cache_operation(ctx, rt, rs, imm);
15118            }
15119            return;
15120        case OPC_PREFE:
15121            check_cp0_enabled(ctx);
15122            /* Treat as NOP. */
15123            return;
15124        }
15125    }
15126
15127    switch (op1) {
15128    case OPC_EXT:
15129    case OPC_INS:
15130        check_insn(ctx, ISA_MIPS_R2);
15131        gen_bitops(ctx, op1, rt, rs, sa, rd);
15132        break;
15133    case OPC_BSHFL:
15134        op2 = MASK_BSHFL(ctx->opcode);
15135        switch (op2) {
15136        case OPC_ALIGN:
15137        case OPC_ALIGN_1:
15138        case OPC_ALIGN_2:
15139        case OPC_ALIGN_3:
15140        case OPC_BITSWAP:
15141            check_insn(ctx, ISA_MIPS_R6);
15142            decode_opc_special3_r6(env, ctx);
15143            break;
15144        default:
15145            check_insn(ctx, ISA_MIPS_R2);
15146            gen_bshfl(ctx, op2, rt, rd);
15147            break;
15148        }
15149        break;
15150#if defined(TARGET_MIPS64)
15151    case OPC_DEXTM:
15152    case OPC_DEXTU:
15153    case OPC_DEXT:
15154    case OPC_DINSM:
15155    case OPC_DINSU:
15156    case OPC_DINS:
15157        check_insn(ctx, ISA_MIPS_R2);
15158        check_mips_64(ctx);
15159        gen_bitops(ctx, op1, rt, rs, sa, rd);
15160        break;
15161    case OPC_DBSHFL:
15162        op2 = MASK_DBSHFL(ctx->opcode);
15163        switch (op2) {
15164        case OPC_DALIGN:
15165        case OPC_DALIGN_1:
15166        case OPC_DALIGN_2:
15167        case OPC_DALIGN_3:
15168        case OPC_DALIGN_4:
15169        case OPC_DALIGN_5:
15170        case OPC_DALIGN_6:
15171        case OPC_DALIGN_7:
15172        case OPC_DBITSWAP:
15173            check_insn(ctx, ISA_MIPS_R6);
15174            decode_opc_special3_r6(env, ctx);
15175            break;
15176        default:
15177            check_insn(ctx, ISA_MIPS_R2);
15178            check_mips_64(ctx);
15179            op2 = MASK_DBSHFL(ctx->opcode);
15180            gen_bshfl(ctx, op2, rt, rd);
15181            break;
15182        }
15183        break;
15184#endif
15185    case OPC_RDHWR:
15186        gen_rdhwr(ctx, rt, rd, extract32(ctx->opcode, 6, 3));
15187        break;
15188    case OPC_FORK:
15189        check_mt(ctx);
15190        {
15191            TCGv t0 = tcg_temp_new();
15192            TCGv t1 = tcg_temp_new();
15193
15194            gen_load_gpr(t0, rt);
15195            gen_load_gpr(t1, rs);
15196            gen_helper_fork(t0, t1);
15197            tcg_temp_free(t0);
15198            tcg_temp_free(t1);
15199        }
15200        break;
15201    case OPC_YIELD:
15202        check_mt(ctx);
15203        {
15204            TCGv t0 = tcg_temp_new();
15205
15206            gen_load_gpr(t0, rs);
15207            gen_helper_yield(t0, cpu_env, t0);
15208            gen_store_gpr(t0, rd);
15209            tcg_temp_free(t0);
15210        }
15211        break;
15212    default:
15213        if (ctx->insn_flags & ISA_MIPS_R6) {
15214            decode_opc_special3_r6(env, ctx);
15215        } else {
15216            decode_opc_special3_legacy(env, ctx);
15217        }
15218    }
15219}
15220
15221static bool decode_opc_legacy(CPUMIPSState *env, DisasContext *ctx)
15222{
15223    int32_t offset;
15224    int rs, rt, rd, sa;
15225    uint32_t op, op1;
15226    int16_t imm;
15227
15228    op = MASK_OP_MAJOR(ctx->opcode);
15229    rs = (ctx->opcode >> 21) & 0x1f;
15230    rt = (ctx->opcode >> 16) & 0x1f;
15231    rd = (ctx->opcode >> 11) & 0x1f;
15232    sa = (ctx->opcode >> 6) & 0x1f;
15233    imm = (int16_t)ctx->opcode;
15234    switch (op) {
15235    case OPC_SPECIAL:
15236        decode_opc_special(env, ctx);
15237        break;
15238    case OPC_SPECIAL2:
15239#if defined(TARGET_MIPS64)
15240        if ((ctx->insn_flags & INSN_R5900) && (ctx->insn_flags & ASE_MMI)) {
15241            decode_mmi(env, ctx);
15242            break;
15243        }
15244#endif
15245        if (TARGET_LONG_BITS == 32 && (ctx->insn_flags & ASE_MXU)) {
15246            if (MASK_SPECIAL2(ctx->opcode) == OPC_MUL) {
15247                gen_arith(ctx, OPC_MUL, rd, rs, rt);
15248            } else {
15249                decode_ase_mxu(ctx, ctx->opcode);
15250            }
15251            break;
15252        }
15253        decode_opc_special2_legacy(env, ctx);
15254        break;
15255    case OPC_SPECIAL3:
15256#if defined(TARGET_MIPS64)
15257        if (ctx->insn_flags & INSN_R5900) {
15258            decode_mmi_sq(env, ctx);    /* MMI_OPC_SQ */
15259        } else {
15260            decode_opc_special3(env, ctx);
15261        }
15262#else
15263        decode_opc_special3(env, ctx);
15264#endif
15265        break;
15266    case OPC_REGIMM:
15267        op1 = MASK_REGIMM(ctx->opcode);
15268        switch (op1) {
15269        case OPC_BLTZL: /* REGIMM branches */
15270        case OPC_BGEZL:
15271        case OPC_BLTZALL:
15272        case OPC_BGEZALL:
15273            check_insn(ctx, ISA_MIPS2);
15274            check_insn_opc_removed(ctx, ISA_MIPS_R6);
15275            /* Fallthrough */
15276        case OPC_BLTZ:
15277        case OPC_BGEZ:
15278            gen_compute_branch(ctx, op1, 4, rs, -1, imm << 2, 4);
15279            break;
15280        case OPC_BLTZAL:
15281        case OPC_BGEZAL:
15282            if (ctx->insn_flags & ISA_MIPS_R6) {
15283                if (rs == 0) {
15284                    /* OPC_NAL, OPC_BAL */
15285                    gen_compute_branch(ctx, op1, 4, 0, -1, imm << 2, 4);
15286                } else {
15287                    gen_reserved_instruction(ctx);
15288                }
15289            } else {
15290                gen_compute_branch(ctx, op1, 4, rs, -1, imm << 2, 4);
15291            }
15292            break;
15293        case OPC_TGEI: /* REGIMM traps */
15294        case OPC_TGEIU:
15295        case OPC_TLTI:
15296        case OPC_TLTIU:
15297        case OPC_TEQI:
15298        case OPC_TNEI:
15299            check_insn(ctx, ISA_MIPS2);
15300            check_insn_opc_removed(ctx, ISA_MIPS_R6);
15301            gen_trap(ctx, op1, rs, -1, imm, 0);
15302            break;
15303        case OPC_SIGRIE:
15304            check_insn(ctx, ISA_MIPS_R6);
15305            gen_reserved_instruction(ctx);
15306            break;
15307        case OPC_SYNCI:
15308            check_insn(ctx, ISA_MIPS_R2);
15309            /*
15310             * Break the TB to be able to sync copied instructions
15311             * immediately.
15312             */
15313            ctx->base.is_jmp = DISAS_STOP;
15314            break;
15315        case OPC_BPOSGE32:    /* MIPS DSP branch */
15316#if defined(TARGET_MIPS64)
15317        case OPC_BPOSGE64:
15318#endif
15319            check_dsp(ctx);
15320            gen_compute_branch(ctx, op1, 4, -1, -2, (int32_t)imm << 2, 4);
15321            break;
15322#if defined(TARGET_MIPS64)
15323        case OPC_DAHI:
15324            check_insn(ctx, ISA_MIPS_R6);
15325            check_mips_64(ctx);
15326            if (rs != 0) {
15327                tcg_gen_addi_tl(cpu_gpr[rs], cpu_gpr[rs], (int64_t)imm << 32);
15328            }
15329            break;
15330        case OPC_DATI:
15331            check_insn(ctx, ISA_MIPS_R6);
15332            check_mips_64(ctx);
15333            if (rs != 0) {
15334                tcg_gen_addi_tl(cpu_gpr[rs], cpu_gpr[rs], (int64_t)imm << 48);
15335            }
15336            break;
15337#endif
15338        default:            /* Invalid */
15339            MIPS_INVAL("regimm");
15340            gen_reserved_instruction(ctx);
15341            break;
15342        }
15343        break;
15344    case OPC_CP0:
15345        check_cp0_enabled(ctx);
15346        op1 = MASK_CP0(ctx->opcode);
15347        switch (op1) {
15348        case OPC_MFC0:
15349        case OPC_MTC0:
15350        case OPC_MFTR:
15351        case OPC_MTTR:
15352        case OPC_MFHC0:
15353        case OPC_MTHC0:
15354#if defined(TARGET_MIPS64)
15355        case OPC_DMFC0:
15356        case OPC_DMTC0:
15357#endif
15358#ifndef CONFIG_USER_ONLY
15359            gen_cp0(env, ctx, op1, rt, rd);
15360#endif /* !CONFIG_USER_ONLY */
15361            break;
15362        case OPC_C0:
15363        case OPC_C0_1:
15364        case OPC_C0_2:
15365        case OPC_C0_3:
15366        case OPC_C0_4:
15367        case OPC_C0_5:
15368        case OPC_C0_6:
15369        case OPC_C0_7:
15370        case OPC_C0_8:
15371        case OPC_C0_9:
15372        case OPC_C0_A:
15373        case OPC_C0_B:
15374        case OPC_C0_C:
15375        case OPC_C0_D:
15376        case OPC_C0_E:
15377        case OPC_C0_F:
15378#ifndef CONFIG_USER_ONLY
15379            gen_cp0(env, ctx, MASK_C0(ctx->opcode), rt, rd);
15380#endif /* !CONFIG_USER_ONLY */
15381            break;
15382        case OPC_MFMC0:
15383#ifndef CONFIG_USER_ONLY
15384            {
15385                uint32_t op2;
15386                TCGv t0 = tcg_temp_new();
15387
15388                op2 = MASK_MFMC0(ctx->opcode);
15389                switch (op2) {
15390                case OPC_DMT:
15391                    check_cp0_mt(ctx);
15392                    gen_helper_dmt(t0);
15393                    gen_store_gpr(t0, rt);
15394                    break;
15395                case OPC_EMT:
15396                    check_cp0_mt(ctx);
15397                    gen_helper_emt(t0);
15398                    gen_store_gpr(t0, rt);
15399                    break;
15400                case OPC_DVPE:
15401                    check_cp0_mt(ctx);
15402                    gen_helper_dvpe(t0, cpu_env);
15403                    gen_store_gpr(t0, rt);
15404                    break;
15405                case OPC_EVPE:
15406                    check_cp0_mt(ctx);
15407                    gen_helper_evpe(t0, cpu_env);
15408                    gen_store_gpr(t0, rt);
15409                    break;
15410                case OPC_DVP:
15411                    check_insn(ctx, ISA_MIPS_R6);
15412                    if (ctx->vp) {
15413                        gen_helper_dvp(t0, cpu_env);
15414                        gen_store_gpr(t0, rt);
15415                    }
15416                    break;
15417                case OPC_EVP:
15418                    check_insn(ctx, ISA_MIPS_R6);
15419                    if (ctx->vp) {
15420                        gen_helper_evp(t0, cpu_env);
15421                        gen_store_gpr(t0, rt);
15422                    }
15423                    break;
15424                case OPC_DI:
15425                    check_insn(ctx, ISA_MIPS_R2);
15426                    save_cpu_state(ctx, 1);
15427                    gen_helper_di(t0, cpu_env);
15428                    gen_store_gpr(t0, rt);
15429                    /*
15430                     * Stop translation as we may have switched
15431                     * the execution mode.
15432                     */
15433                    ctx->base.is_jmp = DISAS_STOP;
15434                    break;
15435                case OPC_EI:
15436                    check_insn(ctx, ISA_MIPS_R2);
15437                    save_cpu_state(ctx, 1);
15438                    gen_helper_ei(t0, cpu_env);
15439                    gen_store_gpr(t0, rt);
15440                    /*
15441                     * DISAS_STOP isn't sufficient, we need to ensure we break
15442                     * out of translated code to check for pending interrupts.
15443                     */
15444                    gen_save_pc(ctx->base.pc_next + 4);
15445                    ctx->base.is_jmp = DISAS_EXIT;
15446                    break;
15447                default:            /* Invalid */
15448                    MIPS_INVAL("mfmc0");
15449                    gen_reserved_instruction(ctx);
15450                    break;
15451                }
15452                tcg_temp_free(t0);
15453            }
15454#endif /* !CONFIG_USER_ONLY */
15455            break;
15456        case OPC_RDPGPR:
15457            check_insn(ctx, ISA_MIPS_R2);
15458            gen_load_srsgpr(rt, rd);
15459            break;
15460        case OPC_WRPGPR:
15461            check_insn(ctx, ISA_MIPS_R2);
15462            gen_store_srsgpr(rt, rd);
15463            break;
15464        default:
15465            MIPS_INVAL("cp0");
15466            gen_reserved_instruction(ctx);
15467            break;
15468        }
15469        break;
15470    case OPC_BOVC: /* OPC_BEQZALC, OPC_BEQC, OPC_ADDI */
15471        if (ctx->insn_flags & ISA_MIPS_R6) {
15472            /* OPC_BOVC, OPC_BEQZALC, OPC_BEQC */
15473            gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
15474        } else {
15475            /* OPC_ADDI */
15476            /* Arithmetic with immediate opcode */
15477            gen_arith_imm(ctx, op, rt, rs, imm);
15478        }
15479        break;
15480    case OPC_ADDIU:
15481         gen_arith_imm(ctx, op, rt, rs, imm);
15482         break;
15483    case OPC_SLTI: /* Set on less than with immediate opcode */
15484    case OPC_SLTIU:
15485         gen_slt_imm(ctx, op, rt, rs, imm);
15486         break;
15487    case OPC_ANDI: /* Arithmetic with immediate opcode */
15488    case OPC_LUI: /* OPC_AUI */
15489    case OPC_ORI:
15490    case OPC_XORI:
15491         gen_logic_imm(ctx, op, rt, rs, imm);
15492         break;
15493    case OPC_J: /* Jump */
15494    case OPC_JAL:
15495         offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 2;
15496         gen_compute_branch(ctx, op, 4, rs, rt, offset, 4);
15497         break;
15498    /* Branch */
15499    case OPC_BLEZC: /* OPC_BGEZC, OPC_BGEC, OPC_BLEZL */
15500        if (ctx->insn_flags & ISA_MIPS_R6) {
15501            if (rt == 0) {
15502                gen_reserved_instruction(ctx);
15503                break;
15504            }
15505            /* OPC_BLEZC, OPC_BGEZC, OPC_BGEC */
15506            gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
15507        } else {
15508            /* OPC_BLEZL */
15509            gen_compute_branch(ctx, op, 4, rs, rt, imm << 2, 4);
15510        }
15511        break;
15512    case OPC_BGTZC: /* OPC_BLTZC, OPC_BLTC, OPC_BGTZL */
15513        if (ctx->insn_flags & ISA_MIPS_R6) {
15514            if (rt == 0) {
15515                gen_reserved_instruction(ctx);
15516                break;
15517            }
15518            /* OPC_BGTZC, OPC_BLTZC, OPC_BLTC */
15519            gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
15520        } else {
15521            /* OPC_BGTZL */
15522            gen_compute_branch(ctx, op, 4, rs, rt, imm << 2, 4);
15523        }
15524        break;
15525    case OPC_BLEZALC: /* OPC_BGEZALC, OPC_BGEUC, OPC_BLEZ */
15526        if (rt == 0) {
15527            /* OPC_BLEZ */
15528            gen_compute_branch(ctx, op, 4, rs, rt, imm << 2, 4);
15529        } else {
15530            check_insn(ctx, ISA_MIPS_R6);
15531            /* OPC_BLEZALC, OPC_BGEZALC, OPC_BGEUC */
15532            gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
15533        }
15534        break;
15535    case OPC_BGTZALC: /* OPC_BLTZALC, OPC_BLTUC, OPC_BGTZ */
15536        if (rt == 0) {
15537            /* OPC_BGTZ */
15538            gen_compute_branch(ctx, op, 4, rs, rt, imm << 2, 4);
15539        } else {
15540            check_insn(ctx, ISA_MIPS_R6);
15541            /* OPC_BGTZALC, OPC_BLTZALC, OPC_BLTUC */
15542            gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
15543        }
15544        break;
15545    case OPC_BEQL:
15546    case OPC_BNEL:
15547        check_insn(ctx, ISA_MIPS2);
15548         check_insn_opc_removed(ctx, ISA_MIPS_R6);
15549        /* Fallthrough */
15550    case OPC_BEQ:
15551    case OPC_BNE:
15552         gen_compute_branch(ctx, op, 4, rs, rt, imm << 2, 4);
15553         break;
15554    case OPC_LL: /* Load and stores */
15555        check_insn(ctx, ISA_MIPS2);
15556        if (ctx->insn_flags & INSN_R5900) {
15557            check_insn_opc_user_only(ctx, INSN_R5900);
15558        }
15559        /* Fallthrough */
15560    case OPC_LWL:
15561    case OPC_LWR:
15562    case OPC_LB:
15563    case OPC_LH:
15564    case OPC_LW:
15565    case OPC_LWPC:
15566    case OPC_LBU:
15567    case OPC_LHU:
15568         gen_ld(ctx, op, rt, rs, imm);
15569         break;
15570    case OPC_SWL:
15571    case OPC_SWR:
15572    case OPC_SB:
15573    case OPC_SH:
15574    case OPC_SW:
15575         gen_st(ctx, op, rt, rs, imm);
15576         break;
15577    case OPC_SC:
15578        check_insn(ctx, ISA_MIPS2);
15579        if (ctx->insn_flags & INSN_R5900) {
15580            check_insn_opc_user_only(ctx, INSN_R5900);
15581        }
15582        gen_st_cond(ctx, rt, rs, imm, MO_TESL, false);
15583        break;
15584    case OPC_CACHE:
15585        check_cp0_enabled(ctx);
15586        check_insn(ctx, ISA_MIPS3 | ISA_MIPS_R1);
15587        if (ctx->hflags & MIPS_HFLAG_ITC_CACHE) {
15588            gen_cache_operation(ctx, rt, rs, imm);
15589        }
15590        /* Treat as NOP. */
15591        break;
15592    case OPC_PREF:
15593        check_insn(ctx, ISA_MIPS4 | ISA_MIPS_R1 | INSN_R5900);
15594        /* Treat as NOP. */
15595        break;
15596
15597    /* Floating point (COP1). */
15598    case OPC_LWC1:
15599    case OPC_LDC1:
15600    case OPC_SWC1:
15601    case OPC_SDC1:
15602        gen_cop1_ldst(ctx, op, rt, rs, imm);
15603        break;
15604
15605    case OPC_CP1:
15606        op1 = MASK_CP1(ctx->opcode);
15607
15608        switch (op1) {
15609        case OPC_MFHC1:
15610        case OPC_MTHC1:
15611            check_cp1_enabled(ctx);
15612            check_insn(ctx, ISA_MIPS_R2);
15613            /* fall through */
15614        case OPC_MFC1:
15615        case OPC_CFC1:
15616        case OPC_MTC1:
15617        case OPC_CTC1:
15618            check_cp1_enabled(ctx);
15619            gen_cp1(ctx, op1, rt, rd);
15620            break;
15621#if defined(TARGET_MIPS64)
15622        case OPC_DMFC1:
15623        case OPC_DMTC1:
15624            check_cp1_enabled(ctx);
15625            check_insn(ctx, ISA_MIPS3);
15626            check_mips_64(ctx);
15627            gen_cp1(ctx, op1, rt, rd);
15628            break;
15629#endif
15630        case OPC_BC1EQZ: /* OPC_BC1ANY2 */
15631            check_cp1_enabled(ctx);
15632            if (ctx->insn_flags & ISA_MIPS_R6) {
15633                /* OPC_BC1EQZ */
15634                gen_compute_branch1_r6(ctx, MASK_CP1(ctx->opcode),
15635                                       rt, imm << 2, 4);
15636            } else {
15637                /* OPC_BC1ANY2 */
15638                check_cop1x(ctx);
15639                check_insn(ctx, ASE_MIPS3D);
15640                gen_compute_branch1(ctx, MASK_BC1(ctx->opcode),
15641                                    (rt >> 2) & 0x7, imm << 2);
15642            }
15643            break;
15644        case OPC_BC1NEZ:
15645            check_cp1_enabled(ctx);
15646            check_insn(ctx, ISA_MIPS_R6);
15647            gen_compute_branch1_r6(ctx, MASK_CP1(ctx->opcode),
15648                                   rt, imm << 2, 4);
15649            break;
15650        case OPC_BC1ANY4:
15651            check_cp1_enabled(ctx);
15652            check_insn_opc_removed(ctx, ISA_MIPS_R6);
15653            check_cop1x(ctx);
15654            check_insn(ctx, ASE_MIPS3D);
15655            /* fall through */
15656        case OPC_BC1:
15657            check_cp1_enabled(ctx);
15658            check_insn_opc_removed(ctx, ISA_MIPS_R6);
15659            gen_compute_branch1(ctx, MASK_BC1(ctx->opcode),
15660                                (rt >> 2) & 0x7, imm << 2);
15661            break;
15662        case OPC_PS_FMT:
15663            check_ps(ctx);
15664            /* fall through */
15665        case OPC_S_FMT:
15666        case OPC_D_FMT:
15667            check_cp1_enabled(ctx);
15668            gen_farith(ctx, ctx->opcode & FOP(0x3f, 0x1f), rt, rd, sa,
15669                       (imm >> 8) & 0x7);
15670            break;
15671        case OPC_W_FMT:
15672        case OPC_L_FMT:
15673        {
15674            int r6_op = ctx->opcode & FOP(0x3f, 0x1f);
15675            check_cp1_enabled(ctx);
15676            if (ctx->insn_flags & ISA_MIPS_R6) {
15677                switch (r6_op) {
15678                case R6_OPC_CMP_AF_S:
15679                case R6_OPC_CMP_UN_S:
15680                case R6_OPC_CMP_EQ_S:
15681                case R6_OPC_CMP_UEQ_S:
15682                case R6_OPC_CMP_LT_S:
15683                case R6_OPC_CMP_ULT_S:
15684                case R6_OPC_CMP_LE_S:
15685                case R6_OPC_CMP_ULE_S:
15686                case R6_OPC_CMP_SAF_S:
15687                case R6_OPC_CMP_SUN_S:
15688                case R6_OPC_CMP_SEQ_S:
15689                case R6_OPC_CMP_SEUQ_S:
15690                case R6_OPC_CMP_SLT_S:
15691                case R6_OPC_CMP_SULT_S:
15692                case R6_OPC_CMP_SLE_S:
15693                case R6_OPC_CMP_SULE_S:
15694                case R6_OPC_CMP_OR_S:
15695                case R6_OPC_CMP_UNE_S:
15696                case R6_OPC_CMP_NE_S:
15697                case R6_OPC_CMP_SOR_S:
15698                case R6_OPC_CMP_SUNE_S:
15699                case R6_OPC_CMP_SNE_S:
15700                    gen_r6_cmp_s(ctx, ctx->opcode & 0x1f, rt, rd, sa);
15701                    break;
15702                case R6_OPC_CMP_AF_D:
15703                case R6_OPC_CMP_UN_D:
15704                case R6_OPC_CMP_EQ_D:
15705                case R6_OPC_CMP_UEQ_D:
15706                case R6_OPC_CMP_LT_D:
15707                case R6_OPC_CMP_ULT_D:
15708                case R6_OPC_CMP_LE_D:
15709                case R6_OPC_CMP_ULE_D:
15710                case R6_OPC_CMP_SAF_D:
15711                case R6_OPC_CMP_SUN_D:
15712                case R6_OPC_CMP_SEQ_D:
15713                case R6_OPC_CMP_SEUQ_D:
15714                case R6_OPC_CMP_SLT_D:
15715                case R6_OPC_CMP_SULT_D:
15716                case R6_OPC_CMP_SLE_D:
15717                case R6_OPC_CMP_SULE_D:
15718                case R6_OPC_CMP_OR_D:
15719                case R6_OPC_CMP_UNE_D:
15720                case R6_OPC_CMP_NE_D:
15721                case R6_OPC_CMP_SOR_D:
15722                case R6_OPC_CMP_SUNE_D:
15723                case R6_OPC_CMP_SNE_D:
15724                    gen_r6_cmp_d(ctx, ctx->opcode & 0x1f, rt, rd, sa);
15725                    break;
15726                default:
15727                    gen_farith(ctx, ctx->opcode & FOP(0x3f, 0x1f),
15728                               rt, rd, sa, (imm >> 8) & 0x7);
15729
15730                    break;
15731                }
15732            } else {
15733                gen_farith(ctx, ctx->opcode & FOP(0x3f, 0x1f), rt, rd, sa,
15734                           (imm >> 8) & 0x7);
15735            }
15736            break;
15737        }
15738        default:
15739            MIPS_INVAL("cp1");
15740            gen_reserved_instruction(ctx);
15741            break;
15742        }
15743        break;
15744
15745    /* Compact branches [R6] and COP2 [non-R6] */
15746    case OPC_BC: /* OPC_LWC2 */
15747    case OPC_BALC: /* OPC_SWC2 */
15748        if (ctx->insn_flags & ISA_MIPS_R6) {
15749            /* OPC_BC, OPC_BALC */
15750            gen_compute_compact_branch(ctx, op, 0, 0,
15751                                       sextract32(ctx->opcode << 2, 0, 28));
15752        } else if (ctx->insn_flags & ASE_LEXT) {
15753            gen_loongson_lswc2(ctx, rt, rs, rd);
15754        } else {
15755            /* OPC_LWC2, OPC_SWC2 */
15756            /* COP2: Not implemented. */
15757            generate_exception_err(ctx, EXCP_CpU, 2);
15758        }
15759        break;
15760    case OPC_BEQZC: /* OPC_JIC, OPC_LDC2 */
15761    case OPC_BNEZC: /* OPC_JIALC, OPC_SDC2 */
15762        if (ctx->insn_flags & ISA_MIPS_R6) {
15763            if (rs != 0) {
15764                /* OPC_BEQZC, OPC_BNEZC */
15765                gen_compute_compact_branch(ctx, op, rs, 0,
15766                                           sextract32(ctx->opcode << 2, 0, 23));
15767            } else {
15768                /* OPC_JIC, OPC_JIALC */
15769                gen_compute_compact_branch(ctx, op, 0, rt, imm);
15770            }
15771        } else if (ctx->insn_flags & ASE_LEXT) {
15772            gen_loongson_lsdc2(ctx, rt, rs, rd);
15773        } else {
15774            /* OPC_LWC2, OPC_SWC2 */
15775            /* COP2: Not implemented. */
15776            generate_exception_err(ctx, EXCP_CpU, 2);
15777        }
15778        break;
15779    case OPC_CP2:
15780        check_insn(ctx, ASE_LMMI);
15781        /* Note that these instructions use different fields.  */
15782        gen_loongson_multimedia(ctx, sa, rd, rt);
15783        break;
15784
15785    case OPC_CP3:
15786        if (ctx->CP0_Config1 & (1 << CP0C1_FP)) {
15787            check_cp1_enabled(ctx);
15788            op1 = MASK_CP3(ctx->opcode);
15789            switch (op1) {
15790            case OPC_LUXC1:
15791            case OPC_SUXC1:
15792                check_insn(ctx, ISA_MIPS5 | ISA_MIPS_R2);
15793                /* Fallthrough */
15794            case OPC_LWXC1:
15795            case OPC_LDXC1:
15796            case OPC_SWXC1:
15797            case OPC_SDXC1:
15798                check_insn(ctx, ISA_MIPS4 | ISA_MIPS_R2);
15799                gen_flt3_ldst(ctx, op1, sa, rd, rs, rt);
15800                break;
15801            case OPC_PREFX:
15802                check_insn(ctx, ISA_MIPS4 | ISA_MIPS_R2);
15803                /* Treat as NOP. */
15804                break;
15805            case OPC_ALNV_PS:
15806                check_insn(ctx, ISA_MIPS5 | ISA_MIPS_R2);
15807                /* Fallthrough */
15808            case OPC_MADD_S:
15809            case OPC_MADD_D:
15810            case OPC_MADD_PS:
15811            case OPC_MSUB_S:
15812            case OPC_MSUB_D:
15813            case OPC_MSUB_PS:
15814            case OPC_NMADD_S:
15815            case OPC_NMADD_D:
15816            case OPC_NMADD_PS:
15817            case OPC_NMSUB_S:
15818            case OPC_NMSUB_D:
15819            case OPC_NMSUB_PS:
15820                check_insn(ctx, ISA_MIPS4 | ISA_MIPS_R2);
15821                gen_flt3_arith(ctx, op1, sa, rs, rd, rt);
15822                break;
15823            default:
15824                MIPS_INVAL("cp3");
15825                gen_reserved_instruction(ctx);
15826                break;
15827            }
15828        } else {
15829            generate_exception_err(ctx, EXCP_CpU, 1);
15830        }
15831        break;
15832
15833#if defined(TARGET_MIPS64)
15834    /* MIPS64 opcodes */
15835    case OPC_LLD:
15836        if (ctx->insn_flags & INSN_R5900) {
15837            check_insn_opc_user_only(ctx, INSN_R5900);
15838        }
15839        /* fall through */
15840    case OPC_LDL:
15841    case OPC_LDR:
15842    case OPC_LWU:
15843    case OPC_LD:
15844        check_insn(ctx, ISA_MIPS3);
15845        check_mips_64(ctx);
15846        gen_ld(ctx, op, rt, rs, imm);
15847        break;
15848    case OPC_SDL:
15849    case OPC_SDR:
15850    case OPC_SD:
15851        check_insn(ctx, ISA_MIPS3);
15852        check_mips_64(ctx);
15853        gen_st(ctx, op, rt, rs, imm);
15854        break;
15855    case OPC_SCD:
15856        check_insn(ctx, ISA_MIPS3);
15857        if (ctx->insn_flags & INSN_R5900) {
15858            check_insn_opc_user_only(ctx, INSN_R5900);
15859        }
15860        check_mips_64(ctx);
15861        gen_st_cond(ctx, rt, rs, imm, MO_TEUQ, false);
15862        break;
15863    case OPC_BNVC: /* OPC_BNEZALC, OPC_BNEC, OPC_DADDI */
15864        if (ctx->insn_flags & ISA_MIPS_R6) {
15865            /* OPC_BNVC, OPC_BNEZALC, OPC_BNEC */
15866            gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
15867        } else {
15868            /* OPC_DADDI */
15869            check_insn(ctx, ISA_MIPS3);
15870            check_mips_64(ctx);
15871            gen_arith_imm(ctx, op, rt, rs, imm);
15872        }
15873        break;
15874    case OPC_DADDIU:
15875        check_insn(ctx, ISA_MIPS3);
15876        check_mips_64(ctx);
15877        gen_arith_imm(ctx, op, rt, rs, imm);
15878        break;
15879#else
15880    case OPC_BNVC: /* OPC_BNEZALC, OPC_BNEC */
15881        if (ctx->insn_flags & ISA_MIPS_R6) {
15882            gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
15883        } else {
15884            MIPS_INVAL("major opcode");
15885            gen_reserved_instruction(ctx);
15886        }
15887        break;
15888#endif
15889    case OPC_DAUI: /* OPC_JALX */
15890        if (ctx->insn_flags & ISA_MIPS_R6) {
15891#if defined(TARGET_MIPS64)
15892            /* OPC_DAUI */
15893            check_mips_64(ctx);
15894            if (rs == 0) {
15895                generate_exception(ctx, EXCP_RI);
15896            } else if (rt != 0) {
15897                TCGv t0 = tcg_temp_new();
15898                gen_load_gpr(t0, rs);
15899                tcg_gen_addi_tl(cpu_gpr[rt], t0, imm << 16);
15900                tcg_temp_free(t0);
15901            }
15902#else
15903            gen_reserved_instruction(ctx);
15904            MIPS_INVAL("major opcode");
15905#endif
15906        } else {
15907            /* OPC_JALX */
15908            check_insn(ctx, ASE_MIPS16 | ASE_MICROMIPS);
15909            offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 2;
15910            gen_compute_branch(ctx, op, 4, rs, rt, offset, 4);
15911        }
15912        break;
15913    case OPC_MDMX:
15914        /* MDMX: Not implemented. */
15915        break;
15916    case OPC_PCREL:
15917        check_insn(ctx, ISA_MIPS_R6);
15918        gen_pcrel(ctx, ctx->opcode, ctx->base.pc_next, rs);
15919        break;
15920    default:            /* Invalid */
15921        MIPS_INVAL("major opcode");
15922        return false;
15923    }
15924    return true;
15925}
15926
15927static void decode_opc(CPUMIPSState *env, DisasContext *ctx)
15928{
15929    /* make sure instructions are on a word boundary */
15930    if (ctx->base.pc_next & 0x3) {
15931        env->CP0_BadVAddr = ctx->base.pc_next;
15932        generate_exception_err(ctx, EXCP_AdEL, EXCP_INST_NOTAVAIL);
15933        return;
15934    }
15935
15936    /* Handle blikely not taken case */
15937    if ((ctx->hflags & MIPS_HFLAG_BMASK_BASE) == MIPS_HFLAG_BL) {
15938        TCGLabel *l1 = gen_new_label();
15939
15940        tcg_gen_brcondi_tl(TCG_COND_NE, bcond, 0, l1);
15941        tcg_gen_movi_i32(hflags, ctx->hflags & ~MIPS_HFLAG_BMASK);
15942        gen_goto_tb(ctx, 1, ctx->base.pc_next + 4);
15943        gen_set_label(l1);
15944    }
15945
15946    /* Transition to the auto-generated decoder.  */
15947
15948    /* Vendor specific extensions */
15949    if (cpu_supports_isa(env, INSN_R5900) && decode_ext_txx9(ctx, ctx->opcode)) {
15950        return;
15951    }
15952    if (cpu_supports_isa(env, INSN_VR54XX) && decode_ext_vr54xx(ctx, ctx->opcode)) {
15953        return;
15954    }
15955#if defined(TARGET_MIPS64)
15956    if (cpu_supports_isa(env, INSN_OCTEON) && decode_ext_octeon(ctx, ctx->opcode)) {
15957        return;
15958    }
15959#endif
15960
15961    /* ISA extensions */
15962    if (ase_msa_available(env) && decode_ase_msa(ctx, ctx->opcode)) {
15963        return;
15964    }
15965
15966    /* ISA (from latest to oldest) */
15967    if (cpu_supports_isa(env, ISA_MIPS_R6) && decode_isa_rel6(ctx, ctx->opcode)) {
15968        return;
15969    }
15970
15971    if (decode_opc_legacy(env, ctx)) {
15972        return;
15973    }
15974
15975    gen_reserved_instruction(ctx);
15976}
15977
15978static void mips_tr_init_disas_context(DisasContextBase *dcbase, CPUState *cs)
15979{
15980    DisasContext *ctx = container_of(dcbase, DisasContext, base);
15981    CPUMIPSState *env = cs->env_ptr;
15982
15983    ctx->page_start = ctx->base.pc_first & TARGET_PAGE_MASK;
15984    ctx->saved_pc = -1;
15985    ctx->insn_flags = env->insn_flags;
15986    ctx->CP0_Config0 = env->CP0_Config0;
15987    ctx->CP0_Config1 = env->CP0_Config1;
15988    ctx->CP0_Config2 = env->CP0_Config2;
15989    ctx->CP0_Config3 = env->CP0_Config3;
15990    ctx->CP0_Config5 = env->CP0_Config5;
15991    ctx->btarget = 0;
15992    ctx->kscrexist = (env->CP0_Config4 >> CP0C4_KScrExist) & 0xff;
15993    ctx->rxi = (env->CP0_Config3 >> CP0C3_RXI) & 1;
15994    ctx->ie = (env->CP0_Config4 >> CP0C4_IE) & 3;
15995    ctx->bi = (env->CP0_Config3 >> CP0C3_BI) & 1;
15996    ctx->bp = (env->CP0_Config3 >> CP0C3_BP) & 1;
15997    ctx->PAMask = env->PAMask;
15998    ctx->mvh = (env->CP0_Config5 >> CP0C5_MVH) & 1;
15999    ctx->eva = (env->CP0_Config5 >> CP0C5_EVA) & 1;
16000    ctx->sc = (env->CP0_Config3 >> CP0C3_SC) & 1;
16001    ctx->CP0_LLAddr_shift = env->CP0_LLAddr_shift;
16002    ctx->cmgcr = (env->CP0_Config3 >> CP0C3_CMGCR) & 1;
16003    /* Restore delay slot state from the tb context.  */
16004    ctx->hflags = (uint32_t)ctx->base.tb->flags; /* FIXME: maybe use 64 bits? */
16005    ctx->ulri = (env->CP0_Config3 >> CP0C3_ULRI) & 1;
16006    ctx->ps = ((env->active_fpu.fcr0 >> FCR0_PS) & 1) ||
16007             (env->insn_flags & (INSN_LOONGSON2E | INSN_LOONGSON2F));
16008    ctx->vp = (env->CP0_Config5 >> CP0C5_VP) & 1;
16009    ctx->mrp = (env->CP0_Config5 >> CP0C5_MRP) & 1;
16010    ctx->nan2008 = (env->active_fpu.fcr31 >> FCR31_NAN2008) & 1;
16011    ctx->abs2008 = (env->active_fpu.fcr31 >> FCR31_ABS2008) & 1;
16012    ctx->mi = (env->CP0_Config5 >> CP0C5_MI) & 1;
16013    ctx->gi = (env->CP0_Config5 >> CP0C5_GI) & 3;
16014    restore_cpu_state(env, ctx);
16015#ifdef CONFIG_USER_ONLY
16016        ctx->mem_idx = MIPS_HFLAG_UM;
16017#else
16018        ctx->mem_idx = hflags_mmu_index(ctx->hflags);
16019#endif
16020    ctx->default_tcg_memop_mask = (!(ctx->insn_flags & ISA_NANOMIPS32) &&
16021                                  (ctx->insn_flags & (ISA_MIPS_R6 |
16022                                  INSN_LOONGSON3A))) ? MO_UNALN : MO_ALIGN;
16023
16024    /*
16025     * Execute a branch and its delay slot as a single instruction.
16026     * This is what GDB expects and is consistent with what the
16027     * hardware does (e.g. if a delay slot instruction faults, the
16028     * reported PC is the PC of the branch).
16029     */
16030    if (ctx->base.singlestep_enabled && (ctx->hflags & MIPS_HFLAG_BMASK)) {
16031        ctx->base.max_insns = 2;
16032    }
16033
16034    LOG_DISAS("\ntb %p idx %d hflags %04x\n", ctx->base.tb, ctx->mem_idx,
16035              ctx->hflags);
16036}
16037
16038static void mips_tr_tb_start(DisasContextBase *dcbase, CPUState *cs)
16039{
16040}
16041
16042static void mips_tr_insn_start(DisasContextBase *dcbase, CPUState *cs)
16043{
16044    DisasContext *ctx = container_of(dcbase, DisasContext, base);
16045
16046    tcg_gen_insn_start(ctx->base.pc_next, ctx->hflags & MIPS_HFLAG_BMASK,
16047                       ctx->btarget);
16048}
16049
16050static void mips_tr_translate_insn(DisasContextBase *dcbase, CPUState *cs)
16051{
16052    CPUMIPSState *env = cs->env_ptr;
16053    DisasContext *ctx = container_of(dcbase, DisasContext, base);
16054    int insn_bytes;
16055    int is_slot;
16056
16057    is_slot = ctx->hflags & MIPS_HFLAG_BMASK;
16058    if (ctx->insn_flags & ISA_NANOMIPS32) {
16059        ctx->opcode = translator_lduw(env, &ctx->base, ctx->base.pc_next);
16060        insn_bytes = decode_isa_nanomips(env, ctx);
16061    } else if (!(ctx->hflags & MIPS_HFLAG_M16)) {
16062        ctx->opcode = translator_ldl(env, &ctx->base, ctx->base.pc_next);
16063        insn_bytes = 4;
16064        decode_opc(env, ctx);
16065    } else if (ctx->insn_flags & ASE_MICROMIPS) {
16066        ctx->opcode = translator_lduw(env, &ctx->base, ctx->base.pc_next);
16067        insn_bytes = decode_isa_micromips(env, ctx);
16068    } else if (ctx->insn_flags & ASE_MIPS16) {
16069        ctx->opcode = translator_lduw(env, &ctx->base, ctx->base.pc_next);
16070        insn_bytes = decode_ase_mips16e(env, ctx);
16071    } else {
16072        gen_reserved_instruction(ctx);
16073        g_assert(ctx->base.is_jmp == DISAS_NORETURN);
16074        return;
16075    }
16076
16077    if (ctx->hflags & MIPS_HFLAG_BMASK) {
16078        if (!(ctx->hflags & (MIPS_HFLAG_BDS16 | MIPS_HFLAG_BDS32 |
16079                             MIPS_HFLAG_FBNSLOT))) {
16080            /*
16081             * Force to generate branch as there is neither delay nor
16082             * forbidden slot.
16083             */
16084            is_slot = 1;
16085        }
16086        if ((ctx->hflags & MIPS_HFLAG_M16) &&
16087            (ctx->hflags & MIPS_HFLAG_FBNSLOT)) {
16088            /*
16089             * Force to generate branch as microMIPS R6 doesn't restrict
16090             * branches in the forbidden slot.
16091             */
16092            is_slot = 1;
16093        }
16094    }
16095    if (is_slot) {
16096        gen_branch(ctx, insn_bytes);
16097    }
16098    if (ctx->base.is_jmp == DISAS_SEMIHOST) {
16099        generate_exception_err(ctx, EXCP_SEMIHOST, insn_bytes);
16100    }
16101    ctx->base.pc_next += insn_bytes;
16102
16103    if (ctx->base.is_jmp != DISAS_NEXT) {
16104        return;
16105    }
16106
16107    /*
16108     * End the TB on (most) page crossings.
16109     * See mips_tr_init_disas_context about single-stepping a branch
16110     * together with its delay slot.
16111     */
16112    if (ctx->base.pc_next - ctx->page_start >= TARGET_PAGE_SIZE
16113        && !ctx->base.singlestep_enabled) {
16114        ctx->base.is_jmp = DISAS_TOO_MANY;
16115    }
16116}
16117
16118static void mips_tr_tb_stop(DisasContextBase *dcbase, CPUState *cs)
16119{
16120    DisasContext *ctx = container_of(dcbase, DisasContext, base);
16121
16122    switch (ctx->base.is_jmp) {
16123    case DISAS_STOP:
16124        gen_save_pc(ctx->base.pc_next);
16125        tcg_gen_lookup_and_goto_ptr();
16126        break;
16127    case DISAS_NEXT:
16128    case DISAS_TOO_MANY:
16129        save_cpu_state(ctx, 0);
16130        gen_goto_tb(ctx, 0, ctx->base.pc_next);
16131        break;
16132    case DISAS_EXIT:
16133        tcg_gen_exit_tb(NULL, 0);
16134        break;
16135    case DISAS_NORETURN:
16136        break;
16137    default:
16138        g_assert_not_reached();
16139    }
16140}
16141
16142static void mips_tr_disas_log(const DisasContextBase *dcbase,
16143                              CPUState *cs, FILE *logfile)
16144{
16145    fprintf(logfile, "IN: %s\n", lookup_symbol(dcbase->pc_first));
16146    target_disas(logfile, cs, dcbase->pc_first, dcbase->tb->size);
16147}
16148
16149static const TranslatorOps mips_tr_ops = {
16150    .init_disas_context = mips_tr_init_disas_context,
16151    .tb_start           = mips_tr_tb_start,
16152    .insn_start         = mips_tr_insn_start,
16153    .translate_insn     = mips_tr_translate_insn,
16154    .tb_stop            = mips_tr_tb_stop,
16155    .disas_log          = mips_tr_disas_log,
16156};
16157
16158void gen_intermediate_code(CPUState *cs, TranslationBlock *tb, int max_insns)
16159{
16160    DisasContext ctx;
16161
16162    translator_loop(&mips_tr_ops, &ctx.base, cs, tb, max_insns);
16163}
16164
16165void mips_tcg_init(void)
16166{
16167    int i;
16168
16169    cpu_gpr[0] = NULL;
16170    for (i = 1; i < 32; i++)
16171        cpu_gpr[i] = tcg_global_mem_new(cpu_env,
16172                                        offsetof(CPUMIPSState,
16173                                                 active_tc.gpr[i]),
16174                                        regnames[i]);
16175#if defined(TARGET_MIPS64)
16176    cpu_gpr_hi[0] = NULL;
16177
16178    for (unsigned i = 1; i < 32; i++) {
16179        g_autofree char *rname = g_strdup_printf("%s[hi]", regnames[i]);
16180
16181        cpu_gpr_hi[i] = tcg_global_mem_new_i64(cpu_env,
16182                                               offsetof(CPUMIPSState,
16183                                                        active_tc.gpr_hi[i]),
16184                                               rname);
16185    }
16186#endif /* !TARGET_MIPS64 */
16187    for (i = 0; i < 32; i++) {
16188        int off = offsetof(CPUMIPSState, active_fpu.fpr[i].wr.d[0]);
16189
16190        fpu_f64[i] = tcg_global_mem_new_i64(cpu_env, off, fregnames[i]);
16191    }
16192    msa_translate_init();
16193    cpu_PC = tcg_global_mem_new(cpu_env,
16194                                offsetof(CPUMIPSState, active_tc.PC), "PC");
16195    for (i = 0; i < MIPS_DSP_ACC; i++) {
16196        cpu_HI[i] = tcg_global_mem_new(cpu_env,
16197                                       offsetof(CPUMIPSState, active_tc.HI[i]),
16198                                       regnames_HI[i]);
16199        cpu_LO[i] = tcg_global_mem_new(cpu_env,
16200                                       offsetof(CPUMIPSState, active_tc.LO[i]),
16201                                       regnames_LO[i]);
16202    }
16203    cpu_dspctrl = tcg_global_mem_new(cpu_env,
16204                                     offsetof(CPUMIPSState,
16205                                              active_tc.DSPControl),
16206                                     "DSPControl");
16207    bcond = tcg_global_mem_new(cpu_env,
16208                               offsetof(CPUMIPSState, bcond), "bcond");
16209    btarget = tcg_global_mem_new(cpu_env,
16210                                 offsetof(CPUMIPSState, btarget), "btarget");
16211    hflags = tcg_global_mem_new_i32(cpu_env,
16212                                    offsetof(CPUMIPSState, hflags), "hflags");
16213
16214    fpu_fcr0 = tcg_global_mem_new_i32(cpu_env,
16215                                      offsetof(CPUMIPSState, active_fpu.fcr0),
16216                                      "fcr0");
16217    fpu_fcr31 = tcg_global_mem_new_i32(cpu_env,
16218                                       offsetof(CPUMIPSState, active_fpu.fcr31),
16219                                       "fcr31");
16220    cpu_lladdr = tcg_global_mem_new(cpu_env, offsetof(CPUMIPSState, lladdr),
16221                                    "lladdr");
16222    cpu_llval = tcg_global_mem_new(cpu_env, offsetof(CPUMIPSState, llval),
16223                                   "llval");
16224
16225    if (TARGET_LONG_BITS == 32) {
16226        mxu_translate_init();
16227    }
16228}
16229
16230void restore_state_to_opc(CPUMIPSState *env, TranslationBlock *tb,
16231                          target_ulong *data)
16232{
16233    env->active_tc.PC = data[0];
16234    env->hflags &= ~MIPS_HFLAG_BMASK;
16235    env->hflags |= data[1];
16236    switch (env->hflags & MIPS_HFLAG_BMASK_BASE) {
16237    case MIPS_HFLAG_BR:
16238        break;
16239    case MIPS_HFLAG_BC:
16240    case MIPS_HFLAG_BL:
16241    case MIPS_HFLAG_B:
16242        env->btarget = data[2];
16243        break;
16244    }
16245}
16246